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

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

unix.superglobalmegacorp.com

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