Annotation of previous_trunk/src/cpu/jit/codegen_x86.c, revision 1.1.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.