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

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

unix.superglobalmegacorp.com

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