Annotation of hatari/src/cpu/jit/compemu_raw_x86.c, revision 1.1.1.1

1.1       root        1: /* This should eventually end up in machdep/, but for now, x86 is the
                      2: only target, and it's easier this way... */
                      3: 
                      4: /*************************************************************************
                      5: * Some basic information about the the target CPU                       *
                      6: *************************************************************************/
                      7: 
                      8: #define EAX_INDEX 0
                      9: #define ECX_INDEX 1
                     10: #define EDX_INDEX 2
                     11: #define EBX_INDEX 3
                     12: #define ESP_INDEX 4
                     13: #define EBP_INDEX 5
                     14: #define ESI_INDEX 6
                     15: #define EDI_INDEX 7
                     16: #if defined(__x86_64__)
                     17: #define R8_INDEX  8
                     18: #define R9_INDEX  9
                     19: #define R10_INDEX 10
                     20: #define R11_INDEX 11
                     21: #define R12_INDEX 12
                     22: #define R13_INDEX 13
                     23: #define R14_INDEX 14
                     24: #define R15_INDEX 15
                     25: #endif
                     26: /* XXX this has to match X86_Reg8H_Base + 4 */
                     27: #define AH_INDEX (0x10+4+EAX_INDEX)
                     28: #define CH_INDEX (0x10+4+ECX_INDEX)
                     29: #define DH_INDEX (0x10+4+EDX_INDEX)
                     30: #define BH_INDEX (0x10+4+EBX_INDEX)
                     31: 
                     32: /* The register in which subroutines return an integer return value */
                     33: #define REG_RESULT EAX_INDEX
                     34: 
                     35: /* The registers subroutines take their first and second argument in */
                     36: #if defined(_WIN32)
                     37: /* Handle the _fastcall parameters of ECX and EDX */
                     38: #define REG_PAR1 ECX_INDEX
                     39: #define REG_PAR2 EDX_INDEX
                     40: #elif defined(__x86_64__)
                     41: #define REG_PAR1 EDI_INDEX
                     42: #define REG_PAR2 ESI_INDEX
                     43: #else
                     44: #define REG_PAR1 EAX_INDEX
                     45: #define REG_PAR2 EDX_INDEX
                     46: #endif
                     47: 
                     48: #if defined(_WIN32)
                     49: #define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */
                     50: #define REG_PC_TMP ECX_INDEX
                     51: #define SHIFTCOUNT_NREG ECX_INDEX  /* Register that can be used for shiftcount. -1 if any reg will do */
                     52: #else
                     53: #define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */
                     54: #define REG_PC_TMP ECX_INDEX /* Another register that is not the above */
                     55: #define SHIFTCOUNT_NREG ECX_INDEX  /* Register that can be used for shiftcount. -1 if any reg will do */
                     56: #endif
                     57: 
                     58: #define MUL_NREG1 EAX_INDEX /* %eax will hold the low 32 bits after a 32x32 mul */
                     59: #define MUL_NREG2 EDX_INDEX /* %edx will hold the high 32 bits */
                     60: 
                     61: #define STACK_ALIGN            16
                     62: #define STACK_OFFSET   sizeof(void *)
                     63: 
                     64: uae_u8 always_used[]={4,0xff};
                     65: #if defined(__x86_64__)
                     66: uae_s8 can_byte[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1};
                     67: uae_s8 can_word[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1};
                     68: #else
                     69: uae_u8 can_byte[]={0,1,2,3,0xff};
                     70: uae_u8 can_word[]={0,1,2,3,5,6,7,0xff};
                     71: #endif
                     72: 
                     73: uae_u8 call_saved[]={0,0,0,0,1,0,0,0};
                     74: 
                     75: /* This *should* be the same as call_saved. But:
                     76: - We might not really know which registers are saved, and which aren't,
                     77: so we need to preserve some, but don't want to rely on everyone else
                     78: also saving those registers
                     79: - Special registers (such like the stack pointer) should not be "preserved"
                     80: by pushing, even though they are "saved" across function calls
                     81: */
                     82: uae_u8 need_to_preserve[]={1,1,1,1,0,1,1,1};
                     83: 
                     84: /* Whether classes of instructions do or don't clobber the native flags */
                     85: #define CLOBBER_MOV
                     86: #define CLOBBER_LEA
                     87: #define CLOBBER_CMOV
                     88: #define CLOBBER_POP
                     89: #define CLOBBER_PUSH
                     90: #define CLOBBER_SUB  clobber_flags()
                     91: #define CLOBBER_SBB  clobber_flags()
                     92: #define CLOBBER_CMP  clobber_flags()
                     93: #define CLOBBER_ADD  clobber_flags()
                     94: #define CLOBBER_ADC  clobber_flags()
                     95: #define CLOBBER_AND  clobber_flags()
                     96: #define CLOBBER_OR   clobber_flags()
                     97: #define CLOBBER_XOR  clobber_flags()
                     98: 
                     99: #define CLOBBER_ROL  clobber_flags()
                    100: #define CLOBBER_ROR  clobber_flags()
                    101: #define CLOBBER_SHLL clobber_flags()
                    102: #define CLOBBER_SHRL clobber_flags()
                    103: #define CLOBBER_SHRA clobber_flags()
                    104: #define CLOBBER_TEST clobber_flags()
                    105: #define CLOBBER_CL16
                    106: #define CLOBBER_CL8
                    107: #define CLOBBER_SE16
                    108: #define CLOBBER_SE8
                    109: #define CLOBBER_ZE16
                    110: #define CLOBBER_ZE8
                    111: #define CLOBBER_SW16 clobber_flags()
                    112: #define CLOBBER_SW32
                    113: #define CLOBBER_SETCC
                    114: #define CLOBBER_MUL  clobber_flags()
                    115: #define CLOBBER_BT   clobber_flags()
                    116: #define CLOBBER_BSF  clobber_flags()
                    117: 
                    118: /*************************************************************************
                    119: * Actual encoding of the instructions on the target CPU                 *
                    120: *************************************************************************/
                    121: 
                    122: //#include "compemu_optimizer_x86.c"
                    123: 
                    124: STATIC_INLINE uae_u16 swap16(uae_u16 x)
                    125: {
                    126:        return ((x&0xff00)>>8)|((x&0x00ff)<<8);
                    127: }
                    128: 
                    129: STATIC_INLINE uae_u32 swap32(uae_u32 x)
                    130: {
                    131:        return ((x&0xff00)<<8)|((x&0x00ff)<<24)|((x&0xff0000)>>8)|((x&0xff000000)>>24);
                    132: }
                    133: 
                    134: STATIC_INLINE int isbyte(uae_s32 x)
                    135: {
                    136:        return (x>=-128 && x<=127);
                    137: }
                    138: 
                    139: LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
                    140: {
                    141:        emit_byte(0x50+r);
                    142: }
                    143: LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
                    144: 
                    145:        LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
                    146: {
                    147:        emit_byte(0x58+r);
                    148: }
                    149: LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
                    150: 
                    151:        LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
                    152: {
                    153:        emit_byte(0x0f);
                    154:        emit_byte(0xba);
                    155:        emit_byte(0xe0+r);
                    156:        emit_byte(i);
                    157: }
                    158: LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
                    159: 
                    160:        LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
                    161: {
                    162:        emit_byte(0x0f);
                    163:        emit_byte(0xa3);
                    164:        emit_byte(0xc0+8*b+r);
                    165: }
                    166: LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
                    167: 
                    168:        LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
                    169: {
                    170:        emit_byte(0x0f);
                    171:        emit_byte(0xba);
                    172:        emit_byte(0xf8+r);
                    173:        emit_byte(i);
                    174: }
                    175: LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
                    176: 
                    177:        LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
                    178: {
                    179:        emit_byte(0x0f);
                    180:        emit_byte(0xbb);
                    181:        emit_byte(0xc0+8*b+r);
                    182: }
                    183: LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
                    184: 
                    185: 
                    186:        LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
                    187: {
                    188:        emit_byte(0x0f);
                    189:        emit_byte(0xba);
                    190:        emit_byte(0xf0+r);
                    191:        emit_byte(i);
                    192: }
                    193: LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
                    194: 
                    195:        LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
                    196: {
                    197:        emit_byte(0x0f);
                    198:        emit_byte(0xb3);
                    199:        emit_byte(0xc0+8*b+r);
                    200: }
                    201: LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
                    202: 
                    203:        LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
                    204: {
                    205:        emit_byte(0x0f);
                    206:        emit_byte(0xba);
                    207:        emit_byte(0xe8+r);
                    208:        emit_byte(i);
                    209: }
                    210: LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
                    211: 
                    212:        LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
                    213: {
                    214:        emit_byte(0x0f);
                    215:        emit_byte(0xab);
                    216:        emit_byte(0xc0+8*b+r);
                    217: }
                    218: LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
                    219: 
                    220:        LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
                    221: {
                    222:        emit_byte(0x66);
                    223:        if (isbyte(i)) {
                    224:                emit_byte(0x83);
                    225:                emit_byte(0xe8+d);
                    226:                emit_byte(i);
                    227:        }
                    228:        else {
                    229:                emit_byte(0x81);
                    230:                emit_byte(0xe8+d);
                    231:                emit_word(i);
                    232:        }
                    233: }
                    234: LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
                    235: 
                    236: 
                    237:        LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
                    238: {
                    239:        emit_byte(0xc7);
                    240:        emit_byte(0x05);
                    241:        emit_long(d);
                    242:        emit_long(s);
                    243: }
                    244: LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
                    245: 
                    246:        LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
                    247: {
                    248:        emit_byte(0x66);
                    249:        emit_byte(0xc7);
                    250:        emit_byte(0x05);
                    251:        emit_long(d);
                    252:        emit_word(s);
                    253: }
                    254: LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
                    255: 
                    256:        LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
                    257: {
                    258:        emit_byte(0xc6);
                    259:        emit_byte(0x05);
                    260:        emit_long(d);
                    261:        emit_byte(s);
                    262: }
                    263: LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
                    264: 
                    265:        LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
                    266: {
                    267:        emit_byte(0xc0);
                    268:        emit_byte(0x05);
                    269:        emit_long(d);
                    270:        emit_byte(i);
                    271: }
                    272: LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
                    273: 
                    274:        LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
                    275: {
                    276:        emit_byte(0xc0);
                    277:        emit_byte(0xc0+r);
                    278:        emit_byte(i);
                    279: }
                    280: LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
                    281: 
                    282:        LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
                    283: {
                    284:        emit_byte(0x66);
                    285:        emit_byte(0xc1);
                    286:        emit_byte(0xc0+r);
                    287:        emit_byte(i);
                    288: }
                    289: LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
                    290: 
                    291:        LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
                    292: {
                    293:        emit_byte(0xc1);
                    294:        emit_byte(0xc0+r);
                    295:        emit_byte(i);
                    296: }
                    297: LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
                    298: 
                    299:        LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
                    300: {
                    301:        emit_byte(0xd3);
                    302:        emit_byte(0xc0+d);
                    303: }
                    304: LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
                    305: 
                    306:        LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
                    307: {
                    308:        emit_byte(0x66);
                    309:        emit_byte(0xd3);
                    310:        emit_byte(0xc0+d);
                    311: }
                    312: LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
                    313: 
                    314:        LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
                    315: {
                    316:        emit_byte(0xd2);
                    317:        emit_byte(0xc0+d);
                    318: }
                    319: LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
                    320: 
                    321:        LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
                    322: {
                    323:        emit_byte(0xd3);
                    324:        emit_byte(0xe0+d);
                    325: }
                    326: LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
                    327: 
                    328:        LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
                    329: {
                    330:        emit_byte(0x66);
                    331:        emit_byte(0xd3);
                    332:        emit_byte(0xe0+d);
                    333: }
                    334: LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
                    335: 
                    336:        LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
                    337: {
                    338:        emit_byte(0xd2);
                    339:        emit_byte(0xe0+d);
                    340: }
                    341: LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
                    342: 
                    343:        LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
                    344: {
                    345:        emit_byte(0xc0);
                    346:        emit_byte(0xc8+r);
                    347:        emit_byte(i);
                    348: }
                    349: LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
                    350: 
                    351:        LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
                    352: {
                    353:        emit_byte(0x66);
                    354:        emit_byte(0xc1);
                    355:        emit_byte(0xc8+r);
                    356:        emit_byte(i);
                    357: }
                    358: LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
                    359: 
                    360:        LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
                    361: {
                    362:        emit_byte(0xc1);
                    363:        emit_byte(0xc8+r);
                    364:        emit_byte(i);
                    365: }
                    366: LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
                    367: 
                    368:        LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
                    369: {
                    370:        emit_byte(0xd3);
                    371:        emit_byte(0xc8+d);
                    372: }
                    373: LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
                    374: 
                    375:        LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
                    376: {
                    377:        emit_byte(0x66);
                    378:        emit_byte(0xd3);
                    379:        emit_byte(0xc8+d);
                    380: }
                    381: LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
                    382: 
                    383:        LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
                    384: {
                    385:        emit_byte(0xd2);
                    386:        emit_byte(0xc8+d);
                    387: }
                    388: LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
                    389: 
                    390:        LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
                    391: {
                    392:        emit_byte(0xd3);
                    393:        emit_byte(0xe8+d);
                    394: }
                    395: LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
                    396: 
                    397:        LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
                    398: {
                    399:        emit_byte(0x66);
                    400:        emit_byte(0xd3);
                    401:        emit_byte(0xe8+d);
                    402: }
                    403: LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
                    404: 
                    405:        LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
                    406: {
                    407:        emit_byte(0xd2);
                    408:        emit_byte(0xe8+d);
                    409: }
                    410: LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
                    411: 
                    412:        LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
                    413: {
                    414:        emit_byte(0xd3);
                    415:        emit_byte(0xf8+d);
                    416: }
                    417: LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
                    418: 
                    419:        LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
                    420: {
                    421:        emit_byte(0x66);
                    422:        emit_byte(0xd3);
                    423:        emit_byte(0xf8+d);
                    424: }
                    425: LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
                    426: 
                    427:        LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
                    428: {
                    429:        emit_byte(0xd2);
                    430:        emit_byte(0xf8+d);
                    431: }
                    432: LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
                    433: 
                    434:        LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
                    435: {
                    436:        emit_byte(0xc1);
                    437:        emit_byte(0xe0+r);
                    438:        emit_byte(i);
                    439: }
                    440: LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
                    441: 
                    442:        LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
                    443: {
                    444:        emit_byte(0x66);
                    445:        emit_byte(0xc1);
                    446:        emit_byte(0xe0+r);
                    447:        emit_byte(i);
                    448: }
                    449: LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
                    450: 
                    451:        LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
                    452: {
                    453:        emit_byte(0xc0);
                    454:        emit_byte(0xe0+r);
                    455:        emit_byte(i);
                    456: }
                    457: LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
                    458: 
                    459:        LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
                    460: {
                    461:        emit_byte(0xc1);
                    462:        emit_byte(0xe8+r);
                    463:        emit_byte(i);
                    464: }
                    465: LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
                    466: 
                    467:        LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
                    468: {
                    469:        emit_byte(0x66);
                    470:        emit_byte(0xc1);
                    471:        emit_byte(0xe8+r);
                    472:        emit_byte(i);
                    473: }
                    474: LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
                    475: 
                    476:        LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
                    477: {
                    478:        emit_byte(0xc0);
                    479:        emit_byte(0xe8+r);
                    480:        emit_byte(i);
                    481: }
                    482: LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
                    483: 
                    484:        LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
                    485: {
                    486:        emit_byte(0xc1);
                    487:        emit_byte(0xf8+r);
                    488:        emit_byte(i);
                    489: }
                    490: LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
                    491: 
                    492:        LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
                    493: {
                    494:        emit_byte(0x66);
                    495:        emit_byte(0xc1);
                    496:        emit_byte(0xf8+r);
                    497:        emit_byte(i);
                    498: }
                    499: LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
                    500: 
                    501:        LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
                    502: {
                    503:        emit_byte(0xc0);
                    504:        emit_byte(0xf8+r);
                    505:        emit_byte(i);
                    506: }
                    507: LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
                    508: 
                    509:        LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
                    510: {
                    511:        emit_byte(0x9e);
                    512: }
                    513: LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
                    514: 
                    515:        LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
                    516: {
                    517:        emit_byte(0x0f);
                    518:        emit_byte(0xa2);
                    519: }
                    520: LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
                    521: 
                    522:        LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
                    523: {
                    524:        emit_byte(0x9f);
                    525: }
                    526: LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
                    527: 
                    528:        LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
                    529: {
                    530:        emit_byte(0x0f);
                    531:        emit_byte(0x90+cc);
                    532:        emit_byte(0xc0+d);
                    533: }
                    534: LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
                    535: 
                    536:        LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
                    537: {
                    538:        emit_byte(0x0f);
                    539:        emit_byte(0x90+cc);
                    540:        emit_byte(0x05);
                    541:        emit_long(d);
                    542: }
                    543: LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
                    544: 
                    545:        LOWFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc))
                    546: {
                    547:        /* replacement using branch and mov */
                    548:        int uncc=(cc^1);
                    549:        emit_byte(0x70+uncc);
                    550:        emit_byte(3);  /* skip next 2 bytes if not cc=true */
                    551:        emit_byte(0x88);
                    552:        emit_byte(0xc0+8*s+d);
                    553: }
                    554: LENDFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc))
                    555: 
                    556:        LOWFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc))
                    557: {
                    558:        if (have_cmov) {
                    559:                emit_byte(0x66);
                    560:                emit_byte(0x0f);
                    561:                emit_byte(0x40+cc);
                    562:                emit_byte(0xc0+8*d+s);
                    563:        }
                    564:        else { /* replacement using branch and mov */
                    565:                int uncc=(cc^1);
                    566:                emit_byte(0x70+uncc);
                    567:                emit_byte(3);  /* skip next 3 bytes if not cc=true */
                    568:                emit_byte(0x66);
                    569:                emit_byte(0x89);
                    570:                emit_byte(0xc0+8*s+d);
                    571:        }
                    572: }
                    573: LENDFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc))
                    574: 
                    575:        LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
                    576: {
                    577:        if (have_cmov) {
                    578:                emit_byte(0x0f);
                    579:                emit_byte(0x40+cc);
                    580:                emit_byte(0xc0+8*d+s);
                    581:        }
                    582:        else { /* replacement using branch and mov */
                    583:                int uncc=(cc^1);
                    584:                emit_byte(0x70+uncc);
                    585:                emit_byte(2);  /* skip next 2 bytes if not cc=true */
                    586:                emit_byte(0x89);
                    587:                emit_byte(0xc0+8*s+d);
                    588:        }
                    589: }
                    590: LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
                    591: 
                    592:        LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
                    593: {
                    594:        emit_byte(0x0f);
                    595:        emit_byte(0xbc);
                    596:        emit_byte(0xc0+8*d+s);
                    597: }
                    598: LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
                    599: 
                    600:        LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
                    601: {
                    602:        emit_byte(0x0f);
                    603:        emit_byte(0xbf);
                    604:        emit_byte(0xc0+8*d+s);
                    605: }
                    606: LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
                    607: 
                    608:        LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
                    609: {
                    610:        emit_byte(0x0f);
                    611:        emit_byte(0xbe);
                    612:        emit_byte(0xc0+8*d+s);
                    613: }
                    614: LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
                    615: 
                    616:        LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
                    617: {
                    618:        emit_byte(0x0f);
                    619:        emit_byte(0xb7);
                    620:        emit_byte(0xc0+8*d+s);
                    621: }
                    622: LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
                    623: 
                    624:        LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
                    625: {
                    626:        emit_byte(0x0f);
                    627:        emit_byte(0xb6);
                    628:        emit_byte(0xc0+8*d+s);
                    629: }
                    630: LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
                    631: 
                    632:        LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
                    633: {
                    634:        emit_byte(0x0f);
                    635:        emit_byte(0xaf);
                    636:        emit_byte(0xc0+8*d+s);
                    637: }
                    638: LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
                    639: 
                    640:        LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
                    641: {
                    642: #ifdef JIT_DEBUG
                    643:        if (d!=MUL_NREG1 || s!=MUL_NREG2) {
                    644:                write_log (L"JIT: Bad register in IMUL: d=%d, s=%d\n",d,s);
                    645:                abort();
                    646:        }
                    647: #endif
                    648:        emit_byte(0xf7);
                    649:        emit_byte(0xea);
                    650: }
                    651: LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
                    652: 
                    653:        LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
                    654: {
                    655: #ifdef JIT_DEBUG
                    656:        if (d!=MUL_NREG1 || s!=MUL_NREG2) {
                    657:                write_log (L"JIT: Bad register in MUL: d=%d, s=%d\n",d,s);
                    658:                abort();
                    659:        }
                    660: #endif
                    661:        emit_byte(0xf7);
                    662:        emit_byte(0xe2);
                    663: }
                    664: LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
                    665: 
                    666:        LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
                    667: {
                    668:        emit_byte(0x88);
                    669:        emit_byte(0xc0+8*s+d);
                    670: }
                    671: LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
                    672: 
                    673:        LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
                    674: {
                    675:        emit_byte(0x66);
                    676:        emit_byte(0x89);
                    677:        emit_byte(0xc0+8*s+d);
                    678: }
                    679: LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
                    680: 
                    681:        LOWFUNC(NONE,READ,3,raw_mov_l_rrm_indexed,(W4 d, R4 baser, R4 index))
                    682: {
                    683:        emit_byte(0x8b);
                    684:        if (baser==5) {
                    685:                emit_byte(0x44+8*d);
                    686:                emit_byte(8*index+baser);
                    687:                emit_byte(0);
                    688:                return;
                    689:        }
                    690:        emit_byte(0x04+8*d);
                    691:        emit_byte(8*index+baser);
                    692: }
                    693: LENDFUNC(NONE,READ,3,raw_mov_l_rrm_indexed,(W4 d, R4 baser, R4 index))
                    694: 
                    695:        LOWFUNC(NONE,READ,3,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index))
                    696: {
                    697:        emit_byte(0x66);
                    698:        emit_byte(0x8b);
                    699:        if (baser==5) {
                    700:                emit_byte(0x44+8*d);
                    701:                emit_byte(8*index+baser);
                    702:                emit_byte(0);
                    703:                return;
                    704:        }
                    705:        emit_byte(0x04+8*d);
                    706:        emit_byte(8*index+baser);
                    707: }
                    708: LENDFUNC(NONE,READ,3,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index))
                    709: 
                    710:        LOWFUNC(NONE,READ,3,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index))
                    711: {
                    712:        emit_byte(0x8a);
                    713:        if (baser==5) {
                    714:                emit_byte(0x44+8*d);
                    715:                emit_byte(8*index+baser);
                    716:                emit_byte(0);
                    717:                return;
                    718:        }
                    719:        emit_byte(0x04+8*d);
                    720:        emit_byte(8*index+baser);
                    721: }
                    722: LENDFUNC(NONE,READ,3,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index))
                    723: 
                    724:        LOWFUNC(NONE,WRITE,3,raw_mov_l_mrr_indexed,(R4 baser, R4 index, R4 s))
                    725: {
                    726:        emit_byte(0x89);
                    727:        if (baser==5) {
                    728:                emit_byte(0x44+8*s);
                    729:                emit_byte(8*index+baser);
                    730:                emit_byte(0);
                    731:                return;
                    732:        }
                    733:        emit_byte(0x04+8*s);
                    734:        emit_byte(8*index+baser);
                    735: }
                    736: LENDFUNC(NONE,WRITE,3,raw_mov_l_mrr_indexed,(R4 baser, R4 index, R4 s))
                    737: 
                    738:        LOWFUNC(NONE,WRITE,3,raw_mov_w_mrr_indexed,(R4 baser, R4 index, R2 s))
                    739: {
                    740:        emit_byte(0x66);
                    741:        emit_byte(0x89);
                    742:        if (baser==5) {
                    743:                emit_byte(0x44+8*s);
                    744:                emit_byte(8*index+baser);
                    745:                emit_byte(0);
                    746:                return;
                    747:        }
                    748:        emit_byte(0x04+8*s);
                    749:        emit_byte(8*index+baser);
                    750: }
                    751: LENDFUNC(NONE,WRITE,3,raw_mov_w_mrr_indexed,(R4 baser, R4 index, R2 s))
                    752: 
                    753:        LOWFUNC(NONE,WRITE,3,raw_mov_b_mrr_indexed,(R4 baser, R4 index, R1 s))
                    754: {
                    755:        emit_byte(0x88);
                    756:        if (baser==5) {
                    757:                emit_byte(0x44+8*s);
                    758:                emit_byte(8*index+baser);
                    759:                emit_byte(0);
                    760:                return;
                    761:        }
                    762:        emit_byte(0x04+8*s);
                    763:        emit_byte(8*index+baser);
                    764: }
                    765: LENDFUNC(NONE,WRITE,3,raw_mov_b_mrr_indexed,(R4 baser, R4 index, R1 s))
                    766: 
                    767:        LOWFUNC(NONE,READ,3,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index))
                    768: {
                    769:        emit_byte(0x8b);
                    770:        emit_byte(0x04+8*d);
                    771:        emit_byte(0x85+8*index);
                    772:        emit_long(base);
                    773: }
                    774: LENDFUNC(NONE,READ,3,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index))
                    775: 
                    776:        LOWFUNC(NONE,READ,4,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM cond))
                    777: {
                    778:        if (have_cmov) {
                    779:                emit_byte(0x0f);
                    780:                emit_byte(0x40+cond);
                    781:        }
                    782:        else { /* replacement using branch and mov */
                    783:                int uncc=(cond^1);
                    784:                emit_byte(0x70+uncc);
                    785:                emit_byte(7);  /* skip next 7 bytes if not cc=true */
                    786:                emit_byte(0x8b);
                    787:        }
                    788:        emit_byte(0x04+8*d);
                    789:        emit_byte(0x85+8*index);
                    790:        emit_long(base);
                    791: }
                    792: LENDFUNC(NONE,READ,4,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM cond))
                    793: 
                    794:        LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
                    795: {
                    796:        if (have_cmov) {
                    797:                emit_byte(0x0f);
                    798:                emit_byte(0x40+cond);
                    799:                emit_byte(0x05+8*d);
                    800:                emit_long(mem);
                    801:        }
                    802:        else { /* replacement using branch and mov */
                    803:                int uncc=(cond^1);
                    804:                emit_byte(0x70+uncc);
                    805:                emit_byte(6);  /* skip next 6 bytes if not cc=true */
                    806:                emit_byte(0x8b);
                    807:                emit_byte(0x05+8*d);
                    808:                emit_long(mem);
                    809:        }
                    810: }
                    811: LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
                    812: 
                    813:        LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
                    814: {
                    815:        emit_byte(0x8b);
                    816:        emit_byte(0x40+8*d+s);
                    817:        emit_byte(offset);
                    818: }
                    819: LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
                    820: 
                    821:        LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
                    822: {
                    823:        emit_byte(0x66);
                    824:        emit_byte(0x8b);
                    825:        emit_byte(0x40+8*d+s);
                    826:        emit_byte(offset);
                    827: }
                    828: LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
                    829: 
                    830:        LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
                    831: {
                    832:        emit_byte(0x8a);
                    833:        emit_byte(0x40+8*d+s);
                    834:        emit_byte(offset);
                    835: }
                    836: LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
                    837: 
                    838:        LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
                    839: {
                    840:        emit_byte(0x8b);
                    841:        emit_byte(0x80+8*d+s);
                    842:        emit_long(offset);
                    843: }
                    844: LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
                    845: 
                    846:        LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
                    847: {
                    848:        emit_byte(0x66);
                    849:        emit_byte(0x8b);
                    850:        emit_byte(0x80+8*d+s);
                    851:        emit_long(offset);
                    852: }
                    853: LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
                    854: 
                    855:        LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
                    856: {
                    857:        emit_byte(0x8a);
                    858:        emit_byte(0x80+8*d+s);
                    859:        emit_long(offset);
                    860: }
                    861: LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
                    862: 
                    863:        LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
                    864: {
                    865:        emit_byte(0xc7);
                    866:        emit_byte(0x40+d);
                    867:        emit_byte(offset);
                    868:        emit_long(i);
                    869: }
                    870: LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
                    871: 
                    872:        LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
                    873: {
                    874:        emit_byte(0x66);
                    875:        emit_byte(0xc7);
                    876:        emit_byte(0x40+d);
                    877:        emit_byte(offset);
                    878:        emit_word(i);
                    879: }
                    880: LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
                    881: 
                    882:        LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
                    883: {
                    884:        emit_byte(0xc6);
                    885:        emit_byte(0x40+d);
                    886:        emit_byte(offset);
                    887:        emit_byte(i);
                    888: }
                    889: LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
                    890: 
                    891:        LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
                    892: {
                    893:        emit_byte(0x89);
                    894:        emit_byte(0x40+8*s+d);
                    895:        emit_byte(offset);
                    896: }
                    897: LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
                    898: 
                    899:        LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
                    900: {
                    901:        emit_byte(0x66);
                    902:        emit_byte(0x89);
                    903:        emit_byte(0x40+8*s+d);
                    904:        emit_byte(offset);
                    905: }
                    906: LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
                    907: 
                    908:        LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
                    909: {
                    910:        emit_byte(0x88);
                    911:        emit_byte(0x40+8*s+d);
                    912:        emit_byte(offset);
                    913: }
                    914: LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
                    915: 
                    916:        LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
                    917: {
                    918:        emit_byte(0x8d);
                    919:        emit_byte(0x80+8*d+s);
                    920:        emit_long(offset);
                    921: }
                    922: LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
                    923: 
                    924:        LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
                    925: {
                    926:        emit_byte(0x8d);
                    927:        if (!offset) {
                    928:                if (s!=5) {
                    929:                        emit_byte(0x04+8*d);
                    930:                        emit_byte(0x40*factor+8*index+s);
                    931:                        return;
                    932:                }
                    933:                emit_byte(0x44+8*d);
                    934:                emit_byte(0x40*factor+8*index+s);
                    935:                emit_byte(0);
                    936:                return;
                    937:        }
                    938:        emit_byte(0x84+8*d);
                    939:        emit_byte(0x40*factor+8*index+s);
                    940:        emit_long(offset);
                    941: }
                    942: LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
                    943: 
                    944:        LOWFUNC(NONE,NONE,3,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index))
                    945: {
                    946:        emit_byte(0x8d);
                    947:        if (s==5) {
                    948:                emit_byte(0x44+8*d);
                    949:                emit_byte(8*index+s);
                    950:                emit_byte(0);
                    951:                return;
                    952:        }
                    953:        emit_byte(0x04+8*d);
                    954:        emit_byte(8*index+s);
                    955: }
                    956: LENDFUNC(NONE,NONE,3,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index))
                    957: 
                    958:        LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
                    959: {
                    960:        emit_byte(0x89);
                    961:        emit_byte(0x80+8*s+d);
                    962:        emit_long(offset);
                    963: }
                    964: LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
                    965: 
                    966:        LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
                    967: {
                    968:        emit_byte(0x66);
                    969:        emit_byte(0x89);
                    970:        emit_byte(0x80+8*s+d);
                    971:        emit_long(offset);
                    972: }
                    973: LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
                    974: 
                    975:        LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
                    976: {
                    977:        emit_byte(0x88);
                    978:        emit_byte(0x80+8*s+d);
                    979:        emit_long(offset);
                    980: }
                    981: LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
                    982: 
                    983:        LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
                    984: {
                    985:        emit_byte(0x0f);
                    986:        emit_byte(0xc8+r);
                    987: }
                    988: LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
                    989: 
                    990:        LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
                    991: {
                    992:        emit_byte(0x66);
                    993:        emit_byte(0xc1);
                    994:        emit_byte(0xc0+r);
                    995:        emit_byte(0x08);
                    996: }
                    997: LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
                    998: 
                    999:        LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
                   1000: {
                   1001:        emit_byte(0x89);
                   1002:        emit_byte(0xc0+8*s+d);
                   1003: }
                   1004: LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
                   1005: 
                   1006:        LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
                   1007: {
                   1008:        emit_byte(0x89);
                   1009:        emit_byte(0x05+8*s);
                   1010:        emit_long(d);
                   1011: }
                   1012: LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
                   1013: 
                   1014:        LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
                   1015: {
                   1016:        emit_byte(0x8b);
                   1017:        emit_byte(0x05+8*d);
                   1018:        emit_long(s);
                   1019: }
                   1020: LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
                   1021: 
                   1022:        LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
                   1023: {
                   1024:        emit_byte(0x66);
                   1025:        emit_byte(0x89);
                   1026:        emit_byte(0x05+8*s);
                   1027:        emit_long(d);
                   1028: }
                   1029: LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
                   1030: 
                   1031:        LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
                   1032: {
                   1033:        emit_byte(0x66);
                   1034:        emit_byte(0x8b);
                   1035:        emit_byte(0x05+8*d);
                   1036:        emit_long(s);
                   1037: }
                   1038: LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
                   1039: 
                   1040:        LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
                   1041: {
                   1042:        emit_byte(0x88);
                   1043:        emit_byte(0x05+8*s);
                   1044:        emit_long(d);
                   1045: }
                   1046: LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
                   1047: 
                   1048:        LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
                   1049: {
                   1050:        emit_byte(0x8a);
                   1051:        emit_byte(0x05+8*d);
                   1052:        emit_long(s);
                   1053: }
                   1054: LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
                   1055: 
                   1056:        LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
                   1057: {
                   1058:        emit_byte(0xb8+d);
                   1059:        emit_long(s);
                   1060: }
                   1061: LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
                   1062: 
                   1063:        LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
                   1064: {
                   1065:        emit_byte(0x66);
                   1066:        emit_byte(0xb8+d);
                   1067:        emit_word(s);
                   1068: }
                   1069: LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
                   1070: 
                   1071:        LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
                   1072: {
                   1073:        emit_byte(0xb0+d);
                   1074:        emit_byte(s);
                   1075: }
                   1076: LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
                   1077: 
                   1078:        LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
                   1079: {
                   1080:        emit_byte(0x81);
                   1081:        emit_byte(0x15);
                   1082:        emit_long(d);
                   1083:        emit_long(s);
                   1084: }
                   1085: LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
                   1086: 
                   1087:        LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
                   1088: {
                   1089:        emit_byte(0x81);
                   1090:        emit_byte(0x05);
                   1091:        emit_long(d);
                   1092:        emit_long(s);
                   1093: }
                   1094: LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
                   1095: 
                   1096:        LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
                   1097: {
                   1098:        emit_byte(0x66);
                   1099:        emit_byte(0x81);
                   1100:        emit_byte(0x05);
                   1101:        emit_long(d);
                   1102:        emit_word(s);
                   1103: }
                   1104: LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
                   1105: 
                   1106:        LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
                   1107: {
                   1108:        emit_byte(0x80);
                   1109:        emit_byte(0x05);
                   1110:        emit_long(d);
                   1111:        emit_byte(s);
                   1112: }
                   1113: LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
                   1114: 
                   1115:        LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
                   1116: {
                   1117:        emit_byte(0xf7);
                   1118:        emit_byte(0xc0+d);
                   1119:        emit_long(i);
                   1120: }
                   1121: LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
                   1122: 
                   1123:        LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
                   1124: {
                   1125:        emit_byte(0x85);
                   1126:        emit_byte(0xc0+8*s+d);
                   1127: }
                   1128: LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
                   1129: 
                   1130:        LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
                   1131: {
                   1132:        emit_byte(0x66);
                   1133:        emit_byte(0x85);
                   1134:        emit_byte(0xc0+8*s+d);
                   1135: }
                   1136: LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
                   1137: 
                   1138:        LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
                   1139: {
                   1140:        emit_byte(0x84);
                   1141:        emit_byte(0xc0+8*s+d);
                   1142: }
                   1143: LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
                   1144: 
                   1145:        LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
                   1146: {
                   1147:        emit_byte(0x81);
                   1148:        emit_byte(0xe0+d);
                   1149:        emit_long(i);
                   1150: }
                   1151: LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
                   1152: 
                   1153:        LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
                   1154: {
                   1155:        emit_byte(0x66);
                   1156:        emit_byte(0x81);
                   1157:        emit_byte(0xe0+d);
                   1158:        emit_word(i);
                   1159: }
                   1160: LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
                   1161: 
                   1162:        LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
                   1163: {
                   1164:        emit_byte(0x21);
                   1165:        emit_byte(0xc0+8*s+d);
                   1166: }
                   1167: LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
                   1168: 
                   1169:        LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
                   1170: {
                   1171:        emit_byte(0x66);
                   1172:        emit_byte(0x21);
                   1173:        emit_byte(0xc0+8*s+d);
                   1174: }
                   1175: LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
                   1176: 
                   1177:        LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
                   1178: {
                   1179:        emit_byte(0x20);
                   1180:        emit_byte(0xc0+8*s+d);
                   1181: }
                   1182: LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
                   1183: 
                   1184:        LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
                   1185: {
                   1186:        emit_byte(0x81);
                   1187:        emit_byte(0xc8+d);
                   1188:        emit_long(i);
                   1189: }
                   1190: LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
                   1191: 
                   1192:        LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
                   1193: {
                   1194:        emit_byte(0x09);
                   1195:        emit_byte(0xc0+8*s+d);
                   1196: }
                   1197: LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
                   1198: 
                   1199:        LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
                   1200: {
                   1201:        emit_byte(0x66);
                   1202:        emit_byte(0x09);
                   1203:        emit_byte(0xc0+8*s+d);
                   1204: }
                   1205: LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
                   1206: 
                   1207:        LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
                   1208: {
                   1209:        emit_byte(0x08);
                   1210:        emit_byte(0xc0+8*s+d);
                   1211: }
                   1212: LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
                   1213: 
                   1214:        LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
                   1215: {
                   1216:        emit_byte(0x11);
                   1217:        emit_byte(0xc0+8*s+d);
                   1218: }
                   1219: LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
                   1220: 
                   1221:        LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
                   1222: {
                   1223:        emit_byte(0x66);
                   1224:        emit_byte(0x11);
                   1225:        emit_byte(0xc0+8*s+d);
                   1226: }
                   1227: LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
                   1228: 
                   1229:        LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
                   1230: {
                   1231:        emit_byte(0x10);
                   1232:        emit_byte(0xc0+8*s+d);
                   1233: }
                   1234: LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
                   1235: 
                   1236:        LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
                   1237: {
                   1238:        emit_byte(0x01);
                   1239:        emit_byte(0xc0+8*s+d);
                   1240: }
                   1241: LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
                   1242: 
                   1243:        LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
                   1244: {
                   1245:        emit_byte(0x66);
                   1246:        emit_byte(0x01);
                   1247:        emit_byte(0xc0+8*s+d);
                   1248: }
                   1249: LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
                   1250: 
                   1251:        LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
                   1252: {
                   1253:        emit_byte(0x00);
                   1254:        emit_byte(0xc0+8*s+d);
                   1255: }
                   1256: LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
                   1257: 
                   1258:        LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
                   1259: {
                   1260:        if (isbyte(i)) {
                   1261:                emit_byte(0x83);
                   1262:                emit_byte(0xe8+d);
                   1263:                emit_byte(i);
                   1264:        }
                   1265:        else {
                   1266:                emit_byte(0x81);
                   1267:                emit_byte(0xe8+d);
                   1268:                emit_long(i);
                   1269:        }
                   1270: }
                   1271: LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
                   1272: 
                   1273:        LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
                   1274: {
                   1275:        emit_byte(0x80);
                   1276:        emit_byte(0xe8+d);
                   1277:        emit_byte(i);
                   1278: }
                   1279: LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
                   1280: 
                   1281:        LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
                   1282: {
                   1283:        if (isbyte(i)) {
                   1284:                emit_byte(0x83);
                   1285:                emit_byte(0xc0+d);
                   1286:                emit_byte(i);
                   1287:        }
                   1288:        else {
                   1289:                emit_byte(0x81);
                   1290:                emit_byte(0xc0+d);
                   1291:                emit_long(i);
                   1292:        }
                   1293: }
                   1294: LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
                   1295: 
                   1296:        LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
                   1297: {
                   1298:        if (isbyte(i)) {
                   1299:                emit_byte(0x66);
                   1300:                emit_byte(0x83);
                   1301:                emit_byte(0xc0+d);
                   1302:                emit_byte(i);
                   1303:        }
                   1304:        else {
                   1305:                emit_byte(0x66);
                   1306:                emit_byte(0x81);
                   1307:                emit_byte(0xc0+d);
                   1308:                emit_word(i);
                   1309:        }
                   1310: }
                   1311: LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
                   1312: 
                   1313:        LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
                   1314: {
                   1315:        emit_byte(0x80);
                   1316:        emit_byte(0xc0+d);
                   1317:        emit_byte(i);
                   1318: }
                   1319: LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
                   1320: 
                   1321:        LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
                   1322: {
                   1323:        emit_byte(0x19);
                   1324:        emit_byte(0xc0+8*s+d);
                   1325: }
                   1326: LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
                   1327: 
                   1328:        LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
                   1329: {
                   1330:        emit_byte(0x66);
                   1331:        emit_byte(0x19);
                   1332:        emit_byte(0xc0+8*s+d);
                   1333: }
                   1334: LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
                   1335: 
                   1336:        LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
                   1337: {
                   1338:        emit_byte(0x18);
                   1339:        emit_byte(0xc0+8*s+d);
                   1340: }
                   1341: LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
                   1342: 
                   1343:        LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
                   1344: {
                   1345:        emit_byte(0x29);
                   1346:        emit_byte(0xc0+8*s+d);
                   1347: }
                   1348: LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
                   1349: 
                   1350:        LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
                   1351: {
                   1352:        emit_byte(0x66);
                   1353:        emit_byte(0x29);
                   1354:        emit_byte(0xc0+8*s+d);
                   1355: }
                   1356: LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
                   1357: 
                   1358:        LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
                   1359: {
                   1360:        emit_byte(0x28);
                   1361:        emit_byte(0xc0+8*s+d);
                   1362: }
                   1363: LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
                   1364: 
                   1365:        LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
                   1366: {
                   1367:        emit_byte(0x39);
                   1368:        emit_byte(0xc0+8*s+d);
                   1369: }
                   1370: LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
                   1371: 
                   1372:        LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
                   1373: {
                   1374:        emit_byte(0x81);
                   1375:        emit_byte(0xf8+r);
                   1376:        emit_long(i);
                   1377: }
                   1378: LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
                   1379: 
                   1380:        LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
                   1381: {
                   1382:        emit_byte(0x66);
                   1383:        emit_byte(0x39);
                   1384:        emit_byte(0xc0+8*s+d);
                   1385: }
                   1386: LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
                   1387: 
                   1388:        LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
                   1389: {
                   1390:        emit_byte(0x80);
                   1391:        emit_byte(0xf8+d);
                   1392:        emit_byte(i);
                   1393: }
                   1394: LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
                   1395: 
                   1396:        LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
                   1397: {
                   1398:        emit_byte(0x38);
                   1399:        emit_byte(0xc0+8*s+d);
                   1400: }
                   1401: LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
                   1402: 
                   1403:        LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
                   1404: {
                   1405:        emit_byte(0x31);
                   1406:        emit_byte(0xc0+8*s+d);
                   1407: }
                   1408: LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
                   1409: 
                   1410:        LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
                   1411: {
                   1412:        emit_byte(0x66);
                   1413:        emit_byte(0x31);
                   1414:        emit_byte(0xc0+8*s+d);
                   1415: }
                   1416: LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
                   1417: 
                   1418:        LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
                   1419: {
                   1420:        emit_byte(0x30);
                   1421:        emit_byte(0xc0+8*s+d);
                   1422: }
                   1423: LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
                   1424: 
                   1425:        LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
                   1426: {
                   1427:        emit_byte(0x81);
                   1428:        emit_byte(0x2d);
                   1429:        emit_long(d);
                   1430:        emit_long(s);
                   1431: }
                   1432: LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
                   1433: 
                   1434:        LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
                   1435: {
                   1436:        emit_byte(0x81);
                   1437:        emit_byte(0x3d);
                   1438:        emit_long(d);
                   1439:        emit_long(s);
                   1440: }
                   1441: LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
                   1442: 
                   1443:        LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
                   1444: {
                   1445:        emit_byte(0x87);
                   1446:        emit_byte(0xc0+8*r1+r2);
                   1447: }
                   1448: LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
                   1449: 
                   1450:        LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
                   1451: {
                   1452:        emit_byte(0x9c);
                   1453: }
                   1454: LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
                   1455: 
                   1456:        LOWFUNC(WRITE,READ,0,raw_popfl,(void))
                   1457: {
                   1458:        emit_byte(0x9d);
                   1459: }
                   1460: LENDFUNC(WRITE,READ,0,raw_popfl,(void))
                   1461: 
                   1462:        /*************************************************************************
                   1463:        * Unoptimizable stuff --- jump                                          *
                   1464:        *************************************************************************/
                   1465: 
                   1466:        STATIC_INLINE void raw_call_r(R4 r)
                   1467: {
                   1468:        lopt_emit_all();
                   1469:        emit_byte(0xff);
                   1470:        emit_byte(0xd0+r);
                   1471: }
                   1472: 
                   1473: STATIC_INLINE void raw_jmp_r(R4 r)
                   1474: {
                   1475:        lopt_emit_all();
                   1476:        emit_byte(0xff);
                   1477:        emit_byte(0xe0+r);
                   1478: }
                   1479: 
                   1480: STATIC_INLINE void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
                   1481: {
                   1482:        int sib;
                   1483: 
                   1484:        switch (m) {
                   1485:        case 1: sib = 0x05; break;
                   1486:        case 2: sib = 0x45; break;
                   1487:        case 4: sib = 0x85; break;
                   1488:        case 8: sib = 0xC5; break;
                   1489:        default: abort();
                   1490:        }
                   1491:        lopt_emit_all();
                   1492:        emit_byte(0xff);
                   1493:        emit_byte(0x24);
                   1494:        emit_byte(8*r+sib);
                   1495:        emit_long(base);
                   1496: }
                   1497: 
                   1498: STATIC_INLINE void raw_jmp_m(uae_u32 base)
                   1499: {
                   1500:        lopt_emit_all();
                   1501:        emit_byte(0xff);
                   1502:        emit_byte(0x25);
                   1503:        emit_long(base);
                   1504: }
                   1505: 
                   1506: STATIC_INLINE void raw_call(uae_u32 t)
                   1507: {
                   1508:        lopt_emit_all();
                   1509:        emit_byte(0xe8);
                   1510:        emit_long(t-(uae_u32)target-4);
                   1511: }
                   1512: 
                   1513: STATIC_INLINE void raw_jmp(uae_u32 t)
                   1514: {
                   1515:        lopt_emit_all();
                   1516:        emit_byte(0xe9);
                   1517:        emit_long(t-(uae_u32)target-4);
                   1518: }
                   1519: 
                   1520: STATIC_INLINE void raw_jl(uae_u32 t)
                   1521: {
                   1522:        lopt_emit_all();
                   1523:        emit_byte(0x0f);
                   1524:        emit_byte(0x8c);
                   1525:        emit_long(t-(uae_u32)target-4);
                   1526: }
                   1527: 
                   1528: STATIC_INLINE void raw_jz(uae_u32 t)
                   1529: {
                   1530:        lopt_emit_all();
                   1531:        emit_byte(0x0f);
                   1532:        emit_byte(0x84);
                   1533:        emit_long(t-(uae_u32)target-4);
                   1534: }
                   1535: 
                   1536: STATIC_INLINE void raw_jnz(uae_u32 t)
                   1537: {
                   1538:        lopt_emit_all();
                   1539:        emit_byte(0x0f);
                   1540:        emit_byte(0x85);
                   1541:        emit_long(t-(uae_u32)target-4);
                   1542: }
                   1543: 
                   1544: STATIC_INLINE void raw_jnz_l_oponly(void)
                   1545: {
                   1546:        lopt_emit_all();
                   1547:        emit_byte(0x0f);
                   1548:        emit_byte(0x85);
                   1549: }
                   1550: 
                   1551: STATIC_INLINE void raw_jcc_l_oponly(int cc)
                   1552: {
                   1553:        lopt_emit_all();
                   1554:        emit_byte(0x0f);
                   1555:        emit_byte(0x80+cc);
                   1556: }
                   1557: 
                   1558: STATIC_INLINE void raw_jnz_b_oponly(void)
                   1559: {
                   1560:        lopt_emit_all();
                   1561:        emit_byte(0x75);
                   1562: }
                   1563: 
                   1564: STATIC_INLINE void raw_jz_b_oponly(void)
                   1565: {
                   1566:        lopt_emit_all();
                   1567:        emit_byte(0x74);
                   1568: }
                   1569: 
                   1570: STATIC_INLINE void raw_jmp_l_oponly(void)
                   1571: {
                   1572:        lopt_emit_all();
                   1573:        emit_byte(0xe9);
                   1574: }
                   1575: 
                   1576: STATIC_INLINE void raw_jmp_b_oponly(void)
                   1577: {
                   1578:        lopt_emit_all();
                   1579:        emit_byte(0xeb);
                   1580: }
                   1581: 
                   1582: STATIC_INLINE void raw_ret(void)
                   1583: {
                   1584:        lopt_emit_all();
                   1585:        emit_byte(0xc3);
                   1586: }
                   1587: 
                   1588: STATIC_INLINE void raw_nop(void)
                   1589: {
                   1590:        lopt_emit_all();
                   1591:        emit_byte(0x90);
                   1592: }
                   1593: 
                   1594: 
                   1595: /*************************************************************************
                   1596: * Flag handling, to and fro UAE flag register                           *
                   1597: *************************************************************************/
                   1598: 
                   1599: 
                   1600: #define FLAG_NREG1 0  /* Set to -1 if any register will do */
                   1601: 
                   1602: STATIC_INLINE void raw_flags_to_reg(int r)
                   1603: {
                   1604:        raw_lahf(0);  /* Most flags in AH */
                   1605:        //raw_setcc(r,0); /* V flag in AL */
                   1606:        raw_setcc_m((uae_u32)live.state[FLAGTMP].mem,0);
                   1607: 
                   1608: #if 1   /* Let's avoid those nasty partial register stalls */
                   1609:        //raw_mov_b_mr((uae_u32)live.state[FLAGTMP].mem,r);
                   1610:        raw_mov_b_mr(((uae_u32)live.state[FLAGTMP].mem)+1,r+4);
                   1611:        //live.state[FLAGTMP].status=CLEAN;
                   1612:        live.state[FLAGTMP].status=INMEM;
                   1613:        live.state[FLAGTMP].realreg=-1;
                   1614:        /* We just "evicted" FLAGTMP. */
                   1615:        if (live.nat[r].nholds!=1) {
                   1616:                /* Huh? */
                   1617:                abort();
                   1618:        }
                   1619:        live.nat[r].nholds=0;
                   1620: #endif
                   1621: }
                   1622: 
                   1623: #define FLAG_NREG2 0  /* Set to -1 if any register will do */
                   1624: STATIC_INLINE void raw_reg_to_flags(int r)
                   1625: {
                   1626:        raw_cmp_b_ri(r,-127); /* set V */
                   1627:        raw_sahf(0);
                   1628: }
                   1629: 
                   1630: /* Apparently, there are enough instructions between flag store and
                   1631: flag reload to avoid the partial memory stall */
                   1632: STATIC_INLINE void raw_load_flagreg(uae_u32 target, uae_u32 r)
                   1633: {
                   1634: #if 1
                   1635:        raw_mov_l_rm(target,(uae_u32)live.state[r].mem);
                   1636: #else
                   1637:        raw_mov_b_rm(target,(uae_u32)live.state[r].mem);
                   1638:        raw_mov_b_rm(target+4,((uae_u32)live.state[r].mem)+1);
                   1639: #endif
                   1640: }
                   1641: 
                   1642: /* FLAGX is word-sized */
                   1643: STATIC_INLINE void raw_load_flagx(uae_u32 target, uae_u32 r)
                   1644: {
                   1645:        if (live.nat[target].canword)
                   1646:                raw_mov_w_rm(target,(uae_u32)live.state[r].mem);
                   1647:        else
                   1648:                raw_mov_l_rm(target,(uae_u32)live.state[r].mem);
                   1649: }
                   1650: 
                   1651: #define NATIVE_FLAG_Z 0x40
                   1652: #define NATIVE_CC_EQ  4
                   1653: STATIC_INLINE void raw_flags_set_zero(int f, int r, int t)
                   1654: {
                   1655:        // FIXME: this is really suboptimal
                   1656:        raw_pushfl();
                   1657:        raw_pop_l_r(f);
                   1658:        raw_and_l_ri(f,~NATIVE_FLAG_Z);
                   1659:        raw_test_l_rr(r,r);
                   1660:        raw_mov_l_ri(r,0);
                   1661:        raw_mov_l_ri(t,NATIVE_FLAG_Z);
                   1662:        raw_cmov_l_rr(r,t,NATIVE_CC_EQ);
                   1663:        raw_or_l(f,r);
                   1664:        raw_push_l_r(f);
                   1665:        raw_popfl();
                   1666: }
                   1667: 
                   1668: STATIC_INLINE void raw_inc_sp(int off)
                   1669: {
                   1670:        raw_add_l_ri(4,off);
                   1671: }
                   1672: 
                   1673: /*************************************************************************
                   1674: * Handling mistaken direct memory access                                *
                   1675: *************************************************************************/
                   1676: 
                   1677: 
                   1678: #ifdef NATMEM_OFFSET
                   1679: #ifdef _WIN32 // %%% BRIAN KING WAS HERE %%%
                   1680: #include <winbase.h>
                   1681: #else
                   1682: #include <asm/sigcontext.h>
                   1683: #endif
                   1684: #include <signal.h>
                   1685: 
                   1686: #define SIG_READ 1
                   1687: #define SIG_WRITE 2
                   1688: 
                   1689: static int in_handler=0;
                   1690: static uae_u8 *veccode;
                   1691: 
                   1692: #ifdef _WIN32
                   1693: 
                   1694: #if defined(CPU_64_BIT)
                   1695: #define ctxPC (pContext->Rip)
                   1696: #else
                   1697: #define ctxPC (pContext->Eip)
                   1698: #endif
                   1699: 
                   1700: int EvalException (LPEXCEPTION_POINTERS blah, int n_except)
                   1701: {
                   1702:        PEXCEPTION_RECORD pExceptRecord = NULL;
                   1703:        PCONTEXT          pContext = NULL;
                   1704: 
                   1705:        uae_u8* i = NULL;
                   1706:        uae_u32 addr = 0;
                   1707:        int r=-1;
                   1708:        int size=4;
                   1709:        int dir=-1;
                   1710:        int len=0;
                   1711: 
                   1712:        if (n_except != STATUS_ACCESS_VIOLATION || !canbang || currprefs.cachesize == 0)
                   1713:                return EXCEPTION_CONTINUE_SEARCH;
                   1714: 
                   1715:        pExceptRecord = blah->ExceptionRecord;
                   1716:        pContext = blah->ContextRecord;
                   1717: 
                   1718:        if (pContext)
                   1719:                i = (uae_u8 *)ctxPC;
                   1720:        if (pExceptRecord)
                   1721:                addr = (uae_u32)(pExceptRecord->ExceptionInformation[1]);
                   1722: #ifdef JIT_DEBUG
                   1723:        write_log (L"JIT: fault address is 0x%x at 0x%x\n",addr,i);
                   1724: #endif
                   1725:        if (!canbang || !currprefs.cachesize)
                   1726:                return EXCEPTION_CONTINUE_SEARCH;
                   1727: 
                   1728:        if (in_handler)
                   1729:                write_log (L"JIT: Argh --- Am already in a handler. Shouldn't happen!\n");
                   1730: 
                   1731:        if (canbang && i>=compiled_code && i<=current_compile_p) {
                   1732:                if (*i==0x66) {
                   1733:                        i++;
                   1734:                        size=2;
                   1735:                        len++;
                   1736:                }
                   1737: 
                   1738:                switch(i[0]) {
                   1739:                case 0x8a:
                   1740:                        if ((i[1]&0xc0)==0x80) {
                   1741:                                r=(i[1]>>3)&7;
                   1742:                                dir=SIG_READ;
                   1743:                                size=1;
                   1744:                                len+=6;
                   1745:                                break;
                   1746:                        }
                   1747:                        break;
                   1748:                case 0x88:
                   1749:                        if ((i[1]&0xc0)==0x80) {
                   1750:                                r=(i[1]>>3)&7;
                   1751:                                dir=SIG_WRITE;
                   1752:                                size=1;
                   1753:                                len+=6;
                   1754:                                break;
                   1755:                        }
                   1756:                        break;
                   1757:                case 0x8b:
                   1758:                        switch(i[1]&0xc0) {
                   1759:                        case 0x80:
                   1760:                                r=(i[1]>>3)&7;
                   1761:                                dir=SIG_READ;
                   1762:                                len+=6;
                   1763:                                break;
                   1764:                        case 0x40:
                   1765:                                r=(i[1]>>3)&7;
                   1766:                                dir=SIG_READ;
                   1767:                                len+=3;
                   1768:                                break;
                   1769:                        case 0x00:
                   1770:                                r=(i[1]>>3)&7;
                   1771:                                dir=SIG_READ;
                   1772:                                len+=2;
                   1773:                                break;
                   1774:                        default:
                   1775:                                break;
                   1776:                        }
                   1777:                        break;
                   1778:                case 0x89:
                   1779:                        switch(i[1]&0xc0) {
                   1780:                        case 0x80:
                   1781:                                r=(i[1]>>3)&7;
                   1782:                                dir=SIG_WRITE;
                   1783:                                len+=6;
                   1784:                                break;
                   1785:                        case 0x40:
                   1786:                                r=(i[1]>>3)&7;
                   1787:                                dir=SIG_WRITE;
                   1788:                                len+=3;
                   1789:                                break;
                   1790:                        case 0x00:
                   1791:                                r=(i[1]>>3)&7;
                   1792:                                dir=SIG_WRITE;
                   1793:                                len+=2;
                   1794:                                break;
                   1795:                        }
                   1796:                        break;
                   1797:                }
                   1798:        }
                   1799: 
                   1800:        if (r!=-1) {
                   1801:                void* pr=NULL;
                   1802: #ifdef JIT_DEBUG
                   1803:                write_log (L"JIT: register was %d, direction was %d, size was %d\n",r,dir,size);
                   1804: #endif
                   1805: 
                   1806:                switch(r) {
                   1807: #if defined(CPU_64_BIT)
                   1808:                case 0: pr=&(pContext->Rax); break;
                   1809:                case 1: pr=&(pContext->Rcx); break;
                   1810:                case 2: pr=&(pContext->Rdx); break;
                   1811:                case 3: pr=&(pContext->Rbx); break;
                   1812:                case 4: pr=(size>1)?NULL:(((uae_u8*)&(pContext->Rax))+1); break;
                   1813:                case 5: pr=(size>1)?
                   1814:                                        (void*)(&(pContext->Rbp)):
                   1815:                        (void*)(((uae_u8*)&(pContext->Rcx))+1); break;
                   1816:                case 6: pr=(size>1)?
                   1817:                                        (void*)(&(pContext->Rsi)):
                   1818:                        (void*)(((uae_u8*)&(pContext->Rdx))+1); break;
                   1819:                case 7: pr=(size>1)?
                   1820:                                        (void*)(&(pContext->Rdi)):
                   1821:                        (void*)(((uae_u8*)&(pContext->Rbx))+1); break;
                   1822: #else
                   1823:                case 0: pr=&(pContext->Eax); break;
                   1824:                case 1: pr=&(pContext->Ecx); break;
                   1825:                case 2: pr=&(pContext->Edx); break;
                   1826:                case 3: pr=&(pContext->Ebx); break;
                   1827:                case 4: pr=(size>1)?NULL:(((uae_u8*)&(pContext->Eax))+1); break;
                   1828:                case 5: pr=(size>1)?
                   1829:                                        (void*)(&(pContext->Ebp)):
                   1830:                        (void*)(((uae_u8*)&(pContext->Ecx))+1); break;
                   1831:                case 6: pr=(size>1)?
                   1832:                                        (void*)(&(pContext->Esi)):
                   1833:                        (void*)(((uae_u8*)&(pContext->Edx))+1); break;
                   1834:                case 7: pr=(size>1)?
                   1835:                                        (void*)(&(pContext->Edi)):
                   1836:                        (void*)(((uae_u8*)&(pContext->Ebx))+1); break;
                   1837: #endif
                   1838:                default: abort();
                   1839:                }
                   1840:                if (pr) {
                   1841:                        blockinfo* bi;
                   1842: 
                   1843:                        if (currprefs.comp_oldsegv) {
                   1844:                                addr-=(uae_u32)NATMEM_OFFSET;
                   1845: 
                   1846: #ifdef JIT_DEBUG
                   1847:                                if ((addr>=0x10000000 && addr<0x40000000) ||
                   1848:                                        (addr>=0x50000000)) {
                   1849:                                                write_log (L"JIT: Suspicious address 0x%x in SEGV handler.\n",addr);
                   1850:                                }
                   1851: #endif
                   1852:                                if (dir==SIG_READ) {
                   1853:                                        switch (size) {
                   1854:                                        case 1: *((uae_u8*)pr)=get_byte (addr); break;
                   1855:                                        case 2: *((uae_u16*)pr)=swap16(get_word (addr)); break;
                   1856:                                        case 4: *((uae_u32*)pr)=swap32(get_long (addr)); break;
                   1857:                                        default: abort();
                   1858:                                        }
                   1859:                                }
                   1860:                                else { /* write */
                   1861:                                        switch (size) {
                   1862:                                        case 1: put_byte (addr,*((uae_u8*)pr)); break;
                   1863:                                        case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
                   1864:                                        case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
                   1865:                                        default: abort();
                   1866:                                        }
                   1867:                                }
                   1868: #ifdef JIT_DEBUG
                   1869:                                write_log (L"JIT: Handled one access!\n");
                   1870: #endif
                   1871:                                fflush(stdout);
                   1872:                                segvcount++;
                   1873:                                ctxPC+=len;
                   1874:                        }
                   1875:                        else {
                   1876:                                void* tmp=target;
                   1877:                                int i;
                   1878:                                uae_u8 vecbuf[5];
                   1879: 
                   1880:                                addr-=(uae_u32)NATMEM_OFFSET;
                   1881: 
                   1882: #ifdef JIT_DEBUG
                   1883:                                if ((addr>=0x10000000 && addr<0x40000000) ||
                   1884:                                        (addr>=0x50000000)) {
                   1885:                                                write_log (L"JIT: Suspicious address 0x%x in SEGV handler.\n",addr);
                   1886:                                }
                   1887: #endif
                   1888: 
                   1889:                                target=(uae_u8*)ctxPC;
                   1890:                                for (i=0;i<5;i++)
                   1891:                                        vecbuf[i]=target[i];
                   1892:                                emit_byte(0xe9);
                   1893:                                emit_long((uae_u32)veccode-(uae_u32)target-4);
                   1894: #ifdef JIT_DEBUG
                   1895: 
                   1896:                                write_log (L"JIT: Create jump to %p\n",veccode);
                   1897:                                write_log (L"JIT: Handled one access!\n");
                   1898: #endif
                   1899:                                segvcount++;
                   1900: 
                   1901:                                target=veccode;
                   1902: 
                   1903:                                if (dir==SIG_READ) {
                   1904:                                        switch(size) {
                   1905:                                        case 1: raw_mov_b_ri(r,get_byte (addr)); break;
                   1906:                                        case 2: raw_mov_w_ri(r,swap16(get_word (addr))); break;
                   1907:                                        case 4: raw_mov_l_ri(r,swap32(get_long (addr))); break;
                   1908:                                        default: abort();
                   1909:                                        }
                   1910:                                }
                   1911:                                else { /* write */
                   1912:                                        switch(size) {
                   1913:                                        case 1: put_byte (addr,*((uae_u8*)pr)); break;
                   1914:                                        case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
                   1915:                                        case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
                   1916:                                        default: abort();
                   1917:                                        }
                   1918:                                }
                   1919:                                for (i=0;i<5;i++)
                   1920:                                        raw_mov_b_mi(ctxPC+i,vecbuf[i]);
                   1921:                                raw_mov_l_mi((uae_u32)&in_handler,0);
                   1922:                                emit_byte(0xe9);
                   1923:                                emit_long(ctxPC+len-(uae_u32)target-4);
                   1924:                                in_handler=1;
                   1925:                                target=(uae_u8*)tmp;
                   1926:                        }
                   1927:                        bi=active;
                   1928:                        while (bi) {
                   1929:                                if (bi->handler &&
                   1930:                                        (uae_u8*)bi->direct_handler<=i &&
                   1931:                                        (uae_u8*)bi->nexthandler>i) {
                   1932: #ifdef JIT_DEBUG
                   1933:                                                write_log (L"JIT: deleted trigger (%p<%p<%p) %p\n",
                   1934:                                                        bi->handler,
                   1935:                                                        i,
                   1936:                                                        bi->nexthandler,
                   1937:                                                        bi->pc_p);
                   1938: #endif
                   1939:                                                invalidate_block(bi);
                   1940:                                                raise_in_cl_list(bi);
                   1941:                                                set_special(0);
                   1942:                                                return EXCEPTION_CONTINUE_EXECUTION;
                   1943:                                }
                   1944:                                bi=bi->next;
                   1945:                        }
                   1946:                        /* Not found in the active list. Might be a rom routine that
                   1947:                        is in the dormant list */
                   1948:                        bi=dormant;
                   1949:                        while (bi) {
                   1950:                                if (bi->handler &&
                   1951:                                        (uae_u8*)bi->direct_handler<=i &&
                   1952:                                        (uae_u8*)bi->nexthandler>i) {
                   1953: #ifdef JIT_DEBUG
                   1954:                                                write_log (L"JIT: deleted trigger (%p<%p<%p) %p\n",
                   1955:                                                        bi->handler,
                   1956:                                                        i,
                   1957:                                                        bi->nexthandler,
                   1958:                                                        bi->pc_p);
                   1959: #endif
                   1960:                                                invalidate_block(bi);
                   1961:                                                raise_in_cl_list(bi);
                   1962:                                                set_special(0);
                   1963:                                                return EXCEPTION_CONTINUE_EXECUTION;
                   1964:                                }
                   1965:                                bi=bi->next;
                   1966:                        }
                   1967: #ifdef JIT_DEBUG
                   1968:                        write_log (L"JIT: Huh? Could not find trigger!\n");
                   1969: #endif
                   1970:                        return EXCEPTION_CONTINUE_EXECUTION;
                   1971:                }
                   1972:        }
                   1973:        write_log (L"JIT: Can't handle access %08X!\n", i);
                   1974: #if 0
                   1975:        if (i)
                   1976:        {
                   1977:                int j;
                   1978: 
                   1979:                for (j=0;j<10;j++) {
                   1980:                        write_log (L"JIT: instruction byte %2d is 0x%02x\n",j,i[j]);
                   1981:                }
                   1982:        }
                   1983:        write_log (L"Please send the above info (starting at \"fault address\") to\n"
                   1984:                L"[email protected]\n"
                   1985:                L"This shouldn't happen ;-)\n");
                   1986: #endif
                   1987:        return EXCEPTION_CONTINUE_SEARCH;
                   1988: }
                   1989: #else
                   1990: static void vec(int x, struct sigcontext sc)
                   1991: {
                   1992:        uae_u8* i=(uae_u8*)sc.eip;
                   1993:        uae_u32 addr=sc.cr2;
                   1994:        int r=-1;
                   1995:        int size=4;
                   1996:        int dir=-1;
                   1997:        int len=0;
                   1998:        int j;
                   1999: 
                   2000:        write_log (L"JIT: fault address is %08x at %08x\n",sc.cr2,sc.eip);
                   2001:        if (!canbang)
                   2002:                write_log (L"JIT: Not happy! Canbang is 0 in SIGSEGV handler!\n");
                   2003:        if (in_handler)
                   2004:                write_log (L"JIT: Argh --- Am already in a handler. Shouldn't happen!\n");
                   2005: 
                   2006:        if (canbang && i>=compiled_code && i<=current_compile_p) {
                   2007:                if (*i==0x66) {
                   2008:                        i++;
                   2009:                        size=2;
                   2010:                        len++;
                   2011:                }
                   2012: 
                   2013:                switch(i[0]) {
                   2014:                case 0x8a:
                   2015:                        if ((i[1]&0xc0)==0x80) {
                   2016:                                r=(i[1]>>3)&7;
                   2017:                                dir=SIG_READ;
                   2018:                                size=1;
                   2019:                                len+=6;
                   2020:                                break;
                   2021:                        }
                   2022:                        break;
                   2023:                case 0x88:
                   2024:                        if ((i[1]&0xc0)==0x80) {
                   2025:                                r=(i[1]>>3)&7;
                   2026:                                dir=SIG_WRITE;
                   2027:                                size=1;
                   2028:                                len+=6;
                   2029:                                break;
                   2030:                        }
                   2031:                        break;
                   2032: 
                   2033:                case 0x8b:
                   2034:                        switch(i[1]&0xc0) {
                   2035:                        case 0x80:
                   2036:                                r=(i[1]>>3)&7;
                   2037:                                dir=SIG_READ;
                   2038:                                len+=6;
                   2039:                                break;
                   2040:                        case 0x40:
                   2041:                                r=(i[1]>>3)&7;
                   2042:                                dir=SIG_READ;
                   2043:                                len+=3;
                   2044:                                break;
                   2045:                        case 0x00:
                   2046:                                r=(i[1]>>3)&7;
                   2047:                                dir=SIG_READ;
                   2048:                                len+=2;
                   2049:                                break;
                   2050:                        default:
                   2051:                                break;
                   2052:                        }
                   2053:                        break;
                   2054: 
                   2055:                case 0x89:
                   2056:                        switch(i[1]&0xc0) {
                   2057:                        case 0x80:
                   2058:                                r=(i[1]>>3)&7;
                   2059:                                dir=SIG_WRITE;
                   2060:                                len+=6;
                   2061:                                break;
                   2062:                        case 0x40:
                   2063:                                r=(i[1]>>3)&7;
                   2064:                                dir=SIG_WRITE;
                   2065:                                len+=3;
                   2066:                                break;
                   2067:                        case 0x00:
                   2068:                                r=(i[1]>>3)&7;
                   2069:                                dir=SIG_WRITE;
                   2070:                                len+=2;
                   2071:                                break;
                   2072:                        }
                   2073:                        break;
                   2074:                }
                   2075:        }
                   2076: 
                   2077:        if (r!=-1) {
                   2078:                void* pr=NULL;
                   2079:                write_log (L"JIT: register was %d, direction was %d, size was %d\n",r,dir,size);
                   2080: 
                   2081:                switch(r) {
                   2082:                case 0: pr=&(sc.eax); break;
                   2083:                case 1: pr=&(sc.ecx); break;
                   2084:                case 2: pr=&(sc.edx); break;
                   2085:                case 3: pr=&(sc.ebx); break;
                   2086:                case 4: pr=(size>1)?NULL:(((uae_u8*)&(sc.eax))+1); break;
                   2087:                case 5: pr=(size>1)?
                   2088:                                        (void*)(&(sc.ebp)):
                   2089:                        (void*)(((uae_u8*)&(sc.ecx))+1); break;
                   2090:                case 6: pr=(size>1)?
                   2091:                                        (void*)(&(sc.esi)):
                   2092:                        (void*)(((uae_u8*)&(sc.edx))+1); break;
                   2093:                case 7: pr=(size>1)?
                   2094:                                        (void*)(&(sc.edi)):
                   2095:                        (void*)(((uae_u8*)&(sc.ebx))+1); break;
                   2096:                default: abort();
                   2097:                }
                   2098:                if (pr) {
                   2099:                        blockinfo* bi;
                   2100: 
                   2101:                        if (currprefs.comp_oldsegv) {
                   2102:                                addr-=NATMEM_OFFSET;
                   2103: 
                   2104:                                if ((addr>=0x10000000 && addr<0x40000000) ||
                   2105:                                        (addr>=0x50000000)) {
                   2106:                                                write_log (L"JIT: Suspicious address in %x SEGV handler.\n",addr);
                   2107:                                }
                   2108:                                if (dir==SIG_READ) {
                   2109:                                        switch(size) {
                   2110:                                        case 1: *((uae_u8*)pr)=get_byte (addr); break;
                   2111:                                        case 2: *((uae_u16*)pr)=get_word (addr); break;
                   2112:                                        case 4: *((uae_u32*)pr)=get_long (addr); break;
                   2113:                                        default: abort();
                   2114:                                        }
                   2115:                                }
                   2116:                                else { /* write */
                   2117:                                        switch(size) {
                   2118:                                        case 1: put_byte (addr,*((uae_u8*)pr)); break;
                   2119:                                        case 2: put_word (addr,*((uae_u16*)pr)); break;
                   2120:                                        case 4: put_long (addr,*((uae_u32*)pr)); break;
                   2121:                                        default: abort();
                   2122:                                        }
                   2123:                                }
                   2124:                                write_log (L"JIT: Handled one access!\n");
                   2125:                                fflush(stdout);
                   2126:                                segvcount++;
                   2127:                                sc.eip+=len;
                   2128:                        }
                   2129:                        else {
                   2130:                                void* tmp=target;
                   2131:                                int i;
                   2132:                                uae_u8 vecbuf[5];
                   2133: 
                   2134:                                addr-=NATMEM_OFFSET;
                   2135: 
                   2136:                                if ((addr>=0x10000000 && addr<0x40000000) ||
                   2137:                                        (addr>=0x50000000)) {
                   2138:                                                write_log (L"JIT: Suspicious address 0x%x in SEGV handler.\n",addr);
                   2139:                                }
                   2140: 
                   2141:                                target=(uae_u8*)sc.eip;
                   2142:                                for (i=0;i<5;i++)
                   2143:                                        vecbuf[i]=target[i];
                   2144:                                emit_byte(0xe9);
                   2145:                                emit_long((uae_u32)veccode-(uae_u32)target-4);
                   2146:                                write_log (L"JIT: Create jump to %p\n",veccode);
                   2147: 
                   2148:                                write_log (L"JIT: Handled one access!\n");
                   2149:                                segvcount++;
                   2150: 
                   2151:                                target=veccode;
                   2152: 
                   2153:                                if (dir==SIG_READ) {
                   2154:                                        switch(size) {
                   2155:                                        case 1: raw_mov_b_ri(r,get_byte (addr)); break;
                   2156:                                        case 2: raw_mov_w_ri(r,get_word (addr)); break;
                   2157:                                        case 4: raw_mov_l_ri(r,get_long (addr)); break;
                   2158:                                        default: abort();
                   2159:                                        }
                   2160:                                }
                   2161:                                else { /* write */
                   2162:                                        switch(size) {
                   2163:                                        case 1: put_byte (addr,*((uae_u8*)pr)); break;
                   2164:                                        case 2: put_word (addr,*((uae_u16*)pr)); break;
                   2165:                                        case 4: put_long (addr,*((uae_u32*)pr)); break;
                   2166:                                        default: abort();
                   2167:                                        }
                   2168:                                }
                   2169:                                for (i=0;i<5;i++)
                   2170:                                        raw_mov_b_mi(sc.eip+i,vecbuf[i]);
                   2171:                                raw_mov_l_mi((uae_u32)&in_handler,0);
                   2172:                                emit_byte(0xe9);
                   2173:                                emit_long(sc.eip+len-(uae_u32)target-4);
                   2174:                                in_handler=1;
                   2175:                                target=tmp;
                   2176:                        }
                   2177:                        bi=active;
                   2178:                        while (bi) {
                   2179:                                if (bi->handler &&
                   2180:                                        (uae_u8*)bi->direct_handler<=i &&
                   2181:                                        (uae_u8*)bi->nexthandler>i) {
                   2182:                                                write_log (L"JIT: deleted trigger (%p<%p<%p) %p\n",
                   2183:                                                        bi->handler,
                   2184:                                                        i,
                   2185:                                                        bi->nexthandler,
                   2186:                                                        bi->pc_p);
                   2187:                                                invalidate_block(bi);
                   2188:                                                raise_in_cl_list(bi);
                   2189:                                                set_special(0);
                   2190:                                                return;
                   2191:                                }
                   2192:                                bi=bi->next;
                   2193:                        }
                   2194:                        /* Not found in the active list. Might be a rom routine that
                   2195:                        is in the dormant list */
                   2196:                        bi=dormant;
                   2197:                        while (bi) {
                   2198:                                if (bi->handler &&
                   2199:                                        (uae_u8*)bi->direct_handler<=i &&
                   2200:                                        (uae_u8*)bi->nexthandler>i) {
                   2201:                                                write_log (L"JIT: deleted trigger (%p<%p<%p) %p\n",
                   2202:                                                        bi->handler,
                   2203:                                                        i,
                   2204:                                                        bi->nexthandler,
                   2205:                                                        bi->pc_p);
                   2206:                                                invalidate_block(bi);
                   2207:                                                raise_in_cl_list(bi);
                   2208:                                                set_special(0);
                   2209:                                                return;
                   2210:                                }
                   2211:                                bi=bi->next;
                   2212:                        }
                   2213:                        write_log (L"JIT: Huh? Could not find trigger!\n");
                   2214:                        return;
                   2215:                }
                   2216:        }
                   2217:        write_log (L"JIT: Can't handle access!\n");
                   2218:        for (j=0;j<10;j++) {
                   2219:                write_log (L"JIT: instruction byte %2d is %02x\n",j,i[j]);
                   2220:        }
                   2221: #if 0
                   2222:        write_log (L"Please send the above info (starting at \"fault address\") to\n"
                   2223:                "[email protected]\n"
                   2224:                "This shouldn't happen ;-)\n");
                   2225:        fflush(stdout);
                   2226: #endif
                   2227:        signal(SIGSEGV,SIG_DFL);  /* returning here will cause a "real" SEGV */
                   2228: }
                   2229: #endif
                   2230: #endif
                   2231: 
                   2232: /*************************************************************************
                   2233: * Checking for CPU features                                             *
                   2234: *************************************************************************/
                   2235: 
                   2236: struct cpuinfo_x86 {
                   2237:        uae_u8  x86;                    // CPU family
                   2238:        uae_u8  x86_vendor;             // CPU vendor
                   2239:        uae_u8  x86_processor;  // CPU canonical processor type
                   2240:        uae_u8  x86_brand_id;   // CPU BrandID if supported, yield 0 otherwise
                   2241:        uae_u32 x86_hwcap;
                   2242:        uae_u8  x86_model;
                   2243:        uae_u8  x86_mask;
                   2244:        int             cpuid_level;    // Maximum supported CPUID level, -1=no CPUID
                   2245:        char            x86_vendor_id[16];
                   2246: };
                   2247: struct cpuinfo_x86 cpuinfo;
                   2248: 
                   2249: enum {
                   2250:        X86_VENDOR_INTEL                = 0,
                   2251:        X86_VENDOR_CYRIX                = 1,
                   2252:        X86_VENDOR_AMD          = 2,
                   2253:        X86_VENDOR_UMC          = 3,
                   2254:        X86_VENDOR_NEXGEN               = 4,
                   2255:        X86_VENDOR_CENTAUR      = 5,
                   2256:        X86_VENDOR_RISE         = 6,
                   2257:        X86_VENDOR_TRANSMETA    = 7,
                   2258:        X86_VENDOR_NSC          = 8,
                   2259:        X86_VENDOR_UNKNOWN      = 0xff
                   2260: };
                   2261: 
                   2262: enum {
                   2263:        X86_PROCESSOR_I386,                       /* 80386 */
                   2264:        X86_PROCESSOR_I486,                       /* 80486DX, 80486SX, 80486DX[24] */
                   2265:        X86_PROCESSOR_PENTIUM,
                   2266:        X86_PROCESSOR_PENTIUMPRO,
                   2267:        X86_PROCESSOR_K6,
                   2268:        X86_PROCESSOR_ATHLON,
                   2269:        X86_PROCESSOR_PENTIUM4,
                   2270:        X86_PROCESSOR_K8,
                   2271:        X86_PROCESSOR_max
                   2272: };
                   2273: 
                   2274: static struct ptt {
                   2275:        const int align_loop;
                   2276:        const int align_loop_max_skip;
                   2277:        const int align_jump;
                   2278:        const int align_jump_max_skip;
                   2279:        const int align_func;
                   2280: }
                   2281: x86_alignments[X86_PROCESSOR_max + 1] = {
                   2282:        {  4,  3,  4,  3,  4 },
                   2283:        { 16, 15, 16, 15, 16 },
                   2284:        { 16,  7, 16,  7, 16 },
                   2285:        { 16, 15, 16,  7, 16 },
                   2286:        { 32,  7, 32,  7, 32 },
                   2287:        { 16,  7, 16,  7, 16 },
                   2288:        {  0,  0,  0,  0,  0 },
                   2289:        { 16,  7, 16,  7, 16 },
                   2290:        {  0,  0,  0,  0,  0 }
                   2291: };
                   2292: 
                   2293: static void
                   2294:        x86_get_cpu_vendor(struct cpuinfo_x86 *c)
                   2295: {
                   2296:        char *v = c->x86_vendor_id;
                   2297: 
                   2298:        if (!strcmp(v, "GenuineIntel"))
                   2299:                c->x86_vendor = X86_VENDOR_INTEL;
                   2300:        else if (!strcmp(v, "AuthenticAMD"))
                   2301:                c->x86_vendor = X86_VENDOR_AMD;
                   2302:        else if (!strcmp(v, "CyrixInstead"))
                   2303:                c->x86_vendor = X86_VENDOR_CYRIX;
                   2304:        else if (!strcmp(v, "Geode by NSC"))
                   2305:                c->x86_vendor = X86_VENDOR_NSC;
                   2306:        else if (!strcmp(v, "UMC UMC UMC "))
                   2307:                c->x86_vendor = X86_VENDOR_UMC;
                   2308:        else if (!strcmp(v, "CentaurHauls"))
                   2309:                c->x86_vendor = X86_VENDOR_CENTAUR;
                   2310:        else if (!strcmp(v, "NexGenDriven"))
                   2311:                c->x86_vendor = X86_VENDOR_NEXGEN;
                   2312:        else if (!strcmp(v, "RiseRiseRise"))
                   2313:                c->x86_vendor = X86_VENDOR_RISE;
                   2314:        else if (!strcmp(v, "GenuineTMx86") ||
                   2315:                !strcmp(v, "TransmetaCPU"))
                   2316:                c->x86_vendor = X86_VENDOR_TRANSMETA;
                   2317:        else
                   2318:                c->x86_vendor = X86_VENDOR_UNKNOWN;
                   2319: }
                   2320: 
                   2321: static void cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx)
                   2322: {
                   2323:        const int CPUID_SPACE = 4096;
                   2324:        uae_u8* cpuid_space = (uae_u8*)cache_alloc(CPUID_SPACE);
                   2325:        static uae_u32 s_op, s_eax, s_ebx, s_ecx, s_edx;
                   2326:        uae_u8* tmp=get_target();
                   2327: 
                   2328:        s_op = op;
                   2329:        set_target(cpuid_space);
                   2330:        raw_push_l_r(0); /* eax */
                   2331:        raw_push_l_r(1); /* ecx */
                   2332:        raw_push_l_r(2); /* edx */
                   2333:        raw_push_l_r(3); /* ebx */
                   2334:        raw_mov_l_rm(0,(uintptr)&s_op);
                   2335:        raw_cpuid(0);
                   2336:        raw_mov_l_mr((uintptr)&s_eax,0);
                   2337:        raw_mov_l_mr((uintptr)&s_ebx,3);
                   2338:        raw_mov_l_mr((uintptr)&s_ecx,1);
                   2339:        raw_mov_l_mr((uintptr)&s_edx,2);
                   2340:        raw_pop_l_r(3);
                   2341:        raw_pop_l_r(2);
                   2342:        raw_pop_l_r(1);
                   2343:        raw_pop_l_r(0);
                   2344:        raw_ret();
                   2345:        set_target(tmp);
                   2346: 
                   2347:        ((compop_func*)cpuid_space)(0);
                   2348:        if (eax != NULL) *eax = s_eax;
                   2349:        if (ebx != NULL) *ebx = s_ebx;
                   2350:        if (ecx != NULL) *ecx = s_ecx;
                   2351:        if (edx != NULL) *edx = s_edx;
                   2352: 
                   2353:        cache_free (cpuid_space);
                   2354: }
                   2355: 
                   2356: static void raw_init_cpu(void)
                   2357: {
                   2358:        struct cpuinfo_x86 *c = &cpuinfo;
                   2359:        uae_u32 xlvl;
                   2360: 
                   2361:        /* Defaults */
                   2362:        c->x86_processor = X86_PROCESSOR_max;
                   2363:        c->x86_vendor = X86_VENDOR_UNKNOWN;
                   2364:        c->cpuid_level = -1;                            /* CPUID not detected */
                   2365:        c->x86_model = c->x86_mask = 0; /* So far unknown... */
                   2366:        c->x86_vendor_id[0] = '\0';             /* Unset */
                   2367:        c->x86_hwcap = 0;
                   2368: 
                   2369:        /* Get vendor name */
                   2370:        c->x86_vendor_id[12] = '\0';
                   2371:        cpuid(0x00000000,
                   2372:                (uae_u32 *)&c->cpuid_level,
                   2373:                (uae_u32 *)&c->x86_vendor_id[0],
                   2374:                (uae_u32 *)&c->x86_vendor_id[8],
                   2375:                (uae_u32 *)&c->x86_vendor_id[4]);
                   2376:        x86_get_cpu_vendor(c);
                   2377: 
                   2378:        /* Intel-defined flags: level 0x00000001 */
                   2379:        c->x86_brand_id = 0;
                   2380:        if ( c->cpuid_level >= 0x00000001 ) {
                   2381:                uae_u32 tfms, brand_id;
                   2382:                cpuid(0x00000001, &tfms, &brand_id, NULL, &c->x86_hwcap);
                   2383:                c->x86 = (tfms >> 8) & 15;
                   2384:                c->x86_model = (tfms >> 4) & 15;
                   2385:                c->x86_brand_id = brand_id & 0xff;
                   2386:                if ( (c->x86_vendor == X86_VENDOR_AMD) &&
                   2387:                        (c->x86 == 0xf)) {
                   2388:                                /* AMD Extended Family and Model Values */
                   2389:                                c->x86 += (tfms >> 20) & 0xff;
                   2390:                                c->x86_model += (tfms >> 12) & 0xf0;
                   2391:                }
                   2392:                c->x86_mask = tfms & 15;
                   2393:        } else {
                   2394:                /* Have CPUID level 0 only - unheard of */
                   2395:                c->x86 = 4;
                   2396:        }
                   2397: 
                   2398:        /* AMD-defined flags: level 0x80000001 */
                   2399:        cpuid(0x80000000, &xlvl, NULL, NULL, NULL);
                   2400:        if ( (xlvl & 0xffff0000) == 0x80000000 ) {
                   2401:                if ( xlvl >= 0x80000001 ) {
                   2402:                        uae_u32 features;
                   2403:                        cpuid(0x80000001, NULL, NULL, NULL, &features);
                   2404:                        if (features & (1 << 29)) {
                   2405:                                /* Assume x86-64 if long mode is supported */
                   2406:                                c->x86_processor = X86_PROCESSOR_K8;
                   2407:                        }
                   2408:                }
                   2409:        }
                   2410: 
                   2411:        /* Canonicalize processor ID */
                   2412:        switch (c->x86) {
                   2413:        case 3:
                   2414:                c->x86_processor = X86_PROCESSOR_I386;
                   2415:                break;
                   2416:        case 4:
                   2417:                c->x86_processor = X86_PROCESSOR_I486;
                   2418:                break;
                   2419:        case 5:
                   2420:                if (c->x86_vendor == X86_VENDOR_AMD)
                   2421:                        c->x86_processor = X86_PROCESSOR_K6;
                   2422:                else
                   2423:                        c->x86_processor = X86_PROCESSOR_PENTIUM;
                   2424:                break;
                   2425:        case 6:
                   2426:                if (c->x86_vendor == X86_VENDOR_AMD)
                   2427:                        c->x86_processor = X86_PROCESSOR_ATHLON;
                   2428:                else
                   2429:                        c->x86_processor = X86_PROCESSOR_PENTIUMPRO;
                   2430:                break;
                   2431:        case 15:
                   2432:                if (c->x86_vendor == X86_VENDOR_INTEL) {
                   2433:                        /* Assume any BrandID >= 8 and family == 15 yields a Pentium 4 */
                   2434:                        if (c->x86_brand_id >= 8)
                   2435:                                c->x86_processor = X86_PROCESSOR_PENTIUM4;
                   2436:                }
                   2437:                if (c->x86_vendor == X86_VENDOR_AMD) {
                   2438:                        /* Assume an Athlon processor if family == 15 and it was not
                   2439:                        detected as an x86-64 so far */
                   2440:                        if (c->x86_processor == X86_PROCESSOR_max)
                   2441:                                c->x86_processor = X86_PROCESSOR_ATHLON;
                   2442:                }
                   2443:                break;
                   2444:        }
                   2445: 
                   2446:        /* Have CMOV support? */
                   2447:        have_cmov = c->x86_hwcap & (1 << 15);
                   2448: 
                   2449: #if 0
                   2450:        /* Can the host CPU suffer from partial register stalls? */
                   2451:        have_rat_stall = (c->x86_vendor == X86_VENDOR_INTEL);
                   2452:        /* It appears that partial register writes are a bad idea even on
                   2453:        AMD K7 cores, even though they are not supposed to have the
                   2454:        dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */
                   2455:        if (c->x86_processor == X86_PROCESSOR_ATHLON)
                   2456:                have_rat_stall = 1;
                   2457: #endif
                   2458:        have_rat_stall = 1;
                   2459: 
                   2460:        /* Alignments */
                   2461:        if (tune_alignment) {
                   2462:                align_loops = x86_alignments[c->x86_processor].align_loop;
                   2463:                align_jumps = x86_alignments[c->x86_processor].align_jump;
                   2464:        }
                   2465:        { 
                   2466:                TCHAR *s = au (c->x86_vendor_id);
                   2467:                write_log (L"CPUID level=%d, Family=%d, Model=%d, Mask=%d, Vendor=%s [%d]\n",
                   2468:                        c->cpuid_level, c->x86, c->x86_model, c->x86_mask, s, c->x86_vendor);
                   2469:                xfree (s);
                   2470:        }
                   2471: }
                   2472: 
                   2473: #if 0
                   2474: static int target_check_bsf(void)
                   2475: {
                   2476:        int mismatch = 0;
                   2477:        for (int g_ZF = 0; g_ZF <= 1; g_ZF++) {
                   2478:                for (int g_CF = 0; g_CF <= 1; g_CF++) {
                   2479:                        for (int g_OF = 0; g_OF <= 1; g_OF++) {
                   2480:                                for (int g_SF = 0; g_SF <= 1; g_SF++) {
                   2481:                                        for (int value = -1; value <= 1; value++) {
                   2482:                                                unsigned long flags = (g_SF << 7) | (g_OF << 11) | (g_ZF << 6) | g_CF;
                   2483:                                                unsigned long tmp = value;
                   2484:                                                __asm__ __volatile__ ("push %0; popf; bsf %1,%1; pushf; pop %0"
                   2485:                                                        : "+r" (flags), "+r" (tmp) : : "cc");
                   2486:                                                int OF = (flags >> 11) & 1;
                   2487:                                                int SF = (flags >>  7) & 1;
                   2488:                                                int ZF = (flags >>  6) & 1;
                   2489:                                                int CF = flags & 1;
                   2490:                                                tmp = (value == 0);
                   2491:                                                if (ZF != tmp || SF != g_SF || OF != g_OF || CF != g_CF)
                   2492:                                                        mismatch = true;
                   2493:                                        }
                   2494:                                }}}}
                   2495:        if (mismatch)
                   2496:                write_log (L"Target CPU defines all flags on BSF instruction\n");
                   2497:        return !mismatch;
                   2498: }
                   2499: #endif
                   2500: 
                   2501: #if 0
                   2502: 
                   2503: /*************************************************************************
                   2504: * Checking for CPU features                                             *
                   2505: *************************************************************************/
                   2506: 
                   2507: typedef struct {
                   2508:        uae_u32 eax;
                   2509:        uae_u32 ecx;
                   2510:        uae_u32 edx;
                   2511:        uae_u32 ebx;
                   2512: } x86_regs;
                   2513: 
                   2514: 
                   2515: /* This could be so much easier if it could make assumptions about the
                   2516: compiler... */
                   2517: 
                   2518: static uae_u32 cpuid_ptr;
                   2519: static uae_u32 cpuid_level;
                   2520: 
                   2521: static x86_regs cpuid(uae_u32 level)
                   2522: {
                   2523:        x86_regs answer;
                   2524:        uae_u8 *cpuid_space;
                   2525:        void* tmp=get_target();
                   2526: 
                   2527:        cpuid_ptr=(uae_u32)&answer;
                   2528:        cpuid_level=level;
                   2529: 
                   2530:        cpuid_space = cache_alloc (256);
                   2531:        set_target(cpuid_space);
                   2532:        raw_push_l_r(0); /* eax */
                   2533:        raw_push_l_r(1); /* ecx */
                   2534:        raw_push_l_r(2); /* edx */
                   2535:        raw_push_l_r(3); /* ebx */
                   2536:        raw_push_l_r(7); /* edi */
                   2537:        raw_mov_l_rm(0,(uae_u32)&cpuid_level);
                   2538:        raw_cpuid(0);
                   2539:        raw_mov_l_rm(7,(uae_u32)&cpuid_ptr);
                   2540:        raw_mov_l_Rr(7,0,0);
                   2541:        raw_mov_l_Rr(7,1,4);
                   2542:        raw_mov_l_Rr(7,2,8);
                   2543:        raw_mov_l_Rr(7,3,12);
                   2544:        raw_pop_l_r(7);
                   2545:        raw_pop_l_r(3);
                   2546:        raw_pop_l_r(2);
                   2547:        raw_pop_l_r(1);
                   2548:        raw_pop_l_r(0);
                   2549:        raw_ret();
                   2550:        set_target(tmp);
                   2551: 
                   2552:        ((cpuop_func*)cpuid_space)(0);
                   2553:        cache_free (cpuid_space);
                   2554:        return answer;
                   2555: }
                   2556: 
                   2557: static void raw_init_cpu(void)
                   2558: {
                   2559:        x86_regs x;
                   2560:        uae_u32 maxlev;
                   2561: 
                   2562:        x=cpuid(0);
                   2563:        maxlev=x.eax;
                   2564:        write_log (L"Max CPUID level=%d Processor is %c%c%c%c%c%c%c%c%c%c%c%c\n",
                   2565:                maxlev,
                   2566:                x.ebx,
                   2567:                x.ebx>>8,
                   2568:                x.ebx>>16,
                   2569:                x.ebx>>24,
                   2570:                x.edx,
                   2571:                x.edx>>8,
                   2572:                x.edx>>16,
                   2573:                x.edx>>24,
                   2574:                x.ecx,
                   2575:                x.ecx>>8,
                   2576:                x.ecx>>16,
                   2577:                x.ecx>>24
                   2578:                );
                   2579:        have_rat_stall=(x.ecx==0x6c65746e);
                   2580: 
                   2581:        if (maxlev>=1) {
                   2582:                x=cpuid(1);
                   2583:                if (x.edx&(1<<15))
                   2584:                        have_cmov=1;
                   2585:        }
                   2586:        have_rat_stall=1;
                   2587: #if 0
                   2588:        if (!have_cmov)
                   2589:                have_rat_stall=0;
                   2590: #endif
                   2591: #if 0
                   2592:        write_log (L"have_cmov=%d, avoid_cmov=%d, have_rat_stall=%d\n",
                   2593:                have_cmov,currprefs.avoid_cmov,have_rat_stall);
                   2594:        if (currprefs.avoid_cmov) {
                   2595:                write_log (L"Disabling cmov use despite processor claiming to support it!\n");
                   2596:                have_cmov=0;
                   2597:        }
                   2598: #else
                   2599:        /* Dear Bernie, I don't want to keep around options which are useless, and not
                   2600:        represented in the GUI anymore... Is this okay? */
                   2601:        write_log (L"have_cmov=%d, have_rat_stall=%d\n", have_cmov, have_rat_stall);
                   2602: #endif
                   2603: #if 0   /* For testing of non-cmov code! */
                   2604:        have_cmov=0;
                   2605: #endif
                   2606: #if 0 /* It appears that partial register writes are a bad idea even on
                   2607:        AMD K7 cores, even though they are not supposed to have the
                   2608:        dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */
                   2609:        if (have_cmov)
                   2610:                have_rat_stall=1;
                   2611: #endif
                   2612: }
                   2613: #endif
                   2614: 
                   2615: /*************************************************************************
                   2616: * FPU stuff                                                             *
                   2617: *************************************************************************/
                   2618: 
                   2619: 
                   2620: STATIC_INLINE void raw_fp_init(void)
                   2621: {
                   2622:        int i;
                   2623: 
                   2624:        for (i=0;i<N_FREGS;i++)
                   2625:                live.spos[i]=-2;
                   2626:        live.tos=-1;  /* Stack is empty */
                   2627: }
                   2628: 
                   2629: STATIC_INLINE void raw_fp_cleanup_drop(void)
                   2630: {
                   2631: #if 0
                   2632:        /* using FINIT instead of popping all the entries.
                   2633:        Seems to have side effects --- there is display corruption in
                   2634:        Quake when this is used */
                   2635:        if (live.tos>1) {
                   2636:                emit_byte(0x9b);
                   2637:                emit_byte(0xdb);
                   2638:                emit_byte(0xe3);
                   2639:                live.tos=-1;
                   2640:        }
                   2641: #endif
                   2642:        while (live.tos>=1) {
                   2643:                emit_byte(0xde);
                   2644:                emit_byte(0xd9);
                   2645:                live.tos-=2;
                   2646:        }
                   2647:        while (live.tos>=0) {
                   2648:                emit_byte(0xdd);
                   2649:                emit_byte(0xd8);
                   2650:                live.tos--;
                   2651:        }
                   2652:        raw_fp_init();
                   2653: }
                   2654: 
                   2655: STATIC_INLINE void make_tos(int r)
                   2656: {
                   2657:        int p,q;
                   2658: 
                   2659:        if (live.spos[r]<0) { /* Register not yet on stack */
                   2660:                emit_byte(0xd9);
                   2661:                emit_byte(0xe8);  /* Push '1' on the stack, just to grow it */
                   2662:                live.tos++;
                   2663:                live.spos[r]=live.tos;
                   2664:                live.onstack[live.tos]=r;
                   2665:                return;
                   2666:        }
                   2667:        /* Register is on stack */
                   2668:        if (live.tos==live.spos[r])
                   2669:                return;
                   2670:        p=live.spos[r];
                   2671:        q=live.onstack[live.tos];
                   2672: 
                   2673:        emit_byte(0xd9);
                   2674:        emit_byte(0xc8+live.tos-live.spos[r]);  /* exchange it with top of stack */
                   2675:        live.onstack[live.tos]=r;
                   2676:        live.spos[r]=live.tos;
                   2677:        live.onstack[p]=q;
                   2678:        live.spos[q]=p;
                   2679: }
                   2680: 
                   2681: STATIC_INLINE int stackpos(int r)
                   2682: {
                   2683:        if (live.spos[r]<0)
                   2684:                abort();
                   2685:        if (live.tos<live.spos[r]) {
                   2686:                write_log (L"JIT: Looking for spos for fnreg %d\n",r);
                   2687:                abort();
                   2688:        }
                   2689:        return live.tos-live.spos[r];
                   2690: }
                   2691: 
                   2692: /* IMO, calling usereg(r) makes no sense, if the register r should supply our function with
                   2693: an argument, because I would expect all arguments to be on the stack already, won't they?
                   2694: Thus, usereg(s) is always useless and also for every FRW d it's too late here now. PeterK
                   2695: */
                   2696: STATIC_INLINE void usereg(int r)
                   2697: {
                   2698: 
                   2699:        if (live.spos[r]<0) {
                   2700:                // write_log (L"usereg wants to push reg %d onto the x87 stack calling make_tos\n", r);
                   2701:                make_tos(r);
                   2702:        }
                   2703: }
                   2704: 
                   2705: /* This is called with one FP value in a reg *above* tos,
                   2706: which it will pop off the stack if necessary */
                   2707: STATIC_INLINE void tos_make(int r)
                   2708: {
                   2709:        if (live.spos[r]<0) {
                   2710:                live.tos++;
                   2711:                live.spos[r]=live.tos;
                   2712:                live.onstack[live.tos]=r;
                   2713:                return;
                   2714:        }
                   2715:        emit_byte(0xdd);
                   2716:        emit_byte(0xd8+(live.tos+1)-live.spos[r]);
                   2717:        /* store top of stack in reg and pop it*/
                   2718: }
                   2719: 
                   2720: 
                   2721: LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
                   2722: {
                   2723:        make_tos(r);
                   2724:        emit_byte(0xdd);
                   2725:        emit_byte(0x15);
                   2726:        emit_long(m);
                   2727: }
                   2728: LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
                   2729: 
                   2730:        LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r))
                   2731: {
                   2732:        make_tos(r);
                   2733:        emit_byte(0xdd);
                   2734:        emit_byte(0x1d);
                   2735:        emit_long(m);
                   2736:        live.onstack[live.tos]=-1;
                   2737:        live.tos--;
                   2738:        live.spos[r]=-2;
                   2739: }
                   2740: LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
                   2741: 
                   2742:        LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
                   2743: {
                   2744:        emit_byte(0xdd);
                   2745:        emit_byte(0x05);
                   2746:        emit_long(m);
                   2747:        tos_make(r);
                   2748: }
                   2749: LENDFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
                   2750: 
                   2751:        LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
                   2752: {
                   2753:        emit_byte(0xdb);
                   2754:        emit_byte(0x05);
                   2755:        emit_long(m);
                   2756:        tos_make(r);
                   2757: }
                   2758: LENDFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
                   2759: 
                   2760:        LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds))
                   2761: {
                   2762:        /* Clamp value to the given range and convert to integer.
                   2763:        ideally, the clamping should be done using two FCMOVs, but
                   2764:        this requires two free fp registers, and we can only be sure
                   2765:        of having one. Using a jump for the lower bound and an FCMOV
                   2766:        for the upper bound, we can do it with one scratch register.
                   2767:        */
                   2768: 
                   2769:        int rs;
                   2770:        usereg(r);
                   2771:        rs = stackpos(r)+1;
                   2772: 
                   2773:        /* Lower bound onto stack */
                   2774:        emit_byte(0xdd);
                   2775:        emit_byte(0x05);
                   2776:        emit_long((uae_u32)&bounds[0]); /* fld double from lower */
                   2777: 
                   2778:        /* Clamp to lower */
                   2779:        emit_byte(0xdb);
                   2780:        emit_byte(0xf0+rs); /* fcomi lower,r */
                   2781:        emit_byte(0x73);
                   2782:        emit_byte(12);      /* jae to writeback */
                   2783: 
                   2784:        /* Upper bound onto stack */
                   2785:        emit_byte(0xdd);
                   2786:        emit_byte(0xd8);        /* fstp st(0) */
                   2787:        emit_byte(0xdd);
                   2788:        emit_byte(0x05);
                   2789:        emit_long((uae_u32)&bounds[1]); /* fld double from upper */
                   2790: 
                   2791:        /* Clamp to upper */
                   2792:        emit_byte(0xdb);
                   2793:        emit_byte(0xf0+rs); /* fcomi upper,r */
                   2794:        emit_byte(0xdb);
                   2795:        emit_byte(0xd0+rs); /* fcmovnbe upper,r */
                   2796: 
                   2797:        /* Store to destination */
                   2798:        emit_byte(0xdb);
                   2799:        emit_byte(0x1d);
                   2800:        emit_long(m);
                   2801: }
                   2802: LENDFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds))
                   2803: 
                   2804:        LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
                   2805: {
                   2806:        emit_byte(0xd9);
                   2807:        emit_byte(0x05);
                   2808:        emit_long(m);
                   2809:        tos_make(r);
                   2810: }
                   2811: LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
                   2812: 
                   2813:        LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
                   2814: {
                   2815:        make_tos(r);
                   2816:        emit_byte(0xd9);
                   2817:        emit_byte(0x15);
                   2818:        emit_long(m);
                   2819: }
                   2820: LENDFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
                   2821: 
                   2822:        LOWFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
                   2823: {
                   2824:        make_tos(r);     /* TOS = r */
                   2825:        emit_byte(0x83);
                   2826:        emit_byte(0xc4);
                   2827:        emit_byte(0xfc); /* add -4 to esp */
                   2828:        emit_byte(0xd9);
                   2829:        emit_byte(0x1c);
                   2830:        emit_byte(0x24); /* fstp store r as SINGLE to [esp] and pop */
                   2831:        emit_byte(0xd9);
                   2832:        emit_byte(0x04);
                   2833:        emit_byte(0x24); /* fld load r as SINGLE from [esp] */
                   2834:        emit_byte(0x83);
                   2835:        emit_byte(0xc4);
                   2836:        emit_byte(0x04); /* add +4 to esp */
                   2837: }
                   2838: LENDFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
                   2839: 
                   2840:        LOWFUNC(NONE,NONE,1,raw_fcut_r,(FRW r))
                   2841: {
                   2842:        make_tos(r);     /* TOS = r */
                   2843:        emit_byte(0x83);
                   2844:        emit_byte(0xc4);
                   2845:        emit_byte(0xf8); /* add -8 to esp */
                   2846:        emit_byte(0xdd);
                   2847:        emit_byte(0x1c);
                   2848:        emit_byte(0x24); /* fstp store r as DOUBLE to [esp] and pop */
                   2849:        emit_byte(0xdd);
                   2850:        emit_byte(0x04);
                   2851:        emit_byte(0x24); /* fld load r as DOUBLE from [esp] */
                   2852:        emit_byte(0x83);
                   2853:        emit_byte(0xc4);
                   2854:        emit_byte(0x08); /* add +8 to esp */
                   2855: }
                   2856: LENDFUNC(NONE,NONE,1,raw_fcut_r,(FRW r))
                   2857: 
                   2858:        LOWFUNC(NONE,READ,2,raw_fmovl_ri,(FW r, IMMS i))
                   2859: {
                   2860:        emit_byte(0x68);
                   2861:        emit_long(i);    /* push immediate32 onto [esp] */
                   2862:        emit_byte(0xdb);
                   2863:        emit_byte(0x04);
                   2864:        emit_byte(0x24); /* fild load m32int from [esp] */
                   2865:        emit_byte(0x83);
                   2866:        emit_byte(0xc4);
                   2867:        emit_byte(0x04); /* add +4 to esp */
                   2868:        tos_make(r);
                   2869: }
                   2870: LENDFUNC(NONE,READ,2,raw_fmovl_ri,(FW r, IMMS i))
                   2871: 
                   2872:        LOWFUNC(NONE,READ,2,raw_fmovs_ri,(FW r, IMM i))
                   2873: {
                   2874:        emit_byte(0x68);
                   2875:        emit_long(i);    /* push immediate32 onto [esp] */
                   2876:        emit_byte(0xd9);
                   2877:        emit_byte(0x04);
                   2878:        emit_byte(0x24); /* fld load m32real from [esp] */
                   2879:        emit_byte(0x83);
                   2880:        emit_byte(0xc4);
                   2881:        emit_byte(0x04); /* add +4 to esp */
                   2882:        tos_make(r);
                   2883: }
                   2884: LENDFUNC(NONE,READ,2,raw_fmovs_ri,(FW r, IMM i))
                   2885: 
                   2886:        LOWFUNC(NONE,READ,3,raw_fmov_ri,(FW r, IMM i1, IMM i2))
                   2887: {
                   2888:        emit_byte(0x68);
                   2889:        emit_long(i2);   /* push immediate32 onto [esp] */
                   2890:        emit_byte(0x68);
                   2891:        emit_long(i1);   /* push immediate32 onto [esp] */
                   2892:        emit_byte(0xdd);
                   2893:        emit_byte(0x04);
                   2894:        emit_byte(0x24); /* fld load m64real from [esp] */
                   2895:        emit_byte(0x83);
                   2896:        emit_byte(0xc4);
                   2897:        emit_byte(0x08); /* add +8 to esp */
                   2898:        tos_make(r);
                   2899: }
                   2900: LENDFUNC(NONE,READ,3,raw_fmov_ri,(FW r, IMM i1, IMM i2))
                   2901: 
                   2902:        LOWFUNC(NONE,READ,4,raw_fmov_ext_ri,(FW r, IMM i1, IMM i2, IMM i3))
                   2903: {
                   2904:        emit_byte(0x68);
                   2905:        emit_long(i3);   /* push immediate32 onto [esp] */
                   2906:        emit_byte(0x68);
                   2907:        emit_long(i2);   /* push immediate32 onto [esp] */
                   2908:        emit_byte(0x68);
                   2909:        emit_long(i1);   /* push immediate32 onto [esp] */
                   2910:        emit_byte(0xdb);
                   2911:        emit_byte(0x2c);
                   2912:        emit_byte(0x24); /* fld load m80real from [esp] */
                   2913:        emit_byte(0x83);
                   2914:        emit_byte(0xc4);
                   2915:        emit_byte(0x0c); /* add +12 to esp */
                   2916:        tos_make(r);
                   2917: }
                   2918: LENDFUNC(NONE,READ,4,raw_fmov_ext_ri,(FW r, IMM i1, IMM i2, IMMi3))
                   2919: 
                   2920:        LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
                   2921: {
                   2922:        int rs;
                   2923: 
                   2924:        /* Stupid x87 can't write a long double to mem without popping the
                   2925:        stack! */
                   2926:        usereg(r);
                   2927:        rs=stackpos(r);
                   2928:        emit_byte(0xd9);     /* Get a copy to the top of stack */
                   2929:        emit_byte(0xc0+rs);
                   2930: 
                   2931:        emit_byte(0xdb);  /* store and pop it */
                   2932:        emit_byte(0x3d);
                   2933:        emit_long(m);
                   2934: }
                   2935: LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
                   2936: 
                   2937:        LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r))
                   2938: {
                   2939:        make_tos(r);
                   2940:        emit_byte(0xdb);  /* store and pop it */
                   2941:        emit_byte(0x3d);
                   2942:        emit_long(m);
                   2943:        live.onstack[live.tos]=-1;
                   2944:        live.tos--;
                   2945:        live.spos[r]=-2;
                   2946: }
                   2947: LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
                   2948: 
                   2949:        LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
                   2950: {
                   2951:        emit_byte(0xdb);
                   2952:        emit_byte(0x2d);
                   2953:        emit_long(m);
                   2954:        tos_make(r);
                   2955: }
                   2956: LENDFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
                   2957: 
                   2958:        LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
                   2959: {
                   2960:        emit_byte(0xd9);
                   2961:        emit_byte(0xeb);
                   2962:        tos_make(r);
                   2963: }
                   2964: LENDFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
                   2965: 
                   2966:        LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
                   2967: {
                   2968:        emit_byte(0xd9);
                   2969:        emit_byte(0xec);
                   2970:        tos_make(r);
                   2971: }
                   2972: LENDFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
                   2973: 
                   2974:        LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
                   2975: {
                   2976:        emit_byte(0xd9);
                   2977:        emit_byte(0xea);
                   2978:        tos_make(r);
                   2979: }
                   2980: LENDFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
                   2981: 
                   2982:        LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
                   2983: {
                   2984:        emit_byte(0xd9);
                   2985:        emit_byte(0xed);
                   2986:        tos_make(r);
                   2987: }
                   2988: LENDFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
                   2989: 
                   2990:        LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
                   2991: {
                   2992:        emit_byte(0xd9);
                   2993:        emit_byte(0xe8);
                   2994:        tos_make(r);
                   2995: }
                   2996: LENDFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
                   2997: 
                   2998:        LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
                   2999: {
                   3000:        emit_byte(0xd9);
                   3001:        emit_byte(0xee);
                   3002:        tos_make(r);
                   3003: }
                   3004: LENDFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
                   3005: 
                   3006:        LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
                   3007: {
                   3008:        int ds;
                   3009: 
                   3010:        ds=stackpos(s);
                   3011:        if (ds==0 && live.spos[d]>=0) {
                   3012:                /* source is on top of stack, and we already have the dest */
                   3013:                int dd=stackpos(d);
                   3014:                emit_byte(0xdd);
                   3015:                emit_byte(0xd0+dd);
                   3016:        }
                   3017:        else {
                   3018:                emit_byte(0xd9);
                   3019:                emit_byte(0xc0+ds); /* duplicate source on tos */
                   3020:                tos_make(d); /* store to destination, pop if necessary */
                   3021:        }
                   3022: }
                   3023: LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
                   3024: 
                   3025:        LOWFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base))
                   3026: {
                   3027:        emit_byte(0xd9);
                   3028:        emit_byte(0xa8+index);
                   3029:        emit_long(base);
                   3030: }
                   3031: LENDFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base))
                   3032: 
                   3033:        LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
                   3034: {
                   3035:        int ds;
                   3036: 
                   3037:        if (d!=s) {
                   3038:                ds=stackpos(s);
                   3039:                emit_byte(0xd9);
                   3040:                emit_byte(0xc0+ds); /* fld x */
                   3041:                emit_byte(0xd9);
                   3042:                emit_byte(0xfa);    /* fsqrt sqrt(x) */
                   3043:                tos_make(d);        /* store to destination */
                   3044:        }
                   3045:        else {
                   3046:                make_tos(d);
                   3047:                emit_byte(0xd9);
                   3048:                emit_byte(0xfa);    /* fsqrt y=sqrt(x) */
                   3049:        }
                   3050: }
                   3051: LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
                   3052: 
                   3053:        LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
                   3054: {
                   3055:        int ds;
                   3056: 
                   3057:        if (d!=s) {
                   3058:                ds=stackpos(s);
                   3059:                emit_byte(0xd9);
                   3060:                emit_byte(0xc0+ds); /* fld x */
                   3061:                emit_byte(0xd9);
                   3062:                emit_byte(0xe1);    /* fabs abs(x) */
                   3063:                tos_make(d);        /* store to destination */
                   3064:        }
                   3065:        else {
                   3066:                make_tos(d);
                   3067:                emit_byte(0xd9);
                   3068:                emit_byte(0xe1);    /* fabs y=abs(x) */
                   3069:        }
                   3070: }
                   3071: LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
                   3072: 
                   3073:        LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
                   3074: {
                   3075:        int ds;
                   3076: 
                   3077:        if (d!=s) {
                   3078:                ds=stackpos(s);
                   3079:                emit_byte(0xd9);
                   3080:                emit_byte(0xc0+ds); /* fld x */
                   3081:                emit_byte(0xd9);
                   3082:                emit_byte(0xfc);    /* frndint int(x) */
                   3083:                tos_make(d);        /* store to destination */
                   3084:        }
                   3085:        else {
                   3086:                make_tos(d);
                   3087:                emit_byte(0xd9);
                   3088:                emit_byte(0xfc);    /* frndint y=int(x) */
                   3089:        }
                   3090: }
                   3091: LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
                   3092: 
                   3093:        LOWFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s))
                   3094: {
                   3095:        int ds;
                   3096: 
                   3097:        if (d!=s) {
                   3098:                ds=stackpos(s);
                   3099:                emit_byte(0xd9);
                   3100:                emit_byte(0xc0+ds); /* fld x */
                   3101:                emit_byte(0xd9);
                   3102:                emit_byte(0xf4);    /* fxtract exp push man */
                   3103:                emit_byte(0xdd);
                   3104:                emit_byte(0xd8);    /* fstp just pop man */
                   3105:                tos_make(d);        /* store exp to destination */
                   3106:        }
                   3107:        else {
                   3108:                make_tos(d);        /* tos=x=y */
                   3109:                emit_byte(0xd9);
                   3110:                emit_byte(0xf4);    /* fxtract exp push man */
                   3111:                emit_byte(0xdd);
                   3112:                emit_byte(0xd8);    /* fstp just pop man */
                   3113:        }
                   3114: }
                   3115: LENDFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s))
                   3116: 
                   3117:        LOWFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s))
                   3118: {
                   3119:        int ds;
                   3120: 
                   3121:        if (d!=s) {
                   3122:                ds=stackpos(s);
                   3123:                emit_byte(0xd9);
                   3124:                emit_byte(0xc0+ds); /* fld x */
                   3125:                emit_byte(0xd9);
                   3126:                emit_byte(0xf4);    /* fxtract exp push man */
                   3127:                emit_byte(0xdd);
                   3128:                emit_byte(0xd9);    /* fstp copy man up & pop */
                   3129:                tos_make(d);        /* store man to destination */
                   3130:        }
                   3131:        else {
                   3132:                make_tos(d);        /* tos=x=y */
                   3133:                emit_byte(0xd9);
                   3134:                emit_byte(0xf4);    /* fxtract exp push man */
                   3135:                emit_byte(0xdd);
                   3136:                emit_byte(0xd9);    /* fstp copy man up & pop */
                   3137:        }
                   3138: }
                   3139: LENDFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s))
                   3140: 
                   3141:        LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
                   3142: {
                   3143:        int ds;
                   3144: 
                   3145:        if (d!=s) {
                   3146:                ds=stackpos(s);
                   3147:                emit_byte(0xd9);
                   3148:                emit_byte(0xc0+ds); /* fld x */
                   3149:                emit_byte(0xd9);
                   3150:                emit_byte(0xfe);    /* fsin sin(x) */
                   3151:                tos_make(d);        /* store to destination */
                   3152:        }
                   3153:        else {
                   3154:                make_tos(d);
                   3155:                emit_byte(0xd9);
                   3156:                emit_byte(0xfe);    /* fsin y=sin(x) */
                   3157:        }
                   3158: }
                   3159: LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
                   3160: 
                   3161:        LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
                   3162: {
                   3163:        int ds;
                   3164: 
                   3165:        if (d!=s) {
                   3166:                ds=stackpos(s);
                   3167:                emit_byte(0xd9);
                   3168:                emit_byte(0xc0+ds); /* fld x */
                   3169:                emit_byte(0xd9);
                   3170:                emit_byte(0xff);    /* fcos cos(x) */
                   3171:                tos_make(d);        /* store to destination */
                   3172:        }
                   3173:        else {
                   3174:                make_tos(d);
                   3175:                emit_byte(0xd9);
                   3176:                emit_byte(0xff);    /* fcos y=cos(x) */
                   3177:        }
                   3178: }
                   3179: LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
                   3180: 
                   3181:        LOWFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s))
                   3182: {
                   3183:        int ds;
                   3184: 
                   3185:        if (d!=s) {
                   3186:                ds=stackpos(s);
                   3187:                emit_byte(0xd9);
                   3188:                emit_byte(0xc0+ds); /* fld x */
                   3189:                emit_byte(0xd9);
                   3190:                emit_byte(0xf2);    /* fptan tan(x)=y/1.0 */
                   3191:                emit_byte(0xdd);
                   3192:                emit_byte(0xd8);    /* fstp pop 1.0 */
                   3193:                tos_make(d);        /* store to destination */
                   3194:        }
                   3195:        else {
                   3196:                make_tos(d);
                   3197:                emit_byte(0xd9);
                   3198:                emit_byte(0xf2);    /* fptan tan(x)=y/1.0 */
                   3199:                emit_byte(0xdd);
                   3200:                emit_byte(0xd8);    /* fstp pop 1.0 */
                   3201:        }
                   3202: }
                   3203: LENDFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s))
                   3204: 
                   3205:        LOWFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s))
                   3206: {
                   3207:        int ds;
                   3208: 
                   3209:        if (s==d) {
                   3210:                //write_log (L"FSINCOS src = dest\n");
                   3211:                make_tos(s);
                   3212:                emit_byte(0xd9);
                   3213:                emit_byte(0xfb); /* fsincos sin(x) push cos(x) */
                   3214:                tos_make(c);     /* store cos(x) to c */
                   3215:                return;
                   3216:        }
                   3217: 
                   3218:        ds=stackpos(s);
                   3219:        emit_byte(0xd9);
                   3220:        emit_byte(0xc0+ds);  /* fld x */
                   3221:        emit_byte(0xd9);
                   3222:        emit_byte(0xfb);     /* fsincos sin(x) push cos(x) */
                   3223:        if (live.spos[c]<0) {
                   3224:                if (live.spos[d]<0) { /* occupy both regs directly */
                   3225:                        live.tos++;
                   3226:                        live.spos[d]=live.tos;
                   3227:                        live.onstack[live.tos]=d; /* sin(x) comes first */
                   3228:                        live.tos++;
                   3229:                        live.spos[c]=live.tos;
                   3230:                        live.onstack[live.tos]=c;
                   3231:                }
                   3232:                else {
                   3233:                        emit_byte(0xd9);
                   3234:                        emit_byte(0xc9); /* fxch swap cos(x) with sin(x) */
                   3235:                        emit_byte(0xdd); /* store sin(x) to d & pop */
                   3236:                        emit_byte(0xd8+(live.tos+2)-live.spos[d]);
                   3237:                        live.tos++;      /* occupy a reg for cos(x) here */
                   3238:                        live.spos[c]=live.tos;
                   3239:                        live.onstack[live.tos]=c;
                   3240:                }
                   3241:        }
                   3242:        else {
                   3243:                emit_byte(0xdd); /* store cos(x) to c & pop */
                   3244:                emit_byte(0xd8+(live.tos+2)-live.spos[c]);
                   3245:                tos_make(d);     /* store sin(x) to destination */
                   3246:        }
                   3247: }
                   3248: LENDFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s))
                   3249: 
                   3250:        float one=1;
                   3251: 
                   3252: LOWFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s))
                   3253: {
                   3254:        int ds;
                   3255: 
                   3256:        if (live.spos[d]==live.tos && live.spos[s]==live.tos-1) {
                   3257:                //write_log (L"fscale found x in TOS-1 and y in TOS\n");
                   3258:                emit_byte(0xd9);
                   3259:                emit_byte(0xfd);    /* fscale y*(2^x) */
                   3260:        }
                   3261:        else {
                   3262:                make_tos(s);        /* tos=x */
                   3263:                ds=stackpos(d);
                   3264:                emit_byte(0xd9);
                   3265:                emit_byte(0xc0+ds); /* fld y */
                   3266:                emit_byte(0xd9);
                   3267:                emit_byte(0xfd);    /* fscale y*(2^x) */
                   3268:                tos_make(d);        /* store y=y*(2^x) */
                   3269:        }
                   3270: }
                   3271: LENDFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s))
                   3272: 
                   3273:        LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
                   3274: {
                   3275:        int ds;
                   3276: 
                   3277:        ds=stackpos(s);
                   3278:        emit_byte(0xd9);
                   3279:        emit_byte(0xc0+ds); /* fld x */
                   3280:        emit_byte(0xd9);
                   3281:        emit_byte(0xfc);    /* frndint int(x) */
                   3282:        emit_byte(0xd9);
                   3283:        emit_byte(0xc1+ds); /* fld x again */
                   3284:        emit_byte(0xd8);
                   3285:        emit_byte(0xe1);    /* fsub frac(x) = x - int(x) */
                   3286:        emit_byte(0xd9);
                   3287:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
                   3288:        emit_byte(0xd8);
                   3289:        emit_byte(0x05);
                   3290:        emit_long((uae_u32)&one); /* fadd (2^frac(x))-1 + 1 */
                   3291:        emit_byte(0xd9);
                   3292:        emit_byte(0xfd);    /* fscale (2^frac(x))*2^int(x) */
                   3293:        emit_byte(0xdd);
                   3294:        emit_byte(0xd9);    /* fstp copy & pop */
                   3295:        tos_make(d);        /* store y=2^x */
                   3296: }
                   3297: LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
                   3298: 
                   3299:        LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
                   3300: {
                   3301:        int ds;
                   3302: 
                   3303:        if (s==d)
                   3304:                make_tos(s);
                   3305:        else {
                   3306:                ds=stackpos(s);
                   3307:                emit_byte(0xd9);
                   3308:                emit_byte(0xc0+ds); /* fld x */
                   3309:        }
                   3310:        emit_byte(0xd9);
                   3311:        emit_byte(0xea);    /* fldl2e log2(e) */
                   3312:        emit_byte(0xd8);
                   3313:        emit_byte(0xc9);    /* fmul x*log2(e) */
                   3314:        emit_byte(0xdd);
                   3315:        emit_byte(0xd1);    /* fst copy up */
                   3316:        emit_byte(0xd9);
                   3317:        emit_byte(0xfc);    /* frndint int(x*log2(e)) */
                   3318:        emit_byte(0xd9);
                   3319:        emit_byte(0xc9);    /* fxch swap top two elements */
                   3320:        emit_byte(0xd8);
                   3321:        emit_byte(0xe1);    /* fsub x*log2(e) - int(x*log2(e))  */
                   3322:        emit_byte(0xd9);
                   3323:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
                   3324:        emit_byte(0xd8);
                   3325:        emit_byte(0x05);
                   3326:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3327:        emit_byte(0xd9);
                   3328:        emit_byte(0xfd);    /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3329:        emit_byte(0xdd);
                   3330:        emit_byte(0xd9);    /* fstp copy & pop */
                   3331:        if (s!=d)
                   3332:                tos_make(d);    /* store y=e^x */
                   3333: }
                   3334: LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
                   3335: 
                   3336:        LOWFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s))
                   3337: {
                   3338:        int ds;
                   3339: 
                   3340:        if (s==d)
                   3341:                make_tos(s);
                   3342:        else {
                   3343:                ds=stackpos(s);
                   3344:                emit_byte(0xd9);
                   3345:                emit_byte(0xc0+ds); /* fld x */
                   3346:        }
                   3347:        emit_byte(0xd9);
                   3348:        emit_byte(0xea);    /* fldl2e log2(e) */
                   3349:        emit_byte(0xd8);
                   3350:        emit_byte(0xc9);    /* fmul x*log2(e) */
                   3351:        emit_byte(0xdd);
                   3352:        emit_byte(0xd1);    /* fst copy up */
                   3353:        emit_byte(0xd9);
                   3354:        emit_byte(0xfc);    /* frndint int(x*log2(e)) */
                   3355:        emit_byte(0xd9);
                   3356:        emit_byte(0xc9);    /* fxch swap top two elements */
                   3357:        emit_byte(0xd8);
                   3358:        emit_byte(0xe1);    /* fsub x*log2(e) - int(x*log2(e))  */
                   3359:        emit_byte(0xd9);
                   3360:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
                   3361:        emit_byte(0xd9);
                   3362:        emit_byte(0xfd);    /* fscale ((2^frac(x))-1)*2^int(x*log2(e)) */
                   3363:        emit_byte(0xdd);
                   3364:        emit_byte(0xd9);    /* fstp copy & pop */
                   3365:        if (s!=d)
                   3366:                tos_make(d);    /* store y=(e^x)-1 */
                   3367: }
                   3368: LENDFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s))
                   3369: 
                   3370:        LOWFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s))
                   3371: {
                   3372:        int ds;
                   3373: 
                   3374:        if (s==d)
                   3375:                make_tos(s);
                   3376:        else {
                   3377:                ds=stackpos(s);
                   3378:                emit_byte(0xd9);
                   3379:                emit_byte(0xc0+ds); /* fld x */
                   3380:        }
                   3381:        emit_byte(0xd9);
                   3382:        emit_byte(0xe9);    /* fldl2t log2(10) */
                   3383:        emit_byte(0xd8);
                   3384:        emit_byte(0xc9);    /* fmul x*log2(10) */
                   3385:        emit_byte(0xdd);
                   3386:        emit_byte(0xd1);    /* fst copy up */
                   3387:        emit_byte(0xd9);
                   3388:        emit_byte(0xfc);    /* frndint int(x*log2(10)) */
                   3389:        emit_byte(0xd9);
                   3390:        emit_byte(0xc9);    /* fxch swap top two elements */
                   3391:        emit_byte(0xd8);
                   3392:        emit_byte(0xe1);    /* fsub x*log2(10) - int(x*log2(10))  */
                   3393:        emit_byte(0xd9);
                   3394:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
                   3395:        emit_byte(0xd8);
                   3396:        emit_byte(0x05);
                   3397:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3398:        emit_byte(0xd9);
                   3399:        emit_byte(0xfd);    /* fscale (2^frac(x))*2^int(x*log2(10)) */
                   3400:        emit_byte(0xdd);
                   3401:        emit_byte(0xd9);    /* fstp copy & pop */
                   3402:        if (s!=d)
                   3403:                tos_make(d);    /* store y=10^x */
                   3404: }
                   3405: LENDFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s))
                   3406: 
                   3407:        LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
                   3408: {
                   3409:        int ds;
                   3410: 
                   3411:        if (s==d)
                   3412:                make_tos(s);
                   3413:        else {
                   3414:                ds=stackpos(s);
                   3415:                emit_byte(0xd9);
                   3416:                emit_byte(0xc0+ds); /* fld x */
                   3417:        }
                   3418:        emit_byte(0xd9);
                   3419:        emit_byte(0xe8);    /* fld1 1 */
                   3420:        emit_byte(0xd9);
                   3421:        emit_byte(0xc9);    /* fxch swap 1 with x */
                   3422:        emit_byte(0xd9);
                   3423:        emit_byte(0xf1);    /* fyl2x 1*log2(x) */
                   3424:        if (s!=d)
                   3425:                tos_make(d);    /* store y=log2(x) */
                   3426: }
                   3427: LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
                   3428: 
                   3429:        LOWFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s))
                   3430: {
                   3431:        int ds;
                   3432: 
                   3433:        if (s==d)
                   3434:                make_tos(s);
                   3435:        else {
                   3436:                ds=stackpos(s);
                   3437:                emit_byte(0xd9);
                   3438:                emit_byte(0xc0+ds); /* fld x */
                   3439:        }
                   3440:        emit_byte(0xd9);
                   3441:        emit_byte(0xed);    /* fldln2 logN(2) */
                   3442:        emit_byte(0xd9);
                   3443:        emit_byte(0xc9);    /* fxch swap logN(2) with x */
                   3444:        emit_byte(0xd9);
                   3445:        emit_byte(0xf1);    /* fyl2x logN(2)*log2(x) */
                   3446:        if (s!=d)
                   3447:                tos_make(d);    /* store y=logN(x) */
                   3448: }
                   3449: LENDFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s))
                   3450: 
                   3451:        LOWFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s))
                   3452: {
                   3453:        int ds;
                   3454: 
                   3455:        if (s==d)
                   3456:                make_tos(s);
                   3457:        else {
                   3458:                ds=stackpos(s);
                   3459:                emit_byte(0xd9);
                   3460:                emit_byte(0xc0+ds); /* fld x */
                   3461:        }
                   3462:        emit_byte(0xd9);
                   3463:        emit_byte(0xed);    /* fldln2 logN(2) */
                   3464:        emit_byte(0xd9);
                   3465:        emit_byte(0xc9);    /* fxch swap logN(2) with x */
                   3466:        emit_byte(0xd9);
                   3467:        emit_byte(0xf9);    /* fyl2xp1 logN(2)*log2(x+1) */
                   3468:        if (s!=d)
                   3469:                tos_make(d);    /* store y=logN(x+1) */
                   3470: }
                   3471: LENDFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s))
                   3472: 
                   3473:        LOWFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s))
                   3474: {
                   3475:        int ds;
                   3476: 
                   3477:        if (s==d)
                   3478:                make_tos(s);
                   3479:        else {
                   3480:                ds=stackpos(s);
                   3481:                emit_byte(0xd9);
                   3482:                emit_byte(0xc0+ds); /* fld x */
                   3483:        }
                   3484:        emit_byte(0xd9);
                   3485:        emit_byte(0xec);    /* fldlg2 log10(2) */
                   3486:        emit_byte(0xd9);
                   3487:        emit_byte(0xc9);    /* fxch swap log10(2) with x */
                   3488:        emit_byte(0xd9);
                   3489:        emit_byte(0xf1);    /* fyl2x log10(2)*log2(x) */
                   3490:        if (s!=d)
                   3491:                tos_make(d);    /* store y=log10(x) */
                   3492: }
                   3493: LENDFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s))
                   3494: 
                   3495:        LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s))
                   3496: {
                   3497:        int ds;
                   3498: 
                   3499:        ds=stackpos(s);
                   3500:        emit_byte(0xd9);
                   3501:        emit_byte(0xc0+ds); /* fld x */
                   3502:        emit_byte(0xd8);
                   3503:        emit_byte(0xc8);    /* fmul x*x */
                   3504:        emit_byte(0xd9);
                   3505:        emit_byte(0xe8);    /* fld 1.0 */
                   3506:        emit_byte(0xde);
                   3507:        emit_byte(0xe1);    /* fsubrp 1 - (x^2) */
                   3508:        emit_byte(0xd9);
                   3509:        emit_byte(0xfa);    /* fsqrt sqrt(1-(x^2)) */
                   3510:        emit_byte(0xd9);
                   3511:        emit_byte(0xc1+ds); /* fld x again */
                   3512:        emit_byte(0xd9);
                   3513:        emit_byte(0xc9);    /* fxch swap x with sqrt(1-(x^2))  */
                   3514:        emit_byte(0xd9);
                   3515:        emit_byte(0xf3);    /* fpatan atan(x/sqrt(1-(x^2))) & pop */
                   3516:        tos_make(d);        /* store y=asin(x) */
                   3517: }
                   3518: LENDFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s))
                   3519: 
                   3520:        static uae_u32 pihalf[] = {0x2168c234, 0xc90fdaa2, 0x3fff}; // LSB=0 to get acos(1)=0
                   3521: LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s))
                   3522: {
                   3523:        int ds;
                   3524: 
                   3525:        ds=stackpos(s);
                   3526:        emit_byte(0xd9);
                   3527:        emit_byte(0xc0+ds); /* fld x */
                   3528:        emit_byte(0xd8);
                   3529:        emit_byte(0xc8);    /* fmul x*x */
                   3530:        emit_byte(0xd9);
                   3531:        emit_byte(0xe8);    /* fld 1.0 */
                   3532:        emit_byte(0xde);
                   3533:        emit_byte(0xe1);    /* fsubrp 1 - (x^2) */
                   3534:        emit_byte(0xd9);
                   3535:        emit_byte(0xfa);    /* fsqrt sqrt(1-(x^2)) */
                   3536:        emit_byte(0xd9);
                   3537:        emit_byte(0xc1+ds); /* fld x again */
                   3538:        emit_byte(0xd9);
                   3539:        emit_byte(0xc9);    /* fxch swap x with sqrt(1-(x^2))  */
                   3540:        emit_byte(0xd9);
                   3541:        emit_byte(0xf3);    /* fpatan atan(x/sqrt(1-(x^2))) & pop */
                   3542:        emit_byte(0xdb);
                   3543:        emit_byte(0x2d);
                   3544:        emit_long((uae_u32)&pihalf); /* fld load pi/2 from pihalf */
                   3545:        emit_byte(0xde);
                   3546:        emit_byte(0xe1);    /* fsubrp pi/2 - asin(x) & pop */
                   3547:        tos_make(d);        /* store y=acos(x) */
                   3548: }
                   3549: LENDFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s))
                   3550: 
                   3551:        LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s))
                   3552: {
                   3553:        int ds;
                   3554: 
                   3555:        if (s==d)
                   3556:                make_tos(s);
                   3557:        else {
                   3558:                ds=stackpos(s);
                   3559:                emit_byte(0xd9);
                   3560:                emit_byte(0xc0+ds); /* fld x */
                   3561:        }
                   3562:        emit_byte(0xd9);
                   3563:        emit_byte(0xe8);    /* fld 1.0 */
                   3564:        emit_byte(0xd9);
                   3565:        emit_byte(0xf3);    /* fpatan atan(x)/1  & pop*/
                   3566:        if (s!=d)
                   3567:                tos_make(d);    /* store y=atan(x) */
                   3568: }
                   3569: LENDFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s))
                   3570: 
                   3571:        LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s))
                   3572: {
                   3573:        int ds;
                   3574: 
                   3575:        ds=stackpos(s);
                   3576:        emit_byte(0xd9);
                   3577:        emit_byte(0xc0+ds); /* fld x */
                   3578:        emit_byte(0xd9);
                   3579:        emit_byte(0xe8);    /* fld 1.0 */
                   3580:        emit_byte(0xdc);
                   3581:        emit_byte(0xc1);    /* fadd 1 + x */
                   3582:        emit_byte(0xd8);
                   3583:        emit_byte(0xe2+ds); /* fsub 1 - x */
                   3584:        emit_byte(0xde);
                   3585:        emit_byte(0xf9);    /* fdivp (1+x)/(1-x) */
                   3586:        emit_byte(0xd9);
                   3587:        emit_byte(0xed);    /* fldl2e logN(2) */
                   3588:        emit_byte(0xd9);
                   3589:        emit_byte(0xc9);    /* fxch swap logN(2) with (1+x)/(1-x) */
                   3590:        emit_byte(0xd9);
                   3591:        emit_byte(0xf1);    /* fyl2x logN(2)*log2((1+x)/(1-x)) pop */
                   3592:        emit_byte(0xd9);
                   3593:        emit_byte(0xe8);    /* fld 1.0 */
                   3594:        emit_byte(0xd9);
                   3595:        emit_byte(0xe0);    /* fchs -1.0 */
                   3596:        emit_byte(0xd9);
                   3597:        emit_byte(0xc9);    /* fxch swap */
                   3598:        emit_byte(0xd9);
                   3599:        emit_byte(0xfd);    /* fscale logN((1+x)/(1-x)) * 2^(-1) */
                   3600:        emit_byte(0xdd);
                   3601:        emit_byte(0xd9);    /* fstp copy & pop */
                   3602:        tos_make(d);        /* store y=atanh(x) */
                   3603: }
                   3604: LENDFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s))
                   3605: 
                   3606:        LOWFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s))
                   3607: {
                   3608:        int ds,tr;
                   3609: 
                   3610:        tr=live.onstack[live.tos+3];
                   3611:        if (s==d)
                   3612:                make_tos(s);
                   3613:        else {
                   3614:                ds=stackpos(s);
                   3615:                emit_byte(0xd9);
                   3616:                emit_byte(0xc0+ds); /* fld x */
                   3617:        }
                   3618:        emit_byte(0xd9);
                   3619:        emit_byte(0xea);     /* fldl2e log2(e) */
                   3620:        emit_byte(0xd8);
                   3621:        emit_byte(0xc9);     /* fmul x*log2(e) */
                   3622:        emit_byte(0xdd);
                   3623:        emit_byte(0xd1);     /* fst copy x*log2(e) */
                   3624:        if (tr>=0) {
                   3625:                emit_byte(0xd9);
                   3626:                emit_byte(0xca); /* fxch swap with temp-reg */
                   3627:                emit_byte(0x83);
                   3628:                emit_byte(0xc4);
                   3629:                emit_byte(0xf4); /* add -12 to esp */
                   3630:                emit_byte(0xdb);
                   3631:                emit_byte(0x3c);
                   3632:                emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */
                   3633:        }
                   3634:        emit_byte(0xd9);
                   3635:        emit_byte(0xe0);     /* fchs -x*log2(e) */
                   3636:        emit_byte(0xd9);
                   3637:        emit_byte(0xc0);     /* fld -x*log2(e) again */
                   3638:        emit_byte(0xd9);
                   3639:        emit_byte(0xfc);     /* frndint int(-x*log2(e)) */
                   3640:        emit_byte(0xd9);
                   3641:        emit_byte(0xc9);     /* fxch swap */
                   3642:        emit_byte(0xd8);
                   3643:        emit_byte(0xe1);     /* fsub -x*log2(e) - int(-x*log2(e))  */
                   3644:        emit_byte(0xd9);
                   3645:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
                   3646:        emit_byte(0xd8);
                   3647:        emit_byte(0x05);
                   3648:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3649:        emit_byte(0xd9);
                   3650:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3651:        emit_byte(0xd9);
                   3652:        emit_byte(0xca);     /* fxch swap e^-x with x*log2(e) in tr */
                   3653:        emit_byte(0xdd);
                   3654:        emit_byte(0xd1);     /* fst copy x*log2(e) */
                   3655:        emit_byte(0xd9);
                   3656:        emit_byte(0xfc);     /* frndint int(x*log2(e)) */
                   3657:        emit_byte(0xd9);
                   3658:        emit_byte(0xc9);     /* fxch swap */
                   3659:        emit_byte(0xd8);
                   3660:        emit_byte(0xe1);     /* fsub x*log2(e) - int(x*log2(e))  */
                   3661:        emit_byte(0xd9);
                   3662:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
                   3663:        emit_byte(0xd8);
                   3664:        emit_byte(0x05);
                   3665:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3666:        emit_byte(0xd9);
                   3667:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3668:        emit_byte(0xdd);
                   3669:        emit_byte(0xd9);     /* fstp copy e^x & pop */
                   3670:        if (tr>=0) {
                   3671:                emit_byte(0xdb);
                   3672:                emit_byte(0x2c);
                   3673:                emit_byte(0x24); /* fld load temp-reg from [esp] */
                   3674:                emit_byte(0x83);
                   3675:                emit_byte(0xc4);
                   3676:                emit_byte(0x0c); /* add +12 to esp */
                   3677:                emit_byte(0xd9);
                   3678:                emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */
                   3679:                emit_byte(0xde);
                   3680:                emit_byte(0xe9); /* fsubp (e^x)-(e^-x) */
                   3681:        }
                   3682:        else {
                   3683:                emit_byte(0xde);
                   3684:                emit_byte(0xe1); /* fsubrp (e^x)-(e^-x) */
                   3685:        }
                   3686:        emit_byte(0xd9);
                   3687:        emit_byte(0xe8);     /* fld 1.0 */
                   3688:        emit_byte(0xd9);
                   3689:        emit_byte(0xe0);     /* fchs -1.0 */
                   3690:        emit_byte(0xd9);
                   3691:        emit_byte(0xc9);     /* fxch swap */
                   3692:        emit_byte(0xd9);
                   3693:        emit_byte(0xfd);     /* fscale ((e^x)-(e^-x))/2 */
                   3694:        emit_byte(0xdd);
                   3695:        emit_byte(0xd9);     /* fstp copy & pop */
                   3696:        if (s!=d)
                   3697:                tos_make(d);     /* store y=sinh(x) */
                   3698: }
                   3699: LENDFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s))
                   3700: 
                   3701:        LOWFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s))
                   3702: {
                   3703:        int ds,tr;
                   3704: 
                   3705:        tr=live.onstack[live.tos+3];
                   3706:        if (s==d)
                   3707:                make_tos(s);
                   3708:        else {
                   3709:                ds=stackpos(s);
                   3710:                emit_byte(0xd9);
                   3711:                emit_byte(0xc0+ds); /* fld x */
                   3712:        }
                   3713:        emit_byte(0xd9);
                   3714:        emit_byte(0xea);     /* fldl2e log2(e) */
                   3715:        emit_byte(0xd8);
                   3716:        emit_byte(0xc9);     /* fmul x*log2(e) */
                   3717:        emit_byte(0xdd);
                   3718:        emit_byte(0xd1);     /* fst copy x*log2(e) */
                   3719:        if (tr>=0) {
                   3720:                emit_byte(0xd9);
                   3721:                emit_byte(0xca); /* fxch swap with temp-reg */
                   3722:                emit_byte(0x83);
                   3723:                emit_byte(0xc4);
                   3724:                emit_byte(0xf4); /* add -12 to esp */
                   3725:                emit_byte(0xdb);
                   3726:                emit_byte(0x3c);
                   3727:                emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */
                   3728:        }
                   3729:        emit_byte(0xd9);
                   3730:        emit_byte(0xe0);     /* fchs -x*log2(e) */
                   3731:        emit_byte(0xd9);
                   3732:        emit_byte(0xc0);     /* fld -x*log2(e) again */
                   3733:        emit_byte(0xd9);
                   3734:        emit_byte(0xfc);     /* frndint int(-x*log2(e)) */
                   3735:        emit_byte(0xd9);
                   3736:        emit_byte(0xc9);     /* fxch swap */
                   3737:        emit_byte(0xd8);
                   3738:        emit_byte(0xe1);     /* fsub -x*log2(e) - int(-x*log2(e))  */
                   3739:        emit_byte(0xd9);
                   3740:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
                   3741:        emit_byte(0xd8);
                   3742:        emit_byte(0x05);
                   3743:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3744:        emit_byte(0xd9);
                   3745:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3746:        emit_byte(0xd9);
                   3747:        emit_byte(0xca);     /* fxch swap e^-x with x*log2(e) in tr */
                   3748:        emit_byte(0xdd);
                   3749:        emit_byte(0xd1);     /* fst copy x*log2(e) */
                   3750:        emit_byte(0xd9);
                   3751:        emit_byte(0xfc);     /* frndint int(x*log2(e)) */
                   3752:        emit_byte(0xd9);
                   3753:        emit_byte(0xc9);     /* fxch swap */
                   3754:        emit_byte(0xd8);
                   3755:        emit_byte(0xe1);     /* fsub x*log2(e) - int(x*log2(e))  */
                   3756:        emit_byte(0xd9);
                   3757:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
                   3758:        emit_byte(0xd8);
                   3759:        emit_byte(0x05);
                   3760:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3761:        emit_byte(0xd9);
                   3762:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3763:        emit_byte(0xdd);
                   3764:        emit_byte(0xd9);     /* fstp copy e^x & pop */
                   3765:        if (tr>=0) {
                   3766:                emit_byte(0xdb);
                   3767:                emit_byte(0x2c);
                   3768:                emit_byte(0x24); /* fld load temp-reg from [esp] */
                   3769:                emit_byte(0x83);
                   3770:                emit_byte(0xc4);
                   3771:                emit_byte(0x0c); /* add +12 to esp */
                   3772:                emit_byte(0xd9);
                   3773:                emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */
                   3774:        }
                   3775:        emit_byte(0xde);
                   3776:        emit_byte(0xc1);     /* faddp (e^x)+(e^-x) */
                   3777:        emit_byte(0xd9);
                   3778:        emit_byte(0xe8);     /* fld 1.0 */
                   3779:        emit_byte(0xd9);
                   3780:        emit_byte(0xe0);     /* fchs -1.0 */
                   3781:        emit_byte(0xd9);
                   3782:        emit_byte(0xc9);     /* fxch swap */
                   3783:        emit_byte(0xd9);
                   3784:        emit_byte(0xfd);     /* fscale ((e^x)+(e^-x))/2 */
                   3785:        emit_byte(0xdd);
                   3786:        emit_byte(0xd9);     /* fstp copy & pop */
                   3787:        if (s!=d)
                   3788:                tos_make(d);     /* store y=cosh(x) */
                   3789: }
                   3790: LENDFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s))
                   3791: 
                   3792:        LOWFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s))
                   3793: {
                   3794:        int ds,tr;
                   3795: 
                   3796:        tr=live.onstack[live.tos+3];
                   3797:        if (s==d)
                   3798:                make_tos(s);
                   3799:        else {
                   3800:                ds=stackpos(s);
                   3801:                emit_byte(0xd9);
                   3802:                emit_byte(0xc0+ds); /* fld x */
                   3803:        }
                   3804:        emit_byte(0xd9);
                   3805:        emit_byte(0xea);     /* fldl2e log2(e) */
                   3806:        emit_byte(0xd8);
                   3807:        emit_byte(0xc9);     /* fmul x*log2(e) */
                   3808:        emit_byte(0xdd);
                   3809:        emit_byte(0xd1);     /* fst copy x*log2(e) */
                   3810:        if (tr>=0) {
                   3811:                emit_byte(0xd9);
                   3812:                emit_byte(0xca); /* fxch swap with temp-reg */
                   3813:                emit_byte(0x83);
                   3814:                emit_byte(0xc4);
                   3815:                emit_byte(0xf4); /* add -12 to esp */
                   3816:                emit_byte(0xdb);
                   3817:                emit_byte(0x3c);
                   3818:                emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */
                   3819:        }
                   3820:        emit_byte(0xd9);
                   3821:        emit_byte(0xe0);     /* fchs -x*log2(e) */
                   3822:        emit_byte(0xd9);
                   3823:        emit_byte(0xc0);     /* fld -x*log2(e) again */
                   3824:        emit_byte(0xd9);
                   3825:        emit_byte(0xfc);     /* frndint int(-x*log2(e)) */
                   3826:        emit_byte(0xd9);
                   3827:        emit_byte(0xc9);     /* fxch swap */
                   3828:        emit_byte(0xd8);
                   3829:        emit_byte(0xe1);     /* fsub -x*log2(e) - int(-x*log2(e))  */
                   3830:        emit_byte(0xd9);
                   3831:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
                   3832:        emit_byte(0xd8);
                   3833:        emit_byte(0x05);
                   3834:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3835:        emit_byte(0xd9);
                   3836:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3837:        emit_byte(0xd9);
                   3838:        emit_byte(0xca);     /* fxch swap e^-x with x*log2(e) */
                   3839:        emit_byte(0xdd);
                   3840:        emit_byte(0xd1);     /* fst copy x*log2(e) */
                   3841:        emit_byte(0xd9);
                   3842:        emit_byte(0xfc);     /* frndint int(x*log2(e)) */
                   3843:        emit_byte(0xd9);
                   3844:        emit_byte(0xc9);     /* fxch swap */
                   3845:        emit_byte(0xd8);
                   3846:        emit_byte(0xe1);     /* fsub x*log2(e) - int(x*log2(e))  */
                   3847:        emit_byte(0xd9);
                   3848:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
                   3849:        emit_byte(0xd8);
                   3850:        emit_byte(0x05);
                   3851:        emit_long((uae_u32)&one);  /* fadd (2^frac(x))-1 + 1 */
                   3852:        emit_byte(0xd9);
                   3853:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
                   3854:        emit_byte(0xdd);
                   3855:        emit_byte(0xd1);     /* fst copy e^x */
                   3856:        emit_byte(0xd8);
                   3857:        emit_byte(0xc2);     /* fadd (e^x)+(e^-x) */
                   3858:        emit_byte(0xd9);
                   3859:        emit_byte(0xca);     /* fxch swap with e^-x */
                   3860:        emit_byte(0xde);
                   3861:        emit_byte(0xe9);     /* fsubp (e^x)-(e^-x) */
                   3862:        if (tr>=0) {
                   3863:                emit_byte(0xdb);
                   3864:                emit_byte(0x2c);
                   3865:                emit_byte(0x24); /* fld load temp-reg from [esp] */
                   3866:                emit_byte(0x83);
                   3867:                emit_byte(0xc4);
                   3868:                emit_byte(0x0c); /* add +12 to esp */
                   3869:                emit_byte(0xd9);
                   3870:                emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */
                   3871:                emit_byte(0xde);
                   3872:                emit_byte(0xf9); /* fdivp ((e^x)-(e^-x))/((e^x)+(e^-x)) */
                   3873:        }
                   3874:        else {
                   3875:                emit_byte(0xde);
                   3876:                emit_byte(0xf1); /* fdivrp ((e^x)-(e^-x))/((e^x)+(e^-x)) */
                   3877:        }
                   3878:        if (s!=d)
                   3879:                tos_make(d);     /* store y=tanh(x) */
                   3880: }
                   3881: LENDFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s))
                   3882: 
                   3883:        LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
                   3884: {
                   3885:        int ds;
                   3886: 
                   3887:        if (d!=s) {
                   3888:                ds=stackpos(s);
                   3889:                emit_byte(0xd9);
                   3890:                emit_byte(0xc0+ds); /* duplicate source */
                   3891:                emit_byte(0xd9);
                   3892:                emit_byte(0xe0); /* take fchs */
                   3893:                tos_make(d); /* store to destination */
                   3894:        }
                   3895:        else {
                   3896:                make_tos(d);
                   3897:                emit_byte(0xd9);
                   3898:                emit_byte(0xe0); /* take fchs */
                   3899:        }
                   3900: }
                   3901: LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
                   3902: 
                   3903:        LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
                   3904: {
                   3905:        int ds;
                   3906: 
                   3907:        if (live.spos[s]==live.tos) {
                   3908:                /* Source is on top of stack */
                   3909:                ds=stackpos(d);
                   3910:                emit_byte(0xdc);
                   3911:                emit_byte(0xc0+ds); /* add source to dest*/
                   3912:        }
                   3913:        else {
                   3914:                make_tos(d);
                   3915:                ds=stackpos(s);
                   3916: 
                   3917:                emit_byte(0xd8);
                   3918:                emit_byte(0xc0+ds); /* add source to dest*/
                   3919:        }
                   3920: }
                   3921: LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
                   3922: 
                   3923:        LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
                   3924: {
                   3925:        int ds;
                   3926: 
                   3927:        if (live.spos[s]==live.tos) {
                   3928:                /* Source is on top of stack */
                   3929:                ds=stackpos(d);
                   3930:                emit_byte(0xdc);
                   3931:                emit_byte(0xe8+ds); /* sub source from dest*/
                   3932:        }
                   3933:        else {
                   3934:                make_tos(d);
                   3935:                ds=stackpos(s);
                   3936: 
                   3937:                emit_byte(0xd8);
                   3938:                emit_byte(0xe0+ds); /* sub src from dest */
                   3939:        }
                   3940: }
                   3941: LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
                   3942: 
                   3943:        LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
                   3944: {
                   3945:        int ds;
                   3946: 
                   3947:        make_tos(d);
                   3948:        ds=stackpos(s);
                   3949: 
                   3950:        emit_byte(0xdd);
                   3951:        emit_byte(0xe0+ds); /* cmp dest with source*/
                   3952: }
                   3953: LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
                   3954: 
                   3955:        LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
                   3956: {
                   3957:        int ds;
                   3958: 
                   3959:        if (live.spos[s]==live.tos) {
                   3960:                /* Source is on top of stack */
                   3961:                ds=stackpos(d);
                   3962:                emit_byte(0xdc);
                   3963:                emit_byte(0xc8+ds); /* mul dest by source*/
                   3964:        }
                   3965:        else {
                   3966:                make_tos(d);
                   3967:                ds=stackpos(s);
                   3968: 
                   3969:                emit_byte(0xd8);
                   3970:                emit_byte(0xc8+ds); /* mul dest by source*/
                   3971:        }
                   3972: }
                   3973: LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
                   3974: 
                   3975:        LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
                   3976: {
                   3977:        int ds;
                   3978: 
                   3979:        if (live.spos[s]==live.tos) {
                   3980:                /* Source is on top of stack */
                   3981:                ds=stackpos(d);
                   3982:                emit_byte(0xdc);
                   3983:                emit_byte(0xf8+ds); /* div dest by source */
                   3984:        }
                   3985:        else {
                   3986:                make_tos(d);
                   3987:                ds=stackpos(s);
                   3988: 
                   3989:                emit_byte(0xd8);
                   3990:                emit_byte(0xf0+ds); /* div dest by source*/
                   3991:        }
                   3992: }
                   3993: LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
                   3994: 
                   3995:        LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
                   3996: {
                   3997:        int ds;
                   3998: 
                   3999:        if (live.spos[d]==live.tos && live.spos[s]==live.tos-1) {
                   4000:                //write_log (L"frem found x in TOS-1 and y in TOS\n");
                   4001:                emit_byte(0xd9);
                   4002:                emit_byte(0xf8);    /* fprem rem(y/x) */
                   4003:        }
                   4004:        else {
                   4005:                make_tos(s);        /* tos=x */
                   4006:                ds=stackpos(d);
                   4007:                emit_byte(0xd9);
                   4008:                emit_byte(0xc0+ds); /* fld y */
                   4009:                emit_byte(0xd9);
                   4010:                emit_byte(0xf8);    /* fprem rem(y/x) */
                   4011:                tos_make(d);        /* store y=rem(y/x) */
                   4012:        }
                   4013: }
                   4014: LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
                   4015: 
                   4016:        LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
                   4017: {
                   4018:        int ds;
                   4019: 
                   4020:        if (live.spos[d]==live.tos && live.spos[s]==live.tos-1) {
                   4021:                //write_log (L"frem1 found x in TOS-1 and y in TOS\n");
                   4022:                emit_byte(0xd9);
                   4023:                emit_byte(0xf5);    /* fprem1 rem1(y/x) */
                   4024:        }
                   4025:        else {
                   4026:                make_tos(s);        /* tos=x */
                   4027:                ds=stackpos(d);
                   4028:                emit_byte(0xd9);
                   4029:                emit_byte(0xc0+ds); /* fld y */
                   4030:                emit_byte(0xd9);
                   4031:                emit_byte(0xf5);    /* fprem1 rem1(y/x) */
                   4032:                tos_make(d);        /* store y=rem(y/x) */
                   4033:        }
                   4034: }
                   4035: LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
                   4036: 
                   4037:        LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
                   4038: {
                   4039:        make_tos(r);
                   4040:        emit_byte(0xd9);  /* ftst */
                   4041:        emit_byte(0xe4);
                   4042: }
                   4043: LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
                   4044: 
                   4045:        STATIC_INLINE void raw_fflags_into_flags(int r)
                   4046: {
                   4047:        int p;
                   4048: 
                   4049:        usereg(r);
                   4050:        p=stackpos(r);
                   4051: 
                   4052:        emit_byte(0xd9);
                   4053:        emit_byte(0xee); /* Push 0 */
                   4054:        emit_byte(0xd9);
                   4055:        emit_byte(0xc9+p); /* swap top two around */
                   4056:        if (have_cmov) {
                   4057:                // gb-- fucomi is for P6 cores only, not K6-2 then...
                   4058:                emit_byte(0xdb);
                   4059:                emit_byte(0xe9+p); /* fucomi them */
                   4060:        }
                   4061:        else {
                   4062:                emit_byte(0xdd);
                   4063:                emit_byte(0xe1+p); /* fucom them */
                   4064:                emit_byte(0x9b);
                   4065:                emit_byte(0xdf);
                   4066:                emit_byte(0xe0); /* fstsw ax */
                   4067:                raw_sahf(0); /* sahf */
                   4068:        }
                   4069:        emit_byte(0xdd);
                   4070:        emit_byte(0xd9+p);  /* store value back, and get rid of 0 */
                   4071: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.