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