nkeynes@991: /** nkeynes@991: * $Id$ nkeynes@991: * nkeynes@995: * x86/x86-64 Instruction generator nkeynes@991: * nkeynes@991: * Copyright (c) 2009 Nathan Keynes. nkeynes@991: * nkeynes@991: * This program is free software; you can redistribute it and/or modify nkeynes@991: * it under the terms of the GNU General Public License as published by nkeynes@991: * the Free Software Foundation; either version 2 of the License, or nkeynes@991: * (at your option) any later version. nkeynes@991: * nkeynes@991: * This program is distributed in the hope that it will be useful, nkeynes@991: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@991: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@991: * GNU General Public License for more details. nkeynes@991: */ nkeynes@995: nkeynes@995: #ifndef lxdream_x86op_H nkeynes@995: #define lxdream_x86op_H nkeynes@995: nkeynes@991: #include nkeynes@991: #include nkeynes@991: nkeynes@991: /******************************** Constants *****************************/ nkeynes@991: nkeynes@991: #define REG_NONE -1 nkeynes@991: nkeynes@991: /* 64-bit general-purpose regs */ nkeynes@991: #define REG_RAX 0 nkeynes@991: #define REG_RCX 1 nkeynes@991: #define REG_RDX 2 nkeynes@991: #define REG_RBX 3 nkeynes@991: #define REG_RSP 4 nkeynes@991: #define REG_RBP 5 nkeynes@991: #define REG_RSI 6 nkeynes@991: #define REG_RDI 7 nkeynes@991: #define REG_R8 8 nkeynes@991: #define REG_R9 9 nkeynes@991: #define REG_R10 10 nkeynes@991: #define REG_R11 11 nkeynes@991: #define REG_R12 12 nkeynes@991: #define REG_R13 13 nkeynes@991: #define REG_R14 14 nkeynes@991: #define REG_R15 15 nkeynes@991: nkeynes@991: /* 32-bit general-purpose regs */ nkeynes@991: #define REG_EAX 0 nkeynes@991: #define REG_ECX 1 nkeynes@991: #define REG_EDX 2 nkeynes@991: #define REG_EBX 3 nkeynes@991: #define REG_ESP 4 nkeynes@991: #define REG_EBP 5 nkeynes@991: #define REG_ESI 6 nkeynes@991: #define REG_EDI 7 nkeynes@991: #define REG_R8D 8 nkeynes@991: #define REG_R9D 9 nkeynes@991: #define REG_R10D 10 nkeynes@991: #define REG_R11D 11 nkeynes@991: #define REG_R12D 12 nkeynes@991: #define REG_R13D 13 nkeynes@991: #define REG_R14D 14 nkeynes@991: #define REG_R15D 15 nkeynes@991: nkeynes@991: /* 8-bit general-purpose regs (no-rex prefix) */ nkeynes@991: #define REG_AL 0 nkeynes@991: #define REG_CL 1 nkeynes@991: #define REG_DL 2 nkeynes@991: #define REG_BL 3 nkeynes@991: #define REG_AH 4 nkeynes@991: #define REG_CH 5 nkeynes@991: #define REG_DH 6 nkeynes@991: #define REG_BH 7 nkeynes@991: nkeynes@991: /* 8-bit general-purpose regs (rex-prefix) */ nkeynes@991: #define REG_SPL 4 nkeynes@991: #define REG_BPL 5 nkeynes@991: #define REG_SIL 6 nkeynes@991: #define REG_DIL 7 nkeynes@991: #define REG_R8L 8 nkeynes@991: #define REG_R9L 9 nkeynes@991: #define REG_R10L 10 nkeynes@991: #define REG_R11L 11 nkeynes@991: #define REG_R12L 12 nkeynes@991: #define REG_R13L 13 nkeynes@991: #define REG_R14L 14 nkeynes@991: #define REG_R15L 15 nkeynes@991: nkeynes@991: /* Condition flag variants */ nkeynes@991: #define X86_COND_O 0x00 /* OF=1 */ nkeynes@991: #define X86_COND_NO 0x01 /* OF=0 */ nkeynes@991: #define X86_COND_B 0x02 /* CF=1 */ nkeynes@991: #define X86_COND_C 0x02 /* CF=1 */ nkeynes@991: #define X86_CONF_NAE 0x02 /* CF=1 */ nkeynes@991: #define X86_COND_AE 0x03 /* CF=0 */ nkeynes@991: #define X86_COND_NB 0x03 /* CF=0 */ nkeynes@991: #define X86_COND_NC 0x03 /* CF=0 */ nkeynes@991: #define X86_COND_E 0x04 /* ZF=1 */ nkeynes@991: #define X86_COND_Z 0x04 /* ZF=1 */ nkeynes@991: #define X86_COND_NE 0x05 /* ZF=0 */ nkeynes@991: #define X86_COND_NZ 0x05 /* ZF=0 */ nkeynes@991: #define X86_COND_BE 0x06 /* CF=1 || ZF=1 */ nkeynes@991: #define X86_COND_NA 0x06 /* CF=1 || ZF=1 */ nkeynes@991: #define X86_COND_A 0x07 /* CF=0 && ZF=0 */ nkeynes@991: #define X86_COND_NBE 0x07 /* CF=0 && ZF=0 */ nkeynes@991: #define X86_COND_S 0x08 /* SF=1 */ nkeynes@991: #define X86_COND_NS 0x09 /* SF=0 */ nkeynes@991: #define X86_COND_P 0x0A /* PF=1 */ nkeynes@991: #define X86_COND_PE 0x0A /* PF=1 */ nkeynes@991: #define X86_COND_NP 0x0B /* PF=0 */ nkeynes@991: #define X86_COND_PO 0x0B /* PF=0 */ nkeynes@991: #define X86_COND_L 0x0C /* SF!=OF */ nkeynes@991: #define X86_COND_NGE 0x0C /* SF!=OF */ nkeynes@991: #define X86_COND_GE 0x0D /* SF=OF */ nkeynes@991: #define X86_COND_NL 0x0D /* SF=OF */ nkeynes@991: #define X86_COND_LE 0x0E /* ZF=1 || SF!=OF */ nkeynes@991: #define X86_COND_NG 0x0E /* ZF=1 || SF!=OF */ nkeynes@991: #define X86_COND_G 0x0F /* ZF=0 && SF=OF */ nkeynes@991: #define X86_COND_NLE 0x0F /* ZF=0 && SF=OF */ nkeynes@991: nkeynes@991: /* SSE floating pointer comparison variants */ nkeynes@991: #define SSE_CMP_EQ 0x00 nkeynes@991: #define SSE_CMP_LT 0x01 nkeynes@991: #define SSE_CMP_LE 0x02 nkeynes@991: #define SSE_CMP_UNORD 0x03 nkeynes@991: #define SSE_CMP_NE 0x04 nkeynes@991: #define SSE_CMP_NLT 0x05 nkeynes@991: #define SSE_CMP_NLE 0x06 nkeynes@991: #define SSE_CMP_ORD 0x07 nkeynes@991: nkeynes@991: /************************** Internal definitions ***************************/ nkeynes@991: #define PREF_REXB 0x41 nkeynes@991: #define PREF_REXX 0x42 nkeynes@991: #define PREF_REXR 0x44 nkeynes@991: #define PREF_REXW 0x48 nkeynes@991: nkeynes@995: /* PREF_REXW if required for pointer operations, otherwise 0 */ nkeynes@995: #define PREF_PTR ((sizeof(void *) == 8) ? PREF_REXW : 0) nkeynes@995: nkeynes@991: extern unsigned char *xlat_output; nkeynes@991: nkeynes@991: #define OP(x) *xlat_output++ = (x) nkeynes@991: #define OP16(x) *((uint16_t *)xlat_output) = (x); xlat_output+=2 nkeynes@991: #define OP32(x) *((uint32_t *)xlat_output) = (x); xlat_output+=4 nkeynes@991: #define OP64(x) *((uint64_t *)xlat_output) = (x); xlat_output+=8 nkeynes@991: #define OPPTR(x) *((void **)xlat_output) = ((void *)x); xlat_output+=(sizeof(void*)) nkeynes@991: nkeynes@991: /* Primary opcode emitter, eg OPCODE(0x0FBE) for MOVSX */ nkeynes@991: #define OPCODE(x) if( (x) > 0xFFFF ) { OP(x>>16); OP((x>>8)&0xFF); OP(x&0xFF); } else if( (x) > 0xFF ) { OP(x>>8); OP(x&0xFF); } else { OP(x); } nkeynes@991: nkeynes@991: /* Test if immediate value is representable as a signed 8-bit integer */ nkeynes@991: #define IS_INT8(imm) ((imm) >= INT8_MIN && (imm) <= INT8_MAX) nkeynes@991: nkeynes@991: /** nkeynes@991: * Encode opcode+reg with no mod/rm (eg MOV imm64, r32) nkeynes@991: */ nkeynes@991: static void x86_encode_opcodereg( int rexw, uint32_t opcode, int reg ) nkeynes@991: { nkeynes@991: int rex = rexw; nkeynes@991: reg &= 0x0F; nkeynes@991: if( reg >= 8 ) { nkeynes@991: rex |= PREF_REXB; nkeynes@991: reg -= 8; nkeynes@991: } nkeynes@991: if( rex != 0 ) { nkeynes@991: OP(rex); nkeynes@991: } nkeynes@991: OPCODE(opcode + reg); nkeynes@991: } nkeynes@991: nkeynes@991: /** nkeynes@991: * Encode opcode with mod/rm reg-reg operation. nkeynes@991: * @param opcode primary instruction opcode nkeynes@991: * @param rr reg field nkeynes@991: * @param rb r/m field nkeynes@991: */ nkeynes@991: static int x86_encode_reg_rm( int rexw, uint32_t opcode, int rr, int rb ) nkeynes@991: { nkeynes@991: int rex = rexw; nkeynes@991: rr &= 0x0F; nkeynes@991: rb &= 0x0F; nkeynes@991: if( rr >= 8 ) { nkeynes@991: rex |= PREF_REXR; nkeynes@991: rr -= 8; nkeynes@991: } nkeynes@991: if( rb >= 8 ) { nkeynes@991: rex |= PREF_REXB; nkeynes@991: rb -= 8; nkeynes@991: } nkeynes@991: if( rex != 0 ) { nkeynes@991: OP(rex); nkeynes@991: } nkeynes@991: OPCODE(opcode); nkeynes@991: OP(0xC0|(rr<<3)|rb); nkeynes@991: } nkeynes@991: nkeynes@991: /** nkeynes@991: * Encode opcode + 32-bit mod/rm memory address. (RIP-relative not supported here) nkeynes@991: * @param rexw REX.W prefix is required, otherwise 0 nkeynes@991: * @param rr Reg-field register (required). nkeynes@991: * @param rb Base (unscaled) register, or -1 for no base register. nkeynes@991: * @param rx Index (scaled) register, or -1 for no index register nkeynes@991: * @param ss Scale shift (0..3) applied to index register (ignored if no index register) nkeynes@991: * @param disp32 Signed displacement (0 for none) nkeynes@991: */ nkeynes@991: static void x86_encode_modrm( int rexw, uint32_t opcode, int rr, int rb, int rx, int ss, int32_t disp32 ) nkeynes@991: { nkeynes@991: /* Construct the rex prefix where necessary */ nkeynes@991: int rex = rexw; nkeynes@991: rr &= 0x0F; nkeynes@991: if( rr >= 8 ) { nkeynes@991: rex |= PREF_REXR; nkeynes@991: rr -= 8; nkeynes@991: } nkeynes@991: if( rb != -1 ) { nkeynes@991: rb &= 0x0F; nkeynes@991: if( rb >= 8 ) { nkeynes@991: rex |= PREF_REXB; nkeynes@991: rb -= 8; nkeynes@991: } nkeynes@991: } nkeynes@991: if( rx != -1 ) { nkeynes@991: rx &= 0x0F; nkeynes@991: if( rx >= 8 ) { nkeynes@991: rex |= PREF_REXX; nkeynes@991: rx -= 8; nkeynes@991: } nkeynes@991: } nkeynes@991: nkeynes@991: if( rex != 0 ) { nkeynes@991: OP(rex); nkeynes@991: } nkeynes@991: OPCODE(opcode); nkeynes@991: nkeynes@991: if( rx == -1 ) { nkeynes@991: if( rb == -1 ) { nkeynes@991: /* [disp32] displacement only - use SIB form for 64-bit mode safety */ nkeynes@991: OP(0x04|(rr<<3)); nkeynes@991: OP(0x25); nkeynes@991: OP32(disp32); nkeynes@991: } else if( rb == REG_ESP ) { /* [%esp + disp32] - SIB is mandatory for %esp/%r12 encodings */ nkeynes@991: if( disp32 == 0 ) { nkeynes@991: OP(0x04|(rr<<3)); nkeynes@991: OP(0x24); nkeynes@991: } else if( IS_INT8(disp32) ) { nkeynes@991: OP(0x44|(rr<<3)); nkeynes@991: OP(0x24); nkeynes@991: OP((int8_t)disp32); nkeynes@991: } else { nkeynes@991: OP(0x84|(rr<<3)); nkeynes@991: OP(0x24); nkeynes@991: OP32(disp32); nkeynes@991: } nkeynes@991: } else { nkeynes@991: if( disp32 == 0 && rb != REG_EBP ) { /* [%ebp] is encoded as [%ebp+0] */ nkeynes@991: OP((rr<<3)|rb); nkeynes@991: } else if( IS_INT8(disp32) ) { nkeynes@991: OP(0x40|(rr<<3)|rb); nkeynes@991: OP((int8_t)disp32); nkeynes@991: } else { nkeynes@991: OP(0x80|(rr<<3)|rb); nkeynes@991: OP32(disp32); nkeynes@991: } nkeynes@991: } nkeynes@991: } else { /* We have a scaled index. Goody */ nkeynes@991: assert( ((rx != REG_ESP) || (rex&PREF_REXX)) && "Bug: attempt to index through %esp" ); /* Indexing by %esp is impossible */ nkeynes@991: if( rb == -1 ) { /* [disp32 + rx << ss] */ nkeynes@991: OP(0x04|(rr<<3)); nkeynes@991: OP(0x05|(ss<<6)|(rx<<3)); nkeynes@991: OP32(disp32); nkeynes@991: } else if( disp32 == 0 && rb != REG_EBP ) { /* [rb + rx << ss]. (Again, %ebp needs to be %ebp+0) */ nkeynes@991: OP(0x04|(rr<<3)); nkeynes@991: OP((ss<<6)|(rx<<3)|rb); nkeynes@991: } else if( IS_INT8(disp32) ) { nkeynes@991: OP(0x44|(rr<<3)); nkeynes@991: OP((ss<<6)|(rx<<3)|rb); nkeynes@991: OP((int8_t)disp32); nkeynes@991: } else { nkeynes@991: OP(0x84|(rr<<3)); nkeynes@991: OP((ss<<6)|(rx<<3)|rb); nkeynes@991: OP32(disp32); nkeynes@991: } nkeynes@991: } nkeynes@991: } nkeynes@991: nkeynes@991: /** nkeynes@991: * Encode opcode + RIP-relative mod/rm (64-bit mode only) nkeynes@991: * @param rexw PREF_REXW or 0 nkeynes@991: * @param opcode primary instruction opcode nkeynes@991: * @param rr mod/rm reg field nkeynes@991: * @param disp32 RIP-relative displacement nkeynes@991: */ nkeynes@991: static void x86_encode_modrm_rip(int rexw, uint32_t opcode, int rr, int32_t disp32) nkeynes@991: { nkeynes@991: int rex = rexw; nkeynes@991: rr &= 0x0F; nkeynes@991: if( rr >= 8 ) { nkeynes@991: rex |= PREF_REXR; nkeynes@991: rr -= 8; nkeynes@991: } nkeynes@991: if( rex != 0 ) { nkeynes@991: OP(rex); nkeynes@991: } nkeynes@991: OPCODE(opcode); nkeynes@991: OP(0x05|(rr<<3)); nkeynes@991: OP32(disp32); nkeynes@991: } nkeynes@991: nkeynes@991: /* 32/64-bit op emitters. 64-bit versions include a rex.w prefix. Note that any nkeynes@991: * other prefixes (mandatory or otherwise) need to be emitted prior to these nkeynes@991: * functions nkeynes@991: */ nkeynes@991: #define x86_encode_opcode64(opcode,reg) x86_encode_opcodereg(PREF_REXW, opcode,reg) nkeynes@991: #define x86_encode_opcode32(opcode,reg) x86_encode_opcodereg(0,opcode,reg) nkeynes@991: #define x86_encode_r32_rm32(opcode,rr,rb) x86_encode_reg_rm(0,opcode,rr,rb) nkeynes@991: #define x86_encode_r64_rm64(opcode,rr,rb) x86_encode_reg_rm(PREF_REXW,opcode,rr,rb) nkeynes@991: #define x86_encode_r32_mem32(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(0,opcode,rr,rb,rx,ss,disp32) nkeynes@991: #define x86_encode_r64_mem64(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,rx,ss,disp32) nkeynes@995: #define x86_encode_rptr_memptr(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_PTR,opcode,rr,rb,rx,ss,disp32) nkeynes@991: #define x86_encode_r32_mem32disp32(opcode,rr,rb,disp32) x86_encode_modrm(0,opcode,rr,rb,-1,0,disp32) nkeynes@991: #define x86_encode_r64_mem64disp64(opcode,rr,rb,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,-1,0,disp32) nkeynes@991: #define x86_encode_r32_ripdisp32(opcode,rr,disp32) x86_encode_modrm_rip(0,opcode,rr,disp32) nkeynes@991: #define x86_encode_r64_ripdisp64(opcode,rr,disp32) x86_encode_modrm_rip(PREF_REXW,opcode,rr,disp32) nkeynes@991: nkeynes@991: /* Convenience versions for the common rbp/rsp relative displacements */ nkeynes@991: #define x86_encode_r32_rbpdisp32(opcode,rr,disp32) x86_encode_modrm(0,opcode,rr,REG_RBP,-1,0,disp32) nkeynes@991: #define x86_encode_r64_rbpdisp64(opcode,rr,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,REG_RBP,-1,0,disp32) nkeynes@991: #define x86_encode_r32_rspdisp32(opcode,rr,disp32) x86_encode_modrm(0,opcode,rr,REG_RSP,-1,0,disp32) nkeynes@991: #define x86_encode_r64_rspdisp64(opcode,rr,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,REG_RSP,-1,0,disp32) nkeynes@991: nkeynes@991: /* Immediate-selection variants (for instructions with imm8s/imm32 variants) */ nkeynes@991: #define x86_encode_imms_rm32(opcode8,opcode32,reg,imm,rb) \ nkeynes@991: if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rm32(opcode8,reg,rb); OP((int8_t)imm); \ nkeynes@991: } else { x86_encode_r32_rm32(opcode32,reg,rb); OP32(imm); } nkeynes@991: #define x86_encode_imms_rm64(opcode8,opcode32,reg,imm,rb) \ nkeynes@991: if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rm64(opcode8,reg,rb); OP((int8_t)imm); \ nkeynes@991: } else { x86_encode_r64_rm64(opcode32,reg,rb); OP32(imm); } nkeynes@995: #define x86_encode_imms_rmptr(opcode8,opcode32,reg,imm,rb) \ nkeynes@995: if( IS_INT8(((int32_t)imm)) ) { x86_encode_reg_rm( PREF_PTR, opcode8,reg,rb); OP((int8_t)imm); \ nkeynes@995: } else { x86_encode_reg_rm( PREF_PTR, opcode32,reg,rb); OP32(imm); } nkeynes@991: #define x86_encode_imms_rbpdisp32(opcode8,opcode32,reg,imm,disp) \ nkeynes@991: if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rbpdisp32(opcode8,reg,disp); OP((int8_t)imm); \ nkeynes@991: } else { x86_encode_r32_rbpdisp32(opcode32,reg,disp); OP32(imm); } nkeynes@991: #define x86_encode_imms_r32disp32(opcode8,opcode32,reg,imm,rb,disp) \ nkeynes@991: if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_mem32disp32(opcode8,reg,rb,disp); OP((int8_t)imm); \ nkeynes@991: } else { x86_encode_r32_mem32disp32(opcode32,reg,rb,disp); OP32(imm); } nkeynes@991: #define x86_encode_imms_rbpdisp64(opcode8,opcode32,reg,imm,disp) \ nkeynes@991: if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rbpdisp64(opcode8,reg,disp); OP((int8_t)imm); \ nkeynes@991: } else { x86_encode_r64_rbpdisp64(opcode32,reg,disp); OP32(imm); } nkeynes@991: nkeynes@991: /*************************** Instruction definitions ***********************/ nkeynes@991: /* Note this does not try to be an exhaustive definition of the instruction - nkeynes@991: * it generally only has the forms that we actually need here. nkeynes@991: */ nkeynes@991: /* Core Integer instructions */ nkeynes@991: #define ADCB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 2, r1); OP(imm) nkeynes@991: #define ADCB_r8_r8(r1,r2) x86_encode_r32_rm32(0x10, r1, r2) nkeynes@991: #define ADCL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 2, imm, r1) nkeynes@991: #define ADCL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83, 0x81, 2, imm, disp) nkeynes@991: #define ADCL_r32_r32(r1,r2) x86_encode_r32_rm32(0x11, r1, r2) nkeynes@991: #define ADCL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x11, r1, disp) nkeynes@991: #define ADCL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x13, r1, disp) nkeynes@991: #define ADCQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 2, imm, r1) nkeynes@991: #define ADCQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x11, r1, r2) nkeynes@991: nkeynes@991: #define ADDB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 0, r1); OP(imm) nkeynes@991: #define ADDB_r8_r8(r1,r2) x86_encode_r32_rm32(0x00, r1, r2) nkeynes@991: #define ADDL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 0, imm, r1) nkeynes@991: #define ADDL_imms_r32disp(imm,rb,d) x86_encode_imms_r32disp32(0x83, 0x81, 0, imm, rb, d) nkeynes@991: #define ADDL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83, 0x81, 0, imm, disp) nkeynes@991: #define ADDL_r32_r32(r1,r2) x86_encode_r32_rm32(0x01, r1, r2) nkeynes@991: #define ADDL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x01, r1, disp) nkeynes@991: #define ADDL_r32_r32disp(r1,r2,dsp) x86_encode_r32_mem32disp32(0x01, r1, r2, dsp) nkeynes@991: #define ADDL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x03, r1, disp) nkeynes@991: #define ADDQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 0, imm, r1) nkeynes@991: #define ADDQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x01, r1, r2) nkeynes@991: nkeynes@991: #define ANDB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 4, r1); OP(imm) nkeynes@991: #define ANDB_r8_r8(r1,r2) x86_encode_r32_rm32(0x20, r1, r2) nkeynes@991: #define ANDL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 4, imm, r1) nkeynes@991: #define ANDL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,4,imm,disp) nkeynes@991: #define ANDL_r32_r32(r1,r2) x86_encode_r32_rm32(0x21, r1, r2) nkeynes@991: #define ANDL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x21, r1, disp) nkeynes@991: #define ANDL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x23, r1, disp) nkeynes@991: #define ANDQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x21, r1, r2) nkeynes@991: #define ANDQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 4, imm, r1) nkeynes@995: #define ANDP_imms_rptr(imm,r1) x86_encode_imms_rmptr(0x83, 0x81, 4, imm, r1) nkeynes@991: nkeynes@991: #define CLC() OP(0xF8) nkeynes@991: #define CLD() OP(0xFC) nkeynes@991: #define CMC() OP(0xF5) nkeynes@991: nkeynes@991: #define CMOVCCL_cc_r32_r32(cc,r1,r2) x86_encode_r32_rm32(0x0F40+(cc), r2, r1) nkeynes@991: #define CMOVCCL_cc_rbpdisp_r32(cc,d,r1) x86_encode_r32_rbpdisp32(0x0F40+(cc), r1, d) nkeynes@991: nkeynes@991: #define CMPB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 7, r1); OP(imm) nkeynes@991: #define CMPB_imms_rbpdisp(imm,disp) x86_encode_r32_rbpdisp32(0x80, 7, disp); OP(imm) nkeynes@991: #define CMPB_r8_r8(r1,r2) x86_encode_r32_rm32(0x38, r1, r2) nkeynes@991: #define CMPL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 7, imm, r1) nkeynes@991: #define CMPL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83, 0x81, 7, imm, disp) nkeynes@991: #define CMPL_r32_r32(r1,r2) x86_encode_r32_rm32(0x39, r1, r2) nkeynes@991: #define CMPL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x39, r1, disp) nkeynes@991: #define CMPL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x3B, r1, disp) nkeynes@991: #define CMPQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 7, imm, r1) nkeynes@991: #define CMPQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x39, r1, r2) nkeynes@991: nkeynes@991: #define IDIVL_r32(r1) x86_encode_r32_rm32(0xF7, 7, r1) nkeynes@991: #define IDIVL_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xF7, 7, disp) nkeynes@991: #define IDIVQ_r64(r1) x86_encode_r64_rm64(0xF7, 7, r1) nkeynes@991: nkeynes@991: #define IMULL_imms_r32(imm,r1) x86_encode_imms_rm32(0x6B,0x69, r1, imm, r1) nkeynes@991: #define IMULL_r32(r1) x86_encode_r32_rm32(0xF7, 5, r1) nkeynes@991: #define IMULL_r32_r32(r1,r2) x86_encode_r32_rm32(0x0FAF, r2, r1) nkeynes@991: #define IMULL_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xF7, 5, disp) nkeynes@991: #define IMULL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FAF, r1, disp) nkeynes@991: #define IMULL_rspdisp(disp) x86_encode_r32_rspdisp32(0xF7, 5, disp) nkeynes@991: #define IMULL_rspdisp_r32(disp,r1) x86_encode_r32_rspdisp32(0x0FAF, r1, disp) nkeynes@991: #define IMULQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x6B,0x69, r1, imm, r1) nkeynes@991: #define IMULQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x0FAF, r2, r1) nkeynes@991: nkeynes@991: #define LEAL_r32disp_r32(r1,disp,r2) x86_encode_r32_mem32(0x8D, r2, r1, -1, 0, disp) nkeynes@991: #define LEAL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x8D, r1, disp) nkeynes@991: #define LEAL_sib_r32(ss,ii,bb,d,r1) x86_encode_r32_mem32(0x8D, r1, bb, ii, ss, d) nkeynes@991: #define LEAQ_r64disp_r64(r1,disp,r2) x86_encode_r64_mem64(0x8D, r2, r1, -1, 0, disp) nkeynes@991: #define LEAQ_rbpdisp_r64(disp,r1) x86_encode_r64_rbpdisp64(0x8D, r1, disp) nkeynes@991: #define LEAP_rptrdisp_rptr(r1,d,r2) x86_encode_rptr_memptr(0x8D, r2, r1, -1, 0, disp) nkeynes@991: #define LEAP_rbpdisp_rptr(disp,r1) x86_encode_rptr_memptr(0x8D, r1, REG_RBP, -1, 0, disp) nkeynes@991: #define LEAP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8D, r1, bb, ii, ss, d) nkeynes@991: nkeynes@991: #define MOVB_r8_r8(r1,r2) x86_encode_r32_rm32(0x88, r1, r2) nkeynes@991: #define MOVL_imm32_r32(i32,r1) x86_encode_opcode32(0xB8, r1); OP32(i32) nkeynes@991: #define MOVL_imm32_rbpdisp(i,disp) x86_encode_r32_rbpdisp32(0xC7,0,disp); OP32(i) nkeynes@991: #define MOVL_imm32_rspdisp(i,disp) x86_encode_r32_rspdisp32(0xC7,0,disp); OP32(i) nkeynes@991: #define MOVL_moffptr_eax(p) OP(0xA1); OPPTR(p) nkeynes@991: #define MOVL_r32_r32(r1,r2) x86_encode_r32_rm32(0x89, r1, r2) nkeynes@991: #define MOVL_r32_r32disp(r1,r2,dsp) x86_encode_r32_mem32disp32(0x89, r1, r2, dsp) nkeynes@991: #define MOVL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x89, r1, disp) nkeynes@991: #define MOVL_r32_rspdisp(r1,disp) x86_encode_r32_rspdisp32(0x89, r1, disp) nkeynes@991: #define MOVL_r32_sib(r1,ss,ii,bb,d) x86_encode_r32_mem32(0x89, r1, bb, ii, ss, d) nkeynes@991: #define MOVL_r32disp_r32(r1,dsp,r2) x86_encode_r32_mem32disp32(0x8B, r2, r1, dsp) nkeynes@991: #define MOVL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x8B, r1, disp) nkeynes@991: #define MOVL_rspdisp_r32(disp,r1) x86_encode_r32_rspdisp32(0x8B, r1, disp) nkeynes@991: #define MOVL_sib_r32(ss,ii,bb,d,r1) x86_encode_r32_mem32(0x8B, r1, bb, ii, ss, d) nkeynes@991: #define MOVQ_imm64_r64(i64,r1) x86_encode_opcode64(0xB8, r1); OP64(i64) nkeynes@991: #define MOVQ_moffptr_rax(p) OP(PREF_REXW); OP(0xA1); OPPTR(p) nkeynes@991: #define MOVQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x89, r1, r2) nkeynes@991: #define MOVQ_r64_rbpdisp(r1,disp) x86_encode_r64_rbpdisp64(0x89, r1, disp) nkeynes@991: #define MOVQ_r64_rspdisp(r1,disp) x86_encode_r64_rspdisp64(0x89, r1, disp) nkeynes@991: #define MOVQ_rbpdisp_r64(disp,r1) x86_encode_r64_rbpdisp64(0x8B, r1, disp) nkeynes@991: #define MOVQ_rspdisp_r64(disp,r1) x86_encode_r64_rspdisp64(0x8B, r1, disp) nkeynes@995: #define MOVP_immptr_rptr(p,r1) x86_encode_opcodereg( PREF_PTR, 0xB8, r1); OPPTR(p) nkeynes@991: #define MOVP_moffptr_rax(p) if( sizeof(void*)==8 ) { OP(PREF_REXW); } OP(0xA1); OPPTR(p) nkeynes@995: #define MOVP_rptr_rptr(r1,r2) x86_encode_reg_rm(PREF_PTR, 0x89, r1, r2) nkeynes@991: #define MOVP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8B, r1, bb, ii, ss, d) nkeynes@991: nkeynes@991: #define MOVSXL_r8_r32(r1,r2) x86_encode_r32_rm32(0x0FBE, r2, r1) nkeynes@991: #define MOVSXL_r16_r32(r1,r2) x86_encode_r32_rm32(0x0FBF, r2, r1) nkeynes@991: #define MOVSXL_rbpdisp8_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FBE, r1, disp) nkeynes@991: #define MOVSXL_rbpdisp16_r32(dsp,r1) x86_encode_r32_rbpdisp32(0x0FBF, r1, dsp) nkeynes@991: #define MOVSXQ_imm32_r64(i32,r1) x86_encode_r64_rm64(0xC7, 0, r1); OP32(i32) /* Technically a MOV */ nkeynes@991: #define MOVSXQ_r8_r64(r1,r2) x86_encode_r64_rm64(0x0FBE, r2, r1) nkeynes@991: #define MOVSXQ_r16_r64(r1,r2) x86_encode_r64_rm64(0x0FBF, r2, r1) nkeynes@991: #define MOVSXQ_r32_r64(r1,r2) x86_encode_r64_rm64(0x63, r2, r1) nkeynes@991: #define MOVSXQ_rbpdisp32_r64(dsp,r1) x86_encode_r64_rbpdisp64(0x63, r1, dsp) nkeynes@991: nkeynes@991: #define MOVZXL_r8_r32(r1,r2) x86_encode_r32_rm32(0x0FB6, r2, r1) nkeynes@991: #define MOVZXL_r16_r32(r1,r2) x86_encode_r32_rm32(0x0FB7, r2, r1) nkeynes@991: #define MOVZXL_rbpdisp8_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FB6, r1, disp) nkeynes@991: #define MOVZXL_rbpdisp16_r32(dsp,r1) x86_encode_r32_rbpdisp32(0x0FB7, r1, dsp) nkeynes@991: nkeynes@991: #define MULL_r32(r1) x86_encode_r32_rm32(0xF7, 4, r1) nkeynes@991: #define MULL_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xF7,4,disp) nkeynes@991: #define MULL_rspdisp(disp) x86_encode_r32_rspdisp32(0xF7,4,disp) nkeynes@991: nkeynes@991: #define NEGB_r8(r1) x86_encode_r32_rm32(0xF6, 3, r1) nkeynes@991: #define NEGL_r32(r1) x86_encode_r32_rm32(0xF7, 3, r1) nkeynes@991: #define NEGL_rbpdisp(r1) x86_encode_r32_rbspdisp32(0xF7, 3, disp) nkeynes@991: #define NEGQ_r64(r1) x86_encode_r64_rm64(0xF7, 3, r1) nkeynes@991: nkeynes@991: #define NOTB_r8(r1) x86_encode_r32_rm32(0xF6, 2, r1) nkeynes@991: #define NOTL_r32(r1) x86_encode_r32_rm32(0xF7, 2, r1) nkeynes@991: #define NOTL_rbpdisp(r1) x86_encode_r32_rbspdisp32(0xF7, 2, disp) nkeynes@991: #define NOTQ_r64(r1) x86_encode_r64_rm64(0xF7, 2, r1) nkeynes@991: nkeynes@991: #define ORB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 1, r1); OP(imm) nkeynes@991: #define ORB_r8_r8(r1,r2) x86_encode_r32_rm32(0x08, r1, r2) nkeynes@991: #define ORL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 1, imm, r1) nkeynes@991: #define ORL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,1,imm,disp) nkeynes@991: #define ORL_r32_r32(r1,r2) x86_encode_r32_rm32(0x09, r1, r2) nkeynes@991: #define ORL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x09, r1, disp) nkeynes@991: #define ORL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0B, r1, disp) nkeynes@991: #define ORQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 1, imm, r1) nkeynes@991: #define ORQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x09, r1, r2) nkeynes@991: nkeynes@991: #define POP_r32(r1) x86_encode_opcode32(0x58, r1) nkeynes@991: nkeynes@991: #define PUSH_imm32(imm) OP(0x68); OP32(imm) nkeynes@991: #define PUSH_r32(r1) x86_encode_opcode32(0x50, r1) nkeynes@991: nkeynes@991: #define RCLL_cl_r32(r1) x86_encode_r32_rm32(0xD3,2,r1) nkeynes@991: #define RCLL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,2,r1); } else { x86_encode_r32_rm32(0xC1,2,r1); OP(imm); } nkeynes@991: #define RCLQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,2,r1) nkeynes@991: #define RCLQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,2,r1); } else { x86_encode_r64_rm64(0xC1,2,r1); OP(imm); } nkeynes@991: #define RCRL_cl_r32(r1) x86_encode_r32_rm32(0xD3,3,r1) nkeynes@991: #define RCRL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,3,r1); } else { x86_encode_r32_rm32(0xC1,3,r1); OP(imm); } nkeynes@991: #define RCRQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,3,r1) nkeynes@991: #define RCRQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,3,r1); } else { x86_encode_r64_rm64(0xC1,3,r1); OP(imm); } nkeynes@991: #define ROLL_cl_r32(r1) x86_encode_r32_rm32(0xD3,0,r1) nkeynes@991: #define ROLL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,0,r1); } else { x86_encode_r32_rm32(0xC1,0,r1); OP(imm); } nkeynes@991: #define ROLQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,0,r1) nkeynes@991: #define ROLQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,0,r1); } else { x86_encode_r64_rm64(0xC1,0,r1); OP(imm); } nkeynes@991: #define RORL_cl_r32(r1) x86_encode_r32_rm32(0xD3,1,r1) nkeynes@991: #define RORL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,1,r1); } else { x86_encode_r32_rm32(0xC1,1,r1); OP(imm); } nkeynes@991: #define RORQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,1,r1) nkeynes@991: #define RORQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,1,r1); } else { x86_encode_r64_rm64(0xC1,1,r1); OP(imm); } nkeynes@991: nkeynes@991: #define SARL_cl_r32(r1) x86_encode_r32_rm32(0xD3,7,r1) nkeynes@991: #define SARL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,7,r1); } else { x86_encode_r32_rm32(0xC1,7,r1); OP(imm); } nkeynes@991: #define SARQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,7,r1) nkeynes@991: #define SARQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,7,r1); } else { x86_encode_r64_rm64(0xC1,7,r1); OP(imm); } nkeynes@991: #define SHLL_cl_r32(r1) x86_encode_r32_rm32(0xD3,4,r1) nkeynes@991: #define SHLL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,4,r1); } else { x86_encode_r32_rm32(0xC1,4,r1); OP(imm); } nkeynes@991: #define SHLQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,4,r1) nkeynes@991: #define SHLQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,4,r1); } else { x86_encode_r64_rm64(0xC1,4,r1); OP(imm); } nkeynes@991: #define SHRL_cl_r32(r1) x86_encode_r32_rm32(0xD3,5,r1) nkeynes@991: #define SHRL_imm_r32(imm,r1) if( imm == 1 ) { x86_encode_r32_rm32(0xD1,5,r1); } else { x86_encode_r32_rm32(0xC1,5,r1); OP(imm); } nkeynes@991: #define SHRQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,5,r1) nkeynes@991: #define SHRQ_imm_r64(imm,r1) if( imm == 1 ) { x86_encode_r64_rm64(0xD1,5,r1); } else { x86_encode_r64_rm64(0xC1,5,r1); OP(imm); } nkeynes@991: nkeynes@991: #define SBBB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 3, r1); OP(imm) nkeynes@991: #define SBBB_r8_r8(r1,r2) x86_encode_r32_rm32(0x18, r1, r2) nkeynes@991: #define SBBL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 3, imm, r1) nkeynes@991: #define SBBL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,3,imm,disp) nkeynes@991: #define SBBL_r32_r32(r1,r2) x86_encode_r32_rm32(0x19, r1, r2) nkeynes@991: #define SBBL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x19, r1, disp) nkeynes@991: #define SBBL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x1B, r1, disp) nkeynes@991: #define SBBQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 3, imm, r1) nkeynes@991: #define SBBQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x19, r1, r2) nkeynes@991: nkeynes@991: #define SETCCB_cc_r8(cc,r1) x86_encode_r32_rm32(0x0F90+(cc), 0, r1) nkeynes@991: #define SETCCB_cc_rbpdisp(cc,disp) x86_encode_r32_rbpdisp32(0x0F90+(cc), 0, disp) nkeynes@991: nkeynes@991: #define STC() OP(0xF9) nkeynes@991: #define STD() OP(0xFD) nkeynes@991: nkeynes@991: #define SUBB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 5, r1); OP(imm) nkeynes@991: #define SUBB_r8_r8(r1,r2) x86_encode_r32_rm32(0x28, r1, r2) nkeynes@991: #define SUBL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 5, imm, r1) nkeynes@991: #define SUBL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,5,imm,disp) nkeynes@991: #define SUBL_r32_r32(r1,r2) x86_encode_r32_rm32(0x29, r1, r2) nkeynes@991: #define SUBL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x29, r1, disp) nkeynes@991: #define SUBL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x2B, r1, disp) nkeynes@991: #define SUBQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 5, imm, r1) nkeynes@991: #define SUBQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x29, r1, r2) nkeynes@991: nkeynes@991: #define TESTB_imms_r8(imm,r1) x86_encode_r32_rm32(0xF6, 0, r1); OP(imm) nkeynes@991: #define TESTB_r8_r8(r1,r2) x86_encode_r32_rm32(0x84, r1, r2) nkeynes@991: #define TESTL_imms_r32(imm,r1) x86_encode_r32_rm32(0xF7, 0, r1); OP32(imm) nkeynes@991: #define TESTL_imms_rbpdisp(imm,dsp) x86_encode_r32_rbpdisp32(0xF7, 0, dsp); OP32(imm) nkeynes@991: #define TESTL_r32_r32(r1,r2) x86_encode_r32_rm32(0x85, r1, r2) nkeynes@991: #define TESTL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x85, r1, disp) nkeynes@991: #define TESTL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x85, r1, disp) /* Same OP */ nkeynes@991: #define TESTQ_imms_r64(imm,r1) x86_encode_r64_rm64(0xF7, 0, r1); OP32(imm) nkeynes@991: #define TESTQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x85, r1, r2) nkeynes@991: nkeynes@991: #define XCHGB_r8_r8(r1,r2) x86_encode_r32_rm32(0x86, r1, r2) nkeynes@991: #define XCHGL_r32_r32(r1,r2) x86_encode_r32_rm32(0x87, r1, r2) nkeynes@991: #define XCHGQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x87, r1, r2) nkeynes@991: nkeynes@991: #define XORB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 6, r1); OP(imm) nkeynes@991: #define XORB_r8_r8(r1,r2) x86_encode_r32_rm32(0x30, r1, r2) nkeynes@991: #define XORL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 6, imm, r1) nkeynes@991: #define XORL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,6,imm,disp) nkeynes@991: #define XORL_r32_r32(r1,r2) x86_encode_r32_rm32(0x31, r1, r2) nkeynes@991: #define XORL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x31, r1, disp) nkeynes@991: #define XORL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x33, r1, disp) nkeynes@991: #define XORQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 6, imm, r1) nkeynes@991: #define XORQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x31, r1, r2) nkeynes@991: nkeynes@991: /* Control flow */ nkeynes@991: #define CALL_rel(rel) OP(0xE8); OP32(rel) nkeynes@991: #define CALL_imm32(ptr) x86_encode_r32_mem32disp32(0xFF, 2, -1, ptr) nkeynes@991: #define CALL_r32(r1) x86_encode_r32_rm32(0xFF, 2, r1) nkeynes@991: #define CALL_r32disp(r1,disp) x86_encode_r32_mem32disp32(0xFF, 2, r1, disp) nkeynes@991: nkeynes@991: #define JCC_cc_rel8(cc,rel) OP(0x70+(cc)); OP(rel) nkeynes@991: #define JCC_cc_rel32(cc,rel) OP(0x0F); OP(0x80+(cc)); OP32(rel) nkeynes@991: #define JCC_cc_rel(cc,rel) if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)rel); } else { JCC_cc_rel32(cc,rel); } nkeynes@991: nkeynes@991: #define JMP_rel8(rel) OP(0xEB); OP(rel) nkeynes@991: #define JMP_rel32(rel) OP(0xE9); OP32(rel) nkeynes@991: #define JMP_rel(rel) if( IS_INT8(rel) ) { JMP_rel8((int8_t)rel); } else { JMP_rel32(rel); } nkeynes@991: #define JMP_prerel(rel) if( IS_INT8(((int32_t)rel)-2) ) { JMP_rel8(((int8_t)rel)-2); } else { JMP_rel32(((int32_t)rel)-5); } nkeynes@991: #define JMP_r32(r1,disp) x86_encode_r32_rm32(0xFF, 4, r1) nkeynes@991: #define JMP_r32disp(r1,disp) x86_encode_r32_mem32disp32(0xFF, 4, r1, disp) nkeynes@991: #define RET() OP(0xC3) nkeynes@991: #define RET_imm(imm) OP(0xC2); OP16(imm) nkeynes@991: nkeynes@991: nkeynes@991: /* x87 Floating point instructions */ nkeynes@991: #define FABS_st0() OP(0xD9); OP(0xE1) nkeynes@991: #define FADDP_st(st) OP(0xDE); OP(0xC0+(st)) nkeynes@991: #define FCHS_st0() OP(0xD9); OP(0xE0) nkeynes@991: #define FCOMIP_st(st) OP(0xDF); OP(0xF0+(st)) nkeynes@991: #define FDIVP_st(st) OP(0xDE); OP(0xF8+(st)) nkeynes@991: #define FILD_r32disp(r32, disp) x86_encode_r32_mem32disp32(0xDB, 0, r32, disp) nkeynes@991: #define FLD0_st0() OP(0xD9); OP(0xEE); nkeynes@991: #define FLD1_st0() OP(0xD9); OP(0xE8); nkeynes@991: #define FLDCW_r32disp(r32, disp) x86_encode_r32_mem32disp32(0xD9, 5, r32, disp) nkeynes@991: #define FMULP_st(st) OP(0xDE); OP(0xC8+(st)) nkeynes@991: #define FNSTCW_r32disp(r32, disp) x86_encode_r32_mem32disp32(0xD9, 7, r32, disp) nkeynes@991: #define FPOP_st() OP(0xDD); OP(0xC0); OP(0xD9); OP(0xF7) nkeynes@991: #define FSUBP_st(st) OP(0xDE); OP(0xE8+(st)) nkeynes@991: #define FSQRT_st0() OP(0xD9); OP(0xFA) nkeynes@991: nkeynes@991: #define FILD_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDB, 0, disp) nkeynes@991: #define FLDF_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xD9, 0, disp) nkeynes@991: #define FLDD_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDD, 0, disp) nkeynes@991: #define FISTP_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDB, 3, disp) nkeynes@991: #define FSTPF_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xD9, 3, disp) nkeynes@991: #define FSTPD_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDD, 3, disp) nkeynes@991: nkeynes@991: nkeynes@991: /* SSE Packed floating point instructions */ nkeynes@991: #define ADDPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F58, r1, disp) nkeynes@991: #define ADDPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F58, r2, r1) nkeynes@991: #define ANDPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F54, r1, disp) nkeynes@991: #define ANDPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F54, r2, r1) nkeynes@991: #define ANDNPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F55, r1, disp) nkeynes@991: #define ANDNPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F55, r2, r1) nkeynes@991: #define CMPPS_cc_rbpdisp_xmm(cc,d,r) x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc) nkeynes@991: #define CMPPS_cc_xmm_xmm(cc,r1,r2) x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc) nkeynes@991: #define DIVPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5E, r1, disp) nkeynes@991: #define DIVPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5E, r2, r1) nkeynes@991: #define MAXPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5F, r1, disp) nkeynes@991: #define MAXPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5F, r2, r1) nkeynes@991: #define MINPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5D, r1, disp) nkeynes@991: #define MINPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5D, r2, r1) nkeynes@991: #define MOV_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F28, r2, r1) nkeynes@991: #define MOVAPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F28, r1, disp) nkeynes@991: #define MOVAPS_xmm_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x0F29, r1, disp) nkeynes@991: #define MOVHLPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F12, r2, r1) nkeynes@991: #define MOVHPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F16, r1, disp) nkeynes@991: #define MOVHPS_xmm_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x0F17, r1, disp) nkeynes@991: #define MOVLHPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F16, r2, r1) nkeynes@991: #define MOVLPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F12, r1, disp) nkeynes@991: #define MOVLPS_xmm_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x0F13, r1, disp) nkeynes@991: #define MOVUPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F10, r1, disp) nkeynes@991: #define MOVUPS_xmm_rbpdisp(disp,r1) x86_encode_r32_rbpdisp32(0x0F11, r1, disp) nkeynes@991: #define MULPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F59, r2, r1) nkeynes@991: #define MULPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0xF59, r1, disp) nkeynes@991: #define ORPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F56, r1, disp) nkeynes@991: #define ORPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F56, r2, r1) nkeynes@991: #define RCPPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0xF53, r1, disp) nkeynes@991: #define RCPPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F53, r2, r1) nkeynes@991: #define RSQRTPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F52, r1, disp) nkeynes@991: #define RSQRTPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F52, r2, r1) nkeynes@991: #define SHUFPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0FC6, r1, disp) nkeynes@991: #define SHUFPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0FC6, r2, r1) nkeynes@991: #define SQRTPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F51, r1, disp) nkeynes@991: #define SQRTPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F51, r2, r1) nkeynes@991: #define SUBPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5C, r1, disp) nkeynes@991: #define SUBPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5C, r2, r1) nkeynes@991: #define UNPCKHPS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F15, r1, disp) nkeynes@991: #define UNPCKHPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F15, r2, r1) nkeynes@991: #define UNPCKLPS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F14, r1, disp) nkeynes@991: #define UNPCKLPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F14, r2, r1) nkeynes@991: #define XORPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F57, r1, disp) nkeynes@991: #define XORPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F57, r2, r1) nkeynes@991: nkeynes@991: /* SSE Scalar floating point instructions */ nkeynes@991: #define ADDSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F58, r1, disp) nkeynes@991: #define ADDSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F58, r2, r1) nkeynes@991: #define CMPSS_cc_rbpdisp_xmm(cc,d,r) OP(0xF3); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc) nkeynes@991: #define CMPSS_cc_xmm_xmm(cc,r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc) nkeynes@991: #define COMISS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F2F, r1, disp) nkeynes@991: #define COMISS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F2F, r2, r1) nkeynes@991: #define DIVSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp) nkeynes@991: #define DIVSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5E, r2, r1) nkeynes@991: #define MAXSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp) nkeynes@991: #define MAXSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5F, r2, r1) nkeynes@991: #define MINSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp) nkeynes@991: #define MINSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5D, r2, r1) nkeynes@991: #define MOVSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F10, r1, disp) nkeynes@991: #define MOVSS_xmm_rbpdisp(r1,disp) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F11, r1, disp) nkeynes@991: #define MOVSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F10, r2, r1) nkeynes@991: #define MULSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0xF59, r1, disp) nkeynes@991: #define MULSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F59, r2, r1) nkeynes@991: #define RCPSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0xF53, r1, disp) nkeynes@991: #define RCPSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F53, r2, r1) nkeynes@991: #define RSQRTSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F52, r1, disp) nkeynes@991: #define RSQRTSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F52, r2, r1) nkeynes@991: #define SQRTSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F51, r1, disp) nkeynes@991: #define SQRTSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F51, r2, r1) nkeynes@991: #define SUBSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp) nkeynes@991: #define SUBSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5C, r2, r1) nkeynes@991: #define UCOMISS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F2E, r1, dsp) nkeynes@991: #define UCOMISS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F2E, r2, r1) nkeynes@991: nkeynes@991: /* SSE2 Packed floating point instructions */ nkeynes@991: #define ADDPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F58, r1, disp) nkeynes@991: #define ADDPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F58, r2, r1) nkeynes@991: #define ANDPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F54, r1, disp) nkeynes@991: #define ANDPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F54, r2, r1) nkeynes@991: #define ANDNPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F55, r1, disp) nkeynes@991: #define ANDNPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F55, r2, r1) nkeynes@991: #define CMPPD_cc_rbpdisp_xmm(cc,d,r) OP(0x66); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc) nkeynes@991: #define CMPPD_cc_xmm_xmm(cc,r1,r2) OP(0x66); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc) nkeynes@991: #define CVTPD2PS_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5A, r1, disp) nkeynes@991: #define CVTPD2PS_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5A, r2, r1) nkeynes@991: #define CVTPS2PD_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F5A, r1, disp) nkeynes@991: #define CVTPS2PD_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5A, r2, r1) nkeynes@991: #define DIVPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp) nkeynes@991: #define DIVPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5E, r2, r1) nkeynes@991: #define MAXPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp) nkeynes@991: #define MAXPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5F, r2, r1) nkeynes@991: #define MINPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp) nkeynes@991: #define MINPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5D, r2, r1) nkeynes@991: #define MOVHPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F16, r1, disp) nkeynes@991: #define MOVHPD_xmm_rbpdisp(r1,disp) OP(0x66); x86_encode_r32_rbpdisp32(0x0F17, r1, disp) nkeynes@991: #define MOVLPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F12, r1, disp) nkeynes@991: #define MOVLPD_xmm_rbpdisp(r1,disp) OP(0x66); x86_encode_r32_rbpdisp32(0x0F13, r1, disp) nkeynes@991: #define MULPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0xF59, r1, disp) nkeynes@991: #define MULPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F59, r2, r1) nkeynes@991: #define ORPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F56, r1, disp) nkeynes@991: #define ORPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F56, r2, r1) nkeynes@991: #define SHUFPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0FC6, r1, disp) nkeynes@991: #define SHUFPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0FC6, r2, r1) nkeynes@991: #define SUBPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp) nkeynes@991: #define SUBPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5C, r2, r1) nkeynes@991: #define UNPCKHPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F15, r1, disp) nkeynes@991: #define UNPCKHPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F15, r2, r1) nkeynes@991: #define UNPCKLPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F14, r1, disp) nkeynes@991: #define UNPCKLPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F14, r2, r1) nkeynes@991: #define XORPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F57, r1, disp) nkeynes@991: #define XORPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F57, r2, r1) nkeynes@991: nkeynes@991: nkeynes@991: /* SSE2 Scalar floating point instructions */ nkeynes@991: #define ADDSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F58, r1, disp) nkeynes@991: #define ADDSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F58, r2, r1) nkeynes@991: #define CMPSD_cc_rbpdisp_xmm(cc,d,r) OP(0xF2); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc) nkeynes@991: #define CMPSD_cc_xmm_xmm(cc,r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc) nkeynes@991: #define COMISD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F2F, r1, disp) nkeynes@991: #define COMISD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F2F, r2, r1) nkeynes@991: #define DIVSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp) nkeynes@991: #define DIVSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5E, r2, r1) nkeynes@991: #define MAXSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp) nkeynes@991: #define MAXSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5F, r2, r1) nkeynes@991: #define MINSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp) nkeynes@991: #define MINSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5D, r2, r1) nkeynes@991: #define MOVSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F10, r1, disp) nkeynes@991: #define MOVSD_xmm_rbpdisp(r1,disp) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F11, r1, disp) nkeynes@991: #define MOVSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F10, r2, r1) nkeynes@991: #define MULSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0xF59, r1, disp) nkeynes@991: #define MULSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F59, r2, r1) nkeynes@991: #define SQRTSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F51, r1, disp) nkeynes@991: #define SQRTSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F51, r2, r1) nkeynes@991: #define SUBSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp) nkeynes@991: #define SUBSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5C, r2, r1) nkeynes@991: #define UCOMISD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F2E, r1, dsp) nkeynes@991: #define UCOMISD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F2E, r2, r1) nkeynes@991: nkeynes@991: /* SSE3 floating point instructions */ nkeynes@991: #define ADDSUBPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0FD0, r1, dsp) nkeynes@991: #define ADDSUBPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0FD0, r2, r1) nkeynes@991: #define ADDSUBPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0FD0, r1, dsp) nkeynes@991: #define ADDSUBPS_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0FD0, r2, r1) nkeynes@991: #define HADDPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F7C, r1, dsp) nkeynes@991: #define HADDPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F7C, r2, r1) nkeynes@991: #define HADDPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F7C, r1, dsp) nkeynes@991: #define HADDPS_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F7C, r2, r1) nkeynes@991: #define HSUBPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F7D, r1, dsp) nkeynes@991: #define HSUBPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F7D, r2, r1) nkeynes@991: #define HSUBPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F7D, r1, dsp) nkeynes@991: #define HSUBPS_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F7D, r2, r1) nkeynes@991: #define MOVSHDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F16, r1, dsp) nkeynes@991: #define MOVSHDUP_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F16, r2, r1) nkeynes@991: #define MOVSLDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F12, r1, dsp) nkeynes@991: #define MOVSLDUP_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F12, r2, r1) nkeynes@995: nkeynes@995: /************************ Import calling conventions *************************/ nkeynes@995: #if SIZEOF_VOID_P == 8 nkeynes@995: #include "xlat/x86/amd64abi.h" nkeynes@995: #else /* 32-bit system */ nkeynes@995: #include "xlat/x86/ia32abi.h" nkeynes@995: #endif nkeynes@995: nkeynes@995: #endif /* !lxdream_x86op_H */