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

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

unix.superglobalmegacorp.com

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