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

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

unix.superglobalmegacorp.com

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