nkeynes@991 | 1 | /**
|
nkeynes@991 | 2 | * $Id$
|
nkeynes@991 | 3 | *
|
nkeynes@995 | 4 | * x86/x86-64 Instruction generator
|
nkeynes@991 | 5 | *
|
nkeynes@991 | 6 | * Copyright (c) 2009 Nathan Keynes.
|
nkeynes@991 | 7 | *
|
nkeynes@991 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@991 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@991 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@991 | 11 | * (at your option) any later version.
|
nkeynes@991 | 12 | *
|
nkeynes@991 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@991 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@991 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@991 | 16 | * GNU General Public License for more details.
|
nkeynes@991 | 17 | */
|
nkeynes@995 | 18 |
|
nkeynes@995 | 19 | #ifndef lxdream_x86op_H
|
nkeynes@995 | 20 | #define lxdream_x86op_H
|
nkeynes@995 | 21 |
|
nkeynes@991 | 22 | #include <stdint.h>
|
nkeynes@991 | 23 | #include <assert.h>
|
nkeynes@991 | 24 |
|
nkeynes@991 | 25 | /******************************** Constants *****************************/
|
nkeynes@991 | 26 |
|
nkeynes@991 | 27 | #define REG_NONE -1
|
nkeynes@991 | 28 |
|
nkeynes@991 | 29 | /* 64-bit general-purpose regs */
|
nkeynes@991 | 30 | #define REG_RAX 0
|
nkeynes@991 | 31 | #define REG_RCX 1
|
nkeynes@991 | 32 | #define REG_RDX 2
|
nkeynes@991 | 33 | #define REG_RBX 3
|
nkeynes@991 | 34 | #define REG_RSP 4
|
nkeynes@991 | 35 | #define REG_RBP 5
|
nkeynes@991 | 36 | #define REG_RSI 6
|
nkeynes@991 | 37 | #define REG_RDI 7
|
nkeynes@991 | 38 | #define REG_R8 8
|
nkeynes@991 | 39 | #define REG_R9 9
|
nkeynes@991 | 40 | #define REG_R10 10
|
nkeynes@991 | 41 | #define REG_R11 11
|
nkeynes@991 | 42 | #define REG_R12 12
|
nkeynes@991 | 43 | #define REG_R13 13
|
nkeynes@991 | 44 | #define REG_R14 14
|
nkeynes@991 | 45 | #define REG_R15 15
|
nkeynes@991 | 46 |
|
nkeynes@991 | 47 | /* 32-bit general-purpose regs */
|
nkeynes@991 | 48 | #define REG_EAX 0
|
nkeynes@991 | 49 | #define REG_ECX 1
|
nkeynes@991 | 50 | #define REG_EDX 2
|
nkeynes@991 | 51 | #define REG_EBX 3
|
nkeynes@991 | 52 | #define REG_ESP 4
|
nkeynes@991 | 53 | #define REG_EBP 5
|
nkeynes@991 | 54 | #define REG_ESI 6
|
nkeynes@991 | 55 | #define REG_EDI 7
|
nkeynes@991 | 56 | #define REG_R8D 8
|
nkeynes@991 | 57 | #define REG_R9D 9
|
nkeynes@991 | 58 | #define REG_R10D 10
|
nkeynes@991 | 59 | #define REG_R11D 11
|
nkeynes@991 | 60 | #define REG_R12D 12
|
nkeynes@991 | 61 | #define REG_R13D 13
|
nkeynes@991 | 62 | #define REG_R14D 14
|
nkeynes@991 | 63 | #define REG_R15D 15
|
nkeynes@991 | 64 |
|
nkeynes@991 | 65 | /* 8-bit general-purpose regs (no-rex prefix) */
|
nkeynes@991 | 66 | #define REG_AL 0
|
nkeynes@991 | 67 | #define REG_CL 1
|
nkeynes@991 | 68 | #define REG_DL 2
|
nkeynes@991 | 69 | #define REG_BL 3
|
nkeynes@991 | 70 | #define REG_AH 4
|
nkeynes@991 | 71 | #define REG_CH 5
|
nkeynes@991 | 72 | #define REG_DH 6
|
nkeynes@991 | 73 | #define REG_BH 7
|
nkeynes@991 | 74 |
|
nkeynes@991 | 75 | /* 8-bit general-purpose regs (rex-prefix) */
|
nkeynes@991 | 76 | #define REG_SPL 4
|
nkeynes@991 | 77 | #define REG_BPL 5
|
nkeynes@991 | 78 | #define REG_SIL 6
|
nkeynes@991 | 79 | #define REG_DIL 7
|
nkeynes@991 | 80 | #define REG_R8L 8
|
nkeynes@991 | 81 | #define REG_R9L 9
|
nkeynes@991 | 82 | #define REG_R10L 10
|
nkeynes@991 | 83 | #define REG_R11L 11
|
nkeynes@991 | 84 | #define REG_R12L 12
|
nkeynes@991 | 85 | #define REG_R13L 13
|
nkeynes@991 | 86 | #define REG_R14L 14
|
nkeynes@991 | 87 | #define REG_R15L 15
|
nkeynes@991 | 88 |
|
nkeynes@991 | 89 | /* Condition flag variants */
|
nkeynes@991 | 90 | #define X86_COND_O 0x00 /* OF=1 */
|
nkeynes@991 | 91 | #define X86_COND_NO 0x01 /* OF=0 */
|
nkeynes@991 | 92 | #define X86_COND_B 0x02 /* CF=1 */
|
nkeynes@991 | 93 | #define X86_COND_C 0x02 /* CF=1 */
|
nkeynes@991 | 94 | #define X86_CONF_NAE 0x02 /* CF=1 */
|
nkeynes@991 | 95 | #define X86_COND_AE 0x03 /* CF=0 */
|
nkeynes@991 | 96 | #define X86_COND_NB 0x03 /* CF=0 */
|
nkeynes@991 | 97 | #define X86_COND_NC 0x03 /* CF=0 */
|
nkeynes@991 | 98 | #define X86_COND_E 0x04 /* ZF=1 */
|
nkeynes@991 | 99 | #define X86_COND_Z 0x04 /* ZF=1 */
|
nkeynes@991 | 100 | #define X86_COND_NE 0x05 /* ZF=0 */
|
nkeynes@991 | 101 | #define X86_COND_NZ 0x05 /* ZF=0 */
|
nkeynes@991 | 102 | #define X86_COND_BE 0x06 /* CF=1 || ZF=1 */
|
nkeynes@991 | 103 | #define X86_COND_NA 0x06 /* CF=1 || ZF=1 */
|
nkeynes@991 | 104 | #define X86_COND_A 0x07 /* CF=0 && ZF=0 */
|
nkeynes@991 | 105 | #define X86_COND_NBE 0x07 /* CF=0 && ZF=0 */
|
nkeynes@991 | 106 | #define X86_COND_S 0x08 /* SF=1 */
|
nkeynes@991 | 107 | #define X86_COND_NS 0x09 /* SF=0 */
|
nkeynes@991 | 108 | #define X86_COND_P 0x0A /* PF=1 */
|
nkeynes@991 | 109 | #define X86_COND_PE 0x0A /* PF=1 */
|
nkeynes@991 | 110 | #define X86_COND_NP 0x0B /* PF=0 */
|
nkeynes@991 | 111 | #define X86_COND_PO 0x0B /* PF=0 */
|
nkeynes@991 | 112 | #define X86_COND_L 0x0C /* SF!=OF */
|
nkeynes@991 | 113 | #define X86_COND_NGE 0x0C /* SF!=OF */
|
nkeynes@991 | 114 | #define X86_COND_GE 0x0D /* SF=OF */
|
nkeynes@991 | 115 | #define X86_COND_NL 0x0D /* SF=OF */
|
nkeynes@991 | 116 | #define X86_COND_LE 0x0E /* ZF=1 || SF!=OF */
|
nkeynes@991 | 117 | #define X86_COND_NG 0x0E /* ZF=1 || SF!=OF */
|
nkeynes@991 | 118 | #define X86_COND_G 0x0F /* ZF=0 && SF=OF */
|
nkeynes@991 | 119 | #define X86_COND_NLE 0x0F /* ZF=0 && SF=OF */
|
nkeynes@991 | 120 |
|
nkeynes@991 | 121 | /* SSE floating pointer comparison variants */
|
nkeynes@991 | 122 | #define SSE_CMP_EQ 0x00
|
nkeynes@991 | 123 | #define SSE_CMP_LT 0x01
|
nkeynes@991 | 124 | #define SSE_CMP_LE 0x02
|
nkeynes@991 | 125 | #define SSE_CMP_UNORD 0x03
|
nkeynes@991 | 126 | #define SSE_CMP_NE 0x04
|
nkeynes@991 | 127 | #define SSE_CMP_NLT 0x05
|
nkeynes@991 | 128 | #define SSE_CMP_NLE 0x06
|
nkeynes@991 | 129 | #define SSE_CMP_ORD 0x07
|
nkeynes@991 | 130 |
|
nkeynes@991 | 131 | /************************** Internal definitions ***************************/
|
nkeynes@991 | 132 | #define PREF_REXB 0x41
|
nkeynes@991 | 133 | #define PREF_REXX 0x42
|
nkeynes@991 | 134 | #define PREF_REXR 0x44
|
nkeynes@991 | 135 | #define PREF_REXW 0x48
|
nkeynes@991 | 136 |
|
nkeynes@995 | 137 | /* PREF_REXW if required for pointer operations, otherwise 0 */
|
nkeynes@995 | 138 | #define PREF_PTR ((sizeof(void *) == 8) ? PREF_REXW : 0)
|
nkeynes@995 | 139 |
|
nkeynes@991 | 140 | extern unsigned char *xlat_output;
|
nkeynes@991 | 141 |
|
nkeynes@991 | 142 | #define OP(x) *xlat_output++ = (x)
|
nkeynes@991 | 143 | #define OP16(x) *((uint16_t *)xlat_output) = (x); xlat_output+=2
|
nkeynes@991 | 144 | #define OP32(x) *((uint32_t *)xlat_output) = (x); xlat_output+=4
|
nkeynes@991 | 145 | #define OP64(x) *((uint64_t *)xlat_output) = (x); xlat_output+=8
|
nkeynes@991 | 146 | #define OPPTR(x) *((void **)xlat_output) = ((void *)x); xlat_output+=(sizeof(void*))
|
nkeynes@991 | 147 |
|
nkeynes@991 | 148 | /* Primary opcode emitter, eg OPCODE(0x0FBE) for MOVSX */
|
nkeynes@1071 | 149 | #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 | 150 |
|
nkeynes@991 | 151 | /* Test if immediate value is representable as a signed 8-bit integer */
|
nkeynes@991 | 152 | #define IS_INT8(imm) ((imm) >= INT8_MIN && (imm) <= INT8_MAX)
|
nkeynes@991 | 153 |
|
nkeynes@991 | 154 | /**
|
nkeynes@991 | 155 | * Encode opcode+reg with no mod/rm (eg MOV imm64, r32)
|
nkeynes@991 | 156 | */
|
nkeynes@1147 | 157 | static inline void x86_encode_opcodereg( int rexw, uint32_t opcode, int reg )
|
nkeynes@991 | 158 | {
|
nkeynes@991 | 159 | int rex = rexw;
|
nkeynes@991 | 160 | reg &= 0x0F;
|
nkeynes@991 | 161 | if( reg >= 8 ) {
|
nkeynes@991 | 162 | rex |= PREF_REXB;
|
nkeynes@991 | 163 | reg -= 8;
|
nkeynes@991 | 164 | }
|
nkeynes@991 | 165 | if( rex != 0 ) {
|
nkeynes@991 | 166 | OP(rex);
|
nkeynes@991 | 167 | }
|
nkeynes@991 | 168 | OPCODE(opcode + reg);
|
nkeynes@991 | 169 | }
|
nkeynes@991 | 170 |
|
nkeynes@991 | 171 | /**
|
nkeynes@991 | 172 | * Encode opcode with mod/rm reg-reg operation.
|
nkeynes@991 | 173 | * @param opcode primary instruction opcode
|
nkeynes@991 | 174 | * @param rr reg field
|
nkeynes@991 | 175 | * @param rb r/m field
|
nkeynes@991 | 176 | */
|
nkeynes@1147 | 177 | static inline void x86_encode_reg_rm( int rexw, uint32_t opcode, int rr, int rb )
|
nkeynes@991 | 178 | {
|
nkeynes@991 | 179 | int rex = rexw;
|
nkeynes@991 | 180 | rr &= 0x0F;
|
nkeynes@991 | 181 | rb &= 0x0F;
|
nkeynes@991 | 182 | if( rr >= 8 ) {
|
nkeynes@991 | 183 | rex |= PREF_REXR;
|
nkeynes@991 | 184 | rr -= 8;
|
nkeynes@991 | 185 | }
|
nkeynes@991 | 186 | if( rb >= 8 ) {
|
nkeynes@991 | 187 | rex |= PREF_REXB;
|
nkeynes@991 | 188 | rb -= 8;
|
nkeynes@991 | 189 | }
|
nkeynes@991 | 190 | if( rex != 0 ) {
|
nkeynes@991 | 191 | OP(rex);
|
nkeynes@991 | 192 | }
|
nkeynes@991 | 193 | OPCODE(opcode);
|
nkeynes@991 | 194 | OP(0xC0|(rr<<3)|rb);
|
nkeynes@991 | 195 | }
|
nkeynes@991 | 196 |
|
nkeynes@991 | 197 | /**
|
nkeynes@991 | 198 | * Encode opcode + 32-bit mod/rm memory address. (RIP-relative not supported here)
|
nkeynes@991 | 199 | * @param rexw REX.W prefix is required, otherwise 0
|
nkeynes@991 | 200 | * @param rr Reg-field register (required).
|
nkeynes@991 | 201 | * @param rb Base (unscaled) register, or -1 for no base register.
|
nkeynes@991 | 202 | * @param rx Index (scaled) register, or -1 for no index register
|
nkeynes@991 | 203 | * @param ss Scale shift (0..3) applied to index register (ignored if no index register)
|
nkeynes@991 | 204 | * @param disp32 Signed displacement (0 for none)
|
nkeynes@991 | 205 | */
|
nkeynes@1147 | 206 | static inline void FORCEINLINE x86_encode_modrm( int rexw, uint32_t opcode, int rr, int rb, int rx, int ss, int32_t disp32 )
|
nkeynes@991 | 207 | {
|
nkeynes@991 | 208 | /* Construct the rex prefix where necessary */
|
nkeynes@991 | 209 | int rex = rexw;
|
nkeynes@991 | 210 | rr &= 0x0F;
|
nkeynes@991 | 211 | if( rr >= 8 ) {
|
nkeynes@991 | 212 | rex |= PREF_REXR;
|
nkeynes@991 | 213 | rr -= 8;
|
nkeynes@991 | 214 | }
|
nkeynes@991 | 215 | if( rb != -1 ) {
|
nkeynes@991 | 216 | rb &= 0x0F;
|
nkeynes@991 | 217 | if( rb >= 8 ) {
|
nkeynes@991 | 218 | rex |= PREF_REXB;
|
nkeynes@991 | 219 | rb -= 8;
|
nkeynes@991 | 220 | }
|
nkeynes@991 | 221 | }
|
nkeynes@991 | 222 | if( rx != -1 ) {
|
nkeynes@991 | 223 | rx &= 0x0F;
|
nkeynes@991 | 224 | if( rx >= 8 ) {
|
nkeynes@991 | 225 | rex |= PREF_REXX;
|
nkeynes@991 | 226 | rx -= 8;
|
nkeynes@991 | 227 | }
|
nkeynes@991 | 228 | }
|
nkeynes@991 | 229 |
|
nkeynes@991 | 230 | if( rex != 0 ) {
|
nkeynes@991 | 231 | OP(rex);
|
nkeynes@991 | 232 | }
|
nkeynes@991 | 233 | OPCODE(opcode);
|
nkeynes@991 | 234 |
|
nkeynes@991 | 235 | if( rx == -1 ) {
|
nkeynes@991 | 236 | if( rb == -1 ) {
|
nkeynes@991 | 237 | /* [disp32] displacement only - use SIB form for 64-bit mode safety */
|
nkeynes@991 | 238 | OP(0x04|(rr<<3));
|
nkeynes@991 | 239 | OP(0x25);
|
nkeynes@991 | 240 | OP32(disp32);
|
nkeynes@991 | 241 | } else if( rb == REG_ESP ) { /* [%esp + disp32] - SIB is mandatory for %esp/%r12 encodings */
|
nkeynes@991 | 242 | if( disp32 == 0 ) {
|
nkeynes@991 | 243 | OP(0x04|(rr<<3));
|
nkeynes@991 | 244 | OP(0x24);
|
nkeynes@991 | 245 | } else if( IS_INT8(disp32) ) {
|
nkeynes@991 | 246 | OP(0x44|(rr<<3));
|
nkeynes@991 | 247 | OP(0x24);
|
nkeynes@991 | 248 | OP((int8_t)disp32);
|
nkeynes@991 | 249 | } else {
|
nkeynes@991 | 250 | OP(0x84|(rr<<3));
|
nkeynes@991 | 251 | OP(0x24);
|
nkeynes@991 | 252 | OP32(disp32);
|
nkeynes@991 | 253 | }
|
nkeynes@991 | 254 | } else {
|
nkeynes@991 | 255 | if( disp32 == 0 && rb != REG_EBP ) { /* [%ebp] is encoded as [%ebp+0] */
|
nkeynes@991 | 256 | OP((rr<<3)|rb);
|
nkeynes@991 | 257 | } else if( IS_INT8(disp32) ) {
|
nkeynes@991 | 258 | OP(0x40|(rr<<3)|rb);
|
nkeynes@991 | 259 | OP((int8_t)disp32);
|
nkeynes@991 | 260 | } else {
|
nkeynes@991 | 261 | OP(0x80|(rr<<3)|rb);
|
nkeynes@991 | 262 | OP32(disp32);
|
nkeynes@991 | 263 | }
|
nkeynes@991 | 264 | }
|
nkeynes@991 | 265 | } else { /* We have a scaled index. Goody */
|
nkeynes@991 | 266 | assert( ((rx != REG_ESP) || (rex&PREF_REXX)) && "Bug: attempt to index through %esp" ); /* Indexing by %esp is impossible */
|
nkeynes@991 | 267 | if( rb == -1 ) { /* [disp32 + rx << ss] */
|
nkeynes@991 | 268 | OP(0x04|(rr<<3));
|
nkeynes@991 | 269 | OP(0x05|(ss<<6)|(rx<<3));
|
nkeynes@991 | 270 | OP32(disp32);
|
nkeynes@991 | 271 | } else if( disp32 == 0 && rb != REG_EBP ) { /* [rb + rx << ss]. (Again, %ebp needs to be %ebp+0) */
|
nkeynes@991 | 272 | OP(0x04|(rr<<3));
|
nkeynes@991 | 273 | OP((ss<<6)|(rx<<3)|rb);
|
nkeynes@991 | 274 | } else if( IS_INT8(disp32) ) {
|
nkeynes@991 | 275 | OP(0x44|(rr<<3));
|
nkeynes@991 | 276 | OP((ss<<6)|(rx<<3)|rb);
|
nkeynes@991 | 277 | OP((int8_t)disp32);
|
nkeynes@991 | 278 | } else {
|
nkeynes@991 | 279 | OP(0x84|(rr<<3));
|
nkeynes@991 | 280 | OP((ss<<6)|(rx<<3)|rb);
|
nkeynes@991 | 281 | OP32(disp32);
|
nkeynes@991 | 282 | }
|
nkeynes@991 | 283 | }
|
nkeynes@991 | 284 | }
|
nkeynes@991 | 285 |
|
nkeynes@991 | 286 | /**
|
nkeynes@991 | 287 | * Encode opcode + RIP-relative mod/rm (64-bit mode only)
|
nkeynes@991 | 288 | * @param rexw PREF_REXW or 0
|
nkeynes@991 | 289 | * @param opcode primary instruction opcode
|
nkeynes@991 | 290 | * @param rr mod/rm reg field
|
nkeynes@991 | 291 | * @param disp32 RIP-relative displacement
|
nkeynes@991 | 292 | */
|
nkeynes@1147 | 293 | static inline void x86_encode_modrm_rip(int rexw, uint32_t opcode, int rr, int32_t disp32)
|
nkeynes@991 | 294 | {
|
nkeynes@991 | 295 | int rex = rexw;
|
nkeynes@991 | 296 | rr &= 0x0F;
|
nkeynes@991 | 297 | if( rr >= 8 ) {
|
nkeynes@991 | 298 | rex |= PREF_REXR;
|
nkeynes@991 | 299 | rr -= 8;
|
nkeynes@991 | 300 | }
|
nkeynes@991 | 301 | if( rex != 0 ) {
|
nkeynes@991 | 302 | OP(rex);
|
nkeynes@991 | 303 | }
|
nkeynes@991 | 304 | OPCODE(opcode);
|
nkeynes@991 | 305 | OP(0x05|(rr<<3));
|
nkeynes@991 | 306 | OP32(disp32);
|
nkeynes@991 | 307 | }
|
nkeynes@991 | 308 |
|
nkeynes@991 | 309 | /* 32/64-bit op emitters. 64-bit versions include a rex.w prefix. Note that any
|
nkeynes@991 | 310 | * other prefixes (mandatory or otherwise) need to be emitted prior to these
|
nkeynes@991 | 311 | * functions
|
nkeynes@991 | 312 | */
|
nkeynes@991 | 313 | #define x86_encode_opcode64(opcode,reg) x86_encode_opcodereg(PREF_REXW, opcode,reg)
|
nkeynes@991 | 314 | #define x86_encode_opcode32(opcode,reg) x86_encode_opcodereg(0,opcode,reg)
|
nkeynes@991 | 315 | #define x86_encode_r32_rm32(opcode,rr,rb) x86_encode_reg_rm(0,opcode,rr,rb)
|
nkeynes@991 | 316 | #define x86_encode_r64_rm64(opcode,rr,rb) x86_encode_reg_rm(PREF_REXW,opcode,rr,rb)
|
nkeynes@1112 | 317 | #define x86_encode_rptr_rmptr(opcode,rr,rb) x86_encode_reg_rm(PREF_PTR,opcode,rr,rb)
|
nkeynes@991 | 318 | #define x86_encode_r32_mem32(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(0,opcode,rr,rb,rx,ss,disp32)
|
nkeynes@991 | 319 | #define x86_encode_r64_mem64(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,rx,ss,disp32)
|
nkeynes@995 | 320 | #define x86_encode_rptr_memptr(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_PTR,opcode,rr,rb,rx,ss,disp32)
|
nkeynes@991 | 321 | #define x86_encode_r32_mem32disp32(opcode,rr,rb,disp32) x86_encode_modrm(0,opcode,rr,rb,-1,0,disp32)
|
nkeynes@991 | 322 | #define x86_encode_r64_mem64disp64(opcode,rr,rb,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,-1,0,disp32)
|
nkeynes@1176 | 323 | #define x86_encode_rptr_memptrdisp(opcode,rr,rb,disp32) x86_encode_modrm(PREF_PTR,opcode,rr,rb,-1,0,disp32)
|
nkeynes@991 | 324 | #define x86_encode_r32_ripdisp32(opcode,rr,disp32) x86_encode_modrm_rip(0,opcode,rr,disp32)
|
nkeynes@991 | 325 | #define x86_encode_r64_ripdisp64(opcode,rr,disp32) x86_encode_modrm_rip(PREF_REXW,opcode,rr,disp32)
|
nkeynes@991 | 326 |
|
nkeynes@991 | 327 | /* Convenience versions for the common rbp/rsp relative displacements */
|
nkeynes@991 | 328 | #define x86_encode_r32_rbpdisp32(opcode,rr,disp32) x86_encode_modrm(0,opcode,rr,REG_RBP,-1,0,disp32)
|
nkeynes@991 | 329 | #define x86_encode_r64_rbpdisp64(opcode,rr,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,REG_RBP,-1,0,disp32)
|
nkeynes@991 | 330 | #define x86_encode_r32_rspdisp32(opcode,rr,disp32) x86_encode_modrm(0,opcode,rr,REG_RSP,-1,0,disp32)
|
nkeynes@991 | 331 | #define x86_encode_r64_rspdisp64(opcode,rr,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,REG_RSP,-1,0,disp32)
|
nkeynes@991 | 332 |
|
nkeynes@991 | 333 | /* Immediate-selection variants (for instructions with imm8s/imm32 variants) */
|
nkeynes@991 | 334 | #define x86_encode_imms_rm32(opcode8,opcode32,reg,imm,rb) \
|
nkeynes@991 | 335 | if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rm32(opcode8,reg,rb); OP((int8_t)imm); \
|
nkeynes@991 | 336 | } else { x86_encode_r32_rm32(opcode32,reg,rb); OP32(imm); }
|
nkeynes@991 | 337 | #define x86_encode_imms_rm64(opcode8,opcode32,reg,imm,rb) \
|
nkeynes@991 | 338 | if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rm64(opcode8,reg,rb); OP((int8_t)imm); \
|
nkeynes@991 | 339 | } else { x86_encode_r64_rm64(opcode32,reg,rb); OP32(imm); }
|
nkeynes@995 | 340 | #define x86_encode_imms_rmptr(opcode8,opcode32,reg,imm,rb) \
|
nkeynes@995 | 341 | if( IS_INT8(((int32_t)imm)) ) { x86_encode_reg_rm( PREF_PTR, opcode8,reg,rb); OP((int8_t)imm); \
|
nkeynes@995 | 342 | } else { x86_encode_reg_rm( PREF_PTR, opcode32,reg,rb); OP32(imm); }
|
nkeynes@991 | 343 | #define x86_encode_imms_rbpdisp32(opcode8,opcode32,reg,imm,disp) \
|
nkeynes@991 | 344 | if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rbpdisp32(opcode8,reg,disp); OP((int8_t)imm); \
|
nkeynes@991 | 345 | } else { x86_encode_r32_rbpdisp32(opcode32,reg,disp); OP32(imm); }
|
nkeynes@991 | 346 | #define x86_encode_imms_r32disp32(opcode8,opcode32,reg,imm,rb,disp) \
|
nkeynes@991 | 347 | if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_mem32disp32(opcode8,reg,rb,disp); OP((int8_t)imm); \
|
nkeynes@991 | 348 | } else { x86_encode_r32_mem32disp32(opcode32,reg,rb,disp); OP32(imm); }
|
nkeynes@991 | 349 | #define x86_encode_imms_rbpdisp64(opcode8,opcode32,reg,imm,disp) \
|
nkeynes@991 | 350 | if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rbpdisp64(opcode8,reg,disp); OP((int8_t)imm); \
|
nkeynes@991 | 351 | } else { x86_encode_r64_rbpdisp64(opcode32,reg,disp); OP32(imm); }
|
nkeynes@991 | 352 |
|
nkeynes@991 | 353 | /*************************** Instruction definitions ***********************/
|
nkeynes@991 | 354 | /* Note this does not try to be an exhaustive definition of the instruction -
|
nkeynes@991 | 355 | * it generally only has the forms that we actually need here.
|
nkeynes@991 | 356 | */
|
nkeynes@991 | 357 | /* Core Integer instructions */
|
nkeynes@991 | 358 | #define ADCB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 2, r1); OP(imm)
|
nkeynes@991 | 359 | #define ADCB_r8_r8(r1,r2) x86_encode_r32_rm32(0x10, r1, r2)
|
nkeynes@991 | 360 | #define ADCL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 2, imm, r1)
|
nkeynes@991 | 361 | #define ADCL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83, 0x81, 2, imm, disp)
|
nkeynes@991 | 362 | #define ADCL_r32_r32(r1,r2) x86_encode_r32_rm32(0x11, r1, r2)
|
nkeynes@991 | 363 | #define ADCL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x11, r1, disp)
|
nkeynes@991 | 364 | #define ADCL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x13, r1, disp)
|
nkeynes@991 | 365 | #define ADCQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 2, imm, r1)
|
nkeynes@991 | 366 | #define ADCQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x11, r1, r2)
|
nkeynes@991 | 367 |
|
nkeynes@991 | 368 | #define ADDB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 0, r1); OP(imm)
|
nkeynes@991 | 369 | #define ADDB_r8_r8(r1,r2) x86_encode_r32_rm32(0x00, r1, r2)
|
nkeynes@991 | 370 | #define ADDL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 0, imm, r1)
|
nkeynes@991 | 371 | #define ADDL_imms_r32disp(imm,rb,d) x86_encode_imms_r32disp32(0x83, 0x81, 0, imm, rb, d)
|
nkeynes@991 | 372 | #define ADDL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83, 0x81, 0, imm, disp)
|
nkeynes@991 | 373 | #define ADDL_r32_r32(r1,r2) x86_encode_r32_rm32(0x01, r1, r2)
|
nkeynes@991 | 374 | #define ADDL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x01, r1, disp)
|
nkeynes@991 | 375 | #define ADDL_r32_r32disp(r1,r2,dsp) x86_encode_r32_mem32disp32(0x01, r1, r2, dsp)
|
nkeynes@991 | 376 | #define ADDL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x03, r1, disp)
|
nkeynes@991 | 377 | #define ADDQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 0, imm, r1)
|
nkeynes@991 | 378 | #define ADDQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x01, r1, r2)
|
nkeynes@991 | 379 |
|
nkeynes@991 | 380 | #define ANDB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 4, r1); OP(imm)
|
nkeynes@991 | 381 | #define ANDB_r8_r8(r1,r2) x86_encode_r32_rm32(0x20, r1, r2)
|
nkeynes@991 | 382 | #define ANDL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 4, imm, r1)
|
nkeynes@991 | 383 | #define ANDL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,4,imm,disp)
|
nkeynes@991 | 384 | #define ANDL_r32_r32(r1,r2) x86_encode_r32_rm32(0x21, r1, r2)
|
nkeynes@991 | 385 | #define ANDL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x21, r1, disp)
|
nkeynes@991 | 386 | #define ANDL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x23, r1, disp)
|
nkeynes@991 | 387 | #define ANDQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x21, r1, r2)
|
nkeynes@991 | 388 | #define ANDQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 4, imm, r1)
|
nkeynes@995 | 389 | #define ANDP_imms_rptr(imm,r1) x86_encode_imms_rmptr(0x83, 0x81, 4, imm, r1)
|
nkeynes@991 | 390 |
|
nkeynes@991 | 391 | #define CLC() OP(0xF8)
|
nkeynes@991 | 392 | #define CLD() OP(0xFC)
|
nkeynes@991 | 393 | #define CMC() OP(0xF5)
|
nkeynes@991 | 394 |
|
nkeynes@991 | 395 | #define CMOVCCL_cc_r32_r32(cc,r1,r2) x86_encode_r32_rm32(0x0F40+(cc), r2, r1)
|
nkeynes@991 | 396 | #define CMOVCCL_cc_rbpdisp_r32(cc,d,r1) x86_encode_r32_rbpdisp32(0x0F40+(cc), r1, d)
|
nkeynes@991 | 397 |
|
nkeynes@991 | 398 | #define CMPB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 7, r1); OP(imm)
|
nkeynes@991 | 399 | #define CMPB_imms_rbpdisp(imm,disp) x86_encode_r32_rbpdisp32(0x80, 7, disp); OP(imm)
|
nkeynes@991 | 400 | #define CMPB_r8_r8(r1,r2) x86_encode_r32_rm32(0x38, r1, r2)
|
nkeynes@991 | 401 | #define CMPL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 7, imm, r1)
|
nkeynes@1112 | 402 | #define CMPL_imms_r32disp(imm,rb,d) x86_encode_imms_r32disp32(0x83, 0x81, 7, imm, rb, d)
|
nkeynes@991 | 403 | #define CMPL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83, 0x81, 7, imm, disp)
|
nkeynes@991 | 404 | #define CMPL_r32_r32(r1,r2) x86_encode_r32_rm32(0x39, r1, r2)
|
nkeynes@1112 | 405 | #define CMPL_r32_r32disp(r1,r2,dsp) x86_encode_r32_mem32disp32(0x39, r1, r2, dsp)
|
nkeynes@991 | 406 | #define CMPL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x39, r1, disp)
|
nkeynes@991 | 407 | #define CMPL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x3B, r1, disp)
|
nkeynes@991 | 408 | #define CMPQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 7, imm, r1)
|
nkeynes@991 | 409 | #define CMPQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x39, r1, r2)
|
nkeynes@991 | 410 |
|
nkeynes@991 | 411 | #define IDIVL_r32(r1) x86_encode_r32_rm32(0xF7, 7, r1)
|
nkeynes@991 | 412 | #define IDIVL_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xF7, 7, disp)
|
nkeynes@991 | 413 | #define IDIVQ_r64(r1) x86_encode_r64_rm64(0xF7, 7, r1)
|
nkeynes@991 | 414 |
|
nkeynes@991 | 415 | #define IMULL_imms_r32(imm,r1) x86_encode_imms_rm32(0x6B,0x69, r1, imm, r1)
|
nkeynes@991 | 416 | #define IMULL_r32(r1) x86_encode_r32_rm32(0xF7, 5, r1)
|
nkeynes@991 | 417 | #define IMULL_r32_r32(r1,r2) x86_encode_r32_rm32(0x0FAF, r2, r1)
|
nkeynes@991 | 418 | #define IMULL_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xF7, 5, disp)
|
nkeynes@991 | 419 | #define IMULL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FAF, r1, disp)
|
nkeynes@991 | 420 | #define IMULL_rspdisp(disp) x86_encode_r32_rspdisp32(0xF7, 5, disp)
|
nkeynes@991 | 421 | #define IMULL_rspdisp_r32(disp,r1) x86_encode_r32_rspdisp32(0x0FAF, r1, disp)
|
nkeynes@991 | 422 | #define IMULQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x6B,0x69, r1, imm, r1)
|
nkeynes@991 | 423 | #define IMULQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x0FAF, r2, r1)
|
nkeynes@991 | 424 |
|
nkeynes@1191 | 425 | #define INC_r32(r1) x86_encode_r32_rm32(0xFF, 0, r1)
|
nkeynes@1191 | 426 |
|
nkeynes@991 | 427 | #define LEAL_r32disp_r32(r1,disp,r2) x86_encode_r32_mem32(0x8D, r2, r1, -1, 0, disp)
|
nkeynes@991 | 428 | #define LEAL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x8D, r1, disp)
|
nkeynes@991 | 429 | #define LEAL_sib_r32(ss,ii,bb,d,r1) x86_encode_r32_mem32(0x8D, r1, bb, ii, ss, d)
|
nkeynes@991 | 430 | #define LEAQ_r64disp_r64(r1,disp,r2) x86_encode_r64_mem64(0x8D, r2, r1, -1, 0, disp)
|
nkeynes@991 | 431 | #define LEAQ_rbpdisp_r64(disp,r1) x86_encode_r64_rbpdisp64(0x8D, r1, disp)
|
nkeynes@1112 | 432 | #define LEAP_rptrdisp_rptr(r1,d,r2) x86_encode_rptr_memptr(0x8D, r2, r1, -1, 0, d)
|
nkeynes@991 | 433 | #define LEAP_rbpdisp_rptr(disp,r1) x86_encode_rptr_memptr(0x8D, r1, REG_RBP, -1, 0, disp)
|
nkeynes@991 | 434 | #define LEAP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8D, r1, bb, ii, ss, d)
|
nkeynes@991 | 435 |
|
nkeynes@991 | 436 | #define MOVB_r8_r8(r1,r2) x86_encode_r32_rm32(0x88, r1, r2)
|
nkeynes@991 | 437 | #define MOVL_imm32_r32(i32,r1) x86_encode_opcode32(0xB8, r1); OP32(i32)
|
nkeynes@991 | 438 | #define MOVL_imm32_rbpdisp(i,disp) x86_encode_r32_rbpdisp32(0xC7,0,disp); OP32(i)
|
nkeynes@991 | 439 | #define MOVL_imm32_rspdisp(i,disp) x86_encode_r32_rspdisp32(0xC7,0,disp); OP32(i)
|
nkeynes@991 | 440 | #define MOVL_moffptr_eax(p) OP(0xA1); OPPTR(p)
|
nkeynes@991 | 441 | #define MOVL_r32_r32(r1,r2) x86_encode_r32_rm32(0x89, r1, r2)
|
nkeynes@991 | 442 | #define MOVL_r32_r32disp(r1,r2,dsp) x86_encode_r32_mem32disp32(0x89, r1, r2, dsp)
|
nkeynes@991 | 443 | #define MOVL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x89, r1, disp)
|
nkeynes@991 | 444 | #define MOVL_r32_rspdisp(r1,disp) x86_encode_r32_rspdisp32(0x89, r1, disp)
|
nkeynes@991 | 445 | #define MOVL_r32_sib(r1,ss,ii,bb,d) x86_encode_r32_mem32(0x89, r1, bb, ii, ss, d)
|
nkeynes@991 | 446 | #define MOVL_r32disp_r32(r1,dsp,r2) x86_encode_r32_mem32disp32(0x8B, r2, r1, dsp)
|
nkeynes@991 | 447 | #define MOVL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x8B, r1, disp)
|
nkeynes@991 | 448 | #define MOVL_rspdisp_r32(disp,r1) x86_encode_r32_rspdisp32(0x8B, r1, disp)
|
nkeynes@991 | 449 | #define MOVL_sib_r32(ss,ii,bb,d,r1) x86_encode_r32_mem32(0x8B, r1, bb, ii, ss, d)
|
nkeynes@991 | 450 | #define MOVQ_imm64_r64(i64,r1) x86_encode_opcode64(0xB8, r1); OP64(i64)
|
nkeynes@991 | 451 | #define MOVQ_moffptr_rax(p) OP(PREF_REXW); OP(0xA1); OPPTR(p)
|
nkeynes@991 | 452 | #define MOVQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x89, r1, r2)
|
nkeynes@991 | 453 | #define MOVQ_r64_rbpdisp(r1,disp) x86_encode_r64_rbpdisp64(0x89, r1, disp)
|
nkeynes@991 | 454 | #define MOVQ_r64_rspdisp(r1,disp) x86_encode_r64_rspdisp64(0x89, r1, disp)
|
nkeynes@991 | 455 | #define MOVQ_rbpdisp_r64(disp,r1) x86_encode_r64_rbpdisp64(0x8B, r1, disp)
|
nkeynes@991 | 456 | #define MOVQ_rspdisp_r64(disp,r1) x86_encode_r64_rspdisp64(0x8B, r1, disp)
|
nkeynes@995 | 457 | #define MOVP_immptr_rptr(p,r1) x86_encode_opcodereg( PREF_PTR, 0xB8, r1); OPPTR(p)
|
nkeynes@991 | 458 | #define MOVP_moffptr_rax(p) if( sizeof(void*)==8 ) { OP(PREF_REXW); } OP(0xA1); OPPTR(p)
|
nkeynes@995 | 459 | #define MOVP_rptr_rptr(r1,r2) x86_encode_reg_rm(PREF_PTR, 0x89, r1, r2)
|
nkeynes@991 | 460 | #define MOVP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8B, r1, bb, ii, ss, d)
|
nkeynes@1176 | 461 | #define MOVP_rptrdisp_rptr(r1,dsp,r2) x86_encode_rptr_memptrdisp(0x8B, r2, r1, dsp)
|
nkeynes@991 | 462 |
|
nkeynes@991 | 463 | #define MOVSXL_r8_r32(r1,r2) x86_encode_r32_rm32(0x0FBE, r2, r1)
|
nkeynes@991 | 464 | #define MOVSXL_r16_r32(r1,r2) x86_encode_r32_rm32(0x0FBF, r2, r1)
|
nkeynes@991 | 465 | #define MOVSXL_rbpdisp8_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FBE, r1, disp)
|
nkeynes@991 | 466 | #define MOVSXL_rbpdisp16_r32(dsp,r1) x86_encode_r32_rbpdisp32(0x0FBF, r1, dsp)
|
nkeynes@991 | 467 | #define MOVSXQ_imm32_r64(i32,r1) x86_encode_r64_rm64(0xC7, 0, r1); OP32(i32) /* Technically a MOV */
|
nkeynes@991 | 468 | #define MOVSXQ_r8_r64(r1,r2) x86_encode_r64_rm64(0x0FBE, r2, r1)
|
nkeynes@991 | 469 | #define MOVSXQ_r16_r64(r1,r2) x86_encode_r64_rm64(0x0FBF, r2, r1)
|
nkeynes@991 | 470 | #define MOVSXQ_r32_r64(r1,r2) x86_encode_r64_rm64(0x63, r2, r1)
|
nkeynes@991 | 471 | #define MOVSXQ_rbpdisp32_r64(dsp,r1) x86_encode_r64_rbpdisp64(0x63, r1, dsp)
|
nkeynes@991 | 472 |
|
nkeynes@991 | 473 | #define MOVZXL_r8_r32(r1,r2) x86_encode_r32_rm32(0x0FB6, r2, r1)
|
nkeynes@991 | 474 | #define MOVZXL_r16_r32(r1,r2) x86_encode_r32_rm32(0x0FB7, r2, r1)
|
nkeynes@991 | 475 | #define MOVZXL_rbpdisp8_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FB6, r1, disp)
|
nkeynes@991 | 476 | #define MOVZXL_rbpdisp16_r32(dsp,r1) x86_encode_r32_rbpdisp32(0x0FB7, r1, dsp)
|
nkeynes@991 | 477 |
|
nkeynes@991 | 478 | #define MULL_r32(r1) x86_encode_r32_rm32(0xF7, 4, r1)
|
nkeynes@991 | 479 | #define MULL_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xF7,4,disp)
|
nkeynes@991 | 480 | #define MULL_rspdisp(disp) x86_encode_r32_rspdisp32(0xF7,4,disp)
|
nkeynes@991 | 481 |
|
nkeynes@991 | 482 | #define NEGB_r8(r1) x86_encode_r32_rm32(0xF6, 3, r1)
|
nkeynes@991 | 483 | #define NEGL_r32(r1) x86_encode_r32_rm32(0xF7, 3, r1)
|
nkeynes@991 | 484 | #define NEGL_rbpdisp(r1) x86_encode_r32_rbspdisp32(0xF7, 3, disp)
|
nkeynes@991 | 485 | #define NEGQ_r64(r1) x86_encode_r64_rm64(0xF7, 3, r1)
|
nkeynes@991 | 486 |
|
nkeynes@1186 | 487 | #define NOP() OP(0x90)
|
nkeynes@1186 | 488 | #define NOP2() OP(0x66); OP(0x90)
|
nkeynes@1186 | 489 |
|
nkeynes@991 | 490 | #define NOTB_r8(r1) x86_encode_r32_rm32(0xF6, 2, r1)
|
nkeynes@991 | 491 | #define NOTL_r32(r1) x86_encode_r32_rm32(0xF7, 2, r1)
|
nkeynes@991 | 492 | #define NOTL_rbpdisp(r1) x86_encode_r32_rbspdisp32(0xF7, 2, disp)
|
nkeynes@991 | 493 | #define NOTQ_r64(r1) x86_encode_r64_rm64(0xF7, 2, r1)
|
nkeynes@991 | 494 |
|
nkeynes@991 | 495 | #define ORB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 1, r1); OP(imm)
|
nkeynes@991 | 496 | #define ORB_r8_r8(r1,r2) x86_encode_r32_rm32(0x08, r1, r2)
|
nkeynes@991 | 497 | #define ORL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 1, imm, r1)
|
nkeynes@991 | 498 | #define ORL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,1,imm,disp)
|
nkeynes@991 | 499 | #define ORL_r32_r32(r1,r2) x86_encode_r32_rm32(0x09, r1, r2)
|
nkeynes@991 | 500 | #define ORL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x09, r1, disp)
|
nkeynes@991 | 501 | #define ORL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0B, r1, disp)
|
nkeynes@991 | 502 | #define ORQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 1, imm, r1)
|
nkeynes@991 | 503 | #define ORQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x09, r1, r2)
|
nkeynes@991 | 504 |
|
nkeynes@991 | 505 | #define POP_r32(r1) x86_encode_opcode32(0x58, r1)
|
nkeynes@991 | 506 |
|
nkeynes@991 | 507 | #define PUSH_imm32(imm) OP(0x68); OP32(imm)
|
nkeynes@991 | 508 | #define PUSH_r32(r1) x86_encode_opcode32(0x50, r1)
|
nkeynes@991 | 509 |
|
nkeynes@991 | 510 | #define RCLL_cl_r32(r1) x86_encode_r32_rm32(0xD3,2,r1)
|
nkeynes@991 | 511 | #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 | 512 | #define RCLQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,2,r1)
|
nkeynes@991 | 513 | #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 | 514 | #define RCRL_cl_r32(r1) x86_encode_r32_rm32(0xD3,3,r1)
|
nkeynes@991 | 515 | #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 | 516 | #define RCRQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,3,r1)
|
nkeynes@991 | 517 | #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 | 518 | #define ROLL_cl_r32(r1) x86_encode_r32_rm32(0xD3,0,r1)
|
nkeynes@991 | 519 | #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 | 520 | #define ROLQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,0,r1)
|
nkeynes@991 | 521 | #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 | 522 | #define RORL_cl_r32(r1) x86_encode_r32_rm32(0xD3,1,r1)
|
nkeynes@991 | 523 | #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 | 524 | #define RORQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,1,r1)
|
nkeynes@991 | 525 | #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 | 526 |
|
nkeynes@991 | 527 | #define SARL_cl_r32(r1) x86_encode_r32_rm32(0xD3,7,r1)
|
nkeynes@991 | 528 | #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 | 529 | #define SARQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,7,r1)
|
nkeynes@991 | 530 | #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 | 531 | #define SHLL_cl_r32(r1) x86_encode_r32_rm32(0xD3,4,r1)
|
nkeynes@991 | 532 | #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 | 533 | #define SHLQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,4,r1)
|
nkeynes@991 | 534 | #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 | 535 | #define SHRL_cl_r32(r1) x86_encode_r32_rm32(0xD3,5,r1)
|
nkeynes@991 | 536 | #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 | 537 | #define SHRQ_cl_r64(r1) x86_encode_r64_rm64(0xD3,5,r1)
|
nkeynes@991 | 538 | #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 | 539 |
|
nkeynes@991 | 540 | #define SBBB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 3, r1); OP(imm)
|
nkeynes@991 | 541 | #define SBBB_r8_r8(r1,r2) x86_encode_r32_rm32(0x18, r1, r2)
|
nkeynes@991 | 542 | #define SBBL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 3, imm, r1)
|
nkeynes@991 | 543 | #define SBBL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,3,imm,disp)
|
nkeynes@991 | 544 | #define SBBL_r32_r32(r1,r2) x86_encode_r32_rm32(0x19, r1, r2)
|
nkeynes@991 | 545 | #define SBBL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x19, r1, disp)
|
nkeynes@991 | 546 | #define SBBL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x1B, r1, disp)
|
nkeynes@991 | 547 | #define SBBQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 3, imm, r1)
|
nkeynes@991 | 548 | #define SBBQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x19, r1, r2)
|
nkeynes@991 | 549 |
|
nkeynes@991 | 550 | #define SETCCB_cc_r8(cc,r1) x86_encode_r32_rm32(0x0F90+(cc), 0, r1)
|
nkeynes@991 | 551 | #define SETCCB_cc_rbpdisp(cc,disp) x86_encode_r32_rbpdisp32(0x0F90+(cc), 0, disp)
|
nkeynes@991 | 552 |
|
nkeynes@991 | 553 | #define STC() OP(0xF9)
|
nkeynes@991 | 554 | #define STD() OP(0xFD)
|
nkeynes@991 | 555 |
|
nkeynes@991 | 556 | #define SUBB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 5, r1); OP(imm)
|
nkeynes@991 | 557 | #define SUBB_r8_r8(r1,r2) x86_encode_r32_rm32(0x28, r1, r2)
|
nkeynes@991 | 558 | #define SUBL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 5, imm, r1)
|
nkeynes@991 | 559 | #define SUBL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,5,imm,disp)
|
nkeynes@991 | 560 | #define SUBL_r32_r32(r1,r2) x86_encode_r32_rm32(0x29, r1, r2)
|
nkeynes@991 | 561 | #define SUBL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x29, r1, disp)
|
nkeynes@991 | 562 | #define SUBL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x2B, r1, disp)
|
nkeynes@991 | 563 | #define SUBQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 5, imm, r1)
|
nkeynes@991 | 564 | #define SUBQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x29, r1, r2)
|
nkeynes@991 | 565 |
|
nkeynes@991 | 566 | #define TESTB_imms_r8(imm,r1) x86_encode_r32_rm32(0xF6, 0, r1); OP(imm)
|
nkeynes@991 | 567 | #define TESTB_r8_r8(r1,r2) x86_encode_r32_rm32(0x84, r1, r2)
|
nkeynes@991 | 568 | #define TESTL_imms_r32(imm,r1) x86_encode_r32_rm32(0xF7, 0, r1); OP32(imm)
|
nkeynes@991 | 569 | #define TESTL_imms_rbpdisp(imm,dsp) x86_encode_r32_rbpdisp32(0xF7, 0, dsp); OP32(imm)
|
nkeynes@991 | 570 | #define TESTL_r32_r32(r1,r2) x86_encode_r32_rm32(0x85, r1, r2)
|
nkeynes@991 | 571 | #define TESTL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x85, r1, disp)
|
nkeynes@991 | 572 | #define TESTL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x85, r1, disp) /* Same OP */
|
nkeynes@991 | 573 | #define TESTQ_imms_r64(imm,r1) x86_encode_r64_rm64(0xF7, 0, r1); OP32(imm)
|
nkeynes@991 | 574 | #define TESTQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x85, r1, r2)
|
nkeynes@1112 | 575 | #define TESTP_rptr_rptr(r1,r2) x86_encode_rptr_rmptr(0x85, r1, r2)
|
nkeynes@991 | 576 |
|
nkeynes@991 | 577 | #define XCHGB_r8_r8(r1,r2) x86_encode_r32_rm32(0x86, r1, r2)
|
nkeynes@991 | 578 | #define XCHGL_r32_r32(r1,r2) x86_encode_r32_rm32(0x87, r1, r2)
|
nkeynes@991 | 579 | #define XCHGQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x87, r1, r2)
|
nkeynes@991 | 580 |
|
nkeynes@991 | 581 | #define XORB_imms_r8(imm,r1) x86_encode_r32_rm32(0x80, 6, r1); OP(imm)
|
nkeynes@991 | 582 | #define XORB_r8_r8(r1,r2) x86_encode_r32_rm32(0x30, r1, r2)
|
nkeynes@991 | 583 | #define XORL_imms_r32(imm,r1) x86_encode_imms_rm32(0x83, 0x81, 6, imm, r1)
|
nkeynes@991 | 584 | #define XORL_imms_rbpdisp(imm,disp) x86_encode_imms_rbpdisp32(0x83,0x81,6,imm,disp)
|
nkeynes@991 | 585 | #define XORL_r32_r32(r1,r2) x86_encode_r32_rm32(0x31, r1, r2)
|
nkeynes@991 | 586 | #define XORL_r32_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x31, r1, disp)
|
nkeynes@991 | 587 | #define XORL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x33, r1, disp)
|
nkeynes@991 | 588 | #define XORQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 6, imm, r1)
|
nkeynes@991 | 589 | #define XORQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x31, r1, r2)
|
nkeynes@991 | 590 |
|
nkeynes@991 | 591 | /* Control flow */
|
nkeynes@991 | 592 | #define CALL_rel(rel) OP(0xE8); OP32(rel)
|
nkeynes@991 | 593 | #define CALL_imm32(ptr) x86_encode_r32_mem32disp32(0xFF, 2, -1, ptr)
|
nkeynes@991 | 594 | #define CALL_r32(r1) x86_encode_r32_rm32(0xFF, 2, r1)
|
nkeynes@991 | 595 | #define CALL_r32disp(r1,disp) x86_encode_r32_mem32disp32(0xFF, 2, r1, disp)
|
nkeynes@991 | 596 |
|
nkeynes@991 | 597 | #define JCC_cc_rel8(cc,rel) OP(0x70+(cc)); OP(rel)
|
nkeynes@991 | 598 | #define JCC_cc_rel32(cc,rel) OP(0x0F); OP(0x80+(cc)); OP32(rel)
|
nkeynes@991 | 599 | #define JCC_cc_rel(cc,rel) if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)rel); } else { JCC_cc_rel32(cc,rel); }
|
nkeynes@1112 | 600 | #define JCC_cc_prerel(cc,rel) if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)((rel)-2)); } else { JCC_cc_rel32(cc,((rel)-6)); }
|
nkeynes@991 | 601 |
|
nkeynes@991 | 602 | #define JMP_rel8(rel) OP(0xEB); OP(rel)
|
nkeynes@991 | 603 | #define JMP_rel32(rel) OP(0xE9); OP32(rel)
|
nkeynes@991 | 604 | #define JMP_rel(rel) if( IS_INT8(rel) ) { JMP_rel8((int8_t)rel); } else { JMP_rel32(rel); }
|
nkeynes@991 | 605 | #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@1112 | 606 | #define JMP_rptr(r1) x86_encode_r32_rm32(0xFF, 4, r1)
|
nkeynes@991 | 607 | #define JMP_r32disp(r1,disp) x86_encode_r32_mem32disp32(0xFF, 4, r1, disp)
|
nkeynes@991 | 608 | #define RET() OP(0xC3)
|
nkeynes@991 | 609 | #define RET_imm(imm) OP(0xC2); OP16(imm)
|
nkeynes@991 | 610 |
|
nkeynes@991 | 611 |
|
nkeynes@991 | 612 | /* x87 Floating point instructions */
|
nkeynes@991 | 613 | #define FABS_st0() OP(0xD9); OP(0xE1)
|
nkeynes@991 | 614 | #define FADDP_st(st) OP(0xDE); OP(0xC0+(st))
|
nkeynes@991 | 615 | #define FCHS_st0() OP(0xD9); OP(0xE0)
|
nkeynes@991 | 616 | #define FCOMIP_st(st) OP(0xDF); OP(0xF0+(st))
|
nkeynes@991 | 617 | #define FDIVP_st(st) OP(0xDE); OP(0xF8+(st))
|
nkeynes@991 | 618 | #define FILD_r32disp(r32, disp) x86_encode_r32_mem32disp32(0xDB, 0, r32, disp)
|
nkeynes@991 | 619 | #define FLD0_st0() OP(0xD9); OP(0xEE);
|
nkeynes@991 | 620 | #define FLD1_st0() OP(0xD9); OP(0xE8);
|
nkeynes@991 | 621 | #define FLDCW_r32disp(r32, disp) x86_encode_r32_mem32disp32(0xD9, 5, r32, disp)
|
nkeynes@991 | 622 | #define FMULP_st(st) OP(0xDE); OP(0xC8+(st))
|
nkeynes@991 | 623 | #define FNSTCW_r32disp(r32, disp) x86_encode_r32_mem32disp32(0xD9, 7, r32, disp)
|
nkeynes@991 | 624 | #define FPOP_st() OP(0xDD); OP(0xC0); OP(0xD9); OP(0xF7)
|
nkeynes@991 | 625 | #define FSUBP_st(st) OP(0xDE); OP(0xE8+(st))
|
nkeynes@991 | 626 | #define FSQRT_st0() OP(0xD9); OP(0xFA)
|
nkeynes@991 | 627 |
|
nkeynes@991 | 628 | #define FILD_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDB, 0, disp)
|
nkeynes@991 | 629 | #define FLDF_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xD9, 0, disp)
|
nkeynes@991 | 630 | #define FLDD_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDD, 0, disp)
|
nkeynes@991 | 631 | #define FISTP_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDB, 3, disp)
|
nkeynes@991 | 632 | #define FSTPF_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xD9, 3, disp)
|
nkeynes@991 | 633 | #define FSTPD_rbpdisp(disp) x86_encode_r32_rbpdisp32(0xDD, 3, disp)
|
nkeynes@991 | 634 |
|
nkeynes@991 | 635 |
|
nkeynes@991 | 636 | /* SSE Packed floating point instructions */
|
nkeynes@991 | 637 | #define ADDPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
|
nkeynes@991 | 638 | #define ADDPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F58, r2, r1)
|
nkeynes@991 | 639 | #define ANDPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F54, r1, disp)
|
nkeynes@991 | 640 | #define ANDPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F54, r2, r1)
|
nkeynes@991 | 641 | #define ANDNPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F55, r1, disp)
|
nkeynes@991 | 642 | #define ANDNPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F55, r2, r1)
|
nkeynes@991 | 643 | #define CMPPS_cc_rbpdisp_xmm(cc,d,r) x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
|
nkeynes@991 | 644 | #define CMPPS_cc_xmm_xmm(cc,r1,r2) x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
|
nkeynes@991 | 645 | #define DIVPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
|
nkeynes@991 | 646 | #define DIVPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5E, r2, r1)
|
nkeynes@991 | 647 | #define MAXPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
|
nkeynes@991 | 648 | #define MAXPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5F, r2, r1)
|
nkeynes@991 | 649 | #define MINPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
|
nkeynes@991 | 650 | #define MINPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5D, r2, r1)
|
nkeynes@991 | 651 | #define MOV_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F28, r2, r1)
|
nkeynes@991 | 652 | #define MOVAPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F28, r1, disp)
|
nkeynes@991 | 653 | #define MOVAPS_xmm_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x0F29, r1, disp)
|
nkeynes@991 | 654 | #define MOVHLPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F12, r2, r1)
|
nkeynes@991 | 655 | #define MOVHPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F16, r1, disp)
|
nkeynes@991 | 656 | #define MOVHPS_xmm_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x0F17, r1, disp)
|
nkeynes@991 | 657 | #define MOVLHPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F16, r2, r1)
|
nkeynes@991 | 658 | #define MOVLPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F12, r1, disp)
|
nkeynes@991 | 659 | #define MOVLPS_xmm_rbpdisp(r1,disp) x86_encode_r32_rbpdisp32(0x0F13, r1, disp)
|
nkeynes@991 | 660 | #define MOVUPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F10, r1, disp)
|
nkeynes@991 | 661 | #define MOVUPS_xmm_rbpdisp(disp,r1) x86_encode_r32_rbpdisp32(0x0F11, r1, disp)
|
nkeynes@991 | 662 | #define MULPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F59, r2, r1)
|
nkeynes@991 | 663 | #define MULPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0xF59, r1, disp)
|
nkeynes@991 | 664 | #define ORPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F56, r1, disp)
|
nkeynes@991 | 665 | #define ORPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F56, r2, r1)
|
nkeynes@991 | 666 | #define RCPPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0xF53, r1, disp)
|
nkeynes@991 | 667 | #define RCPPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F53, r2, r1)
|
nkeynes@991 | 668 | #define RSQRTPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F52, r1, disp)
|
nkeynes@991 | 669 | #define RSQRTPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F52, r2, r1)
|
nkeynes@991 | 670 | #define SHUFPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0FC6, r1, disp)
|
nkeynes@991 | 671 | #define SHUFPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0FC6, r2, r1)
|
nkeynes@991 | 672 | #define SQRTPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F51, r1, disp)
|
nkeynes@991 | 673 | #define SQRTPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F51, r2, r1)
|
nkeynes@991 | 674 | #define SUBPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
|
nkeynes@991 | 675 | #define SUBPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5C, r2, r1)
|
nkeynes@991 | 676 | #define UNPCKHPS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F15, r1, disp)
|
nkeynes@991 | 677 | #define UNPCKHPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F15, r2, r1)
|
nkeynes@991 | 678 | #define UNPCKLPS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F14, r1, disp)
|
nkeynes@991 | 679 | #define UNPCKLPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F14, r2, r1)
|
nkeynes@991 | 680 | #define XORPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F57, r1, disp)
|
nkeynes@991 | 681 | #define XORPS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F57, r2, r1)
|
nkeynes@991 | 682 |
|
nkeynes@991 | 683 | /* SSE Scalar floating point instructions */
|
nkeynes@991 | 684 | #define ADDSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
|
nkeynes@991 | 685 | #define ADDSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F58, r2, r1)
|
nkeynes@991 | 686 | #define CMPSS_cc_rbpdisp_xmm(cc,d,r) OP(0xF3); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
|
nkeynes@991 | 687 | #define CMPSS_cc_xmm_xmm(cc,r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
|
nkeynes@991 | 688 | #define COMISS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F2F, r1, disp)
|
nkeynes@991 | 689 | #define COMISS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F2F, r2, r1)
|
nkeynes@991 | 690 | #define DIVSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
|
nkeynes@991 | 691 | #define DIVSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5E, r2, r1)
|
nkeynes@991 | 692 | #define MAXSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
|
nkeynes@991 | 693 | #define MAXSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5F, r2, r1)
|
nkeynes@991 | 694 | #define MINSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
|
nkeynes@991 | 695 | #define MINSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5D, r2, r1)
|
nkeynes@991 | 696 | #define MOVSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F10, r1, disp)
|
nkeynes@991 | 697 | #define MOVSS_xmm_rbpdisp(r1,disp) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F11, r1, disp)
|
nkeynes@991 | 698 | #define MOVSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F10, r2, r1)
|
nkeynes@991 | 699 | #define MULSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0xF59, r1, disp)
|
nkeynes@991 | 700 | #define MULSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F59, r2, r1)
|
nkeynes@991 | 701 | #define RCPSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0xF53, r1, disp)
|
nkeynes@991 | 702 | #define RCPSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F53, r2, r1)
|
nkeynes@991 | 703 | #define RSQRTSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F52, r1, disp)
|
nkeynes@991 | 704 | #define RSQRTSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F52, r2, r1)
|
nkeynes@991 | 705 | #define SQRTSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F51, r1, disp)
|
nkeynes@991 | 706 | #define SQRTSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F51, r2, r1)
|
nkeynes@991 | 707 | #define SUBSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
|
nkeynes@991 | 708 | #define SUBSS_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F5C, r2, r1)
|
nkeynes@991 | 709 | #define UCOMISS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F2E, r1, dsp)
|
nkeynes@991 | 710 | #define UCOMISS_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F2E, r2, r1)
|
nkeynes@991 | 711 |
|
nkeynes@991 | 712 | /* SSE2 Packed floating point instructions */
|
nkeynes@991 | 713 | #define ADDPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
|
nkeynes@991 | 714 | #define ADDPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F58, r2, r1)
|
nkeynes@991 | 715 | #define ANDPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F54, r1, disp)
|
nkeynes@991 | 716 | #define ANDPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F54, r2, r1)
|
nkeynes@991 | 717 | #define ANDNPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F55, r1, disp)
|
nkeynes@991 | 718 | #define ANDNPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F55, r2, r1)
|
nkeynes@991 | 719 | #define CMPPD_cc_rbpdisp_xmm(cc,d,r) OP(0x66); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
|
nkeynes@991 | 720 | #define CMPPD_cc_xmm_xmm(cc,r1,r2) OP(0x66); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
|
nkeynes@991 | 721 | #define CVTPD2PS_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5A, r1, disp)
|
nkeynes@991 | 722 | #define CVTPD2PS_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5A, r2, r1)
|
nkeynes@991 | 723 | #define CVTPS2PD_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F5A, r1, disp)
|
nkeynes@991 | 724 | #define CVTPS2PD_xmm_xmm(r1,r2) x86_encode_r32_rm32(0x0F5A, r2, r1)
|
nkeynes@991 | 725 | #define DIVPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
|
nkeynes@991 | 726 | #define DIVPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5E, r2, r1)
|
nkeynes@991 | 727 | #define MAXPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
|
nkeynes@991 | 728 | #define MAXPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5F, r2, r1)
|
nkeynes@991 | 729 | #define MINPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
|
nkeynes@991 | 730 | #define MINPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5D, r2, r1)
|
nkeynes@991 | 731 | #define MOVHPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F16, r1, disp)
|
nkeynes@991 | 732 | #define MOVHPD_xmm_rbpdisp(r1,disp) OP(0x66); x86_encode_r32_rbpdisp32(0x0F17, r1, disp)
|
nkeynes@991 | 733 | #define MOVLPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F12, r1, disp)
|
nkeynes@991 | 734 | #define MOVLPD_xmm_rbpdisp(r1,disp) OP(0x66); x86_encode_r32_rbpdisp32(0x0F13, r1, disp)
|
nkeynes@991 | 735 | #define MULPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0xF59, r1, disp)
|
nkeynes@991 | 736 | #define MULPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F59, r2, r1)
|
nkeynes@991 | 737 | #define ORPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F56, r1, disp)
|
nkeynes@991 | 738 | #define ORPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F56, r2, r1)
|
nkeynes@991 | 739 | #define SHUFPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0FC6, r1, disp)
|
nkeynes@991 | 740 | #define SHUFPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0FC6, r2, r1)
|
nkeynes@991 | 741 | #define SUBPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
|
nkeynes@991 | 742 | #define SUBPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F5C, r2, r1)
|
nkeynes@991 | 743 | #define UNPCKHPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F15, r1, disp)
|
nkeynes@991 | 744 | #define UNPCKHPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F15, r2, r1)
|
nkeynes@991 | 745 | #define UNPCKLPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F14, r1, disp)
|
nkeynes@991 | 746 | #define UNPCKLPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F14, r2, r1)
|
nkeynes@991 | 747 | #define XORPD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F57, r1, disp)
|
nkeynes@991 | 748 | #define XORPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F57, r2, r1)
|
nkeynes@991 | 749 |
|
nkeynes@991 | 750 |
|
nkeynes@991 | 751 | /* SSE2 Scalar floating point instructions */
|
nkeynes@991 | 752 | #define ADDSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
|
nkeynes@991 | 753 | #define ADDSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F58, r2, r1)
|
nkeynes@991 | 754 | #define CMPSD_cc_rbpdisp_xmm(cc,d,r) OP(0xF2); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
|
nkeynes@991 | 755 | #define CMPSD_cc_xmm_xmm(cc,r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
|
nkeynes@991 | 756 | #define COMISD_rbpdisp_xmm(disp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F2F, r1, disp)
|
nkeynes@991 | 757 | #define COMISD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F2F, r2, r1)
|
nkeynes@991 | 758 | #define DIVSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
|
nkeynes@991 | 759 | #define DIVSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5E, r2, r1)
|
nkeynes@991 | 760 | #define MAXSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
|
nkeynes@991 | 761 | #define MAXSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5F, r2, r1)
|
nkeynes@991 | 762 | #define MINSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
|
nkeynes@991 | 763 | #define MINSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5D, r2, r1)
|
nkeynes@991 | 764 | #define MOVSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F10, r1, disp)
|
nkeynes@991 | 765 | #define MOVSD_xmm_rbpdisp(r1,disp) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F11, r1, disp)
|
nkeynes@991 | 766 | #define MOVSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F10, r2, r1)
|
nkeynes@991 | 767 | #define MULSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0xF59, r1, disp)
|
nkeynes@991 | 768 | #define MULSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F59, r2, r1)
|
nkeynes@991 | 769 | #define SQRTSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F51, r1, disp)
|
nkeynes@991 | 770 | #define SQRTSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F51, r2, r1)
|
nkeynes@991 | 771 | #define SUBSD_rbpdisp_xmm(disp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
|
nkeynes@991 | 772 | #define SUBSD_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F5C, r2, r1)
|
nkeynes@991 | 773 | #define UCOMISD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F2E, r1, dsp)
|
nkeynes@991 | 774 | #define UCOMISD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F2E, r2, r1)
|
nkeynes@991 | 775 |
|
nkeynes@991 | 776 | /* SSE3 floating point instructions */
|
nkeynes@991 | 777 | #define ADDSUBPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0FD0, r1, dsp)
|
nkeynes@991 | 778 | #define ADDSUBPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0FD0, r2, r1)
|
nkeynes@991 | 779 | #define ADDSUBPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0FD0, r1, dsp)
|
nkeynes@991 | 780 | #define ADDSUBPS_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0FD0, r2, r1)
|
nkeynes@991 | 781 | #define HADDPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F7C, r1, dsp)
|
nkeynes@991 | 782 | #define HADDPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F7C, r2, r1)
|
nkeynes@991 | 783 | #define HADDPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F7C, r1, dsp)
|
nkeynes@991 | 784 | #define HADDPS_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F7C, r2, r1)
|
nkeynes@991 | 785 | #define HSUBPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F7D, r1, dsp)
|
nkeynes@991 | 786 | #define HSUBPD_xmm_xmm(r1,r2) OP(0x66); x86_encode_r32_rm32(0x0F7D, r2, r1)
|
nkeynes@991 | 787 | #define HSUBPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0F7D, r1, dsp)
|
nkeynes@991 | 788 | #define HSUBPS_xmm_xmm(r1,r2) OP(0xF2); x86_encode_r32_rm32(0x0F7D, r2, r1)
|
nkeynes@991 | 789 | #define MOVSHDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F16, r1, dsp)
|
nkeynes@991 | 790 | #define MOVSHDUP_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F16, r2, r1)
|
nkeynes@991 | 791 | #define MOVSLDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F12, r1, dsp)
|
nkeynes@991 | 792 | #define MOVSLDUP_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F12, r2, r1)
|
nkeynes@995 | 793 |
|
nkeynes@995 | 794 | /************************ Import calling conventions *************************/
|
nkeynes@995 | 795 | #if SIZEOF_VOID_P == 8
|
nkeynes@995 | 796 | #include "xlat/x86/amd64abi.h"
|
nkeynes@995 | 797 | #else /* 32-bit system */
|
nkeynes@995 | 798 | #include "xlat/x86/ia32abi.h"
|
nkeynes@995 | 799 | #endif
|
nkeynes@995 | 800 |
|
nkeynes@995 | 801 | #endif /* !lxdream_x86op_H */
|