1 /* 2 * 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * Copyright (c) 2010, Intel Corporation. 28 * All rights reserved. 29 */ 30 31 /* Copyright (c) 1988 AT&T */ 32 /* All Rights Reserved */ 33 34 /* 35 * $FreeBSD$ 36 */ 37 38 #include "dis_tables.h" 39 40 /* BEGIN CSTYLED */ 41 42 /* 43 * Disassembly begins in dis_distable, which is equivalent to the One-byte 44 * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy). The 45 * decoding loops then traverse out through the other tables as necessary to 46 * decode a given instruction. 47 * 48 * The behavior of this file can be controlled by one of the following flags: 49 * 50 * DIS_TEXT Include text for disassembly 51 * DIS_MEM Include memory-size calculations 52 * 53 * Either or both of these can be defined. 54 * 55 * This file is not, and will never be, cstyled. If anything, the tables should 56 * be taken out another tab stop or two so nothing overlaps. 57 */ 58 59 /* 60 * These functions must be provided for the consumer to do disassembly. 61 */ 62 #ifdef DIS_TEXT 63 extern char *strncpy(char *, const char *, size_t); 64 extern size_t strlen(const char *); 65 extern int strcmp(const char *, const char *); 66 extern int strncmp(const char *, const char *, size_t); 67 extern size_t strlcat(char *, const char *, size_t); 68 #endif 69 70 71 #define TERM 0 /* used to indicate that the 'indirect' */ 72 /* field terminates - no pointer. */ 73 74 /* Used to decode instructions. */ 75 typedef struct instable { 76 struct instable *it_indirect; /* for decode op codes */ 77 uchar_t it_adrmode; 78 #ifdef DIS_TEXT 79 char it_name[NCPS]; 80 uint_t it_suffix:1; /* mnem + "w", "l", or "d" */ 81 #endif 82 #ifdef DIS_MEM 83 uint_t it_size:16; 84 #endif 85 uint_t it_invalid64:1; /* opcode invalid in amd64 */ 86 uint_t it_always64:1; /* 64 bit when in 64 bit mode */ 87 uint_t it_invalid32:1; /* invalid in IA32 */ 88 uint_t it_stackop:1; /* push/pop stack operation */ 89 } instable_t; 90 91 /* 92 * Instruction formats. 93 */ 94 enum { 95 UNKNOWN, 96 MRw, 97 IMlw, 98 IMw, 99 IR, 100 OA, 101 AO, 102 MS, 103 SM, 104 Mv, 105 Mw, 106 M, /* register or memory */ 107 Mb, /* register or memory, always byte sized */ 108 MO, /* memory only (no registers) */ 109 PREF, 110 SWAPGS, 111 MONITOR_MWAIT, 112 R, 113 RA, 114 SEG, 115 MR, 116 RM, 117 IA, 118 MA, 119 SD, 120 AD, 121 SA, 122 D, 123 INM, 124 SO, 125 BD, 126 I, 127 P, 128 V, 129 DSHIFT, /* for double shift that has an 8-bit immediate */ 130 U, 131 OVERRIDE, 132 NORM, /* instructions w/o ModR/M byte, no memory access */ 133 IMPLMEM, /* instructions w/o ModR/M byte, implicit mem access */ 134 O, /* for call */ 135 JTAB, /* jump table */ 136 IMUL, /* for 186 iimul instr */ 137 CBW, /* so data16 can be evaluated for cbw and variants */ 138 MvI, /* for 186 logicals */ 139 ENTER, /* for 186 enter instr */ 140 RMw, /* for 286 arpl instr */ 141 Ib, /* for push immediate byte */ 142 F, /* for 287 instructions */ 143 FF, /* for 287 instructions */ 144 FFC, /* for 287 instructions */ 145 DM, /* 16-bit data */ 146 AM, /* 16-bit addr */ 147 LSEG, /* for 3-bit seg reg encoding */ 148 MIb, /* for 386 logicals */ 149 SREG, /* for 386 special registers */ 150 PREFIX, /* a REP instruction prefix */ 151 LOCK, /* a LOCK instruction prefix */ 152 INT3, /* The int 3 instruction, which has a fake operand */ 153 INTx, /* The normal int instruction, with explicit int num */ 154 DSHIFTcl, /* for double shift that implicitly uses %cl */ 155 CWD, /* so data16 can be evaluated for cwd and variants */ 156 RET, /* single immediate 16-bit operand */ 157 MOVZ, /* for movs and movz, with different size operands */ 158 CRC32, /* for crc32, with different size operands */ 159 XADDB, /* for xaddb */ 160 MOVSXZ, /* AMD64 mov sign extend 32 to 64 bit instruction */ 161 MOVBE, /* movbe instruction */ 162 163 /* 164 * MMX/SIMD addressing modes. 165 */ 166 167 MMO, /* Prefixable MMX/SIMD-Int mm/mem -> mm */ 168 MMOIMPL, /* Prefixable MMX/SIMD-Int mm -> mm (mem) */ 169 MMO3P, /* Prefixable MMX/SIMD-Int mm -> r32,imm8 */ 170 MMOM3, /* Prefixable MMX/SIMD-Int mm -> r32 */ 171 MMOS, /* Prefixable MMX/SIMD-Int mm -> mm/mem */ 172 MMOMS, /* Prefixable MMX/SIMD-Int mm -> mem */ 173 MMOPM, /* MMX/SIMD-Int mm/mem -> mm,imm8 */ 174 MMOPM_66o, /* MMX/SIMD-Int 0x66 optional mm/mem -> mm,imm8 */ 175 MMOPRM, /* Prefixable MMX/SIMD-Int r32/mem -> mm,imm8 */ 176 MMOSH, /* Prefixable MMX mm,imm8 */ 177 MM, /* MMX/SIMD-Int mm/mem -> mm */ 178 MMS, /* MMX/SIMD-Int mm -> mm/mem */ 179 MMSH, /* MMX mm,imm8 */ 180 XMMO, /* Prefixable SIMD xmm/mem -> xmm */ 181 XMMOS, /* Prefixable SIMD xmm -> xmm/mem */ 182 XMMOPM, /* Prefixable SIMD xmm/mem w/to xmm,imm8 */ 183 XMMOMX, /* Prefixable SIMD mm/mem -> xmm */ 184 XMMOX3, /* Prefixable SIMD xmm -> r32 */ 185 XMMOXMM, /* Prefixable SIMD xmm/mem -> mm */ 186 XMMOM, /* Prefixable SIMD xmm -> mem */ 187 XMMOMS, /* Prefixable SIMD mem -> xmm */ 188 XMM, /* SIMD xmm/mem -> xmm */ 189 XMM_66r, /* SIMD 0x66 prefix required xmm/mem -> xmm */ 190 XMM_66o, /* SIMD 0x66 prefix optional xmm/mem -> xmm */ 191 XMMXIMPL, /* SIMD xmm -> xmm (mem) */ 192 XMM3P, /* SIMD xmm -> r32,imm8 */ 193 XMM3PM_66r, /* SIMD 0x66 prefix required xmm -> r32/mem,imm8 */ 194 XMMP, /* SIMD xmm/mem w/to xmm,imm8 */ 195 XMMP_66o, /* SIMD 0x66 prefix optional xmm/mem w/to xmm,imm8 */ 196 XMMP_66r, /* SIMD 0x66 prefix required xmm/mem w/to xmm,imm8 */ 197 XMMPRM, /* SIMD r32/mem -> xmm,imm8 */ 198 XMMPRM_66r, /* SIMD 0x66 prefix required r32/mem -> xmm,imm8 */ 199 XMMS, /* SIMD xmm -> xmm/mem */ 200 XMMM, /* SIMD mem -> xmm */ 201 XMMM_66r, /* SIMD 0x66 prefix required mem -> xmm */ 202 XMMMS, /* SIMD xmm -> mem */ 203 XMM3MX, /* SIMD r32/mem -> xmm */ 204 XMM3MXS, /* SIMD xmm -> r32/mem */ 205 XMMSH, /* SIMD xmm,imm8 */ 206 XMMXM3, /* SIMD xmm/mem -> r32 */ 207 XMMX3, /* SIMD xmm -> r32 */ 208 XMMXMM, /* SIMD xmm/mem -> mm */ 209 XMMMX, /* SIMD mm -> xmm */ 210 XMMXM, /* SIMD xmm -> mm */ 211 XMMX2I, /* SIMD xmm -> xmm, imm, imm */ 212 XMM2I, /* SIMD xmm, imm, imm */ 213 XMMFENCE, /* SIMD lfence or mfence */ 214 XMMSFNC, /* SIMD sfence (none or mem) */ 215 XGETBV_XSETBV, 216 VEX_NONE, /* VEX no operand */ 217 VEX_MO, /* VEX mod_rm -> implicit reg */ 218 VEX_RMrX, /* VEX VEX.vvvv, mod_rm -> mod_reg */ 219 VEX_RRX, /* VEX VEX.vvvv, mod_reg -> mod_rm */ 220 VEX_RMRX, /* VEX VEX.vvvv, mod_rm, imm8[7:4] -> mod_reg */ 221 VEX_MX, /* VEX mod_rm -> mod_reg */ 222 VEX_MXI, /* VEX mod_rm, imm8 -> mod_reg */ 223 VEX_XXI, /* VEX mod_rm, imm8 -> VEX.vvvv */ 224 VEX_MR, /* VEX mod_rm -> mod_reg */ 225 VEX_RRI, /* VEX mod_reg, mod_rm -> implicit(eflags/r32) */ 226 VEX_RX, /* VEX mod_reg -> mod_rm */ 227 VEX_RR, /* VEX mod_rm -> mod_reg */ 228 VEX_RRi, /* VEX mod_rm, imm8 -> mod_reg */ 229 VEX_RM, /* VEX mod_reg -> mod_rm */ 230 VEX_RRM, /* VEX VEX.vvvv, mod_reg -> mod_rm */ 231 VEX_RMX /* VEX VEX.vvvv, mod_rm -> mod_reg */ 232 }; 233 234 /* 235 * VEX prefixes 236 */ 237 #define VEX_2bytes 0xC5 /* the first byte of two-byte form */ 238 #define VEX_3bytes 0xC4 /* the first byte of three-byte form */ 239 240 #define FILL 0x90 /* Fill byte used for alignment (nop) */ 241 242 /* 243 ** Register numbers for the i386 244 */ 245 #define EAX_REGNO 0 246 #define ECX_REGNO 1 247 #define EDX_REGNO 2 248 #define EBX_REGNO 3 249 #define ESP_REGNO 4 250 #define EBP_REGNO 5 251 #define ESI_REGNO 6 252 #define EDI_REGNO 7 253 254 /* 255 * modes for immediate values 256 */ 257 #define MODE_NONE 0 258 #define MODE_IPREL 1 /* signed IP relative value */ 259 #define MODE_SIGNED 2 /* sign extended immediate */ 260 #define MODE_IMPLIED 3 /* constant value implied from opcode */ 261 #define MODE_OFFSET 4 /* offset part of an address */ 262 #define MODE_RIPREL 5 /* like IPREL, but from %rip (amd64) */ 263 264 /* 265 * The letters used in these macros are: 266 * IND - indirect to another to another table 267 * "T" - means to Terminate indirections (this is the final opcode) 268 * "S" - means "operand length suffix required" 269 * "NS" - means "no suffix" which is the operand length suffix of the opcode 270 * "Z" - means instruction size arg required 271 * "u" - means the opcode is invalid in IA32 but valid in amd64 272 * "x" - means the opcode is invalid in amd64, but not IA32 273 * "y" - means the operand size is always 64 bits in 64 bit mode 274 * "p" - means push/pop stack operation 275 */ 276 277 #if defined(DIS_TEXT) && defined(DIS_MEM) 278 #define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0} 279 #define INDx(table) {(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0} 280 #define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0} 281 #define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 0, 1, 0} 282 #define TNSx(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0, 0} 283 #define TNSy(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 0} 284 #define TNSyp(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 1} 285 #define TNSZ(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0} 286 #define TNSZy(name, amode, sz) {TERM, amode, name, 0, sz, 0, 1, 0, 0} 287 #define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0} 288 #define TSx(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0, 0} 289 #define TSy(name, amode) {TERM, amode, name, 1, 0, 0, 1, 0, 0} 290 #define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 1} 291 #define TSZ(name, amode, sz) {TERM, amode, name, 1, sz, 0, 0, 0, 0} 292 #define TSZx(name, amode, sz) {TERM, amode, name, 1, sz, 1, 0, 0, 0} 293 #define TSZy(name, amode, sz) {TERM, amode, name, 1, sz, 0, 1, 0, 0} 294 #define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0} 295 #elif defined(DIS_TEXT) 296 #define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0} 297 #define INDx(table) {(instable_t *)table, 0, "", 0, 1, 0, 0, 0} 298 #define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0} 299 #define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0} 300 #define TNSx(name, amode) {TERM, amode, name, 0, 1, 0, 0, 0} 301 #define TNSy(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0} 302 #define TNSyp(name, amode) {TERM, amode, name, 0, 0, 1, 0, 1} 303 #define TNSZ(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0} 304 #define TNSZy(name, amode, sz) {TERM, amode, name, 0, 0, 1, 0, 0} 305 #define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0} 306 #define TSx(name, amode) {TERM, amode, name, 1, 1, 0, 0, 0} 307 #define TSy(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0} 308 #define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 1} 309 #define TSZ(name, amode, sz) {TERM, amode, name, 1, 0, 0, 0, 0} 310 #define TSZx(name, amode, sz) {TERM, amode, name, 1, 1, 0, 0, 0} 311 #define TSZy(name, amode, sz) {TERM, amode, name, 1, 0, 1, 0, 0} 312 #define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0} 313 #elif defined(DIS_MEM) 314 #define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0, 0} 315 #define INDx(table) {(instable_t *)table, 0, 0, 1, 0, 0, 0} 316 #define TNS(name, amode) {TERM, amode, 0, 0, 0, 0, 0} 317 #define TNSu(name, amode) {TERM, amode, 0, 0, 0, 1, 0} 318 #define TNSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0} 319 #define TNSyp(name, amode) {TERM, amode, 0, 0, 1, 0, 1} 320 #define TNSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0} 321 #define TNSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0} 322 #define TNSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0} 323 #define TS(name, amode) {TERM, amode, 0, 0, 0, 0, 0} 324 #define TSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0} 325 #define TSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0} 326 #define TSp(name, amode) {TERM, amode, 0, 0, 0, 0, 1} 327 #define TSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0} 328 #define TSZx(name, amode, sz) {TERM, amode, sz, 1, 0, 0, 0} 329 #define TSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0} 330 #define INVALID {TERM, UNKNOWN, 0, 0, 0, 0, 0} 331 #else 332 #define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0} 333 #define INDx(table) {(instable_t *)table, 0, 1, 0, 0, 0} 334 #define TNS(name, amode) {TERM, amode, 0, 0, 0, 0} 335 #define TNSu(name, amode) {TERM, amode, 0, 0, 1, 0} 336 #define TNSy(name, amode) {TERM, amode, 0, 1, 0, 0} 337 #define TNSyp(name, amode) {TERM, amode, 0, 1, 0, 1} 338 #define TNSx(name, amode) {TERM, amode, 1, 0, 0, 0} 339 #define TNSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0} 340 #define TNSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0} 341 #define TS(name, amode) {TERM, amode, 0, 0, 0, 0} 342 #define TSx(name, amode) {TERM, amode, 1, 0, 0, 0} 343 #define TSy(name, amode) {TERM, amode, 0, 1, 0, 0} 344 #define TSp(name, amode) {TERM, amode, 0, 0, 0, 1} 345 #define TSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0} 346 #define TSZx(name, amode, sz) {TERM, amode, 1, 0, 0, 0} 347 #define TSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0} 348 #define INVALID {TERM, UNKNOWN, 0, 0, 0, 0} 349 #endif 350 351 #ifdef DIS_TEXT 352 /* 353 * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode 354 */ 355 const char *const dis_addr16[3][8] = { 356 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "", 357 "(%bx)", 358 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)", 359 "(%bx)", 360 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)", 361 "(%bx)", 362 }; 363 364 365 /* 366 * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2 367 */ 368 const char *const dis_addr32_mode0[16] = { 369 "(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "", "(%esi)", "(%edi)", 370 "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "", "(%r14d)", "(%r15d)" 371 }; 372 373 const char *const dis_addr32_mode12[16] = { 374 "(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "(%ebp)", "(%esi)", "(%edi)", 375 "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)" 376 }; 377 378 /* 379 * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2 380 */ 381 const char *const dis_addr64_mode0[16] = { 382 "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rip)", "(%rsi)", "(%rdi)", 383 "(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)" 384 }; 385 const char *const dis_addr64_mode12[16] = { 386 "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rbp)", "(%rsi)", "(%rdi)", 387 "(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)" 388 }; 389 390 /* 391 * decode for scale from SIB byte 392 */ 393 const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" }; 394 395 /* 396 * register decoding for normal references to registers (ie. not addressing) 397 */ 398 const char *const dis_REG8[16] = { 399 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", 400 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" 401 }; 402 403 const char *const dis_REG8_REX[16] = { 404 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", 405 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" 406 }; 407 408 const char *const dis_REG16[16] = { 409 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", 410 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" 411 }; 412 413 const char *const dis_REG32[16] = { 414 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", 415 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" 416 }; 417 418 const char *const dis_REG64[16] = { 419 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", 420 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 421 }; 422 423 const char *const dis_DEBUGREG[16] = { 424 "%db0", "%db1", "%db2", "%db3", "%db4", "%db5", "%db6", "%db7", 425 "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15" 426 }; 427 428 const char *const dis_CONTROLREG[16] = { 429 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?", 430 "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?" 431 }; 432 433 const char *const dis_TESTREG[16] = { 434 "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7", 435 "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7" 436 }; 437 438 const char *const dis_MMREG[16] = { 439 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7", 440 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 441 }; 442 443 const char *const dis_XMMREG[16] = { 444 "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 445 "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15" 446 }; 447 448 const char *const dis_YMMREG[16] = { 449 "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7", 450 "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15" 451 }; 452 453 const char *const dis_SEGREG[16] = { 454 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>", 455 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>" 456 }; 457 458 /* 459 * SIMD predicate suffixes 460 */ 461 const char *const dis_PREDSUFFIX[8] = { 462 "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord" 463 }; 464 465 const char *const dis_AVXvgrp7[3][8] = { 466 /*0 1 2 3 4 5 6 7*/ 467 /*71*/ {"", "", "vpsrlw", "", "vpsraw", "", "vpsllw", ""}, 468 /*72*/ {"", "", "vpsrld", "", "vpsrad", "", "vpslld", ""}, 469 /*73*/ {"", "", "vpsrlq", "vpsrldq", "", "", "vpsllq", "vpslldq"} 470 }; 471 472 #endif /* DIS_TEXT */ 473 474 /* 475 * "decode table" for 64 bit mode MOVSXD instruction (opcode 0x63) 476 */ 477 const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ); 478 479 /* 480 * "decode table" for pause and clflush instructions 481 */ 482 const instable_t dis_opPause = TNS("pause", NORM); 483 484 /* 485 * Decode table for 0x0F00 opcodes 486 */ 487 const instable_t dis_op0F00[8] = { 488 489 /* [0] */ TNS("sldt",M), TNS("str",M), TNSy("lldt",M), TNSy("ltr",M), 490 /* [4] */ TNSZ("verr",M,2), TNSZ("verw",M,2), INVALID, INVALID, 491 }; 492 493 494 /* 495 * Decode table for 0x0F01 opcodes 496 */ 497 const instable_t dis_op0F01[8] = { 498 499 /* [0] */ TNSZ("sgdt",MO,6), TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6), TNSZ("lidt",MO,6), 500 /* [4] */ TNSZ("smsw",M,2), INVALID, TNSZ("lmsw",M,2), TNS("invlpg",SWAPGS), 501 }; 502 503 /* 504 * Decode table for 0x0F18 opcodes -- SIMD prefetch 505 */ 506 const instable_t dis_op0F18[8] = { 507 508 /* [0] */ TNS("prefetchnta",PREF),TNS("prefetcht0",PREF), TNS("prefetcht1",PREF), TNS("prefetcht2",PREF), 509 /* [4] */ INVALID, INVALID, INVALID, INVALID, 510 }; 511 512 /* 513 * Decode table for 0x0FAE opcodes -- SIMD state save/restore 514 */ 515 const instable_t dis_op0FAE[8] = { 516 /* [0] */ TNSZ("fxsave",M,512), TNSZ("fxrstor",M,512), TNS("ldmxcsr",M), TNS("stmxcsr",M), 517 /* [4] */ TNSZ("xsave",M,512), TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE), TNS("sfence",XMMSFNC), 518 }; 519 520 /* 521 * Decode table for 0x0FBA opcodes 522 */ 523 524 const instable_t dis_op0FBA[8] = { 525 526 /* [0] */ INVALID, INVALID, INVALID, INVALID, 527 /* [4] */ TS("bt",MIb), TS("bts",MIb), TS("btr",MIb), TS("btc",MIb), 528 }; 529 530 /* 531 * Decode table for 0x0FC7 opcode 532 */ 533 534 const instable_t dis_op0FC7[8] = { 535 536 /* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, INVALID, 537 /* [4] */ INVALID, INVALID, INVALID, INVALID, 538 }; 539 540 541 /* 542 * Decode table for 0x0FC8 opcode -- 486 bswap instruction 543 * 544 *bit pattern: 0000 1111 1100 1reg 545 */ 546 const instable_t dis_op0FC8[4] = { 547 /* [0] */ TNS("bswap",R), INVALID, INVALID, INVALID, 548 }; 549 550 /* 551 * Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions 552 */ 553 const instable_t dis_op0F7123[4][8] = { 554 { 555 /* [70].0 */ INVALID, INVALID, INVALID, INVALID, 556 /* .4 */ INVALID, INVALID, INVALID, INVALID, 557 }, { 558 /* [71].0 */ INVALID, INVALID, TNS("psrlw",MMOSH), INVALID, 559 /* .4 */ TNS("psraw",MMOSH), INVALID, TNS("psllw",MMOSH), INVALID, 560 }, { 561 /* [72].0 */ INVALID, INVALID, TNS("psrld",MMOSH), INVALID, 562 /* .4 */ TNS("psrad",MMOSH), INVALID, TNS("pslld",MMOSH), INVALID, 563 }, { 564 /* [73].0 */ INVALID, INVALID, TNS("psrlq",MMOSH), TNS("INVALID",MMOSH), 565 /* .4 */ INVALID, INVALID, TNS("psllq",MMOSH), TNS("INVALID",MMOSH), 566 } }; 567 568 /* 569 * Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes. 570 */ 571 const instable_t dis_opSIMD7123[32] = { 572 /* [70].0 */ INVALID, INVALID, INVALID, INVALID, 573 /* .4 */ INVALID, INVALID, INVALID, INVALID, 574 575 /* [71].0 */ INVALID, INVALID, TNS("psrlw",XMMSH), INVALID, 576 /* .4 */ TNS("psraw",XMMSH), INVALID, TNS("psllw",XMMSH), INVALID, 577 578 /* [72].0 */ INVALID, INVALID, TNS("psrld",XMMSH), INVALID, 579 /* .4 */ TNS("psrad",XMMSH), INVALID, TNS("pslld",XMMSH), INVALID, 580 581 /* [73].0 */ INVALID, INVALID, TNS("psrlq",XMMSH), TNS("psrldq",XMMSH), 582 /* .4 */ INVALID, INVALID, TNS("psllq",XMMSH), TNS("pslldq",XMMSH), 583 }; 584 585 /* 586 * SIMD instructions have been wedged into the existing IA32 instruction 587 * set through the use of prefixes. That is, while 0xf0 0x58 may be 588 * addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different 589 * instruction - addss. At present, three prefixes have been coopted in 590 * this manner - address size (0x66), repnz (0xf2) and repz (0xf3). The 591 * following tables are used to provide the prefixed instruction names. 592 * The arrays are sparse, but they're fast. 593 */ 594 595 /* 596 * Decode table for SIMD instructions with the address size (0x66) prefix. 597 */ 598 const instable_t dis_opSIMDdata16[256] = { 599 /* [00] */ INVALID, INVALID, INVALID, INVALID, 600 /* [04] */ INVALID, INVALID, INVALID, INVALID, 601 /* [08] */ INVALID, INVALID, INVALID, INVALID, 602 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 603 604 /* [10] */ TNSZ("movupd",XMM,16), TNSZ("movupd",XMMS,16), TNSZ("movlpd",XMMM,8), TNSZ("movlpd",XMMMS,8), 605 /* [14] */ TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8), TNSZ("movhpd",XMMMS,8), 606 /* [18] */ INVALID, INVALID, INVALID, INVALID, 607 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 608 609 /* [20] */ INVALID, INVALID, INVALID, INVALID, 610 /* [24] */ INVALID, INVALID, INVALID, INVALID, 611 /* [28] */ TNSZ("movapd",XMM,16), TNSZ("movapd",XMMS,16), TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16), 612 /* [2C] */ TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8), 613 614 /* [30] */ INVALID, INVALID, INVALID, INVALID, 615 /* [34] */ INVALID, INVALID, INVALID, INVALID, 616 /* [38] */ INVALID, INVALID, INVALID, INVALID, 617 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 618 619 /* [40] */ INVALID, INVALID, INVALID, INVALID, 620 /* [44] */ INVALID, INVALID, INVALID, INVALID, 621 /* [48] */ INVALID, INVALID, INVALID, INVALID, 622 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 623 624 /* [50] */ TNS("movmskpd",XMMOX3), TNSZ("sqrtpd",XMM,16), INVALID, INVALID, 625 /* [54] */ TNSZ("andpd",XMM,16), TNSZ("andnpd",XMM,16), TNSZ("orpd",XMM,16), TNSZ("xorpd",XMM,16), 626 /* [58] */ TNSZ("addpd",XMM,16), TNSZ("mulpd",XMM,16), TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16), 627 /* [5C] */ TNSZ("subpd",XMM,16), TNSZ("minpd",XMM,16), TNSZ("divpd",XMM,16), TNSZ("maxpd",XMM,16), 628 629 /* [60] */ TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16), 630 /* [64] */ TNSZ("pcmpgtb",XMM,16), TNSZ("pcmpgtw",XMM,16), TNSZ("pcmpgtd",XMM,16), TNSZ("packuswb",XMM,16), 631 /* [68] */ TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16), 632 /* [6C] */ TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16), 633 634 /* [70] */ TNSZ("pshufd",XMMP,16), INVALID, INVALID, INVALID, 635 /* [74] */ TNSZ("pcmpeqb",XMM,16), TNSZ("pcmpeqw",XMM,16), TNSZ("pcmpeqd",XMM,16), INVALID, 636 /* [78] */ TNSZ("extrq",XMM2I,16), TNSZ("extrq",XMM,16), INVALID, INVALID, 637 /* [7C] */ INVALID, INVALID, TNSZ("movd",XMM3MXS,4), TNSZ("movdqa",XMMS,16), 638 639 /* [80] */ INVALID, INVALID, INVALID, INVALID, 640 /* [84] */ INVALID, INVALID, INVALID, INVALID, 641 /* [88] */ INVALID, INVALID, INVALID, INVALID, 642 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 643 644 /* [90] */ INVALID, INVALID, INVALID, INVALID, 645 /* [94] */ INVALID, INVALID, INVALID, INVALID, 646 /* [98] */ INVALID, INVALID, INVALID, INVALID, 647 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 648 649 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 650 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 651 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 652 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 653 654 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 655 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 656 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 657 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 658 659 /* [C0] */ INVALID, INVALID, TNSZ("cmppd",XMMP,16), INVALID, 660 /* [C4] */ TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P), TNSZ("shufpd",XMMP,16), INVALID, 661 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 662 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 663 664 /* [D0] */ INVALID, TNSZ("psrlw",XMM,16), TNSZ("psrld",XMM,16), TNSZ("psrlq",XMM,16), 665 /* [D4] */ TNSZ("paddq",XMM,16), TNSZ("pmullw",XMM,16), TNSZ("movq",XMMS,8), TNS("pmovmskb",XMMX3), 666 /* [D8] */ TNSZ("psubusb",XMM,16), TNSZ("psubusw",XMM,16), TNSZ("pminub",XMM,16), TNSZ("pand",XMM,16), 667 /* [DC] */ TNSZ("paddusb",XMM,16), TNSZ("paddusw",XMM,16), TNSZ("pmaxub",XMM,16), TNSZ("pandn",XMM,16), 668 669 /* [E0] */ TNSZ("pavgb",XMM,16), TNSZ("psraw",XMM,16), TNSZ("psrad",XMM,16), TNSZ("pavgw",XMM,16), 670 /* [E4] */ TNSZ("pmulhuw",XMM,16), TNSZ("pmulhw",XMM,16), TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16), 671 /* [E8] */ TNSZ("psubsb",XMM,16), TNSZ("psubsw",XMM,16), TNSZ("pminsw",XMM,16), TNSZ("por",XMM,16), 672 /* [EC] */ TNSZ("paddsb",XMM,16), TNSZ("paddsw",XMM,16), TNSZ("pmaxsw",XMM,16), TNSZ("pxor",XMM,16), 673 674 /* [F0] */ INVALID, TNSZ("psllw",XMM,16), TNSZ("pslld",XMM,16), TNSZ("psllq",XMM,16), 675 /* [F4] */ TNSZ("pmuludq",XMM,16), TNSZ("pmaddwd",XMM,16), TNSZ("psadbw",XMM,16), TNSZ("maskmovdqu", XMMXIMPL,16), 676 /* [F8] */ TNSZ("psubb",XMM,16), TNSZ("psubw",XMM,16), TNSZ("psubd",XMM,16), TNSZ("psubq",XMM,16), 677 /* [FC] */ TNSZ("paddb",XMM,16), TNSZ("paddw",XMM,16), TNSZ("paddd",XMM,16), INVALID, 678 }; 679 680 const instable_t dis_opAVX660F[256] = { 681 /* [00] */ INVALID, INVALID, INVALID, INVALID, 682 /* [04] */ INVALID, INVALID, INVALID, INVALID, 683 /* [08] */ INVALID, INVALID, INVALID, INVALID, 684 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 685 686 /* [10] */ TNSZ("vmovupd",VEX_MX,16), TNSZ("vmovupd",VEX_RX,16), TNSZ("vmovlpd",VEX_RMrX,8), TNSZ("vmovlpd",VEX_RM,8), 687 /* [14] */ TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8), TNSZ("vmovhpd",VEX_RM,8), 688 /* [18] */ INVALID, INVALID, INVALID, INVALID, 689 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 690 691 /* [20] */ INVALID, INVALID, INVALID, INVALID, 692 /* [24] */ INVALID, INVALID, INVALID, INVALID, 693 /* [28] */ TNSZ("vmovapd",VEX_MX,16), TNSZ("vmovapd",VEX_RX,16), INVALID, TNSZ("vmovntpd",VEX_RM,16), 694 /* [2C] */ INVALID, INVALID, TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8), 695 696 /* [30] */ INVALID, INVALID, INVALID, INVALID, 697 /* [34] */ INVALID, INVALID, INVALID, INVALID, 698 /* [38] */ INVALID, INVALID, INVALID, INVALID, 699 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 700 701 /* [40] */ INVALID, INVALID, INVALID, INVALID, 702 /* [44] */ INVALID, INVALID, INVALID, INVALID, 703 /* [48] */ INVALID, INVALID, INVALID, INVALID, 704 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 705 706 /* [50] */ TNS("vmovmskpd",VEX_MR), TNSZ("vsqrtpd",VEX_MX,16), INVALID, INVALID, 707 /* [54] */ TNSZ("vandpd",VEX_RMrX,16), TNSZ("vandnpd",VEX_RMrX,16), TNSZ("vorpd",VEX_RMrX,16), TNSZ("vxorpd",VEX_RMrX,16), 708 /* [58] */ TNSZ("vaddpd",VEX_RMrX,16), TNSZ("vmulpd",VEX_RMrX,16), TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16), 709 /* [5C] */ TNSZ("vsubpd",VEX_RMrX,16), TNSZ("vminpd",VEX_RMrX,16), TNSZ("vdivpd",VEX_RMrX,16), TNSZ("vmaxpd",VEX_RMrX,16), 710 711 /* [60] */ TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16), 712 /* [64] */ TNSZ("vpcmpgtb",VEX_RMrX,16), TNSZ("vpcmpgtw",VEX_RMrX,16), TNSZ("vpcmpgtd",VEX_RMrX,16), TNSZ("vpackuswb",VEX_RMrX,16), 713 /* [68] */ TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16), 714 /* [6C] */ TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16), 715 716 /* [70] */ TNSZ("vpshufd",VEX_MXI,16), TNSZ("vgrp71",VEX_XXI,16), TNSZ("vgrp72",VEX_XXI,16), TNSZ("vgrp73",VEX_XXI,16), 717 /* [74] */ TNSZ("vpcmpeqb",VEX_RMrX,16), TNSZ("vpcmpeqw",VEX_RMrX,16), TNSZ("vpcmpeqd",VEX_RMrX,16), INVALID, 718 /* [78] */ INVALID, INVALID, INVALID, INVALID, 719 /* [7C] */ TNSZ("vhaddpd",VEX_RMrX,16), TNSZ("vhsubpd",VEX_RMrX,16), TNSZ("vmovd",VEX_RR,4), TNSZ("vmovdqa",VEX_RX,16), 720 721 /* [80] */ INVALID, INVALID, INVALID, INVALID, 722 /* [84] */ INVALID, INVALID, INVALID, INVALID, 723 /* [88] */ INVALID, INVALID, INVALID, INVALID, 724 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 725 726 /* [90] */ INVALID, INVALID, INVALID, INVALID, 727 /* [94] */ INVALID, INVALID, INVALID, INVALID, 728 /* [98] */ INVALID, INVALID, INVALID, INVALID, 729 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 730 731 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 732 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 733 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 734 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 735 736 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 737 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 738 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 739 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 740 741 /* [C0] */ INVALID, INVALID, TNSZ("vcmppd",VEX_RMRX,16), INVALID, 742 /* [C4] */ TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR), TNSZ("vshufpd",VEX_RMRX,16), INVALID, 743 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 744 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 745 746 /* [D0] */ TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16), TNSZ("vpsrld",VEX_RMrX,16), TNSZ("vpsrlq",VEX_RMrX,16), 747 /* [D4] */ TNSZ("vpaddq",VEX_RMrX,16), TNSZ("vpmullw",VEX_RMrX,16), TNSZ("vmovq",VEX_RX,8), TNS("vpmovmskb",VEX_MR), 748 /* [D8] */ TNSZ("vpsubusb",VEX_RMrX,16), TNSZ("vpsubusw",VEX_RMrX,16), TNSZ("vpminub",VEX_RMrX,16), TNSZ("vpand",VEX_RMrX,16), 749 /* [DC] */ TNSZ("vpaddusb",VEX_RMrX,16), TNSZ("vpaddusw",VEX_RMrX,16), TNSZ("vpmaxub",VEX_RMrX,16), TNSZ("vpandn",VEX_RMrX,16), 750 751 /* [E0] */ TNSZ("vpavgb",VEX_RMrX,16), TNSZ("vpsraw",VEX_RMrX,16), TNSZ("vpsrad",VEX_RMrX,16), TNSZ("vpavgw",VEX_RMrX,16), 752 /* [E4] */ TNSZ("vpmulhuw",VEX_RMrX,16), TNSZ("vpmulhw",VEX_RMrX,16), TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16), 753 /* [E8] */ TNSZ("vpsubsb",VEX_RMrX,16), TNSZ("vpsubsw",VEX_RMrX,16), TNSZ("vpminsw",VEX_RMrX,16), TNSZ("vpor",VEX_RMrX,16), 754 /* [EC] */ TNSZ("vpaddsb",VEX_RMrX,16), TNSZ("vpaddsw",VEX_RMrX,16), TNSZ("vpmaxsw",VEX_RMrX,16), TNSZ("vpxor",VEX_RMrX,16), 755 756 /* [F0] */ INVALID, TNSZ("vpsllw",VEX_RMrX,16), TNSZ("vpslld",VEX_RMrX,16), TNSZ("vpsllq",VEX_RMrX,16), 757 /* [F4] */ TNSZ("vpmuludq",VEX_RMrX,16), TNSZ("vpmaddwd",VEX_RMrX,16), TNSZ("vpsadbw",VEX_RMrX,16), TNS("vmaskmovdqu",VEX_MX), 758 /* [F8] */ TNSZ("vpsubb",VEX_RMrX,16), TNSZ("vpsubw",VEX_RMrX,16), TNSZ("vpsubd",VEX_RMrX,16), TNSZ("vpsubq",VEX_RMrX,16), 759 /* [FC] */ TNSZ("vpaddb",VEX_RMrX,16), TNSZ("vpaddw",VEX_RMrX,16), TNSZ("vpaddd",VEX_RMrX,16), INVALID, 760 }; 761 762 /* 763 * Decode table for SIMD instructions with the repnz (0xf2) prefix. 764 */ 765 const instable_t dis_opSIMDrepnz[256] = { 766 /* [00] */ INVALID, INVALID, INVALID, INVALID, 767 /* [04] */ INVALID, INVALID, INVALID, INVALID, 768 /* [08] */ INVALID, INVALID, INVALID, INVALID, 769 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 770 771 /* [10] */ TNSZ("movsd",XMM,8), TNSZ("movsd",XMMS,8), INVALID, INVALID, 772 /* [14] */ INVALID, INVALID, INVALID, INVALID, 773 /* [18] */ INVALID, INVALID, INVALID, INVALID, 774 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 775 776 /* [20] */ INVALID, INVALID, INVALID, INVALID, 777 /* [24] */ INVALID, INVALID, INVALID, INVALID, 778 /* [28] */ INVALID, INVALID, TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8), 779 /* [2C] */ TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID, INVALID, 780 781 /* [30] */ INVALID, INVALID, INVALID, INVALID, 782 /* [34] */ INVALID, INVALID, INVALID, INVALID, 783 /* [38] */ INVALID, INVALID, INVALID, INVALID, 784 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 785 786 /* [40] */ INVALID, INVALID, INVALID, INVALID, 787 /* [44] */ INVALID, INVALID, INVALID, INVALID, 788 /* [48] */ INVALID, INVALID, INVALID, INVALID, 789 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 790 791 /* [50] */ INVALID, TNSZ("sqrtsd",XMM,8), INVALID, INVALID, 792 /* [54] */ INVALID, INVALID, INVALID, INVALID, 793 /* [58] */ TNSZ("addsd",XMM,8), TNSZ("mulsd",XMM,8), TNSZ("cvtsd2ss",XMM,8), INVALID, 794 /* [5C] */ TNSZ("subsd",XMM,8), TNSZ("minsd",XMM,8), TNSZ("divsd",XMM,8), TNSZ("maxsd",XMM,8), 795 796 /* [60] */ INVALID, INVALID, INVALID, INVALID, 797 /* [64] */ INVALID, INVALID, INVALID, INVALID, 798 /* [68] */ INVALID, INVALID, INVALID, INVALID, 799 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 800 801 /* [70] */ TNSZ("pshuflw",XMMP,16),INVALID, INVALID, INVALID, 802 /* [74] */ INVALID, INVALID, INVALID, INVALID, 803 /* [78] */ TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID, INVALID, 804 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 805 806 /* [80] */ INVALID, INVALID, INVALID, INVALID, 807 /* [84] */ INVALID, INVALID, INVALID, INVALID, 808 /* [88] */ INVALID, INVALID, INVALID, INVALID, 809 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 810 811 /* [90] */ INVALID, INVALID, INVALID, INVALID, 812 /* [94] */ INVALID, INVALID, INVALID, INVALID, 813 /* [98] */ INVALID, INVALID, INVALID, INVALID, 814 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 815 816 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 817 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 818 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 819 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 820 821 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 822 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 823 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 824 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 825 826 /* [C0] */ INVALID, INVALID, TNSZ("cmpsd",XMMP,8), INVALID, 827 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 828 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 829 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 830 831 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 832 /* [D4] */ INVALID, INVALID, TNS("movdq2q",XMMXM), INVALID, 833 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 834 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 835 836 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 837 /* [E4] */ INVALID, INVALID, TNSZ("cvtpd2dq",XMM,16),INVALID, 838 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 839 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 840 841 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 842 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 843 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 844 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 845 }; 846 847 const instable_t dis_opAVXF20F[256] = { 848 /* [00] */ INVALID, INVALID, INVALID, INVALID, 849 /* [04] */ INVALID, INVALID, INVALID, INVALID, 850 /* [08] */ INVALID, INVALID, INVALID, INVALID, 851 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 852 853 /* [10] */ TNSZ("vmovsd",VEX_RMrX,8), TNSZ("vmovsd",VEX_RRX,8), TNSZ("vmovddup",VEX_MX,8), INVALID, 854 /* [14] */ INVALID, INVALID, INVALID, INVALID, 855 /* [18] */ INVALID, INVALID, INVALID, INVALID, 856 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 857 858 /* [20] */ INVALID, INVALID, INVALID, INVALID, 859 /* [24] */ INVALID, INVALID, INVALID, INVALID, 860 /* [28] */ INVALID, INVALID, TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID, 861 /* [2C] */ TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID, INVALID, 862 863 /* [30] */ INVALID, INVALID, INVALID, INVALID, 864 /* [34] */ INVALID, INVALID, INVALID, INVALID, 865 /* [38] */ INVALID, INVALID, INVALID, INVALID, 866 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 867 868 /* [40] */ INVALID, INVALID, INVALID, INVALID, 869 /* [44] */ INVALID, INVALID, INVALID, INVALID, 870 /* [48] */ INVALID, INVALID, INVALID, INVALID, 871 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 872 873 /* [50] */ INVALID, TNSZ("vsqrtsd",VEX_RMrX,8), INVALID, INVALID, 874 /* [54] */ INVALID, INVALID, INVALID, INVALID, 875 /* [58] */ TNSZ("vaddsd",VEX_RMrX,8), TNSZ("vmulsd",VEX_RMrX,8), TNSZ("vcvtsd2ss",VEX_RMrX,8), INVALID, 876 /* [5C] */ TNSZ("vsubsd",VEX_RMrX,8), TNSZ("vminsd",VEX_RMrX,8), TNSZ("vdivsd",VEX_RMrX,8), TNSZ("vmaxsd",VEX_RMrX,8), 877 878 /* [60] */ INVALID, INVALID, INVALID, INVALID, 879 /* [64] */ INVALID, INVALID, INVALID, INVALID, 880 /* [68] */ INVALID, INVALID, INVALID, INVALID, 881 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 882 883 /* [70] */ TNSZ("vpshuflw",VEX_MXI,16),INVALID, INVALID, INVALID, 884 /* [74] */ INVALID, INVALID, INVALID, INVALID, 885 /* [78] */ INVALID, INVALID, INVALID, INVALID, 886 /* [7C] */ TNSZ("vhaddps",VEX_RMrX,8), TNSZ("vhsubps",VEX_RMrX,8), INVALID, INVALID, 887 888 /* [80] */ INVALID, INVALID, INVALID, INVALID, 889 /* [84] */ INVALID, INVALID, INVALID, INVALID, 890 /* [88] */ INVALID, INVALID, INVALID, INVALID, 891 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 892 893 /* [90] */ INVALID, INVALID, INVALID, INVALID, 894 /* [94] */ INVALID, INVALID, INVALID, INVALID, 895 /* [98] */ INVALID, INVALID, INVALID, INVALID, 896 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 897 898 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 899 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 900 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 901 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 902 903 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 904 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 905 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 906 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 907 908 /* [C0] */ INVALID, INVALID, TNSZ("vcmpsd",VEX_RMRX,8), INVALID, 909 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 910 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 911 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 912 913 /* [D0] */ TNSZ("vaddsubps",VEX_RMrX,8), INVALID, INVALID, INVALID, 914 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 915 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 916 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 917 918 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 919 /* [E4] */ INVALID, INVALID, TNSZ("vcvtpd2dq",VEX_MX,16),INVALID, 920 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 921 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 922 923 /* [F0] */ TNSZ("vlddqu",VEX_MX,16), INVALID, INVALID, INVALID, 924 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 925 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 926 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 927 }; 928 929 /* 930 * Decode table for SIMD instructions with the repz (0xf3) prefix. 931 */ 932 const instable_t dis_opSIMDrepz[256] = { 933 /* [00] */ INVALID, INVALID, INVALID, INVALID, 934 /* [04] */ INVALID, INVALID, INVALID, INVALID, 935 /* [08] */ INVALID, INVALID, INVALID, INVALID, 936 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 937 938 /* [10] */ TNSZ("movss",XMM,4), TNSZ("movss",XMMS,4), INVALID, INVALID, 939 /* [14] */ INVALID, INVALID, INVALID, INVALID, 940 /* [18] */ INVALID, INVALID, INVALID, INVALID, 941 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 942 943 /* [20] */ INVALID, INVALID, INVALID, INVALID, 944 /* [24] */ INVALID, INVALID, INVALID, INVALID, 945 /* [28] */ INVALID, INVALID, TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4), 946 /* [2C] */ TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID, INVALID, 947 948 /* [30] */ INVALID, INVALID, INVALID, INVALID, 949 /* [34] */ INVALID, INVALID, INVALID, INVALID, 950 /* [38] */ INVALID, INVALID, INVALID, INVALID, 951 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 952 953 /* [40] */ INVALID, INVALID, INVALID, INVALID, 954 /* [44] */ INVALID, INVALID, INVALID, INVALID, 955 /* [48] */ INVALID, INVALID, INVALID, INVALID, 956 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 957 958 /* [50] */ INVALID, TNSZ("sqrtss",XMM,4), TNSZ("rsqrtss",XMM,4), TNSZ("rcpss",XMM,4), 959 /* [54] */ INVALID, INVALID, INVALID, INVALID, 960 /* [58] */ TNSZ("addss",XMM,4), TNSZ("mulss",XMM,4), TNSZ("cvtss2sd",XMM,4), TNSZ("cvttps2dq",XMM,16), 961 /* [5C] */ TNSZ("subss",XMM,4), TNSZ("minss",XMM,4), TNSZ("divss",XMM,4), TNSZ("maxss",XMM,4), 962 963 /* [60] */ INVALID, INVALID, INVALID, INVALID, 964 /* [64] */ INVALID, INVALID, INVALID, INVALID, 965 /* [68] */ INVALID, INVALID, INVALID, INVALID, 966 /* [6C] */ INVALID, INVALID, INVALID, TNSZ("movdqu",XMM,16), 967 968 /* [70] */ TNSZ("pshufhw",XMMP,16),INVALID, INVALID, INVALID, 969 /* [74] */ INVALID, INVALID, INVALID, INVALID, 970 /* [78] */ INVALID, INVALID, INVALID, INVALID, 971 /* [7C] */ INVALID, INVALID, TNSZ("movq",XMM,8), TNSZ("movdqu",XMMS,16), 972 973 /* [80] */ INVALID, INVALID, INVALID, INVALID, 974 /* [84] */ INVALID, INVALID, INVALID, INVALID, 975 /* [88] */ INVALID, INVALID, INVALID, INVALID, 976 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 977 978 /* [90] */ INVALID, INVALID, INVALID, INVALID, 979 /* [94] */ INVALID, INVALID, INVALID, INVALID, 980 /* [98] */ INVALID, INVALID, INVALID, INVALID, 981 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 982 983 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 984 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 985 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 986 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 987 988 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 989 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 990 /* [B8] */ TS("popcnt",MRw), INVALID, INVALID, INVALID, 991 /* [BC] */ INVALID, TS("lzcnt",MRw), INVALID, INVALID, 992 993 /* [C0] */ INVALID, INVALID, TNSZ("cmpss",XMMP,4), INVALID, 994 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 995 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 996 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 997 998 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 999 /* [D4] */ INVALID, INVALID, TNS("movq2dq",XMMMX), INVALID, 1000 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 1001 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 1002 1003 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1004 /* [E4] */ INVALID, INVALID, TNSZ("cvtdq2pd",XMM,8), INVALID, 1005 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1006 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1007 1008 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 1009 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1010 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1011 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1012 }; 1013 1014 const instable_t dis_opAVXF30F[256] = { 1015 /* [00] */ INVALID, INVALID, INVALID, INVALID, 1016 /* [04] */ INVALID, INVALID, INVALID, INVALID, 1017 /* [08] */ INVALID, INVALID, INVALID, INVALID, 1018 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 1019 1020 /* [10] */ TNSZ("vmovss",VEX_RMrX,4), TNSZ("vmovss",VEX_RRX,4), TNSZ("vmovsldup",VEX_MX,4), INVALID, 1021 /* [14] */ INVALID, INVALID, TNSZ("vmovshdup",VEX_MX,4), INVALID, 1022 /* [18] */ INVALID, INVALID, INVALID, INVALID, 1023 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 1024 1025 /* [20] */ INVALID, INVALID, INVALID, INVALID, 1026 /* [24] */ INVALID, INVALID, INVALID, INVALID, 1027 /* [28] */ INVALID, INVALID, TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID, 1028 /* [2C] */ TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID, INVALID, 1029 1030 /* [30] */ INVALID, INVALID, INVALID, INVALID, 1031 /* [34] */ INVALID, INVALID, INVALID, INVALID, 1032 /* [38] */ INVALID, INVALID, INVALID, INVALID, 1033 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 1034 1035 /* [40] */ INVALID, INVALID, INVALID, INVALID, 1036 /* [44] */ INVALID, INVALID, INVALID, INVALID, 1037 /* [48] */ INVALID, INVALID, INVALID, INVALID, 1038 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 1039 1040 /* [50] */ INVALID, TNSZ("vsqrtss",VEX_RMrX,4), TNSZ("vrsqrtss",VEX_RMrX,4), TNSZ("vrcpss",VEX_RMrX,4), 1041 /* [54] */ INVALID, INVALID, INVALID, INVALID, 1042 /* [58] */ TNSZ("vaddss",VEX_RMrX,4), TNSZ("vmulss",VEX_RMrX,4), TNSZ("vcvtss2sd",VEX_RMrX,4), TNSZ("vcvttps2dq",VEX_MX,16), 1043 /* [5C] */ TNSZ("vsubss",VEX_RMrX,4), TNSZ("vminss",VEX_RMrX,4), TNSZ("vdivss",VEX_RMrX,4), TNSZ("vmaxss",VEX_RMrX,4), 1044 1045 /* [60] */ INVALID, INVALID, INVALID, INVALID, 1046 /* [64] */ INVALID, INVALID, INVALID, INVALID, 1047 /* [68] */ INVALID, INVALID, INVALID, INVALID, 1048 /* [6C] */ INVALID, INVALID, INVALID, TNSZ("vmovdqu",VEX_MX,16), 1049 1050 /* [70] */ TNSZ("vpshufhw",VEX_MXI,16),INVALID, INVALID, INVALID, 1051 /* [74] */ INVALID, INVALID, INVALID, INVALID, 1052 /* [78] */ INVALID, INVALID, INVALID, INVALID, 1053 /* [7C] */ INVALID, INVALID, TNSZ("vmovq",VEX_MX,8), TNSZ("vmovdqu",VEX_RX,16), 1054 1055 /* [80] */ INVALID, INVALID, INVALID, INVALID, 1056 /* [84] */ INVALID, INVALID, INVALID, INVALID, 1057 /* [88] */ INVALID, INVALID, INVALID, INVALID, 1058 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 1059 1060 /* [90] */ INVALID, INVALID, INVALID, INVALID, 1061 /* [94] */ INVALID, INVALID, INVALID, INVALID, 1062 /* [98] */ INVALID, INVALID, INVALID, INVALID, 1063 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 1064 1065 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 1066 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 1067 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 1068 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 1069 1070 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 1071 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 1072 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 1073 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 1074 1075 /* [C0] */ INVALID, INVALID, TNSZ("vcmpss",VEX_RMRX,4), INVALID, 1076 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 1077 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1078 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1079 1080 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 1081 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 1082 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 1083 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 1084 1085 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1086 /* [E4] */ INVALID, INVALID, TNSZ("vcvtdq2pd",VEX_MX,8), INVALID, 1087 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1088 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1089 1090 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 1091 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1092 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1093 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1094 }; 1095 /* 1096 * The following two tables are used to encode crc32 and movbe 1097 * since they share the same opcodes. 1098 */ 1099 const instable_t dis_op0F38F0[2] = { 1100 /* [00] */ TNS("crc32b",CRC32), 1101 TS("movbe",MOVBE), 1102 }; 1103 1104 const instable_t dis_op0F38F1[2] = { 1105 /* [00] */ TS("crc32",CRC32), 1106 TS("movbe",MOVBE), 1107 }; 1108 1109 const instable_t dis_op0F38[256] = { 1110 /* [00] */ TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16), 1111 /* [04] */ TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16), TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16), 1112 /* [08] */ TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16), 1113 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 1114 1115 /* [10] */ TNSZ("pblendvb",XMM_66r,16),INVALID, INVALID, INVALID, 1116 /* [14] */ TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID, TNSZ("ptest",XMM_66r,16), 1117 /* [18] */ INVALID, INVALID, INVALID, INVALID, 1118 /* [1C] */ TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID, 1119 1120 /* [20] */ TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16), 1121 /* [24] */ TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID, INVALID, 1122 /* [28] */ TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16), 1123 /* [2C] */ INVALID, INVALID, INVALID, INVALID, 1124 1125 /* [30] */ TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16), 1126 /* [34] */ TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID, TNSZ("pcmpgtq",XMM_66r,16), 1127 /* [38] */ TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16), 1128 /* [3C] */ TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16), 1129 1130 /* [40] */ TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID, INVALID, 1131 /* [44] */ INVALID, INVALID, INVALID, INVALID, 1132 /* [48] */ INVALID, INVALID, INVALID, INVALID, 1133 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 1134 1135 /* [50] */ INVALID, INVALID, INVALID, INVALID, 1136 /* [54] */ INVALID, INVALID, INVALID, INVALID, 1137 /* [58] */ INVALID, INVALID, INVALID, INVALID, 1138 /* [5C] */ INVALID, INVALID, INVALID, INVALID, 1139 1140 /* [60] */ INVALID, INVALID, INVALID, INVALID, 1141 /* [64] */ INVALID, INVALID, INVALID, INVALID, 1142 /* [68] */ INVALID, INVALID, INVALID, INVALID, 1143 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 1144 1145 /* [70] */ INVALID, INVALID, INVALID, INVALID, 1146 /* [74] */ INVALID, INVALID, INVALID, INVALID, 1147 /* [78] */ INVALID, INVALID, INVALID, INVALID, 1148 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 1149 1150 /* [80] */ INVALID, INVALID, INVALID, INVALID, 1151 /* [84] */ INVALID, INVALID, INVALID, INVALID, 1152 /* [88] */ INVALID, INVALID, INVALID, INVALID, 1153 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 1154 1155 /* [90] */ INVALID, INVALID, INVALID, INVALID, 1156 /* [94] */ INVALID, INVALID, INVALID, INVALID, 1157 /* [98] */ INVALID, INVALID, INVALID, INVALID, 1158 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 1159 1160 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 1161 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 1162 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 1163 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 1164 1165 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 1166 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 1167 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 1168 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 1169 1170 /* [C0] */ INVALID, INVALID, INVALID, INVALID, 1171 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 1172 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1173 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1174 1175 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 1176 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 1177 /* [D8] */ INVALID, INVALID, INVALID, TNSZ("aesimc",XMM_66r,16), 1178 /* [DC] */ TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16), 1179 1180 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1181 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 1182 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1183 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1184 /* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID, 1185 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1186 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1187 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1188 }; 1189 1190 const instable_t dis_opAVX660F38[256] = { 1191 /* [00] */ TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16), 1192 /* [04] */ TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16), TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16), 1193 /* [08] */ TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16), 1194 /* [0C] */ TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8), TNSZ("vtestpd",VEX_RRI,16), 1195 1196 /* [10] */ INVALID, INVALID, INVALID, INVALID, 1197 /* [14] */ INVALID, INVALID, INVALID, TNSZ("vptest",VEX_RRI,16), 1198 /* [18] */ TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID, 1199 /* [1C] */ TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID, 1200 1201 /* [20] */ TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16), 1202 /* [24] */ TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID, INVALID, 1203 /* [28] */ TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16), 1204 /* [2C] */ TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16), 1205 1206 /* [30] */ TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16), 1207 /* [34] */ TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),INVALID, TNSZ("vpcmpgtq",VEX_RMrX,16), 1208 /* [38] */ TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16), 1209 /* [3C] */ TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16), 1210 1211 /* [40] */ TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID, INVALID, 1212 /* [44] */ INVALID, INVALID, INVALID, INVALID, 1213 /* [48] */ INVALID, INVALID, INVALID, INVALID, 1214 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 1215 1216 /* [50] */ INVALID, INVALID, INVALID, INVALID, 1217 /* [54] */ INVALID, INVALID, INVALID, INVALID, 1218 /* [58] */ INVALID, INVALID, INVALID, INVALID, 1219 /* [5C] */ INVALID, INVALID, INVALID, INVALID, 1220 1221 /* [60] */ INVALID, INVALID, INVALID, INVALID, 1222 /* [64] */ INVALID, INVALID, INVALID, INVALID, 1223 /* [68] */ INVALID, INVALID, INVALID, INVALID, 1224 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 1225 1226 /* [70] */ INVALID, INVALID, INVALID, INVALID, 1227 /* [74] */ INVALID, INVALID, INVALID, INVALID, 1228 /* [78] */ INVALID, INVALID, INVALID, INVALID, 1229 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 1230 1231 /* [80] */ INVALID, INVALID, INVALID, INVALID, 1232 /* [84] */ INVALID, INVALID, INVALID, INVALID, 1233 /* [88] */ INVALID, INVALID, INVALID, INVALID, 1234 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 1235 1236 /* [90] */ INVALID, INVALID, INVALID, INVALID, 1237 /* [94] */ INVALID, INVALID, INVALID, INVALID, 1238 /* [98] */ INVALID, INVALID, INVALID, INVALID, 1239 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 1240 1241 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 1242 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 1243 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 1244 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 1245 1246 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 1247 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 1248 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 1249 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 1250 1251 /* [C0] */ INVALID, INVALID, INVALID, INVALID, 1252 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 1253 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1254 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1255 1256 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 1257 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 1258 /* [D8] */ INVALID, INVALID, INVALID, TNSZ("vaesimc",VEX_MX,16), 1259 /* [DC] */ TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16), 1260 1261 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1262 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 1263 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1264 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1265 /* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID, 1266 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1267 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1268 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1269 }; 1270 1271 const instable_t dis_op0F3A[256] = { 1272 /* [00] */ INVALID, INVALID, INVALID, INVALID, 1273 /* [04] */ INVALID, INVALID, INVALID, INVALID, 1274 /* [08] */ TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16), 1275 /* [0C] */ TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16), 1276 1277 /* [10] */ INVALID, INVALID, INVALID, INVALID, 1278 /* [14] */ TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16), 1279 /* [18] */ INVALID, INVALID, INVALID, INVALID, 1280 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 1281 1282 /* [20] */ TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID, 1283 /* [24] */ INVALID, INVALID, INVALID, INVALID, 1284 /* [28] */ INVALID, INVALID, INVALID, INVALID, 1285 /* [2C] */ INVALID, INVALID, INVALID, INVALID, 1286 1287 /* [30] */ INVALID, INVALID, INVALID, INVALID, 1288 /* [34] */ INVALID, INVALID, INVALID, INVALID, 1289 /* [38] */ INVALID, INVALID, INVALID, INVALID, 1290 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 1291 1292 /* [40] */ TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID, 1293 /* [44] */ TNSZ("pclmulqdq",XMMP_66r,16),INVALID, INVALID, INVALID, 1294 /* [48] */ INVALID, INVALID, INVALID, INVALID, 1295 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 1296 1297 /* [50] */ INVALID, INVALID, INVALID, INVALID, 1298 /* [54] */ INVALID, INVALID, INVALID, INVALID, 1299 /* [58] */ INVALID, INVALID, INVALID, INVALID, 1300 /* [5C] */ INVALID, INVALID, INVALID, INVALID, 1301 1302 /* [60] */ TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16), 1303 /* [64] */ INVALID, INVALID, INVALID, INVALID, 1304 /* [68] */ INVALID, INVALID, INVALID, INVALID, 1305 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 1306 1307 /* [70] */ INVALID, INVALID, INVALID, INVALID, 1308 /* [74] */ INVALID, INVALID, INVALID, INVALID, 1309 /* [78] */ INVALID, INVALID, INVALID, INVALID, 1310 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 1311 1312 /* [80] */ INVALID, INVALID, INVALID, INVALID, 1313 /* [84] */ INVALID, INVALID, INVALID, INVALID, 1314 /* [88] */ INVALID, INVALID, INVALID, INVALID, 1315 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 1316 1317 /* [90] */ INVALID, INVALID, INVALID, INVALID, 1318 /* [94] */ INVALID, INVALID, INVALID, INVALID, 1319 /* [98] */ INVALID, INVALID, INVALID, INVALID, 1320 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 1321 1322 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 1323 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 1324 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 1325 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 1326 1327 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 1328 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 1329 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 1330 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 1331 1332 /* [C0] */ INVALID, INVALID, INVALID, INVALID, 1333 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 1334 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1335 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1336 1337 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 1338 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 1339 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 1340 /* [DC] */ INVALID, INVALID, INVALID, TNSZ("aeskeygenassist",XMMP_66r,16), 1341 1342 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1343 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 1344 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1345 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1346 1347 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 1348 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1349 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1350 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1351 }; 1352 1353 const instable_t dis_opAVX660F3A[256] = { 1354 /* [00] */ INVALID, INVALID, INVALID, INVALID, 1355 /* [04] */ TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID, 1356 /* [08] */ TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16), 1357 /* [0C] */ TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16), 1358 1359 /* [10] */ INVALID, INVALID, INVALID, INVALID, 1360 /* [14] */ TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16), 1361 /* [18] */ TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID, INVALID, 1362 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 1363 1364 /* [20] */ TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID, 1365 /* [24] */ INVALID, INVALID, INVALID, INVALID, 1366 /* [28] */ INVALID, INVALID, INVALID, INVALID, 1367 /* [2C] */ INVALID, INVALID, INVALID, INVALID, 1368 1369 /* [30] */ INVALID, INVALID, INVALID, INVALID, 1370 /* [34] */ INVALID, INVALID, INVALID, INVALID, 1371 /* [38] */ INVALID, INVALID, INVALID, INVALID, 1372 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 1373 1374 /* [40] */ TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID, 1375 /* [44] */ TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID, INVALID, INVALID, 1376 /* [48] */ INVALID, INVALID, TNSZ("vblendvps",VEX_RMRX,8), TNSZ("vblendvpd",VEX_RMRX,16), 1377 /* [4C] */ TNSZ("vpblendvb",VEX_RMRX,16),INVALID, INVALID, INVALID, 1378 1379 /* [50] */ INVALID, INVALID, INVALID, INVALID, 1380 /* [54] */ INVALID, INVALID, INVALID, INVALID, 1381 /* [58] */ INVALID, INVALID, INVALID, INVALID, 1382 /* [5C] */ INVALID, INVALID, INVALID, INVALID, 1383 1384 /* [60] */ TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16), 1385 /* [64] */ INVALID, INVALID, INVALID, INVALID, 1386 /* [68] */ INVALID, INVALID, INVALID, INVALID, 1387 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 1388 1389 /* [70] */ INVALID, INVALID, INVALID, INVALID, 1390 /* [74] */ INVALID, INVALID, INVALID, INVALID, 1391 /* [78] */ INVALID, INVALID, INVALID, INVALID, 1392 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 1393 1394 /* [80] */ INVALID, INVALID, INVALID, INVALID, 1395 /* [84] */ INVALID, INVALID, INVALID, INVALID, 1396 /* [88] */ INVALID, INVALID, INVALID, INVALID, 1397 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 1398 1399 /* [90] */ INVALID, INVALID, INVALID, INVALID, 1400 /* [94] */ INVALID, INVALID, INVALID, INVALID, 1401 /* [98] */ INVALID, INVALID, INVALID, INVALID, 1402 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 1403 1404 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 1405 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 1406 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 1407 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 1408 1409 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 1410 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 1411 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 1412 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 1413 1414 /* [C0] */ INVALID, INVALID, INVALID, INVALID, 1415 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 1416 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1417 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1418 1419 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 1420 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 1421 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 1422 /* [DC] */ INVALID, INVALID, INVALID, TNSZ("vaeskeygenassist",VEX_MXI,16), 1423 1424 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1425 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 1426 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1427 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1428 1429 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 1430 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1431 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1432 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1433 }; 1434 1435 /* 1436 * Decode table for 0x0F opcodes 1437 */ 1438 1439 const instable_t dis_op0F[16][16] = { 1440 { 1441 /* [00] */ IND(dis_op0F00), IND(dis_op0F01), TNS("lar",MR), TNS("lsl",MR), 1442 /* [04] */ INVALID, TNS("syscall",NORM), TNS("clts",NORM), TNS("sysret",NORM), 1443 /* [08] */ TNS("invd",NORM), TNS("wbinvd",NORM), INVALID, TNS("ud2",NORM), 1444 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 1445 }, { 1446 /* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8), 1447 /* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8), 1448 /* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID, 1449 /* [1C] */ INVALID, INVALID, INVALID, TS("nopw", Mw), 1450 }, { 1451 /* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), 1452 /* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID, 1453 /* [28] */ TNSZ("movaps",XMMO,16), TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16), 1454 /* [2C] */ TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4), 1455 }, { 1456 /* [30] */ TNS("wrmsr",NORM), TNS("rdtsc",NORM), TNS("rdmsr",NORM), TNS("rdpmc",NORM), 1457 /* [34] */ TNSx("sysenter",NORM), TNSx("sysexit",NORM), INVALID, INVALID, 1458 /* [38] */ INVALID, INVALID, INVALID, INVALID, 1459 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 1460 }, { 1461 /* [40] */ TS("cmovx.o",MR), TS("cmovx.no",MR), TS("cmovx.b",MR), TS("cmovx.ae",MR), 1462 /* [44] */ TS("cmovx.e",MR), TS("cmovx.ne",MR), TS("cmovx.be",MR), TS("cmovx.a",MR), 1463 /* [48] */ TS("cmovx.s",MR), TS("cmovx.ns",MR), TS("cmovx.pe",MR), TS("cmovx.po",MR), 1464 /* [4C] */ TS("cmovx.l",MR), TS("cmovx.ge",MR), TS("cmovx.le",MR), TS("cmovx.g",MR), 1465 }, { 1466 /* [50] */ TNS("movmskps",XMMOX3), TNSZ("sqrtps",XMMO,16), TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16), 1467 /* [54] */ TNSZ("andps",XMMO,16), TNSZ("andnps",XMMO,16), TNSZ("orps",XMMO,16), TNSZ("xorps",XMMO,16), 1468 /* [58] */ TNSZ("addps",XMMO,16), TNSZ("mulps",XMMO,16), TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16), 1469 /* [5C] */ TNSZ("subps",XMMO,16), TNSZ("minps",XMMO,16), TNSZ("divps",XMMO,16), TNSZ("maxps",XMMO,16), 1470 }, { 1471 /* [60] */ TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8), 1472 /* [64] */ TNSZ("pcmpgtb",MMO,8), TNSZ("pcmpgtw",MMO,8), TNSZ("pcmpgtd",MMO,8), TNSZ("packuswb",MMO,8), 1473 /* [68] */ TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8), 1474 /* [6C] */ TNSZ("INVALID",MMO,0), TNSZ("INVALID",MMO,0), TNSZ("movd",MMO,4), TNSZ("movq",MMO,8), 1475 }, { 1476 /* [70] */ TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR), TNS("psrXXX",MR), TNS("psrXXX",MR), 1477 /* [74] */ TNSZ("pcmpeqb",MMO,8), TNSZ("pcmpeqw",MMO,8), TNSZ("pcmpeqd",MMO,8), TNS("emms",NORM), 1478 /* [78] */ TNS("INVALID",XMMO), TNS("INVALID",XMMO), INVALID, INVALID, 1479 /* [7C] */ INVALID, INVALID, TNSZ("movd",MMOS,4), TNSZ("movq",MMOS,8), 1480 }, { 1481 /* [80] */ TNS("jo",D), TNS("jno",D), TNS("jb",D), TNS("jae",D), 1482 /* [84] */ TNS("je",D), TNS("jne",D), TNS("jbe",D), TNS("ja",D), 1483 /* [88] */ TNS("js",D), TNS("jns",D), TNS("jp",D), TNS("jnp",D), 1484 /* [8C] */ TNS("jl",D), TNS("jge",D), TNS("jle",D), TNS("jg",D), 1485 }, { 1486 /* [90] */ TNS("seto",Mb), TNS("setno",Mb), TNS("setb",Mb), TNS("setae",Mb), 1487 /* [94] */ TNS("sete",Mb), TNS("setne",Mb), TNS("setbe",Mb), TNS("seta",Mb), 1488 /* [98] */ TNS("sets",Mb), TNS("setns",Mb), TNS("setp",Mb), TNS("setnp",Mb), 1489 /* [9C] */ TNS("setl",Mb), TNS("setge",Mb), TNS("setle",Mb), TNS("setg",Mb), 1490 }, { 1491 /* [A0] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("cpuid",NORM), TS("bt",RMw), 1492 /* [A4] */ TS("shld",DSHIFT), TS("shld",DSHIFTcl), INVALID, INVALID, 1493 /* [A8] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("rsm",NORM), TS("bts",RMw), 1494 /* [AC] */ TS("shrd",DSHIFT), TS("shrd",DSHIFTcl), IND(dis_op0FAE), TS("imul",MRw), 1495 }, { 1496 /* [B0] */ TNS("cmpxchgb",RMw), TS("cmpxchg",RMw), TS("lss",MR), TS("btr",RMw), 1497 /* [B4] */ TS("lfs",MR), TS("lgs",MR), TS("movzb",MOVZ), TNS("movzwl",MOVZ), 1498 /* [B8] */ TNS("INVALID",MRw), INVALID, IND(dis_op0FBA), TS("btc",RMw), 1499 /* [BC] */ TS("bsf",MRw), TS("bsr",MRw), TS("movsb",MOVZ), TNS("movswl",MOVZ), 1500 }, { 1501 /* [C0] */ TNS("xaddb",XADDB), TS("xadd",RMw), TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM), 1502 /* [C4] */ TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7), 1503 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1504 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1505 }, { 1506 /* [D0] */ INVALID, TNSZ("psrlw",MMO,8), TNSZ("psrld",MMO,8), TNSZ("psrlq",MMO,8), 1507 /* [D4] */ TNSZ("paddq",MMO,8), TNSZ("pmullw",MMO,8), TNSZ("INVALID",MMO,0), TNS("pmovmskb",MMOM3), 1508 /* [D8] */ TNSZ("psubusb",MMO,8), TNSZ("psubusw",MMO,8), TNSZ("pminub",MMO,8), TNSZ("pand",MMO,8), 1509 /* [DC] */ TNSZ("paddusb",MMO,8), TNSZ("paddusw",MMO,8), TNSZ("pmaxub",MMO,8), TNSZ("pandn",MMO,8), 1510 }, { 1511 /* [E0] */ TNSZ("pavgb",MMO,8), TNSZ("psraw",MMO,8), TNSZ("psrad",MMO,8), TNSZ("pavgw",MMO,8), 1512 /* [E4] */ TNSZ("pmulhuw",MMO,8), TNSZ("pmulhw",MMO,8), TNS("INVALID",XMMO), TNSZ("movntq",MMOMS,8), 1513 /* [E8] */ TNSZ("psubsb",MMO,8), TNSZ("psubsw",MMO,8), TNSZ("pminsw",MMO,8), TNSZ("por",MMO,8), 1514 /* [EC] */ TNSZ("paddsb",MMO,8), TNSZ("paddsw",MMO,8), TNSZ("pmaxsw",MMO,8), TNSZ("pxor",MMO,8), 1515 }, { 1516 /* [F0] */ INVALID, TNSZ("psllw",MMO,8), TNSZ("pslld",MMO,8), TNSZ("psllq",MMO,8), 1517 /* [F4] */ TNSZ("pmuludq",MMO,8), TNSZ("pmaddwd",MMO,8), TNSZ("psadbw",MMO,8), TNSZ("maskmovq",MMOIMPL,8), 1518 /* [F8] */ TNSZ("psubb",MMO,8), TNSZ("psubw",MMO,8), TNSZ("psubd",MMO,8), TNSZ("psubq",MMO,8), 1519 /* [FC] */ TNSZ("paddb",MMO,8), TNSZ("paddw",MMO,8), TNSZ("paddd",MMO,8), INVALID, 1520 } }; 1521 1522 const instable_t dis_opAVX0F[16][16] = { 1523 { 1524 /* [00] */ INVALID, INVALID, INVALID, INVALID, 1525 /* [04] */ INVALID, INVALID, INVALID, INVALID, 1526 /* [08] */ INVALID, INVALID, INVALID, INVALID, 1527 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 1528 }, { 1529 /* [10] */ TNSZ("vmovups",VEX_MX,16), TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8), TNSZ("vmovlps",VEX_RM,8), 1530 /* [14] */ TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8), 1531 /* [18] */ INVALID, INVALID, INVALID, INVALID, 1532 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 1533 }, { 1534 /* [20] */ INVALID, INVALID, INVALID, INVALID, 1535 /* [24] */ INVALID, INVALID, INVALID, INVALID, 1536 /* [28] */ TNSZ("vmovaps",VEX_MX,16), TNSZ("vmovaps",VEX_RX,16),INVALID, TNSZ("vmovntps",VEX_RM,16), 1537 /* [2C] */ INVALID, INVALID, TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4), 1538 }, { 1539 /* [30] */ INVALID, INVALID, INVALID, INVALID, 1540 /* [34] */ INVALID, INVALID, INVALID, INVALID, 1541 /* [38] */ INVALID, INVALID, INVALID, INVALID, 1542 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 1543 }, { 1544 /* [40] */ INVALID, INVALID, INVALID, INVALID, 1545 /* [44] */ INVALID, INVALID, INVALID, INVALID, 1546 /* [48] */ INVALID, INVALID, INVALID, INVALID, 1547 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 1548 }, { 1549 /* [50] */ TNS("vmovmskps",VEX_MR), TNSZ("vsqrtps",VEX_MX,16), TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16), 1550 /* [54] */ TNSZ("vandps",VEX_RMrX,16), TNSZ("vandnps",VEX_RMrX,16), TNSZ("vorps",VEX_RMrX,16), TNSZ("vxorps",VEX_RMrX,16), 1551 /* [58] */ TNSZ("vaddps",VEX_RMrX,16), TNSZ("vmulps",VEX_RMrX,16), TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16), 1552 /* [5C] */ TNSZ("vsubps",VEX_RMrX,16), TNSZ("vminps",VEX_RMrX,16), TNSZ("vdivps",VEX_RMrX,16), TNSZ("vmaxps",VEX_RMrX,16), 1553 }, { 1554 /* [60] */ INVALID, INVALID, INVALID, INVALID, 1555 /* [64] */ INVALID, INVALID, INVALID, INVALID, 1556 /* [68] */ INVALID, INVALID, INVALID, INVALID, 1557 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 1558 }, { 1559 /* [70] */ INVALID, INVALID, INVALID, INVALID, 1560 /* [74] */ INVALID, INVALID, INVALID, TNS("vzeroupper", VEX_NONE), 1561 /* [78] */ INVALID, INVALID, INVALID, INVALID, 1562 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 1563 }, { 1564 /* [80] */ INVALID, INVALID, INVALID, INVALID, 1565 /* [84] */ INVALID, INVALID, INVALID, INVALID, 1566 /* [88] */ INVALID, INVALID, INVALID, INVALID, 1567 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 1568 }, { 1569 /* [90] */ INVALID, INVALID, INVALID, INVALID, 1570 /* [94] */ INVALID, INVALID, INVALID, INVALID, 1571 /* [98] */ INVALID, INVALID, INVALID, INVALID, 1572 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 1573 }, { 1574 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 1575 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 1576 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 1577 /* [AC] */ INVALID, INVALID, TNSZ("vldmxcsr",VEX_MO,2), INVALID, 1578 }, { 1579 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 1580 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 1581 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 1582 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 1583 }, { 1584 /* [C0] */ INVALID, INVALID, TNSZ("vcmpps",VEX_RMRX,16),INVALID, 1585 /* [C4] */ INVALID, INVALID, TNSZ("vshufps",VEX_RMRX,16),INVALID, 1586 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1587 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1588 }, { 1589 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 1590 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 1591 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 1592 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 1593 }, { 1594 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 1595 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 1596 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 1597 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 1598 }, { 1599 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 1600 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 1601 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 1602 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 1603 } }; 1604 1605 /* 1606 * Decode table for 0x80 opcodes 1607 */ 1608 1609 const instable_t dis_op80[8] = { 1610 1611 /* [0] */ TNS("addb",IMlw), TNS("orb",IMw), TNS("adcb",IMlw), TNS("sbbb",IMlw), 1612 /* [4] */ TNS("andb",IMw), TNS("subb",IMlw), TNS("xorb",IMw), TNS("cmpb",IMlw), 1613 }; 1614 1615 1616 /* 1617 * Decode table for 0x81 opcodes. 1618 */ 1619 1620 const instable_t dis_op81[8] = { 1621 1622 /* [0] */ TS("add",IMlw), TS("or",IMw), TS("adc",IMlw), TS("sbb",IMlw), 1623 /* [4] */ TS("and",IMw), TS("sub",IMlw), TS("xor",IMw), TS("cmp",IMlw), 1624 }; 1625 1626 1627 /* 1628 * Decode table for 0x82 opcodes. 1629 */ 1630 1631 const instable_t dis_op82[8] = { 1632 1633 /* [0] */ TNSx("addb",IMlw), TNSx("orb",IMlw), TNSx("adcb",IMlw), TNSx("sbbb",IMlw), 1634 /* [4] */ TNSx("andb",IMlw), TNSx("subb",IMlw), TNSx("xorb",IMlw), TNSx("cmpb",IMlw), 1635 }; 1636 /* 1637 * Decode table for 0x83 opcodes. 1638 */ 1639 1640 const instable_t dis_op83[8] = { 1641 1642 /* [0] */ TS("add",IMlw), TS("or",IMlw), TS("adc",IMlw), TS("sbb",IMlw), 1643 /* [4] */ TS("and",IMlw), TS("sub",IMlw), TS("xor",IMlw), TS("cmp",IMlw), 1644 }; 1645 1646 /* 1647 * Decode table for 0xC0 opcodes. 1648 */ 1649 1650 const instable_t dis_opC0[8] = { 1651 1652 /* [0] */ TNS("rolb",MvI), TNS("rorb",MvI), TNS("rclb",MvI), TNS("rcrb",MvI), 1653 /* [4] */ TNS("shlb",MvI), TNS("shrb",MvI), INVALID, TNS("sarb",MvI), 1654 }; 1655 1656 /* 1657 * Decode table for 0xD0 opcodes. 1658 */ 1659 1660 const instable_t dis_opD0[8] = { 1661 1662 /* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv), 1663 /* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv), 1664 }; 1665 1666 /* 1667 * Decode table for 0xC1 opcodes. 1668 * 186 instruction set 1669 */ 1670 1671 const instable_t dis_opC1[8] = { 1672 1673 /* [0] */ TS("rol",MvI), TS("ror",MvI), TS("rcl",MvI), TS("rcr",MvI), 1674 /* [4] */ TS("shl",MvI), TS("shr",MvI), TS("sal",MvI), TS("sar",MvI), 1675 }; 1676 1677 /* 1678 * Decode table for 0xD1 opcodes. 1679 */ 1680 1681 const instable_t dis_opD1[8] = { 1682 1683 /* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv), 1684 /* [4] */ TS("shl",Mv), TS("shr",Mv), TS("sal",Mv), TS("sar",Mv), 1685 }; 1686 1687 1688 /* 1689 * Decode table for 0xD2 opcodes. 1690 */ 1691 1692 const instable_t dis_opD2[8] = { 1693 1694 /* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv), 1695 /* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv), 1696 }; 1697 /* 1698 * Decode table for 0xD3 opcodes. 1699 */ 1700 1701 const instable_t dis_opD3[8] = { 1702 1703 /* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv), 1704 /* [4] */ TS("shl",Mv), TS("shr",Mv), TS("salb",Mv), TS("sar",Mv), 1705 }; 1706 1707 1708 /* 1709 * Decode table for 0xF6 opcodes. 1710 */ 1711 1712 const instable_t dis_opF6[8] = { 1713 1714 /* [0] */ TNS("testb",IMw), TNS("testb",IMw), TNS("notb",Mw), TNS("negb",Mw), 1715 /* [4] */ TNS("mulb",MA), TNS("imulb",MA), TNS("divb",MA), TNS("idivb",MA), 1716 }; 1717 1718 1719 /* 1720 * Decode table for 0xF7 opcodes. 1721 */ 1722 1723 const instable_t dis_opF7[8] = { 1724 1725 /* [0] */ TS("test",IMw), TS("test",IMw), TS("not",Mw), TS("neg",Mw), 1726 /* [4] */ TS("mul",MA), TS("imul",MA), TS("div",MA), TS("idiv",MA), 1727 }; 1728 1729 1730 /* 1731 * Decode table for 0xFE opcodes. 1732 */ 1733 1734 const instable_t dis_opFE[8] = { 1735 1736 /* [0] */ TNS("incb",Mw), TNS("decb",Mw), INVALID, INVALID, 1737 /* [4] */ INVALID, INVALID, INVALID, INVALID, 1738 }; 1739 /* 1740 * Decode table for 0xFF opcodes. 1741 */ 1742 1743 const instable_t dis_opFF[8] = { 1744 1745 /* [0] */ TS("inc",Mw), TS("dec",Mw), TNSyp("call",INM), TNS("lcall",INM), 1746 /* [4] */ TNSy("jmp",INM), TNS("ljmp",INM), TSp("push",M), INVALID, 1747 }; 1748 1749 /* for 287 instructions, which are a mess to decode */ 1750 1751 const instable_t dis_opFP1n2[8][8] = { 1752 { 1753 /* bit pattern: 1101 1xxx MODxx xR/M */ 1754 /* [0,0] */ TNS("fadds",M), TNS("fmuls",M), TNS("fcoms",M), TNS("fcomps",M), 1755 /* [0,4] */ TNS("fsubs",M), TNS("fsubrs",M), TNS("fdivs",M), TNS("fdivrs",M), 1756 }, { 1757 /* [1,0] */ TNS("flds",M), INVALID, TNS("fsts",M), TNS("fstps",M), 1758 /* [1,4] */ TNSZ("fldenv",M,28), TNSZ("fldcw",M,2), TNSZ("fnstenv",M,28), TNSZ("fnstcw",M,2), 1759 }, { 1760 /* [2,0] */ TNS("fiaddl",M), TNS("fimull",M), TNS("ficoml",M), TNS("ficompl",M), 1761 /* [2,4] */ TNS("fisubl",M), TNS("fisubrl",M), TNS("fidivl",M), TNS("fidivrl",M), 1762 }, { 1763 /* [3,0] */ TNS("fildl",M), INVALID, TNS("fistl",M), TNS("fistpl",M), 1764 /* [3,4] */ INVALID, TNSZ("fldt",M,10), INVALID, TNSZ("fstpt",M,10), 1765 }, { 1766 /* [4,0] */ TNSZ("faddl",M,8), TNSZ("fmull",M,8), TNSZ("fcoml",M,8), TNSZ("fcompl",M,8), 1767 /* [4,1] */ TNSZ("fsubl",M,8), TNSZ("fsubrl",M,8), TNSZ("fdivl",M,8), TNSZ("fdivrl",M,8), 1768 }, { 1769 /* [5,0] */ TNSZ("fldl",M,8), INVALID, TNSZ("fstl",M,8), TNSZ("fstpl",M,8), 1770 /* [5,4] */ TNSZ("frstor",M,108), INVALID, TNSZ("fnsave",M,108), TNSZ("fnstsw",M,2), 1771 }, { 1772 /* [6,0] */ TNSZ("fiadd",M,2), TNSZ("fimul",M,2), TNSZ("ficom",M,2), TNSZ("ficomp",M,2), 1773 /* [6,4] */ TNSZ("fisub",M,2), TNSZ("fisubr",M,2), TNSZ("fidiv",M,2), TNSZ("fidivr",M,2), 1774 }, { 1775 /* [7,0] */ TNSZ("fild",M,2), INVALID, TNSZ("fist",M,2), TNSZ("fistp",M,2), 1776 /* [7,4] */ TNSZ("fbld",M,10), TNSZ("fildll",M,8), TNSZ("fbstp",M,10), TNSZ("fistpll",M,8), 1777 } }; 1778 1779 const instable_t dis_opFP3[8][8] = { 1780 { 1781 /* bit pattern: 1101 1xxx 11xx xREG */ 1782 /* [0,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F), 1783 /* [0,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF), 1784 }, { 1785 /* [1,0] */ TNS("fld",F), TNS("fxch",F), TNS("fnop",NORM), TNS("fstp",F), 1786 /* [1,4] */ INVALID, INVALID, INVALID, INVALID, 1787 }, { 1788 /* [2,0] */ INVALID, INVALID, INVALID, INVALID, 1789 /* [2,4] */ INVALID, TNS("fucompp",NORM), INVALID, INVALID, 1790 }, { 1791 /* [3,0] */ INVALID, INVALID, INVALID, INVALID, 1792 /* [3,4] */ INVALID, INVALID, INVALID, INVALID, 1793 }, { 1794 /* [4,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F), 1795 /* [4,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF), 1796 }, { 1797 /* [5,0] */ TNS("ffree",F), TNS("fxch",F), TNS("fst",F), TNS("fstp",F), 1798 /* [5,4] */ TNS("fucom",F), TNS("fucomp",F), INVALID, INVALID, 1799 }, { 1800 /* [6,0] */ TNS("faddp",FF), TNS("fmulp",FF), TNS("fcomp",F), TNS("fcompp",NORM), 1801 /* [6,4] */ TNS("fsubp",FF), TNS("fsubrp",FF), TNS("fdivp",FF), TNS("fdivrp",FF), 1802 }, { 1803 /* [7,0] */ TNS("ffreep",F), TNS("fxch",F), TNS("fstp",F), TNS("fstp",F), 1804 /* [7,4] */ TNS("fnstsw",M), TNS("fucomip",FFC), TNS("fcomip",FFC), INVALID, 1805 } }; 1806 1807 const instable_t dis_opFP4[4][8] = { 1808 { 1809 /* bit pattern: 1101 1001 111x xxxx */ 1810 /* [0,0] */ TNS("fchs",NORM), TNS("fabs",NORM), INVALID, INVALID, 1811 /* [0,4] */ TNS("ftst",NORM), TNS("fxam",NORM), TNS("ftstp",NORM), INVALID, 1812 }, { 1813 /* [1,0] */ TNS("fld1",NORM), TNS("fldl2t",NORM), TNS("fldl2e",NORM), TNS("fldpi",NORM), 1814 /* [1,4] */ TNS("fldlg2",NORM), TNS("fldln2",NORM), TNS("fldz",NORM), INVALID, 1815 }, { 1816 /* [2,0] */ TNS("f2xm1",NORM), TNS("fyl2x",NORM), TNS("fptan",NORM), TNS("fpatan",NORM), 1817 /* [2,4] */ TNS("fxtract",NORM), TNS("fprem1",NORM), TNS("fdecstp",NORM), TNS("fincstp",NORM), 1818 }, { 1819 /* [3,0] */ TNS("fprem",NORM), TNS("fyl2xp1",NORM), TNS("fsqrt",NORM), TNS("fsincos",NORM), 1820 /* [3,4] */ TNS("frndint",NORM), TNS("fscale",NORM), TNS("fsin",NORM), TNS("fcos",NORM), 1821 } }; 1822 1823 const instable_t dis_opFP5[8] = { 1824 /* bit pattern: 1101 1011 111x xxxx */ 1825 /* [0] */ TNS("feni",NORM), TNS("fdisi",NORM), TNS("fnclex",NORM), TNS("fninit",NORM), 1826 /* [4] */ TNS("fsetpm",NORM), TNS("frstpm",NORM), INVALID, INVALID, 1827 }; 1828 1829 const instable_t dis_opFP6[8] = { 1830 /* bit pattern: 1101 1011 11yy yxxx */ 1831 /* [00] */ TNS("fcmov.nb",FF), TNS("fcmov.ne",FF), TNS("fcmov.nbe",FF), TNS("fcmov.nu",FF), 1832 /* [04] */ INVALID, TNS("fucomi",F), TNS("fcomi",F), INVALID, 1833 }; 1834 1835 const instable_t dis_opFP7[8] = { 1836 /* bit pattern: 1101 1010 11yy yxxx */ 1837 /* [00] */ TNS("fcmov.b",FF), TNS("fcmov.e",FF), TNS("fcmov.be",FF), TNS("fcmov.u",FF), 1838 /* [04] */ INVALID, INVALID, INVALID, INVALID, 1839 }; 1840 1841 /* 1842 * Main decode table for the op codes. The first two nibbles 1843 * will be used as an index into the table. If there is a 1844 * a need to further decode an instruction, the array to be 1845 * referenced is indicated with the other two entries being 1846 * empty. 1847 */ 1848 1849 const instable_t dis_distable[16][16] = { 1850 { 1851 /* [0,0] */ TNS("addb",RMw), TS("add",RMw), TNS("addb",MRw), TS("add",MRw), 1852 /* [0,4] */ TNS("addb",IA), TS("add",IA), TSx("push",SEG), TSx("pop",SEG), 1853 /* [0,8] */ TNS("orb",RMw), TS("or",RMw), TNS("orb",MRw), TS("or",MRw), 1854 /* [0,C] */ TNS("orb",IA), TS("or",IA), TSx("push",SEG), IND(dis_op0F), 1855 }, { 1856 /* [1,0] */ TNS("adcb",RMw), TS("adc",RMw), TNS("adcb",MRw), TS("adc",MRw), 1857 /* [1,4] */ TNS("adcb",IA), TS("adc",IA), TSx("push",SEG), TSx("pop",SEG), 1858 /* [1,8] */ TNS("sbbb",RMw), TS("sbb",RMw), TNS("sbbb",MRw), TS("sbb",MRw), 1859 /* [1,C] */ TNS("sbbb",IA), TS("sbb",IA), TSx("push",SEG), TSx("pop",SEG), 1860 }, { 1861 /* [2,0] */ TNS("andb",RMw), TS("and",RMw), TNS("andb",MRw), TS("and",MRw), 1862 /* [2,4] */ TNS("andb",IA), TS("and",IA), TNS("%es:",OVERRIDE), TNSx("daa",NORM), 1863 /* [2,8] */ TNS("subb",RMw), TS("sub",RMw), TNS("subb",MRw), TS("sub",MRw), 1864 /* [2,C] */ TNS("subb",IA), TS("sub",IA), TNS("%cs:",OVERRIDE), TNSx("das",NORM), 1865 }, { 1866 /* [3,0] */ TNS("xorb",RMw), TS("xor",RMw), TNS("xorb",MRw), TS("xor",MRw), 1867 /* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNS("%ss:",OVERRIDE), TNSx("aaa",NORM), 1868 /* [3,8] */ TNS("cmpb",RMw), TS("cmp",RMw), TNS("cmpb",MRw), TS("cmp",MRw), 1869 /* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNS("%ds:",OVERRIDE), TNSx("aas",NORM), 1870 }, { 1871 /* [4,0] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R), 1872 /* [4,4] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R), 1873 /* [4,8] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R), 1874 /* [4,C] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R), 1875 }, { 1876 /* [5,0] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R), 1877 /* [5,4] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R), 1878 /* [5,8] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R), 1879 /* [5,C] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R), 1880 }, { 1881 /* [6,0] */ TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR), TNS("arpl",RMw), 1882 /* [6,4] */ TNS("%fs:",OVERRIDE), TNS("%gs:",OVERRIDE), TNS("data16",DM), TNS("addr16",AM), 1883 /* [6,8] */ TSp("push",I), TS("imul",IMUL), TSp("push",Ib), TS("imul",IMUL), 1884 /* [6,C] */ TNSZ("insb",IMPLMEM,1), TSZ("ins",IMPLMEM,4), TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4), 1885 }, { 1886 /* [7,0] */ TNSy("jo",BD), TNSy("jno",BD), TNSy("jb",BD), TNSy("jae",BD), 1887 /* [7,4] */ TNSy("je",BD), TNSy("jne",BD), TNSy("jbe",BD), TNSy("ja",BD), 1888 /* [7,8] */ TNSy("js",BD), TNSy("jns",BD), TNSy("jp",BD), TNSy("jnp",BD), 1889 /* [7,C] */ TNSy("jl",BD), TNSy("jge",BD), TNSy("jle",BD), TNSy("jg",BD), 1890 }, { 1891 /* [8,0] */ IND(dis_op80), IND(dis_op81), INDx(dis_op82), IND(dis_op83), 1892 /* [8,4] */ TNS("testb",RMw), TS("test",RMw), TNS("xchgb",RMw), TS("xchg",RMw), 1893 /* [8,8] */ TNS("movb",RMw), TS("mov",RMw), TNS("movb",MRw), TS("mov",MRw), 1894 /* [8,C] */ TNS("movw",SM), TS("lea",MR), TNS("movw",MS), TSp("pop",M), 1895 }, { 1896 /* [9,0] */ TNS("nop",NORM), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), 1897 /* [9,4] */ TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), 1898 /* [9,8] */ TNS("cXtX",CBW), TNS("cXtX",CWD), TNSx("lcall",SO), TNS("fwait",NORM), 1899 /* [9,C] */ TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4), TNSx("sahf",NORM), TNSx("lahf",NORM), 1900 }, { 1901 /* [A,0] */ TNS("movb",OA), TS("mov",OA), TNS("movb",AO), TS("mov",AO), 1902 /* [A,4] */ TNSZ("movsb",SD,1), TS("movs",SD), TNSZ("cmpsb",SD,1), TS("cmps",SD), 1903 /* [A,8] */ TNS("testb",IA), TS("test",IA), TNS("stosb",AD), TS("stos",AD), 1904 /* [A,C] */ TNS("lodsb",SA), TS("lods",SA), TNS("scasb",AD), TS("scas",AD), 1905 }, { 1906 /* [B,0] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), 1907 /* [B,4] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), 1908 /* [B,8] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR), 1909 /* [B,C] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR), 1910 }, { 1911 /* [C,0] */ IND(dis_opC0), IND(dis_opC1), TNSyp("ret",RET), TNSyp("ret",NORM), 1912 /* [C,4] */ TNSx("les",MR), TNSx("lds",MR), TNS("movb",IMw), TS("mov",IMw), 1913 /* [C,8] */ TNSyp("enter",ENTER), TNSyp("leave",NORM), TNS("lret",RET), TNS("lret",NORM), 1914 /* [C,C] */ TNS("int",INT3), TNS("int",INTx), TNSx("into",NORM), TNS("iret",NORM), 1915 }, { 1916 /* [D,0] */ IND(dis_opD0), IND(dis_opD1), IND(dis_opD2), IND(dis_opD3), 1917 /* [D,4] */ TNSx("aam",U), TNSx("aad",U), TNSx("falc",NORM), TNSZ("xlat",IMPLMEM,1), 1918 1919 /* 287 instructions. Note that although the indirect field */ 1920 /* indicates opFP1n2 for further decoding, this is not necessarily */ 1921 /* the case since the opFP arrays are not partitioned according to key1 */ 1922 /* and key2. opFP1n2 is given only to indicate that we haven't */ 1923 /* finished decoding the instruction. */ 1924 /* [D,8] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), 1925 /* [D,C] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), 1926 }, { 1927 /* [E,0] */ TNSy("loopnz",BD), TNSy("loopz",BD), TNSy("loop",BD), TNSy("jcxz",BD), 1928 /* [E,4] */ TNS("inb",P), TS("in",P), TNS("outb",P), TS("out",P), 1929 /* [E,8] */ TNSyp("call",D), TNSy("jmp",D), TNSx("ljmp",SO), TNSy("jmp",BD), 1930 /* [E,C] */ TNS("inb",V), TS("in",V), TNS("outb",V), TS("out",V), 1931 }, { 1932 /* [F,0] */ TNS("lock",LOCK), TNS("icebp", NORM), TNS("repnz",PREFIX), TNS("repz",PREFIX), 1933 /* [F,4] */ TNS("hlt",NORM), TNS("cmc",NORM), IND(dis_opF6), IND(dis_opF7), 1934 /* [F,8] */ TNS("clc",NORM), TNS("stc",NORM), TNS("cli",NORM), TNS("sti",NORM), 1935 /* [F,C] */ TNS("cld",NORM), TNS("std",NORM), IND(dis_opFE), IND(dis_opFF), 1936 } }; 1937 1938 /* END CSTYLED */ 1939 1940 /* 1941 * common functions to decode and disassemble an x86 or amd64 instruction 1942 */ 1943 1944 /* 1945 * These are the individual fields of a REX prefix. Note that a REX 1946 * prefix with none of these set is still needed to: 1947 * - use the MOVSXD (sign extend 32 to 64 bits) instruction 1948 * - access the %sil, %dil, %bpl, %spl registers 1949 */ 1950 #define REX_W 0x08 /* 64 bit operand size when set */ 1951 #define REX_R 0x04 /* high order bit extension of ModRM reg field */ 1952 #define REX_X 0x02 /* high order bit extension of SIB index field */ 1953 #define REX_B 0x01 /* extends ModRM r_m, SIB base, or opcode reg */ 1954 1955 /* 1956 * These are the individual fields of a VEX prefix. 1957 */ 1958 #define VEX_R 0x08 /* REX.R in 1's complement form */ 1959 #define VEX_X 0x04 /* REX.X in 1's complement form */ 1960 #define VEX_B 0x02 /* REX.B in 1's complement form */ 1961 /* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */ 1962 #define VEX_L 0x04 1963 #define VEX_W 0x08 /* opcode specific, use like REX.W */ 1964 #define VEX_m 0x1F /* VEX m-mmmm field */ 1965 #define VEX_v 0x78 /* VEX register specifier */ 1966 #define VEX_p 0x03 /* VEX pp field, opcode extension */ 1967 1968 /* VEX m-mmmm field, only used by three bytes prefix */ 1969 #define VEX_m_0F 0x01 /* implied 0F leading opcode byte */ 1970 #define VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */ 1971 #define VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */ 1972 1973 /* VEX pp field, providing equivalent functionality of a SIMD prefix */ 1974 #define VEX_p_66 0x01 1975 #define VEX_p_F3 0x02 1976 #define VEX_p_F2 0x03 1977 1978 /* 1979 * Even in 64 bit mode, usually only 4 byte immediate operands are supported. 1980 */ 1981 static int isize[] = {1, 2, 4, 4}; 1982 static int isize64[] = {1, 2, 4, 8}; 1983 1984 /* 1985 * Just a bunch of useful macros. 1986 */ 1987 #define WBIT(x) (x & 0x1) /* to get w bit */ 1988 #define REGNO(x) (x & 0x7) /* to get 3 bit register */ 1989 #define VBIT(x) ((x)>>1 & 0x1) /* to get 'v' bit */ 1990 #define OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1) 1991 #define OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1) 1992 1993 #define REG_ONLY 3 /* mode to indicate a register operand (not memory) */ 1994 1995 #define BYTE_OPND 0 /* w-bit value indicating byte register */ 1996 #define LONG_OPND 1 /* w-bit value indicating opnd_size register */ 1997 #define MM_OPND 2 /* "value" used to indicate a mmx reg */ 1998 #define XMM_OPND 3 /* "value" used to indicate a xmm reg */ 1999 #define SEG_OPND 4 /* "value" used to indicate a segment reg */ 2000 #define CONTROL_OPND 5 /* "value" used to indicate a control reg */ 2001 #define DEBUG_OPND 6 /* "value" used to indicate a debug reg */ 2002 #define TEST_OPND 7 /* "value" used to indicate a test reg */ 2003 #define WORD_OPND 8 /* w-bit value indicating word size reg */ 2004 #define YMM_OPND 9 /* "value" used to indicate a ymm reg */ 2005 2006 /* 2007 * Get the next byte and separate the op code into the high and low nibbles. 2008 */ 2009 static int 2010 dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low) 2011 { 2012 int byte; 2013 2014 /* 2015 * x86 instructions have a maximum length of 15 bytes. Bail out if 2016 * we try to read more. 2017 */ 2018 if (x->d86_len >= 15) 2019 return (x->d86_error = 1); 2020 2021 if (x->d86_error) 2022 return (1); 2023 byte = x->d86_get_byte(x->d86_data); 2024 if (byte < 0) 2025 return (x->d86_error = 1); 2026 x->d86_bytes[x->d86_len++] = byte; 2027 *low = byte & 0xf; /* ----xxxx low 4 bits */ 2028 *high = byte >> 4 & 0xf; /* xxxx---- bits 7 to 4 */ 2029 return (0); 2030 } 2031 2032 /* 2033 * Get and decode an SIB (scaled index base) byte 2034 */ 2035 static void 2036 dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base) 2037 { 2038 int byte; 2039 2040 if (x->d86_error) 2041 return; 2042 2043 byte = x->d86_get_byte(x->d86_data); 2044 if (byte < 0) { 2045 x->d86_error = 1; 2046 return; 2047 } 2048 x->d86_bytes[x->d86_len++] = byte; 2049 2050 *base = byte & 0x7; 2051 *index = (byte >> 3) & 0x7; 2052 *ss = (byte >> 6) & 0x3; 2053 } 2054 2055 /* 2056 * Get the byte following the op code and separate it into the 2057 * mode, register, and r/m fields. 2058 */ 2059 static void 2060 dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m) 2061 { 2062 if (x->d86_got_modrm == 0) { 2063 if (x->d86_rmindex == -1) 2064 x->d86_rmindex = x->d86_len; 2065 dtrace_get_SIB(x, mode, reg, r_m); 2066 x->d86_got_modrm = 1; 2067 } 2068 } 2069 2070 /* 2071 * Adjust register selection based on any REX prefix bits present. 2072 */ 2073 /*ARGSUSED*/ 2074 static void 2075 dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m) 2076 { 2077 if (reg != NULL && r_m == NULL) { 2078 if (rex_prefix & REX_B) 2079 *reg += 8; 2080 } else { 2081 if (reg != NULL && (REX_R & rex_prefix) != 0) 2082 *reg += 8; 2083 if (r_m != NULL && (REX_B & rex_prefix) != 0) 2084 *r_m += 8; 2085 } 2086 } 2087 2088 /* 2089 * Adjust register selection based on any VEX prefix bits present. 2090 * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix 2091 */ 2092 /*ARGSUSED*/ 2093 static void 2094 dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m) 2095 { 2096 if (reg != NULL && r_m == NULL) { 2097 if (!(vex_byte1 & VEX_B)) 2098 *reg += 8; 2099 } else { 2100 if (reg != NULL && ((VEX_R & vex_byte1) == 0)) 2101 *reg += 8; 2102 if (r_m != NULL && ((VEX_B & vex_byte1) == 0)) 2103 *r_m += 8; 2104 } 2105 } 2106 2107 /* 2108 * Get an immediate operand of the given size, with sign extension. 2109 */ 2110 static void 2111 dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex) 2112 { 2113 int i; 2114 int byte; 2115 int valsize; 2116 2117 if (x->d86_numopnds < opindex + 1) 2118 x->d86_numopnds = opindex + 1; 2119 2120 switch (wbit) { 2121 case BYTE_OPND: 2122 valsize = 1; 2123 break; 2124 case LONG_OPND: 2125 if (x->d86_opnd_size == SIZE16) 2126 valsize = 2; 2127 else if (x->d86_opnd_size == SIZE32) 2128 valsize = 4; 2129 else 2130 valsize = 8; 2131 break; 2132 case MM_OPND: 2133 case XMM_OPND: 2134 case YMM_OPND: 2135 case SEG_OPND: 2136 case CONTROL_OPND: 2137 case DEBUG_OPND: 2138 case TEST_OPND: 2139 valsize = size; 2140 break; 2141 case WORD_OPND: 2142 valsize = 2; 2143 break; 2144 } 2145 if (valsize < size) 2146 valsize = size; 2147 2148 if (x->d86_error) 2149 return; 2150 x->d86_opnd[opindex].d86_value = 0; 2151 for (i = 0; i < size; ++i) { 2152 byte = x->d86_get_byte(x->d86_data); 2153 if (byte < 0) { 2154 x->d86_error = 1; 2155 return; 2156 } 2157 x->d86_bytes[x->d86_len++] = byte; 2158 x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8); 2159 } 2160 /* Do sign extension */ 2161 if (x->d86_bytes[x->d86_len - 1] & 0x80) { 2162 for (; i < sizeof (uint64_t); i++) 2163 x->d86_opnd[opindex].d86_value |= 2164 (uint64_t)0xff << (i * 8); 2165 } 2166 #ifdef DIS_TEXT 2167 x->d86_opnd[opindex].d86_mode = MODE_SIGNED; 2168 x->d86_opnd[opindex].d86_value_size = valsize; 2169 x->d86_imm_bytes += size; 2170 #endif 2171 } 2172 2173 /* 2174 * Get an ip relative operand of the given size, with sign extension. 2175 */ 2176 static void 2177 dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex) 2178 { 2179 dtrace_imm_opnd(x, wbit, size, opindex); 2180 #ifdef DIS_TEXT 2181 x->d86_opnd[opindex].d86_mode = MODE_IPREL; 2182 #endif 2183 } 2184 2185 /* 2186 * Check to see if there is a segment override prefix pending. 2187 * If so, print it in the current 'operand' location and set 2188 * the override flag back to false. 2189 */ 2190 /*ARGSUSED*/ 2191 static void 2192 dtrace_check_override(dis86_t *x, int opindex) 2193 { 2194 #ifdef DIS_TEXT 2195 if (x->d86_seg_prefix) { 2196 (void) strlcat(x->d86_opnd[opindex].d86_prefix, 2197 x->d86_seg_prefix, PFIXLEN); 2198 } 2199 #endif 2200 x->d86_seg_prefix = NULL; 2201 } 2202 2203 2204 /* 2205 * Process a single instruction Register or Memory operand. 2206 * 2207 * mode = addressing mode from ModRM byte 2208 * r_m = r_m (or reg if mode == 3) field from ModRM byte 2209 * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use. 2210 * o = index of operand that we are processing (0, 1 or 2) 2211 * 2212 * the value of reg or r_m must have already been adjusted for any REX prefix. 2213 */ 2214 /*ARGSUSED*/ 2215 static void 2216 dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex) 2217 { 2218 int have_SIB = 0; /* flag presence of scale-index-byte */ 2219 uint_t ss; /* scale-factor from opcode */ 2220 uint_t index; /* index register number */ 2221 uint_t base; /* base register number */ 2222 int dispsize; /* size of displacement in bytes */ 2223 #ifdef DIS_TEXT 2224 char *opnd = x->d86_opnd[opindex].d86_opnd; 2225 #endif 2226 2227 if (x->d86_numopnds < opindex + 1) 2228 x->d86_numopnds = opindex + 1; 2229 2230 if (x->d86_error) 2231 return; 2232 2233 /* 2234 * first handle a simple register 2235 */ 2236 if (mode == REG_ONLY) { 2237 #ifdef DIS_TEXT 2238 switch (wbit) { 2239 case MM_OPND: 2240 (void) strlcat(opnd, dis_MMREG[r_m], OPLEN); 2241 break; 2242 case XMM_OPND: 2243 (void) strlcat(opnd, dis_XMMREG[r_m], OPLEN); 2244 break; 2245 case YMM_OPND: 2246 (void) strlcat(opnd, dis_YMMREG[r_m], OPLEN); 2247 break; 2248 case SEG_OPND: 2249 (void) strlcat(opnd, dis_SEGREG[r_m], OPLEN); 2250 break; 2251 case CONTROL_OPND: 2252 (void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN); 2253 break; 2254 case DEBUG_OPND: 2255 (void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN); 2256 break; 2257 case TEST_OPND: 2258 (void) strlcat(opnd, dis_TESTREG[r_m], OPLEN); 2259 break; 2260 case BYTE_OPND: 2261 if (x->d86_rex_prefix == 0) 2262 (void) strlcat(opnd, dis_REG8[r_m], OPLEN); 2263 else 2264 (void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN); 2265 break; 2266 case WORD_OPND: 2267 (void) strlcat(opnd, dis_REG16[r_m], OPLEN); 2268 break; 2269 case LONG_OPND: 2270 if (x->d86_opnd_size == SIZE16) 2271 (void) strlcat(opnd, dis_REG16[r_m], OPLEN); 2272 else if (x->d86_opnd_size == SIZE32) 2273 (void) strlcat(opnd, dis_REG32[r_m], OPLEN); 2274 else 2275 (void) strlcat(opnd, dis_REG64[r_m], OPLEN); 2276 break; 2277 } 2278 #endif /* DIS_TEXT */ 2279 return; 2280 } 2281 2282 /* 2283 * if symbolic representation, skip override prefix, if any 2284 */ 2285 dtrace_check_override(x, opindex); 2286 2287 /* 2288 * Handle 16 bit memory references first, since they decode 2289 * the mode values more simply. 2290 * mode 1 is r_m + 8 bit displacement 2291 * mode 2 is r_m + 16 bit displacement 2292 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp 2293 */ 2294 if (x->d86_addr_size == SIZE16) { 2295 if ((mode == 0 && r_m == 6) || mode == 2) 2296 dtrace_imm_opnd(x, WORD_OPND, 2, opindex); 2297 else if (mode == 1) 2298 dtrace_imm_opnd(x, BYTE_OPND, 1, opindex); 2299 #ifdef DIS_TEXT 2300 if (mode == 0 && r_m == 6) 2301 x->d86_opnd[opindex].d86_mode = MODE_SIGNED; 2302 else if (mode == 0) 2303 x->d86_opnd[opindex].d86_mode = MODE_NONE; 2304 else 2305 x->d86_opnd[opindex].d86_mode = MODE_OFFSET; 2306 (void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN); 2307 #endif 2308 return; 2309 } 2310 2311 /* 2312 * 32 and 64 bit addressing modes are more complex since they 2313 * can involve an SIB (scaled index and base) byte to decode. 2314 */ 2315 if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) { 2316 have_SIB = 1; 2317 dtrace_get_SIB(x, &ss, &index, &base); 2318 if (x->d86_error) 2319 return; 2320 if (base != 5 || mode != 0) 2321 if (x->d86_rex_prefix & REX_B) 2322 base += 8; 2323 if (x->d86_rex_prefix & REX_X) 2324 index += 8; 2325 } else { 2326 base = r_m; 2327 } 2328 2329 /* 2330 * Compute the displacement size and get its bytes 2331 */ 2332 dispsize = 0; 2333 2334 if (mode == 1) 2335 dispsize = 1; 2336 else if (mode == 2) 2337 dispsize = 4; 2338 else if ((r_m & 7) == EBP_REGNO || 2339 (have_SIB && (base & 7) == EBP_REGNO)) 2340 dispsize = 4; 2341 2342 if (dispsize > 0) { 2343 dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND, 2344 dispsize, opindex); 2345 if (x->d86_error) 2346 return; 2347 } 2348 2349 #ifdef DIS_TEXT 2350 if (dispsize > 0) 2351 x->d86_opnd[opindex].d86_mode = MODE_OFFSET; 2352 2353 if (have_SIB == 0) { 2354 if (x->d86_mode == SIZE32) { 2355 if (mode == 0) 2356 (void) strlcat(opnd, dis_addr32_mode0[r_m], 2357 OPLEN); 2358 else 2359 (void) strlcat(opnd, dis_addr32_mode12[r_m], 2360 OPLEN); 2361 } else { 2362 if (mode == 0) { 2363 (void) strlcat(opnd, dis_addr64_mode0[r_m], 2364 OPLEN); 2365 if (r_m == 5) { 2366 x->d86_opnd[opindex].d86_mode = 2367 MODE_RIPREL; 2368 } 2369 } else { 2370 (void) strlcat(opnd, dis_addr64_mode12[r_m], 2371 OPLEN); 2372 } 2373 } 2374 } else { 2375 uint_t need_paren = 0; 2376 char **regs; 2377 if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */ 2378 regs = (char **)dis_REG32; 2379 else 2380 regs = (char **)dis_REG64; 2381 2382 /* 2383 * print the base (if any) 2384 */ 2385 if (base == EBP_REGNO && mode == 0) { 2386 if (index != ESP_REGNO) { 2387 (void) strlcat(opnd, "(", OPLEN); 2388 need_paren = 1; 2389 } 2390 } else { 2391 (void) strlcat(opnd, "(", OPLEN); 2392 (void) strlcat(opnd, regs[base], OPLEN); 2393 need_paren = 1; 2394 } 2395 2396 /* 2397 * print the index (if any) 2398 */ 2399 if (index != ESP_REGNO) { 2400 (void) strlcat(opnd, ",", OPLEN); 2401 (void) strlcat(opnd, regs[index], OPLEN); 2402 (void) strlcat(opnd, dis_scale_factor[ss], OPLEN); 2403 } else 2404 if (need_paren) 2405 (void) strlcat(opnd, ")", OPLEN); 2406 } 2407 #endif 2408 } 2409 2410 /* 2411 * Operand sequence for standard instruction involving one register 2412 * and one register/memory operand. 2413 * wbit indicates a byte(0) or opnd_size(1) operation 2414 * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r") 2415 */ 2416 #define STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit) { \ 2417 dtrace_get_modrm(x, &mode, ®, &r_m); \ 2418 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 2419 dtrace_get_operand(x, mode, r_m, wbit, vbit); \ 2420 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit); \ 2421 } 2422 2423 /* 2424 * Similar to above, but allows for the two operands to be of different 2425 * classes (ie. wbit). 2426 * wbit is for the r_m operand 2427 * w2 is for the reg operand 2428 */ 2429 #define MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit) { \ 2430 dtrace_get_modrm(x, &mode, ®, &r_m); \ 2431 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 2432 dtrace_get_operand(x, mode, r_m, wbit, vbit); \ 2433 dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit); \ 2434 } 2435 2436 /* 2437 * Similar, but for 2 operands plus an immediate. 2438 * vbit indicates direction 2439 * 0 for "opcode imm, r, r_m" or 2440 * 1 for "opcode imm, r_m, r" 2441 */ 2442 #define THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \ 2443 dtrace_get_modrm(x, &mode, ®, &r_m); \ 2444 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 2445 dtrace_get_operand(x, mode, r_m, wbit, 2-vbit); \ 2446 dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit); \ 2447 dtrace_imm_opnd(x, wbit, immsize, 0); \ 2448 } 2449 2450 /* 2451 * Similar, but for 2 operands plus two immediates. 2452 */ 2453 #define FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \ 2454 dtrace_get_modrm(x, &mode, ®, &r_m); \ 2455 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 2456 dtrace_get_operand(x, mode, r_m, wbit, 2); \ 2457 dtrace_get_operand(x, REG_ONLY, reg, w2, 3); \ 2458 dtrace_imm_opnd(x, wbit, immsize, 1); \ 2459 dtrace_imm_opnd(x, wbit, immsize, 0); \ 2460 } 2461 2462 /* 2463 * 1 operands plus two immediates. 2464 */ 2465 #define ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \ 2466 dtrace_get_modrm(x, &mode, ®, &r_m); \ 2467 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 2468 dtrace_get_operand(x, mode, r_m, wbit, 2); \ 2469 dtrace_imm_opnd(x, wbit, immsize, 1); \ 2470 dtrace_imm_opnd(x, wbit, immsize, 0); \ 2471 } 2472 2473 /* 2474 * Dissassemble a single x86 or amd64 instruction. 2475 * 2476 * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64) 2477 * for interpreting instructions. 2478 * 2479 * returns non-zero for bad opcode 2480 */ 2481 int 2482 dtrace_disx86(dis86_t *x, uint_t cpu_mode) 2483 { 2484 instable_t *dp; /* decode table being used */ 2485 #ifdef DIS_TEXT 2486 uint_t i; 2487 #endif 2488 #ifdef DIS_MEM 2489 uint_t nomem = 0; 2490 #define NOMEM (nomem = 1) 2491 #else 2492 #define NOMEM /* nothing */ 2493 #endif 2494 uint_t opnd_size; /* SIZE16, SIZE32 or SIZE64 */ 2495 uint_t addr_size; /* SIZE16, SIZE32 or SIZE64 */ 2496 uint_t wbit; /* opcode wbit, 0 is 8 bit, !0 for opnd_size */ 2497 uint_t w2; /* wbit value for second operand */ 2498 uint_t vbit; 2499 uint_t mode = 0; /* mode value from ModRM byte */ 2500 uint_t reg; /* reg value from ModRM byte */ 2501 uint_t r_m; /* r_m value from ModRM byte */ 2502 2503 uint_t opcode1; /* high nibble of 1st byte */ 2504 uint_t opcode2; /* low nibble of 1st byte */ 2505 uint_t opcode3; /* extra opcode bits usually from ModRM byte */ 2506 uint_t opcode4; /* high nibble of 2nd byte */ 2507 uint_t opcode5; /* low nibble of 2nd byte */ 2508 uint_t opcode6; /* high nibble of 3rd byte */ 2509 uint_t opcode7; /* low nibble of 3rd byte */ 2510 uint_t opcode_bytes = 1; 2511 2512 /* 2513 * legacy prefixes come in 5 flavors, you should have only one of each 2514 */ 2515 uint_t opnd_size_prefix = 0; 2516 uint_t addr_size_prefix = 0; 2517 uint_t segment_prefix = 0; 2518 uint_t lock_prefix = 0; 2519 uint_t rep_prefix = 0; 2520 uint_t rex_prefix = 0; /* amd64 register extension prefix */ 2521 2522 /* 2523 * Intel VEX instruction encoding prefix and fields 2524 */ 2525 2526 /* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */ 2527 uint_t vex_prefix = 0; 2528 2529 /* 2530 * VEX prefix byte 1, includes vex.r, vex.x and vex.b 2531 * (for 3 bytes prefix) 2532 */ 2533 uint_t vex_byte1 = 0; 2534 2535 /* 2536 * For 32-bit mode, it should prefetch the next byte to 2537 * distinguish between AVX and les/lds 2538 */ 2539 uint_t vex_prefetch = 0; 2540 2541 uint_t vex_m = 0; 2542 uint_t vex_v = 0; 2543 uint_t vex_p = 0; 2544 uint_t vex_R = 1; 2545 uint_t vex_X = 1; 2546 uint_t vex_B = 1; 2547 uint_t vex_W = 0; 2548 uint_t vex_L; 2549 2550 2551 size_t off; 2552 2553 instable_t dp_mmx; 2554 2555 x->d86_len = 0; 2556 x->d86_rmindex = -1; 2557 x->d86_error = 0; 2558 #ifdef DIS_TEXT 2559 x->d86_numopnds = 0; 2560 x->d86_seg_prefix = NULL; 2561 x->d86_mnem[0] = 0; 2562 for (i = 0; i < 4; ++i) { 2563 x->d86_opnd[i].d86_opnd[0] = 0; 2564 x->d86_opnd[i].d86_prefix[0] = 0; 2565 x->d86_opnd[i].d86_value_size = 0; 2566 x->d86_opnd[i].d86_value = 0; 2567 x->d86_opnd[i].d86_mode = MODE_NONE; 2568 } 2569 #endif 2570 x->d86_rex_prefix = 0; 2571 x->d86_got_modrm = 0; 2572 x->d86_memsize = 0; 2573 2574 if (cpu_mode == SIZE16) { 2575 opnd_size = SIZE16; 2576 addr_size = SIZE16; 2577 } else if (cpu_mode == SIZE32) { 2578 opnd_size = SIZE32; 2579 addr_size = SIZE32; 2580 } else { 2581 opnd_size = SIZE32; 2582 addr_size = SIZE64; 2583 } 2584 2585 /* 2586 * Get one opcode byte and check for zero padding that follows 2587 * jump tables. 2588 */ 2589 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2590 goto error; 2591 2592 if (opcode1 == 0 && opcode2 == 0 && 2593 x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) { 2594 #ifdef DIS_TEXT 2595 (void) strncpy(x->d86_mnem, ".byte\t0", OPLEN); 2596 #endif 2597 goto done; 2598 } 2599 2600 /* 2601 * Gather up legacy x86 prefix bytes. 2602 */ 2603 for (;;) { 2604 uint_t *which_prefix = NULL; 2605 2606 dp = (instable_t *)&dis_distable[opcode1][opcode2]; 2607 2608 switch (dp->it_adrmode) { 2609 case PREFIX: 2610 which_prefix = &rep_prefix; 2611 break; 2612 case LOCK: 2613 which_prefix = &lock_prefix; 2614 break; 2615 case OVERRIDE: 2616 which_prefix = &segment_prefix; 2617 #ifdef DIS_TEXT 2618 x->d86_seg_prefix = (char *)dp->it_name; 2619 #endif 2620 if (dp->it_invalid64 && cpu_mode == SIZE64) 2621 goto error; 2622 break; 2623 case AM: 2624 which_prefix = &addr_size_prefix; 2625 break; 2626 case DM: 2627 which_prefix = &opnd_size_prefix; 2628 break; 2629 } 2630 if (which_prefix == NULL) 2631 break; 2632 *which_prefix = (opcode1 << 4) | opcode2; 2633 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2634 goto error; 2635 } 2636 2637 /* 2638 * Handle amd64 mode PREFIX values. 2639 * Some of the segment prefixes are no-ops. (only FS/GS actually work) 2640 * We might have a REX prefix (opcodes 0x40-0x4f) 2641 */ 2642 if (cpu_mode == SIZE64) { 2643 if (segment_prefix != 0x64 && segment_prefix != 0x65) 2644 segment_prefix = 0; 2645 2646 if (opcode1 == 0x4) { 2647 rex_prefix = (opcode1 << 4) | opcode2; 2648 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2649 goto error; 2650 dp = (instable_t *)&dis_distable[opcode1][opcode2]; 2651 } else if (opcode1 == 0xC && 2652 (opcode2 == 0x4 || opcode2 == 0x5)) { 2653 /* AVX instructions */ 2654 vex_prefix = (opcode1 << 4) | opcode2; 2655 x->d86_rex_prefix = 0x40; 2656 } 2657 } else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) { 2658 /* LDS, LES or AVX */ 2659 dtrace_get_modrm(x, &mode, ®, &r_m); 2660 vex_prefetch = 1; 2661 2662 if (mode == REG_ONLY) { 2663 /* AVX */ 2664 vex_prefix = (opcode1 << 4) | opcode2; 2665 x->d86_rex_prefix = 0x40; 2666 opcode3 = (((mode << 3) | reg)>>1) & 0x0F; 2667 opcode4 = ((reg << 3) | r_m) & 0x0F; 2668 } 2669 } 2670 2671 if (vex_prefix == VEX_2bytes) { 2672 if (!vex_prefetch) { 2673 if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0) 2674 goto error; 2675 } 2676 vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3; 2677 vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2; 2678 vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3; 2679 vex_p = opcode4 & VEX_p; 2680 /* 2681 * The vex.x and vex.b bits are not defined in two bytes 2682 * mode vex prefix, their default values are 1 2683 */ 2684 vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B; 2685 2686 if (vex_R == 0) 2687 x->d86_rex_prefix |= REX_R; 2688 2689 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2690 goto error; 2691 2692 switch (vex_p) { 2693 case VEX_p_66: 2694 dp = (instable_t *) 2695 &dis_opAVX660F[(opcode1 << 4) | opcode2]; 2696 break; 2697 case VEX_p_F3: 2698 dp = (instable_t *) 2699 &dis_opAVXF30F[(opcode1 << 4) | opcode2]; 2700 break; 2701 case VEX_p_F2: 2702 dp = (instable_t *) 2703 &dis_opAVXF20F [(opcode1 << 4) | opcode2]; 2704 break; 2705 default: 2706 dp = (instable_t *) 2707 &dis_opAVX0F[opcode1][opcode2]; 2708 2709 } 2710 2711 } else if (vex_prefix == VEX_3bytes) { 2712 if (!vex_prefetch) { 2713 if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0) 2714 goto error; 2715 } 2716 vex_R = (opcode3 & VEX_R) >> 3; 2717 vex_X = (opcode3 & VEX_X) >> 2; 2718 vex_B = (opcode3 & VEX_B) >> 1; 2719 vex_m = (((opcode3 << 4) | opcode4) & VEX_m); 2720 vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B); 2721 2722 if (vex_R == 0) 2723 x->d86_rex_prefix |= REX_R; 2724 if (vex_X == 0) 2725 x->d86_rex_prefix |= REX_X; 2726 if (vex_B == 0) 2727 x->d86_rex_prefix |= REX_B; 2728 2729 if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0) 2730 goto error; 2731 vex_W = (opcode5 & VEX_W) >> 3; 2732 vex_L = (opcode6 & VEX_L) >> 2; 2733 vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3; 2734 vex_p = opcode6 & VEX_p; 2735 2736 if (vex_W) 2737 x->d86_rex_prefix |= REX_W; 2738 2739 /* Only these three vex_m values valid; others are reserved */ 2740 if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) && 2741 (vex_m != VEX_m_0F3A)) 2742 goto error; 2743 2744 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2745 goto error; 2746 2747 switch (vex_p) { 2748 case VEX_p_66: 2749 if (vex_m == VEX_m_0F) { 2750 dp = (instable_t *) 2751 &dis_opAVX660F 2752 [(opcode1 << 4) | opcode2]; 2753 } else if (vex_m == VEX_m_0F38) { 2754 dp = (instable_t *) 2755 &dis_opAVX660F38 2756 [(opcode1 << 4) | opcode2]; 2757 } else if (vex_m == VEX_m_0F3A) { 2758 dp = (instable_t *) 2759 &dis_opAVX660F3A 2760 [(opcode1 << 4) | opcode2]; 2761 } else { 2762 goto error; 2763 } 2764 break; 2765 case VEX_p_F3: 2766 if (vex_m == VEX_m_0F) { 2767 dp = (instable_t *) 2768 &dis_opAVXF30F 2769 [(opcode1 << 4) | opcode2]; 2770 } else { 2771 goto error; 2772 } 2773 break; 2774 case VEX_p_F2: 2775 if (vex_m == VEX_m_0F) { 2776 dp = (instable_t *) 2777 &dis_opAVXF20F 2778 [(opcode1 << 4) | opcode2]; 2779 } else { 2780 goto error; 2781 } 2782 break; 2783 default: 2784 dp = (instable_t *) 2785 &dis_opAVX0F[opcode1][opcode2]; 2786 2787 } 2788 } 2789 if (vex_prefix) { 2790 if (vex_L) 2791 wbit = YMM_OPND; 2792 else 2793 wbit = XMM_OPND; 2794 } 2795 2796 /* 2797 * Deal with selection of operand and address size now. 2798 * Note that the REX.W bit being set causes opnd_size_prefix to be 2799 * ignored. 2800 */ 2801 if (cpu_mode == SIZE64) { 2802 if ((rex_prefix & REX_W) || vex_W) 2803 opnd_size = SIZE64; 2804 else if (opnd_size_prefix) 2805 opnd_size = SIZE16; 2806 2807 if (addr_size_prefix) 2808 addr_size = SIZE32; 2809 } else if (cpu_mode == SIZE32) { 2810 if (opnd_size_prefix) 2811 opnd_size = SIZE16; 2812 if (addr_size_prefix) 2813 addr_size = SIZE16; 2814 } else { 2815 if (opnd_size_prefix) 2816 opnd_size = SIZE32; 2817 if (addr_size_prefix) 2818 addr_size = SIZE32; 2819 } 2820 /* 2821 * The pause instruction - a repz'd nop. This doesn't fit 2822 * with any of the other prefix goop added for SSE, so we'll 2823 * special-case it here. 2824 */ 2825 if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) { 2826 rep_prefix = 0; 2827 dp = (instable_t *)&dis_opPause; 2828 } 2829 2830 /* 2831 * Some 386 instructions have 2 bytes of opcode before the mod_r/m 2832 * byte so we may need to perform a table indirection. 2833 */ 2834 if (dp->it_indirect == (instable_t *)dis_op0F) { 2835 if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0) 2836 goto error; 2837 opcode_bytes = 2; 2838 if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) { 2839 uint_t subcode; 2840 2841 if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0) 2842 goto error; 2843 opcode_bytes = 3; 2844 subcode = ((opcode6 & 0x3) << 1) | 2845 ((opcode7 & 0x8) >> 3); 2846 dp = (instable_t *)&dis_op0F7123[opcode5][subcode]; 2847 } else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) { 2848 dp = (instable_t *)&dis_op0FC8[0]; 2849 } else if ((opcode4 == 0x3) && (opcode5 == 0xA)) { 2850 opcode_bytes = 3; 2851 if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0) 2852 goto error; 2853 if (opnd_size == SIZE16) 2854 opnd_size = SIZE32; 2855 2856 dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7]; 2857 #ifdef DIS_TEXT 2858 if (strcmp(dp->it_name, "INVALID") == 0) 2859 goto error; 2860 #endif 2861 switch (dp->it_adrmode) { 2862 case XMMP_66r: 2863 case XMMPRM_66r: 2864 case XMM3PM_66r: 2865 if (opnd_size_prefix == 0) { 2866 goto error; 2867 } 2868 break; 2869 case XMMP_66o: 2870 if (opnd_size_prefix == 0) { 2871 /* SSSE3 MMX instructions */ 2872 dp_mmx = *dp; 2873 dp = &dp_mmx; 2874 dp->it_adrmode = MMOPM_66o; 2875 #ifdef DIS_MEM 2876 dp->it_size = 8; 2877 #endif 2878 } 2879 break; 2880 default: 2881 goto error; 2882 } 2883 } else if ((opcode4 == 0x3) && (opcode5 == 0x8)) { 2884 opcode_bytes = 3; 2885 if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0) 2886 goto error; 2887 dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7]; 2888 2889 /* 2890 * Both crc32 and movbe have the same 3rd opcode 2891 * byte of either 0xF0 or 0xF1, so we use another 2892 * indirection to distinguish between the two. 2893 */ 2894 if (dp->it_indirect == (instable_t *)dis_op0F38F0 || 2895 dp->it_indirect == (instable_t *)dis_op0F38F1) { 2896 2897 dp = dp->it_indirect; 2898 if (rep_prefix != 0xF2) { 2899 /* It is movbe */ 2900 dp++; 2901 } 2902 } 2903 #ifdef DIS_TEXT 2904 if (strcmp(dp->it_name, "INVALID") == 0) 2905 goto error; 2906 #endif 2907 switch (dp->it_adrmode) { 2908 case XMM_66r: 2909 case XMMM_66r: 2910 if (opnd_size_prefix == 0) { 2911 goto error; 2912 } 2913 break; 2914 case XMM_66o: 2915 if (opnd_size_prefix == 0) { 2916 /* SSSE3 MMX instructions */ 2917 dp_mmx = *dp; 2918 dp = &dp_mmx; 2919 dp->it_adrmode = MM; 2920 #ifdef DIS_MEM 2921 dp->it_size = 8; 2922 #endif 2923 } 2924 break; 2925 case CRC32: 2926 if (rep_prefix != 0xF2) { 2927 goto error; 2928 } 2929 rep_prefix = 0; 2930 break; 2931 case MOVBE: 2932 if (rep_prefix != 0x0) { 2933 goto error; 2934 } 2935 break; 2936 default: 2937 goto error; 2938 } 2939 } else { 2940 dp = (instable_t *)&dis_op0F[opcode4][opcode5]; 2941 } 2942 } 2943 2944 /* 2945 * If still not at a TERM decode entry, then a ModRM byte 2946 * exists and its fields further decode the instruction. 2947 */ 2948 x->d86_got_modrm = 0; 2949 if (dp->it_indirect != TERM) { 2950 dtrace_get_modrm(x, &mode, &opcode3, &r_m); 2951 if (x->d86_error) 2952 goto error; 2953 reg = opcode3; 2954 2955 /* 2956 * decode 287 instructions (D8-DF) from opcodeN 2957 */ 2958 if (opcode1 == 0xD && opcode2 >= 0x8) { 2959 if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4) 2960 dp = (instable_t *)&dis_opFP5[r_m]; 2961 else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4) 2962 dp = (instable_t *)&dis_opFP7[opcode3]; 2963 else if (opcode2 == 0xB && mode == 0x3) 2964 dp = (instable_t *)&dis_opFP6[opcode3]; 2965 else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4) 2966 dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m]; 2967 else if (mode == 0x3) 2968 dp = (instable_t *) 2969 &dis_opFP3[opcode2 - 8][opcode3]; 2970 else 2971 dp = (instable_t *) 2972 &dis_opFP1n2[opcode2 - 8][opcode3]; 2973 } else { 2974 dp = (instable_t *)dp->it_indirect + opcode3; 2975 } 2976 } 2977 2978 /* 2979 * In amd64 bit mode, ARPL opcode is changed to MOVSXD 2980 * (sign extend 32bit to 64 bit) 2981 */ 2982 if ((vex_prefix == 0) && cpu_mode == SIZE64 && 2983 opcode1 == 0x6 && opcode2 == 0x3) 2984 dp = (instable_t *)&dis_opMOVSLD; 2985 2986 /* 2987 * at this point we should have a correct (or invalid) opcode 2988 */ 2989 if (cpu_mode == SIZE64 && dp->it_invalid64 || 2990 cpu_mode != SIZE64 && dp->it_invalid32) 2991 goto error; 2992 if (dp->it_indirect != TERM) 2993 goto error; 2994 2995 /* 2996 * deal with MMX/SSE opcodes which are changed by prefixes 2997 */ 2998 switch (dp->it_adrmode) { 2999 case MMO: 3000 case MMOIMPL: 3001 case MMO3P: 3002 case MMOM3: 3003 case MMOMS: 3004 case MMOPM: 3005 case MMOPRM: 3006 case MMOS: 3007 case XMMO: 3008 case XMMOM: 3009 case XMMOMS: 3010 case XMMOPM: 3011 case XMMOS: 3012 case XMMOMX: 3013 case XMMOX3: 3014 case XMMOXMM: 3015 /* 3016 * This is horrible. Some SIMD instructions take the 3017 * form 0x0F 0x?? ..., which is easily decoded using the 3018 * existing tables. Other SIMD instructions use various 3019 * prefix bytes to overload existing instructions. For 3020 * Example, addps is F0, 58, whereas addss is F3 (repz), 3021 * F0, 58. Presumably someone got a raise for this. 3022 * 3023 * If we see one of the instructions which can be 3024 * modified in this way (if we've got one of the SIMDO* 3025 * address modes), we'll check to see if the last prefix 3026 * was a repz. If it was, we strip the prefix from the 3027 * mnemonic, and we indirect using the dis_opSIMDrepz 3028 * table. 3029 */ 3030 3031 /* 3032 * Calculate our offset in dis_op0F 3033 */ 3034 if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F)) 3035 goto error; 3036 3037 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) / 3038 sizeof (instable_t); 3039 3040 /* 3041 * Rewrite if this instruction used one of the magic prefixes. 3042 */ 3043 if (rep_prefix) { 3044 if (rep_prefix == 0xf2) 3045 dp = (instable_t *)&dis_opSIMDrepnz[off]; 3046 else 3047 dp = (instable_t *)&dis_opSIMDrepz[off]; 3048 rep_prefix = 0; 3049 } else if (opnd_size_prefix) { 3050 dp = (instable_t *)&dis_opSIMDdata16[off]; 3051 opnd_size_prefix = 0; 3052 if (opnd_size == SIZE16) 3053 opnd_size = SIZE32; 3054 } 3055 break; 3056 3057 case MMOSH: 3058 /* 3059 * As with the "normal" SIMD instructions, the MMX 3060 * shuffle instructions are overloaded. These 3061 * instructions, however, are special in that they use 3062 * an extra byte, and thus an extra table. As of this 3063 * writing, they only use the opnd_size prefix. 3064 */ 3065 3066 /* 3067 * Calculate our offset in dis_op0F7123 3068 */ 3069 if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 > 3070 sizeof (dis_op0F7123)) 3071 goto error; 3072 3073 if (opnd_size_prefix) { 3074 off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) / 3075 sizeof (instable_t); 3076 dp = (instable_t *)&dis_opSIMD7123[off]; 3077 opnd_size_prefix = 0; 3078 if (opnd_size == SIZE16) 3079 opnd_size = SIZE32; 3080 } 3081 break; 3082 case MRw: 3083 if (rep_prefix) { 3084 if (rep_prefix == 0xf3) { 3085 3086 /* 3087 * Calculate our offset in dis_op0F 3088 */ 3089 if ((uintptr_t)dp - (uintptr_t)dis_op0F 3090 > sizeof (dis_op0F)) 3091 goto error; 3092 3093 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) / 3094 sizeof (instable_t); 3095 3096 dp = (instable_t *)&dis_opSIMDrepz[off]; 3097 rep_prefix = 0; 3098 } else { 3099 goto error; 3100 } 3101 } 3102 break; 3103 } 3104 3105 /* 3106 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64. 3107 */ 3108 if (cpu_mode == SIZE64) 3109 if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop)) 3110 opnd_size = SIZE64; 3111 3112 #ifdef DIS_TEXT 3113 /* 3114 * At this point most instructions can format the opcode mnemonic 3115 * including the prefixes. 3116 */ 3117 if (lock_prefix) 3118 (void) strlcat(x->d86_mnem, "lock ", OPLEN); 3119 3120 if (rep_prefix == 0xf2) 3121 (void) strlcat(x->d86_mnem, "repnz ", OPLEN); 3122 else if (rep_prefix == 0xf3) 3123 (void) strlcat(x->d86_mnem, "repz ", OPLEN); 3124 3125 if (cpu_mode == SIZE64 && addr_size_prefix) 3126 (void) strlcat(x->d86_mnem, "addr32 ", OPLEN); 3127 3128 if (dp->it_adrmode != CBW && 3129 dp->it_adrmode != CWD && 3130 dp->it_adrmode != XMMSFNC) { 3131 if (strcmp(dp->it_name, "INVALID") == 0) 3132 goto error; 3133 (void) strlcat(x->d86_mnem, dp->it_name, OPLEN); 3134 if (dp->it_suffix) { 3135 char *types[] = {"", "w", "l", "q"}; 3136 if (opcode_bytes == 2 && opcode4 == 4) { 3137 /* It's a cmovx.yy. Replace the suffix x */ 3138 for (i = 5; i < OPLEN; i++) { 3139 if (x->d86_mnem[i] == '.') 3140 break; 3141 } 3142 x->d86_mnem[i - 1] = *types[opnd_size]; 3143 } else if ((opnd_size == 2) && (opcode_bytes == 3) && 3144 ((opcode6 == 1 && opcode7 == 6) || 3145 (opcode6 == 2 && opcode7 == 2))) { 3146 /* 3147 * To handle PINSRD and PEXTRD 3148 */ 3149 (void) strlcat(x->d86_mnem, "d", OPLEN); 3150 } else { 3151 (void) strlcat(x->d86_mnem, types[opnd_size], 3152 OPLEN); 3153 } 3154 } 3155 } 3156 #endif 3157 3158 /* 3159 * Process operands based on the addressing modes. 3160 */ 3161 x->d86_mode = cpu_mode; 3162 /* 3163 * In vex mode the rex_prefix has no meaning 3164 */ 3165 if (!vex_prefix) 3166 x->d86_rex_prefix = rex_prefix; 3167 x->d86_opnd_size = opnd_size; 3168 x->d86_addr_size = addr_size; 3169 vbit = 0; /* initialize for mem/reg -> reg */ 3170 switch (dp->it_adrmode) { 3171 /* 3172 * amd64 instruction to sign extend 32 bit reg/mem operands 3173 * into 64 bit register values 3174 */ 3175 case MOVSXZ: 3176 #ifdef DIS_TEXT 3177 if (rex_prefix == 0) 3178 (void) strncpy(x->d86_mnem, "movzld", OPLEN); 3179 #endif 3180 dtrace_get_modrm(x, &mode, ®, &r_m); 3181 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3182 x->d86_opnd_size = SIZE64; 3183 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3184 x->d86_opnd_size = opnd_size = SIZE32; 3185 wbit = LONG_OPND; 3186 dtrace_get_operand(x, mode, r_m, wbit, 0); 3187 break; 3188 3189 /* 3190 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF) 3191 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7) 3192 * wbit lives in 2nd byte, note that operands 3193 * are different sized 3194 */ 3195 case MOVZ: 3196 if (rex_prefix & REX_W) { 3197 /* target register size = 64 bit */ 3198 x->d86_mnem[5] = 'q'; 3199 } 3200 dtrace_get_modrm(x, &mode, ®, &r_m); 3201 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3202 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3203 x->d86_opnd_size = opnd_size = SIZE16; 3204 wbit = WBIT(opcode5); 3205 dtrace_get_operand(x, mode, r_m, wbit, 0); 3206 break; 3207 case CRC32: 3208 opnd_size = SIZE32; 3209 if (rex_prefix & REX_W) 3210 opnd_size = SIZE64; 3211 x->d86_opnd_size = opnd_size; 3212 3213 dtrace_get_modrm(x, &mode, ®, &r_m); 3214 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3215 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3216 wbit = WBIT(opcode7); 3217 if (opnd_size_prefix) 3218 x->d86_opnd_size = opnd_size = SIZE16; 3219 dtrace_get_operand(x, mode, r_m, wbit, 0); 3220 break; 3221 case MOVBE: 3222 opnd_size = SIZE32; 3223 if (rex_prefix & REX_W) 3224 opnd_size = SIZE64; 3225 x->d86_opnd_size = opnd_size; 3226 3227 dtrace_get_modrm(x, &mode, ®, &r_m); 3228 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3229 wbit = WBIT(opcode7); 3230 if (opnd_size_prefix) 3231 x->d86_opnd_size = opnd_size = SIZE16; 3232 if (wbit) { 3233 /* reg -> mem */ 3234 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0); 3235 dtrace_get_operand(x, mode, r_m, wbit, 1); 3236 } else { 3237 /* mem -> reg */ 3238 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3239 dtrace_get_operand(x, mode, r_m, wbit, 0); 3240 } 3241 break; 3242 3243 /* 3244 * imul instruction, with either 8-bit or longer immediate 3245 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s) 3246 */ 3247 case IMUL: 3248 wbit = LONG_OPND; 3249 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 3250 OPSIZE(opnd_size, opcode2 == 0x9), 1); 3251 break; 3252 3253 /* memory or register operand to register, with 'w' bit */ 3254 case MRw: 3255 wbit = WBIT(opcode2); 3256 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0); 3257 break; 3258 3259 /* register to memory or register operand, with 'w' bit */ 3260 /* arpl happens to fit here also because it is odd */ 3261 case RMw: 3262 if (opcode_bytes == 2) 3263 wbit = WBIT(opcode5); 3264 else 3265 wbit = WBIT(opcode2); 3266 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 3267 break; 3268 3269 /* xaddb instruction */ 3270 case XADDB: 3271 wbit = 0; 3272 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 3273 break; 3274 3275 /* MMX register to memory or register operand */ 3276 case MMS: 3277 case MMOS: 3278 #ifdef DIS_TEXT 3279 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND; 3280 #else 3281 wbit = LONG_OPND; 3282 #endif 3283 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1); 3284 break; 3285 3286 /* MMX register to memory */ 3287 case MMOMS: 3288 dtrace_get_modrm(x, &mode, ®, &r_m); 3289 if (mode == REG_ONLY) 3290 goto error; 3291 wbit = MM_OPND; 3292 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1); 3293 break; 3294 3295 /* Double shift. Has immediate operand specifying the shift. */ 3296 case DSHIFT: 3297 wbit = LONG_OPND; 3298 dtrace_get_modrm(x, &mode, ®, &r_m); 3299 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3300 dtrace_get_operand(x, mode, r_m, wbit, 2); 3301 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3302 dtrace_imm_opnd(x, wbit, 1, 0); 3303 break; 3304 3305 /* 3306 * Double shift. With no immediate operand, specifies using %cl. 3307 */ 3308 case DSHIFTcl: 3309 wbit = LONG_OPND; 3310 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 3311 break; 3312 3313 /* immediate to memory or register operand */ 3314 case IMlw: 3315 wbit = WBIT(opcode2); 3316 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3317 dtrace_get_operand(x, mode, r_m, wbit, 1); 3318 /* 3319 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83 3320 */ 3321 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0); 3322 break; 3323 3324 /* immediate to memory or register operand with the */ 3325 /* 'w' bit present */ 3326 case IMw: 3327 wbit = WBIT(opcode2); 3328 dtrace_get_modrm(x, &mode, ®, &r_m); 3329 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3330 dtrace_get_operand(x, mode, r_m, wbit, 1); 3331 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0); 3332 break; 3333 3334 /* immediate to register with register in low 3 bits */ 3335 /* of op code */ 3336 case IR: 3337 /* w-bit here (with regs) is bit 3 */ 3338 wbit = opcode2 >>3 & 0x1; 3339 reg = REGNO(opcode2); 3340 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 3341 mode = REG_ONLY; 3342 r_m = reg; 3343 dtrace_get_operand(x, mode, r_m, wbit, 1); 3344 dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0); 3345 break; 3346 3347 /* MMX immediate shift of register */ 3348 case MMSH: 3349 case MMOSH: 3350 wbit = MM_OPND; 3351 goto mm_shift; /* in next case */ 3352 3353 /* SIMD immediate shift of register */ 3354 case XMMSH: 3355 wbit = XMM_OPND; 3356 mm_shift: 3357 reg = REGNO(opcode7); 3358 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 3359 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 3360 dtrace_imm_opnd(x, wbit, 1, 0); 3361 NOMEM; 3362 break; 3363 3364 /* accumulator to memory operand */ 3365 case AO: 3366 vbit = 1; 3367 /*FALLTHROUGH*/ 3368 3369 /* memory operand to accumulator */ 3370 case OA: 3371 wbit = WBIT(opcode2); 3372 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit); 3373 dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit); 3374 #ifdef DIS_TEXT 3375 x->d86_opnd[vbit].d86_mode = MODE_OFFSET; 3376 #endif 3377 break; 3378 3379 3380 /* segment register to memory or register operand */ 3381 case SM: 3382 vbit = 1; 3383 /*FALLTHROUGH*/ 3384 3385 /* memory or register operand to segment register */ 3386 case MS: 3387 dtrace_get_modrm(x, &mode, ®, &r_m); 3388 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3389 dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit); 3390 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit); 3391 break; 3392 3393 /* 3394 * rotate or shift instructions, which may shift by 1 or 3395 * consult the cl register, depending on the 'v' bit 3396 */ 3397 case Mv: 3398 vbit = VBIT(opcode2); 3399 wbit = WBIT(opcode2); 3400 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3401 dtrace_get_operand(x, mode, r_m, wbit, 1); 3402 #ifdef DIS_TEXT 3403 if (vbit) { 3404 (void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN); 3405 } else { 3406 x->d86_opnd[0].d86_mode = MODE_SIGNED; 3407 x->d86_opnd[0].d86_value_size = 1; 3408 x->d86_opnd[0].d86_value = 1; 3409 } 3410 #endif 3411 break; 3412 /* 3413 * immediate rotate or shift instructions 3414 */ 3415 case MvI: 3416 wbit = WBIT(opcode2); 3417 normal_imm_mem: 3418 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3419 dtrace_get_operand(x, mode, r_m, wbit, 1); 3420 dtrace_imm_opnd(x, wbit, 1, 0); 3421 break; 3422 3423 /* bit test instructions */ 3424 case MIb: 3425 wbit = LONG_OPND; 3426 goto normal_imm_mem; 3427 3428 /* single memory or register operand with 'w' bit present */ 3429 case Mw: 3430 wbit = WBIT(opcode2); 3431 just_mem: 3432 dtrace_get_modrm(x, &mode, ®, &r_m); 3433 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3434 dtrace_get_operand(x, mode, r_m, wbit, 0); 3435 break; 3436 3437 case SWAPGS: 3438 if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) { 3439 #ifdef DIS_TEXT 3440 (void) strncpy(x->d86_mnem, "swapgs", OPLEN); 3441 #endif 3442 NOMEM; 3443 break; 3444 } 3445 /*FALLTHROUGH*/ 3446 3447 /* prefetch instruction - memory operand, but no memory acess */ 3448 case PREF: 3449 NOMEM; 3450 /*FALLTHROUGH*/ 3451 3452 /* single memory or register operand */ 3453 case M: 3454 wbit = LONG_OPND; 3455 goto just_mem; 3456 3457 /* single memory or register byte operand */ 3458 case Mb: 3459 wbit = BYTE_OPND; 3460 goto just_mem; 3461 3462 case MONITOR_MWAIT: 3463 if (mode == 3) { 3464 if (r_m == 0) { 3465 #ifdef DIS_TEXT 3466 (void) strncpy(x->d86_mnem, "monitor", OPLEN); 3467 #endif 3468 NOMEM; 3469 break; 3470 } else if (r_m == 1) { 3471 #ifdef DIS_TEXT 3472 (void) strncpy(x->d86_mnem, "mwait", OPLEN); 3473 #endif 3474 NOMEM; 3475 break; 3476 } else { 3477 goto error; 3478 } 3479 } 3480 /*FALLTHROUGH*/ 3481 case XGETBV_XSETBV: 3482 if (mode == 3) { 3483 if (r_m == 0) { 3484 #ifdef DIS_TEXT 3485 (void) strncpy(x->d86_mnem, "xgetbv", OPLEN); 3486 #endif 3487 NOMEM; 3488 break; 3489 } else if (r_m == 1) { 3490 #ifdef DIS_TEXT 3491 (void) strncpy(x->d86_mnem, "xsetbv", OPLEN); 3492 #endif 3493 NOMEM; 3494 break; 3495 } else { 3496 goto error; 3497 } 3498 3499 } 3500 /*FALLTHROUGH*/ 3501 case MO: 3502 /* Similar to M, but only memory (no direct registers) */ 3503 wbit = LONG_OPND; 3504 dtrace_get_modrm(x, &mode, ®, &r_m); 3505 if (mode == 3) 3506 goto error; 3507 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3508 dtrace_get_operand(x, mode, r_m, wbit, 0); 3509 break; 3510 3511 /* move special register to register or reverse if vbit */ 3512 case SREG: 3513 switch (opcode5) { 3514 3515 case 2: 3516 vbit = 1; 3517 /*FALLTHROUGH*/ 3518 case 0: 3519 wbit = CONTROL_OPND; 3520 break; 3521 3522 case 3: 3523 vbit = 1; 3524 /*FALLTHROUGH*/ 3525 case 1: 3526 wbit = DEBUG_OPND; 3527 break; 3528 3529 case 6: 3530 vbit = 1; 3531 /*FALLTHROUGH*/ 3532 case 4: 3533 wbit = TEST_OPND; 3534 break; 3535 3536 } 3537 dtrace_get_modrm(x, &mode, ®, &r_m); 3538 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3539 dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit); 3540 dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit); 3541 NOMEM; 3542 break; 3543 3544 /* 3545 * single register operand with register in the low 3 3546 * bits of op code 3547 */ 3548 case R: 3549 if (opcode_bytes == 2) 3550 reg = REGNO(opcode5); 3551 else 3552 reg = REGNO(opcode2); 3553 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 3554 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0); 3555 NOMEM; 3556 break; 3557 3558 /* 3559 * register to accumulator with register in the low 3 3560 * bits of op code, xchg instructions 3561 */ 3562 case RA: 3563 NOMEM; 3564 reg = REGNO(opcode2); 3565 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 3566 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0); 3567 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1); 3568 break; 3569 3570 /* 3571 * single segment register operand, with register in 3572 * bits 3-4 of op code byte 3573 */ 3574 case SEG: 3575 NOMEM; 3576 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3; 3577 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0); 3578 break; 3579 3580 /* 3581 * single segment register operand, with register in 3582 * bits 3-5 of op code 3583 */ 3584 case LSEG: 3585 NOMEM; 3586 /* long seg reg from opcode */ 3587 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7; 3588 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0); 3589 break; 3590 3591 /* memory or register operand to register */ 3592 case MR: 3593 if (vex_prefetch) 3594 x->d86_got_modrm = 1; 3595 wbit = LONG_OPND; 3596 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0); 3597 break; 3598 3599 case RM: 3600 wbit = LONG_OPND; 3601 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 3602 break; 3603 3604 /* MMX/SIMD-Int memory or mm reg to mm reg */ 3605 case MM: 3606 case MMO: 3607 #ifdef DIS_TEXT 3608 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND; 3609 #else 3610 wbit = LONG_OPND; 3611 #endif 3612 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0); 3613 break; 3614 3615 case MMOIMPL: 3616 #ifdef DIS_TEXT 3617 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND; 3618 #else 3619 wbit = LONG_OPND; 3620 #endif 3621 dtrace_get_modrm(x, &mode, ®, &r_m); 3622 if (mode != REG_ONLY) 3623 goto error; 3624 3625 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3626 dtrace_get_operand(x, mode, r_m, wbit, 0); 3627 dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1); 3628 mode = 0; /* change for memory access size... */ 3629 break; 3630 3631 /* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */ 3632 case MMO3P: 3633 wbit = MM_OPND; 3634 goto xmm3p; 3635 case XMM3P: 3636 wbit = XMM_OPND; 3637 xmm3p: 3638 dtrace_get_modrm(x, &mode, ®, &r_m); 3639 if (mode != REG_ONLY) 3640 goto error; 3641 3642 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1, 3643 1); 3644 NOMEM; 3645 break; 3646 3647 case XMM3PM_66r: 3648 THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND, 3649 1, 0); 3650 break; 3651 3652 /* MMX/SIMD-Int predicated r32/mem to mm reg */ 3653 case MMOPRM: 3654 wbit = LONG_OPND; 3655 w2 = MM_OPND; 3656 goto xmmprm; 3657 case XMMPRM: 3658 case XMMPRM_66r: 3659 wbit = LONG_OPND; 3660 w2 = XMM_OPND; 3661 xmmprm: 3662 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1); 3663 break; 3664 3665 /* MMX/SIMD-Int predicated mm/mem to mm reg */ 3666 case MMOPM: 3667 case MMOPM_66o: 3668 wbit = w2 = MM_OPND; 3669 goto xmmprm; 3670 3671 /* MMX/SIMD-Int mm reg to r32 */ 3672 case MMOM3: 3673 NOMEM; 3674 dtrace_get_modrm(x, &mode, ®, &r_m); 3675 if (mode != REG_ONLY) 3676 goto error; 3677 wbit = MM_OPND; 3678 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0); 3679 break; 3680 3681 /* SIMD memory or xmm reg operand to xmm reg */ 3682 case XMM: 3683 case XMM_66o: 3684 case XMM_66r: 3685 case XMMO: 3686 case XMMXIMPL: 3687 wbit = XMM_OPND; 3688 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0); 3689 3690 if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY) 3691 goto error; 3692 3693 #ifdef DIS_TEXT 3694 /* 3695 * movlps and movhlps share opcodes. They differ in the 3696 * addressing modes allowed for their operands. 3697 * movhps and movlhps behave similarly. 3698 */ 3699 if (mode == REG_ONLY) { 3700 if (strcmp(dp->it_name, "movlps") == 0) 3701 (void) strncpy(x->d86_mnem, "movhlps", OPLEN); 3702 else if (strcmp(dp->it_name, "movhps") == 0) 3703 (void) strncpy(x->d86_mnem, "movlhps", OPLEN); 3704 } 3705 #endif 3706 if (dp->it_adrmode == XMMXIMPL) 3707 mode = 0; /* change for memory access size... */ 3708 break; 3709 3710 /* SIMD xmm reg to memory or xmm reg */ 3711 case XMMS: 3712 case XMMOS: 3713 case XMMMS: 3714 case XMMOMS: 3715 dtrace_get_modrm(x, &mode, ®, &r_m); 3716 #ifdef DIS_TEXT 3717 if ((strcmp(dp->it_name, "movlps") == 0 || 3718 strcmp(dp->it_name, "movhps") == 0 || 3719 strcmp(dp->it_name, "movntps") == 0) && 3720 mode == REG_ONLY) 3721 goto error; 3722 #endif 3723 wbit = XMM_OPND; 3724 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1); 3725 break; 3726 3727 /* SIMD memory to xmm reg */ 3728 case XMMM: 3729 case XMMM_66r: 3730 case XMMOM: 3731 wbit = XMM_OPND; 3732 dtrace_get_modrm(x, &mode, ®, &r_m); 3733 #ifdef DIS_TEXT 3734 if (mode == REG_ONLY) { 3735 if (strcmp(dp->it_name, "movhps") == 0) 3736 (void) strncpy(x->d86_mnem, "movlhps", OPLEN); 3737 else 3738 goto error; 3739 } 3740 #endif 3741 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0); 3742 break; 3743 3744 /* SIMD memory or r32 to xmm reg */ 3745 case XMM3MX: 3746 wbit = LONG_OPND; 3747 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0); 3748 break; 3749 3750 case XMM3MXS: 3751 wbit = LONG_OPND; 3752 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1); 3753 break; 3754 3755 /* SIMD memory or mm reg to xmm reg */ 3756 case XMMOMX: 3757 /* SIMD mm to xmm */ 3758 case XMMMX: 3759 wbit = MM_OPND; 3760 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0); 3761 break; 3762 3763 /* SIMD memory or xmm reg to mm reg */ 3764 case XMMXMM: 3765 case XMMOXMM: 3766 case XMMXM: 3767 wbit = XMM_OPND; 3768 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0); 3769 break; 3770 3771 3772 /* SIMD memory or xmm reg to r32 */ 3773 case XMMXM3: 3774 wbit = XMM_OPND; 3775 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0); 3776 break; 3777 3778 /* SIMD xmm to r32 */ 3779 case XMMX3: 3780 case XMMOX3: 3781 dtrace_get_modrm(x, &mode, ®, &r_m); 3782 if (mode != REG_ONLY) 3783 goto error; 3784 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3785 dtrace_get_operand(x, mode, r_m, XMM_OPND, 0); 3786 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3787 NOMEM; 3788 break; 3789 3790 /* SIMD predicated memory or xmm reg with/to xmm reg */ 3791 case XMMP: 3792 case XMMP_66r: 3793 case XMMP_66o: 3794 case XMMOPM: 3795 wbit = XMM_OPND; 3796 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1, 3797 1); 3798 3799 #ifdef DIS_TEXT 3800 /* 3801 * cmpps and cmpss vary their instruction name based 3802 * on the value of imm8. Other XMMP instructions, 3803 * such as shufps, require explicit specification of 3804 * the predicate. 3805 */ 3806 if (dp->it_name[0] == 'c' && 3807 dp->it_name[1] == 'm' && 3808 dp->it_name[2] == 'p' && 3809 strlen(dp->it_name) == 5) { 3810 uchar_t pred = x->d86_opnd[0].d86_value & 0xff; 3811 3812 if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *))) 3813 goto error; 3814 3815 (void) strncpy(x->d86_mnem, "cmp", OPLEN); 3816 (void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred], 3817 OPLEN); 3818 (void) strlcat(x->d86_mnem, 3819 dp->it_name + strlen(dp->it_name) - 2, 3820 OPLEN); 3821 x->d86_opnd[0] = x->d86_opnd[1]; 3822 x->d86_opnd[1] = x->d86_opnd[2]; 3823 x->d86_numopnds = 2; 3824 } 3825 #endif 3826 break; 3827 3828 case XMMX2I: 3829 FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND, 3830 1); 3831 NOMEM; 3832 break; 3833 3834 case XMM2I: 3835 ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1); 3836 NOMEM; 3837 break; 3838 3839 /* immediate operand to accumulator */ 3840 case IA: 3841 wbit = WBIT(opcode2); 3842 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1); 3843 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0); 3844 NOMEM; 3845 break; 3846 3847 /* memory or register operand to accumulator */ 3848 case MA: 3849 wbit = WBIT(opcode2); 3850 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3851 dtrace_get_operand(x, mode, r_m, wbit, 0); 3852 break; 3853 3854 /* si register to di register used to reference memory */ 3855 case SD: 3856 #ifdef DIS_TEXT 3857 dtrace_check_override(x, 0); 3858 x->d86_numopnds = 2; 3859 if (addr_size == SIZE64) { 3860 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)", 3861 OPLEN); 3862 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)", 3863 OPLEN); 3864 } else if (addr_size == SIZE32) { 3865 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)", 3866 OPLEN); 3867 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)", 3868 OPLEN); 3869 } else { 3870 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)", 3871 OPLEN); 3872 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)", 3873 OPLEN); 3874 } 3875 #endif 3876 wbit = LONG_OPND; 3877 break; 3878 3879 /* accumulator to di register */ 3880 case AD: 3881 wbit = WBIT(opcode2); 3882 #ifdef DIS_TEXT 3883 dtrace_check_override(x, 1); 3884 x->d86_numopnds = 2; 3885 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0); 3886 if (addr_size == SIZE64) 3887 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)", 3888 OPLEN); 3889 else if (addr_size == SIZE32) 3890 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)", 3891 OPLEN); 3892 else 3893 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)", 3894 OPLEN); 3895 #endif 3896 break; 3897 3898 /* si register to accumulator */ 3899 case SA: 3900 wbit = WBIT(opcode2); 3901 #ifdef DIS_TEXT 3902 dtrace_check_override(x, 0); 3903 x->d86_numopnds = 2; 3904 if (addr_size == SIZE64) 3905 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)", 3906 OPLEN); 3907 else if (addr_size == SIZE32) 3908 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)", 3909 OPLEN); 3910 else 3911 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)", 3912 OPLEN); 3913 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1); 3914 #endif 3915 break; 3916 3917 /* 3918 * single operand, a 16/32 bit displacement 3919 */ 3920 case D: 3921 wbit = LONG_OPND; 3922 dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0); 3923 NOMEM; 3924 break; 3925 3926 /* jmp/call indirect to memory or register operand */ 3927 case INM: 3928 #ifdef DIS_TEXT 3929 (void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN); 3930 #endif 3931 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3932 dtrace_get_operand(x, mode, r_m, LONG_OPND, 0); 3933 wbit = LONG_OPND; 3934 break; 3935 3936 /* 3937 * for long jumps and long calls -- a new code segment 3938 * register and an offset in IP -- stored in object 3939 * code in reverse order. Note - not valid in amd64 3940 */ 3941 case SO: 3942 dtrace_check_override(x, 1); 3943 wbit = LONG_OPND; 3944 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1); 3945 #ifdef DIS_TEXT 3946 x->d86_opnd[1].d86_mode = MODE_SIGNED; 3947 #endif 3948 /* will now get segment operand */ 3949 dtrace_imm_opnd(x, wbit, 2, 0); 3950 break; 3951 3952 /* 3953 * jmp/call. single operand, 8 bit displacement. 3954 * added to current EIP in 'compofff' 3955 */ 3956 case BD: 3957 dtrace_disp_opnd(x, BYTE_OPND, 1, 0); 3958 NOMEM; 3959 break; 3960 3961 /* single 32/16 bit immediate operand */ 3962 case I: 3963 wbit = LONG_OPND; 3964 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0); 3965 break; 3966 3967 /* single 8 bit immediate operand */ 3968 case Ib: 3969 wbit = LONG_OPND; 3970 dtrace_imm_opnd(x, wbit, 1, 0); 3971 break; 3972 3973 case ENTER: 3974 wbit = LONG_OPND; 3975 dtrace_imm_opnd(x, wbit, 2, 0); 3976 dtrace_imm_opnd(x, wbit, 1, 1); 3977 switch (opnd_size) { 3978 case SIZE64: 3979 x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8; 3980 break; 3981 case SIZE32: 3982 x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4; 3983 break; 3984 case SIZE16: 3985 x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2; 3986 break; 3987 } 3988 3989 break; 3990 3991 /* 16-bit immediate operand */ 3992 case RET: 3993 wbit = LONG_OPND; 3994 dtrace_imm_opnd(x, wbit, 2, 0); 3995 break; 3996 3997 /* single 8 bit port operand */ 3998 case P: 3999 dtrace_check_override(x, 0); 4000 dtrace_imm_opnd(x, BYTE_OPND, 1, 0); 4001 NOMEM; 4002 break; 4003 4004 /* single operand, dx register (variable port instruction) */ 4005 case V: 4006 x->d86_numopnds = 1; 4007 dtrace_check_override(x, 0); 4008 #ifdef DIS_TEXT 4009 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN); 4010 #endif 4011 NOMEM; 4012 break; 4013 4014 /* 4015 * The int instruction, which has two forms: 4016 * int 3 (breakpoint) or 4017 * int n, where n is indicated in the subsequent 4018 * byte (format Ib). The int 3 instruction (opcode 0xCC), 4019 * where, although the 3 looks like an operand, 4020 * it is implied by the opcode. It must be converted 4021 * to the correct base and output. 4022 */ 4023 case INT3: 4024 #ifdef DIS_TEXT 4025 x->d86_numopnds = 1; 4026 x->d86_opnd[0].d86_mode = MODE_SIGNED; 4027 x->d86_opnd[0].d86_value_size = 1; 4028 x->d86_opnd[0].d86_value = 3; 4029 #endif 4030 NOMEM; 4031 break; 4032 4033 /* single 8 bit immediate operand */ 4034 case INTx: 4035 dtrace_imm_opnd(x, BYTE_OPND, 1, 0); 4036 NOMEM; 4037 break; 4038 4039 /* an unused byte must be discarded */ 4040 case U: 4041 if (x->d86_get_byte(x->d86_data) < 0) 4042 goto error; 4043 x->d86_len++; 4044 NOMEM; 4045 break; 4046 4047 case CBW: 4048 #ifdef DIS_TEXT 4049 if (opnd_size == SIZE16) 4050 (void) strlcat(x->d86_mnem, "cbtw", OPLEN); 4051 else if (opnd_size == SIZE32) 4052 (void) strlcat(x->d86_mnem, "cwtl", OPLEN); 4053 else 4054 (void) strlcat(x->d86_mnem, "cltq", OPLEN); 4055 #endif 4056 wbit = LONG_OPND; 4057 NOMEM; 4058 break; 4059 4060 case CWD: 4061 #ifdef DIS_TEXT 4062 if (opnd_size == SIZE16) 4063 (void) strlcat(x->d86_mnem, "cwtd", OPLEN); 4064 else if (opnd_size == SIZE32) 4065 (void) strlcat(x->d86_mnem, "cltd", OPLEN); 4066 else 4067 (void) strlcat(x->d86_mnem, "cqtd", OPLEN); 4068 #endif 4069 wbit = LONG_OPND; 4070 NOMEM; 4071 break; 4072 4073 case XMMSFNC: 4074 /* 4075 * sfence is sfence if mode is REG_ONLY. If mode isn't 4076 * REG_ONLY, mnemonic should be 'clflush'. 4077 */ 4078 dtrace_get_modrm(x, &mode, ®, &r_m); 4079 4080 /* sfence doesn't take operands */ 4081 #ifdef DIS_TEXT 4082 if (mode == REG_ONLY) { 4083 (void) strlcat(x->d86_mnem, "sfence", OPLEN); 4084 } else { 4085 (void) strlcat(x->d86_mnem, "clflush", OPLEN); 4086 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 4087 dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0); 4088 NOMEM; 4089 } 4090 #else 4091 if (mode != REG_ONLY) { 4092 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 4093 dtrace_get_operand(x, mode, r_m, LONG_OPND, 0); 4094 NOMEM; 4095 } 4096 #endif 4097 break; 4098 4099 /* 4100 * no disassembly, the mnemonic was all there was so go on 4101 */ 4102 case NORM: 4103 if (dp->it_invalid32 && cpu_mode != SIZE64) 4104 goto error; 4105 NOMEM; 4106 /*FALLTHROUGH*/ 4107 case IMPLMEM: 4108 break; 4109 4110 case XMMFENCE: 4111 /* 4112 * XRSTOR and LFENCE share the same opcode but differ in mode 4113 */ 4114 dtrace_get_modrm(x, &mode, ®, &r_m); 4115 4116 if (mode == REG_ONLY) { 4117 /* 4118 * Only the following exact byte sequences are allowed: 4119 * 4120 * 0f ae e8 lfence 4121 * 0f ae f0 mfence 4122 */ 4123 if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 && 4124 (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0) 4125 goto error; 4126 } else { 4127 #ifdef DIS_TEXT 4128 (void) strncpy(x->d86_mnem, "xrstor", OPLEN); 4129 #endif 4130 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 4131 dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0); 4132 } 4133 break; 4134 4135 /* float reg */ 4136 case F: 4137 #ifdef DIS_TEXT 4138 x->d86_numopnds = 1; 4139 (void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN); 4140 x->d86_opnd[0].d86_opnd[4] = r_m + '0'; 4141 #endif 4142 NOMEM; 4143 break; 4144 4145 /* float reg to float reg, with ret bit present */ 4146 case FF: 4147 vbit = opcode2 >> 2 & 0x1; /* vbit = 1: st -> st(i) */ 4148 /*FALLTHROUGH*/ 4149 case FFC: /* case for vbit always = 0 */ 4150 #ifdef DIS_TEXT 4151 x->d86_numopnds = 2; 4152 (void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN); 4153 (void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN); 4154 x->d86_opnd[vbit].d86_opnd[4] = r_m + '0'; 4155 #endif 4156 NOMEM; 4157 break; 4158 4159 /* AVX instructions */ 4160 case VEX_MO: 4161 /* op(ModR/M.r/m) */ 4162 x->d86_numopnds = 1; 4163 dtrace_get_modrm(x, &mode, ®, &r_m); 4164 #ifdef DIS_TEXT 4165 if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3)) 4166 (void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN); 4167 #endif 4168 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4169 dtrace_get_operand(x, mode, r_m, wbit, 0); 4170 break; 4171 case VEX_RMrX: 4172 /* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */ 4173 x->d86_numopnds = 3; 4174 dtrace_get_modrm(x, &mode, ®, &r_m); 4175 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4176 4177 if (mode != REG_ONLY) { 4178 if ((dp == &dis_opAVXF20F[0x10]) || 4179 (dp == &dis_opAVXF30F[0x10])) { 4180 /* vmovsd <m64>, <xmm> */ 4181 /* or vmovss <m64>, <xmm> */ 4182 x->d86_numopnds = 2; 4183 goto L_VEX_MX; 4184 } 4185 } 4186 4187 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2); 4188 /* 4189 * VEX prefix uses the 1's complement form to encode the 4190 * XMM/YMM regs 4191 */ 4192 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1); 4193 4194 if ((dp == &dis_opAVXF20F[0x2A]) || 4195 (dp == &dis_opAVXF30F[0x2A])) { 4196 /* 4197 * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>, 4198 * <xmm>, <xmm> 4199 */ 4200 wbit = LONG_OPND; 4201 } 4202 #ifdef DIS_TEXT 4203 else if ((mode == REG_ONLY) && 4204 (dp == &dis_opAVX0F[0x1][0x6])) { /* vmovlhps */ 4205 (void) strncpy(x->d86_mnem, "vmovlhps", OPLEN); 4206 } else if ((mode == REG_ONLY) && 4207 (dp == &dis_opAVX0F[0x1][0x2])) { /* vmovhlps */ 4208 (void) strncpy(x->d86_mnem, "vmovhlps", OPLEN); 4209 } 4210 #endif 4211 dtrace_get_operand(x, mode, r_m, wbit, 0); 4212 4213 break; 4214 4215 case VEX_RRX: 4216 /* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */ 4217 x->d86_numopnds = 3; 4218 4219 dtrace_get_modrm(x, &mode, ®, &r_m); 4220 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4221 4222 if (mode != REG_ONLY) { 4223 if ((dp == &dis_opAVXF20F[0x11]) || 4224 (dp == &dis_opAVXF30F[0x11])) { 4225 /* vmovsd <xmm>, <m64> */ 4226 /* or vmovss <xmm>, <m64> */ 4227 x->d86_numopnds = 2; 4228 goto L_VEX_RM; 4229 } 4230 } 4231 4232 dtrace_get_operand(x, mode, r_m, wbit, 2); 4233 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1); 4234 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0); 4235 break; 4236 4237 case VEX_RMRX: 4238 /* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */ 4239 x->d86_numopnds = 4; 4240 4241 dtrace_get_modrm(x, &mode, ®, &r_m); 4242 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4243 dtrace_get_operand(x, REG_ONLY, reg, wbit, 3); 4244 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2); 4245 if (dp == &dis_opAVX660F3A[0x18]) { 4246 /* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */ 4247 dtrace_get_operand(x, mode, r_m, XMM_OPND, 1); 4248 } else if ((dp == &dis_opAVX660F3A[0x20]) || 4249 (dp == & dis_opAVX660F[0xC4])) { 4250 /* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */ 4251 /* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */ 4252 dtrace_get_operand(x, mode, r_m, LONG_OPND, 1); 4253 } else if (dp == &dis_opAVX660F3A[0x22]) { 4254 /* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */ 4255 #ifdef DIS_TEXT 4256 if (vex_W) 4257 x->d86_mnem[6] = 'q'; 4258 #endif 4259 dtrace_get_operand(x, mode, r_m, LONG_OPND, 1); 4260 } else { 4261 dtrace_get_operand(x, mode, r_m, wbit, 1); 4262 } 4263 4264 /* one byte immediate number */ 4265 dtrace_imm_opnd(x, wbit, 1, 0); 4266 4267 /* vblendvpd, vblendvps, vblendvb use the imm encode the regs */ 4268 if ((dp == &dis_opAVX660F3A[0x4A]) || 4269 (dp == &dis_opAVX660F3A[0x4B]) || 4270 (dp == &dis_opAVX660F3A[0x4C])) { 4271 #ifdef DIS_TEXT 4272 int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4; 4273 #endif 4274 x->d86_opnd[0].d86_mode = MODE_NONE; 4275 #ifdef DIS_TEXT 4276 if (vex_L) 4277 (void) strncpy(x->d86_opnd[0].d86_opnd, 4278 dis_YMMREG[regnum], OPLEN); 4279 else 4280 (void) strncpy(x->d86_opnd[0].d86_opnd, 4281 dis_XMMREG[regnum], OPLEN); 4282 #endif 4283 } 4284 break; 4285 4286 case VEX_MX: 4287 /* ModR/M.reg := op(ModR/M.rm) */ 4288 x->d86_numopnds = 2; 4289 4290 dtrace_get_modrm(x, &mode, ®, &r_m); 4291 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4292 L_VEX_MX: 4293 4294 if ((dp == &dis_opAVXF20F[0xE6]) || 4295 (dp == &dis_opAVX660F[0x5A]) || 4296 (dp == &dis_opAVX660F[0xE6])) { 4297 /* vcvtpd2dq <ymm>, <xmm> */ 4298 /* or vcvtpd2ps <ymm>, <xmm> */ 4299 /* or vcvttpd2dq <ymm>, <xmm> */ 4300 dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1); 4301 dtrace_get_operand(x, mode, r_m, wbit, 0); 4302 } else if ((dp == &dis_opAVXF30F[0xE6]) || 4303 (dp == &dis_opAVX0F[0x5][0xA])) { 4304 /* vcvtdq2pd <xmm>, <ymm> */ 4305 /* or vcvtps2pd <xmm>, <ymm> */ 4306 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4307 dtrace_get_operand(x, mode, r_m, XMM_OPND, 0); 4308 } else if (dp == &dis_opAVX660F[0x6E]) { 4309 /* vmovd/q <reg/mem 32/64>, <xmm> */ 4310 #ifdef DIS_TEXT 4311 if (vex_W) 4312 x->d86_mnem[4] = 'q'; 4313 #endif 4314 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4315 dtrace_get_operand(x, mode, r_m, LONG_OPND, 0); 4316 } else { 4317 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4318 dtrace_get_operand(x, mode, r_m, wbit, 0); 4319 } 4320 4321 break; 4322 4323 case VEX_MXI: 4324 /* ModR/M.reg := op(ModR/M.rm, imm8) */ 4325 x->d86_numopnds = 3; 4326 4327 dtrace_get_modrm(x, &mode, ®, &r_m); 4328 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4329 4330 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2); 4331 dtrace_get_operand(x, mode, r_m, wbit, 1); 4332 4333 /* one byte immediate number */ 4334 dtrace_imm_opnd(x, wbit, 1, 0); 4335 break; 4336 4337 case VEX_XXI: 4338 /* VEX.vvvv := op(ModR/M.rm, imm8) */ 4339 x->d86_numopnds = 3; 4340 4341 dtrace_get_modrm(x, &mode, ®, &r_m); 4342 #ifdef DIS_TEXT 4343 (void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg], 4344 OPLEN); 4345 #endif 4346 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4347 4348 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2); 4349 dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1); 4350 4351 /* one byte immediate number */ 4352 dtrace_imm_opnd(x, wbit, 1, 0); 4353 break; 4354 4355 case VEX_MR: 4356 /* ModR/M.reg (reg32/64) := op(ModR/M.rm) */ 4357 if (dp == &dis_opAVX660F[0xC5]) { 4358 /* vpextrw <imm8>, <xmm>, <reg> */ 4359 x->d86_numopnds = 2; 4360 vbit = 2; 4361 } else { 4362 x->d86_numopnds = 2; 4363 vbit = 1; 4364 } 4365 4366 dtrace_get_modrm(x, &mode, ®, &r_m); 4367 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4368 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit); 4369 dtrace_get_operand(x, mode, r_m, wbit, vbit - 1); 4370 4371 if (vbit == 2) 4372 dtrace_imm_opnd(x, wbit, 1, 0); 4373 4374 break; 4375 4376 case VEX_RRI: 4377 /* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */ 4378 x->d86_numopnds = 2; 4379 4380 dtrace_get_modrm(x, &mode, ®, &r_m); 4381 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4382 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4383 dtrace_get_operand(x, mode, r_m, wbit, 0); 4384 break; 4385 4386 case VEX_RX: 4387 /* ModR/M.rm := op(ModR/M.reg) */ 4388 if (dp == &dis_opAVX660F3A[0x19]) { /* vextractf128 */ 4389 x->d86_numopnds = 3; 4390 4391 dtrace_get_modrm(x, &mode, ®, &r_m); 4392 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4393 4394 dtrace_get_operand(x, mode, r_m, XMM_OPND, 2); 4395 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4396 4397 /* one byte immediate number */ 4398 dtrace_imm_opnd(x, wbit, 1, 0); 4399 break; 4400 } 4401 4402 x->d86_numopnds = 2; 4403 4404 dtrace_get_modrm(x, &mode, ®, &r_m); 4405 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4406 dtrace_get_operand(x, mode, r_m, wbit, 1); 4407 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0); 4408 break; 4409 4410 case VEX_RR: 4411 /* ModR/M.rm := op(ModR/M.reg) */ 4412 x->d86_numopnds = 2; 4413 4414 dtrace_get_modrm(x, &mode, ®, &r_m); 4415 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4416 4417 if (dp == &dis_opAVX660F[0x7E]) { 4418 /* vmovd/q <reg/mem 32/64>, <xmm> */ 4419 #ifdef DIS_TEXT 4420 if (vex_W) 4421 x->d86_mnem[4] = 'q'; 4422 #endif 4423 dtrace_get_operand(x, mode, r_m, LONG_OPND, 1); 4424 } else 4425 dtrace_get_operand(x, mode, r_m, wbit, 1); 4426 4427 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0); 4428 break; 4429 4430 case VEX_RRi: 4431 /* ModR/M.rm := op(ModR/M.reg, imm) */ 4432 x->d86_numopnds = 3; 4433 4434 dtrace_get_modrm(x, &mode, ®, &r_m); 4435 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4436 4437 #ifdef DIS_TEXT 4438 if (dp == &dis_opAVX660F3A[0x16]) { 4439 /* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */ 4440 if (vex_W) 4441 x->d86_mnem[6] = 'q'; 4442 } 4443 #endif 4444 dtrace_get_operand(x, mode, r_m, LONG_OPND, 2); 4445 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4446 4447 /* one byte immediate number */ 4448 dtrace_imm_opnd(x, wbit, 1, 0); 4449 break; 4450 4451 case VEX_RM: 4452 /* ModR/M.rm := op(ModR/M.reg) */ 4453 if (dp == &dis_opAVX660F3A[0x17]) { /* vextractps */ 4454 x->d86_numopnds = 3; 4455 4456 dtrace_get_modrm(x, &mode, ®, &r_m); 4457 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4458 4459 dtrace_get_operand(x, mode, r_m, LONG_OPND, 2); 4460 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 4461 /* one byte immediate number */ 4462 dtrace_imm_opnd(x, wbit, 1, 0); 4463 break; 4464 } 4465 x->d86_numopnds = 2; 4466 4467 dtrace_get_modrm(x, &mode, ®, &r_m); 4468 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4469 L_VEX_RM: 4470 vbit = 1; 4471 dtrace_get_operand(x, mode, r_m, wbit, vbit); 4472 dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1); 4473 4474 break; 4475 4476 case VEX_RRM: 4477 /* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */ 4478 x->d86_numopnds = 3; 4479 4480 dtrace_get_modrm(x, &mode, ®, &r_m); 4481 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4482 dtrace_get_operand(x, mode, r_m, wbit, 2); 4483 /* VEX use the 1's complement form encode the XMM/YMM regs */ 4484 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1); 4485 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0); 4486 break; 4487 4488 case VEX_RMX: 4489 /* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */ 4490 x->d86_numopnds = 3; 4491 4492 dtrace_get_modrm(x, &mode, ®, &r_m); 4493 dtrace_vex_adjust(vex_byte1, mode, ®, &r_m); 4494 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2); 4495 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1); 4496 dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0); 4497 break; 4498 4499 case VEX_NONE: 4500 #ifdef DIS_TEXT 4501 if (vex_L) 4502 (void) strncpy(x->d86_mnem, "vzeroall", OPLEN); 4503 #endif 4504 break; 4505 /* an invalid op code */ 4506 case AM: 4507 case DM: 4508 case OVERRIDE: 4509 case PREFIX: 4510 case UNKNOWN: 4511 NOMEM; 4512 default: 4513 goto error; 4514 } /* end switch */ 4515 if (x->d86_error) 4516 goto error; 4517 4518 done: 4519 #ifdef DIS_MEM 4520 /* 4521 * compute the size of any memory accessed by the instruction 4522 */ 4523 if (x->d86_memsize != 0) { 4524 return (0); 4525 } else if (dp->it_stackop) { 4526 switch (opnd_size) { 4527 case SIZE16: 4528 x->d86_memsize = 2; 4529 break; 4530 case SIZE32: 4531 x->d86_memsize = 4; 4532 break; 4533 case SIZE64: 4534 x->d86_memsize = 8; 4535 break; 4536 } 4537 } else if (nomem || mode == REG_ONLY) { 4538 x->d86_memsize = 0; 4539 4540 } else if (dp->it_size != 0) { 4541 /* 4542 * In 64 bit mode descriptor table entries 4543 * go up to 10 bytes and popf/pushf are always 8 bytes 4544 */ 4545 if (x->d86_mode == SIZE64 && dp->it_size == 6) 4546 x->d86_memsize = 10; 4547 else if (x->d86_mode == SIZE64 && opcode1 == 0x9 && 4548 (opcode2 == 0xc || opcode2 == 0xd)) 4549 x->d86_memsize = 8; 4550 else 4551 x->d86_memsize = dp->it_size; 4552 4553 } else if (wbit == 0) { 4554 x->d86_memsize = 1; 4555 4556 } else if (wbit == LONG_OPND) { 4557 if (opnd_size == SIZE64) 4558 x->d86_memsize = 8; 4559 else if (opnd_size == SIZE32) 4560 x->d86_memsize = 4; 4561 else 4562 x->d86_memsize = 2; 4563 4564 } else if (wbit == SEG_OPND) { 4565 x->d86_memsize = 4; 4566 4567 } else { 4568 x->d86_memsize = 8; 4569 } 4570 #endif 4571 return (0); 4572 4573 error: 4574 #ifdef DIS_TEXT 4575 (void) strlcat(x->d86_mnem, "undef", OPLEN); 4576 #endif 4577 return (1); 4578 } 4579 4580 #ifdef DIS_TEXT 4581 4582 /* 4583 * Some instructions should have immediate operands printed 4584 * as unsigned integers. We compare against this table. 4585 */ 4586 static char *unsigned_ops[] = { 4587 "or", "and", "xor", "test", "in", "out", "lcall", "ljmp", 4588 "rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl", 4589 0 4590 }; 4591 4592 4593 static int 4594 isunsigned_op(char *opcode) 4595 { 4596 char *where; 4597 int i; 4598 int is_unsigned = 0; 4599 4600 /* 4601 * Work back to start of last mnemonic, since we may have 4602 * prefixes on some opcodes. 4603 */ 4604 where = opcode + strlen(opcode) - 1; 4605 while (where > opcode && *where != ' ') 4606 --where; 4607 if (*where == ' ') 4608 ++where; 4609 4610 for (i = 0; unsigned_ops[i]; ++i) { 4611 if (strncmp(where, unsigned_ops[i], 4612 strlen(unsigned_ops[i]))) 4613 continue; 4614 is_unsigned = 1; 4615 break; 4616 } 4617 return (is_unsigned); 4618 } 4619 4620 /* 4621 * Print a numeric immediate into end of buf, maximum length buflen. 4622 * The immediate may be an address or a displacement. Mask is set 4623 * for address size. If the immediate is a "small negative", or 4624 * if it's a negative displacement of any magnitude, print as -<absval>. 4625 * Respect the "octal" flag. "Small negative" is defined as "in the 4626 * interval [NEG_LIMIT, 0)". 4627 * 4628 * Also, "isunsigned_op()" instructions never print negatives. 4629 * 4630 * Return whether we decided to print a negative value or not. 4631 */ 4632 4633 #define NEG_LIMIT -255 4634 enum {IMM, DISP}; 4635 enum {POS, TRY_NEG}; 4636 4637 static int 4638 print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf, 4639 size_t buflen, int disp, int try_neg) 4640 { 4641 int curlen; 4642 int64_t sv = (int64_t)usv; 4643 int octal = dis->d86_flags & DIS_F_OCTAL; 4644 4645 curlen = strlen(buf); 4646 4647 if (try_neg == TRY_NEG && sv < 0 && 4648 (disp || sv >= NEG_LIMIT) && 4649 !isunsigned_op(dis->d86_mnem)) { 4650 dis->d86_sprintf_func(buf + curlen, buflen - curlen, 4651 octal ? "-0%llo" : "-0x%llx", (-sv) & mask); 4652 return (1); 4653 } else { 4654 if (disp == DISP) 4655 dis->d86_sprintf_func(buf + curlen, buflen - curlen, 4656 octal ? "+0%llo" : "+0x%llx", usv & mask); 4657 else 4658 dis->d86_sprintf_func(buf + curlen, buflen - curlen, 4659 octal ? "0%llo" : "0x%llx", usv & mask); 4660 return (0); 4661 4662 } 4663 } 4664 4665 4666 static int 4667 log2(int size) 4668 { 4669 switch (size) { 4670 case 1: return (0); 4671 case 2: return (1); 4672 case 4: return (2); 4673 case 8: return (3); 4674 } 4675 return (0); 4676 } 4677 4678 /* ARGSUSED */ 4679 void 4680 dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf, 4681 size_t buflen) 4682 { 4683 uint64_t reltgt = 0; 4684 uint64_t tgt = 0; 4685 int curlen; 4686 int (*lookup)(void *, uint64_t, char *, size_t); 4687 int i; 4688 int64_t sv; 4689 uint64_t usv, mask, save_mask, save_usv; 4690 static uint64_t masks[] = 4691 {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL}; 4692 save_usv = 0; 4693 4694 dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem); 4695 4696 /* 4697 * For PC-relative jumps, the pc is really the next pc after executing 4698 * this instruction, so increment it appropriately. 4699 */ 4700 pc += dis->d86_len; 4701 4702 for (i = 0; i < dis->d86_numopnds; i++) { 4703 d86opnd_t *op = &dis->d86_opnd[i]; 4704 4705 if (i != 0) 4706 (void) strlcat(buf, ",", buflen); 4707 4708 (void) strlcat(buf, op->d86_prefix, buflen); 4709 4710 /* 4711 * sv is for the signed, possibly-truncated immediate or 4712 * displacement; usv retains the original size and 4713 * unsignedness for symbol lookup. 4714 */ 4715 4716 sv = usv = op->d86_value; 4717 4718 /* 4719 * About masks: for immediates that represent 4720 * addresses, the appropriate display size is 4721 * the effective address size of the instruction. 4722 * This includes MODE_OFFSET, MODE_IPREL, and 4723 * MODE_RIPREL. Immediates that are simply 4724 * immediate values should display in the operand's 4725 * size, however, since they don't represent addresses. 4726 */ 4727 4728 /* d86_addr_size is SIZEnn, which is log2(real size) */ 4729 mask = masks[dis->d86_addr_size]; 4730 4731 /* d86_value_size and d86_imm_bytes are in bytes */ 4732 if (op->d86_mode == MODE_SIGNED || 4733 op->d86_mode == MODE_IMPLIED) 4734 mask = masks[log2(op->d86_value_size)]; 4735 4736 switch (op->d86_mode) { 4737 4738 case MODE_NONE: 4739 4740 (void) strlcat(buf, op->d86_opnd, buflen); 4741 break; 4742 4743 case MODE_SIGNED: 4744 case MODE_IMPLIED: 4745 case MODE_OFFSET: 4746 4747 tgt = usv; 4748 4749 if (dis->d86_seg_prefix) 4750 (void) strlcat(buf, dis->d86_seg_prefix, 4751 buflen); 4752 4753 if (op->d86_mode == MODE_SIGNED || 4754 op->d86_mode == MODE_IMPLIED) { 4755 (void) strlcat(buf, "$", buflen); 4756 } 4757 4758 if (print_imm(dis, usv, mask, buf, buflen, 4759 IMM, TRY_NEG) && 4760 (op->d86_mode == MODE_SIGNED || 4761 op->d86_mode == MODE_IMPLIED)) { 4762 4763 /* 4764 * We printed a negative value for an 4765 * immediate that wasn't a 4766 * displacement. Note that fact so we can 4767 * print the positive value as an 4768 * annotation. 4769 */ 4770 4771 save_usv = usv; 4772 save_mask = mask; 4773 } 4774 (void) strlcat(buf, op->d86_opnd, buflen); 4775 4776 break; 4777 4778 case MODE_IPREL: 4779 case MODE_RIPREL: 4780 4781 reltgt = pc + sv; 4782 4783 switch (mode) { 4784 case SIZE16: 4785 reltgt = (uint16_t)reltgt; 4786 break; 4787 case SIZE32: 4788 reltgt = (uint32_t)reltgt; 4789 break; 4790 } 4791 4792 (void) print_imm(dis, usv, mask, buf, buflen, 4793 DISP, TRY_NEG); 4794 4795 if (op->d86_mode == MODE_RIPREL) 4796 (void) strlcat(buf, "(%rip)", buflen); 4797 break; 4798 } 4799 } 4800 4801 /* 4802 * The symbol lookups may result in false positives, 4803 * particularly on object files, where small numbers may match 4804 * the 0-relative non-relocated addresses of symbols. 4805 */ 4806 4807 lookup = dis->d86_sym_lookup; 4808 if (tgt != 0) { 4809 if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 && 4810 lookup(dis->d86_data, tgt, NULL, 0) == 0) { 4811 (void) strlcat(buf, "\t<", buflen); 4812 curlen = strlen(buf); 4813 lookup(dis->d86_data, tgt, buf + curlen, 4814 buflen - curlen); 4815 (void) strlcat(buf, ">", buflen); 4816 } 4817 4818 /* 4819 * If we printed a negative immediate above, print the 4820 * positive in case our heuristic was unhelpful 4821 */ 4822 if (save_usv) { 4823 (void) strlcat(buf, "\t<", buflen); 4824 (void) print_imm(dis, save_usv, save_mask, buf, buflen, 4825 IMM, POS); 4826 (void) strlcat(buf, ">", buflen); 4827 } 4828 } 4829 4830 if (reltgt != 0) { 4831 /* Print symbol or effective address for reltgt */ 4832 4833 (void) strlcat(buf, "\t<", buflen); 4834 curlen = strlen(buf); 4835 lookup(dis->d86_data, reltgt, buf + curlen, 4836 buflen - curlen); 4837 (void) strlcat(buf, ">", buflen); 4838 } 4839 } 4840 4841 #endif /* DIS_TEXT */ 4842