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

1.1     ! root        1: /*
        !             2:  *  compiler/codegen_x86.cpp - IA-32 code generator
        !             3:  *
        !             4:  *  Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer
        !             5:  *
        !             6:  *  Adaptation for Basilisk II and improvements, copyright 2000-2005
        !             7:  *    Gwenole Beauchesne
        !             8:  *
        !             9:  *  Basilisk II (C) 1997-2008 Christian Bauer
        !            10:  *
        !            11:  *  Portions related to CPU detection come from linux/arch/i386/kernel/setup.c
        !            12:  *  
        !            13:  *  This program is free software; you can redistribute it and/or modify
        !            14:  *  it under the terms of the GNU General Public License as published by
        !            15:  *  the Free Software Foundation; either version 2 of the License, or
        !            16:  *  (at your option) any later version.
        !            17:  *
        !            18:  *  This program is distributed in the hope that it will be useful,
        !            19:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            20:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            21:  *  GNU General Public License for more details.
        !            22:  *
        !            23:  *  You should have received a copy of the GNU General Public License
        !            24:  *  along with this program; if not, write to the Free Software
        !            25:  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            26:  */
        !            27: 
        !            28: /* This should eventually end up in machdep/, but for now, x86 is the
        !            29:    only target, and it's easier this way... */
        !            30: 
        !            31: #include "flags_x86.h"
        !            32: 
        !            33: /*************************************************************************
        !            34:  * Some basic information about the the target CPU                       *
        !            35:  *************************************************************************/
        !            36: 
        !            37: #define EAX_INDEX 0
        !            38: #define ECX_INDEX 1
        !            39: #define EDX_INDEX 2
        !            40: #define EBX_INDEX 3
        !            41: #define ESP_INDEX 4
        !            42: #define EBP_INDEX 5
        !            43: #define ESI_INDEX 6
        !            44: #define EDI_INDEX 7
        !            45: #if defined(__x86_64__)
        !            46: #define R8_INDEX  8
        !            47: #define R9_INDEX  9
        !            48: #define R10_INDEX 10
        !            49: #define R11_INDEX 11
        !            50: #define R12_INDEX 12
        !            51: #define R13_INDEX 13
        !            52: #define R14_INDEX 14
        !            53: #define R15_INDEX 15
        !            54: #endif
        !            55: /* XXX this has to match X86_Reg8H_Base + 4 */
        !            56: #define AH_INDEX (0x10+4+EAX_INDEX)
        !            57: #define CH_INDEX (0x10+4+ECX_INDEX)
        !            58: #define DH_INDEX (0x10+4+EDX_INDEX)
        !            59: #define BH_INDEX (0x10+4+EBX_INDEX)
        !            60: 
        !            61: /* The register in which subroutines return an integer return value */
        !            62: #define REG_RESULT EAX_INDEX
        !            63: 
        !            64: /* The registers subroutines take their first and second argument in */
        !            65: #if defined( _MSC_VER ) && !defined( USE_NORMAL_CALLING_CONVENTION )
        !            66: /* Handle the _fastcall parameters of ECX and EDX */
        !            67: #define REG_PAR1 ECX_INDEX
        !            68: #define REG_PAR2 EDX_INDEX
        !            69: #elif defined(__x86_64__)
        !            70: #define REG_PAR1 EDI_INDEX
        !            71: #define REG_PAR2 ESI_INDEX
        !            72: #else
        !            73: #define REG_PAR1 EAX_INDEX
        !            74: #define REG_PAR2 EDX_INDEX
        !            75: #endif
        !            76: 
        !            77: #define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */
        !            78: #if defined( _MSC_VER ) && !defined( USE_NORMAL_CALLING_CONVENTION )
        !            79: #define REG_PC_TMP EAX_INDEX
        !            80: #else
        !            81: #define REG_PC_TMP ECX_INDEX /* Another register that is not the above */
        !            82: #endif
        !            83: 
        !            84: #define SHIFTCOUNT_NREG ECX_INDEX  /* Register that can be used for shiftcount.
        !            85:                              -1 if any reg will do */
        !            86: #define MUL_NREG1 EAX_INDEX /* %eax will hold the low 32 bits after a 32x32 mul */
        !            87: #define MUL_NREG2 EDX_INDEX /* %edx will hold the high 32 bits */
        !            88: 
        !            89: #define STACK_ALIGN            16
        !            90: #define STACK_OFFSET   sizeof(void *)
        !            91: 
        !            92: uae_s8 always_used[]={4,-1};
        !            93: #if defined(__x86_64__)
        !            94: uae_s8 can_byte[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1};
        !            95: uae_s8 can_word[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1};
        !            96: #else
        !            97: uae_s8 can_byte[]={0,1,2,3,-1};
        !            98: uae_s8 can_word[]={0,1,2,3,5,6,7,-1};
        !            99: #endif
        !           100: 
        !           101: #if USE_OPTIMIZED_CALLS
        !           102: /* Make sure interpretive core does not use cpuopti */
        !           103: uae_u8 call_saved[]={0,0,0,1,1,1,1,1};
        !           104: #error FIXME: code not ready
        !           105: #else
        !           106: /* cpuopti mutate instruction handlers to assume registers are saved
        !           107:    by the caller */
        !           108: uae_u8 call_saved[]={0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0};
        !           109: #endif
        !           110: 
        !           111: /* This *should* be the same as call_saved. But:
        !           112:    - We might not really know which registers are saved, and which aren't,
        !           113:      so we need to preserve some, but don't want to rely on everyone else
        !           114:      also saving those registers
        !           115:    - Special registers (such like the stack pointer) should not be "preserved"
        !           116:      by pushing, even though they are "saved" across function calls
        !           117: */
        !           118: #if defined(__x86_64__)
        !           119: /* callee-saved registers as defined by Linux AMD64 ABI: rbx, rbp, rsp, r12 - r15 */
        !           120: /* preserve r11 because it's generally used to hold pointers to functions */
        !           121: static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1};
        !           122: #else
        !           123: /* callee-saved registers as defined by System V IA-32 ABI: edi, esi, ebx, ebp */
        !           124: static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,1,1};
        !           125: #endif
        !           126: 
        !           127: /* Whether classes of instructions do or don't clobber the native flags */
        !           128: #define CLOBBER_MOV
        !           129: #define CLOBBER_LEA
        !           130: #define CLOBBER_CMOV
        !           131: #define CLOBBER_POP
        !           132: #define CLOBBER_PUSH
        !           133: #define CLOBBER_SUB  clobber_flags()
        !           134: #define CLOBBER_SBB  clobber_flags()
        !           135: #define CLOBBER_CMP  clobber_flags()
        !           136: #define CLOBBER_ADD  clobber_flags()
        !           137: #define CLOBBER_ADC  clobber_flags()
        !           138: #define CLOBBER_AND  clobber_flags()
        !           139: #define CLOBBER_OR   clobber_flags()
        !           140: #define CLOBBER_XOR  clobber_flags()
        !           141: 
        !           142: #define CLOBBER_ROL  clobber_flags()
        !           143: #define CLOBBER_ROR  clobber_flags()
        !           144: #define CLOBBER_SHLL clobber_flags()
        !           145: #define CLOBBER_SHRL clobber_flags()
        !           146: #define CLOBBER_SHRA clobber_flags()
        !           147: #define CLOBBER_TEST clobber_flags()
        !           148: #define CLOBBER_CL16 
        !           149: #define CLOBBER_CL8  
        !           150: #define CLOBBER_SE32
        !           151: #define CLOBBER_SE16
        !           152: #define CLOBBER_SE8
        !           153: #define CLOBBER_ZE32
        !           154: #define CLOBBER_ZE16
        !           155: #define CLOBBER_ZE8
        !           156: #define CLOBBER_SW16 clobber_flags()
        !           157: #define CLOBBER_SW32
        !           158: #define CLOBBER_SETCC
        !           159: #define CLOBBER_MUL  clobber_flags()
        !           160: #define CLOBBER_BT   clobber_flags()
        !           161: #define CLOBBER_BSF  clobber_flags()
        !           162: 
        !           163: /* The older code generator is now deprecated.  */
        !           164: #define USE_NEW_RTASM 1
        !           165: 
        !           166: #if USE_NEW_RTASM
        !           167: 
        !           168: #if defined(__x86_64__)
        !           169: #define X86_TARGET_64BIT               1
        !           170: /* The address override prefix causes a 5 cycles penalty on Intel Core
        !           171:    processors. Another solution would be to decompose the load in an LEA,
        !           172:    MOV (to zero-extend), MOV (from memory): is it better? */
        !           173: #define ADDR32                                 x86_emit_byte(0x67),
        !           174: #else
        !           175: #define ADDR32                                 /**/
        !           176: #endif
        !           177: #define X86_FLAT_REGISTERS             0
        !           178: #define X86_OPTIMIZE_ALU               1
        !           179: #define X86_OPTIMIZE_ROTSHI            1
        !           180: #include "codegen_x86.h"
        !           181: 
        !           182: #define x86_emit_byte(B)               emit_byte(B)
        !           183: #define x86_emit_word(W)               emit_word(W)
        !           184: #define x86_emit_long(L)               emit_long(L)
        !           185: #define x86_emit_quad(Q)               emit_quad(Q)
        !           186: #define x86_get_target()               get_target()
        !           187: #define x86_emit_failure(MSG)  jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__)
        !           188: 
        !           189: static void jit_fail(const char *msg, const char *file, int line, const char *function)
        !           190: {
        !           191:        fprintf(stderr, "JIT failure in function %s from file %s at line %d: %s\n",
        !           192:                        function, file, line, msg);
        !           193:        abort();
        !           194: }
        !           195: 
        !           196: LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
        !           197: {
        !           198: #if defined(__x86_64__)
        !           199:        PUSHQr(r);
        !           200: #else
        !           201:        PUSHLr(r);
        !           202: #endif
        !           203: }
        !           204: LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
        !           205: 
        !           206: LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
        !           207: {
        !           208: #if defined(__x86_64__)
        !           209:        POPQr(r);
        !           210: #else
        !           211:        POPLr(r);
        !           212: #endif
        !           213: }
        !           214: LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
        !           215: 
        !           216: LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
        !           217: {
        !           218: #if defined(__x86_64__)
        !           219:        POPQm(d, X86_NOREG, X86_NOREG, 1);
        !           220: #else
        !           221:        POPLm(d, X86_NOREG, X86_NOREG, 1);
        !           222: #endif
        !           223: }
        !           224: LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
        !           225: 
        !           226: LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
        !           227: {
        !           228:        BTLir(i, r);
        !           229: }
        !           230: LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
        !           231: 
        !           232: LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
        !           233: {
        !           234:        BTLrr(b, r);
        !           235: }
        !           236: LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
        !           237: 
        !           238: LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
        !           239: {
        !           240:        BTCLir(i, r);
        !           241: }
        !           242: LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
        !           243: 
        !           244: LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
        !           245: {
        !           246:        BTCLrr(b, r);
        !           247: }
        !           248: LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
        !           249: 
        !           250: LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
        !           251: {
        !           252:        BTRLir(i, r);
        !           253: }
        !           254: LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
        !           255: 
        !           256: LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
        !           257: {
        !           258:        BTRLrr(b, r);
        !           259: }
        !           260: LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
        !           261: 
        !           262: LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
        !           263: {
        !           264:        BTSLir(i, r);
        !           265: }
        !           266: LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
        !           267: 
        !           268: LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
        !           269: {
        !           270:        BTSLrr(b, r);
        !           271: }
        !           272: LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
        !           273: 
        !           274: LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
        !           275: {
        !           276:        SUBWir(i, d);
        !           277: }
        !           278: LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
        !           279: 
        !           280: LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
        !           281: {
        !           282:        MOVLmr(s, X86_NOREG, X86_NOREG, 1, d);
        !           283: }
        !           284: LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
        !           285: 
        !           286: LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
        !           287: {
        !           288:        MOVLim(s, d, X86_NOREG, X86_NOREG, 1);
        !           289: }
        !           290: LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
        !           291: 
        !           292: LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
        !           293: {
        !           294:        MOVWim(s, d, X86_NOREG, X86_NOREG, 1);
        !           295: }
        !           296: LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
        !           297: 
        !           298: LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
        !           299: {
        !           300:        MOVBim(s, d, X86_NOREG, X86_NOREG, 1);
        !           301: }
        !           302: LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
        !           303: 
        !           304: LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
        !           305: {
        !           306:        ROLBim(i, d, X86_NOREG, X86_NOREG, 1);
        !           307: }
        !           308: LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
        !           309: 
        !           310: LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
        !           311: {
        !           312:        ROLBir(i, r);
        !           313: }
        !           314: LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
        !           315: 
        !           316: LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
        !           317: {
        !           318:        ROLWir(i, r);
        !           319: }
        !           320: LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
        !           321: 
        !           322: LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
        !           323: {
        !           324:        ROLLir(i, r);
        !           325: }
        !           326: LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
        !           327: 
        !           328: LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
        !           329: {
        !           330:        ROLLrr(r, d);
        !           331: }
        !           332: LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
        !           333: 
        !           334: LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
        !           335: {
        !           336:        ROLWrr(r, d);
        !           337: }
        !           338: LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
        !           339: 
        !           340: LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
        !           341: {
        !           342:        ROLBrr(r, d);
        !           343: }
        !           344: LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
        !           345: 
        !           346: LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
        !           347: {
        !           348:        SHLLrr(r, d);
        !           349: }
        !           350: LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
        !           351: 
        !           352: LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
        !           353: {
        !           354:        SHLWrr(r, d);
        !           355: }
        !           356: LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
        !           357: 
        !           358: LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
        !           359: {
        !           360:        SHLBrr(r, d);
        !           361: }
        !           362: LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
        !           363: 
        !           364: LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
        !           365: {
        !           366:        RORBir(i, r);
        !           367: }
        !           368: LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
        !           369: 
        !           370: LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
        !           371: {
        !           372:        RORWir(i, r);
        !           373: }
        !           374: LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
        !           375: 
        !           376: LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
        !           377: {
        !           378:        ORLmr(s, X86_NOREG, X86_NOREG, 1, d);
        !           379: }
        !           380: LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
        !           381: 
        !           382: LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
        !           383: {
        !           384:        RORLir(i, r);
        !           385: }
        !           386: LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
        !           387: 
        !           388: LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
        !           389: {
        !           390:        RORLrr(r, d);
        !           391: }
        !           392: LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
        !           393: 
        !           394: LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
        !           395: {
        !           396:        RORWrr(r, d);
        !           397: }
        !           398: LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
        !           399: 
        !           400: LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
        !           401: {
        !           402:        RORBrr(r, d);
        !           403: }
        !           404: LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
        !           405: 
        !           406: LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
        !           407: {
        !           408:        SHRLrr(r, d);
        !           409: }
        !           410: LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
        !           411: 
        !           412: LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
        !           413: {
        !           414:        SHRWrr(r, d);
        !           415: }
        !           416: LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
        !           417: 
        !           418: LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
        !           419: {
        !           420:        SHRBrr(r, d);
        !           421: }
        !           422: LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
        !           423: 
        !           424: LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
        !           425: {
        !           426:        SARLrr(r, d);
        !           427: }
        !           428: LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
        !           429: 
        !           430: LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
        !           431: {
        !           432:        SARWrr(r, d);
        !           433: }
        !           434: LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
        !           435: 
        !           436: LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
        !           437: {
        !           438:        SARBrr(r, d);
        !           439: }
        !           440: LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
        !           441: 
        !           442: LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
        !           443: {
        !           444:        SHLLir(i, r);
        !           445: }
        !           446: LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
        !           447: 
        !           448: LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
        !           449: {
        !           450:        SHLWir(i, r);
        !           451: }
        !           452: LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
        !           453: 
        !           454: LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
        !           455: {
        !           456:        SHLBir(i, r);
        !           457: }
        !           458: LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
        !           459: 
        !           460: LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
        !           461: {
        !           462:        SHRLir(i, r);
        !           463: }
        !           464: LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
        !           465: 
        !           466: LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
        !           467: {
        !           468:        SHRWir(i, r);
        !           469: }
        !           470: LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
        !           471: 
        !           472: LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
        !           473: {
        !           474:        SHRBir(i, r);
        !           475: }
        !           476: LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
        !           477: 
        !           478: LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
        !           479: {
        !           480:        SARLir(i, r);
        !           481: }
        !           482: LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
        !           483: 
        !           484: LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
        !           485: {
        !           486:        SARWir(i, r);
        !           487: }
        !           488: LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
        !           489: 
        !           490: LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
        !           491: {
        !           492:        SARBir(i, r);
        !           493: }
        !           494: LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
        !           495: 
        !           496: LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
        !           497: {
        !           498:        SAHF();
        !           499: }
        !           500: LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
        !           501: 
        !           502: LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
        !           503: {
        !           504:        CPUID();
        !           505: }
        !           506: LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
        !           507: 
        !           508: LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
        !           509: {
        !           510:        LAHF();
        !           511: }
        !           512: LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
        !           513: 
        !           514: LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
        !           515: {
        !           516:        SETCCir(cc, d);
        !           517: }
        !           518: LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
        !           519: 
        !           520: LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
        !           521: {
        !           522:        SETCCim(cc, d, X86_NOREG, X86_NOREG, 1);
        !           523: }
        !           524: LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
        !           525: 
        !           526: LOWFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc))
        !           527: {
        !           528:        /* replacement using branch and mov */
        !           529:        int8 *target_p = (int8 *)x86_get_target() + 1;
        !           530:        JCCSii(cc^1, 0);
        !           531:        MOVBrr(s, d);
        !           532:        *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
        !           533: }
        !           534: LENDFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc))
        !           535: 
        !           536: LOWFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc))
        !           537: {
        !           538:        if (have_cmov)
        !           539:                CMOVWrr(cc, s, d);
        !           540:        else { /* replacement using branch and mov */
        !           541:                int8 *target_p = (int8 *)x86_get_target() + 1;
        !           542:                JCCSii(cc^1, 0);
        !           543:                MOVWrr(s, d);
        !           544:            *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
        !           545:        }
        !           546: }
        !           547: LENDFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc))
        !           548: 
        !           549: LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
        !           550: {
        !           551:        if (have_cmov)
        !           552:                CMOVLrr(cc, s, d);
        !           553:        else { /* replacement using branch and mov */
        !           554:                int8 *target_p = (int8 *)x86_get_target() + 1;
        !           555:                JCCSii(cc^1, 0);
        !           556:                MOVLrr(s, d);
        !           557:            *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
        !           558:        }
        !           559: }
        !           560: LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
        !           561: 
        !           562: LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
        !           563: {
        !           564:        BSFLrr(s, d);
        !           565: }
        !           566: LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
        !           567: 
        !           568: LOWFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s))
        !           569: {
        !           570:        MOVSLQrr(s, d);
        !           571: }
        !           572: LENDFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s))
        !           573: 
        !           574: LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
        !           575: {
        !           576:        MOVSWLrr(s, d);
        !           577: }
        !           578: LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
        !           579: 
        !           580: LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
        !           581: {
        !           582:        MOVSBLrr(s, d);
        !           583: }
        !           584: LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
        !           585: 
        !           586: LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
        !           587: {
        !           588:        MOVZWLrr(s, d);
        !           589: }
        !           590: LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
        !           591: 
        !           592: LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
        !           593: {
        !           594:        MOVZBLrr(s, d);
        !           595: }
        !           596: LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
        !           597: 
        !           598: LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
        !           599: {
        !           600:        IMULLrr(s, d);
        !           601: }
        !           602: LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
        !           603: 
        !           604: LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
        !           605: {
        !           606:        if (d!=MUL_NREG1 || s!=MUL_NREG2) {
        !           607:        write_log("Bad register in IMUL: d=%d, s=%d\n",d,s);
        !           608:        abort();
        !           609:        }
        !           610:        IMULLr(s);
        !           611: }
        !           612: LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
        !           613: 
        !           614: LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
        !           615: {
        !           616:        if (d!=MUL_NREG1 || s!=MUL_NREG2) {
        !           617:        write_log("Bad register in MUL: d=%d, s=%d\n",d,s);
        !           618:        abort();
        !           619:        }
        !           620:        MULLr(s);
        !           621: }
        !           622: LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
        !           623: 
        !           624: LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
        !           625: {
        !           626:        abort(); /* %^$&%^$%#^ x86! */
        !           627: }
        !           628: LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
        !           629: 
        !           630: LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
        !           631: {
        !           632:        MOVBrr(s, d);
        !           633: }
        !           634: LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
        !           635: 
        !           636: LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
        !           637: {
        !           638:        MOVWrr(s, d);
        !           639: }
        !           640: LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
        !           641: 
        !           642: LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
        !           643: {
        !           644:        ADDR32 MOVLmr(0, baser, index, factor, d);
        !           645: }
        !           646: LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
        !           647: 
        !           648: LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
        !           649: {
        !           650:        ADDR32 MOVWmr(0, baser, index, factor, d);
        !           651: }
        !           652: LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
        !           653: 
        !           654: LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
        !           655: {
        !           656:        ADDR32 MOVBmr(0, baser, index, factor, d);
        !           657: }
        !           658: LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
        !           659: 
        !           660: LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
        !           661: {
        !           662:        ADDR32 MOVLrm(s, 0, baser, index, factor);
        !           663: }
        !           664: LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
        !           665: 
        !           666: LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
        !           667: {
        !           668:        ADDR32 MOVWrm(s, 0, baser, index, factor);
        !           669: }
        !           670: LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
        !           671: 
        !           672: LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
        !           673: {
        !           674:        ADDR32 MOVBrm(s, 0, baser, index, factor);
        !           675: }
        !           676: LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
        !           677: 
        !           678: LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
        !           679: {
        !           680:        ADDR32 MOVLrm(s, base, baser, index, factor);
        !           681: }
        !           682: LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
        !           683: 
        !           684: LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
        !           685: {
        !           686:        ADDR32 MOVWrm(s, base, baser, index, factor);
        !           687: }
        !           688: LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
        !           689: 
        !           690: LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
        !           691: {
        !           692:        ADDR32 MOVBrm(s, base, baser, index, factor);
        !           693: }
        !           694: LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
        !           695: 
        !           696: LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
        !           697: {
        !           698:        ADDR32 MOVLmr(base, baser, index, factor, d);
        !           699: }
        !           700: LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
        !           701: 
        !           702: LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
        !           703: {
        !           704:        ADDR32 MOVWmr(base, baser, index, factor, d);
        !           705: }
        !           706: LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
        !           707: 
        !           708: LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
        !           709: {
        !           710:        ADDR32 MOVBmr(base, baser, index, factor, d);
        !           711: }
        !           712: LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
        !           713: 
        !           714: LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
        !           715: {
        !           716:        ADDR32 MOVLmr(base, X86_NOREG, index, factor, d);
        !           717: }
        !           718: LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
        !           719: 
        !           720: LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
        !           721: {
        !           722:        if (have_cmov)
        !           723:                ADDR32 CMOVLmr(cond, base, X86_NOREG, index, factor, d);
        !           724:        else { /* replacement using branch and mov */
        !           725:                int8 *target_p = (int8 *)x86_get_target() + 1;
        !           726:                JCCSii(cond^1, 0);
        !           727:                ADDR32 MOVLmr(base, X86_NOREG, index, factor, d);
        !           728:            *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
        !           729:        }
        !           730: }
        !           731: LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
        !           732: 
        !           733: LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
        !           734: {
        !           735:        if (have_cmov)
        !           736:                CMOVLmr(cond, mem, X86_NOREG, X86_NOREG, 1, d);
        !           737:        else { /* replacement using branch and mov */
        !           738:                int8 *target_p = (int8 *)x86_get_target() + 1;
        !           739:                JCCSii(cond^1, 0);
        !           740:                MOVLmr(mem, X86_NOREG, X86_NOREG, 1, d);
        !           741:            *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
        !           742:        }
        !           743: }
        !           744: LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
        !           745: 
        !           746: LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
        !           747: {
        !           748:        ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d);
        !           749: }
        !           750: LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
        !           751: 
        !           752: LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
        !           753: {
        !           754:        ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d);
        !           755: }
        !           756: LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
        !           757: 
        !           758: LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
        !           759: {
        !           760:        ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d);
        !           761: }
        !           762: LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
        !           763: 
        !           764: LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
        !           765: {
        !           766:        ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d);
        !           767: }
        !           768: LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
        !           769: 
        !           770: LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
        !           771: {
        !           772:        ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d);
        !           773: }
        !           774: LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
        !           775: 
        !           776: LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
        !           777: {
        !           778:        ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d);
        !           779: }
        !           780: LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
        !           781: 
        !           782: LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
        !           783: {
        !           784:        ADDR32 MOVLim(i, offset, d, X86_NOREG, 1);
        !           785: }
        !           786: LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
        !           787: 
        !           788: LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
        !           789: {
        !           790:        ADDR32 MOVWim(i, offset, d, X86_NOREG, 1);
        !           791: }
        !           792: LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
        !           793: 
        !           794: LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
        !           795: {
        !           796:        ADDR32 MOVBim(i, offset, d, X86_NOREG, 1);
        !           797: }
        !           798: LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
        !           799: 
        !           800: LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
        !           801: {
        !           802:        ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1);
        !           803: }
        !           804: LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
        !           805: 
        !           806: LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
        !           807: {
        !           808:        ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1);
        !           809: }
        !           810: LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
        !           811: 
        !           812: LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
        !           813: {
        !           814:        ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1);
        !           815: }
        !           816: LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
        !           817: 
        !           818: LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
        !           819: {
        !           820:        LEALmr(offset, s, X86_NOREG, 1, d);
        !           821: }
        !           822: LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
        !           823: 
        !           824: LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
        !           825: {
        !           826:        LEALmr(offset, s, index, factor, d);
        !           827: }
        !           828: LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
        !           829: 
        !           830: LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
        !           831: {
        !           832:        LEALmr(0, s, index, factor, d);
        !           833: }
        !           834: LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
        !           835: 
        !           836: LOWFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor))
        !           837: {
        !           838:        LEALmr(0, X86_NOREG, index, factor, d);
        !           839: }
        !           840: LENDFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor))
        !           841: 
        !           842: LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
        !           843: {
        !           844:        ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1);
        !           845: }
        !           846: LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
        !           847: 
        !           848: LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
        !           849: {
        !           850:        ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1);
        !           851: }
        !           852: LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
        !           853: 
        !           854: LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
        !           855: {
        !           856:        ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1);
        !           857: }
        !           858: LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
        !           859: 
        !           860: LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
        !           861: {
        !           862:        BSWAPLr(r);
        !           863: }
        !           864: LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
        !           865: 
        !           866: LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
        !           867: {
        !           868:        ROLWir(8, r);
        !           869: }
        !           870: LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
        !           871: 
        !           872: LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
        !           873: {
        !           874:        MOVLrr(s, d);
        !           875: }
        !           876: LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
        !           877: 
        !           878: LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
        !           879: {
        !           880:        MOVLrm(s, d, X86_NOREG, X86_NOREG, 1);
        !           881: }
        !           882: LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
        !           883: 
        !           884: LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
        !           885: {
        !           886:        MOVWrm(s, d, X86_NOREG, X86_NOREG, 1);
        !           887: }
        !           888: LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
        !           889: 
        !           890: LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
        !           891: {
        !           892:        MOVWmr(s, X86_NOREG, X86_NOREG, 1, d);
        !           893: }
        !           894: LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
        !           895: 
        !           896: LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
        !           897: {
        !           898:        MOVBrm(s, d, X86_NOREG, X86_NOREG, 1);
        !           899: }
        !           900: LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
        !           901: 
        !           902: LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
        !           903: {
        !           904:        MOVBmr(s, X86_NOREG, X86_NOREG, 1, d);
        !           905: }
        !           906: LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
        !           907: 
        !           908: LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
        !           909: {
        !           910:        MOVLir(s, d);
        !           911: }
        !           912: LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
        !           913: 
        !           914: LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
        !           915: {
        !           916:        MOVWir(s, d);
        !           917: }
        !           918: LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
        !           919: 
        !           920: LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
        !           921: {
        !           922:        MOVBir(s, d);
        !           923: }
        !           924: LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
        !           925: 
        !           926: LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
        !           927: {
        !           928:        ADCLim(s, d, X86_NOREG, X86_NOREG, 1);
        !           929: }
        !           930: LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
        !           931: 
        !           932: LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) 
        !           933: {
        !           934:        ADDLim(s, d, X86_NOREG, X86_NOREG, 1);
        !           935: }
        !           936: LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) 
        !           937: 
        !           938: LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) 
        !           939: {
        !           940:        ADDWim(s, d, X86_NOREG, X86_NOREG, 1);
        !           941: }
        !           942: LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) 
        !           943: 
        !           944: LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) 
        !           945: {
        !           946:        ADDBim(s, d, X86_NOREG, X86_NOREG, 1);
        !           947: }
        !           948: LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) 
        !           949: 
        !           950: LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
        !           951: {
        !           952:        TESTLir(i, d);
        !           953: }
        !           954: LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
        !           955: 
        !           956: LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
        !           957: {
        !           958:        TESTLrr(s, d);
        !           959: }
        !           960: LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
        !           961: 
        !           962: LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
        !           963: {
        !           964:        TESTWrr(s, d);
        !           965: }
        !           966: LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
        !           967: 
        !           968: LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
        !           969: {
        !           970:        TESTBrr(s, d);
        !           971: }
        !           972: LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
        !           973: 
        !           974: LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
        !           975: {
        !           976:        XORLir(i, d);
        !           977: }
        !           978: LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
        !           979: 
        !           980: LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
        !           981: {
        !           982:        ANDLir(i, d);
        !           983: }
        !           984: LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
        !           985: 
        !           986: LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
        !           987: {
        !           988:        ANDWir(i, d);
        !           989: }
        !           990: LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
        !           991: 
        !           992: LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
        !           993: {
        !           994:        ANDLrr(s, d);
        !           995: }
        !           996: LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
        !           997: 
        !           998: LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
        !           999: {
        !          1000:        ANDWrr(s, d);
        !          1001: }
        !          1002: LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
        !          1003: 
        !          1004: LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
        !          1005: {
        !          1006:        ANDBrr(s, d);
        !          1007: }
        !          1008: LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
        !          1009: 
        !          1010: LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
        !          1011: {
        !          1012:        ORLir(i, d);
        !          1013: }
        !          1014: LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
        !          1015: 
        !          1016: LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
        !          1017: {
        !          1018:        ORLrr(s, d);
        !          1019: }
        !          1020: LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
        !          1021: 
        !          1022: LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
        !          1023: {
        !          1024:        ORWrr(s, d);
        !          1025: }
        !          1026: LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
        !          1027: 
        !          1028: LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
        !          1029: {
        !          1030:        ORBrr(s, d);
        !          1031: }
        !          1032: LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
        !          1033: 
        !          1034: LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
        !          1035: {
        !          1036:        ADCLrr(s, d);
        !          1037: }
        !          1038: LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
        !          1039: 
        !          1040: LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
        !          1041: {
        !          1042:        ADCWrr(s, d);
        !          1043: }
        !          1044: LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
        !          1045: 
        !          1046: LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
        !          1047: {
        !          1048:        ADCBrr(s, d);
        !          1049: }
        !          1050: LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
        !          1051: 
        !          1052: LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
        !          1053: {
        !          1054:        ADDLrr(s, d);
        !          1055: }
        !          1056: LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
        !          1057: 
        !          1058: LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
        !          1059: {
        !          1060:        ADDWrr(s, d);
        !          1061: }
        !          1062: LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
        !          1063: 
        !          1064: LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
        !          1065: {
        !          1066:        ADDBrr(s, d);
        !          1067: }
        !          1068: LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
        !          1069: 
        !          1070: LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
        !          1071: {
        !          1072:        SUBLir(i, d);
        !          1073: }
        !          1074: LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
        !          1075: 
        !          1076: LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
        !          1077: {
        !          1078:        SUBBir(i, d);
        !          1079: }
        !          1080: LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
        !          1081: 
        !          1082: LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
        !          1083: {
        !          1084:        ADDLir(i, d);
        !          1085: }
        !          1086: LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
        !          1087: 
        !          1088: LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
        !          1089: {
        !          1090:        ADDWir(i, d);
        !          1091: }
        !          1092: LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
        !          1093: 
        !          1094: LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
        !          1095: {
        !          1096:        ADDBir(i, d);
        !          1097: }
        !          1098: LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
        !          1099: 
        !          1100: LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
        !          1101: {
        !          1102:        SBBLrr(s, d);
        !          1103: }
        !          1104: LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
        !          1105: 
        !          1106: LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
        !          1107: {
        !          1108:        SBBWrr(s, d);
        !          1109: }
        !          1110: LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
        !          1111: 
        !          1112: LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
        !          1113: {
        !          1114:        SBBBrr(s, d);
        !          1115: }
        !          1116: LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
        !          1117: 
        !          1118: LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
        !          1119: {
        !          1120:        SUBLrr(s, d);
        !          1121: }
        !          1122: LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
        !          1123: 
        !          1124: LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
        !          1125: {
        !          1126:        SUBWrr(s, d);
        !          1127: }
        !          1128: LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
        !          1129: 
        !          1130: LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
        !          1131: {
        !          1132:        SUBBrr(s, d);
        !          1133: }
        !          1134: LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
        !          1135: 
        !          1136: LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
        !          1137: {
        !          1138:        CMPLrr(s, d);
        !          1139: }
        !          1140: LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
        !          1141: 
        !          1142: LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
        !          1143: {
        !          1144:        CMPLir(i, r);
        !          1145: }
        !          1146: LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
        !          1147: 
        !          1148: LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
        !          1149: {
        !          1150:        CMPWrr(s, d);
        !          1151: }
        !          1152: LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
        !          1153: 
        !          1154: LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
        !          1155: {
        !          1156:        CMPBim(s, d, X86_NOREG, X86_NOREG, 1);
        !          1157: }
        !          1158: LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
        !          1159: 
        !          1160: LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
        !          1161: {
        !          1162:        CMPBir(i, d);
        !          1163: }
        !          1164: LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
        !          1165: 
        !          1166: LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
        !          1167: {
        !          1168:        CMPBrr(s, d);
        !          1169: }
        !          1170: LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
        !          1171: 
        !          1172: LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
        !          1173: {
        !          1174:        ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d);
        !          1175: }
        !          1176: LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
        !          1177: 
        !          1178: LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
        !          1179: {
        !          1180:        XORLrr(s, d);
        !          1181: }
        !          1182: LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
        !          1183: 
        !          1184: LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
        !          1185: {
        !          1186:        XORWrr(s, d);
        !          1187: }
        !          1188: LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
        !          1189: 
        !          1190: LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
        !          1191: {
        !          1192:        XORBrr(s, d);
        !          1193: }
        !          1194: LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
        !          1195: 
        !          1196: LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
        !          1197: {
        !          1198:        SUBLim(s, d, X86_NOREG, X86_NOREG, 1);
        !          1199: }
        !          1200: LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
        !          1201: 
        !          1202: LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
        !          1203: {
        !          1204:        CMPLim(s, d, X86_NOREG, X86_NOREG, 1);
        !          1205: }
        !          1206: LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
        !          1207: 
        !          1208: LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
        !          1209: {
        !          1210:        XCHGLrr(r2, r1);
        !          1211: }
        !          1212: LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
        !          1213: 
        !          1214: LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2))
        !          1215: {
        !          1216:        XCHGBrr(r2, r1);
        !          1217: }
        !          1218: LENDFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2))
        !          1219: 
        !          1220: LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
        !          1221: {
        !          1222:        PUSHF();
        !          1223: }
        !          1224: LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
        !          1225: 
        !          1226: LOWFUNC(WRITE,READ,0,raw_popfl,(void))
        !          1227: {
        !          1228:        POPF();
        !          1229: }
        !          1230: LENDFUNC(WRITE,READ,0,raw_popfl,(void))
        !          1231: 
        !          1232: /* Generate floating-point instructions */
        !          1233: static inline void x86_fadd_m(MEMR s)
        !          1234: {
        !          1235:        FADDLm(s,X86_NOREG,X86_NOREG,1);
        !          1236: }
        !          1237: 
        !          1238: #else
        !          1239: 
        !          1240: const bool optimize_accum              = true;
        !          1241: const bool optimize_imm8               = true;
        !          1242: const bool optimize_shift_once = true;
        !          1243: 
        !          1244: /*************************************************************************
        !          1245:  * Actual encoding of the instructions on the target CPU                 *
        !          1246:  *************************************************************************/
        !          1247: 
        !          1248: static __inline__ int isaccum(int r)
        !          1249: {
        !          1250:        return (r == EAX_INDEX);
        !          1251: }
        !          1252: 
        !          1253: static __inline__ int isbyte(uae_s32 x)
        !          1254: {
        !          1255:        return (x>=-128 && x<=127);
        !          1256: }
        !          1257: 
        !          1258: static __inline__ int isword(uae_s32 x)
        !          1259: {
        !          1260:        return (x>=-32768 && x<=32767);
        !          1261: }
        !          1262: 
        !          1263: LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
        !          1264: {
        !          1265:        emit_byte(0x50+r);
        !          1266: }
        !          1267: LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
        !          1268: 
        !          1269: LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
        !          1270: {
        !          1271:        emit_byte(0x58+r);
        !          1272: }
        !          1273: LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
        !          1274: 
        !          1275: LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
        !          1276: {
        !          1277:        emit_byte(0x8f);
        !          1278:        emit_byte(0x05);
        !          1279:        emit_long(d);
        !          1280: }
        !          1281: LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
        !          1282: 
        !          1283: LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
        !          1284: {
        !          1285:        emit_byte(0x0f);
        !          1286:        emit_byte(0xba);
        !          1287:        emit_byte(0xe0+r);
        !          1288:        emit_byte(i);
        !          1289: }
        !          1290: LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
        !          1291: 
        !          1292: LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
        !          1293: {
        !          1294:        emit_byte(0x0f);
        !          1295:        emit_byte(0xa3);
        !          1296:        emit_byte(0xc0+8*b+r);
        !          1297: }
        !          1298: LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
        !          1299: 
        !          1300: LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
        !          1301: {
        !          1302:        emit_byte(0x0f);
        !          1303:        emit_byte(0xba);
        !          1304:        emit_byte(0xf8+r);
        !          1305:        emit_byte(i);
        !          1306: }
        !          1307: LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
        !          1308: 
        !          1309: LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
        !          1310: {
        !          1311:        emit_byte(0x0f);
        !          1312:        emit_byte(0xbb);
        !          1313:        emit_byte(0xc0+8*b+r);
        !          1314: }
        !          1315: LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
        !          1316: 
        !          1317: 
        !          1318: LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
        !          1319: {
        !          1320:        emit_byte(0x0f);
        !          1321:        emit_byte(0xba);
        !          1322:        emit_byte(0xf0+r);
        !          1323:        emit_byte(i);
        !          1324: }
        !          1325: LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
        !          1326: 
        !          1327: LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
        !          1328: {
        !          1329:        emit_byte(0x0f);
        !          1330:        emit_byte(0xb3);
        !          1331:        emit_byte(0xc0+8*b+r);
        !          1332: }
        !          1333: LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
        !          1334: 
        !          1335: LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
        !          1336: {
        !          1337:        emit_byte(0x0f);
        !          1338:        emit_byte(0xba);
        !          1339:        emit_byte(0xe8+r);
        !          1340:        emit_byte(i);
        !          1341: }
        !          1342: LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
        !          1343: 
        !          1344: LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
        !          1345: {
        !          1346:        emit_byte(0x0f);
        !          1347:        emit_byte(0xab);
        !          1348:        emit_byte(0xc0+8*b+r);
        !          1349: }
        !          1350: LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
        !          1351: 
        !          1352: LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
        !          1353: {
        !          1354:     emit_byte(0x66);
        !          1355:     if (isbyte(i)) {
        !          1356:        emit_byte(0x83);
        !          1357:        emit_byte(0xe8+d);
        !          1358:        emit_byte(i);
        !          1359:     }
        !          1360:     else {
        !          1361:        if (optimize_accum && isaccum(d))
        !          1362:        emit_byte(0x2d);
        !          1363:        else {
        !          1364:        emit_byte(0x81);
        !          1365:        emit_byte(0xe8+d);
        !          1366:        }
        !          1367:        emit_word(i);
        !          1368:     }
        !          1369: }
        !          1370: LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
        !          1371: 
        !          1372: 
        !          1373: LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
        !          1374: {
        !          1375:     emit_byte(0x8b);
        !          1376:     emit_byte(0x05+8*d);
        !          1377:     emit_long(s);
        !          1378: }
        !          1379: LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
        !          1380: 
        !          1381: LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
        !          1382: {
        !          1383:     emit_byte(0xc7);
        !          1384:     emit_byte(0x05);
        !          1385:     emit_long(d);
        !          1386:     emit_long(s);
        !          1387: }
        !          1388: LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
        !          1389: 
        !          1390: LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
        !          1391: {
        !          1392:     emit_byte(0x66);
        !          1393:     emit_byte(0xc7);
        !          1394:     emit_byte(0x05);
        !          1395:     emit_long(d);
        !          1396:     emit_word(s);
        !          1397: }
        !          1398: LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
        !          1399: 
        !          1400: LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
        !          1401: {
        !          1402:     emit_byte(0xc6);
        !          1403:     emit_byte(0x05);
        !          1404:     emit_long(d);
        !          1405:     emit_byte(s);
        !          1406: }
        !          1407: LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
        !          1408: 
        !          1409: LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
        !          1410: {
        !          1411:        if (optimize_shift_once && (i == 1)) {
        !          1412:        emit_byte(0xd0);
        !          1413:        emit_byte(0x05);
        !          1414:        emit_long(d);
        !          1415:        }
        !          1416:        else {
        !          1417:     emit_byte(0xc0);
        !          1418:     emit_byte(0x05);
        !          1419:     emit_long(d);
        !          1420:     emit_byte(i);
        !          1421:        }
        !          1422: }
        !          1423: LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
        !          1424: 
        !          1425: LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
        !          1426: {
        !          1427:        if (optimize_shift_once && (i == 1)) {
        !          1428:     emit_byte(0xd0);
        !          1429:     emit_byte(0xc0+r);
        !          1430:        }
        !          1431:        else {
        !          1432:     emit_byte(0xc0);
        !          1433:     emit_byte(0xc0+r);
        !          1434:     emit_byte(i);
        !          1435:        }
        !          1436: }
        !          1437: LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
        !          1438: 
        !          1439: LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
        !          1440: {
        !          1441:     emit_byte(0x66);
        !          1442:     emit_byte(0xc1);
        !          1443:     emit_byte(0xc0+r);
        !          1444:     emit_byte(i);
        !          1445: }
        !          1446: LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
        !          1447: 
        !          1448: LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
        !          1449: {
        !          1450:        if (optimize_shift_once && (i == 1)) {
        !          1451:     emit_byte(0xd1);
        !          1452:     emit_byte(0xc0+r);
        !          1453:        }
        !          1454:        else {
        !          1455:     emit_byte(0xc1);
        !          1456:     emit_byte(0xc0+r);
        !          1457:     emit_byte(i);
        !          1458:        }
        !          1459: }
        !          1460: LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
        !          1461: 
        !          1462: LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
        !          1463: {
        !          1464:     emit_byte(0xd3);
        !          1465:     emit_byte(0xc0+d);
        !          1466: }
        !          1467: LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
        !          1468: 
        !          1469: LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
        !          1470: {
        !          1471:     emit_byte(0x66);
        !          1472:     emit_byte(0xd3);
        !          1473:     emit_byte(0xc0+d);
        !          1474: }
        !          1475: LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
        !          1476: 
        !          1477: LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
        !          1478: {
        !          1479:     emit_byte(0xd2);
        !          1480:     emit_byte(0xc0+d);
        !          1481: }
        !          1482: LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
        !          1483: 
        !          1484: LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
        !          1485: {
        !          1486:     emit_byte(0xd3);
        !          1487:     emit_byte(0xe0+d);
        !          1488: }
        !          1489: LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
        !          1490: 
        !          1491: LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
        !          1492: {
        !          1493:     emit_byte(0x66);
        !          1494:     emit_byte(0xd3);
        !          1495:     emit_byte(0xe0+d);
        !          1496: }
        !          1497: LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
        !          1498: 
        !          1499: LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
        !          1500: {
        !          1501:     emit_byte(0xd2);
        !          1502:     emit_byte(0xe0+d);
        !          1503: }
        !          1504: LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
        !          1505: 
        !          1506: LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
        !          1507: {
        !          1508:        if (optimize_shift_once && (i == 1)) {
        !          1509:     emit_byte(0xd0);
        !          1510:     emit_byte(0xc8+r);
        !          1511:        }
        !          1512:        else {
        !          1513:     emit_byte(0xc0);
        !          1514:     emit_byte(0xc8+r);
        !          1515:     emit_byte(i);
        !          1516:        }
        !          1517: }
        !          1518: LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
        !          1519: 
        !          1520: LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
        !          1521: {
        !          1522:     emit_byte(0x66);
        !          1523:     emit_byte(0xc1);
        !          1524:     emit_byte(0xc8+r);
        !          1525:     emit_byte(i);
        !          1526: }
        !          1527: LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
        !          1528: 
        !          1529: // gb-- used for making an fpcr value in compemu_fpp.cpp
        !          1530: LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
        !          1531: {
        !          1532:     emit_byte(0x0b);
        !          1533:     emit_byte(0x05+8*d);
        !          1534:     emit_long(s);
        !          1535: }
        !          1536: LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
        !          1537: 
        !          1538: LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
        !          1539: {
        !          1540:        if (optimize_shift_once && (i == 1)) {
        !          1541:     emit_byte(0xd1);
        !          1542:     emit_byte(0xc8+r);
        !          1543:        }
        !          1544:        else {
        !          1545:     emit_byte(0xc1);
        !          1546:     emit_byte(0xc8+r);
        !          1547:     emit_byte(i);
        !          1548:        }
        !          1549: }
        !          1550: LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
        !          1551: 
        !          1552: LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
        !          1553: {
        !          1554:     emit_byte(0xd3);
        !          1555:     emit_byte(0xc8+d);
        !          1556: }
        !          1557: LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
        !          1558: 
        !          1559: LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
        !          1560: {
        !          1561:     emit_byte(0x66);
        !          1562:     emit_byte(0xd3);
        !          1563:     emit_byte(0xc8+d);
        !          1564: }
        !          1565: LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
        !          1566: 
        !          1567: LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
        !          1568: {
        !          1569:     emit_byte(0xd2);
        !          1570:     emit_byte(0xc8+d);
        !          1571: }
        !          1572: LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
        !          1573: 
        !          1574: LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
        !          1575: {
        !          1576:     emit_byte(0xd3);
        !          1577:     emit_byte(0xe8+d);
        !          1578: }
        !          1579: LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
        !          1580: 
        !          1581: LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
        !          1582: {
        !          1583:     emit_byte(0x66);
        !          1584:     emit_byte(0xd3);
        !          1585:     emit_byte(0xe8+d);
        !          1586: }
        !          1587: LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
        !          1588: 
        !          1589: LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
        !          1590: {
        !          1591:     emit_byte(0xd2);
        !          1592:     emit_byte(0xe8+d);
        !          1593: }
        !          1594: LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
        !          1595: 
        !          1596: LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
        !          1597: {
        !          1598:     emit_byte(0xd3);
        !          1599:     emit_byte(0xf8+d);
        !          1600: }
        !          1601: LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
        !          1602: 
        !          1603: LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
        !          1604: {
        !          1605:     emit_byte(0x66);
        !          1606:     emit_byte(0xd3);
        !          1607:     emit_byte(0xf8+d);
        !          1608: }
        !          1609: LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
        !          1610: 
        !          1611: LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
        !          1612: {
        !          1613:     emit_byte(0xd2);
        !          1614:     emit_byte(0xf8+d);
        !          1615: }
        !          1616: LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
        !          1617: 
        !          1618: LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
        !          1619: {
        !          1620:        if (optimize_shift_once && (i == 1)) {
        !          1621:     emit_byte(0xd1);
        !          1622:     emit_byte(0xe0+r);
        !          1623:        }
        !          1624:        else {
        !          1625:     emit_byte(0xc1);
        !          1626:     emit_byte(0xe0+r);
        !          1627:     emit_byte(i);
        !          1628:        }
        !          1629: }
        !          1630: LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
        !          1631: 
        !          1632: LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
        !          1633: {
        !          1634:     emit_byte(0x66);
        !          1635:     emit_byte(0xc1);
        !          1636:     emit_byte(0xe0+r);
        !          1637:     emit_byte(i);
        !          1638: }
        !          1639: LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
        !          1640: 
        !          1641: LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
        !          1642: {
        !          1643:        if (optimize_shift_once && (i == 1)) {
        !          1644:     emit_byte(0xd0);
        !          1645:     emit_byte(0xe0+r);
        !          1646:        }
        !          1647:        else {
        !          1648:     emit_byte(0xc0);
        !          1649:     emit_byte(0xe0+r);
        !          1650:     emit_byte(i);
        !          1651:        }
        !          1652: }
        !          1653: LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
        !          1654: 
        !          1655: LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
        !          1656: {
        !          1657:        if (optimize_shift_once && (i == 1)) {
        !          1658:     emit_byte(0xd1);
        !          1659:     emit_byte(0xe8+r);
        !          1660:        }
        !          1661:        else {
        !          1662:     emit_byte(0xc1);
        !          1663:     emit_byte(0xe8+r);
        !          1664:     emit_byte(i);
        !          1665:        }
        !          1666: }
        !          1667: LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
        !          1668: 
        !          1669: LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
        !          1670: {
        !          1671:     emit_byte(0x66);
        !          1672:     emit_byte(0xc1);
        !          1673:     emit_byte(0xe8+r);
        !          1674:     emit_byte(i);
        !          1675: }
        !          1676: LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
        !          1677: 
        !          1678: LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
        !          1679: {
        !          1680:        if (optimize_shift_once && (i == 1)) {
        !          1681:     emit_byte(0xd0);
        !          1682:     emit_byte(0xe8+r);
        !          1683:        }
        !          1684:        else {
        !          1685:     emit_byte(0xc0);
        !          1686:     emit_byte(0xe8+r);
        !          1687:     emit_byte(i);
        !          1688:        }
        !          1689: }
        !          1690: LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
        !          1691: 
        !          1692: LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
        !          1693: {
        !          1694:        if (optimize_shift_once && (i == 1)) {
        !          1695:     emit_byte(0xd1);
        !          1696:     emit_byte(0xf8+r);
        !          1697:        }
        !          1698:        else {
        !          1699:     emit_byte(0xc1);
        !          1700:     emit_byte(0xf8+r);
        !          1701:     emit_byte(i);
        !          1702:        }
        !          1703: }
        !          1704: LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
        !          1705: 
        !          1706: LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
        !          1707: {
        !          1708:     emit_byte(0x66);
        !          1709:     emit_byte(0xc1);
        !          1710:     emit_byte(0xf8+r);
        !          1711:     emit_byte(i);
        !          1712: }
        !          1713: LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
        !          1714: 
        !          1715: LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
        !          1716: {
        !          1717:        if (optimize_shift_once && (i == 1)) {
        !          1718:     emit_byte(0xd0);
        !          1719:     emit_byte(0xf8+r);
        !          1720:        }
        !          1721:        else {
        !          1722:     emit_byte(0xc0);
        !          1723:     emit_byte(0xf8+r);
        !          1724:     emit_byte(i);
        !          1725:        }
        !          1726: }
        !          1727: LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
        !          1728: 
        !          1729: LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
        !          1730: {
        !          1731:     emit_byte(0x9e);
        !          1732: }
        !          1733: LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
        !          1734: 
        !          1735: LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
        !          1736: {
        !          1737:     emit_byte(0x0f);
        !          1738:     emit_byte(0xa2);
        !          1739: }
        !          1740: LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
        !          1741: 
        !          1742: LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
        !          1743: {
        !          1744:     emit_byte(0x9f);
        !          1745: }
        !          1746: LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
        !          1747: 
        !          1748: LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
        !          1749: {
        !          1750:     emit_byte(0x0f);
        !          1751:     emit_byte(0x90+cc);
        !          1752:     emit_byte(0xc0+d);
        !          1753: }
        !          1754: LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
        !          1755: 
        !          1756: LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
        !          1757: {
        !          1758:     emit_byte(0x0f);
        !          1759:     emit_byte(0x90+cc);
        !          1760:     emit_byte(0x05);
        !          1761:     emit_long(d);
        !          1762: }
        !          1763: LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
        !          1764: 
        !          1765: LOWFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc))
        !          1766: {
        !          1767:        /* replacement using branch and mov */
        !          1768:        int uncc=(cc^1);
        !          1769:        emit_byte(0x70+uncc); 
        !          1770:        emit_byte(3);  /* skip next 2 bytes if not cc=true */
        !          1771:     emit_byte(0x88);
        !          1772:     emit_byte(0xc0+8*s+d);
        !          1773: }
        !          1774: LENDFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc))
        !          1775: 
        !          1776: LOWFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc))
        !          1777: {
        !          1778:     if (have_cmov) {
        !          1779:        emit_byte(0x66);
        !          1780:        emit_byte(0x0f);
        !          1781:        emit_byte(0x40+cc);
        !          1782:        emit_byte(0xc0+8*d+s);
        !          1783:     }
        !          1784:     else { /* replacement using branch and mov */
        !          1785:        int uncc=(cc^1);
        !          1786:        emit_byte(0x70+uncc); 
        !          1787:        emit_byte(3);  /* skip next 3 bytes if not cc=true */
        !          1788:        emit_byte(0x66);
        !          1789:        emit_byte(0x89);
        !          1790:        emit_byte(0xc0+8*s+d);
        !          1791:     }
        !          1792: }
        !          1793: LENDFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc))
        !          1794: 
        !          1795: LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
        !          1796: {
        !          1797:     if (have_cmov) {
        !          1798:        emit_byte(0x0f);
        !          1799:        emit_byte(0x40+cc);
        !          1800:        emit_byte(0xc0+8*d+s);
        !          1801:     }
        !          1802:     else { /* replacement using branch and mov */
        !          1803:        int uncc=(cc^1);
        !          1804:        emit_byte(0x70+uncc); 
        !          1805:        emit_byte(2);  /* skip next 2 bytes if not cc=true */
        !          1806:        emit_byte(0x89);
        !          1807:        emit_byte(0xc0+8*s+d);
        !          1808:     }
        !          1809: }
        !          1810: LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
        !          1811: 
        !          1812: LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
        !          1813: {
        !          1814:     emit_byte(0x0f);
        !          1815:     emit_byte(0xbc);
        !          1816:     emit_byte(0xc0+8*d+s);
        !          1817: }
        !          1818: LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
        !          1819: 
        !          1820: LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
        !          1821: {
        !          1822:     emit_byte(0x0f);
        !          1823:     emit_byte(0xbf);
        !          1824:     emit_byte(0xc0+8*d+s);
        !          1825: }
        !          1826: LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
        !          1827: 
        !          1828: LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
        !          1829: {
        !          1830:     emit_byte(0x0f);
        !          1831:     emit_byte(0xbe);
        !          1832:     emit_byte(0xc0+8*d+s);
        !          1833: }
        !          1834: LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
        !          1835: 
        !          1836: LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
        !          1837: {
        !          1838:     emit_byte(0x0f);
        !          1839:     emit_byte(0xb7);
        !          1840:     emit_byte(0xc0+8*d+s);
        !          1841: }
        !          1842: LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
        !          1843: 
        !          1844: LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
        !          1845: {
        !          1846:     emit_byte(0x0f);
        !          1847:     emit_byte(0xb6);
        !          1848:     emit_byte(0xc0+8*d+s);
        !          1849: }
        !          1850: LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
        !          1851: 
        !          1852: LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
        !          1853: {
        !          1854:     emit_byte(0x0f);
        !          1855:     emit_byte(0xaf);
        !          1856:     emit_byte(0xc0+8*d+s);
        !          1857: }
        !          1858: LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
        !          1859: 
        !          1860: LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
        !          1861: {
        !          1862:     if (d!=MUL_NREG1 || s!=MUL_NREG2)
        !          1863:        abort();
        !          1864:     emit_byte(0xf7);
        !          1865:     emit_byte(0xea);
        !          1866: }
        !          1867: LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
        !          1868: 
        !          1869: LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
        !          1870: {
        !          1871:     if (d!=MUL_NREG1 || s!=MUL_NREG2) {
        !          1872:        printf("Bad register in MUL: d=%d, s=%d\n",d,s);
        !          1873:        abort();
        !          1874:     }
        !          1875:     emit_byte(0xf7);
        !          1876:     emit_byte(0xe2);
        !          1877: }
        !          1878: LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
        !          1879: 
        !          1880: LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
        !          1881: {
        !          1882:     abort(); /* %^$&%^$%#^ x86! */
        !          1883:     emit_byte(0x0f);
        !          1884:     emit_byte(0xaf);
        !          1885:     emit_byte(0xc0+8*d+s);
        !          1886: }
        !          1887: LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
        !          1888: 
        !          1889: LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
        !          1890: {
        !          1891:     emit_byte(0x88);
        !          1892:     emit_byte(0xc0+8*s+d);
        !          1893: }
        !          1894: LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
        !          1895: 
        !          1896: LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
        !          1897: {
        !          1898:     emit_byte(0x66);
        !          1899:     emit_byte(0x89);
        !          1900:     emit_byte(0xc0+8*s+d);
        !          1901: }
        !          1902: LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
        !          1903: 
        !          1904: LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
        !          1905: {
        !          1906:     int isebp=(baser==5)?0x40:0;
        !          1907:     int fi;
        !          1908:     
        !          1909:     switch(factor) {
        !          1910:      case 1: fi=0; break;
        !          1911:      case 2: fi=1; break;
        !          1912:      case 4: fi=2; break;
        !          1913:      case 8: fi=3; break;
        !          1914:      default: abort();
        !          1915:     }
        !          1916: 
        !          1917: 
        !          1918:     emit_byte(0x8b);
        !          1919:     emit_byte(0x04+8*d+isebp);
        !          1920:     emit_byte(baser+8*index+0x40*fi);
        !          1921:     if (isebp)
        !          1922:        emit_byte(0x00);
        !          1923: }
        !          1924: LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
        !          1925: 
        !          1926: LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
        !          1927: {
        !          1928:     int fi;
        !          1929:     int isebp;
        !          1930:     
        !          1931:     switch(factor) {
        !          1932:      case 1: fi=0; break;
        !          1933:      case 2: fi=1; break;
        !          1934:      case 4: fi=2; break;
        !          1935:      case 8: fi=3; break;
        !          1936:      default: abort();
        !          1937:     }
        !          1938:     isebp=(baser==5)?0x40:0;
        !          1939:     
        !          1940:     emit_byte(0x66);
        !          1941:     emit_byte(0x8b);
        !          1942:     emit_byte(0x04+8*d+isebp);
        !          1943:     emit_byte(baser+8*index+0x40*fi);
        !          1944:     if (isebp)
        !          1945:        emit_byte(0x00);
        !          1946: }
        !          1947: LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
        !          1948: 
        !          1949: LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
        !          1950: {
        !          1951:    int fi;
        !          1952:   int isebp;
        !          1953: 
        !          1954:   switch(factor) {
        !          1955:   case 1: fi=0; break;
        !          1956:   case 2: fi=1; break;
        !          1957:   case 4: fi=2; break;
        !          1958:   case 8: fi=3; break;
        !          1959:   default: abort();
        !          1960:   }
        !          1961:   isebp=(baser==5)?0x40:0;
        !          1962: 
        !          1963:    emit_byte(0x8a);
        !          1964:     emit_byte(0x04+8*d+isebp);
        !          1965:     emit_byte(baser+8*index+0x40*fi);
        !          1966:     if (isebp)
        !          1967:        emit_byte(0x00);
        !          1968: }
        !          1969: LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
        !          1970: 
        !          1971: LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
        !          1972: {
        !          1973:   int fi;
        !          1974:   int isebp;
        !          1975: 
        !          1976:   switch(factor) {
        !          1977:   case 1: fi=0; break;
        !          1978:   case 2: fi=1; break;
        !          1979:   case 4: fi=2; break;
        !          1980:   case 8: fi=3; break;
        !          1981:   default: abort();
        !          1982:   }
        !          1983: 
        !          1984:   
        !          1985:   isebp=(baser==5)?0x40:0;
        !          1986: 
        !          1987:     emit_byte(0x89);
        !          1988:     emit_byte(0x04+8*s+isebp);
        !          1989:     emit_byte(baser+8*index+0x40*fi);
        !          1990:     if (isebp)
        !          1991:        emit_byte(0x00);
        !          1992: }
        !          1993: LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
        !          1994: 
        !          1995: LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
        !          1996: {
        !          1997:   int fi;
        !          1998:   int isebp;
        !          1999: 
        !          2000:   switch(factor) {
        !          2001:   case 1: fi=0; break;
        !          2002:   case 2: fi=1; break;
        !          2003:   case 4: fi=2; break;
        !          2004:   case 8: fi=3; break;
        !          2005:   default: abort();
        !          2006:   }
        !          2007:   isebp=(baser==5)?0x40:0;
        !          2008: 
        !          2009:     emit_byte(0x66);
        !          2010:     emit_byte(0x89);
        !          2011:     emit_byte(0x04+8*s+isebp);
        !          2012:     emit_byte(baser+8*index+0x40*fi);
        !          2013:     if (isebp)
        !          2014:        emit_byte(0x00);
        !          2015: }
        !          2016: LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
        !          2017: 
        !          2018: LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
        !          2019: {
        !          2020:   int fi;
        !          2021:   int isebp;
        !          2022: 
        !          2023:   switch(factor) {
        !          2024:   case 1: fi=0; break;
        !          2025:   case 2: fi=1; break;
        !          2026:   case 4: fi=2; break;
        !          2027:   case 8: fi=3; break;
        !          2028:   default: abort();
        !          2029:   }
        !          2030:   isebp=(baser==5)?0x40:0;
        !          2031: 
        !          2032:     emit_byte(0x88);
        !          2033:     emit_byte(0x04+8*s+isebp);
        !          2034:     emit_byte(baser+8*index+0x40*fi);
        !          2035:     if (isebp)
        !          2036:        emit_byte(0x00);
        !          2037: }
        !          2038: LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
        !          2039: 
        !          2040: LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
        !          2041: {
        !          2042:   int fi;
        !          2043: 
        !          2044:   switch(factor) {
        !          2045:   case 1: fi=0; break;
        !          2046:   case 2: fi=1; break;
        !          2047:   case 4: fi=2; break;
        !          2048:   case 8: fi=3; break;
        !          2049:   default: abort();
        !          2050:   }
        !          2051: 
        !          2052:     emit_byte(0x89);
        !          2053:     emit_byte(0x84+8*s);
        !          2054:     emit_byte(baser+8*index+0x40*fi);
        !          2055:     emit_long(base);
        !          2056: }
        !          2057: LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
        !          2058: 
        !          2059: LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
        !          2060: {
        !          2061:   int fi;
        !          2062: 
        !          2063:   switch(factor) {
        !          2064:   case 1: fi=0; break;
        !          2065:   case 2: fi=1; break;
        !          2066:   case 4: fi=2; break;
        !          2067:   case 8: fi=3; break;
        !          2068:   default: abort();
        !          2069:   }
        !          2070: 
        !          2071:     emit_byte(0x66);
        !          2072:     emit_byte(0x89);
        !          2073:     emit_byte(0x84+8*s);
        !          2074:     emit_byte(baser+8*index+0x40*fi);
        !          2075:     emit_long(base);
        !          2076: }
        !          2077: LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
        !          2078: 
        !          2079: LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
        !          2080: {
        !          2081:   int fi;
        !          2082: 
        !          2083:   switch(factor) {
        !          2084:   case 1: fi=0; break;
        !          2085:   case 2: fi=1; break;
        !          2086:   case 4: fi=2; break;
        !          2087:   case 8: fi=3; break;
        !          2088:   default: abort();
        !          2089:   }
        !          2090: 
        !          2091:     emit_byte(0x88);
        !          2092:     emit_byte(0x84+8*s);
        !          2093:     emit_byte(baser+8*index+0x40*fi);
        !          2094:     emit_long(base);
        !          2095: }
        !          2096: LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
        !          2097: 
        !          2098: LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
        !          2099: {
        !          2100:   int fi;
        !          2101: 
        !          2102:   switch(factor) {
        !          2103:   case 1: fi=0; break;
        !          2104:   case 2: fi=1; break;
        !          2105:   case 4: fi=2; break;
        !          2106:   case 8: fi=3; break;
        !          2107:   default: abort();
        !          2108:   }
        !          2109: 
        !          2110:     emit_byte(0x8b);
        !          2111:     emit_byte(0x84+8*d);
        !          2112:     emit_byte(baser+8*index+0x40*fi);
        !          2113:     emit_long(base);
        !          2114: }
        !          2115: LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
        !          2116: 
        !          2117: LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
        !          2118: {
        !          2119:   int fi;
        !          2120: 
        !          2121:   switch(factor) {
        !          2122:   case 1: fi=0; break;
        !          2123:   case 2: fi=1; break;
        !          2124:   case 4: fi=2; break;
        !          2125:   case 8: fi=3; break;
        !          2126:   default: abort();
        !          2127:   }
        !          2128: 
        !          2129:     emit_byte(0x66);
        !          2130:     emit_byte(0x8b);
        !          2131:     emit_byte(0x84+8*d);
        !          2132:     emit_byte(baser+8*index+0x40*fi);
        !          2133:     emit_long(base);
        !          2134: }
        !          2135: LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
        !          2136: 
        !          2137: LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
        !          2138: {
        !          2139:   int fi;
        !          2140: 
        !          2141:   switch(factor) {
        !          2142:   case 1: fi=0; break;
        !          2143:   case 2: fi=1; break;
        !          2144:   case 4: fi=2; break;
        !          2145:   case 8: fi=3; break;
        !          2146:   default: abort();
        !          2147:   }
        !          2148: 
        !          2149:     emit_byte(0x8a);
        !          2150:     emit_byte(0x84+8*d);
        !          2151:     emit_byte(baser+8*index+0x40*fi);
        !          2152:     emit_long(base);
        !          2153: }
        !          2154: LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
        !          2155: 
        !          2156: LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
        !          2157: {
        !          2158:   int fi;
        !          2159:   switch(factor) {
        !          2160:   case 1: fi=0; break;
        !          2161:   case 2: fi=1; break;
        !          2162:   case 4: fi=2; break;
        !          2163:   case 8: fi=3; break;
        !          2164:   default: 
        !          2165:     fprintf(stderr,"Bad factor %d in mov_l_rm_indexed!\n",factor);
        !          2166:     abort();
        !          2167:   }
        !          2168:     emit_byte(0x8b);
        !          2169:     emit_byte(0x04+8*d);
        !          2170:     emit_byte(0x05+8*index+64*fi);
        !          2171:     emit_long(base);
        !          2172: }
        !          2173: LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
        !          2174: 
        !          2175: LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
        !          2176: {
        !          2177:     int fi;
        !          2178:     switch(factor) {
        !          2179:      case 1: fi=0; break;
        !          2180:      case 2: fi=1; break;
        !          2181:      case 4: fi=2; break;
        !          2182:      case 8: fi=3; break;
        !          2183:      default: 
        !          2184:        fprintf(stderr,"Bad factor %d in mov_l_rm_indexed!\n",factor);
        !          2185:        abort();
        !          2186:     }
        !          2187:     if (have_cmov) {
        !          2188:        emit_byte(0x0f);
        !          2189:        emit_byte(0x40+cond);
        !          2190:        emit_byte(0x04+8*d);
        !          2191:        emit_byte(0x05+8*index+64*fi);
        !          2192:        emit_long(base);
        !          2193:     }
        !          2194:     else { /* replacement using branch and mov */
        !          2195:        int uncc=(cond^1);
        !          2196:        emit_byte(0x70+uncc); 
        !          2197:        emit_byte(7);  /* skip next 7 bytes if not cc=true */
        !          2198:        emit_byte(0x8b);
        !          2199:        emit_byte(0x04+8*d);
        !          2200:        emit_byte(0x05+8*index+64*fi);
        !          2201:        emit_long(base);
        !          2202:     }
        !          2203: }
        !          2204: LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
        !          2205: 
        !          2206: LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
        !          2207: {
        !          2208:     if (have_cmov) {
        !          2209:        emit_byte(0x0f);
        !          2210:        emit_byte(0x40+cond);
        !          2211:        emit_byte(0x05+8*d);
        !          2212:        emit_long(mem);
        !          2213:     }
        !          2214:     else { /* replacement using branch and mov */
        !          2215:        int uncc=(cond^1);
        !          2216:        emit_byte(0x70+uncc); 
        !          2217:        emit_byte(6);  /* skip next 6 bytes if not cc=true */
        !          2218:        emit_byte(0x8b);
        !          2219:        emit_byte(0x05+8*d);
        !          2220:        emit_long(mem);
        !          2221:     }
        !          2222: }
        !          2223: LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
        !          2224: 
        !          2225: LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
        !          2226: {
        !          2227:        Dif(!isbyte(offset)) abort();
        !          2228:     emit_byte(0x8b);
        !          2229:     emit_byte(0x40+8*d+s);
        !          2230:     emit_byte(offset);
        !          2231: }
        !          2232: LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
        !          2233: 
        !          2234: LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
        !          2235: {
        !          2236:        Dif(!isbyte(offset)) abort();
        !          2237:     emit_byte(0x66);
        !          2238:     emit_byte(0x8b);
        !          2239:     emit_byte(0x40+8*d+s);
        !          2240:     emit_byte(offset);
        !          2241: }
        !          2242: LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
        !          2243: 
        !          2244: LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
        !          2245: {
        !          2246:        Dif(!isbyte(offset)) abort();
        !          2247:     emit_byte(0x8a);
        !          2248:     emit_byte(0x40+8*d+s);
        !          2249:     emit_byte(offset);
        !          2250: }
        !          2251: LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
        !          2252: 
        !          2253: LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
        !          2254: {
        !          2255:     emit_byte(0x8b);
        !          2256:     emit_byte(0x80+8*d+s);
        !          2257:     emit_long(offset);
        !          2258: }
        !          2259: LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
        !          2260: 
        !          2261: LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
        !          2262: {
        !          2263:     emit_byte(0x66);
        !          2264:     emit_byte(0x8b);
        !          2265:     emit_byte(0x80+8*d+s);
        !          2266:     emit_long(offset);
        !          2267: }
        !          2268: LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
        !          2269: 
        !          2270: LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
        !          2271: {
        !          2272:     emit_byte(0x8a);
        !          2273:     emit_byte(0x80+8*d+s);
        !          2274:     emit_long(offset);
        !          2275: }
        !          2276: LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
        !          2277: 
        !          2278: LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
        !          2279: {
        !          2280:        Dif(!isbyte(offset)) abort();
        !          2281:     emit_byte(0xc7);
        !          2282:     emit_byte(0x40+d);
        !          2283:     emit_byte(offset);
        !          2284:     emit_long(i);
        !          2285: }
        !          2286: LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
        !          2287: 
        !          2288: LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
        !          2289: {
        !          2290:        Dif(!isbyte(offset)) abort();
        !          2291:     emit_byte(0x66);
        !          2292:     emit_byte(0xc7);
        !          2293:     emit_byte(0x40+d);
        !          2294:     emit_byte(offset);
        !          2295:     emit_word(i);
        !          2296: }
        !          2297: LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
        !          2298: 
        !          2299: LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
        !          2300: {
        !          2301:        Dif(!isbyte(offset)) abort();
        !          2302:     emit_byte(0xc6);
        !          2303:     emit_byte(0x40+d);
        !          2304:     emit_byte(offset);
        !          2305:     emit_byte(i);
        !          2306: }
        !          2307: LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
        !          2308: 
        !          2309: LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
        !          2310: {
        !          2311:        Dif(!isbyte(offset)) abort();
        !          2312:     emit_byte(0x89);
        !          2313:     emit_byte(0x40+8*s+d);
        !          2314:     emit_byte(offset);
        !          2315: }
        !          2316: LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
        !          2317: 
        !          2318: LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
        !          2319: {
        !          2320:        Dif(!isbyte(offset)) abort();
        !          2321:     emit_byte(0x66);
        !          2322:     emit_byte(0x89);
        !          2323:     emit_byte(0x40+8*s+d);
        !          2324:     emit_byte(offset);
        !          2325: }
        !          2326: LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
        !          2327: 
        !          2328: LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
        !          2329: {
        !          2330:        Dif(!isbyte(offset)) abort();
        !          2331:     emit_byte(0x88);
        !          2332:     emit_byte(0x40+8*s+d);
        !          2333:     emit_byte(offset);
        !          2334: }
        !          2335: LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
        !          2336: 
        !          2337: LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
        !          2338: {
        !          2339:        if (optimize_imm8 && isbyte(offset)) {
        !          2340:     emit_byte(0x8d);
        !          2341:        emit_byte(0x40+8*d+s);
        !          2342:        emit_byte(offset);
        !          2343:        }
        !          2344:        else {
        !          2345:     emit_byte(0x8d);
        !          2346:        emit_byte(0x80+8*d+s);
        !          2347:        emit_long(offset);
        !          2348:        }
        !          2349: }
        !          2350: LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
        !          2351: 
        !          2352: LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
        !          2353: {
        !          2354:   int fi;
        !          2355:   
        !          2356:   switch(factor) {
        !          2357:   case 1: fi=0; break;
        !          2358:   case 2: fi=1; break;
        !          2359:   case 4: fi=2; break;
        !          2360:   case 8: fi=3; break;
        !          2361:   default: abort();
        !          2362:   }
        !          2363: 
        !          2364:        if (optimize_imm8 && isbyte(offset)) {
        !          2365:     emit_byte(0x8d);
        !          2366:        emit_byte(0x44+8*d);
        !          2367:        emit_byte(0x40*fi+8*index+s);
        !          2368:        emit_byte(offset);
        !          2369:        }
        !          2370:        else {
        !          2371:     emit_byte(0x8d);
        !          2372:        emit_byte(0x84+8*d);
        !          2373:        emit_byte(0x40*fi+8*index+s);
        !          2374:        emit_long(offset);
        !          2375:        }
        !          2376: }
        !          2377: LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
        !          2378: 
        !          2379: LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
        !          2380: {
        !          2381:   int isebp=(s==5)?0x40:0;
        !          2382:   int fi;
        !          2383:   
        !          2384:   switch(factor) {
        !          2385:   case 1: fi=0; break;
        !          2386:   case 2: fi=1; break;
        !          2387:   case 4: fi=2; break;
        !          2388:   case 8: fi=3; break;
        !          2389:   default: abort();
        !          2390:   }
        !          2391: 
        !          2392:     emit_byte(0x8d);
        !          2393:     emit_byte(0x04+8*d+isebp);
        !          2394:     emit_byte(0x40*fi+8*index+s);
        !          2395:     if (isebp)
        !          2396:       emit_byte(0);
        !          2397: }
        !          2398: LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
        !          2399: 
        !          2400: LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
        !          2401: {
        !          2402:        if (optimize_imm8 && isbyte(offset)) {
        !          2403:     emit_byte(0x89);
        !          2404:     emit_byte(0x40+8*s+d);
        !          2405:     emit_byte(offset);
        !          2406:        }
        !          2407:        else {
        !          2408:     emit_byte(0x89);
        !          2409:     emit_byte(0x80+8*s+d);
        !          2410:     emit_long(offset);
        !          2411:        }
        !          2412: }
        !          2413: LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
        !          2414: 
        !          2415: LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
        !          2416: {
        !          2417:     emit_byte(0x66);
        !          2418:     emit_byte(0x89);
        !          2419:     emit_byte(0x80+8*s+d);
        !          2420:     emit_long(offset);
        !          2421: }
        !          2422: LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
        !          2423: 
        !          2424: LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
        !          2425: {
        !          2426:        if (optimize_imm8 && isbyte(offset)) {
        !          2427:     emit_byte(0x88);
        !          2428:     emit_byte(0x40+8*s+d);
        !          2429:     emit_byte(offset);
        !          2430:        }
        !          2431:        else {
        !          2432:     emit_byte(0x88);
        !          2433:     emit_byte(0x80+8*s+d);
        !          2434:     emit_long(offset);
        !          2435:        }
        !          2436: }
        !          2437: LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
        !          2438: 
        !          2439: LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
        !          2440: {
        !          2441:     emit_byte(0x0f);
        !          2442:     emit_byte(0xc8+r);
        !          2443: }
        !          2444: LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
        !          2445: 
        !          2446: LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
        !          2447: {
        !          2448:     emit_byte(0x66);
        !          2449:     emit_byte(0xc1);
        !          2450:     emit_byte(0xc0+r);
        !          2451:     emit_byte(0x08);
        !          2452: }
        !          2453: LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
        !          2454: 
        !          2455: LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
        !          2456: {
        !          2457:     emit_byte(0x89);
        !          2458:     emit_byte(0xc0+8*s+d);
        !          2459: }
        !          2460: LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
        !          2461: 
        !          2462: LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
        !          2463: {
        !          2464:     emit_byte(0x89);
        !          2465:     emit_byte(0x05+8*s);
        !          2466:     emit_long(d);
        !          2467: }
        !          2468: LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
        !          2469: 
        !          2470: LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
        !          2471: {
        !          2472:     emit_byte(0x66);
        !          2473:     emit_byte(0x89);
        !          2474:     emit_byte(0x05+8*s);
        !          2475:     emit_long(d);
        !          2476: }
        !          2477: LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
        !          2478: 
        !          2479: LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
        !          2480: {
        !          2481:     emit_byte(0x66);
        !          2482:     emit_byte(0x8b);
        !          2483:     emit_byte(0x05+8*d);
        !          2484:     emit_long(s);
        !          2485: }
        !          2486: LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
        !          2487: 
        !          2488: LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
        !          2489: {
        !          2490:     emit_byte(0x88);
        !          2491:     emit_byte(0x05+8*(s&0xf)); /* XXX this handles %ah case (defined as 0x10+4) and others */
        !          2492:     emit_long(d);
        !          2493: }
        !          2494: LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
        !          2495: 
        !          2496: LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
        !          2497: {
        !          2498:     emit_byte(0x8a);
        !          2499:     emit_byte(0x05+8*d);
        !          2500:     emit_long(s);
        !          2501: }
        !          2502: LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
        !          2503: 
        !          2504: LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
        !          2505: {
        !          2506:     emit_byte(0xb8+d);
        !          2507:     emit_long(s);
        !          2508: }
        !          2509: LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
        !          2510: 
        !          2511: LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
        !          2512: {
        !          2513:     emit_byte(0x66);
        !          2514:     emit_byte(0xb8+d);
        !          2515:     emit_word(s);
        !          2516: }
        !          2517: LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
        !          2518: 
        !          2519: LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
        !          2520: {
        !          2521:     emit_byte(0xb0+d);
        !          2522:     emit_byte(s);
        !          2523: }
        !          2524: LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
        !          2525: 
        !          2526: LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
        !          2527: {
        !          2528:     emit_byte(0x81);
        !          2529:     emit_byte(0x15);
        !          2530:     emit_long(d);
        !          2531:     emit_long(s);
        !          2532: }
        !          2533: LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
        !          2534: 
        !          2535: LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) 
        !          2536: {
        !          2537:        if (optimize_imm8 && isbyte(s)) {
        !          2538:     emit_byte(0x83);
        !          2539:     emit_byte(0x05);
        !          2540:     emit_long(d);
        !          2541:     emit_byte(s);
        !          2542:        }
        !          2543:        else {
        !          2544:     emit_byte(0x81);
        !          2545:     emit_byte(0x05);
        !          2546:     emit_long(d);
        !          2547:     emit_long(s);
        !          2548:        }
        !          2549: }
        !          2550: LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) 
        !          2551: 
        !          2552: LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) 
        !          2553: {
        !          2554:     emit_byte(0x66);
        !          2555:     emit_byte(0x81);
        !          2556:     emit_byte(0x05);
        !          2557:     emit_long(d);
        !          2558:     emit_word(s);
        !          2559: }
        !          2560: LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) 
        !          2561: 
        !          2562: LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) 
        !          2563: {
        !          2564:     emit_byte(0x80);
        !          2565:     emit_byte(0x05);
        !          2566:     emit_long(d);
        !          2567:     emit_byte(s);
        !          2568: }
        !          2569: LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) 
        !          2570: 
        !          2571: LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
        !          2572: {
        !          2573:        if (optimize_accum && isaccum(d))
        !          2574:        emit_byte(0xa9);
        !          2575:        else {
        !          2576:     emit_byte(0xf7);
        !          2577:     emit_byte(0xc0+d);
        !          2578:        }
        !          2579:     emit_long(i);
        !          2580: }
        !          2581: LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
        !          2582: 
        !          2583: LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
        !          2584: {
        !          2585:     emit_byte(0x85);
        !          2586:     emit_byte(0xc0+8*s+d);
        !          2587: }
        !          2588: LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
        !          2589: 
        !          2590: LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
        !          2591: {
        !          2592:     emit_byte(0x66);
        !          2593:     emit_byte(0x85);
        !          2594:     emit_byte(0xc0+8*s+d);
        !          2595: }
        !          2596: LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
        !          2597: 
        !          2598: LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
        !          2599: {
        !          2600:     emit_byte(0x84);
        !          2601:     emit_byte(0xc0+8*s+d);
        !          2602: }
        !          2603: LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
        !          2604: 
        !          2605: LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
        !          2606: {
        !          2607:     emit_byte(0x81);
        !          2608:     emit_byte(0xf0+d);
        !          2609:     emit_long(i);
        !          2610: }
        !          2611: LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
        !          2612: 
        !          2613: LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
        !          2614: {
        !          2615:        if (optimize_imm8 && isbyte(i)) {
        !          2616:        emit_byte(0x83);
        !          2617:        emit_byte(0xe0+d);
        !          2618:        emit_byte(i);
        !          2619:        }
        !          2620:        else {
        !          2621:        if (optimize_accum && isaccum(d))
        !          2622:        emit_byte(0x25);
        !          2623:        else {
        !          2624:        emit_byte(0x81);
        !          2625:        emit_byte(0xe0+d);
        !          2626:        }
        !          2627:        emit_long(i);
        !          2628:        }
        !          2629: }
        !          2630: LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
        !          2631: 
        !          2632: LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
        !          2633: {
        !          2634:        emit_byte(0x66);
        !          2635:        if (optimize_imm8 && isbyte(i)) {
        !          2636:        emit_byte(0x83);
        !          2637:        emit_byte(0xe0+d);
        !          2638:        emit_byte(i);
        !          2639:        }
        !          2640:        else {
        !          2641:        if (optimize_accum && isaccum(d))
        !          2642:        emit_byte(0x25);
        !          2643:        else {
        !          2644:        emit_byte(0x81);
        !          2645:        emit_byte(0xe0+d);
        !          2646:        }
        !          2647:        emit_word(i);
        !          2648:        }
        !          2649: }
        !          2650: LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
        !          2651: 
        !          2652: LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
        !          2653: {
        !          2654:     emit_byte(0x21);
        !          2655:     emit_byte(0xc0+8*s+d);
        !          2656: }
        !          2657: LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
        !          2658: 
        !          2659: LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
        !          2660: {
        !          2661:     emit_byte(0x66);
        !          2662:     emit_byte(0x21);
        !          2663:     emit_byte(0xc0+8*s+d);
        !          2664: }
        !          2665: LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
        !          2666: 
        !          2667: LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
        !          2668: {
        !          2669:     emit_byte(0x20);
        !          2670:     emit_byte(0xc0+8*s+d);
        !          2671: }
        !          2672: LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
        !          2673: 
        !          2674: LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
        !          2675: {
        !          2676:        if (optimize_imm8 && isbyte(i)) {
        !          2677:     emit_byte(0x83);
        !          2678:     emit_byte(0xc8+d);
        !          2679:     emit_byte(i);
        !          2680:        }
        !          2681:        else {
        !          2682:        if (optimize_accum && isaccum(d))
        !          2683:        emit_byte(0x0d);
        !          2684:        else {
        !          2685:     emit_byte(0x81);
        !          2686:     emit_byte(0xc8+d);
        !          2687:        }
        !          2688:     emit_long(i);
        !          2689:        }
        !          2690: }
        !          2691: LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
        !          2692: 
        !          2693: LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
        !          2694: {
        !          2695:     emit_byte(0x09);
        !          2696:     emit_byte(0xc0+8*s+d);
        !          2697: }
        !          2698: LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
        !          2699: 
        !          2700: LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
        !          2701: {
        !          2702:     emit_byte(0x66);
        !          2703:     emit_byte(0x09);
        !          2704:     emit_byte(0xc0+8*s+d);
        !          2705: }
        !          2706: LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
        !          2707: 
        !          2708: LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
        !          2709: {
        !          2710:     emit_byte(0x08);
        !          2711:     emit_byte(0xc0+8*s+d);
        !          2712: }
        !          2713: LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
        !          2714: 
        !          2715: LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
        !          2716: {
        !          2717:     emit_byte(0x11);
        !          2718:     emit_byte(0xc0+8*s+d);
        !          2719: }
        !          2720: LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
        !          2721: 
        !          2722: LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
        !          2723: {
        !          2724:     emit_byte(0x66);
        !          2725:     emit_byte(0x11);
        !          2726:     emit_byte(0xc0+8*s+d);
        !          2727: }
        !          2728: LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
        !          2729: 
        !          2730: LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
        !          2731: {
        !          2732:     emit_byte(0x10);
        !          2733:     emit_byte(0xc0+8*s+d);
        !          2734: }
        !          2735: LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
        !          2736: 
        !          2737: LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
        !          2738: {
        !          2739:     emit_byte(0x01);
        !          2740:     emit_byte(0xc0+8*s+d);
        !          2741: }
        !          2742: LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
        !          2743: 
        !          2744: LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
        !          2745: {
        !          2746:     emit_byte(0x66);
        !          2747:     emit_byte(0x01);
        !          2748:     emit_byte(0xc0+8*s+d);
        !          2749: }
        !          2750: LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
        !          2751: 
        !          2752: LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
        !          2753: {
        !          2754:     emit_byte(0x00);
        !          2755:     emit_byte(0xc0+8*s+d);
        !          2756: }
        !          2757: LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
        !          2758: 
        !          2759: LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
        !          2760: {
        !          2761:   if (isbyte(i)) {
        !          2762:     emit_byte(0x83);
        !          2763:     emit_byte(0xe8+d);
        !          2764:     emit_byte(i);
        !          2765:   }
        !          2766:   else {
        !          2767:     if (optimize_accum && isaccum(d))
        !          2768:     emit_byte(0x2d);
        !          2769:     else {
        !          2770:     emit_byte(0x81);
        !          2771:     emit_byte(0xe8+d);
        !          2772:     }
        !          2773:     emit_long(i);
        !          2774:   }
        !          2775: }
        !          2776: LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
        !          2777: 
        !          2778: LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
        !          2779: {
        !          2780:        if (optimize_accum && isaccum(d))
        !          2781:        emit_byte(0x2c);
        !          2782:        else {
        !          2783:     emit_byte(0x80);
        !          2784:     emit_byte(0xe8+d);
        !          2785:        }
        !          2786:     emit_byte(i);
        !          2787: }
        !          2788: LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
        !          2789: 
        !          2790: LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
        !          2791: {
        !          2792:     if (isbyte(i)) {
        !          2793:        emit_byte(0x83);
        !          2794:        emit_byte(0xc0+d);
        !          2795:        emit_byte(i);
        !          2796:     }
        !          2797:     else {
        !          2798:        if (optimize_accum && isaccum(d))
        !          2799:        emit_byte(0x05);
        !          2800:        else {
        !          2801:        emit_byte(0x81);
        !          2802:        emit_byte(0xc0+d);
        !          2803:        }
        !          2804:        emit_long(i);
        !          2805:     }
        !          2806: }
        !          2807: LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
        !          2808: 
        !          2809: LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
        !          2810: {
        !          2811:        emit_byte(0x66);
        !          2812:     if (isbyte(i)) {
        !          2813:        emit_byte(0x83);
        !          2814:        emit_byte(0xc0+d);
        !          2815:        emit_byte(i);
        !          2816:     }
        !          2817:     else {
        !          2818:        if (optimize_accum && isaccum(d))
        !          2819:        emit_byte(0x05);
        !          2820:        else {
        !          2821:        emit_byte(0x81);
        !          2822:        emit_byte(0xc0+d);
        !          2823:        }
        !          2824:        emit_word(i);
        !          2825:     }
        !          2826: }
        !          2827: LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
        !          2828: 
        !          2829: LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
        !          2830: {
        !          2831:        if (optimize_accum && isaccum(d))
        !          2832:        emit_byte(0x04);
        !          2833:        else {
        !          2834:        emit_byte(0x80);
        !          2835:        emit_byte(0xc0+d);
        !          2836:        }
        !          2837:     emit_byte(i);
        !          2838: }
        !          2839: LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
        !          2840: 
        !          2841: LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
        !          2842: {
        !          2843:     emit_byte(0x19);
        !          2844:     emit_byte(0xc0+8*s+d);
        !          2845: }
        !          2846: LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
        !          2847: 
        !          2848: LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
        !          2849: {
        !          2850:     emit_byte(0x66);
        !          2851:     emit_byte(0x19);
        !          2852:     emit_byte(0xc0+8*s+d);
        !          2853: }
        !          2854: LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
        !          2855: 
        !          2856: LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
        !          2857: {
        !          2858:     emit_byte(0x18);
        !          2859:     emit_byte(0xc0+8*s+d);
        !          2860: }
        !          2861: LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
        !          2862: 
        !          2863: LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
        !          2864: {
        !          2865:     emit_byte(0x29);
        !          2866:     emit_byte(0xc0+8*s+d);
        !          2867: }
        !          2868: LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
        !          2869: 
        !          2870: LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
        !          2871: {
        !          2872:     emit_byte(0x66);
        !          2873:     emit_byte(0x29);
        !          2874:     emit_byte(0xc0+8*s+d);
        !          2875: }
        !          2876: LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
        !          2877: 
        !          2878: LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
        !          2879: {
        !          2880:     emit_byte(0x28);
        !          2881:     emit_byte(0xc0+8*s+d);
        !          2882: }
        !          2883: LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
        !          2884: 
        !          2885: LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
        !          2886: {
        !          2887:     emit_byte(0x39);
        !          2888:     emit_byte(0xc0+8*s+d);
        !          2889: }
        !          2890: LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
        !          2891: 
        !          2892: LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
        !          2893: {
        !          2894:        if (optimize_imm8 && isbyte(i)) {
        !          2895:     emit_byte(0x83);
        !          2896:     emit_byte(0xf8+r);
        !          2897:     emit_byte(i);
        !          2898:        }
        !          2899:        else {
        !          2900:        if (optimize_accum && isaccum(r))
        !          2901:        emit_byte(0x3d);
        !          2902:        else {
        !          2903:     emit_byte(0x81);
        !          2904:     emit_byte(0xf8+r);
        !          2905:        }
        !          2906:     emit_long(i);
        !          2907:        }
        !          2908: }
        !          2909: LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
        !          2910: 
        !          2911: LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
        !          2912: {
        !          2913:     emit_byte(0x66);
        !          2914:     emit_byte(0x39);
        !          2915:     emit_byte(0xc0+8*s+d);
        !          2916: }
        !          2917: LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
        !          2918: 
        !          2919: LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
        !          2920: {
        !          2921:     emit_byte(0x80);
        !          2922:     emit_byte(0x3d);
        !          2923:     emit_long(d);
        !          2924:     emit_byte(s);
        !          2925: }
        !          2926: LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
        !          2927: 
        !          2928: LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
        !          2929: {
        !          2930:   if (optimize_accum && isaccum(d))
        !          2931:   emit_byte(0x3c);
        !          2932:   else {
        !          2933:   emit_byte(0x80);
        !          2934:   emit_byte(0xf8+d);
        !          2935:   }
        !          2936:   emit_byte(i);
        !          2937: }
        !          2938: LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
        !          2939: 
        !          2940: LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
        !          2941: {
        !          2942:     emit_byte(0x38);
        !          2943:     emit_byte(0xc0+8*s+d);
        !          2944: }
        !          2945: LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
        !          2946: 
        !          2947: LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
        !          2948: {
        !          2949:     int fi;
        !          2950:     
        !          2951:     switch(factor) {
        !          2952:      case 1: fi=0; break;
        !          2953:      case 2: fi=1; break;
        !          2954:      case 4: fi=2; break;
        !          2955:      case 8: fi=3; break;
        !          2956:      default: abort();
        !          2957:     }
        !          2958:     emit_byte(0x39);
        !          2959:     emit_byte(0x04+8*d);
        !          2960:     emit_byte(5+8*index+0x40*fi);
        !          2961:     emit_long(offset);
        !          2962: }
        !          2963: LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
        !          2964: 
        !          2965: LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
        !          2966: {
        !          2967:     emit_byte(0x31);
        !          2968:     emit_byte(0xc0+8*s+d);
        !          2969: }
        !          2970: LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
        !          2971: 
        !          2972: LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
        !          2973: {
        !          2974:     emit_byte(0x66);
        !          2975:     emit_byte(0x31);
        !          2976:     emit_byte(0xc0+8*s+d);
        !          2977: }
        !          2978: LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
        !          2979: 
        !          2980: LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
        !          2981: {
        !          2982:     emit_byte(0x30);
        !          2983:     emit_byte(0xc0+8*s+d);
        !          2984: }
        !          2985: LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
        !          2986: 
        !          2987: LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
        !          2988: {
        !          2989:        if (optimize_imm8 && isbyte(s)) {
        !          2990:     emit_byte(0x83);
        !          2991:     emit_byte(0x2d);
        !          2992:     emit_long(d);
        !          2993:     emit_byte(s);
        !          2994:        }
        !          2995:        else {
        !          2996:     emit_byte(0x81);
        !          2997:     emit_byte(0x2d);
        !          2998:     emit_long(d);
        !          2999:     emit_long(s);
        !          3000:        }
        !          3001: }
        !          3002: LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
        !          3003: 
        !          3004: LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
        !          3005: {
        !          3006:        if (optimize_imm8 && isbyte(s)) {
        !          3007:     emit_byte(0x83);
        !          3008:     emit_byte(0x3d);
        !          3009:     emit_long(d);
        !          3010:     emit_byte(s);
        !          3011:        }
        !          3012:        else {
        !          3013:     emit_byte(0x81);
        !          3014:     emit_byte(0x3d);
        !          3015:     emit_long(d);
        !          3016:     emit_long(s);
        !          3017:        }
        !          3018: }
        !          3019: LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
        !          3020: 
        !          3021: LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
        !          3022: {
        !          3023:   emit_byte(0x87);
        !          3024:   emit_byte(0xc0+8*r1+r2);
        !          3025: }
        !          3026: LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
        !          3027: 
        !          3028: LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2))
        !          3029: {
        !          3030:   emit_byte(0x86);
        !          3031:   emit_byte(0xc0+8*(r1&0xf)+(r2&0xf)); /* XXX this handles upper-halves registers (e.g. %ah defined as 0x10+4) */
        !          3032: }
        !          3033: LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
        !          3034: 
        !          3035: /*************************************************************************
        !          3036:  * FIXME: mem access modes probably wrong                                *
        !          3037:  *************************************************************************/
        !          3038: 
        !          3039: LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
        !          3040: {
        !          3041:        emit_byte(0x9c);
        !          3042: }
        !          3043: LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
        !          3044: 
        !          3045: LOWFUNC(WRITE,READ,0,raw_popfl,(void))
        !          3046: {
        !          3047:        emit_byte(0x9d);
        !          3048: }
        !          3049: LENDFUNC(WRITE,READ,0,raw_popfl,(void))
        !          3050: 
        !          3051: /* Generate floating-point instructions */
        !          3052: static inline void x86_fadd_m(MEMR s)
        !          3053: {
        !          3054:        emit_byte(0xdc);
        !          3055:        emit_byte(0x05);
        !          3056:        emit_long(s);
        !          3057: }
        !          3058: 
        !          3059: #endif
        !          3060: 
        !          3061: /*************************************************************************
        !          3062:  * Unoptimizable stuff --- jump                                          *
        !          3063:  *************************************************************************/
        !          3064: 
        !          3065: static __inline__ void raw_call_r(R4 r)
        !          3066: {
        !          3067: #if USE_NEW_RTASM
        !          3068:     CALLsr(r);
        !          3069: #else
        !          3070:     emit_byte(0xff);
        !          3071:     emit_byte(0xd0+r);
        !          3072: #endif
        !          3073: }
        !          3074: 
        !          3075: static __inline__ void raw_call_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
        !          3076: {
        !          3077: #if USE_NEW_RTASM
        !          3078:     CALLsm(base, X86_NOREG, r, m);
        !          3079: #else
        !          3080:     int mu;
        !          3081:     switch(m) {
        !          3082:      case 1: mu=0; break;
        !          3083:      case 2: mu=1; break;
        !          3084:      case 4: mu=2; break;
        !          3085:      case 8: mu=3; break;
        !          3086:      default: abort();
        !          3087:     }
        !          3088:     emit_byte(0xff);
        !          3089:     emit_byte(0x14);
        !          3090:     emit_byte(0x05+8*r+0x40*mu);
        !          3091:     emit_long(base);
        !          3092: #endif
        !          3093: }
        !          3094: 
        !          3095: static __inline__ void raw_jmp_r(R4 r)
        !          3096: {
        !          3097: #if USE_NEW_RTASM
        !          3098:     JMPsr(r);
        !          3099: #else
        !          3100:     emit_byte(0xff);
        !          3101:     emit_byte(0xe0+r);
        !          3102: #endif
        !          3103: }
        !          3104: 
        !          3105: static __inline__ void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
        !          3106: {
        !          3107: #if USE_NEW_RTASM
        !          3108:     JMPsm(base, X86_NOREG, r, m);
        !          3109: #else
        !          3110:     int mu;
        !          3111:     switch(m) {
        !          3112:      case 1: mu=0; break;
        !          3113:      case 2: mu=1; break;
        !          3114:      case 4: mu=2; break;
        !          3115:      case 8: mu=3; break;
        !          3116:      default: abort();
        !          3117:     }
        !          3118:     emit_byte(0xff);
        !          3119:     emit_byte(0x24);
        !          3120:     emit_byte(0x05+8*r+0x40*mu);
        !          3121:     emit_long(base);
        !          3122: #endif
        !          3123: }
        !          3124: 
        !          3125: static __inline__ void raw_jmp_m(uae_u32 base)
        !          3126: {
        !          3127:     emit_byte(0xff);
        !          3128:     emit_byte(0x25);
        !          3129:     emit_long(base);
        !          3130: }
        !          3131: 
        !          3132: 
        !          3133: static __inline__ void raw_call(uae_u32 t)
        !          3134: {
        !          3135: #if USE_NEW_RTASM
        !          3136:     CALLm(t);
        !          3137: #else
        !          3138:     emit_byte(0xe8);
        !          3139:     emit_long(t-(uae_u32)target-4);
        !          3140: #endif
        !          3141: }
        !          3142: 
        !          3143: static __inline__ void raw_jmp(uae_u32 t)
        !          3144: {
        !          3145: #if USE_NEW_RTASM
        !          3146:     JMPm(t);
        !          3147: #else
        !          3148:     emit_byte(0xe9);
        !          3149:     emit_long(t-(uae_u32)target-4);
        !          3150: #endif
        !          3151: }
        !          3152: 
        !          3153: static __inline__ void raw_jl(uae_u32 t)
        !          3154: {
        !          3155:     emit_byte(0x0f);
        !          3156:     emit_byte(0x8c);
        !          3157:     emit_long(t-(uintptr)target-4);
        !          3158: }
        !          3159: 
        !          3160: static __inline__ void raw_jz(uae_u32 t)
        !          3161: {
        !          3162:     emit_byte(0x0f);
        !          3163:     emit_byte(0x84);
        !          3164:     emit_long(t-(uintptr)target-4);
        !          3165: }
        !          3166: 
        !          3167: static __inline__ void raw_jnz(uae_u32 t)
        !          3168: {
        !          3169:     emit_byte(0x0f);
        !          3170:     emit_byte(0x85);
        !          3171:     emit_long(t-(uintptr)target-4);
        !          3172: }
        !          3173: 
        !          3174: static __inline__ void raw_jnz_l_oponly(void)
        !          3175: {
        !          3176:     emit_byte(0x0f); 
        !          3177:     emit_byte(0x85); 
        !          3178: }
        !          3179: 
        !          3180: static __inline__ void raw_jcc_l_oponly(int cc)
        !          3181: {
        !          3182:     emit_byte(0x0f); 
        !          3183:     emit_byte(0x80+cc); 
        !          3184: }
        !          3185: 
        !          3186: static __inline__ void raw_jnz_b_oponly(void)
        !          3187: {
        !          3188:     emit_byte(0x75); 
        !          3189: }
        !          3190: 
        !          3191: static __inline__ void raw_jz_b_oponly(void)
        !          3192: {
        !          3193:     emit_byte(0x74); 
        !          3194: }
        !          3195: 
        !          3196: static __inline__ void raw_jcc_b_oponly(int cc)
        !          3197: {
        !          3198:        emit_byte(0x70+cc);
        !          3199: }
        !          3200: 
        !          3201: static __inline__ void raw_jmp_l_oponly(void)
        !          3202: {
        !          3203:     emit_byte(0xe9); 
        !          3204: }
        !          3205: 
        !          3206: static __inline__ void raw_jmp_b_oponly(void)
        !          3207: {
        !          3208:     emit_byte(0xeb); 
        !          3209: }
        !          3210: 
        !          3211: static __inline__ void raw_ret(void)
        !          3212: {
        !          3213:     emit_byte(0xc3);  
        !          3214: }
        !          3215: 
        !          3216: static __inline__ void raw_nop(void)
        !          3217: {
        !          3218:     emit_byte(0x90);
        !          3219: }
        !          3220: 
        !          3221: static __inline__ void raw_emit_nop_filler(int nbytes)
        !          3222: {
        !          3223:   /* Source: GNU Binutils 2.12.90.0.15 */
        !          3224:   /* Various efficient no-op patterns for aligning code labels.
        !          3225:      Note: Don't try to assemble the instructions in the comments.
        !          3226:      0L and 0w are not legal.  */
        !          3227:   static const uae_u8 f32_1[] =
        !          3228:     {0x90};                                                                    /* nop                                  */
        !          3229:   static const uae_u8 f32_2[] =
        !          3230:     {0x89,0xf6};                                                       /* movl %esi,%esi               */
        !          3231:   static const uae_u8 f32_3[] =
        !          3232:     {0x8d,0x76,0x00};                                          /* leal 0(%esi),%esi    */
        !          3233:   static const uae_u8 f32_4[] =
        !          3234:     {0x8d,0x74,0x26,0x00};                                     /* leal 0(%esi,1),%esi  */
        !          3235:   static const uae_u8 f32_5[] =
        !          3236:     {0x90,                                                                     /* nop                                  */
        !          3237:      0x8d,0x74,0x26,0x00};                                     /* leal 0(%esi,1),%esi  */
        !          3238:   static const uae_u8 f32_6[] =
        !          3239:     {0x8d,0xb6,0x00,0x00,0x00,0x00};           /* leal 0L(%esi),%esi   */
        !          3240:   static const uae_u8 f32_7[] =
        !          3241:     {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00};      /* leal 0L(%esi,1),%esi */
        !          3242:   static const uae_u8 f32_8[] =
        !          3243:     {0x90,                                                                     /* nop                                  */
        !          3244:      0x8d,0xb4,0x26,0x00,0x00,0x00,0x00};      /* leal 0L(%esi,1),%esi */
        !          3245:   static const uae_u8 f32_9[] =
        !          3246:     {0x89,0xf6,                                                                /* movl %esi,%esi               */
        !          3247:      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};      /* leal 0L(%edi,1),%edi */
        !          3248:   static const uae_u8 f32_10[] =
        !          3249:     {0x8d,0x76,0x00,                                           /* leal 0(%esi),%esi    */
        !          3250:      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};      /* leal 0L(%edi,1),%edi */
        !          3251:   static const uae_u8 f32_11[] =
        !          3252:     {0x8d,0x74,0x26,0x00,                                      /* leal 0(%esi,1),%esi  */
        !          3253:      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};      /* leal 0L(%edi,1),%edi */
        !          3254:   static const uae_u8 f32_12[] =
        !          3255:     {0x8d,0xb6,0x00,0x00,0x00,0x00,                    /* leal 0L(%esi),%esi   */
        !          3256:      0x8d,0xbf,0x00,0x00,0x00,0x00};           /* leal 0L(%edi),%edi   */
        !          3257:   static const uae_u8 f32_13[] =
        !          3258:     {0x8d,0xb6,0x00,0x00,0x00,0x00,                    /* leal 0L(%esi),%esi   */
        !          3259:      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};      /* leal 0L(%edi,1),%edi */
        !          3260:   static const uae_u8 f32_14[] =
        !          3261:     {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00,       /* leal 0L(%esi,1),%esi */
        !          3262:      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};      /* leal 0L(%edi,1),%edi */
        !          3263:   static const uae_u8 f32_15[] =
        !          3264:     {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90,       /* jmp .+15; lotsa nops */
        !          3265:      0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
        !          3266:   static const uae_u8 f32_16[] =
        !          3267:     {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90,       /* jmp .+15; lotsa nops */
        !          3268:      0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
        !          3269:   static const uae_u8 *const f32_patt[] = {
        !          3270:     f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
        !          3271:     f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
        !          3272:   };
        !          3273:   static const uae_u8 prefixes[4] = { 0x66, 0x66, 0x66, 0x66 };
        !          3274: 
        !          3275: #if defined(__x86_64__)
        !          3276:   /* The recommended way to pad 64bit code is to use NOPs preceded by
        !          3277:      maximally four 0x66 prefixes.  Balance the size of nops.  */
        !          3278:   if (nbytes == 0)
        !          3279:          return;
        !          3280: 
        !          3281:   int i;
        !          3282:   int nnops = (nbytes + 3) / 4;
        !          3283:   int len = nbytes / nnops;
        !          3284:   int remains = nbytes - nnops * len;
        !          3285: 
        !          3286:   for (i = 0; i < remains; i++) {
        !          3287:          emit_block(prefixes, len);
        !          3288:          raw_nop();
        !          3289:   }
        !          3290:   for (; i < nnops; i++) {
        !          3291:          emit_block(prefixes, len - 1);
        !          3292:          raw_nop();
        !          3293:   }
        !          3294: #else
        !          3295:   int nloops = nbytes / 16;
        !          3296:   while (nloops-- > 0)
        !          3297:        emit_block(f32_16, sizeof(f32_16));
        !          3298: 
        !          3299:   nbytes %= 16;
        !          3300:   if (nbytes)
        !          3301:        emit_block(f32_patt[nbytes - 1], nbytes);
        !          3302: #endif
        !          3303: }
        !          3304: 
        !          3305: 
        !          3306: /*************************************************************************
        !          3307:  * Flag handling, to and fro UAE flag register                           *
        !          3308:  *************************************************************************/
        !          3309: 
        !          3310: static __inline__ void raw_flags_evicted(int r)
        !          3311: {
        !          3312:   //live.state[FLAGTMP].status=CLEAN;
        !          3313:   live.state[FLAGTMP].status=INMEM;
        !          3314:   live.state[FLAGTMP].realreg=-1;
        !          3315:   /* We just "evicted" FLAGTMP. */
        !          3316:   if (live.nat[r].nholds!=1) {
        !          3317:       /* Huh? */
        !          3318:       abort();
        !          3319:   }
        !          3320:   live.nat[r].nholds=0;
        !          3321: }
        !          3322: 
        !          3323: #define FLAG_NREG1_FLAGREG 0  /* Set to -1 if any register will do */
        !          3324: static __inline__ void raw_flags_to_reg_FLAGREG(int r)
        !          3325: {
        !          3326:   raw_lahf(0);  /* Most flags in AH */
        !          3327:   //raw_setcc(r,0); /* V flag in AL */
        !          3328:   raw_setcc_m((uintptr)live.state[FLAGTMP].mem,0); 
        !          3329:   
        !          3330: #if 1   /* Let's avoid those nasty partial register stalls */
        !          3331:   //raw_mov_b_mr((uintptr)live.state[FLAGTMP].mem,r);
        !          3332:   raw_mov_b_mr(((uintptr)live.state[FLAGTMP].mem)+1,AH_INDEX);
        !          3333:   raw_flags_evicted(r);
        !          3334: #endif
        !          3335: }
        !          3336: 
        !          3337: #define FLAG_NREG2_FLAGREG 0  /* Set to -1 if any register will do */
        !          3338: static __inline__ void raw_reg_to_flags_FLAGREG(int r)
        !          3339: {
        !          3340:   raw_cmp_b_ri(r,-127); /* set V */
        !          3341:   raw_sahf(0);
        !          3342: }
        !          3343: 
        !          3344: #define FLAG_NREG3_FLAGREG 0  /* Set to -1 if any register will do */
        !          3345: static __inline__ void raw_flags_set_zero_FLAGREG(int s, int tmp)
        !          3346: {
        !          3347:     raw_mov_l_rr(tmp,s);
        !          3348:     raw_lahf(s); /* flags into ah */
        !          3349:     raw_and_l_ri(s,0xffffbfff);
        !          3350:     raw_and_l_ri(tmp,0x00004000);
        !          3351:     raw_xor_l_ri(tmp,0x00004000);
        !          3352:     raw_or_l(s,tmp);
        !          3353:     raw_sahf(s);
        !          3354: }
        !          3355: 
        !          3356: static __inline__ void raw_flags_init_FLAGREG(void) { }
        !          3357: 
        !          3358: #define FLAG_NREG1_FLAGSTK -1  /* Set to -1 if any register will do */
        !          3359: static __inline__ void raw_flags_to_reg_FLAGSTK(int r)
        !          3360: {
        !          3361:        raw_pushfl();
        !          3362:        raw_pop_l_r(r);
        !          3363:        raw_mov_l_mr((uintptr)live.state[FLAGTMP].mem,r);
        !          3364:        raw_flags_evicted(r);
        !          3365: }
        !          3366: 
        !          3367: #define FLAG_NREG2_FLAGSTK -1  /* Set to -1 if any register will do */
        !          3368: static __inline__ void raw_reg_to_flags_FLAGSTK(int r)
        !          3369: {
        !          3370:        raw_push_l_r(r);
        !          3371:        raw_popfl();
        !          3372: }
        !          3373: 
        !          3374: #define FLAG_NREG3_FLAGSTK -1  /* Set to -1 if any register will do */
        !          3375: static __inline__ void raw_flags_set_zero_FLAGSTK(int s, int tmp)
        !          3376: {
        !          3377:     raw_mov_l_rr(tmp,s);
        !          3378:     raw_pushfl();
        !          3379:     raw_pop_l_r(s);
        !          3380:     raw_and_l_ri(s,0xffffffbf);
        !          3381:     raw_and_l_ri(tmp,0x00000040);
        !          3382:     raw_xor_l_ri(tmp,0x00000040);
        !          3383:     raw_or_l(s,tmp);
        !          3384:     raw_push_l_r(s);
        !          3385:     raw_popfl();
        !          3386: }
        !          3387: 
        !          3388: static __inline__ void raw_flags_init_FLAGSTK(void) { }
        !          3389: 
        !          3390: #if defined(__x86_64__)
        !          3391: /* Try to use the LAHF/SETO method on x86_64 since it is faster.
        !          3392:    This can't be the default because some older CPUs don't support
        !          3393:    LAHF/SAHF in long mode.  */
        !          3394: static int FLAG_NREG1_FLAGGEN = 0;
        !          3395: static __inline__ void raw_flags_to_reg_FLAGGEN(int r)
        !          3396: {
        !          3397:        if (have_lahf_lm) {
        !          3398:                // NOTE: the interpreter uses the normal EFLAGS layout
        !          3399:                //   pushf/popf CF(0) ZF( 6) SF( 7) OF(11)
        !          3400:                //   sahf/lahf  CF(8) ZF(14) SF(15) OF( 0)
        !          3401:                assert(r == 0);
        !          3402:                raw_setcc(r,0);                                 /* V flag in AL */
        !          3403:                raw_lea_l_r_scaled(0,0,8);              /* move it to its EFLAGS location */
        !          3404:                raw_mov_b_mr(((uintptr)live.state[FLAGTMP].mem)+1,0);
        !          3405:                raw_lahf(0);                                    /* most flags in AH */
        !          3406:                raw_mov_b_mr((uintptr)live.state[FLAGTMP].mem,AH_INDEX);
        !          3407:                raw_flags_evicted(r);
        !          3408:        }
        !          3409:        else
        !          3410:                raw_flags_to_reg_FLAGSTK(r);
        !          3411: }
        !          3412: 
        !          3413: static int FLAG_NREG2_FLAGGEN = 0;
        !          3414: static __inline__ void raw_reg_to_flags_FLAGGEN(int r)
        !          3415: {
        !          3416:        if (have_lahf_lm) {
        !          3417:                raw_xchg_b_rr(0,AH_INDEX);
        !          3418:                raw_cmp_b_ri(r,-120); /* set V */
        !          3419:                raw_sahf(0);
        !          3420:        }
        !          3421:        else
        !          3422:                raw_reg_to_flags_FLAGSTK(r);
        !          3423: }
        !          3424: 
        !          3425: static int FLAG_NREG3_FLAGGEN = 0;
        !          3426: static __inline__ void raw_flags_set_zero_FLAGGEN(int s, int tmp)
        !          3427: {
        !          3428:        if (have_lahf_lm)
        !          3429:                raw_flags_set_zero_FLAGREG(s, tmp);
        !          3430:        else
        !          3431:                raw_flags_set_zero_FLAGSTK(s, tmp);
        !          3432: }
        !          3433: 
        !          3434: static __inline__ void raw_flags_init_FLAGGEN(void)
        !          3435: {
        !          3436:        if (have_lahf_lm) {
        !          3437:                FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGREG;
        !          3438:                FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGREG;
        !          3439:                FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGREG;
        !          3440:        }
        !          3441:        else {
        !          3442:                FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGSTK;
        !          3443:                FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGSTK;
        !          3444:                FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGSTK;
        !          3445:        }
        !          3446: }
        !          3447: #endif
        !          3448: 
        !          3449: #ifdef SAHF_SETO_PROFITABLE
        !          3450: #define FLAG_SUFFIX FLAGREG
        !          3451: #elif defined __x86_64__
        !          3452: #define FLAG_SUFFIX FLAGGEN
        !          3453: #else
        !          3454: #define FLAG_SUFFIX FLAGSTK
        !          3455: #endif
        !          3456: 
        !          3457: #define FLAG_GLUE_2(x, y)              x ## _ ## y
        !          3458: #define FLAG_GLUE_1(x, y)              FLAG_GLUE_2(x, y)
        !          3459: #define FLAG_GLUE(x)                   FLAG_GLUE_1(x, FLAG_SUFFIX)
        !          3460: 
        !          3461: #define raw_flags_init                 FLAG_GLUE(raw_flags_init)
        !          3462: #define FLAG_NREG1                             FLAG_GLUE(FLAG_NREG1)
        !          3463: #define raw_flags_to_reg               FLAG_GLUE(raw_flags_to_reg)
        !          3464: #define FLAG_NREG2                             FLAG_GLUE(FLAG_NREG2)
        !          3465: #define raw_reg_to_flags               FLAG_GLUE(raw_reg_to_flags)
        !          3466: #define FLAG_NREG3                             FLAG_GLUE(FLAG_NREG3)
        !          3467: #define raw_flags_set_zero             FLAG_GLUE(raw_flags_set_zero)
        !          3468: 
        !          3469: /* Apparently, there are enough instructions between flag store and
        !          3470:    flag reload to avoid the partial memory stall */
        !          3471: static __inline__ void raw_load_flagreg(uae_u32 target, uae_u32 r)
        !          3472: {
        !          3473: #if 1
        !          3474:     raw_mov_l_rm(target,(uintptr)live.state[r].mem);
        !          3475: #else
        !          3476:     raw_mov_b_rm(target,(uintptr)live.state[r].mem);
        !          3477:     raw_mov_b_rm(target+4,((uintptr)live.state[r].mem)+1);
        !          3478: #endif
        !          3479: }
        !          3480: 
        !          3481: /* FLAGX is byte sized, and we *do* write it at that size */
        !          3482: static __inline__ void raw_load_flagx(uae_u32 target, uae_u32 r)
        !          3483: {
        !          3484:     if (live.nat[target].canbyte)
        !          3485:        raw_mov_b_rm(target,(uintptr)live.state[r].mem);
        !          3486:     else if (live.nat[target].canword)
        !          3487:        raw_mov_w_rm(target,(uintptr)live.state[r].mem);
        !          3488:     else
        !          3489:        raw_mov_l_rm(target,(uintptr)live.state[r].mem);
        !          3490: }
        !          3491: 
        !          3492: static __inline__ void raw_dec_sp(int off)
        !          3493: {
        !          3494:     if (off) raw_sub_l_ri(ESP_INDEX,off);
        !          3495: }
        !          3496: 
        !          3497: static __inline__ void raw_inc_sp(int off)
        !          3498: {
        !          3499:     if (off) raw_add_l_ri(ESP_INDEX,off);
        !          3500: }
        !          3501: 
        !          3502: /*************************************************************************
        !          3503:  * Handling mistaken direct memory access                                *
        !          3504:  *************************************************************************/
        !          3505: 
        !          3506: // gb-- I don't need that part for JIT Basilisk II
        !          3507: #if defined(NATMEM_OFFSET) && 0
        !          3508: #include <asm/sigcontext.h>
        !          3509: #include <signal.h>
        !          3510: 
        !          3511: #define SIG_READ 1
        !          3512: #define SIG_WRITE 2
        !          3513: 
        !          3514: static int in_handler=0;
        !          3515: static uae_u8 veccode[256];
        !          3516: 
        !          3517: static void vec(int x, struct sigcontext sc)
        !          3518: {
        !          3519:     uae_u8* i=(uae_u8*)sc.eip;
        !          3520:     uae_u32 addr=sc.cr2;
        !          3521:     int r=-1;
        !          3522:     int size=4;
        !          3523:     int dir=-1;
        !          3524:     int len=0;
        !          3525:     int j;
        !          3526:     
        !          3527:     write_log("fault address is %08x at %08x\n",sc.cr2,sc.eip);
        !          3528:     if (!canbang) 
        !          3529:        write_log("Not happy! Canbang is 0 in SIGSEGV handler!\n");
        !          3530:     if (in_handler) 
        !          3531:        write_log("Argh --- Am already in a handler. Shouldn't happen!\n");
        !          3532: 
        !          3533:     if (canbang && i>=compiled_code && i<=current_compile_p) {
        !          3534:        if (*i==0x66) {
        !          3535:            i++;
        !          3536:            size=2;
        !          3537:            len++;
        !          3538:        }
        !          3539:        
        !          3540:        switch(i[0]) {
        !          3541:         case 0x8a:
        !          3542:                                            if ((i[1]&0xc0)==0x80) {
        !          3543:                r=(i[1]>>3)&7;
        !          3544:                dir=SIG_READ;
        !          3545:                size=1;
        !          3546:                len+=6;
        !          3547:                break;
        !          3548:            }
        !          3549:            break;
        !          3550:         case 0x88:
        !          3551:            if ((i[1]&0xc0)==0x80) {
        !          3552:                r=(i[1]>>3)&7;
        !          3553:                dir=SIG_WRITE;
        !          3554:                size=1;
        !          3555:                len+=6;
        !          3556:                break;
        !          3557:            }
        !          3558:            break;
        !          3559:         case 0x8b:
        !          3560:            if ((i[1]&0xc0)==0x80) {
        !          3561:                r=(i[1]>>3)&7;
        !          3562:                dir=SIG_READ;
        !          3563:                len+=6;
        !          3564:                break;
        !          3565:            }
        !          3566:            if ((i[1]&0xc0)==0x40) {
        !          3567:                r=(i[1]>>3)&7;
        !          3568:                dir=SIG_READ;
        !          3569:                len+=3;
        !          3570:                break;
        !          3571:            }
        !          3572:            break;
        !          3573:         case 0x89:
        !          3574:            if ((i[1]&0xc0)==0x80) {
        !          3575:                r=(i[1]>>3)&7;
        !          3576:                dir=SIG_WRITE;
        !          3577:                len+=6;
        !          3578:                break;
        !          3579:            }
        !          3580:            if ((i[1]&0xc0)==0x40) {
        !          3581:                r=(i[1]>>3)&7;
        !          3582:                dir=SIG_WRITE;
        !          3583:                len+=3;
        !          3584:                break;
        !          3585:            }
        !          3586:            break;
        !          3587:        }       
        !          3588:     }
        !          3589: 
        !          3590:     if (r!=-1) { 
        !          3591:        void* pr=NULL;
        !          3592:        write_log("register was %d, direction was %d, size was %d\n",r,dir,size);
        !          3593:        
        !          3594:        switch(r) {
        !          3595:         case 0: pr=&(sc.eax); break;
        !          3596:         case 1: pr=&(sc.ecx); break;
        !          3597:         case 2: pr=&(sc.edx); break;
        !          3598:         case 3: pr=&(sc.ebx); break;
        !          3599:         case 4: pr=(size>1)?NULL:(((uae_u8*)&(sc.eax))+1); break;
        !          3600:         case 5: pr=(size>1)?
        !          3601:                     (void*)(&(sc.ebp)):
        !          3602:                         (void*)(((uae_u8*)&(sc.ecx))+1); break;
        !          3603:         case 6: pr=(size>1)?
        !          3604:                     (void*)(&(sc.esi)):
        !          3605:                         (void*)(((uae_u8*)&(sc.edx))+1); break;
        !          3606:         case 7: pr=(size>1)?
        !          3607:                     (void*)(&(sc.edi)):
        !          3608:                         (void*)(((uae_u8*)&(sc.ebx))+1); break;
        !          3609:         default: abort();
        !          3610:        }
        !          3611:        if (pr) {
        !          3612:            blockinfo* bi;
        !          3613: 
        !          3614:            if (currprefs.comp_oldsegv) {
        !          3615:            addr-=NATMEM_OFFSET;
        !          3616: 
        !          3617:            if ((addr>=0x10000000 && addr<0x40000000) ||
        !          3618:                (addr>=0x50000000)) {
        !          3619:                write_log("Suspicious address in %x SEGV handler.\n",addr);
        !          3620:            }
        !          3621:            if (dir==SIG_READ) {
        !          3622:                switch(size) {
        !          3623:                 case 1: *((uae_u8*)pr)=get_byte(addr); break;
        !          3624:                 case 2: *((uae_u16*)pr)=get_word(addr); break;
        !          3625:                 case 4: *((uae_u32*)pr)=get_long(addr); break;
        !          3626:                 default: abort();
        !          3627:                }
        !          3628:            }
        !          3629:            else { /* write */
        !          3630:                switch(size) {
        !          3631:                 case 1: put_byte(addr,*((uae_u8*)pr)); break;
        !          3632:                 case 2: put_word(addr,*((uae_u16*)pr)); break;
        !          3633:                 case 4: put_long(addr,*((uae_u32*)pr)); break;
        !          3634:                 default: abort();
        !          3635:                }
        !          3636:            }
        !          3637:            write_log("Handled one access!\n");
        !          3638:            fflush(stdout);
        !          3639:            segvcount++;
        !          3640:            sc.eip+=len;
        !          3641:            }
        !          3642:            else {
        !          3643:                void* tmp=target;
        !          3644:                int i;
        !          3645:                uae_u8 vecbuf[5];
        !          3646:                
        !          3647:                addr-=NATMEM_OFFSET;
        !          3648:                
        !          3649:                if ((addr>=0x10000000 && addr<0x40000000) ||
        !          3650:                    (addr>=0x50000000)) {
        !          3651:                    write_log("Suspicious address in %x SEGV handler.\n",addr);
        !          3652:                }
        !          3653:                
        !          3654:                target=(uae_u8*)sc.eip;
        !          3655:                for (i=0;i<5;i++)
        !          3656:                    vecbuf[i]=target[i];
        !          3657:                emit_byte(0xe9);
        !          3658:                emit_long((uintptr)veccode-(uintptr)target-4);
        !          3659:                write_log("Create jump to %p\n",veccode);
        !          3660:            
        !          3661:                write_log("Handled one access!\n");
        !          3662:                fflush(stdout);
        !          3663:                segvcount++;
        !          3664:                
        !          3665:                target=veccode;
        !          3666: 
        !          3667:                if (dir==SIG_READ) {
        !          3668:                    switch(size) {
        !          3669:                     case 1: raw_mov_b_ri(r,get_byte(addr)); break;
        !          3670:                     case 2: raw_mov_w_ri(r,get_byte(addr)); break;
        !          3671:                     case 4: raw_mov_l_ri(r,get_byte(addr)); break;
        !          3672:                     default: abort();
        !          3673:                    }
        !          3674:                }
        !          3675:                else { /* write */
        !          3676:                    switch(size) {
        !          3677:                     case 1: put_byte(addr,*((uae_u8*)pr)); break;
        !          3678:                     case 2: put_word(addr,*((uae_u16*)pr)); break;
        !          3679:                     case 4: put_long(addr,*((uae_u32*)pr)); break;
        !          3680:                     default: abort();
        !          3681:                    }
        !          3682:                }
        !          3683:                for (i=0;i<5;i++)
        !          3684:                    raw_mov_b_mi(sc.eip+i,vecbuf[i]);
        !          3685:                raw_mov_l_mi((uintptr)&in_handler,0);
        !          3686:                emit_byte(0xe9);
        !          3687:                emit_long(sc.eip+len-(uintptr)target-4);
        !          3688:                in_handler=1;
        !          3689:                target=tmp;
        !          3690:            }
        !          3691:            bi=active;
        !          3692:            while (bi) {
        !          3693:                if (bi->handler && 
        !          3694:                    (uae_u8*)bi->direct_handler<=i &&
        !          3695:                    (uae_u8*)bi->nexthandler>i) {
        !          3696:                    write_log("deleted trigger (%p<%p<%p) %p\n",
        !          3697:                              bi->handler,
        !          3698:                              i,
        !          3699:                              bi->nexthandler,
        !          3700:                              bi->pc_p);
        !          3701:                    invalidate_block(bi);
        !          3702:                    raise_in_cl_list(bi);
        !          3703:                    set_special(0);
        !          3704:                    return;
        !          3705:                }
        !          3706:                bi=bi->next;
        !          3707:            }
        !          3708:            /* Not found in the active list. Might be a rom routine that
        !          3709:               is in the dormant list */
        !          3710:            bi=dormant;
        !          3711:            while (bi) {
        !          3712:                if (bi->handler && 
        !          3713:                    (uae_u8*)bi->direct_handler<=i &&
        !          3714:                    (uae_u8*)bi->nexthandler>i) {
        !          3715:                    write_log("deleted trigger (%p<%p<%p) %p\n",
        !          3716:                              bi->handler,
        !          3717:                              i,
        !          3718:                              bi->nexthandler,
        !          3719:                              bi->pc_p);
        !          3720:                    invalidate_block(bi);
        !          3721:                    raise_in_cl_list(bi);
        !          3722:                    set_special(0);
        !          3723:                    return;
        !          3724:                }
        !          3725:                bi=bi->next;
        !          3726:            }
        !          3727:            write_log("Huh? Could not find trigger!\n");
        !          3728:            return;
        !          3729:        }
        !          3730:     }
        !          3731:     write_log("Can't handle access!\n");
        !          3732:     for (j=0;j<10;j++) {
        !          3733:        write_log("instruction byte %2d is %02x\n",j,i[j]);
        !          3734:     }
        !          3735:     write_log("Please send the above info (starting at \"fault address\") to\n"
        !          3736:           "[email protected]\n"
        !          3737:           "This shouldn't happen ;-)\n");
        !          3738:     fflush(stdout);
        !          3739:     signal(SIGSEGV,SIG_DFL);  /* returning here will cause a "real" SEGV */
        !          3740: }
        !          3741: #endif
        !          3742: 
        !          3743: 
        !          3744: /*************************************************************************
        !          3745:  * Checking for CPU features                                             *
        !          3746:  *************************************************************************/
        !          3747: 
        !          3748: struct cpuinfo_x86 {
        !          3749:   uae_u8       x86;                    // CPU family
        !          3750:   uae_u8       x86_vendor;             // CPU vendor
        !          3751:   uae_u8       x86_processor;  // CPU canonical processor type
        !          3752:   uae_u8       x86_brand_id;   // CPU BrandID if supported, yield 0 otherwise
        !          3753:   uae_u32      x86_hwcap;
        !          3754:   uae_u8       x86_model;
        !          3755:   uae_u8       x86_mask;
        !          3756:   int          cpuid_level;    // Maximum supported CPUID level, -1=no CPUID
        !          3757:   char         x86_vendor_id[16];
        !          3758: };
        !          3759: struct cpuinfo_x86 cpuinfo;
        !          3760: 
        !          3761: enum {
        !          3762:   X86_VENDOR_INTEL             = 0,
        !          3763:   X86_VENDOR_CYRIX             = 1,
        !          3764:   X86_VENDOR_AMD               = 2,
        !          3765:   X86_VENDOR_UMC               = 3,
        !          3766:   X86_VENDOR_NEXGEN            = 4,
        !          3767:   X86_VENDOR_CENTAUR   = 5,
        !          3768:   X86_VENDOR_RISE              = 6,
        !          3769:   X86_VENDOR_TRANSMETA = 7,
        !          3770:   X86_VENDOR_NSC               = 8,
        !          3771:   X86_VENDOR_UNKNOWN   = 0xff
        !          3772: };
        !          3773: 
        !          3774: enum {
        !          3775:   X86_PROCESSOR_I386,                       /* 80386 */
        !          3776:   X86_PROCESSOR_I486,                       /* 80486DX, 80486SX, 80486DX[24] */
        !          3777:   X86_PROCESSOR_PENTIUM,
        !          3778:   X86_PROCESSOR_PENTIUMPRO,
        !          3779:   X86_PROCESSOR_K6,
        !          3780:   X86_PROCESSOR_ATHLON,
        !          3781:   X86_PROCESSOR_PENTIUM4,
        !          3782:   X86_PROCESSOR_X86_64,
        !          3783:   X86_PROCESSOR_max
        !          3784: };
        !          3785: 
        !          3786: static const char * x86_processor_string_table[X86_PROCESSOR_max] = {
        !          3787:   "80386",
        !          3788:   "80486",
        !          3789:   "Pentium",
        !          3790:   "PentiumPro",
        !          3791:   "K6",
        !          3792:   "Athlon",
        !          3793:   "Pentium4",
        !          3794:   "x86-64"
        !          3795: };
        !          3796: 
        !          3797: static struct ptt {
        !          3798:   const int align_loop;
        !          3799:   const int align_loop_max_skip;
        !          3800:   const int align_jump;
        !          3801:   const int align_jump_max_skip;
        !          3802:   const int align_func;
        !          3803: }
        !          3804: x86_alignments[X86_PROCESSOR_max] = {
        !          3805:   {  4,  3,  4,  3,  4 },
        !          3806:   { 16, 15, 16, 15, 16 },
        !          3807:   { 16,  7, 16,  7, 16 },
        !          3808:   { 16, 15, 16,  7, 16 },
        !          3809:   { 32,  7, 32,  7, 32 },
        !          3810:   { 16,  7, 16,  7, 16 },
        !          3811:   {  0,  0,  0,  0,  0 },
        !          3812:   { 16,  7, 16,  7, 16 }
        !          3813: };
        !          3814: 
        !          3815: static void
        !          3816: x86_get_cpu_vendor(struct cpuinfo_x86 *c)
        !          3817: {
        !          3818:        char *v = c->x86_vendor_id;
        !          3819: 
        !          3820:        if (!strcmp(v, "GenuineIntel"))
        !          3821:                c->x86_vendor = X86_VENDOR_INTEL;
        !          3822:        else if (!strcmp(v, "AuthenticAMD"))
        !          3823:                c->x86_vendor = X86_VENDOR_AMD;
        !          3824:        else if (!strcmp(v, "CyrixInstead"))
        !          3825:                c->x86_vendor = X86_VENDOR_CYRIX;
        !          3826:        else if (!strcmp(v, "Geode by NSC"))
        !          3827:                c->x86_vendor = X86_VENDOR_NSC;
        !          3828:        else if (!strcmp(v, "UMC UMC UMC "))
        !          3829:                c->x86_vendor = X86_VENDOR_UMC;
        !          3830:        else if (!strcmp(v, "CentaurHauls"))
        !          3831:                c->x86_vendor = X86_VENDOR_CENTAUR;
        !          3832:        else if (!strcmp(v, "NexGenDriven"))
        !          3833:                c->x86_vendor = X86_VENDOR_NEXGEN;
        !          3834:        else if (!strcmp(v, "RiseRiseRise"))
        !          3835:                c->x86_vendor = X86_VENDOR_RISE;
        !          3836:        else if (!strcmp(v, "GenuineTMx86") ||
        !          3837:                 !strcmp(v, "TransmetaCPU"))
        !          3838:                c->x86_vendor = X86_VENDOR_TRANSMETA;
        !          3839:        else
        !          3840:                c->x86_vendor = X86_VENDOR_UNKNOWN;
        !          3841: }
        !          3842: 
        !          3843: static void
        !          3844: cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx)
        !          3845: {
        !          3846:   const int CPUID_SPACE = 4096;
        !          3847:   uae_u8* cpuid_space = (uae_u8 *)vm_acquire(CPUID_SPACE);
        !          3848:   if (cpuid_space == VM_MAP_FAILED)
        !          3849:     abort();
        !          3850:   vm_protect(cpuid_space, CPUID_SPACE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE);
        !          3851: 
        !          3852:   static uae_u32 s_op, s_eax, s_ebx, s_ecx, s_edx;
        !          3853:   uae_u8* tmp=get_target();
        !          3854: 
        !          3855:   s_op = op;
        !          3856:   set_target(cpuid_space);
        !          3857:   raw_push_l_r(0); /* eax */
        !          3858:   raw_push_l_r(1); /* ecx */
        !          3859:   raw_push_l_r(2); /* edx */
        !          3860:   raw_push_l_r(3); /* ebx */
        !          3861:   raw_mov_l_rm(0,(uintptr)&s_op);
        !          3862:   raw_cpuid(0);
        !          3863:   raw_mov_l_mr((uintptr)&s_eax,0);
        !          3864:   raw_mov_l_mr((uintptr)&s_ebx,3);
        !          3865:   raw_mov_l_mr((uintptr)&s_ecx,1);
        !          3866:   raw_mov_l_mr((uintptr)&s_edx,2);
        !          3867:   raw_pop_l_r(3);
        !          3868:   raw_pop_l_r(2);
        !          3869:   raw_pop_l_r(1);
        !          3870:   raw_pop_l_r(0);
        !          3871:   raw_ret();
        !          3872:   set_target(tmp);
        !          3873: 
        !          3874:   ((cpuop_func*)cpuid_space)(0);
        !          3875:   if (eax != NULL) *eax = s_eax;
        !          3876:   if (ebx != NULL) *ebx = s_ebx;
        !          3877:   if (ecx != NULL) *ecx = s_ecx;
        !          3878:   if (edx != NULL) *edx = s_edx;
        !          3879: 
        !          3880:   vm_release(cpuid_space, CPUID_SPACE);
        !          3881: }
        !          3882: 
        !          3883: static void
        !          3884: raw_init_cpu(void)
        !          3885: {
        !          3886:   struct cpuinfo_x86 *c = &cpuinfo;
        !          3887: 
        !          3888:   /* Defaults */
        !          3889:   c->x86_processor = X86_PROCESSOR_max;
        !          3890:   c->x86_vendor = X86_VENDOR_UNKNOWN;
        !          3891:   c->cpuid_level = -1;                         /* CPUID not detected */
        !          3892:   c->x86_model = c->x86_mask = 0;      /* So far unknown... */
        !          3893:   c->x86_vendor_id[0] = '\0';          /* Unset */
        !          3894:   c->x86_hwcap = 0;
        !          3895:   
        !          3896:   /* Get vendor name */
        !          3897:   c->x86_vendor_id[12] = '\0';
        !          3898:   cpuid(0x00000000,
        !          3899:                (uae_u32 *)&c->cpuid_level,
        !          3900:                (uae_u32 *)&c->x86_vendor_id[0],
        !          3901:                (uae_u32 *)&c->x86_vendor_id[8],
        !          3902:                (uae_u32 *)&c->x86_vendor_id[4]);
        !          3903:   x86_get_cpu_vendor(c);
        !          3904: 
        !          3905:   /* Intel-defined flags: level 0x00000001 */
        !          3906:   c->x86_brand_id = 0;
        !          3907:   if ( c->cpuid_level >= 0x00000001 ) {
        !          3908:        uae_u32 tfms, brand_id;
        !          3909:        cpuid(0x00000001, &tfms, &brand_id, NULL, &c->x86_hwcap);
        !          3910:        c->x86 = (tfms >> 8) & 15;
        !          3911:        if (c->x86 == 0xf)
        !          3912:                c->x86 += (tfms >> 20) & 0xff; /* extended family */
        !          3913:        c->x86_model = (tfms >> 4) & 15;
        !          3914:        if (c->x86_model == 0xf)
        !          3915:                c->x86_model |= (tfms >> 12) & 0xf0; /* extended model */
        !          3916:        c->x86_brand_id = brand_id & 0xff;
        !          3917:        c->x86_mask = tfms & 15;
        !          3918:   } else {
        !          3919:        /* Have CPUID level 0 only - unheard of */
        !          3920:        c->x86 = 4;
        !          3921:   }
        !          3922: 
        !          3923:   /* AMD-defined flags: level 0x80000001 */
        !          3924:   uae_u32 xlvl;
        !          3925:   cpuid(0x80000000, &xlvl, NULL, NULL, NULL);
        !          3926:   if ( (xlvl & 0xffff0000) == 0x80000000 ) {
        !          3927:        if ( xlvl >= 0x80000001 ) {
        !          3928:          uae_u32 features, extra_features;
        !          3929:          cpuid(0x80000001, NULL, NULL, &extra_features, &features);
        !          3930:          if (features & (1 << 29)) {
        !          3931:                /* Assume x86-64 if long mode is supported */
        !          3932:                c->x86_processor = X86_PROCESSOR_X86_64;
        !          3933:          }
        !          3934:          if (extra_features & (1 << 0))
        !          3935:                  have_lahf_lm = true;
        !          3936:        }
        !          3937:   }
        !          3938:          
        !          3939:   /* Canonicalize processor ID */
        !          3940:   switch (c->x86) {
        !          3941:   case 3:
        !          3942:        c->x86_processor = X86_PROCESSOR_I386;
        !          3943:        break;
        !          3944:   case 4:
        !          3945:        c->x86_processor = X86_PROCESSOR_I486;
        !          3946:        break;
        !          3947:   case 5:
        !          3948:        if (c->x86_vendor == X86_VENDOR_AMD)
        !          3949:          c->x86_processor = X86_PROCESSOR_K6;
        !          3950:        else
        !          3951:          c->x86_processor = X86_PROCESSOR_PENTIUM;
        !          3952:        break;
        !          3953:   case 6:
        !          3954:        if (c->x86_vendor == X86_VENDOR_AMD)
        !          3955:          c->x86_processor = X86_PROCESSOR_ATHLON;
        !          3956:        else
        !          3957:          c->x86_processor = X86_PROCESSOR_PENTIUMPRO;
        !          3958:        break;
        !          3959:   case 15:
        !          3960:          if (c->x86_processor == X86_PROCESSOR_max) {
        !          3961:                  switch (c->x86_vendor) {
        !          3962:                  case X86_VENDOR_INTEL:
        !          3963:                          c->x86_processor = X86_PROCESSOR_PENTIUM4;
        !          3964:                          break;
        !          3965:                  case X86_VENDOR_AMD:
        !          3966:                          /* Assume a 32-bit Athlon processor if not in long mode */
        !          3967:                          c->x86_processor = X86_PROCESSOR_ATHLON;
        !          3968:                          break;
        !          3969:                  }
        !          3970:          }
        !          3971:          break;
        !          3972:   }
        !          3973:   if (c->x86_processor == X86_PROCESSOR_max) {
        !          3974:        c->x86_processor = X86_PROCESSOR_I386;
        !          3975:        fprintf(stderr, "Error: unknown processor type, assuming i386\n");
        !          3976:        fprintf(stderr, "  Family  : %d\n", c->x86);
        !          3977:        fprintf(stderr, "  Model   : %d\n", c->x86_model);
        !          3978:        fprintf(stderr, "  Mask    : %d\n", c->x86_mask);
        !          3979:        fprintf(stderr, "  Vendor  : %s [%d]\n", c->x86_vendor_id, c->x86_vendor);
        !          3980:        if (c->x86_brand_id)
        !          3981:          fprintf(stderr, "  BrandID : %02x\n", c->x86_brand_id);
        !          3982:   }
        !          3983: 
        !          3984:   /* Have CMOV support? */
        !          3985:   have_cmov = c->x86_hwcap & (1 << 15);
        !          3986: #if defined(__x86_64__)
        !          3987:   if (!have_cmov) {
        !          3988:          write_log("x86-64 implementations are bound to have CMOV!\n");
        !          3989:          abort();
        !          3990:   }
        !          3991: #endif
        !          3992: 
        !          3993:   /* Can the host CPU suffer from partial register stalls? */
        !          3994:   have_rat_stall = (c->x86_vendor == X86_VENDOR_INTEL);
        !          3995: #if 1
        !          3996:   /* It appears that partial register writes are a bad idea even on
        !          3997:         AMD K7 cores, even though they are not supposed to have the
        !          3998:         dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */
        !          3999:   if (c->x86_processor == X86_PROCESSOR_ATHLON)
        !          4000:        have_rat_stall = true;
        !          4001: #endif
        !          4002: 
        !          4003:   /* Alignments */
        !          4004:   if (tune_alignment) {
        !          4005:        align_loops = x86_alignments[c->x86_processor].align_loop;
        !          4006:        align_jumps = x86_alignments[c->x86_processor].align_jump;
        !          4007:   }
        !          4008: 
        !          4009:   write_log("Max CPUID level=%d Processor is %s [%s]\n",
        !          4010:                        c->cpuid_level, c->x86_vendor_id,
        !          4011:                        x86_processor_string_table[c->x86_processor]);
        !          4012: 
        !          4013:   raw_flags_init();
        !          4014: }
        !          4015: 
        !          4016: static bool target_check_bsf(void)
        !          4017: {
        !          4018:        bool mismatch = false;
        !          4019:        for (int g_ZF = 0; g_ZF <= 1; g_ZF++) {
        !          4020:        for (int g_CF = 0; g_CF <= 1; g_CF++) {
        !          4021:        for (int g_OF = 0; g_OF <= 1; g_OF++) {
        !          4022:        for (int g_SF = 0; g_SF <= 1; g_SF++) {
        !          4023:                for (int value = -1; value <= 1; value++) {
        !          4024:                        unsigned long flags = (g_SF << 7) | (g_OF << 11) | (g_ZF << 6) | g_CF;
        !          4025:                        unsigned long tmp = value;
        !          4026:                        __asm__ __volatile__ ("push %0; popf; bsf %1,%1; pushf; pop %0"
        !          4027:                                                                  : "+r" (flags), "+r" (tmp) : : "cc");
        !          4028:                        int OF = (flags >> 11) & 1;
        !          4029:                        int SF = (flags >>  7) & 1;
        !          4030:                        int ZF = (flags >>  6) & 1;
        !          4031:                        int CF = flags & 1;
        !          4032:                        tmp = (value == 0);
        !          4033:                        if (ZF != tmp || SF != g_SF || OF != g_OF || CF != g_CF)
        !          4034:                                mismatch = true;
        !          4035:                }
        !          4036:        }}}}
        !          4037:        if (mismatch)
        !          4038:                write_log("Target CPU defines all flags on BSF instruction\n");
        !          4039:        return !mismatch;
        !          4040: }
        !          4041: 
        !          4042: 
        !          4043: /*************************************************************************
        !          4044:  * FPU stuff                                                             *
        !          4045:  *************************************************************************/
        !          4046: 
        !          4047: 
        !          4048: static __inline__ void raw_fp_init(void)
        !          4049: {
        !          4050:     int i;
        !          4051:     
        !          4052:     for (i=0;i<N_FREGS;i++)
        !          4053:        live.spos[i]=-2;
        !          4054:     live.tos=-1;  /* Stack is empty */
        !          4055: }
        !          4056: 
        !          4057: static __inline__ void raw_fp_cleanup_drop(void)
        !          4058: {
        !          4059: #if 0
        !          4060:     /* using FINIT instead of popping all the entries.
        !          4061:        Seems to have side effects --- there is display corruption in
        !          4062:        Quake when this is used */
        !          4063:     if (live.tos>1) {
        !          4064:        emit_byte(0x9b);
        !          4065:        emit_byte(0xdb);
        !          4066:        emit_byte(0xe3);
        !          4067:        live.tos=-1;
        !          4068:     }
        !          4069: #endif
        !          4070:     while (live.tos>=1) {
        !          4071:        emit_byte(0xde);
        !          4072:        emit_byte(0xd9);
        !          4073:        live.tos-=2;
        !          4074:     }
        !          4075:     while (live.tos>=0) {
        !          4076:        emit_byte(0xdd);
        !          4077:        emit_byte(0xd8);
        !          4078:        live.tos--;
        !          4079:     }
        !          4080:     raw_fp_init();
        !          4081: }
        !          4082: 
        !          4083: static __inline__ void make_tos(int r)
        !          4084: {
        !          4085:     int p,q;
        !          4086: 
        !          4087:     if (live.spos[r]<0) { /* Register not yet on stack */
        !          4088:        emit_byte(0xd9);
        !          4089:        emit_byte(0xe8);  /* Push '1' on the stack, just to grow it */
        !          4090:        live.tos++;
        !          4091:        live.spos[r]=live.tos;
        !          4092:        live.onstack[live.tos]=r;
        !          4093:        return;
        !          4094:     }
        !          4095:     /* Register is on stack */
        !          4096:     if (live.tos==live.spos[r])
        !          4097:        return;
        !          4098:     p=live.spos[r];
        !          4099:     q=live.onstack[live.tos];
        !          4100: 
        !          4101:     emit_byte(0xd9);
        !          4102:     emit_byte(0xc8+live.tos-live.spos[r]);  /* exchange it with top of stack */
        !          4103:     live.onstack[live.tos]=r;
        !          4104:     live.spos[r]=live.tos;
        !          4105:     live.onstack[p]=q;
        !          4106:     live.spos[q]=p;
        !          4107: }
        !          4108: 
        !          4109: static __inline__ void make_tos2(int r, int r2)
        !          4110: {
        !          4111:     int q;
        !          4112: 
        !          4113:     make_tos(r2); /* Put the reg that's supposed to end up in position2
        !          4114:                     on top */
        !          4115: 
        !          4116:     if (live.spos[r]<0) { /* Register not yet on stack */
        !          4117:        make_tos(r); /* This will extend the stack */
        !          4118:        return;
        !          4119:     }
        !          4120:     /* Register is on stack */
        !          4121:     emit_byte(0xd9);
        !          4122:     emit_byte(0xc9); /* Move r2 into position 2 */
        !          4123: 
        !          4124:     q=live.onstack[live.tos-1];
        !          4125:     live.onstack[live.tos]=q;
        !          4126:     live.spos[q]=live.tos;
        !          4127:     live.onstack[live.tos-1]=r2;
        !          4128:     live.spos[r2]=live.tos-1;
        !          4129: 
        !          4130:     make_tos(r); /* And r into 1 */
        !          4131: }
        !          4132: 
        !          4133: static __inline__ int stackpos(int r)
        !          4134: {
        !          4135:     if (live.spos[r]<0)
        !          4136:        abort();
        !          4137:     if (live.tos<live.spos[r]) {
        !          4138:        printf("Looking for spos for fnreg %d\n",r);
        !          4139:        abort();
        !          4140:     }
        !          4141:     return live.tos-live.spos[r];
        !          4142: }
        !          4143: 
        !          4144: static __inline__ void usereg(int r)
        !          4145: {
        !          4146:     if (live.spos[r]<0)
        !          4147:        make_tos(r);
        !          4148: }
        !          4149: 
        !          4150: /* This is called with one FP value in a reg *above* tos, which it will
        !          4151:    pop off the stack if necessary */
        !          4152: static __inline__ void tos_make(int r)
        !          4153: {
        !          4154:     if (live.spos[r]<0) {
        !          4155:        live.tos++;
        !          4156:        live.spos[r]=live.tos;
        !          4157:        live.onstack[live.tos]=r;
        !          4158:        return;
        !          4159:     }
        !          4160:     emit_byte(0xdd);
        !          4161:     emit_byte(0xd8+(live.tos+1)-live.spos[r]);  /* store top of stack in reg, 
        !          4162:                                         and pop it*/
        !          4163: }
        !          4164: 
        !          4165: /* FP helper functions */
        !          4166: #if USE_NEW_RTASM
        !          4167: #define DEFINE_OP(NAME, GEN)                   \
        !          4168: static inline void raw_##NAME(uint32 m)                \
        !          4169: {                                              \
        !          4170:     GEN(m, X86_NOREG, X86_NOREG, 1);           \
        !          4171: }
        !          4172: DEFINE_OP(fstl,  FSTLm);
        !          4173: DEFINE_OP(fstpl, FSTPLm);
        !          4174: DEFINE_OP(fldl,  FLDLm);
        !          4175: DEFINE_OP(fildl, FILDLm);
        !          4176: DEFINE_OP(fistl, FISTLm);
        !          4177: DEFINE_OP(flds,  FLDSm);
        !          4178: DEFINE_OP(fsts,  FSTSm);
        !          4179: DEFINE_OP(fstpt, FSTPTm);
        !          4180: DEFINE_OP(fldt,  FLDTm);
        !          4181: #else
        !          4182: #define DEFINE_OP(NAME, OP1, OP2)              \
        !          4183: static inline void raw_##NAME(uint32 m)                \
        !          4184: {                                              \
        !          4185:     emit_byte(OP1);                            \
        !          4186:     emit_byte(OP2);                            \
        !          4187:     emit_long(m);                              \
        !          4188: }
        !          4189: DEFINE_OP(fstl,  0xdd, 0x15);
        !          4190: DEFINE_OP(fstpl, 0xdd, 0x1d);
        !          4191: DEFINE_OP(fldl,  0xdd, 0x05);
        !          4192: DEFINE_OP(fildl, 0xdb, 0x05);
        !          4193: DEFINE_OP(fistl, 0xdb, 0x15);
        !          4194: DEFINE_OP(flds,  0xd9, 0x05);
        !          4195: DEFINE_OP(fsts,  0xd9, 0x15);
        !          4196: DEFINE_OP(fstpt, 0xdb, 0x3d);
        !          4197: DEFINE_OP(fldt,  0xdb, 0x2d);
        !          4198: #endif
        !          4199: #undef DEFINE_OP
        !          4200: 
        !          4201: LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
        !          4202: {
        !          4203:     make_tos(r);
        !          4204:     raw_fstl(m);
        !          4205: }
        !          4206: LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
        !          4207: 
        !          4208: LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r))
        !          4209: {
        !          4210:     make_tos(r);
        !          4211:     raw_fstpl(m);
        !          4212:     live.onstack[live.tos]=-1;
        !          4213:     live.tos--;
        !          4214:     live.spos[r]=-2;
        !          4215: }
        !          4216: LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
        !          4217: 
        !          4218: LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
        !          4219: {
        !          4220:     raw_fldl(m);
        !          4221:     tos_make(r);
        !          4222: }
        !          4223: LENDFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
        !          4224: 
        !          4225: LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
        !          4226: {
        !          4227:     raw_fildl(m);
        !          4228:     tos_make(r);
        !          4229: }
        !          4230: LENDFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
        !          4231: 
        !          4232: LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
        !          4233: {
        !          4234:     make_tos(r);
        !          4235:     raw_fistl(m);
        !          4236: }
        !          4237: LENDFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
        !          4238: 
        !          4239: LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
        !          4240: {
        !          4241:     raw_flds(m);
        !          4242:     tos_make(r);
        !          4243: }
        !          4244: LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
        !          4245: 
        !          4246: LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
        !          4247: {
        !          4248:     make_tos(r);
        !          4249:     raw_fsts(m);
        !          4250: }
        !          4251: LENDFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
        !          4252: 
        !          4253: LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
        !          4254: {
        !          4255:     int rs;
        !          4256: 
        !          4257:     /* Stupid x87 can't write a long double to mem without popping the 
        !          4258:        stack! */
        !          4259:     usereg(r);
        !          4260:     rs=stackpos(r);
        !          4261:     emit_byte(0xd9);     /* Get a copy to the top of stack */
        !          4262:     emit_byte(0xc0+rs);
        !          4263: 
        !          4264:     raw_fstpt(m);      /* store and pop it */
        !          4265: }
        !          4266: LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
        !          4267: 
        !          4268: LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r))
        !          4269: {
        !          4270:     int rs;
        !          4271: 
        !          4272:     make_tos(r);
        !          4273:     raw_fstpt(m);      /* store and pop it */
        !          4274:     live.onstack[live.tos]=-1;
        !          4275:     live.tos--;
        !          4276:     live.spos[r]=-2;
        !          4277: }
        !          4278: LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
        !          4279: 
        !          4280: LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
        !          4281: {
        !          4282:     raw_fldt(m);
        !          4283:     tos_make(r);
        !          4284: }
        !          4285: LENDFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
        !          4286: 
        !          4287: LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
        !          4288: {
        !          4289:     emit_byte(0xd9);
        !          4290:     emit_byte(0xeb);
        !          4291:     tos_make(r);
        !          4292: }
        !          4293: LENDFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
        !          4294: 
        !          4295: LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
        !          4296: {
        !          4297:     emit_byte(0xd9);
        !          4298:     emit_byte(0xec);
        !          4299:     tos_make(r);
        !          4300: }
        !          4301: LENDFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
        !          4302: 
        !          4303: LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
        !          4304: {
        !          4305:     emit_byte(0xd9);
        !          4306:     emit_byte(0xea);
        !          4307:     tos_make(r);
        !          4308: }
        !          4309: LENDFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
        !          4310: 
        !          4311: LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
        !          4312: {
        !          4313:     emit_byte(0xd9);
        !          4314:     emit_byte(0xed);
        !          4315:     tos_make(r);
        !          4316: }
        !          4317: LENDFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
        !          4318: 
        !          4319: LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
        !          4320: {
        !          4321:     emit_byte(0xd9);
        !          4322:     emit_byte(0xe8);
        !          4323:     tos_make(r);
        !          4324: }
        !          4325: LENDFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
        !          4326: 
        !          4327: LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
        !          4328: {
        !          4329:     emit_byte(0xd9);
        !          4330:     emit_byte(0xee);
        !          4331:     tos_make(r);
        !          4332: }
        !          4333: LENDFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
        !          4334: 
        !          4335: LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
        !          4336: {
        !          4337:     int ds;
        !          4338: 
        !          4339:     usereg(s);
        !          4340:     ds=stackpos(s);
        !          4341:     if (ds==0 && live.spos[d]>=0) {
        !          4342:        /* source is on top of stack, and we already have the dest */
        !          4343:        int dd=stackpos(d);
        !          4344:        emit_byte(0xdd);
        !          4345:        emit_byte(0xd0+dd);
        !          4346:     }
        !          4347:     else {
        !          4348:        emit_byte(0xd9);
        !          4349:        emit_byte(0xc0+ds); /* duplicate source on tos */
        !          4350:        tos_make(d); /* store to destination, pop if necessary */
        !          4351:     }
        !          4352: }
        !          4353: LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
        !          4354: 
        !          4355: LOWFUNC(NONE,READ,4,raw_fldcw_m_indexed,(R4 index, IMM base))
        !          4356: {
        !          4357:     emit_byte(0xd9);
        !          4358:     emit_byte(0xa8+index);
        !          4359:     emit_long(base);
        !          4360: }
        !          4361: LENDFUNC(NONE,READ,4,raw_fldcw_m_indexed,(R4 index, IMM base))
        !          4362: 
        !          4363: 
        !          4364: LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
        !          4365: {
        !          4366:     int ds;
        !          4367: 
        !          4368:     if (d!=s) {
        !          4369:        usereg(s);
        !          4370:        ds=stackpos(s);
        !          4371:        emit_byte(0xd9);
        !          4372:        emit_byte(0xc0+ds); /* duplicate source */
        !          4373:        emit_byte(0xd9);
        !          4374:        emit_byte(0xfa); /* take square root */
        !          4375:        tos_make(d); /* store to destination */
        !          4376:     }
        !          4377:     else {
        !          4378:        make_tos(d);
        !          4379:        emit_byte(0xd9);
        !          4380:        emit_byte(0xfa); /* take square root */
        !          4381:     }  
        !          4382: }
        !          4383: LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
        !          4384: 
        !          4385: LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
        !          4386: {
        !          4387:     int ds;
        !          4388: 
        !          4389:     if (d!=s) {
        !          4390:        usereg(s);
        !          4391:        ds=stackpos(s);
        !          4392:        emit_byte(0xd9);
        !          4393:        emit_byte(0xc0+ds); /* duplicate source */
        !          4394:        emit_byte(0xd9);
        !          4395:        emit_byte(0xe1); /* take fabs */
        !          4396:        tos_make(d); /* store to destination */
        !          4397:     }
        !          4398:     else {
        !          4399:        make_tos(d);
        !          4400:        emit_byte(0xd9);
        !          4401:        emit_byte(0xe1); /* take fabs */
        !          4402:     }  
        !          4403: }
        !          4404: LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
        !          4405: 
        !          4406: LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
        !          4407: {
        !          4408:     int ds;
        !          4409: 
        !          4410:     if (d!=s) {
        !          4411:        usereg(s);
        !          4412:        ds=stackpos(s);
        !          4413:        emit_byte(0xd9);
        !          4414:        emit_byte(0xc0+ds); /* duplicate source */
        !          4415:        emit_byte(0xd9);
        !          4416:        emit_byte(0xfc); /* take frndint */
        !          4417:        tos_make(d); /* store to destination */
        !          4418:     }
        !          4419:     else {
        !          4420:        make_tos(d);
        !          4421:        emit_byte(0xd9);
        !          4422:        emit_byte(0xfc); /* take frndint */
        !          4423:     }  
        !          4424: }
        !          4425: LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
        !          4426: 
        !          4427: LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
        !          4428: {
        !          4429:     int ds;
        !          4430: 
        !          4431:     if (d!=s) {
        !          4432:        usereg(s);
        !          4433:        ds=stackpos(s);
        !          4434:        emit_byte(0xd9);
        !          4435:        emit_byte(0xc0+ds); /* duplicate source */
        !          4436:        emit_byte(0xd9);
        !          4437:        emit_byte(0xff); /* take cos */
        !          4438:        tos_make(d); /* store to destination */
        !          4439:     }
        !          4440:     else {
        !          4441:        make_tos(d);
        !          4442:        emit_byte(0xd9);
        !          4443:        emit_byte(0xff); /* take cos */
        !          4444:     }  
        !          4445: }
        !          4446: LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
        !          4447: 
        !          4448: LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
        !          4449: {
        !          4450:     int ds;
        !          4451: 
        !          4452:     if (d!=s) {
        !          4453:        usereg(s);
        !          4454:        ds=stackpos(s);
        !          4455:        emit_byte(0xd9);
        !          4456:        emit_byte(0xc0+ds); /* duplicate source */
        !          4457:        emit_byte(0xd9);
        !          4458:        emit_byte(0xfe); /* take sin */
        !          4459:        tos_make(d); /* store to destination */
        !          4460:     }
        !          4461:     else {
        !          4462:        make_tos(d);
        !          4463:        emit_byte(0xd9);
        !          4464:        emit_byte(0xfe); /* take sin */
        !          4465:     }  
        !          4466: }
        !          4467: LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
        !          4468: 
        !          4469: static const double one=1;
        !          4470: LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
        !          4471: {
        !          4472:     int ds;
        !          4473: 
        !          4474:     usereg(s);
        !          4475:     ds=stackpos(s);
        !          4476:     emit_byte(0xd9);
        !          4477:     emit_byte(0xc0+ds); /* duplicate source */
        !          4478: 
        !          4479:     emit_byte(0xd9);
        !          4480:     emit_byte(0xc0);  /* duplicate top of stack. Now up to 8 high */
        !          4481:     emit_byte(0xd9);
        !          4482:     emit_byte(0xfc);  /* rndint */
        !          4483:     emit_byte(0xd9);
        !          4484:     emit_byte(0xc9);  /* swap top two elements */
        !          4485:     emit_byte(0xd8);
        !          4486:     emit_byte(0xe1);  /* subtract rounded from original */
        !          4487:     emit_byte(0xd9);
        !          4488:     emit_byte(0xf0);  /* f2xm1 */
        !          4489:     x86_fadd_m((uintptr)&one);  /* Add '1' without using extra stack space */
        !          4490:     emit_byte(0xd9);
        !          4491:     emit_byte(0xfd);  /* and scale it */
        !          4492:     emit_byte(0xdd);
        !          4493:     emit_byte(0xd9);  /* take he rounded value off */
        !          4494:     tos_make(d); /* store to destination */
        !          4495: }
        !          4496: LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
        !          4497: 
        !          4498: LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
        !          4499: {
        !          4500:     int ds;
        !          4501: 
        !          4502:     usereg(s);
        !          4503:     ds=stackpos(s);
        !          4504:     emit_byte(0xd9);
        !          4505:     emit_byte(0xc0+ds); /* duplicate source */
        !          4506:     emit_byte(0xd9);
        !          4507:     emit_byte(0xea);   /* fldl2e */
        !          4508:     emit_byte(0xde);
        !          4509:     emit_byte(0xc9);  /* fmulp --- multiply source by log2(e) */
        !          4510: 
        !          4511:     emit_byte(0xd9);
        !          4512:     emit_byte(0xc0);  /* duplicate top of stack. Now up to 8 high */
        !          4513:     emit_byte(0xd9);
        !          4514:     emit_byte(0xfc);  /* rndint */
        !          4515:     emit_byte(0xd9);
        !          4516:     emit_byte(0xc9);  /* swap top two elements */
        !          4517:     emit_byte(0xd8);
        !          4518:     emit_byte(0xe1);  /* subtract rounded from original */
        !          4519:     emit_byte(0xd9);
        !          4520:     emit_byte(0xf0);  /* f2xm1 */
        !          4521:     x86_fadd_m((uintptr)&one);  /* Add '1' without using extra stack space */
        !          4522:     emit_byte(0xd9);
        !          4523:     emit_byte(0xfd);  /* and scale it */
        !          4524:     emit_byte(0xdd);
        !          4525:     emit_byte(0xd9);  /* take he rounded value off */
        !          4526:     tos_make(d); /* store to destination */
        !          4527: }
        !          4528: LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
        !          4529:  
        !          4530: LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
        !          4531: {
        !          4532:     int ds;
        !          4533: 
        !          4534:     usereg(s);
        !          4535:     ds=stackpos(s);
        !          4536:     emit_byte(0xd9);
        !          4537:     emit_byte(0xc0+ds); /* duplicate source */
        !          4538:     emit_byte(0xd9);
        !          4539:     emit_byte(0xe8); /* push '1' */
        !          4540:     emit_byte(0xd9);
        !          4541:     emit_byte(0xc9); /* swap top two */
        !          4542:     emit_byte(0xd9);
        !          4543:     emit_byte(0xf1); /* take 1*log2(x) */
        !          4544:     tos_make(d); /* store to destination */
        !          4545: }
        !          4546: LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
        !          4547: 
        !          4548: 
        !          4549: LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
        !          4550: {
        !          4551:     int ds;
        !          4552: 
        !          4553:     if (d!=s) {
        !          4554:        usereg(s);
        !          4555:        ds=stackpos(s);
        !          4556:        emit_byte(0xd9);
        !          4557:        emit_byte(0xc0+ds); /* duplicate source */
        !          4558:        emit_byte(0xd9);
        !          4559:        emit_byte(0xe0); /* take fchs */
        !          4560:        tos_make(d); /* store to destination */
        !          4561:     }
        !          4562:     else {
        !          4563:        make_tos(d);
        !          4564:        emit_byte(0xd9);
        !          4565:        emit_byte(0xe0); /* take fchs */
        !          4566:     }  
        !          4567: }
        !          4568: LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
        !          4569: 
        !          4570: LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
        !          4571: {
        !          4572:     int ds;
        !          4573: 
        !          4574:     usereg(s);
        !          4575:     usereg(d);
        !          4576:     
        !          4577:     if (live.spos[s]==live.tos) {
        !          4578:        /* Source is on top of stack */
        !          4579:        ds=stackpos(d);
        !          4580:        emit_byte(0xdc);
        !          4581:        emit_byte(0xc0+ds); /* add source to dest*/
        !          4582:     }
        !          4583:     else {
        !          4584:        make_tos(d);
        !          4585:        ds=stackpos(s);
        !          4586:        
        !          4587:        emit_byte(0xd8);
        !          4588:        emit_byte(0xc0+ds); /* add source to dest*/
        !          4589:     }
        !          4590: }
        !          4591: LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
        !          4592: 
        !          4593: LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
        !          4594: {
        !          4595:     int ds;
        !          4596: 
        !          4597:     usereg(s);
        !          4598:     usereg(d);
        !          4599:     
        !          4600:     if (live.spos[s]==live.tos) {
        !          4601:        /* Source is on top of stack */
        !          4602:        ds=stackpos(d);
        !          4603:        emit_byte(0xdc);
        !          4604:        emit_byte(0xe8+ds); /* sub source from dest*/
        !          4605:     }
        !          4606:     else {
        !          4607:        make_tos(d);
        !          4608:        ds=stackpos(s);
        !          4609:        
        !          4610:        emit_byte(0xd8);
        !          4611:        emit_byte(0xe0+ds); /* sub src from dest */
        !          4612:     }
        !          4613: }
        !          4614: LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
        !          4615: 
        !          4616: LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
        !          4617: {
        !          4618:     int ds;
        !          4619: 
        !          4620:     usereg(s);
        !          4621:     usereg(d);
        !          4622:     
        !          4623:     make_tos(d);
        !          4624:     ds=stackpos(s);
        !          4625: 
        !          4626:     emit_byte(0xdd);
        !          4627:     emit_byte(0xe0+ds); /* cmp dest with source*/
        !          4628: }
        !          4629: LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
        !          4630: 
        !          4631: LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
        !          4632: {
        !          4633:     int ds;
        !          4634: 
        !          4635:     usereg(s);
        !          4636:     usereg(d);
        !          4637:     
        !          4638:     if (live.spos[s]==live.tos) {
        !          4639:        /* Source is on top of stack */
        !          4640:        ds=stackpos(d);
        !          4641:        emit_byte(0xdc);
        !          4642:        emit_byte(0xc8+ds); /* mul dest by source*/
        !          4643:     }
        !          4644:     else {
        !          4645:        make_tos(d);
        !          4646:        ds=stackpos(s);
        !          4647:        
        !          4648:        emit_byte(0xd8);
        !          4649:        emit_byte(0xc8+ds); /* mul dest by source*/
        !          4650:     }
        !          4651: }
        !          4652: LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
        !          4653: 
        !          4654: LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
        !          4655: {
        !          4656:     int ds;
        !          4657: 
        !          4658:     usereg(s);
        !          4659:     usereg(d);
        !          4660:     
        !          4661:     if (live.spos[s]==live.tos) {
        !          4662:        /* Source is on top of stack */
        !          4663:        ds=stackpos(d);
        !          4664:        emit_byte(0xdc);
        !          4665:        emit_byte(0xf8+ds); /* div dest by source */
        !          4666:     }
        !          4667:     else {
        !          4668:        make_tos(d);
        !          4669:        ds=stackpos(s);
        !          4670:        
        !          4671:        emit_byte(0xd8);
        !          4672:        emit_byte(0xf0+ds); /* div dest by source*/
        !          4673:     }
        !          4674: }
        !          4675: LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
        !          4676: 
        !          4677: LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
        !          4678: {
        !          4679:     int ds;
        !          4680: 
        !          4681:     usereg(s);
        !          4682:     usereg(d);
        !          4683:     
        !          4684:     make_tos2(d,s);
        !          4685:     ds=stackpos(s);
        !          4686: 
        !          4687:     if (ds!=1) {
        !          4688:        printf("Failed horribly in raw_frem_rr! ds is %d\n",ds);
        !          4689:        abort();
        !          4690:     }
        !          4691:     emit_byte(0xd9);
        !          4692:     emit_byte(0xf8); /* take rem from dest by source */
        !          4693: }
        !          4694: LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
        !          4695: 
        !          4696: LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
        !          4697: {
        !          4698:     int ds;
        !          4699: 
        !          4700:     usereg(s);
        !          4701:     usereg(d);
        !          4702:     
        !          4703:     make_tos2(d,s);
        !          4704:     ds=stackpos(s);
        !          4705: 
        !          4706:     if (ds!=1) {
        !          4707:        printf("Failed horribly in raw_frem1_rr! ds is %d\n",ds);
        !          4708:        abort();
        !          4709:     }
        !          4710:     emit_byte(0xd9);
        !          4711:     emit_byte(0xf5); /* take rem1 from dest by source */
        !          4712: }
        !          4713: LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
        !          4714: 
        !          4715: 
        !          4716: LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
        !          4717: {
        !          4718:     make_tos(r);
        !          4719:     emit_byte(0xd9);  /* ftst */
        !          4720:     emit_byte(0xe4);
        !          4721: }
        !          4722: LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
        !          4723: 
        !          4724: /* %eax register is clobbered if target processor doesn't support fucomi */
        !          4725: #define FFLAG_NREG_CLOBBER_CONDITION !have_cmov
        !          4726: #define FFLAG_NREG EAX_INDEX
        !          4727: 
        !          4728: static __inline__ void raw_fflags_into_flags(int r)
        !          4729: {
        !          4730:     int p;
        !          4731: 
        !          4732:     usereg(r);
        !          4733:     p=stackpos(r);
        !          4734: 
        !          4735:     emit_byte(0xd9);
        !          4736:     emit_byte(0xee); /* Push 0 */
        !          4737:     emit_byte(0xd9);
        !          4738:     emit_byte(0xc9+p); /* swap top two around */
        !          4739:        if (have_cmov) {
        !          4740:                // gb-- fucomi is for P6 cores only, not K6-2 then...
        !          4741:        emit_byte(0xdb);
        !          4742:        emit_byte(0xe9+p); /* fucomi them */
        !          4743:        }
        !          4744:        else {
        !          4745:                emit_byte(0xdd);
        !          4746:                emit_byte(0xe1+p); /* fucom them */
        !          4747:                emit_byte(0x9b);
        !          4748:                emit_byte(0xdf);
        !          4749:                emit_byte(0xe0); /* fstsw ax */
        !          4750:                raw_sahf(0); /* sahf */
        !          4751:        }
        !          4752:     emit_byte(0xdd);
        !          4753:     emit_byte(0xd9+p);  /* store value back, and get rid of 0 */
        !          4754: }

unix.superglobalmegacorp.com

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