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

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
        !            28:  * along with this program; if not, write to the Free Software
        !            29:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
        !          3716: static void cpuid_count(uae_u32 op, uae_u32 count, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx)
        !          3717: {
        !          3718:        int cpuinfo[4];
        !          3719:        cpuinfo[0] = op;
        !          3720:        cpuinfo[1] = 0;
        !          3721:        cpuinfo[2] = count;
        !          3722:        cpuinfo[3] = 0;
        !          3723:        __cpuidex(cpuinfo, op, count);
        !          3724:        *eax = cpuinfo[0];
        !          3725:        *ebx = cpuinfo[1];
        !          3726:        *ecx = cpuinfo[2];
        !          3727:        *edx = cpuinfo[3];
        !          3728:        }
        !          3729: #endif
        !          3730: 
1.1       root     3731: static void
                   3732: cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx)
                   3733: {
1.1.1.2 ! root     3734:        cpuid_count(op, 0, eax, ebx, ecx, edx);
1.1       root     3735: }
                   3736: 
                   3737: static void
                   3738: raw_init_cpu(void)
                   3739: {
1.1.1.2 ! root     3740:        struct cpuinfo_x86 *c = &cpuinfo;
        !          3741:        uae_u32 dummy;
1.1       root     3742: 
1.1.1.2 ! root     3743:        /* Defaults */
        !          3744:        c->x86_processor = X86_PROCESSOR_max;
        !          3745:        c->x86_vendor = X86_VENDOR_UNKNOWN;
        !          3746:        c->cpuid_level = -1;                            /* CPUID not detected */
        !          3747:        c->x86_model = c->x86_mask = 0; /* So far unknown... */
        !          3748:        c->x86_vendor_id[0] = '\0';             /* Unset */
        !          3749:        c->x86_hwcap = 0;
        !          3750: #ifdef CPU_x86_64
        !          3751:        c->x86_clflush_size = 64;
        !          3752: #else
        !          3753:        c->x86_clflush_size = 32;
        !          3754: #endif
        !          3755: 
        !          3756:        /* Get vendor name */
        !          3757:        c->x86_vendor_id[12] = '\0';
        !          3758:        cpuid(0x00000000,
1.1       root     3759:                (uae_u32 *)&c->cpuid_level,
                   3760:                (uae_u32 *)&c->x86_vendor_id[0],
                   3761:                (uae_u32 *)&c->x86_vendor_id[8],
                   3762:                (uae_u32 *)&c->x86_vendor_id[4]);
1.1.1.2 ! root     3763:        x86_get_cpu_vendor(c);
1.1       root     3764: 
1.1.1.2 ! root     3765:        /* Intel-defined flags: level 0x00000001 */
        !          3766:        c->x86_brand_id = 0;
        !          3767:        if ( c->cpuid_level >= 0x00000001 ) {
        !          3768:                uae_u32 tfms, brand_id;
        !          3769:                cpuid(0x00000001, &tfms, &brand_id, &dummy, &c->x86_hwcap);
        !          3770:                c->x86 = (tfms >> 8) & 15;
        !          3771:                if (c->x86 == 0xf)
        !          3772:                        c->x86 += (tfms >> 20) & 0xff; /* extended family */
        !          3773:                c->x86_model = (tfms >> 4) & 15;
        !          3774:                if (c->x86_model == 0xf)
        !          3775:                        c->x86_model |= (tfms >> 12) & 0xf0; /* extended model */
        !          3776:                c->x86_brand_id = brand_id & 0xff;
        !          3777:                c->x86_mask = tfms & 15;
        !          3778:                if (c->x86_hwcap & (1 << 19))
        !          3779:                {
        !          3780:                        c->x86_clflush_size = ((brand_id >> 8) & 0xff) * 8;
        !          3781:                }
        !          3782:        } else {
        !          3783:                /* Have CPUID level 0 only - unheard of */
        !          3784:                c->x86 = 4;
        !          3785:        }
        !          3786: 
        !          3787:        /* AMD-defined flags: level 0x80000001 */
        !          3788:        uae_u32 xlvl;
        !          3789:        cpuid(0x80000000, &xlvl, &dummy, &dummy, &dummy);
        !          3790:        if ( (xlvl & 0xffff0000) == 0x80000000 ) {
        !          3791:                if ( xlvl >= 0x80000001 ) {
        !          3792:                        uae_u32 features, extra_features;
        !          3793:                        cpuid(0x80000001, &dummy, &dummy, &extra_features, &features);
        !          3794:                        if (features & (1 << 29)) {
        !          3795:                                /* Assume x86-64 if long mode is supported */
        !          3796:                                c->x86_processor = X86_PROCESSOR_X86_64;
        !          3797:                        }
        !          3798:                        if (extra_features & (1 << 0))
        !          3799:                                have_lahf_lm = true;
        !          3800:                }
1.1       root     3801:        }
                   3802: 
1.1.1.2 ! root     3803:        /* Canonicalize processor ID */
        !          3804:        switch (c->x86) {
        !          3805:        case 3:
        !          3806:                c->x86_processor = X86_PROCESSOR_I386;
        !          3807:                break;
        !          3808:        case 4:
        !          3809:                c->x86_processor = X86_PROCESSOR_I486;
        !          3810:                break;
        !          3811:        case 5:
        !          3812:                if (c->x86_vendor == X86_VENDOR_AMD)
        !          3813:                        c->x86_processor = X86_PROCESSOR_K6;
        !          3814:                else
        !          3815:                        c->x86_processor = X86_PROCESSOR_PENTIUM;
        !          3816:                break;
        !          3817:        case 6:
        !          3818:                if (c->x86_vendor == X86_VENDOR_AMD)
        !          3819:                        c->x86_processor = X86_PROCESSOR_ATHLON;
        !          3820:                else
        !          3821:                        c->x86_processor = X86_PROCESSOR_PENTIUMPRO;
        !          3822:                break;
        !          3823:        case 15:
        !          3824:                if (c->x86_processor == X86_PROCESSOR_max) {
        !          3825:                        switch (c->x86_vendor) {
        !          3826:                        case X86_VENDOR_INTEL:
        !          3827:                                c->x86_processor = X86_PROCESSOR_PENTIUM4;
        !          3828:                                break;
        !          3829:                        case X86_VENDOR_AMD:
        !          3830:                                /* Assume a 32-bit Athlon processor if not in long mode */
        !          3831:                                c->x86_processor = X86_PROCESSOR_ATHLON;
        !          3832:                                break;
        !          3833:                        }
        !          3834:                }
        !          3835:                break;
        !          3836:        }
        !          3837:        if (c->x86_processor == X86_PROCESSOR_max) {
        !          3838:                c->x86_processor = X86_PROCESSOR_I386;
        !          3839:                jit_log("Error: unknown processor type");
        !          3840:                jit_log("  Family  : %d", c->x86);
        !          3841:                jit_log("  Model   : %d", c->x86_model);
        !          3842:                jit_log("  Mask    : %d", c->x86_mask);
        !          3843:                jit_log("  Vendor  : %s [%d]", c->x86_vendor_id, c->x86_vendor);
        !          3844:                if (c->x86_brand_id)
        !          3845:                        jit_log("  BrandID : %02x", c->x86_brand_id);
        !          3846:        }
        !          3847: 
        !          3848:        /* Have CMOV support? */
        !          3849:        have_cmov = (c->x86_hwcap & (1 << 15)) != 0;
        !          3850: #if defined(CPU_x86_64)
        !          3851:        if (!have_cmov) {
        !          3852:                jit_abort("x86-64 implementations are bound to have CMOV!");
        !          3853:        }
1.1       root     3854: #endif
                   3855: 
1.1.1.2 ! root     3856:        c->x86_has_xmm2 = (c->x86_hwcap & (1 << 26)) != 0;
        !          3857: 
        !          3858:        /* Can the host CPU suffer from partial register stalls? */
        !          3859:        // non-RAT_STALL mode is currently broken
        !          3860:        have_rat_stall = true; //(c->x86_vendor == X86_VENDOR_INTEL);
        !          3861: #if 0
        !          3862:        /* It appears that partial register writes are a bad idea even on
        !          3863:        AMD K7 cores, even though they are not supposed to have the
        !          3864:        dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */
        !          3865:        if (c->x86_processor == X86_PROCESSOR_ATHLON)
        !          3866:                have_rat_stall = true;
1.1       root     3867: #endif
                   3868: 
1.1.1.2 ! root     3869:        /* Alignments */
        !          3870:        if (tune_alignment) {
        !          3871:                align_loops = x86_alignments[c->x86_processor].align_loop;
        !          3872:                align_jumps = x86_alignments[c->x86_processor].align_jump;
        !          3873:        }
1.1       root     3874: 
1.1.1.2 ! root     3875:        jit_log("Max CPUID level=%d Processor is %s [%s]",
1.1       root     3876:                        c->cpuid_level, c->x86_vendor_id,
                   3877:                        x86_processor_string_table[c->x86_processor]);
                   3878: 
1.1.1.2 ! root     3879:        raw_flags_init();
1.1       root     3880: }
                   3881: 
1.1.1.2 ! root     3882: #if 0
        !          3883: static void __attribute_noinline__ prevent_redzone_use(void) {}
        !          3884: 
1.1       root     3885: static bool target_check_bsf(void)
                   3886: {
                   3887:        bool mismatch = false;
                   3888:        for (int g_ZF = 0; g_ZF <= 1; g_ZF++) {
1.1.1.2 ! root     3889:                for (int g_CF = 0; g_CF <= 1; g_CF++) {
        !          3890:                        for (int g_OF = 0; g_OF <= 1; g_OF++) {
        !          3891:                                for (int g_SF = 0; g_SF <= 1; g_SF++) {
        !          3892:                                        for (int value = -1; value <= 1; value++) {
        !          3893:                                                uintptr flags = (g_SF << 7) | (g_OF << 11) | (g_ZF << 6) | g_CF;
        !          3894:                                                intptr tmp = value;
        !          3895:                                                prevent_redzone_use();
        !          3896:                                                __asm__ __volatile__ ("push %0; popf; bsf %1,%1; pushf; pop %0"
        !          3897:                                                        : "+r" (flags), "+r" (tmp) : : "cc");
        !          3898:                                                int OF = (flags >> 11) & 1;
        !          3899:                                                int SF = (flags >>  7) & 1;
        !          3900:                                                int ZF = (flags >>  6) & 1;
        !          3901:                                                int CF = flags & 1;
        !          3902:                                                tmp = (value == 0);
        !          3903:                                                if (ZF != tmp || SF != g_SF || OF != g_OF || CF != g_CF)
        !          3904:                                                        mismatch = true;
        !          3905:                                        }
        !          3906:                                }}}}
1.1       root     3907:        if (mismatch)
1.1.1.2 ! root     3908:        {
        !          3909:                jit_log("Target CPU defines all flags on BSF instruction");
        !          3910:        }
1.1       root     3911:        return !mismatch;
                   3912: }
1.1.1.2 ! root     3913: #endif
1.1       root     3914: 
                   3915: /*************************************************************************
1.1.1.2 ! root     3916: * FPU stuff                                                             *
        !          3917: *************************************************************************/
1.1       root     3918: 
                   3919: 
1.1.1.2 ! root     3920: static inline void raw_fp_init(void)
1.1       root     3921: {
1.1.1.2 ! root     3922:        int i;
        !          3923: 
        !          3924:        for (i=0;i<N_FREGS;i++)
        !          3925:                live.spos[i]=-2;
        !          3926:        live.tos=-1;  /* Stack is empty */
1.1       root     3927: }
                   3928: 
1.1.1.2 ! root     3929: static inline void raw_fp_cleanup_drop(void)
1.1       root     3930: {
                   3931: #if 0
1.1.1.2 ! root     3932:        /* using FINIT instead of popping all the entries.
        !          3933:        Seems to have side effects --- there is display corruption in
        !          3934:        Quake when this is used */
        !          3935:        if (live.tos>1) {
        !          3936:                emit_byte(0x9b);
        !          3937:                emit_byte(0xdb);
        !          3938:                emit_byte(0xe3);
        !          3939:                live.tos=-1;
        !          3940:        }
1.1       root     3941: #endif
1.1.1.2 ! root     3942:        while (live.tos>=1) {
        !          3943:                emit_byte(0xde);
        !          3944:                emit_byte(0xd9);
        !          3945:                live.tos-=2;
        !          3946:        }
        !          3947:        while (live.tos>=0) {
        !          3948:                emit_byte(0xdd);
        !          3949:                emit_byte(0xd8);
        !          3950:                live.tos--;
        !          3951:        }
        !          3952:        raw_fp_init();
1.1       root     3953: }
                   3954: 
1.1.1.2 ! root     3955: static inline void make_tos(int r)
1.1       root     3956: {
1.1.1.2 ! root     3957:        int p,q;
        !          3958: 
        !          3959:        if (live.spos[r]<0) { /* Register not yet on stack */
        !          3960:                emit_byte(0xd9);
        !          3961:                emit_byte(0xe8);  /* Push '1' on the stack, just to grow it */
        !          3962:                live.tos++;
        !          3963:                live.spos[r]=live.tos;
        !          3964:                live.onstack[live.tos]=r;
        !          3965:                return;
        !          3966:        }
        !          3967:        /* Register is on stack */
        !          3968:        if (live.tos==live.spos[r])
        !          3969:                return;
        !          3970:        p=live.spos[r];
        !          3971:        q=live.onstack[live.tos];
1.1       root     3972: 
                   3973:        emit_byte(0xd9);
1.1.1.2 ! root     3974:        emit_byte(0xc8+live.tos-live.spos[r]);  /* exchange it with top of stack */
1.1       root     3975:        live.onstack[live.tos]=r;
1.1.1.2 ! root     3976:        live.spos[r]=live.tos;
        !          3977:        live.onstack[p]=q;
        !          3978:        live.spos[q]=p;
1.1       root     3979: }
                   3980: 
1.1.1.2 ! root     3981: static inline void make_tos2(int r, int r2)
1.1       root     3982: {
                   3983:     int q;
                   3984: 
                   3985:     make_tos(r2); /* Put the reg that's supposed to end up in position2
                   3986:                     on top */
                   3987: 
                   3988:     if (live.spos[r]<0) { /* Register not yet on stack */
                   3989:        make_tos(r); /* This will extend the stack */
                   3990:        return;
                   3991:     }
                   3992:     /* Register is on stack */
                   3993:     emit_byte(0xd9);
                   3994:     emit_byte(0xc9); /* Move r2 into position 2 */
                   3995: 
                   3996:     q=live.onstack[live.tos-1];
                   3997:     live.onstack[live.tos]=q;
                   3998:     live.spos[q]=live.tos;
                   3999:     live.onstack[live.tos-1]=r2;
                   4000:     live.spos[r2]=live.tos-1;
                   4001: 
                   4002:     make_tos(r); /* And r into 1 */
                   4003: }
                   4004: 
1.1.1.2 ! root     4005: static inline int stackpos(int r)
1.1       root     4006: {
1.1.1.2 ! root     4007:        if (live.spos[r]<0)
        !          4008:                abort();
        !          4009:        if (live.tos<live.spos[r]) {
        !          4010:                jit_abort("Looking for spos for fnreg %d",r);
        !          4011:        }
        !          4012:        return live.tos-live.spos[r];
1.1       root     4013: }
                   4014: 
1.1.1.2 ! root     4015: /* IMO, calling usereg(r) makes no sense, if the register r should supply our function with
        !          4016: an argument, because I would expect all arguments to be on the stack already, won't they?
        !          4017: Thus, usereg(s) is always useless and also for every FRW d it's too late here now. PeterK
        !          4018: */
        !          4019: static inline void usereg(int r)
1.1       root     4020: {
1.1.1.2 ! root     4021:        if (live.spos[r]<0)
        !          4022:                make_tos(r);
1.1       root     4023: }
                   4024: 
                   4025: /* This is called with one FP value in a reg *above* tos, which it will
                   4026:    pop off the stack if necessary */
1.1.1.2 ! root     4027: static inline void tos_make(int r)
1.1       root     4028: {
1.1.1.2 ! root     4029:        if (live.spos[r]<0) {
        !          4030:                live.tos++;
        !          4031:                live.spos[r]=live.tos;
        !          4032:                live.onstack[live.tos]=r;
        !          4033:                return;
        !          4034:        }
        !          4035:        emit_byte(0xdd);
        !          4036:        emit_byte(0xd8+(live.tos+1)-live.spos[r]);  /* store top of stack in reg,
        !          4037:                                                       and pop it*/
1.1       root     4038: }
                   4039: 
                   4040: /* FP helper functions */
                   4041: #if USE_NEW_RTASM
                   4042: #define DEFINE_OP(NAME, GEN)                   \
                   4043: static inline void raw_##NAME(uint32 m)                \
                   4044: {                                              \
                   4045:     GEN(m, X86_NOREG, X86_NOREG, 1);           \
                   4046: }
                   4047: DEFINE_OP(fstl,  FSTLm);
                   4048: DEFINE_OP(fstpl, FSTPLm);
                   4049: DEFINE_OP(fldl,  FLDLm);
                   4050: DEFINE_OP(fildl, FILDLm);
                   4051: DEFINE_OP(fistl, FISTLm);
                   4052: DEFINE_OP(flds,  FLDSm);
                   4053: DEFINE_OP(fsts,  FSTSm);
                   4054: DEFINE_OP(fstpt, FSTPTm);
                   4055: DEFINE_OP(fldt,  FLDTm);
1.1.1.2 ! root     4056: DEFINE_OP(fistpl, FISTPLm);
1.1       root     4057: #else
                   4058: #define DEFINE_OP(NAME, OP1, OP2)              \
                   4059: static inline void raw_##NAME(uint32 m)                \
                   4060: {                                              \
                   4061:     emit_byte(OP1);                            \
                   4062:     emit_byte(OP2);                            \
                   4063:     emit_long(m);                              \
                   4064: }
                   4065: DEFINE_OP(fstl,  0xdd, 0x15);
                   4066: DEFINE_OP(fstpl, 0xdd, 0x1d);
                   4067: DEFINE_OP(fldl,  0xdd, 0x05);
                   4068: DEFINE_OP(fildl, 0xdb, 0x05);
                   4069: DEFINE_OP(fistl, 0xdb, 0x15);
                   4070: DEFINE_OP(flds,  0xd9, 0x05);
                   4071: DEFINE_OP(fsts,  0xd9, 0x15);
                   4072: DEFINE_OP(fstpt, 0xdb, 0x3d);
                   4073: DEFINE_OP(fldt,  0xdb, 0x2d);
1.1.1.2 ! root     4074: DEFINE_OP(fistpl, 0xdb, 0x1d);
1.1       root     4075: #endif
                   4076: #undef DEFINE_OP
                   4077: 
                   4078: LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
                   4079: {
1.1.1.2 ! root     4080:        make_tos(r);
        !          4081:        raw_fstl(m);
1.1       root     4082: }
                   4083: LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
                   4084: 
                   4085: LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r))
                   4086: {
1.1.1.2 ! root     4087:        make_tos(r);
        !          4088:        raw_fstpl(m);
        !          4089:        live.onstack[live.tos]=-1;
        !          4090:        live.tos--;
        !          4091:        live.spos[r]=-2;
1.1       root     4092: }
                   4093: LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
                   4094: 
                   4095: LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
                   4096: {
1.1.1.2 ! root     4097:        raw_fldl(m);
        !          4098:        tos_make(r);
1.1       root     4099: }
                   4100: LENDFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
                   4101: 
                   4102: LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
                   4103: {
1.1.1.2 ! root     4104:        raw_fildl(m);
        !          4105:        tos_make(r);
1.1       root     4106: }
                   4107: LENDFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
                   4108: 
                   4109: LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
                   4110: {
1.1.1.2 ! root     4111:        make_tos(r);
        !          4112:        raw_fistl(m);
1.1       root     4113: }
                   4114: LENDFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
                   4115: 
1.1.1.2 ! root     4116: LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds))
        !          4117: {
        !          4118:        /* Clamp value to the given range and convert to integer. */
        !          4119: 
        !          4120:        int rs;
        !          4121:        usereg(r);
        !          4122:        rs = stackpos(r)+1;
        !          4123: 
        !          4124:        /* Lower bound onto stack */
        !          4125:        raw_fldl((uintptr) &bounds[0]); /* fld double from lower */
        !          4126: 
        !          4127:        /* Clamp to lower */
        !          4128:        emit_byte(0xdb);
        !          4129:        emit_byte(0xf0+rs); /* fcomi lower,r */
        !          4130:        emit_byte(0x73);
        !          4131:        emit_byte(12);      /* jae to writeback */
        !          4132: 
        !          4133:        /* Upper bound onto stack */
        !          4134:        emit_byte(0xdd);
        !          4135:        emit_byte(0xd8);        /* fstp st(0) */
        !          4136:        raw_fldl((uintptr) &bounds[1]); /* fld double from upper */
        !          4137: 
        !          4138:        /* Clamp to upper */
        !          4139:        emit_byte(0xdb);
        !          4140:        emit_byte(0xf0+rs); /* fcomi upper,r */
        !          4141:        emit_byte(0xdb);
        !          4142:        emit_byte(0xd0+rs); /* fcmovnbe upper,r */
        !          4143: 
        !          4144:        /* Store to destination */
        !          4145:        raw_fistpl(m);
        !          4146: }
        !          4147: LENDFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds))
        !          4148: 
1.1       root     4149: LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
                   4150: {
1.1.1.2 ! root     4151:        raw_flds(m);
        !          4152:        tos_make(r);
1.1       root     4153: }
                   4154: LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
                   4155: 
                   4156: LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
                   4157: {
1.1.1.2 ! root     4158:        make_tos(r);
        !          4159:        raw_fsts(m);
1.1       root     4160: }
                   4161: LENDFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
                   4162: 
                   4163: LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
                   4164: {
1.1.1.2 ! root     4165:        int rs;
1.1       root     4166: 
1.1.1.2 ! root     4167:        /* Stupid x87 can't write a long double to mem without popping the
        !          4168:        stack! */
        !          4169:        usereg(r);
        !          4170:        rs=stackpos(r);
        !          4171:        emit_byte(0xd9);     /* Get a copy to the top of stack */
        !          4172:        emit_byte(0xc0+rs);
1.1       root     4173: 
1.1.1.2 ! root     4174:        raw_fstpt(m);   /* store and pop it */
1.1       root     4175: }
                   4176: LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
                   4177: 
                   4178: LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r))
                   4179: {
1.1.1.2 ! root     4180:        make_tos(r);
        !          4181:        raw_fstpt(m);   /* store and pop it */
        !          4182:        live.onstack[live.tos]=-1;
        !          4183:        live.tos--;
        !          4184:        live.spos[r]=-2;
1.1       root     4185: }
                   4186: LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
                   4187: 
                   4188: LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
                   4189: {
1.1.1.2 ! root     4190:        raw_fldt(m);
        !          4191:        tos_make(r);
1.1       root     4192: }
                   4193: LENDFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
                   4194: 
                   4195: LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
                   4196: {
1.1.1.2 ! root     4197:        emit_byte(0xd9);
        !          4198:        emit_byte(0xeb);
        !          4199:        tos_make(r);
1.1       root     4200: }
                   4201: LENDFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
                   4202: 
                   4203: LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
                   4204: {
1.1.1.2 ! root     4205:        emit_byte(0xd9);
        !          4206:        emit_byte(0xec);
        !          4207:        tos_make(r);
1.1       root     4208: }
                   4209: LENDFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
                   4210: 
                   4211: LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
                   4212: {
1.1.1.2 ! root     4213:        emit_byte(0xd9);
        !          4214:        emit_byte(0xea);
        !          4215:        tos_make(r);
1.1       root     4216: }
                   4217: LENDFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
                   4218: 
                   4219: LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
                   4220: {
1.1.1.2 ! root     4221:        emit_byte(0xd9);
        !          4222:        emit_byte(0xed);
        !          4223:        tos_make(r);
1.1       root     4224: }
                   4225: LENDFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
                   4226: 
                   4227: LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
                   4228: {
1.1.1.2 ! root     4229:        emit_byte(0xd9);
        !          4230:        emit_byte(0xe8);
        !          4231:        tos_make(r);
1.1       root     4232: }
                   4233: LENDFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
                   4234: 
                   4235: LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
                   4236: {
1.1.1.2 ! root     4237:        emit_byte(0xd9);
        !          4238:        emit_byte(0xee);
        !          4239:        tos_make(r);
1.1       root     4240: }
                   4241: LENDFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
                   4242: 
                   4243: LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
                   4244: {
1.1.1.2 ! root     4245:        int ds;
1.1       root     4246: 
1.1.1.2 ! root     4247:        usereg(s);
        !          4248:        ds=stackpos(s);
        !          4249:        if (ds==0 && live.spos[d]>=0) {
        !          4250:                /* source is on top of stack, and we already have the dest */
        !          4251:                int dd=stackpos(d);
        !          4252:                emit_byte(0xdd);
        !          4253:                emit_byte(0xd0+dd);
        !          4254:        }
        !          4255:        else {
        !          4256:                emit_byte(0xd9);
        !          4257:                emit_byte(0xc0+ds); /* duplicate source on tos */
        !          4258:                tos_make(d); /* store to destination, pop if necessary */
        !          4259:        }
1.1       root     4260: }
                   4261: LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
                   4262: 
1.1.1.2 ! root     4263: LOWFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base))
1.1       root     4264: {
1.1.1.2 ! root     4265:        x86_64_prefix(true, false, NULL, NULL, &index);
        !          4266:        emit_byte(0xd9);
        !          4267:        emit_byte(0xa8 + index);
        !          4268:        emit_long(base);
1.1       root     4269: }
1.1.1.2 ! root     4270: LENDFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base))
1.1       root     4271: 
                   4272: LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
                   4273: {
1.1.1.2 ! root     4274:        int ds;
1.1       root     4275: 
1.1.1.2 ! root     4276:        if (d!=s) {
        !          4277:                usereg(s);
        !          4278:                ds=stackpos(s);
        !          4279:                emit_byte(0xd9);
        !          4280:                emit_byte(0xc0+ds); /* duplicate source */
        !          4281:                emit_byte(0xd9);
        !          4282:                emit_byte(0xfa); /* take square root */
        !          4283:                tos_make(d);        /* store to destination */
        !          4284:        }
        !          4285:        else {
        !          4286:                make_tos(d);
        !          4287:                emit_byte(0xd9);
        !          4288:                emit_byte(0xfa);    /* take square root */
        !          4289:        }
1.1       root     4290: }
                   4291: LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
                   4292: 
                   4293: LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
                   4294: {
1.1.1.2 ! root     4295:        int ds;
1.1       root     4296: 
1.1.1.2 ! root     4297:        if (d!=s) {
        !          4298:                usereg(s);
        !          4299:                ds=stackpos(s);
        !          4300:                emit_byte(0xd9);
        !          4301:                emit_byte(0xc0+ds); /* duplicate source */
        !          4302:                emit_byte(0xd9);
        !          4303:                emit_byte(0xe1); /* take fabs */
        !          4304:                tos_make(d);        /* store to destination */
        !          4305:        }
        !          4306:        else {
        !          4307:                make_tos(d);
        !          4308:                emit_byte(0xd9);
        !          4309:                emit_byte(0xe1); /* take fabs */
        !          4310:        }
1.1       root     4311: }
                   4312: LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
                   4313: 
                   4314: LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
                   4315: {
1.1.1.2 ! root     4316:        int ds;
1.1       root     4317: 
1.1.1.2 ! root     4318:        if (d!=s) {
        !          4319:                usereg(s);
        !          4320:                ds=stackpos(s);
        !          4321:                emit_byte(0xd9);
        !          4322:                emit_byte(0xc0+ds); /* duplicate source */
        !          4323:                emit_byte(0xd9);
        !          4324:                emit_byte(0xfc); /* take frndint */
        !          4325:                tos_make(d);        /* store to destination */
        !          4326:        }
        !          4327:        else {
        !          4328:                make_tos(d);
        !          4329:                emit_byte(0xd9);
        !          4330:                emit_byte(0xfc); /* take frndint */
        !          4331:        }
1.1       root     4332: }
                   4333: LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
                   4334: 
                   4335: LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
                   4336: {
1.1.1.2 ! root     4337:        int ds;
1.1       root     4338: 
1.1.1.2 ! root     4339:        if (d!=s) {
        !          4340:                usereg(s);
        !          4341:                ds=stackpos(s);
        !          4342:                emit_byte(0xd9);
        !          4343:                emit_byte(0xc0+ds); /* duplicate source */
        !          4344:                emit_byte(0xd9);
        !          4345:                emit_byte(0xff);    /* take cos */
        !          4346:                tos_make(d);        /* store to destination */
        !          4347:        }
        !          4348:        else {
        !          4349:                make_tos(d);
        !          4350:                emit_byte(0xd9);
        !          4351:                emit_byte(0xff);    /* take cos */
        !          4352:        }
1.1       root     4353: }
                   4354: LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
                   4355: 
                   4356: LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
                   4357: {
1.1.1.2 ! root     4358:        int ds;
1.1       root     4359: 
1.1.1.2 ! root     4360:        if (d!=s) {
        !          4361:                ds=stackpos(s);
        !          4362:                emit_byte(0xd9);
        !          4363:                emit_byte(0xc0+ds); /* fld x */
        !          4364:                emit_byte(0xd9);
        !          4365:                emit_byte(0xfe);    /* fsin sin(x) */
        !          4366:                tos_make(d);        /* store to destination */
        !          4367:        }
        !          4368:        else {
        !          4369:                make_tos(d);
        !          4370:                emit_byte(0xd9);
        !          4371:                emit_byte(0xfe);    /* fsin y=sin(x) */
        !          4372:        }
1.1       root     4373: }
                   4374: LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
                   4375: 
1.1.1.2 ! root     4376: static const double one = 1;
        !          4377: 
1.1       root     4378: LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
                   4379: {
1.1.1.2 ! root     4380:        int ds;
1.1       root     4381: 
1.1.1.2 ! root     4382:        ds=stackpos(s);
        !          4383:        emit_byte(0xd9);
        !          4384:        emit_byte(0xc0+ds); /* fld x */
        !          4385:        emit_byte(0xd9);
        !          4386:        emit_byte(0xfc);    /* frndint int(x) */
        !          4387:        emit_byte(0xd9);
        !          4388:        emit_byte(0xc1+ds); /* fld x again */
        !          4389:        emit_byte(0xd8);
        !          4390:        emit_byte(0xe1);    /* fsub frac(x) = x - int(x) */
        !          4391:        emit_byte(0xd9);
        !          4392:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
        !          4393:        x86_fadd_m((uintptr) &one); /* Add '1' without using extra stack space */
        !          4394:        emit_byte(0xd9);
        !          4395:        emit_byte(0xfd);    /* fscale (2^frac(x))*2^int(x) */
        !          4396:        emit_byte(0xdd);
        !          4397:        emit_byte(0xd9);    /* fstp copy & pop */
        !          4398:        tos_make(d);        /* store y=2^x */
1.1       root     4399: }
                   4400: LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
                   4401: 
                   4402: LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
                   4403: {
1.1.1.2 ! root     4404:        int ds;
1.1       root     4405: 
1.1.1.2 ! root     4406:        if (s==d)
        !          4407:                make_tos(s);
        !          4408:        else {
        !          4409:                ds=stackpos(s);
        !          4410:                emit_byte(0xd9);
        !          4411:                emit_byte(0xc0+ds); /* duplicate source */
        !          4412:        }
        !          4413:        emit_byte(0xd9);
        !          4414:        emit_byte(0xea);    /* fldl2e log2(e) */
        !          4415:        emit_byte(0xd8);
        !          4416:        emit_byte(0xc9);    /* fmul x*log2(e) */
        !          4417:        emit_byte(0xdd);
        !          4418:        emit_byte(0xd1);    /* fst copy up */
        !          4419:        emit_byte(0xd9);
        !          4420:        emit_byte(0xfc);    /* frndint int(x*log2(e)) */
        !          4421:        emit_byte(0xd9);
        !          4422:        emit_byte(0xc9);    /* fxch swap top two elements */
        !          4423:        emit_byte(0xd8);
        !          4424:        emit_byte(0xe1);    /* fsub x*log2(e) - int(x*log2(e))  */
        !          4425:        emit_byte(0xd9);
        !          4426:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
        !          4427:        x86_fadd_m((uintptr) &one); /* Add '1' without using extra stack space */
        !          4428:        emit_byte(0xd9);
        !          4429:        emit_byte(0xfd);    /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          4430:        emit_byte(0xdd);
        !          4431:        emit_byte(0xd9);    /* fstp copy & pop */
        !          4432:        if (s!=d)
        !          4433:                tos_make(d);    /* store y=e^x */
1.1       root     4434: }
                   4435: LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
1.1.1.2 ! root     4436: 
1.1       root     4437: LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
                   4438: {
1.1.1.2 ! root     4439:        int ds;
1.1       root     4440: 
1.1.1.2 ! root     4441:        if (s==d)
        !          4442:                make_tos(s);
        !          4443:        else {
        !          4444:                ds=stackpos(s);
        !          4445:                emit_byte(0xd9);
        !          4446:                emit_byte(0xc0+ds); /* duplicate source */
        !          4447:        }
        !          4448:        emit_byte(0xd9);
        !          4449:        emit_byte(0xe8);    /* push '1' */
        !          4450:        emit_byte(0xd9);
        !          4451:        emit_byte(0xc9);    /* swap top two */
        !          4452:        emit_byte(0xd9);
        !          4453:        emit_byte(0xf1);    /* take 1*log2(x) */
        !          4454:        if (s!=d)
        !          4455:                tos_make(d);    /* store to destination */
1.1       root     4456: }
                   4457: LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
                   4458: 
                   4459: 
                   4460: LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
                   4461: {
1.1.1.2 ! root     4462:        int ds;
1.1       root     4463: 
1.1.1.2 ! root     4464:        if (d!=s) {
        !          4465:                usereg(s);
        !          4466:                ds=stackpos(s);
        !          4467:                emit_byte(0xd9);
        !          4468:                emit_byte(0xc0+ds); /* duplicate source */
        !          4469:                emit_byte(0xd9);
        !          4470:                emit_byte(0xe0); /* take fchs */
        !          4471:                tos_make(d); /* store to destination */
        !          4472:        }
        !          4473:        else {
        !          4474:                make_tos(d);
        !          4475:                emit_byte(0xd9);
        !          4476:                emit_byte(0xe0); /* take fchs */
        !          4477:        }
1.1       root     4478: }
                   4479: LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
                   4480: 
                   4481: LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
                   4482: {
1.1.1.2 ! root     4483:        int ds;
1.1       root     4484: 
1.1.1.2 ! root     4485:        usereg(s);
        !          4486:        usereg(d);
        !          4487: 
        !          4488:        if (live.spos[s]==live.tos) {
        !          4489:                /* Source is on top of stack */
        !          4490:                ds=stackpos(d);
        !          4491:                emit_byte(0xdc);
        !          4492:                emit_byte(0xc0+ds); /* add source to dest*/
        !          4493:        }
        !          4494:        else {
        !          4495:                make_tos(d);
        !          4496:                ds=stackpos(s);
        !          4497: 
        !          4498:                emit_byte(0xd8);
        !          4499:                emit_byte(0xc0+ds); /* add source to dest*/
        !          4500:        }
1.1       root     4501: }
                   4502: LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
                   4503: 
                   4504: LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
                   4505: {
1.1.1.2 ! root     4506:        int ds;
1.1       root     4507: 
1.1.1.2 ! root     4508:        usereg(s);
        !          4509:        usereg(d);
        !          4510: 
        !          4511:        if (live.spos[s]==live.tos) {
        !          4512:                /* Source is on top of stack */
        !          4513:                ds=stackpos(d);
        !          4514:                emit_byte(0xdc);
        !          4515:                emit_byte(0xe8+ds); /* sub source from dest*/
        !          4516:        }
        !          4517:        else {
        !          4518:                make_tos(d);
        !          4519:                ds=stackpos(s);
        !          4520: 
        !          4521:                emit_byte(0xd8);
        !          4522:                emit_byte(0xe0+ds); /* sub src from dest */
        !          4523:        }
1.1       root     4524: }
                   4525: LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
                   4526: 
                   4527: LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
                   4528: {
1.1.1.2 ! root     4529:        int ds;
1.1       root     4530: 
1.1.1.2 ! root     4531:        usereg(s);
        !          4532:        usereg(d);
        !          4533: 
        !          4534:        make_tos(d);
        !          4535:        ds=stackpos(s);
1.1       root     4536: 
1.1.1.2 ! root     4537:        emit_byte(0xdd);
        !          4538:        emit_byte(0xe0+ds); /* cmp dest with source*/
1.1       root     4539: }
                   4540: LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
                   4541: 
                   4542: LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
                   4543: {
1.1.1.2 ! root     4544:        int ds;
1.1       root     4545: 
1.1.1.2 ! root     4546:        usereg(s);
        !          4547:        usereg(d);
        !          4548: 
        !          4549:        if (live.spos[s]==live.tos) {
        !          4550:                /* Source is on top of stack */
        !          4551:                ds=stackpos(d);
        !          4552:                emit_byte(0xdc);
        !          4553:                emit_byte(0xc8+ds); /* mul dest by source*/
        !          4554:        }
        !          4555:        else {
        !          4556:                make_tos(d);
        !          4557:                ds=stackpos(s);
        !          4558: 
        !          4559:                emit_byte(0xd8);
        !          4560:                emit_byte(0xc8+ds); /* mul dest by source*/
        !          4561:        }
1.1       root     4562: }
                   4563: LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
                   4564: 
                   4565: LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
                   4566: {
1.1.1.2 ! root     4567:        int ds;
1.1       root     4568: 
1.1.1.2 ! root     4569:        usereg(s);
        !          4570:        usereg(d);
        !          4571: 
        !          4572:        if (live.spos[s]==live.tos) {
        !          4573:                /* Source is on top of stack */
        !          4574:                ds=stackpos(d);
        !          4575:                emit_byte(0xdc);
        !          4576:                emit_byte(0xf8+ds); /* div dest by source */
        !          4577:        }
        !          4578:        else {
        !          4579:                make_tos(d);
        !          4580:                ds=stackpos(s);
        !          4581: 
        !          4582:                emit_byte(0xd8);
        !          4583:                emit_byte(0xf0+ds); /* div dest by source*/
        !          4584:        }
1.1       root     4585: }
                   4586: LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
                   4587: 
                   4588: LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
                   4589: {
1.1.1.2 ! root     4590:        int ds;
1.1       root     4591: 
1.1.1.2 ! root     4592:        usereg(s);
        !          4593:        usereg(d);
1.1       root     4594: 
1.1.1.2 ! root     4595:        make_tos2(d,s);
        !          4596:        ds=stackpos(s);
        !          4597: 
        !          4598:        if (ds!=1) {
        !          4599:                printf("Failed horribly in raw_frem_rr! ds is %d\n",ds);
        !          4600:                abort();
        !          4601:        }
        !          4602:        emit_byte(0xd9);
        !          4603:        emit_byte(0xf8); /* take rem from dest by source */
1.1       root     4604: }
                   4605: LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
                   4606: 
                   4607: LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
                   4608: {
1.1.1.2 ! root     4609:        int ds;
1.1       root     4610: 
1.1.1.2 ! root     4611:        usereg(s);
        !          4612:        usereg(d);
1.1       root     4613: 
1.1.1.2 ! root     4614:        make_tos2(d,s);
        !          4615:        ds=stackpos(s);
        !          4616: 
        !          4617:        if (ds!=1) {
        !          4618:                printf("Failed horribly in raw_frem1_rr! ds is %d\n",ds);
        !          4619:                abort();
        !          4620:        }
        !          4621:        emit_byte(0xd9);
        !          4622:        emit_byte(0xf5); /* take rem1 from dest by source */
1.1       root     4623: }
                   4624: LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
                   4625: 
                   4626: 
                   4627: LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
                   4628: {
1.1.1.2 ! root     4629:        make_tos(r);
        !          4630:        emit_byte(0xd9);  /* ftst */
        !          4631:        emit_byte(0xe4);
1.1       root     4632: }
                   4633: LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
                   4634: 
1.1.1.2 ! root     4635: LOWFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s))
        !          4636: {
        !          4637:        int ds;
        !          4638: 
        !          4639:        if (s==d)
        !          4640:                make_tos(s);
        !          4641:        else {
        !          4642:                ds=stackpos(s);
        !          4643:                emit_byte(0xd9);
        !          4644:                emit_byte(0xc0+ds); /* fld x */
        !          4645:        }
        !          4646:        emit_byte(0xd9);
        !          4647:        emit_byte(0xea);    /* fldl2e log2(e) */
        !          4648:        emit_byte(0xd8);
        !          4649:        emit_byte(0xc9);    /* fmul x*log2(e) */
        !          4650:        emit_byte(0xdd);
        !          4651:        emit_byte(0xd1);    /* fst copy up */
        !          4652:        emit_byte(0xd9);
        !          4653:        emit_byte(0xfc);    /* frndint int(x*log2(e)) */
        !          4654:        emit_byte(0xd9);
        !          4655:        emit_byte(0xc9);    /* fxch swap top two elements */
        !          4656:        emit_byte(0xd8);
        !          4657:        emit_byte(0xe1);    /* fsub x*log2(e) - int(x*log2(e))  */
        !          4658:        emit_byte(0xd9);
        !          4659:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
        !          4660:        emit_byte(0xd9);
        !          4661:        emit_byte(0xfd);    /* fscale ((2^frac(x))-1)*2^int(x*log2(e)) */
        !          4662:        emit_byte(0xdd);
        !          4663:        emit_byte(0xd9);    /* fstp copy & pop */
        !          4664:        if (s!=d)
        !          4665:                tos_make(d);    /* store y=(e^x)-1 */
        !          4666: }
        !          4667: LENDFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s))
        !          4668: 
        !          4669: LOWFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s))
        !          4670: {
        !          4671:        int ds;
        !          4672: 
        !          4673:        if (s==d)
        !          4674:                make_tos(s);
        !          4675:        else {
        !          4676:                ds=stackpos(s);
        !          4677:                emit_byte(0xd9);
        !          4678:                emit_byte(0xc0+ds); /* fld x */
        !          4679:        }
        !          4680:        emit_byte(0xd9);
        !          4681:        emit_byte(0xe9);    /* fldl2t log2(10) */
        !          4682:        emit_byte(0xd8);
        !          4683:        emit_byte(0xc9);    /* fmul x*log2(10) */
        !          4684:        emit_byte(0xdd);
        !          4685:        emit_byte(0xd1);    /* fst copy up */
        !          4686:        emit_byte(0xd9);
        !          4687:        emit_byte(0xfc);    /* frndint int(x*log2(10)) */
        !          4688:        emit_byte(0xd9);
        !          4689:        emit_byte(0xc9);    /* fxch swap top two elements */
        !          4690:        emit_byte(0xd8);
        !          4691:        emit_byte(0xe1);    /* fsub x*log2(10) - int(x*log2(10))  */
        !          4692:        emit_byte(0xd9);
        !          4693:        emit_byte(0xf0);    /* f2xm1 (2^frac(x))-1 */
        !          4694:        x86_fadd_m((uintptr) &one);
        !          4695:        emit_byte(0xd9);
        !          4696:        emit_byte(0xfd);    /* fscale (2^frac(x))*2^int(x*log2(10)) */
        !          4697:        emit_byte(0xdd);
        !          4698:        emit_byte(0xd9);    /* fstp copy & pop */
        !          4699:        if (s!=d)
        !          4700:                tos_make(d);    /* store y=10^x */
        !          4701: }
        !          4702: LENDFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s))
        !          4703: 
        !          4704: LOWFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s))
        !          4705: {
        !          4706:        int ds;
        !          4707: 
        !          4708:        if (s==d) {
        !          4709:                //write_log (_T("FSINCOS src = dest\n"));
        !          4710:                make_tos(s);
        !          4711:                emit_byte(0xd9);
        !          4712:                emit_byte(0xfb); /* fsincos sin(x) push cos(x) */
        !          4713:                tos_make(c);     /* store cos(x) to c */
        !          4714:                return;
        !          4715:        }
        !          4716: 
        !          4717:        ds=stackpos(s);
        !          4718:        emit_byte(0xd9);
        !          4719:        emit_byte(0xc0+ds);  /* fld x */
        !          4720:        emit_byte(0xd9);
        !          4721:        emit_byte(0xfb);     /* fsincos sin(x) push cos(x) */
        !          4722:        if (live.spos[c]<0) {
        !          4723:                if (live.spos[d]<0) { /* occupy both regs directly */
        !          4724:                        live.tos++;
        !          4725:                        live.spos[d]=live.tos;
        !          4726:                        live.onstack[live.tos]=d; /* sin(x) comes first */
        !          4727:                        live.tos++;
        !          4728:                        live.spos[c]=live.tos;
        !          4729:                        live.onstack[live.tos]=c;
        !          4730:                }
        !          4731:                else {
        !          4732:                        emit_byte(0xd9);
        !          4733:                        emit_byte(0xc9); /* fxch swap cos(x) with sin(x) */
        !          4734:                        emit_byte(0xdd); /* store sin(x) to d & pop */
        !          4735:                        emit_byte(0xd8+(live.tos+2)-live.spos[d]);
        !          4736:                        live.tos++;      /* occupy a reg for cos(x) here */
        !          4737:                        live.spos[c]=live.tos;
        !          4738:                        live.onstack[live.tos]=c;
        !          4739:                }
        !          4740:        }
        !          4741:        else {
        !          4742:                emit_byte(0xdd); /* store cos(x) to c & pop */
        !          4743:                emit_byte(0xd8+(live.tos+2)-live.spos[c]);
        !          4744:                tos_make(d);     /* store sin(x) to destination */
        !          4745:        }
        !          4746: }
        !          4747: LENDFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s))
        !          4748: 
        !          4749: LOWFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s))
        !          4750: {
        !          4751:        int ds;
        !          4752: 
        !          4753:        if (live.spos[d]==live.tos && live.spos[s]==live.tos-1) {
        !          4754:                //write_log (_T("fscale found x in TOS-1 and y in TOS\n"));
        !          4755:                emit_byte(0xd9);
        !          4756:                emit_byte(0xfd);    /* fscale y*(2^x) */
        !          4757:        }
        !          4758:        else {
        !          4759:                make_tos(s);        /* tos=x */
        !          4760:                ds=stackpos(d);
        !          4761:                emit_byte(0xd9);
        !          4762:                emit_byte(0xc0+ds); /* fld y */
        !          4763:                emit_byte(0xd9);
        !          4764:                emit_byte(0xfd);    /* fscale y*(2^x) */
        !          4765:                tos_make(d);        /* store y=y*(2^x) */
        !          4766:        }
        !          4767: }
        !          4768: LENDFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s))
        !          4769: 
        !          4770: LOWFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s))
        !          4771: {
        !          4772:        int ds;
        !          4773: 
        !          4774:        if (d!=s) {
        !          4775:                ds=stackpos(s);
        !          4776:                emit_byte(0xd9);
        !          4777:                emit_byte(0xc0+ds); /* fld x */
        !          4778:                emit_byte(0xd9);
        !          4779:                emit_byte(0xf2);    /* fptan tan(x)=y/1.0 */
        !          4780:                emit_byte(0xdd);
        !          4781:                emit_byte(0xd8);    /* fstp pop 1.0 */
        !          4782:                tos_make(d);        /* store to destination */
        !          4783:        }
        !          4784:        else {
        !          4785:                make_tos(d);
        !          4786:                emit_byte(0xd9);
        !          4787:                emit_byte(0xf2);    /* fptan tan(x)=y/1.0 */
        !          4788:                emit_byte(0xdd);
        !          4789:                emit_byte(0xd8);    /* fstp pop 1.0 */
        !          4790:        }
        !          4791: }
        !          4792: LENDFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s))
        !          4793: 
        !          4794: #ifdef CPU_x86_64
        !          4795: #define REX64() emit_byte(0x48)
        !          4796: #else
        !          4797: #define REX64()
        !          4798: #endif
        !          4799: 
        !          4800: LOWFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
        !          4801: {
        !          4802:        make_tos(r);     /* TOS = r */
        !          4803:        REX64();
        !          4804:        emit_byte(0x83);
        !          4805:        emit_byte(0xc4);
        !          4806:        emit_byte(0xfc); /* add -4 to esp */
        !          4807:        emit_byte(0xd9);
        !          4808:        emit_byte(0x1c);
        !          4809:        emit_byte(0x24); /* fstp store r as SINGLE to [esp] and pop */
        !          4810:        emit_byte(0xd9);
        !          4811:        emit_byte(0x04);
        !          4812:        emit_byte(0x24); /* fld load r as SINGLE from [esp] */
        !          4813:        emit_byte(0x9b); /* let the CPU wait on FPU exceptions */
        !          4814:        REX64();
        !          4815:        emit_byte(0x83);
        !          4816:        emit_byte(0xc4);
        !          4817:        emit_byte(0x04); /* add +4 to esp */
        !          4818: }
        !          4819: LENDFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
        !          4820: 
        !          4821: LOWFUNC(NONE,NONE,1,raw_fcut_r,(FRW r))
        !          4822: {
        !          4823:        make_tos(r);     /* TOS = r */
        !          4824:        REX64();
        !          4825:        emit_byte(0x83);
        !          4826:        emit_byte(0xc4);
        !          4827:        emit_byte(0xf8); /* add -8 to esp */
        !          4828:        emit_byte(0xdd);
        !          4829:        emit_byte(0x1c);
        !          4830:        emit_byte(0x24); /* fstp store r as DOUBLE to [esp] and pop */
        !          4831:        emit_byte(0xdd);
        !          4832:        emit_byte(0x04);
        !          4833:        emit_byte(0x24); /* fld load r as DOUBLE from [esp] */
        !          4834:        emit_byte(0x9b); /* let the CPU wait on FPU exceptions */
        !          4835:        REX64();
        !          4836:        emit_byte(0x83);
        !          4837:        emit_byte(0xc4);
        !          4838:        emit_byte(0x08); /* add +8 to esp */
        !          4839: }
        !          4840: LENDFUNC(NONE,NONE,1,raw_fcut_r,(FRW r))
        !          4841: 
        !          4842: LOWFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s))
        !          4843: {
        !          4844:        int ds;
        !          4845: 
        !          4846:        if (d!=s) {
        !          4847:                ds=stackpos(s);
        !          4848:                emit_byte(0xd9);
        !          4849:                emit_byte(0xc0+ds); /* fld x */
        !          4850:                emit_byte(0xd9);
        !          4851:                emit_byte(0xf4);    /* fxtract exp push man */
        !          4852:                emit_byte(0xdd);
        !          4853:                emit_byte(0xd8);    /* fstp just pop man */
        !          4854:                tos_make(d);        /* store exp to destination */
        !          4855:        }
        !          4856:        else {
        !          4857:                make_tos(d);        /* tos=x=y */
        !          4858:                emit_byte(0xd9);
        !          4859:                emit_byte(0xf4);    /* fxtract exp push man */
        !          4860:                emit_byte(0xdd);
        !          4861:                emit_byte(0xd8);    /* fstp just pop man */
        !          4862:        }
        !          4863: }
        !          4864: LENDFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s))
        !          4865: 
        !          4866: LOWFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s))
        !          4867: {
        !          4868:        int ds;
        !          4869: 
        !          4870:        if (d!=s) {
        !          4871:                ds=stackpos(s);
        !          4872:                emit_byte(0xd9);
        !          4873:                emit_byte(0xc0+ds); /* fld x */
        !          4874:                emit_byte(0xd9);
        !          4875:                emit_byte(0xf4);    /* fxtract exp push man */
        !          4876:                emit_byte(0xdd);
        !          4877:                emit_byte(0xd9);    /* fstp copy man up & pop */
        !          4878:                tos_make(d);        /* store man to destination */
        !          4879:        }
        !          4880:        else {
        !          4881:                make_tos(d);        /* tos=x=y */
        !          4882:                emit_byte(0xd9);
        !          4883:                emit_byte(0xf4);    /* fxtract exp push man */
        !          4884:                emit_byte(0xdd);
        !          4885:                emit_byte(0xd9);    /* fstp copy man up & pop */
        !          4886:        }
        !          4887: }
        !          4888: LENDFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s))
        !          4889: 
        !          4890: LOWFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s))
        !          4891: {
        !          4892:        int ds;
        !          4893: 
        !          4894:        if (s==d)
        !          4895:                make_tos(s);
        !          4896:        else {
        !          4897:                ds=stackpos(s);
        !          4898:                emit_byte(0xd9);
        !          4899:                emit_byte(0xc0+ds); /* fld x */
        !          4900:        }
        !          4901:        emit_byte(0xd9);
        !          4902:        emit_byte(0xed);    /* fldln2 logN(2) */
        !          4903:        emit_byte(0xd9);
        !          4904:        emit_byte(0xc9);    /* fxch swap logN(2) with x */
        !          4905:        emit_byte(0xd9);
        !          4906:        emit_byte(0xf1);    /* fyl2x logN(2)*log2(x) */
        !          4907:        if (s!=d)
        !          4908:                tos_make(d);    /* store y=logN(x) */
        !          4909: }
        !          4910: LENDFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s))
        !          4911: 
        !          4912: LOWFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s))
        !          4913: {
        !          4914:        int ds;
        !          4915: 
        !          4916:        if (s==d)
        !          4917:                make_tos(s);
        !          4918:        else {
        !          4919:                ds=stackpos(s);
        !          4920:                emit_byte(0xd9);
        !          4921:                emit_byte(0xc0+ds); /* fld x */
        !          4922:        }
        !          4923:        emit_byte(0xd9);
        !          4924:        emit_byte(0xed);    /* fldln2 logN(2) */
        !          4925:        emit_byte(0xd9);
        !          4926:        emit_byte(0xc9);    /* fxch swap logN(2) with x */
        !          4927:        emit_byte(0xd9);
        !          4928:        emit_byte(0xf9);    /* fyl2xp1 logN(2)*log2(x+1) */
        !          4929:        if (s!=d)
        !          4930:                tos_make(d);    /* store y=logN(x+1) */
        !          4931: }
        !          4932: LENDFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s))
        !          4933: 
        !          4934: LOWFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s))
        !          4935: {
        !          4936:        int ds;
        !          4937: 
        !          4938:        if (s==d)
        !          4939:                make_tos(s);
        !          4940:        else {
        !          4941:                ds=stackpos(s);
        !          4942:                emit_byte(0xd9);
        !          4943:                emit_byte(0xc0+ds); /* fld x */
        !          4944:        }
        !          4945:        emit_byte(0xd9);
        !          4946:        emit_byte(0xec);    /* fldlg2 log10(2) */
        !          4947:        emit_byte(0xd9);
        !          4948:        emit_byte(0xc9);    /* fxch swap log10(2) with x */
        !          4949:        emit_byte(0xd9);
        !          4950:        emit_byte(0xf1);    /* fyl2x log10(2)*log2(x) */
        !          4951:        if (s!=d)
        !          4952:                tos_make(d);    /* store y=log10(x) */
        !          4953: }
        !          4954: LENDFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s))
        !          4955: 
        !          4956: LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s))
        !          4957: {
        !          4958:        int ds;
        !          4959: 
        !          4960:        ds=stackpos(s);
        !          4961:        emit_byte(0xd9);
        !          4962:        emit_byte(0xc0+ds); /* fld x */
        !          4963:        emit_byte(0xd8);
        !          4964:        emit_byte(0xc8);    /* fmul x*x */
        !          4965:        emit_byte(0xd9);
        !          4966:        emit_byte(0xe8);    /* fld 1.0 */
        !          4967:        emit_byte(0xde);
        !          4968:        emit_byte(0xe1);    /* fsubrp 1 - (x^2) */
        !          4969:        emit_byte(0xd9);
        !          4970:        emit_byte(0xfa);    /* fsqrt sqrt(1-(x^2)) */
        !          4971:        emit_byte(0xd9);
        !          4972:        emit_byte(0xc1+ds); /* fld x again */
        !          4973:        emit_byte(0xd9);
        !          4974:        emit_byte(0xc9);    /* fxch swap x with sqrt(1-(x^2))  */
        !          4975:        emit_byte(0xd9);
        !          4976:        emit_byte(0xf3);    /* fpatan atan(x/sqrt(1-(x^2))) & pop */
        !          4977:        tos_make(d);        /* store y=asin(x) */
        !          4978: }
        !          4979: LENDFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s))
        !          4980: 
        !          4981: static uae_u32 pihalf[] = {0x2168c234, 0xc90fdaa2, 0x3fff}; // LSB=0 to get acos(1)=0
        !          4982: 
        !          4983: LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s))
        !          4984: {
        !          4985:        int ds;
        !          4986: 
        !          4987:        ds=stackpos(s);
        !          4988:        emit_byte(0xd9);
        !          4989:        emit_byte(0xc0+ds); /* fld x */
        !          4990:        emit_byte(0xd8);
        !          4991:        emit_byte(0xc8);    /* fmul x*x */
        !          4992:        emit_byte(0xd9);
        !          4993:        emit_byte(0xe8);    /* fld 1.0 */
        !          4994:        emit_byte(0xde);
        !          4995:        emit_byte(0xe1);    /* fsubrp 1 - (x^2) */
        !          4996:        emit_byte(0xd9);
        !          4997:        emit_byte(0xfa);    /* fsqrt sqrt(1-(x^2)) */
        !          4998:        emit_byte(0xd9);
        !          4999:        emit_byte(0xc1+ds); /* fld x again */
        !          5000:        emit_byte(0xd9);
        !          5001:        emit_byte(0xc9);    /* fxch swap x with sqrt(1-(x^2))  */
        !          5002:        emit_byte(0xd9);
        !          5003:        emit_byte(0xf3);    /* fpatan atan(x/sqrt(1-(x^2))) & pop */
        !          5004:        raw_fldt((uintptr) &pihalf); /* fld load pi/2 from pihalf */
        !          5005:        emit_byte(0xde);
        !          5006:        emit_byte(0xe1);    /* fsubrp pi/2 - asin(x) & pop */
        !          5007:        tos_make(d);        /* store y=acos(x) */
        !          5008: }
        !          5009: LENDFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s))
        !          5010: 
        !          5011: LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s))
        !          5012: {
        !          5013:        int ds;
        !          5014: 
        !          5015:        if (s==d)
        !          5016:                make_tos(s);
        !          5017:        else {
        !          5018:                ds=stackpos(s);
        !          5019:                emit_byte(0xd9);
        !          5020:                emit_byte(0xc0+ds); /* fld x */
        !          5021:        }
        !          5022:        emit_byte(0xd9);
        !          5023:        emit_byte(0xe8);    /* fld 1.0 */
        !          5024:        emit_byte(0xd9);
        !          5025:        emit_byte(0xf3);    /* fpatan atan(x)/1  & pop*/
        !          5026:        if (s!=d)
        !          5027:                tos_make(d);    /* store y=atan(x) */
        !          5028: }
        !          5029: LENDFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s))
        !          5030: 
        !          5031: LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s))
        !          5032: {
        !          5033:        int ds;
        !          5034: 
        !          5035:        ds=stackpos(s);
        !          5036:        emit_byte(0xd9);
        !          5037:        emit_byte(0xc0+ds); /* fld x */
        !          5038:        emit_byte(0xd9);
        !          5039:        emit_byte(0xe8);    /* fld 1.0 */
        !          5040:        emit_byte(0xdc);
        !          5041:        emit_byte(0xc1);    /* fadd 1 + x */
        !          5042:        emit_byte(0xd8);
        !          5043:        emit_byte(0xe2+ds); /* fsub 1 - x */
        !          5044:        emit_byte(0xde);
        !          5045:        emit_byte(0xf9);    /* fdivp (1+x)/(1-x) */
        !          5046:        emit_byte(0xd9);
        !          5047:        emit_byte(0xed);    /* fldl2e logN(2) */
        !          5048:        emit_byte(0xd9);
        !          5049:        emit_byte(0xc9);    /* fxch swap logN(2) with (1+x)/(1-x) */
        !          5050:        emit_byte(0xd9);
        !          5051:        emit_byte(0xf1);    /* fyl2x logN(2)*log2((1+x)/(1-x)) pop */
        !          5052:        emit_byte(0xd9);
        !          5053:        emit_byte(0xe8);    /* fld 1.0 */
        !          5054:        emit_byte(0xd9);
        !          5055:        emit_byte(0xe0);    /* fchs -1.0 */
        !          5056:        emit_byte(0xd9);
        !          5057:        emit_byte(0xc9);    /* fxch swap */
        !          5058:        emit_byte(0xd9);
        !          5059:        emit_byte(0xfd);    /* fscale logN((1+x)/(1-x)) * 2^(-1) */
        !          5060:        emit_byte(0xdd);
        !          5061:        emit_byte(0xd9);    /* fstp copy & pop */
        !          5062:        tos_make(d);        /* store y=atanh(x) */
        !          5063: }
        !          5064: LENDFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s))
        !          5065: 
        !          5066: LOWFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s))
        !          5067: {
        !          5068:        int ds,tr;
        !          5069: 
        !          5070:        tr=live.onstack[live.tos+3];
        !          5071:        if (s==d)
        !          5072:                make_tos(s);
        !          5073:        else {
        !          5074:                ds=stackpos(s);
        !          5075:                emit_byte(0xd9);
        !          5076:                emit_byte(0xc0+ds); /* fld x */
        !          5077:        }
        !          5078:        emit_byte(0xd9);
        !          5079:        emit_byte(0xea);     /* fldl2e log2(e) */
        !          5080:        emit_byte(0xd8);
        !          5081:        emit_byte(0xc9);     /* fmul x*log2(e) */
        !          5082:        emit_byte(0xdd);
        !          5083:        emit_byte(0xd1);     /* fst copy x*log2(e) */
        !          5084:        if (tr>=0) {
        !          5085:                emit_byte(0xd9);
        !          5086:                emit_byte(0xca); /* fxch swap with temp-reg */
        !          5087:                REX64();
        !          5088:                emit_byte(0x83);
        !          5089:                emit_byte(0xc4);
        !          5090:                emit_byte(0xf4); /* add -12 to esp */
        !          5091:                emit_byte(0xdb);
        !          5092:                emit_byte(0x3c);
        !          5093:                emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */
        !          5094:        }
        !          5095:        emit_byte(0xd9);
        !          5096:        emit_byte(0xe0);     /* fchs -x*log2(e) */
        !          5097:        emit_byte(0xd9);
        !          5098:        emit_byte(0xc0);     /* fld -x*log2(e) again */
        !          5099:        emit_byte(0xd9);
        !          5100:        emit_byte(0xfc);     /* frndint int(-x*log2(e)) */
        !          5101:        emit_byte(0xd9);
        !          5102:        emit_byte(0xc9);     /* fxch swap */
        !          5103:        emit_byte(0xd8);
        !          5104:        emit_byte(0xe1);     /* fsub -x*log2(e) - int(-x*log2(e))  */
        !          5105:        emit_byte(0xd9);
        !          5106:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
        !          5107:        x86_fadd_m((uintptr) &one);
        !          5108:        emit_byte(0xd9);
        !          5109:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          5110:        emit_byte(0xd9);
        !          5111:        emit_byte(0xca);     /* fxch swap e^-x with x*log2(e) in tr */
        !          5112:        emit_byte(0xdd);
        !          5113:        emit_byte(0xd1);     /* fst copy x*log2(e) */
        !          5114:        emit_byte(0xd9);
        !          5115:        emit_byte(0xfc);     /* frndint int(x*log2(e)) */
        !          5116:        emit_byte(0xd9);
        !          5117:        emit_byte(0xc9);     /* fxch swap */
        !          5118:        emit_byte(0xd8);
        !          5119:        emit_byte(0xe1);     /* fsub x*log2(e) - int(x*log2(e))  */
        !          5120:        emit_byte(0xd9);
        !          5121:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
        !          5122:        x86_fadd_m((uintptr) &one);
        !          5123:        emit_byte(0xd9);
        !          5124:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          5125:        emit_byte(0xdd);
        !          5126:        emit_byte(0xd9);     /* fstp copy e^x & pop */
        !          5127:        if (tr>=0) {
        !          5128:                emit_byte(0xdb);
        !          5129:                emit_byte(0x2c);
        !          5130:                emit_byte(0x24); /* fld load temp-reg from [esp] */
        !          5131:                emit_byte(0xd9);
        !          5132:                emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */
        !          5133:                emit_byte(0xde);
        !          5134:                emit_byte(0xe9); /* fsubp (e^x)-(e^-x) */
        !          5135:                REX64();
        !          5136:                emit_byte(0x83);
        !          5137:                emit_byte(0xc4);
        !          5138:                emit_byte(0x0c); /* delayed add +12 to esp */
        !          5139:        }
        !          5140:        else {
        !          5141:                emit_byte(0xde);
        !          5142:                emit_byte(0xe1); /* fsubrp (e^x)-(e^-x) */
        !          5143:        }
        !          5144:        emit_byte(0xd9);
        !          5145:        emit_byte(0xe8);     /* fld 1.0 */
        !          5146:        emit_byte(0xd9);
        !          5147:        emit_byte(0xe0);     /* fchs -1.0 */
        !          5148:        emit_byte(0xd9);
        !          5149:        emit_byte(0xc9);     /* fxch swap */
        !          5150:        emit_byte(0xd9);
        !          5151:        emit_byte(0xfd);     /* fscale ((e^x)-(e^-x))/2 */
        !          5152:        emit_byte(0xdd);
        !          5153:        emit_byte(0xd9);     /* fstp copy & pop */
        !          5154:        if (s!=d)
        !          5155:                tos_make(d);     /* store y=sinh(x) */
        !          5156: }
        !          5157: LENDFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s))
        !          5158: 
        !          5159: LOWFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s))
        !          5160: {
        !          5161:        int ds,tr;
        !          5162: 
        !          5163:        tr=live.onstack[live.tos+3];
        !          5164:        if (s==d)
        !          5165:                make_tos(s);
        !          5166:        else {
        !          5167:                ds=stackpos(s);
        !          5168:                emit_byte(0xd9);
        !          5169:                emit_byte(0xc0+ds); /* fld x */
        !          5170:        }
        !          5171:        emit_byte(0xd9);
        !          5172:        emit_byte(0xea);     /* fldl2e log2(e) */
        !          5173:        emit_byte(0xd8);
        !          5174:        emit_byte(0xc9);     /* fmul x*log2(e) */
        !          5175:        emit_byte(0xdd);
        !          5176:        emit_byte(0xd1);     /* fst copy x*log2(e) */
        !          5177:        if (tr>=0) {
        !          5178:                emit_byte(0xd9);
        !          5179:                emit_byte(0xca); /* fxch swap with temp-reg */
        !          5180:                REX64();
        !          5181:                emit_byte(0x83);
        !          5182:                emit_byte(0xc4);
        !          5183:                emit_byte(0xf4); /* add -12 to esp */
        !          5184:                emit_byte(0xdb);
        !          5185:                emit_byte(0x3c);
        !          5186:                emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */
        !          5187:        }
        !          5188:        emit_byte(0xd9);
        !          5189:        emit_byte(0xe0);     /* fchs -x*log2(e) */
        !          5190:        emit_byte(0xd9);
        !          5191:        emit_byte(0xc0);     /* fld -x*log2(e) again */
        !          5192:        emit_byte(0xd9);
        !          5193:        emit_byte(0xfc);     /* frndint int(-x*log2(e)) */
        !          5194:        emit_byte(0xd9);
        !          5195:        emit_byte(0xc9);     /* fxch swap */
        !          5196:        emit_byte(0xd8);
        !          5197:        emit_byte(0xe1);     /* fsub -x*log2(e) - int(-x*log2(e))  */
        !          5198:        emit_byte(0xd9);
        !          5199:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
        !          5200:        x86_fadd_m((uintptr) &one);
        !          5201:        emit_byte(0xd9);
        !          5202:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          5203:        emit_byte(0xd9);
        !          5204:        emit_byte(0xca);     /* fxch swap e^-x with x*log2(e) in tr */
        !          5205:        emit_byte(0xdd);
        !          5206:        emit_byte(0xd1);     /* fst copy x*log2(e) */
        !          5207:        emit_byte(0xd9);
        !          5208:        emit_byte(0xfc);     /* frndint int(x*log2(e)) */
        !          5209:        emit_byte(0xd9);
        !          5210:        emit_byte(0xc9);     /* fxch swap */
        !          5211:        emit_byte(0xd8);
        !          5212:        emit_byte(0xe1);     /* fsub x*log2(e) - int(x*log2(e))  */
        !          5213:        emit_byte(0xd9);
        !          5214:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
        !          5215:        x86_fadd_m((uintptr) &one);
        !          5216:        emit_byte(0xd9);
        !          5217:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          5218:        emit_byte(0xdd);
        !          5219:        emit_byte(0xd9);     /* fstp copy e^x & pop */
        !          5220:        if (tr>=0) {
        !          5221:                emit_byte(0xdb);
        !          5222:                emit_byte(0x2c);
        !          5223:                emit_byte(0x24); /* fld load temp-reg from [esp] */
        !          5224:                emit_byte(0xd9);
        !          5225:                emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */
        !          5226:                REX64();
        !          5227:                emit_byte(0x83);
        !          5228:                emit_byte(0xc4);
        !          5229:                emit_byte(0x0c); /* delayed add +12 to esp */
        !          5230:        }
        !          5231:        emit_byte(0xde);
        !          5232:        emit_byte(0xc1);     /* faddp (e^x)+(e^-x) */
        !          5233:        emit_byte(0xd9);
        !          5234:        emit_byte(0xe8);     /* fld 1.0 */
        !          5235:        emit_byte(0xd9);
        !          5236:        emit_byte(0xe0);     /* fchs -1.0 */
        !          5237:        emit_byte(0xd9);
        !          5238:        emit_byte(0xc9);     /* fxch swap */
        !          5239:        emit_byte(0xd9);
        !          5240:        emit_byte(0xfd);     /* fscale ((e^x)+(e^-x))/2 */
        !          5241:        emit_byte(0xdd);
        !          5242:        emit_byte(0xd9);     /* fstp copy & pop */
        !          5243:        if (s!=d)
        !          5244:                tos_make(d);     /* store y=cosh(x) */
        !          5245: }
        !          5246: LENDFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s))
        !          5247: 
        !          5248: LOWFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s))
        !          5249: {
        !          5250:        int ds,tr;
        !          5251: 
        !          5252:        tr=live.onstack[live.tos+3];
        !          5253:        if (s==d)
        !          5254:                make_tos(s);
        !          5255:        else {
        !          5256:                ds=stackpos(s);
        !          5257:                emit_byte(0xd9);
        !          5258:                emit_byte(0xc0+ds); /* fld x */
        !          5259:        }
        !          5260:        emit_byte(0xd9);
        !          5261:        emit_byte(0xea);     /* fldl2e log2(e) */
        !          5262:        emit_byte(0xd8);
        !          5263:        emit_byte(0xc9);     /* fmul x*log2(e) */
        !          5264:        emit_byte(0xdd);
        !          5265:        emit_byte(0xd1);     /* fst copy x*log2(e) */
        !          5266:        if (tr>=0) {
        !          5267:                emit_byte(0xd9);
        !          5268:                emit_byte(0xca); /* fxch swap with temp-reg */
        !          5269:                REX64();
        !          5270:                emit_byte(0x83);
        !          5271:                emit_byte(0xc4);
        !          5272:                emit_byte(0xf4); /* add -12 to esp */
        !          5273:                emit_byte(0xdb);
        !          5274:                emit_byte(0x3c);
        !          5275:                emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */
        !          5276:        }
        !          5277:        emit_byte(0xd9);
        !          5278:        emit_byte(0xe0);     /* fchs -x*log2(e) */
        !          5279:        emit_byte(0xd9);
        !          5280:        emit_byte(0xc0);     /* fld -x*log2(e) again */
        !          5281:        emit_byte(0xd9);
        !          5282:        emit_byte(0xfc);     /* frndint int(-x*log2(e)) */
        !          5283:        emit_byte(0xd9);
        !          5284:        emit_byte(0xc9);     /* fxch swap */
        !          5285:        emit_byte(0xd8);
        !          5286:        emit_byte(0xe1);     /* fsub -x*log2(e) - int(-x*log2(e))  */
        !          5287:        emit_byte(0xd9);
        !          5288:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
        !          5289:        x86_fadd_m((uintptr) &one);
        !          5290:        emit_byte(0xd9);
        !          5291:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          5292:        emit_byte(0xd9);
        !          5293:        emit_byte(0xca);     /* fxch swap e^-x with x*log2(e) */
        !          5294:        emit_byte(0xdd);
        !          5295:        emit_byte(0xd1);     /* fst copy x*log2(e) */
        !          5296:        emit_byte(0xd9);
        !          5297:        emit_byte(0xfc);     /* frndint int(x*log2(e)) */
        !          5298:        emit_byte(0xd9);
        !          5299:        emit_byte(0xc9);     /* fxch swap */
        !          5300:        emit_byte(0xd8);
        !          5301:        emit_byte(0xe1);     /* fsub x*log2(e) - int(x*log2(e))  */
        !          5302:        emit_byte(0xd9);
        !          5303:        emit_byte(0xf0);     /* f2xm1 (2^frac(x))-1 */
        !          5304:        x86_fadd_m((uintptr) &one);
        !          5305:        emit_byte(0xd9);
        !          5306:        emit_byte(0xfd);     /* fscale (2^frac(x))*2^int(x*log2(e)) */
        !          5307:        emit_byte(0xdd);
        !          5308:        emit_byte(0xd1);     /* fst copy e^x */
        !          5309:        emit_byte(0xd8);
        !          5310:        emit_byte(0xc2);     /* fadd (e^x)+(e^-x) */
        !          5311:        emit_byte(0xd9);
        !          5312:        emit_byte(0xca);     /* fxch swap with e^-x */
        !          5313:        emit_byte(0xde);
        !          5314:        emit_byte(0xe9);     /* fsubp (e^x)-(e^-x) */
        !          5315:        if (tr>=0) {
        !          5316:                emit_byte(0xdb);
        !          5317:                emit_byte(0x2c);
        !          5318:                emit_byte(0x24); /* fld load temp-reg from [esp] */
        !          5319:                emit_byte(0xd9);
        !          5320:                emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */
        !          5321:                emit_byte(0xde);
        !          5322:                emit_byte(0xf9); /* fdivp ((e^x)-(e^-x))/((e^x)+(e^-x)) */
        !          5323:                REX64();
        !          5324:                emit_byte(0x83);
        !          5325:                emit_byte(0xc4);
        !          5326:                emit_byte(0x0c); /* delayed add +12 to esp */
        !          5327:        }
        !          5328:        else {
        !          5329:                emit_byte(0xde);
        !          5330:                emit_byte(0xf1); /* fdivrp ((e^x)-(e^-x))/((e^x)+(e^-x)) */
        !          5331:        }
        !          5332:        if (s!=d)
        !          5333:                tos_make(d);     /* store y=tanh(x) */
        !          5334: }
        !          5335: LENDFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s))
        !          5336: 
1.1       root     5337: /* %eax register is clobbered if target processor doesn't support fucomi */
                   5338: #define FFLAG_NREG_CLOBBER_CONDITION !have_cmov
                   5339: #define FFLAG_NREG EAX_INDEX
                   5340: 
1.1.1.2 ! root     5341: static inline void raw_fflags_into_flags(int r)
1.1       root     5342: {
1.1.1.2 ! root     5343:        int p;
1.1       root     5344: 
1.1.1.2 ! root     5345:        usereg(r);
        !          5346:        p=stackpos(r);
1.1       root     5347: 
1.1.1.2 ! root     5348:        emit_byte(0xd9);
        !          5349:        emit_byte(0xee); /* Push 0 */
        !          5350:        emit_byte(0xd9);
        !          5351:        emit_byte(0xc9+p); /* swap top two around */
1.1       root     5352:        if (have_cmov) {
                   5353:                // gb-- fucomi is for P6 cores only, not K6-2 then...
1.1.1.2 ! root     5354:                emit_byte(0xdb);
        !          5355:                emit_byte(0xe9+p); /* fucomi them */
1.1       root     5356:        }
                   5357:        else {
                   5358:                emit_byte(0xdd);
                   5359:                emit_byte(0xe1+p); /* fucom them */
                   5360:                emit_byte(0x9b);
                   5361:                emit_byte(0xdf);
                   5362:                emit_byte(0xe0); /* fstsw ax */
                   5363:                raw_sahf(0); /* sahf */
                   5364:        }
1.1.1.2 ! root     5365:        emit_byte(0xdd);
        !          5366:        emit_byte(0xd9+p);  /* store value back, and get rid of 0 */
1.1       root     5367: }

unix.superglobalmegacorp.com

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