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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #include "dis_tables.h" 32 33 /* BEGIN CSTYLED */ 34 35 /* 36 * Disassembly begins in dis_distable, which is equivalent to the One-byte 37 * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy). The 38 * decoding loops then traverse out through the other tables as necessary to 39 * decode a given instruction. 40 * 41 * The behavior of this file can be controlled by one of the following flags: 42 * 43 * DIS_TEXT Include text for disassembly 44 * DIS_MEM Include memory-size calculations 45 * 46 * Either or both of these can be defined. 47 * 48 * This file is not, and will never be, cstyled. If anything, the tables should 49 * be taken out another tab stop or two so nothing overlaps. 50 */ 51 52 /* 53 * These functions must be provided for the consumer to do disassembly. 54 */ 55 #ifdef DIS_TEXT 56 extern char *strncpy(char *, const char *, size_t); 57 extern size_t strlen(const char *); 58 extern int strcmp(const char *, const char *); 59 extern int strncmp(const char *, const char *, size_t); 60 extern size_t strlcat(char *, const char *, size_t); 61 #endif 62 63 64 #define TERM 0 /* used to indicate that the 'indirect' */ 65 /* field terminates - no pointer. */ 66 67 /* Used to decode instructions. */ 68 typedef struct instable { 69 struct instable *it_indirect; /* for decode op codes */ 70 uchar_t it_adrmode; 71 #ifdef DIS_TEXT 72 char it_name[NCPS]; 73 uint_t it_suffix:1; /* mnem + "w", "l", or "d" */ 74 #endif 75 #ifdef DIS_MEM 76 uint_t it_size:16; 77 #endif 78 uint_t it_invalid64:1; /* opcode invalid in amd64 */ 79 uint_t it_always64:1; /* 64 bit when in 64 bit mode */ 80 uint_t it_invalid32:1; /* invalid in IA32 */ 81 uint_t it_stackop:1; /* push/pop stack operation */ 82 } instable_t; 83 84 /* 85 * Instruction formats. 86 */ 87 enum { 88 UNKNOWN, 89 MRw, 90 IMlw, 91 IMw, 92 IR, 93 OA, 94 AO, 95 MS, 96 SM, 97 Mv, 98 Mw, 99 M, /* register or memory */ 100 Mb, /* register or memory, always byte sized */ 101 MO, /* memory only (no registers) */ 102 PREF, 103 SWAPGS, 104 MONITOR_MWAIT, 105 R, 106 RA, 107 SEG, 108 MR, 109 RM, 110 IA, 111 MA, 112 SD, 113 AD, 114 SA, 115 D, 116 INM, 117 SO, 118 BD, 119 I, 120 P, 121 V, 122 DSHIFT, /* for double shift that has an 8-bit immediate */ 123 U, 124 OVERRIDE, 125 NORM, /* instructions w/o ModR/M byte, no memory access */ 126 IMPLMEM, /* instructions w/o ModR/M byte, implicit mem access */ 127 O, /* for call */ 128 JTAB, /* jump table */ 129 IMUL, /* for 186 iimul instr */ 130 CBW, /* so data16 can be evaluated for cbw and variants */ 131 MvI, /* for 186 logicals */ 132 ENTER, /* for 186 enter instr */ 133 RMw, /* for 286 arpl instr */ 134 Ib, /* for push immediate byte */ 135 F, /* for 287 instructions */ 136 FF, /* for 287 instructions */ 137 FFC, /* for 287 instructions */ 138 DM, /* 16-bit data */ 139 AM, /* 16-bit addr */ 140 LSEG, /* for 3-bit seg reg encoding */ 141 MIb, /* for 386 logicals */ 142 SREG, /* for 386 special registers */ 143 PREFIX, /* a REP instruction prefix */ 144 LOCK, /* a LOCK instruction prefix */ 145 INT3, /* The int 3 instruction, which has a fake operand */ 146 INTx, /* The normal int instruction, with explicit int num */ 147 DSHIFTcl, /* for double shift that implicitly uses %cl */ 148 CWD, /* so data16 can be evaluated for cwd and variants */ 149 RET, /* single immediate 16-bit operand */ 150 MOVZ, /* for movs and movz, with different size operands */ 151 CRC32, /* for crc32, with different size operands */ 152 XADDB, /* for xaddb */ 153 MOVSXZ, /* AMD64 mov sign extend 32 to 64 bit instruction */ 154 MOVBE, /* movbe instruction */ 155 156 /* 157 * MMX/SIMD addressing modes. 158 */ 159 160 MMO, /* Prefixable MMX/SIMD-Int mm/mem -> mm */ 161 MMOIMPL, /* Prefixable MMX/SIMD-Int mm -> mm (mem) */ 162 MMO3P, /* Prefixable MMX/SIMD-Int mm -> r32,imm8 */ 163 MMOM3, /* Prefixable MMX/SIMD-Int mm -> r32 */ 164 MMOS, /* Prefixable MMX/SIMD-Int mm -> mm/mem */ 165 MMOMS, /* Prefixable MMX/SIMD-Int mm -> mem */ 166 MMOPM, /* MMX/SIMD-Int mm/mem -> mm,imm8 */ 167 MMOPM_66o, /* MMX/SIMD-Int 0x66 optional mm/mem -> mm,imm8 */ 168 MMOPRM, /* Prefixable MMX/SIMD-Int r32/mem -> mm,imm8 */ 169 MMOSH, /* Prefixable MMX mm,imm8 */ 170 MM, /* MMX/SIMD-Int mm/mem -> mm */ 171 MMS, /* MMX/SIMD-Int mm -> mm/mem */ 172 MMSH, /* MMX mm,imm8 */ 173 XMMO, /* Prefixable SIMD xmm/mem -> xmm */ 174 XMMOS, /* Prefixable SIMD xmm -> xmm/mem */ 175 XMMOPM, /* Prefixable SIMD xmm/mem w/to xmm,imm8 */ 176 XMMOMX, /* Prefixable SIMD mm/mem -> xmm */ 177 XMMOX3, /* Prefixable SIMD xmm -> r32 */ 178 XMMOXMM, /* Prefixable SIMD xmm/mem -> mm */ 179 XMMOM, /* Prefixable SIMD xmm -> mem */ 180 XMMOMS, /* Prefixable SIMD mem -> xmm */ 181 XMM, /* SIMD xmm/mem -> xmm */ 182 XMM_66r, /* SIMD 0x66 prefix required xmm/mem -> xmm */ 183 XMM_66o, /* SIMD 0x66 prefix optional xmm/mem -> xmm */ 184 XMMXIMPL, /* SIMD xmm -> xmm (mem) */ 185 XMM3P, /* SIMD xmm -> r32,imm8 */ 186 XMM3PM_66r, /* SIMD 0x66 prefix required xmm -> r32/mem,imm8 */ 187 XMMP, /* SIMD xmm/mem w/to xmm,imm8 */ 188 XMMP_66o, /* SIMD 0x66 prefix optional xmm/mem w/to xmm,imm8 */ 189 XMMP_66r, /* SIMD 0x66 prefix required xmm/mem w/to xmm,imm8 */ 190 XMMPRM, /* SIMD r32/mem -> xmm,imm8 */ 191 XMMPRM_66r, /* SIMD 0x66 prefix required r32/mem -> xmm,imm8 */ 192 XMMS, /* SIMD xmm -> xmm/mem */ 193 XMMM, /* SIMD mem -> xmm */ 194 XMMM_66r, /* SIMD 0x66 prefix required mem -> xmm */ 195 XMMMS, /* SIMD xmm -> mem */ 196 XMM3MX, /* SIMD r32/mem -> xmm */ 197 XMM3MXS, /* SIMD xmm -> r32/mem */ 198 XMMSH, /* SIMD xmm,imm8 */ 199 XMMXM3, /* SIMD xmm/mem -> r32 */ 200 XMMX3, /* SIMD xmm -> r32 */ 201 XMMXMM, /* SIMD xmm/mem -> mm */ 202 XMMMX, /* SIMD mm -> xmm */ 203 XMMXM, /* SIMD xmm -> mm */ 204 XMMX2I, /* SIMD xmm -> xmm, imm, imm */ 205 XMM2I, /* SIMD xmm, imm, imm */ 206 XMMFENCE, /* SIMD lfence or mfence */ 207 XMMSFNC /* SIMD sfence (none or mem) */ 208 }; 209 210 #define FILL 0x90 /* Fill byte used for alignment (nop) */ 211 212 /* 213 ** Register numbers for the i386 214 */ 215 #define EAX_REGNO 0 216 #define ECX_REGNO 1 217 #define EDX_REGNO 2 218 #define EBX_REGNO 3 219 #define ESP_REGNO 4 220 #define EBP_REGNO 5 221 #define ESI_REGNO 6 222 #define EDI_REGNO 7 223 224 /* 225 * modes for immediate values 226 */ 227 #define MODE_NONE 0 228 #define MODE_IPREL 1 /* signed IP relative value */ 229 #define MODE_SIGNED 2 /* sign extended immediate */ 230 #define MODE_IMPLIED 3 /* constant value implied from opcode */ 231 #define MODE_OFFSET 4 /* offset part of an address */ 232 #define MODE_RIPREL 5 /* like IPREL, but from %rip (amd64) */ 233 234 /* 235 * The letters used in these macros are: 236 * IND - indirect to another to another table 237 * "T" - means to Terminate indirections (this is the final opcode) 238 * "S" - means "operand length suffix required" 239 * "NS" - means "no suffix" which is the operand length suffix of the opcode 240 * "Z" - means instruction size arg required 241 * "u" - means the opcode is invalid in IA32 but valid in amd64 242 * "x" - means the opcode is invalid in amd64, but not IA32 243 * "y" - means the operand size is always 64 bits in 64 bit mode 244 * "p" - means push/pop stack operation 245 */ 246 247 #if defined(DIS_TEXT) && defined(DIS_MEM) 248 #define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0} 249 #define INDx(table) {(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0} 250 #define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0} 251 #define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 0, 1, 0} 252 #define TNSx(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0, 0} 253 #define TNSy(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 0} 254 #define TNSyp(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 1} 255 #define TNSZ(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0} 256 #define TNSZy(name, amode, sz) {TERM, amode, name, 0, sz, 0, 1, 0, 0} 257 #define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0} 258 #define TSx(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0, 0} 259 #define TSy(name, amode) {TERM, amode, name, 1, 0, 0, 1, 0, 0} 260 #define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 1} 261 #define TSZ(name, amode, sz) {TERM, amode, name, 1, sz, 0, 0, 0, 0} 262 #define TSZx(name, amode, sz) {TERM, amode, name, 1, sz, 1, 0, 0, 0} 263 #define TSZy(name, amode, sz) {TERM, amode, name, 1, sz, 0, 1, 0, 0} 264 #define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0} 265 #elif defined(DIS_TEXT) 266 #define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0} 267 #define INDx(table) {(instable_t *)table, 0, "", 0, 1, 0, 0, 0} 268 #define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0} 269 #define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0} 270 #define TNSx(name, amode) {TERM, amode, name, 0, 1, 0, 0, 0} 271 #define TNSy(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0} 272 #define TNSyp(name, amode) {TERM, amode, name, 0, 0, 1, 0, 1} 273 #define TNSZ(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0} 274 #define TNSZy(name, amode, sz) {TERM, amode, name, 0, 0, 1, 0, 0} 275 #define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0} 276 #define TSx(name, amode) {TERM, amode, name, 1, 1, 0, 0, 0} 277 #define TSy(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0} 278 #define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 1} 279 #define TSZ(name, amode, sz) {TERM, amode, name, 1, 0, 0, 0, 0} 280 #define TSZx(name, amode, sz) {TERM, amode, name, 1, 1, 0, 0, 0} 281 #define TSZy(name, amode, sz) {TERM, amode, name, 1, 0, 1, 0, 0} 282 #define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0} 283 #elif defined(DIS_MEM) 284 #define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0, 0} 285 #define INDx(table) {(instable_t *)table, 0, 0, 1, 0, 0, 0} 286 #define TNS(name, amode) {TERM, amode, 0, 0, 0, 0, 0} 287 #define TNSu(name, amode) {TERM, amode, 0, 0, 0, 1, 0} 288 #define TNSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0} 289 #define TNSyp(name, amode) {TERM, amode, 0, 0, 1, 0, 1} 290 #define TNSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0} 291 #define TNSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0} 292 #define TNSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0} 293 #define TS(name, amode) {TERM, amode, 0, 0, 0, 0, 0} 294 #define TSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0} 295 #define TSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0} 296 #define TSp(name, amode) {TERM, amode, 0, 0, 0, 0, 1} 297 #define TSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0} 298 #define TSZx(name, amode, sz) {TERM, amode, sz, 1, 0, 0, 0} 299 #define TSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0} 300 #define INVALID {TERM, UNKNOWN, 0, 0, 0, 0, 0} 301 #else 302 #define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0} 303 #define INDx(table) {(instable_t *)table, 0, 1, 0, 0, 0} 304 #define TNS(name, amode) {TERM, amode, 0, 0, 0, 0} 305 #define TNSu(name, amode) {TERM, amode, 0, 0, 1, 0} 306 #define TNSy(name, amode) {TERM, amode, 0, 1, 0, 0} 307 #define TNSyp(name, amode) {TERM, amode, 0, 1, 0, 1} 308 #define TNSx(name, amode) {TERM, amode, 1, 0, 0, 0} 309 #define TNSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0} 310 #define TNSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0} 311 #define TS(name, amode) {TERM, amode, 0, 0, 0, 0} 312 #define TSx(name, amode) {TERM, amode, 1, 0, 0, 0} 313 #define TSy(name, amode) {TERM, amode, 0, 1, 0, 0} 314 #define TSp(name, amode) {TERM, amode, 0, 0, 0, 1} 315 #define TSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0} 316 #define TSZx(name, amode, sz) {TERM, amode, 1, 0, 0, 0} 317 #define TSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0} 318 #define INVALID {TERM, UNKNOWN, 0, 0, 0, 0} 319 #endif 320 321 #ifdef DIS_TEXT 322 /* 323 * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode 324 */ 325 const char *const dis_addr16[3][8] = { 326 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "", 327 "(%bx)", 328 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)", 329 "(%bx)", 330 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)", 331 "(%bx)", 332 }; 333 334 335 /* 336 * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2 337 */ 338 const char *const dis_addr32_mode0[16] = { 339 "(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "", "(%esi)", "(%edi)", 340 "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "", "(%r14d)", "(%r15d)" 341 }; 342 343 const char *const dis_addr32_mode12[16] = { 344 "(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "(%ebp)", "(%esi)", "(%edi)", 345 "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)" 346 }; 347 348 /* 349 * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2 350 */ 351 const char *const dis_addr64_mode0[16] = { 352 "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rip)", "(%rsi)", "(%rdi)", 353 "(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)" 354 }; 355 const char *const dis_addr64_mode12[16] = { 356 "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rbp)", "(%rsi)", "(%rdi)", 357 "(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)" 358 }; 359 360 /* 361 * decode for scale from SIB byte 362 */ 363 const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" }; 364 365 /* 366 * register decoding for normal references to registers (ie. not addressing) 367 */ 368 const char *const dis_REG8[16] = { 369 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", 370 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" 371 }; 372 373 const char *const dis_REG8_REX[16] = { 374 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", 375 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" 376 }; 377 378 const char *const dis_REG16[16] = { 379 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", 380 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" 381 }; 382 383 const char *const dis_REG32[16] = { 384 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", 385 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" 386 }; 387 388 const char *const dis_REG64[16] = { 389 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", 390 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 391 }; 392 393 const char *const dis_DEBUGREG[16] = { 394 "%db0", "%db1", "%db2", "%db3", "%db4", "%db5", "%db6", "%db7", 395 "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15" 396 }; 397 398 const char *const dis_CONTROLREG[16] = { 399 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?", 400 "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?" 401 }; 402 403 const char *const dis_TESTREG[16] = { 404 "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7", 405 "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7" 406 }; 407 408 const char *const dis_MMREG[16] = { 409 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7", 410 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 411 }; 412 413 const char *const dis_XMMREG[16] = { 414 "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 415 "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15" 416 }; 417 418 const char *const dis_SEGREG[16] = { 419 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>", 420 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>" 421 }; 422 423 /* 424 * SIMD predicate suffixes 425 */ 426 const char *const dis_PREDSUFFIX[8] = { 427 "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord" 428 }; 429 430 431 432 #endif /* DIS_TEXT */ 433 434 435 436 437 /* 438 * "decode table" for 64 bit mode MOVSXD instruction (opcode 0x63) 439 */ 440 const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ); 441 442 /* 443 * "decode table" for pause and clflush instructions 444 */ 445 const instable_t dis_opPause = TNS("pause", NORM); 446 447 /* 448 * Decode table for 0x0F00 opcodes 449 */ 450 const instable_t dis_op0F00[8] = { 451 452 /* [0] */ TNS("sldt",M), TNS("str",M), TNSy("lldt",M), TNSy("ltr",M), 453 /* [4] */ TNSZ("verr",M,2), TNSZ("verw",M,2), INVALID, INVALID, 454 }; 455 456 457 /* 458 * Decode table for 0x0F01 opcodes 459 */ 460 const instable_t dis_op0F01[8] = { 461 462 /* [0] */ TNSZ("sgdt",MO,6), TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",MO,6), TNSZ("lidt",MO,6), 463 /* [4] */ TNSZ("smsw",M,2), INVALID, TNSZ("lmsw",M,2), TNS("invlpg",SWAPGS), 464 }; 465 466 /* 467 * Decode table for 0x0F18 opcodes -- SIMD prefetch 468 */ 469 const instable_t dis_op0F18[8] = { 470 471 /* [0] */ TNS("prefetchnta",PREF),TNS("prefetcht0",PREF), TNS("prefetcht1",PREF), TNS("prefetcht2",PREF), 472 /* [4] */ INVALID, INVALID, INVALID, INVALID, 473 }; 474 475 /* 476 * Decode table for 0x0FAE opcodes -- SIMD state save/restore 477 */ 478 const instable_t dis_op0FAE[8] = { 479 /* [0] */ TNSZ("fxsave",M,512), TNSZ("fxrstor",M,512), TNS("ldmxcsr",M), TNS("stmxcsr",M), 480 /* [4] */ INVALID, TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE), TNS("sfence",XMMSFNC), 481 }; 482 483 /* 484 * Decode table for 0x0FBA opcodes 485 */ 486 487 const instable_t dis_op0FBA[8] = { 488 489 /* [0] */ INVALID, INVALID, INVALID, INVALID, 490 /* [4] */ TS("bt",MIb), TS("bts",MIb), TS("btr",MIb), TS("btc",MIb), 491 }; 492 493 /* 494 * Decode table for 0x0FC7 opcode 495 */ 496 497 const instable_t dis_op0FC7[8] = { 498 499 /* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, INVALID, 500 /* [4] */ INVALID, INVALID, INVALID, INVALID, 501 }; 502 503 504 /* 505 * Decode table for 0x0FC8 opcode -- 486 bswap instruction 506 * 507 *bit pattern: 0000 1111 1100 1reg 508 */ 509 const instable_t dis_op0FC8[4] = { 510 /* [0] */ TNS("bswap",R), INVALID, INVALID, INVALID, 511 }; 512 513 /* 514 * Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions 515 */ 516 const instable_t dis_op0F7123[4][8] = { 517 { 518 /* [70].0 */ INVALID, INVALID, INVALID, INVALID, 519 /* .4 */ INVALID, INVALID, INVALID, INVALID, 520 }, { 521 /* [71].0 */ INVALID, INVALID, TNS("psrlw",MMOSH), INVALID, 522 /* .4 */ TNS("psraw",MMOSH), INVALID, TNS("psllw",MMOSH), INVALID, 523 }, { 524 /* [72].0 */ INVALID, INVALID, TNS("psrld",MMOSH), INVALID, 525 /* .4 */ TNS("psrad",MMOSH), INVALID, TNS("pslld",MMOSH), INVALID, 526 }, { 527 /* [73].0 */ INVALID, INVALID, TNS("psrlq",MMOSH), TNS("INVALID",MMOSH), 528 /* .4 */ INVALID, INVALID, TNS("psllq",MMOSH), TNS("INVALID",MMOSH), 529 } }; 530 531 /* 532 * Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes. 533 */ 534 const instable_t dis_opSIMD7123[32] = { 535 /* [70].0 */ INVALID, INVALID, INVALID, INVALID, 536 /* .4 */ INVALID, INVALID, INVALID, INVALID, 537 538 /* [71].0 */ INVALID, INVALID, TNS("psrlw",XMMSH), INVALID, 539 /* .4 */ TNS("psraw",XMMSH), INVALID, TNS("psllw",XMMSH), INVALID, 540 541 /* [72].0 */ INVALID, INVALID, TNS("psrld",XMMSH), INVALID, 542 /* .4 */ TNS("psrad",XMMSH), INVALID, TNS("pslld",XMMSH), INVALID, 543 544 /* [73].0 */ INVALID, INVALID, TNS("psrlq",XMMSH), TNS("psrldq",XMMSH), 545 /* .4 */ INVALID, INVALID, TNS("psllq",XMMSH), TNS("pslldq",XMMSH), 546 }; 547 548 /* 549 * SIMD instructions have been wedged into the existing IA32 instruction 550 * set through the use of prefixes. That is, while 0xf0 0x58 may be 551 * addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different 552 * instruction - addss. At present, three prefixes have been coopted in 553 * this manner - address size (0x66), repnz (0xf2) and repz (0xf3). The 554 * following tables are used to provide the prefixed instruction names. 555 * The arrays are sparse, but they're fast. 556 */ 557 558 /* 559 * Decode table for SIMD instructions with the address size (0x66) prefix. 560 */ 561 const instable_t dis_opSIMDdata16[256] = { 562 /* [00] */ INVALID, INVALID, INVALID, INVALID, 563 /* [04] */ INVALID, INVALID, INVALID, INVALID, 564 /* [08] */ INVALID, INVALID, INVALID, INVALID, 565 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 566 567 /* [10] */ TNSZ("movupd",XMM,16), TNSZ("movupd",XMMS,16), TNSZ("movlpd",XMMM,8), TNSZ("movlpd",XMMMS,8), 568 /* [14] */ TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8), TNSZ("movhpd",XMMMS,8), 569 /* [18] */ INVALID, INVALID, INVALID, INVALID, 570 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 571 572 /* [20] */ INVALID, INVALID, INVALID, INVALID, 573 /* [24] */ INVALID, INVALID, INVALID, INVALID, 574 /* [28] */ TNSZ("movapd",XMM,16), TNSZ("movapd",XMMS,16), TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16), 575 /* [2C] */ TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8), 576 577 /* [30] */ INVALID, INVALID, INVALID, INVALID, 578 /* [34] */ INVALID, INVALID, INVALID, INVALID, 579 /* [38] */ INVALID, INVALID, INVALID, INVALID, 580 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 581 582 /* [40] */ INVALID, INVALID, INVALID, INVALID, 583 /* [44] */ INVALID, INVALID, INVALID, INVALID, 584 /* [48] */ INVALID, INVALID, INVALID, INVALID, 585 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 586 587 /* [50] */ TNS("movmskpd",XMMOX3), TNSZ("sqrtpd",XMM,16), INVALID, INVALID, 588 /* [54] */ TNSZ("andpd",XMM,16), TNSZ("andnpd",XMM,16), TNSZ("orpd",XMM,16), TNSZ("xorpd",XMM,16), 589 /* [58] */ TNSZ("addpd",XMM,16), TNSZ("mulpd",XMM,16), TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16), 590 /* [5C] */ TNSZ("subpd",XMM,16), TNSZ("minpd",XMM,16), TNSZ("divpd",XMM,16), TNSZ("maxpd",XMM,16), 591 592 /* [60] */ TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16), 593 /* [64] */ TNSZ("pcmpgtb",XMM,16), TNSZ("pcmpgtw",XMM,16), TNSZ("pcmpgtd",XMM,16), TNSZ("packuswb",XMM,16), 594 /* [68] */ TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16), 595 /* [6C] */ TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16), 596 597 /* [70] */ TNSZ("pshufd",XMMP,16), INVALID, INVALID, INVALID, 598 /* [74] */ TNSZ("pcmpeqb",XMM,16), TNSZ("pcmpeqw",XMM,16), TNSZ("pcmpeqd",XMM,16), INVALID, 599 /* [78] */ TNSZ("extrq",XMM2I,16), TNSZ("extrq",XMM,16), INVALID, INVALID, 600 /* [7C] */ INVALID, INVALID, TNSZ("movd",XMM3MXS,4), TNSZ("movdqa",XMMS,16), 601 602 /* [80] */ INVALID, INVALID, INVALID, INVALID, 603 /* [84] */ INVALID, INVALID, INVALID, INVALID, 604 /* [88] */ INVALID, INVALID, INVALID, INVALID, 605 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 606 607 /* [90] */ INVALID, INVALID, INVALID, INVALID, 608 /* [94] */ INVALID, INVALID, INVALID, INVALID, 609 /* [98] */ INVALID, INVALID, INVALID, INVALID, 610 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 611 612 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 613 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 614 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 615 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 616 617 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 618 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 619 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 620 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 621 622 /* [C0] */ INVALID, INVALID, TNSZ("cmppd",XMMP,16), INVALID, 623 /* [C4] */ TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P), TNSZ("shufpd",XMMP,16), INVALID, 624 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 625 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 626 627 /* [D0] */ INVALID, TNSZ("psrlw",XMM,16), TNSZ("psrld",XMM,16), TNSZ("psrlq",XMM,16), 628 /* [D4] */ TNSZ("paddq",XMM,16), TNSZ("pmullw",XMM,16), TNSZ("movq",XMMS,8), TNS("pmovmskb",XMMX3), 629 /* [D8] */ TNSZ("psubusb",XMM,16), TNSZ("psubusw",XMM,16), TNSZ("pminub",XMM,16), TNSZ("pand",XMM,16), 630 /* [DC] */ TNSZ("paddusb",XMM,16), TNSZ("paddusw",XMM,16), TNSZ("pmaxub",XMM,16), TNSZ("pandn",XMM,16), 631 632 /* [E0] */ TNSZ("pavgb",XMM,16), TNSZ("psraw",XMM,16), TNSZ("psrad",XMM,16), TNSZ("pavgw",XMM,16), 633 /* [E4] */ TNSZ("pmulhuw",XMM,16), TNSZ("pmulhw",XMM,16), TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16), 634 /* [E8] */ TNSZ("psubsb",XMM,16), TNSZ("psubsw",XMM,16), TNSZ("pminsw",XMM,16), TNSZ("por",XMM,16), 635 /* [EC] */ TNSZ("paddsb",XMM,16), TNSZ("paddsw",XMM,16), TNSZ("pmaxsw",XMM,16), TNSZ("pxor",XMM,16), 636 637 /* [F0] */ INVALID, TNSZ("psllw",XMM,16), TNSZ("pslld",XMM,16), TNSZ("psllq",XMM,16), 638 /* [F4] */ TNSZ("pmuludq",XMM,16), TNSZ("pmaddwd",XMM,16), TNSZ("psadbw",XMM,16), TNSZ("maskmovdqu", XMMXIMPL,16), 639 /* [F8] */ TNSZ("psubb",XMM,16), TNSZ("psubw",XMM,16), TNSZ("psubd",XMM,16), TNSZ("psubq",XMM,16), 640 /* [FC] */ TNSZ("paddb",XMM,16), TNSZ("paddw",XMM,16), TNSZ("paddd",XMM,16), INVALID, 641 }; 642 643 /* 644 * Decode table for SIMD instructions with the repnz (0xf2) prefix. 645 */ 646 const instable_t dis_opSIMDrepnz[256] = { 647 /* [00] */ INVALID, INVALID, INVALID, INVALID, 648 /* [04] */ INVALID, INVALID, INVALID, INVALID, 649 /* [08] */ INVALID, INVALID, INVALID, INVALID, 650 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 651 652 /* [10] */ TNSZ("movsd",XMM,8), TNSZ("movsd",XMMS,8), INVALID, INVALID, 653 /* [14] */ INVALID, INVALID, INVALID, INVALID, 654 /* [18] */ INVALID, INVALID, INVALID, INVALID, 655 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 656 657 /* [20] */ INVALID, INVALID, INVALID, INVALID, 658 /* [24] */ INVALID, INVALID, INVALID, INVALID, 659 /* [28] */ INVALID, INVALID, TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8), 660 /* [2C] */ TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID, INVALID, 661 662 /* [30] */ INVALID, INVALID, INVALID, INVALID, 663 /* [34] */ INVALID, INVALID, INVALID, INVALID, 664 /* [38] */ INVALID, INVALID, INVALID, INVALID, 665 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 666 667 /* [40] */ INVALID, INVALID, INVALID, INVALID, 668 /* [44] */ INVALID, INVALID, INVALID, INVALID, 669 /* [48] */ INVALID, INVALID, INVALID, INVALID, 670 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 671 672 /* [50] */ INVALID, TNSZ("sqrtsd",XMM,8), INVALID, INVALID, 673 /* [54] */ INVALID, INVALID, INVALID, INVALID, 674 /* [58] */ TNSZ("addsd",XMM,8), TNSZ("mulsd",XMM,8), TNSZ("cvtsd2ss",XMM,8), INVALID, 675 /* [5C] */ TNSZ("subsd",XMM,8), TNSZ("minsd",XMM,8), TNSZ("divsd",XMM,8), TNSZ("maxsd",XMM,8), 676 677 /* [60] */ INVALID, INVALID, INVALID, INVALID, 678 /* [64] */ INVALID, INVALID, INVALID, INVALID, 679 /* [68] */ INVALID, INVALID, INVALID, INVALID, 680 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 681 682 /* [70] */ TNSZ("pshuflw",XMMP,16),INVALID, INVALID, INVALID, 683 /* [74] */ INVALID, INVALID, INVALID, INVALID, 684 /* [78] */ TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID, INVALID, 685 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 686 687 /* [80] */ INVALID, INVALID, INVALID, INVALID, 688 /* [84] */ INVALID, INVALID, INVALID, INVALID, 689 /* [88] */ INVALID, INVALID, INVALID, INVALID, 690 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 691 692 /* [90] */ INVALID, INVALID, INVALID, INVALID, 693 /* [94] */ INVALID, INVALID, INVALID, INVALID, 694 /* [98] */ INVALID, INVALID, INVALID, INVALID, 695 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 696 697 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 698 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 699 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 700 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 701 702 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 703 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 704 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 705 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 706 707 /* [C0] */ INVALID, INVALID, TNSZ("cmpsd",XMMP,8), INVALID, 708 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 709 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 710 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 711 712 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 713 /* [D4] */ INVALID, INVALID, TNS("movdq2q",XMMXM), INVALID, 714 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 715 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 716 717 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 718 /* [E4] */ INVALID, INVALID, TNSZ("cvtpd2dq",XMM,16),INVALID, 719 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 720 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 721 722 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 723 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 724 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 725 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 726 }; 727 728 /* 729 * Decode table for SIMD instructions with the repz (0xf3) prefix. 730 */ 731 const instable_t dis_opSIMDrepz[256] = { 732 /* [00] */ INVALID, INVALID, INVALID, INVALID, 733 /* [04] */ INVALID, INVALID, INVALID, INVALID, 734 /* [08] */ INVALID, INVALID, INVALID, INVALID, 735 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 736 737 /* [10] */ TNSZ("movss",XMM,4), TNSZ("movss",XMMS,4), INVALID, INVALID, 738 /* [14] */ INVALID, INVALID, INVALID, INVALID, 739 /* [18] */ INVALID, INVALID, INVALID, INVALID, 740 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 741 742 /* [20] */ INVALID, INVALID, INVALID, INVALID, 743 /* [24] */ INVALID, INVALID, INVALID, INVALID, 744 /* [28] */ INVALID, INVALID, TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4), 745 /* [2C] */ TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID, INVALID, 746 747 /* [30] */ INVALID, INVALID, INVALID, INVALID, 748 /* [34] */ INVALID, INVALID, INVALID, INVALID, 749 /* [38] */ INVALID, INVALID, INVALID, INVALID, 750 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 751 752 /* [40] */ INVALID, INVALID, INVALID, INVALID, 753 /* [44] */ INVALID, INVALID, INVALID, INVALID, 754 /* [48] */ INVALID, INVALID, INVALID, INVALID, 755 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 756 757 /* [50] */ INVALID, TNSZ("sqrtss",XMM,4), TNSZ("rsqrtss",XMM,4), TNSZ("rcpss",XMM,4), 758 /* [54] */ INVALID, INVALID, INVALID, INVALID, 759 /* [58] */ TNSZ("addss",XMM,4), TNSZ("mulss",XMM,4), TNSZ("cvtss2sd",XMM,4), TNSZ("cvttps2dq",XMM,16), 760 /* [5C] */ TNSZ("subss",XMM,4), TNSZ("minss",XMM,4), TNSZ("divss",XMM,4), TNSZ("maxss",XMM,4), 761 762 /* [60] */ INVALID, INVALID, INVALID, INVALID, 763 /* [64] */ INVALID, INVALID, INVALID, INVALID, 764 /* [68] */ INVALID, INVALID, INVALID, INVALID, 765 /* [6C] */ INVALID, INVALID, INVALID, TNSZ("movdqu",XMM,16), 766 767 /* [70] */ TNSZ("pshufhw",XMMP,16),INVALID, INVALID, INVALID, 768 /* [74] */ INVALID, INVALID, INVALID, INVALID, 769 /* [78] */ INVALID, INVALID, INVALID, INVALID, 770 /* [7C] */ INVALID, INVALID, TNSZ("movq",XMM,8), TNSZ("movdqu",XMMS,16), 771 772 /* [80] */ INVALID, INVALID, INVALID, INVALID, 773 /* [84] */ INVALID, INVALID, INVALID, INVALID, 774 /* [88] */ INVALID, INVALID, INVALID, INVALID, 775 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 776 777 /* [90] */ INVALID, INVALID, INVALID, INVALID, 778 /* [94] */ INVALID, INVALID, INVALID, INVALID, 779 /* [98] */ INVALID, INVALID, INVALID, INVALID, 780 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 781 782 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 783 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 784 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 785 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 786 787 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 788 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 789 /* [B8] */ TS("popcnt",MRw), INVALID, INVALID, INVALID, 790 /* [BC] */ INVALID, TS("lzcnt",MRw), INVALID, INVALID, 791 792 /* [C0] */ INVALID, INVALID, TNSZ("cmpss",XMMP,4), INVALID, 793 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 794 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 795 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 796 797 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 798 /* [D4] */ INVALID, INVALID, TNS("movq2dq",XMMMX), INVALID, 799 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 800 /* [DC] */ INVALID, INVALID, INVALID, INVALID, 801 802 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 803 /* [E4] */ INVALID, INVALID, TNSZ("cvtdq2pd",XMM,8), INVALID, 804 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 805 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 806 807 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 808 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 809 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 810 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 811 }; 812 813 /* 814 * The following two tables are used to encode crc32 and movbe 815 * since they share the same opcodes. 816 */ 817 const instable_t dis_op0F38F0[2] = { 818 /* [00] */ TNS("crc32b",CRC32), 819 TS("movbe",MOVBE), 820 }; 821 822 const instable_t dis_op0F38F1[2] = { 823 /* [00] */ TS("crc32",CRC32), 824 TS("movbe",MOVBE), 825 }; 826 827 const instable_t dis_op0F38[256] = { 828 /* [00] */ TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16), 829 /* [04] */ TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16), TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16), 830 /* [08] */ TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16), 831 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 832 833 /* [10] */ TNSZ("pblendvb",XMM_66r,16),INVALID, INVALID, INVALID, 834 /* [14] */ TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID, TNSZ("ptest",XMM_66r,16), 835 /* [18] */ INVALID, INVALID, INVALID, INVALID, 836 /* [1C] */ TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID, 837 838 /* [20] */ TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16), 839 /* [24] */ TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID, INVALID, 840 /* [28] */ TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16), 841 /* [2C] */ INVALID, INVALID, INVALID, INVALID, 842 843 /* [30] */ TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16), 844 /* [34] */ TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID, TNSZ("pcmpgtq",XMM_66r,16), 845 /* [38] */ TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16), 846 /* [3C] */ TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16), 847 848 /* [40] */ TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID, INVALID, 849 /* [44] */ INVALID, INVALID, INVALID, INVALID, 850 /* [48] */ INVALID, INVALID, INVALID, INVALID, 851 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 852 853 /* [50] */ INVALID, INVALID, INVALID, INVALID, 854 /* [54] */ INVALID, INVALID, INVALID, INVALID, 855 /* [58] */ INVALID, INVALID, INVALID, INVALID, 856 /* [5C] */ INVALID, INVALID, INVALID, INVALID, 857 858 /* [60] */ INVALID, INVALID, INVALID, INVALID, 859 /* [64] */ INVALID, INVALID, INVALID, INVALID, 860 /* [68] */ INVALID, INVALID, INVALID, INVALID, 861 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 862 863 /* [70] */ INVALID, INVALID, INVALID, INVALID, 864 /* [74] */ INVALID, INVALID, INVALID, INVALID, 865 /* [78] */ INVALID, INVALID, INVALID, INVALID, 866 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 867 868 /* [80] */ INVALID, INVALID, INVALID, INVALID, 869 /* [84] */ INVALID, INVALID, INVALID, INVALID, 870 /* [88] */ INVALID, INVALID, INVALID, INVALID, 871 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 872 873 /* [90] */ INVALID, INVALID, INVALID, INVALID, 874 /* [94] */ INVALID, INVALID, INVALID, INVALID, 875 /* [98] */ INVALID, INVALID, INVALID, INVALID, 876 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 877 878 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 879 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 880 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 881 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 882 883 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 884 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 885 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 886 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 887 888 /* [C0] */ INVALID, INVALID, INVALID, INVALID, 889 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 890 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 891 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 892 893 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 894 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 895 /* [D8] */ INVALID, INVALID, INVALID, TNSZ("aesimc",XMM_66r,16), 896 /* [DC] */ TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16), 897 898 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 899 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 900 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 901 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 902 /* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID, 903 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 904 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 905 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 906 }; 907 908 const instable_t dis_op0F3A[256] = { 909 /* [00] */ INVALID, INVALID, INVALID, INVALID, 910 /* [04] */ INVALID, INVALID, INVALID, INVALID, 911 /* [08] */ TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16), 912 /* [0C] */ TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16), 913 914 /* [10] */ INVALID, INVALID, INVALID, INVALID, 915 /* [14] */ TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16), 916 /* [18] */ INVALID, INVALID, INVALID, INVALID, 917 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 918 919 /* [20] */ TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID, 920 /* [24] */ INVALID, INVALID, INVALID, INVALID, 921 /* [28] */ INVALID, INVALID, INVALID, INVALID, 922 /* [2C] */ INVALID, INVALID, INVALID, INVALID, 923 924 /* [30] */ INVALID, INVALID, INVALID, INVALID, 925 /* [34] */ INVALID, INVALID, INVALID, INVALID, 926 /* [38] */ INVALID, INVALID, INVALID, INVALID, 927 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 928 929 /* [40] */ TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID, 930 /* [44] */ TNSZ("pclmulqdq",XMMP_66r,16),INVALID, INVALID, INVALID, 931 /* [48] */ INVALID, INVALID, INVALID, INVALID, 932 /* [4C] */ INVALID, INVALID, INVALID, INVALID, 933 934 /* [50] */ INVALID, INVALID, INVALID, INVALID, 935 /* [54] */ INVALID, INVALID, INVALID, INVALID, 936 /* [58] */ INVALID, INVALID, INVALID, INVALID, 937 /* [5C] */ INVALID, INVALID, INVALID, INVALID, 938 939 /* [60] */ TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16), 940 /* [64] */ INVALID, INVALID, INVALID, INVALID, 941 /* [68] */ INVALID, INVALID, INVALID, INVALID, 942 /* [6C] */ INVALID, INVALID, INVALID, INVALID, 943 944 /* [70] */ INVALID, INVALID, INVALID, INVALID, 945 /* [74] */ INVALID, INVALID, INVALID, INVALID, 946 /* [78] */ INVALID, INVALID, INVALID, INVALID, 947 /* [7C] */ INVALID, INVALID, INVALID, INVALID, 948 949 /* [80] */ INVALID, INVALID, INVALID, INVALID, 950 /* [84] */ INVALID, INVALID, INVALID, INVALID, 951 /* [88] */ INVALID, INVALID, INVALID, INVALID, 952 /* [8C] */ INVALID, INVALID, INVALID, INVALID, 953 954 /* [90] */ INVALID, INVALID, INVALID, INVALID, 955 /* [94] */ INVALID, INVALID, INVALID, INVALID, 956 /* [98] */ INVALID, INVALID, INVALID, INVALID, 957 /* [9C] */ INVALID, INVALID, INVALID, INVALID, 958 959 /* [A0] */ INVALID, INVALID, INVALID, INVALID, 960 /* [A4] */ INVALID, INVALID, INVALID, INVALID, 961 /* [A8] */ INVALID, INVALID, INVALID, INVALID, 962 /* [AC] */ INVALID, INVALID, INVALID, INVALID, 963 964 /* [B0] */ INVALID, INVALID, INVALID, INVALID, 965 /* [B4] */ INVALID, INVALID, INVALID, INVALID, 966 /* [B8] */ INVALID, INVALID, INVALID, INVALID, 967 /* [BC] */ INVALID, INVALID, INVALID, INVALID, 968 969 /* [C0] */ INVALID, INVALID, INVALID, INVALID, 970 /* [C4] */ INVALID, INVALID, INVALID, INVALID, 971 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 972 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 973 974 /* [D0] */ INVALID, INVALID, INVALID, INVALID, 975 /* [D4] */ INVALID, INVALID, INVALID, INVALID, 976 /* [D8] */ INVALID, INVALID, INVALID, INVALID, 977 /* [DC] */ INVALID, INVALID, INVALID, TNSZ("aeskeygenassist",XMMP_66r,16), 978 979 /* [E0] */ INVALID, INVALID, INVALID, INVALID, 980 /* [E4] */ INVALID, INVALID, INVALID, INVALID, 981 /* [E8] */ INVALID, INVALID, INVALID, INVALID, 982 /* [EC] */ INVALID, INVALID, INVALID, INVALID, 983 984 /* [F0] */ INVALID, INVALID, INVALID, INVALID, 985 /* [F4] */ INVALID, INVALID, INVALID, INVALID, 986 /* [F8] */ INVALID, INVALID, INVALID, INVALID, 987 /* [FC] */ INVALID, INVALID, INVALID, INVALID, 988 }; 989 990 /* 991 * Decode table for 0x0F opcodes 992 */ 993 994 const instable_t dis_op0F[16][16] = { 995 { 996 /* [00] */ IND(dis_op0F00), IND(dis_op0F01), TNS("lar",MR), TNS("lsl",MR), 997 /* [04] */ INVALID, TNS("syscall",NORM), TNS("clts",NORM), TNS("sysret",NORM), 998 /* [08] */ TNS("invd",NORM), TNS("wbinvd",NORM), INVALID, TNS("ud2",NORM), 999 /* [0C] */ INVALID, INVALID, INVALID, INVALID, 1000 }, { 1001 /* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8), 1002 /* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8), 1003 /* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID, 1004 /* [1C] */ INVALID, INVALID, INVALID, INVALID, 1005 }, { 1006 /* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), 1007 /* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID, 1008 /* [28] */ TNSZ("movaps",XMMO,16), TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16), 1009 /* [2C] */ TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4), 1010 }, { 1011 /* [30] */ TNS("wrmsr",NORM), TNS("rdtsc",NORM), TNS("rdmsr",NORM), TNS("rdpmc",NORM), 1012 /* [34] */ TNSx("sysenter",NORM), TNSx("sysexit",NORM), INVALID, INVALID, 1013 /* [38] */ INVALID, INVALID, INVALID, INVALID, 1014 /* [3C] */ INVALID, INVALID, INVALID, INVALID, 1015 }, { 1016 /* [40] */ TS("cmovx.o",MR), TS("cmovx.no",MR), TS("cmovx.b",MR), TS("cmovx.ae",MR), 1017 /* [44] */ TS("cmovx.e",MR), TS("cmovx.ne",MR), TS("cmovx.be",MR), TS("cmovx.a",MR), 1018 /* [48] */ TS("cmovx.s",MR), TS("cmovx.ns",MR), TS("cmovx.pe",MR), TS("cmovx.po",MR), 1019 /* [4C] */ TS("cmovx.l",MR), TS("cmovx.ge",MR), TS("cmovx.le",MR), TS("cmovx.g",MR), 1020 }, { 1021 /* [50] */ TNS("movmskps",XMMOX3), TNSZ("sqrtps",XMMO,16), TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16), 1022 /* [54] */ TNSZ("andps",XMMO,16), TNSZ("andnps",XMMO,16), TNSZ("orps",XMMO,16), TNSZ("xorps",XMMO,16), 1023 /* [58] */ TNSZ("addps",XMMO,16), TNSZ("mulps",XMMO,16), TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16), 1024 /* [5C] */ TNSZ("subps",XMMO,16), TNSZ("minps",XMMO,16), TNSZ("divps",XMMO,16), TNSZ("maxps",XMMO,16), 1025 }, { 1026 /* [60] */ TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8), 1027 /* [64] */ TNSZ("pcmpgtb",MMO,8), TNSZ("pcmpgtw",MMO,8), TNSZ("pcmpgtd",MMO,8), TNSZ("packuswb",MMO,8), 1028 /* [68] */ TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8), 1029 /* [6C] */ TNSZ("INVALID",MMO,0), TNSZ("INVALID",MMO,0), TNSZ("movd",MMO,4), TNSZ("movq",MMO,8), 1030 }, { 1031 /* [70] */ TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR), TNS("psrXXX",MR), TNS("psrXXX",MR), 1032 /* [74] */ TNSZ("pcmpeqb",MMO,8), TNSZ("pcmpeqw",MMO,8), TNSZ("pcmpeqd",MMO,8), TNS("emms",NORM), 1033 /* [78] */ TNS("INVALID",XMMO), TNS("INVALID",XMMO), INVALID, INVALID, 1034 /* [7C] */ INVALID, INVALID, TNSZ("movd",MMOS,4), TNSZ("movq",MMOS,8), 1035 }, { 1036 /* [80] */ TNS("jo",D), TNS("jno",D), TNS("jb",D), TNS("jae",D), 1037 /* [84] */ TNS("je",D), TNS("jne",D), TNS("jbe",D), TNS("ja",D), 1038 /* [88] */ TNS("js",D), TNS("jns",D), TNS("jp",D), TNS("jnp",D), 1039 /* [8C] */ TNS("jl",D), TNS("jge",D), TNS("jle",D), TNS("jg",D), 1040 }, { 1041 /* [90] */ TNS("seto",Mb), TNS("setno",Mb), TNS("setb",Mb), TNS("setae",Mb), 1042 /* [94] */ TNS("sete",Mb), TNS("setne",Mb), TNS("setbe",Mb), TNS("seta",Mb), 1043 /* [98] */ TNS("sets",Mb), TNS("setns",Mb), TNS("setp",Mb), TNS("setnp",Mb), 1044 /* [9C] */ TNS("setl",Mb), TNS("setge",Mb), TNS("setle",Mb), TNS("setg",Mb), 1045 }, { 1046 /* [A0] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("cpuid",NORM), TS("bt",RMw), 1047 /* [A4] */ TS("shld",DSHIFT), TS("shld",DSHIFTcl), INVALID, INVALID, 1048 /* [A8] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("rsm",NORM), TS("bts",RMw), 1049 /* [AC] */ TS("shrd",DSHIFT), TS("shrd",DSHIFTcl), IND(dis_op0FAE), TS("imul",MRw), 1050 }, { 1051 /* [B0] */ TNS("cmpxchgb",RMw), TS("cmpxchg",RMw), TS("lss",MR), TS("btr",RMw), 1052 /* [B4] */ TS("lfs",MR), TS("lgs",MR), TS("movzb",MOVZ), TNS("movzwl",MOVZ), 1053 /* [B8] */ TNS("INVALID",MRw), INVALID, IND(dis_op0FBA), TS("btc",RMw), 1054 /* [BC] */ TS("bsf",MRw), TS("bsr",MRw), TS("movsb",MOVZ), TNS("movswl",MOVZ), 1055 }, { 1056 /* [C0] */ TNS("xaddb",XADDB), TS("xadd",RMw), TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM), 1057 /* [C4] */ TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7), 1058 /* [C8] */ INVALID, INVALID, INVALID, INVALID, 1059 /* [CC] */ INVALID, INVALID, INVALID, INVALID, 1060 }, { 1061 /* [D0] */ INVALID, TNSZ("psrlw",MMO,8), TNSZ("psrld",MMO,8), TNSZ("psrlq",MMO,8), 1062 /* [D4] */ TNSZ("paddq",MMO,8), TNSZ("pmullw",MMO,8), TNSZ("INVALID",MMO,0), TNS("pmovmskb",MMOM3), 1063 /* [D8] */ TNSZ("psubusb",MMO,8), TNSZ("psubusw",MMO,8), TNSZ("pminub",MMO,8), TNSZ("pand",MMO,8), 1064 /* [DC] */ TNSZ("paddusb",MMO,8), TNSZ("paddusw",MMO,8), TNSZ("pmaxub",MMO,8), TNSZ("pandn",MMO,8), 1065 }, { 1066 /* [E0] */ TNSZ("pavgb",MMO,8), TNSZ("psraw",MMO,8), TNSZ("psrad",MMO,8), TNSZ("pavgw",MMO,8), 1067 /* [E4] */ TNSZ("pmulhuw",MMO,8), TNSZ("pmulhw",MMO,8), TNS("INVALID",XMMO), TNSZ("movntq",MMOMS,8), 1068 /* [E8] */ TNSZ("psubsb",MMO,8), TNSZ("psubsw",MMO,8), TNSZ("pminsw",MMO,8), TNSZ("por",MMO,8), 1069 /* [EC] */ TNSZ("paddsb",MMO,8), TNSZ("paddsw",MMO,8), TNSZ("pmaxsw",MMO,8), TNSZ("pxor",MMO,8), 1070 }, { 1071 /* [F0] */ INVALID, TNSZ("psllw",MMO,8), TNSZ("pslld",MMO,8), TNSZ("psllq",MMO,8), 1072 /* [F4] */ TNSZ("pmuludq",MMO,8), TNSZ("pmaddwd",MMO,8), TNSZ("psadbw",MMO,8), TNSZ("maskmovq",MMOIMPL,8), 1073 /* [F8] */ TNSZ("psubb",MMO,8), TNSZ("psubw",MMO,8), TNSZ("psubd",MMO,8), TNSZ("psubq",MMO,8), 1074 /* [FC] */ TNSZ("paddb",MMO,8), TNSZ("paddw",MMO,8), TNSZ("paddd",MMO,8), INVALID, 1075 } }; 1076 1077 1078 /* 1079 * Decode table for 0x80 opcodes 1080 */ 1081 1082 const instable_t dis_op80[8] = { 1083 1084 /* [0] */ TNS("addb",IMlw), TNS("orb",IMw), TNS("adcb",IMlw), TNS("sbbb",IMlw), 1085 /* [4] */ TNS("andb",IMw), TNS("subb",IMlw), TNS("xorb",IMw), TNS("cmpb",IMlw), 1086 }; 1087 1088 1089 /* 1090 * Decode table for 0x81 opcodes. 1091 */ 1092 1093 const instable_t dis_op81[8] = { 1094 1095 /* [0] */ TS("add",IMlw), TS("or",IMw), TS("adc",IMlw), TS("sbb",IMlw), 1096 /* [4] */ TS("and",IMw), TS("sub",IMlw), TS("xor",IMw), TS("cmp",IMlw), 1097 }; 1098 1099 1100 /* 1101 * Decode table for 0x82 opcodes. 1102 */ 1103 1104 const instable_t dis_op82[8] = { 1105 1106 /* [0] */ TNSx("addb",IMlw), TNSx("orb",IMlw), TNSx("adcb",IMlw), TNSx("sbbb",IMlw), 1107 /* [4] */ TNSx("andb",IMlw), TNSx("subb",IMlw), TNSx("xorb",IMlw), TNSx("cmpb",IMlw), 1108 }; 1109 /* 1110 * Decode table for 0x83 opcodes. 1111 */ 1112 1113 const instable_t dis_op83[8] = { 1114 1115 /* [0] */ TS("add",IMlw), TS("or",IMlw), TS("adc",IMlw), TS("sbb",IMlw), 1116 /* [4] */ TS("and",IMlw), TS("sub",IMlw), TS("xor",IMlw), TS("cmp",IMlw), 1117 }; 1118 1119 /* 1120 * Decode table for 0xC0 opcodes. 1121 */ 1122 1123 const instable_t dis_opC0[8] = { 1124 1125 /* [0] */ TNS("rolb",MvI), TNS("rorb",MvI), TNS("rclb",MvI), TNS("rcrb",MvI), 1126 /* [4] */ TNS("shlb",MvI), TNS("shrb",MvI), INVALID, TNS("sarb",MvI), 1127 }; 1128 1129 /* 1130 * Decode table for 0xD0 opcodes. 1131 */ 1132 1133 const instable_t dis_opD0[8] = { 1134 1135 /* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv), 1136 /* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv), 1137 }; 1138 1139 /* 1140 * Decode table for 0xC1 opcodes. 1141 * 186 instruction set 1142 */ 1143 1144 const instable_t dis_opC1[8] = { 1145 1146 /* [0] */ TS("rol",MvI), TS("ror",MvI), TS("rcl",MvI), TS("rcr",MvI), 1147 /* [4] */ TS("shl",MvI), TS("shr",MvI), TS("sal",MvI), TS("sar",MvI), 1148 }; 1149 1150 /* 1151 * Decode table for 0xD1 opcodes. 1152 */ 1153 1154 const instable_t dis_opD1[8] = { 1155 1156 /* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv), 1157 /* [4] */ TS("shl",Mv), TS("shr",Mv), TS("sal",Mv), TS("sar",Mv), 1158 }; 1159 1160 1161 /* 1162 * Decode table for 0xD2 opcodes. 1163 */ 1164 1165 const instable_t dis_opD2[8] = { 1166 1167 /* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv), 1168 /* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv), 1169 }; 1170 /* 1171 * Decode table for 0xD3 opcodes. 1172 */ 1173 1174 const instable_t dis_opD3[8] = { 1175 1176 /* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv), 1177 /* [4] */ TS("shl",Mv), TS("shr",Mv), TS("salb",Mv), TS("sar",Mv), 1178 }; 1179 1180 1181 /* 1182 * Decode table for 0xF6 opcodes. 1183 */ 1184 1185 const instable_t dis_opF6[8] = { 1186 1187 /* [0] */ TNS("testb",IMw), TNS("testb",IMw), TNS("notb",Mw), TNS("negb",Mw), 1188 /* [4] */ TNS("mulb",MA), TNS("imulb",MA), TNS("divb",MA), TNS("idivb",MA), 1189 }; 1190 1191 1192 /* 1193 * Decode table for 0xF7 opcodes. 1194 */ 1195 1196 const instable_t dis_opF7[8] = { 1197 1198 /* [0] */ TS("test",IMw), TS("test",IMw), TS("not",Mw), TS("neg",Mw), 1199 /* [4] */ TS("mul",MA), TS("imul",MA), TS("div",MA), TS("idiv",MA), 1200 }; 1201 1202 1203 /* 1204 * Decode table for 0xFE opcodes. 1205 */ 1206 1207 const instable_t dis_opFE[8] = { 1208 1209 /* [0] */ TNS("incb",Mw), TNS("decb",Mw), INVALID, INVALID, 1210 /* [4] */ INVALID, INVALID, INVALID, INVALID, 1211 }; 1212 /* 1213 * Decode table for 0xFF opcodes. 1214 */ 1215 1216 const instable_t dis_opFF[8] = { 1217 1218 /* [0] */ TS("inc",Mw), TS("dec",Mw), TNSyp("call",INM), TNS("lcall",INM), 1219 /* [4] */ TNSy("jmp",INM), TNS("ljmp",INM), TSp("push",M), INVALID, 1220 }; 1221 1222 /* for 287 instructions, which are a mess to decode */ 1223 1224 const instable_t dis_opFP1n2[8][8] = { 1225 { 1226 /* bit pattern: 1101 1xxx MODxx xR/M */ 1227 /* [0,0] */ TNS("fadds",M), TNS("fmuls",M), TNS("fcoms",M), TNS("fcomps",M), 1228 /* [0,4] */ TNS("fsubs",M), TNS("fsubrs",M), TNS("fdivs",M), TNS("fdivrs",M), 1229 }, { 1230 /* [1,0] */ TNS("flds",M), INVALID, TNS("fsts",M), TNS("fstps",M), 1231 /* [1,4] */ TNSZ("fldenv",M,28), TNSZ("fldcw",M,2), TNSZ("fnstenv",M,28), TNSZ("fnstcw",M,2), 1232 }, { 1233 /* [2,0] */ TNS("fiaddl",M), TNS("fimull",M), TNS("ficoml",M), TNS("ficompl",M), 1234 /* [2,4] */ TNS("fisubl",M), TNS("fisubrl",M), TNS("fidivl",M), TNS("fidivrl",M), 1235 }, { 1236 /* [3,0] */ TNS("fildl",M), INVALID, TNS("fistl",M), TNS("fistpl",M), 1237 /* [3,4] */ INVALID, TNSZ("fldt",M,10), INVALID, TNSZ("fstpt",M,10), 1238 }, { 1239 /* [4,0] */ TNSZ("faddl",M,8), TNSZ("fmull",M,8), TNSZ("fcoml",M,8), TNSZ("fcompl",M,8), 1240 /* [4,1] */ TNSZ("fsubl",M,8), TNSZ("fsubrl",M,8), TNSZ("fdivl",M,8), TNSZ("fdivrl",M,8), 1241 }, { 1242 /* [5,0] */ TNSZ("fldl",M,8), INVALID, TNSZ("fstl",M,8), TNSZ("fstpl",M,8), 1243 /* [5,4] */ TNSZ("frstor",M,108), INVALID, TNSZ("fnsave",M,108), TNSZ("fnstsw",M,2), 1244 }, { 1245 /* [6,0] */ TNSZ("fiadd",M,2), TNSZ("fimul",M,2), TNSZ("ficom",M,2), TNSZ("ficomp",M,2), 1246 /* [6,4] */ TNSZ("fisub",M,2), TNSZ("fisubr",M,2), TNSZ("fidiv",M,2), TNSZ("fidivr",M,2), 1247 }, { 1248 /* [7,0] */ TNSZ("fild",M,2), INVALID, TNSZ("fist",M,2), TNSZ("fistp",M,2), 1249 /* [7,4] */ TNSZ("fbld",M,10), TNSZ("fildll",M,8), TNSZ("fbstp",M,10), TNSZ("fistpll",M,8), 1250 } }; 1251 1252 const instable_t dis_opFP3[8][8] = { 1253 { 1254 /* bit pattern: 1101 1xxx 11xx xREG */ 1255 /* [0,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F), 1256 /* [0,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF), 1257 }, { 1258 /* [1,0] */ TNS("fld",F), TNS("fxch",F), TNS("fnop",NORM), TNS("fstp",F), 1259 /* [1,4] */ INVALID, INVALID, INVALID, INVALID, 1260 }, { 1261 /* [2,0] */ INVALID, INVALID, INVALID, INVALID, 1262 /* [2,4] */ INVALID, TNS("fucompp",NORM), INVALID, INVALID, 1263 }, { 1264 /* [3,0] */ INVALID, INVALID, INVALID, INVALID, 1265 /* [3,4] */ INVALID, INVALID, INVALID, INVALID, 1266 }, { 1267 /* [4,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F), 1268 /* [4,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF), 1269 }, { 1270 /* [5,0] */ TNS("ffree",F), TNS("fxch",F), TNS("fst",F), TNS("fstp",F), 1271 /* [5,4] */ TNS("fucom",F), TNS("fucomp",F), INVALID, INVALID, 1272 }, { 1273 /* [6,0] */ TNS("faddp",FF), TNS("fmulp",FF), TNS("fcomp",F), TNS("fcompp",NORM), 1274 /* [6,4] */ TNS("fsubp",FF), TNS("fsubrp",FF), TNS("fdivp",FF), TNS("fdivrp",FF), 1275 }, { 1276 /* [7,0] */ TNS("ffreep",F), TNS("fxch",F), TNS("fstp",F), TNS("fstp",F), 1277 /* [7,4] */ TNS("fnstsw",M), TNS("fucomip",FFC), TNS("fcomip",FFC), INVALID, 1278 } }; 1279 1280 const instable_t dis_opFP4[4][8] = { 1281 { 1282 /* bit pattern: 1101 1001 111x xxxx */ 1283 /* [0,0] */ TNS("fchs",NORM), TNS("fabs",NORM), INVALID, INVALID, 1284 /* [0,4] */ TNS("ftst",NORM), TNS("fxam",NORM), TNS("ftstp",NORM), INVALID, 1285 }, { 1286 /* [1,0] */ TNS("fld1",NORM), TNS("fldl2t",NORM), TNS("fldl2e",NORM), TNS("fldpi",NORM), 1287 /* [1,4] */ TNS("fldlg2",NORM), TNS("fldln2",NORM), TNS("fldz",NORM), INVALID, 1288 }, { 1289 /* [2,0] */ TNS("f2xm1",NORM), TNS("fyl2x",NORM), TNS("fptan",NORM), TNS("fpatan",NORM), 1290 /* [2,4] */ TNS("fxtract",NORM), TNS("fprem1",NORM), TNS("fdecstp",NORM), TNS("fincstp",NORM), 1291 }, { 1292 /* [3,0] */ TNS("fprem",NORM), TNS("fyl2xp1",NORM), TNS("fsqrt",NORM), TNS("fsincos",NORM), 1293 /* [3,4] */ TNS("frndint",NORM), TNS("fscale",NORM), TNS("fsin",NORM), TNS("fcos",NORM), 1294 } }; 1295 1296 const instable_t dis_opFP5[8] = { 1297 /* bit pattern: 1101 1011 111x xxxx */ 1298 /* [0] */ TNS("feni",NORM), TNS("fdisi",NORM), TNS("fnclex",NORM), TNS("fninit",NORM), 1299 /* [4] */ TNS("fsetpm",NORM), TNS("frstpm",NORM), INVALID, INVALID, 1300 }; 1301 1302 const instable_t dis_opFP6[8] = { 1303 /* bit pattern: 1101 1011 11yy yxxx */ 1304 /* [00] */ TNS("fcmov.nb",FF), TNS("fcmov.ne",FF), TNS("fcmov.nbe",FF), TNS("fcmov.nu",FF), 1305 /* [04] */ INVALID, TNS("fucomi",F), TNS("fcomi",F), INVALID, 1306 }; 1307 1308 const instable_t dis_opFP7[8] = { 1309 /* bit pattern: 1101 1010 11yy yxxx */ 1310 /* [00] */ TNS("fcmov.b",FF), TNS("fcmov.e",FF), TNS("fcmov.be",FF), TNS("fcmov.u",FF), 1311 /* [04] */ INVALID, INVALID, INVALID, INVALID, 1312 }; 1313 1314 /* 1315 * Main decode table for the op codes. The first two nibbles 1316 * will be used as an index into the table. If there is a 1317 * a need to further decode an instruction, the array to be 1318 * referenced is indicated with the other two entries being 1319 * empty. 1320 */ 1321 1322 const instable_t dis_distable[16][16] = { 1323 { 1324 /* [0,0] */ TNS("addb",RMw), TS("add",RMw), TNS("addb",MRw), TS("add",MRw), 1325 /* [0,4] */ TNS("addb",IA), TS("add",IA), TSx("push",SEG), TSx("pop",SEG), 1326 /* [0,8] */ TNS("orb",RMw), TS("or",RMw), TNS("orb",MRw), TS("or",MRw), 1327 /* [0,C] */ TNS("orb",IA), TS("or",IA), TSx("push",SEG), IND(dis_op0F), 1328 }, { 1329 /* [1,0] */ TNS("adcb",RMw), TS("adc",RMw), TNS("adcb",MRw), TS("adc",MRw), 1330 /* [1,4] */ TNS("adcb",IA), TS("adc",IA), TSx("push",SEG), TSx("pop",SEG), 1331 /* [1,8] */ TNS("sbbb",RMw), TS("sbb",RMw), TNS("sbbb",MRw), TS("sbb",MRw), 1332 /* [1,C] */ TNS("sbbb",IA), TS("sbb",IA), TSx("push",SEG), TSx("pop",SEG), 1333 }, { 1334 /* [2,0] */ TNS("andb",RMw), TS("and",RMw), TNS("andb",MRw), TS("and",MRw), 1335 /* [2,4] */ TNS("andb",IA), TS("and",IA), TNSx("%es:",OVERRIDE), TNSx("daa",NORM), 1336 /* [2,8] */ TNS("subb",RMw), TS("sub",RMw), TNS("subb",MRw), TS("sub",MRw), 1337 /* [2,C] */ TNS("subb",IA), TS("sub",IA), TNSx("%cs:",OVERRIDE), TNSx("das",NORM), 1338 }, { 1339 /* [3,0] */ TNS("xorb",RMw), TS("xor",RMw), TNS("xorb",MRw), TS("xor",MRw), 1340 /* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNSx("%ss:",OVERRIDE), TNSx("aaa",NORM), 1341 /* [3,8] */ TNS("cmpb",RMw), TS("cmp",RMw), TNS("cmpb",MRw), TS("cmp",MRw), 1342 /* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNSx("%ds:",OVERRIDE), TNSx("aas",NORM), 1343 }, { 1344 /* [4,0] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R), 1345 /* [4,4] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R), 1346 /* [4,8] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R), 1347 /* [4,C] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R), 1348 }, { 1349 /* [5,0] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R), 1350 /* [5,4] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R), 1351 /* [5,8] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R), 1352 /* [5,C] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R), 1353 }, { 1354 /* [6,0] */ TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR), TNS("arpl",RMw), 1355 /* [6,4] */ TNS("%fs:",OVERRIDE), TNS("%gs:",OVERRIDE), TNS("data16",DM), TNS("addr16",AM), 1356 /* [6,8] */ TSp("push",I), TS("imul",IMUL), TSp("push",Ib), TS("imul",IMUL), 1357 /* [6,C] */ TNSZ("insb",IMPLMEM,1), TSZ("ins",IMPLMEM,4), TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4), 1358 }, { 1359 /* [7,0] */ TNSy("jo",BD), TNSy("jno",BD), TNSy("jb",BD), TNSy("jae",BD), 1360 /* [7,4] */ TNSy("je",BD), TNSy("jne",BD), TNSy("jbe",BD), TNSy("ja",BD), 1361 /* [7,8] */ TNSy("js",BD), TNSy("jns",BD), TNSy("jp",BD), TNSy("jnp",BD), 1362 /* [7,C] */ TNSy("jl",BD), TNSy("jge",BD), TNSy("jle",BD), TNSy("jg",BD), 1363 }, { 1364 /* [8,0] */ IND(dis_op80), IND(dis_op81), INDx(dis_op82), IND(dis_op83), 1365 /* [8,4] */ TNS("testb",RMw), TS("test",RMw), TNS("xchgb",RMw), TS("xchg",RMw), 1366 /* [8,8] */ TNS("movb",RMw), TS("mov",RMw), TNS("movb",MRw), TS("mov",MRw), 1367 /* [8,C] */ TNS("movw",SM), TS("lea",MR), TNS("movw",MS), TSp("pop",M), 1368 }, { 1369 /* [9,0] */ TNS("nop",NORM), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), 1370 /* [9,4] */ TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), 1371 /* [9,8] */ TNS("cXtX",CBW), TNS("cXtX",CWD), TNSx("lcall",SO), TNS("fwait",NORM), 1372 /* [9,C] */ TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4), TNSx("sahf",NORM), TNSx("lahf",NORM), 1373 }, { 1374 /* [A,0] */ TNS("movb",OA), TS("mov",OA), TNS("movb",AO), TS("mov",AO), 1375 /* [A,4] */ TNSZ("movsb",SD,1), TS("movs",SD), TNSZ("cmpsb",SD,1), TS("cmps",SD), 1376 /* [A,8] */ TNS("testb",IA), TS("test",IA), TNS("stosb",AD), TS("stos",AD), 1377 /* [A,C] */ TNS("lodsb",SA), TS("lods",SA), TNS("scasb",AD), TS("scas",AD), 1378 }, { 1379 /* [B,0] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), 1380 /* [B,4] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), 1381 /* [B,8] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR), 1382 /* [B,C] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR), 1383 }, { 1384 /* [C,0] */ IND(dis_opC0), IND(dis_opC1), TNSyp("ret",RET), TNSyp("ret",NORM), 1385 /* [C,4] */ TNSx("les",MR), TNSx("lds",MR), TNS("movb",IMw), TS("mov",IMw), 1386 /* [C,8] */ TNSyp("enter",ENTER), TNSyp("leave",NORM), TNS("lret",RET), TNS("lret",NORM), 1387 /* [C,C] */ TNS("int",INT3), TNS("int",INTx), TNSx("into",NORM), TNS("iret",NORM), 1388 }, { 1389 /* [D,0] */ IND(dis_opD0), IND(dis_opD1), IND(dis_opD2), IND(dis_opD3), 1390 /* [D,4] */ TNSx("aam",U), TNSx("aad",U), TNSx("falc",NORM), TNSZ("xlat",IMPLMEM,1), 1391 1392 /* 287 instructions. Note that although the indirect field */ 1393 /* indicates opFP1n2 for further decoding, this is not necessarily */ 1394 /* the case since the opFP arrays are not partitioned according to key1 */ 1395 /* and key2. opFP1n2 is given only to indicate that we haven't */ 1396 /* finished decoding the instruction. */ 1397 /* [D,8] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), 1398 /* [D,C] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), 1399 }, { 1400 /* [E,0] */ TNSy("loopnz",BD), TNSy("loopz",BD), TNSy("loop",BD), TNSy("jcxz",BD), 1401 /* [E,4] */ TNS("inb",P), TS("in",P), TNS("outb",P), TS("out",P), 1402 /* [E,8] */ TNSyp("call",D), TNSy("jmp",D), TNSx("ljmp",SO), TNSy("jmp",BD), 1403 /* [E,C] */ TNS("inb",V), TS("in",V), TNS("outb",V), TS("out",V), 1404 }, { 1405 /* [F,0] */ TNS("lock",LOCK), TNS("icebp", NORM), TNS("repnz",PREFIX), TNS("repz",PREFIX), 1406 /* [F,4] */ TNS("hlt",NORM), TNS("cmc",NORM), IND(dis_opF6), IND(dis_opF7), 1407 /* [F,8] */ TNS("clc",NORM), TNS("stc",NORM), TNS("cli",NORM), TNS("sti",NORM), 1408 /* [F,C] */ TNS("cld",NORM), TNS("std",NORM), IND(dis_opFE), IND(dis_opFF), 1409 } }; 1410 1411 /* END CSTYLED */ 1412 1413 /* 1414 * common functions to decode and disassemble an x86 or amd64 instruction 1415 */ 1416 1417 /* 1418 * These are the individual fields of a REX prefix. Note that a REX 1419 * prefix with none of these set is still needed to: 1420 * - use the MOVSXD (sign extend 32 to 64 bits) instruction 1421 * - access the %sil, %dil, %bpl, %spl registers 1422 */ 1423 #define REX_W 0x08 /* 64 bit operand size when set */ 1424 #define REX_R 0x04 /* high order bit extension of ModRM reg field */ 1425 #define REX_X 0x02 /* high order bit extension of SIB index field */ 1426 #define REX_B 0x01 /* extends ModRM r_m, SIB base, or opcode reg */ 1427 1428 /* 1429 * Even in 64 bit mode, usually only 4 byte immediate operands are supported. 1430 */ 1431 static int isize[] = {1, 2, 4, 4}; 1432 static int isize64[] = {1, 2, 4, 8}; 1433 1434 /* 1435 * Just a bunch of useful macros. 1436 */ 1437 #define WBIT(x) (x & 0x1) /* to get w bit */ 1438 #define REGNO(x) (x & 0x7) /* to get 3 bit register */ 1439 #define VBIT(x) ((x)>>1 & 0x1) /* to get 'v' bit */ 1440 #define OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1) 1441 #define OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1) 1442 1443 #define REG_ONLY 3 /* mode to indicate a register operand (not memory) */ 1444 1445 #define BYTE_OPND 0 /* w-bit value indicating byte register */ 1446 #define LONG_OPND 1 /* w-bit value indicating opnd_size register */ 1447 #define MM_OPND 2 /* "value" used to indicate a mmx reg */ 1448 #define XMM_OPND 3 /* "value" used to indicate a xmm reg */ 1449 #define SEG_OPND 4 /* "value" used to indicate a segment reg */ 1450 #define CONTROL_OPND 5 /* "value" used to indicate a control reg */ 1451 #define DEBUG_OPND 6 /* "value" used to indicate a debug reg */ 1452 #define TEST_OPND 7 /* "value" used to indicate a test reg */ 1453 #define WORD_OPND 8 /* w-bit value indicating word size reg */ 1454 1455 /* 1456 * Get the next byte and separate the op code into the high and low nibbles. 1457 */ 1458 static int 1459 dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low) 1460 { 1461 int byte; 1462 1463 /* 1464 * x86 instructions have a maximum length of 15 bytes. Bail out if 1465 * we try to read more. 1466 */ 1467 if (x->d86_len >= 15) 1468 return (x->d86_error = 1); 1469 1470 if (x->d86_error) 1471 return (1); 1472 byte = x->d86_get_byte(x->d86_data); 1473 if (byte < 0) 1474 return (x->d86_error = 1); 1475 x->d86_bytes[x->d86_len++] = byte; 1476 *low = byte & 0xf; /* ----xxxx low 4 bits */ 1477 *high = byte >> 4 & 0xf; /* xxxx---- bits 7 to 4 */ 1478 return (0); 1479 } 1480 1481 /* 1482 * Get and decode an SIB (scaled index base) byte 1483 */ 1484 static void 1485 dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base) 1486 { 1487 int byte; 1488 1489 if (x->d86_error) 1490 return; 1491 1492 byte = x->d86_get_byte(x->d86_data); 1493 if (byte < 0) { 1494 x->d86_error = 1; 1495 return; 1496 } 1497 x->d86_bytes[x->d86_len++] = byte; 1498 1499 *base = byte & 0x7; 1500 *index = (byte >> 3) & 0x7; 1501 *ss = (byte >> 6) & 0x3; 1502 } 1503 1504 /* 1505 * Get the byte following the op code and separate it into the 1506 * mode, register, and r/m fields. 1507 */ 1508 static void 1509 dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m) 1510 { 1511 if (x->d86_got_modrm == 0) { 1512 if (x->d86_rmindex == -1) 1513 x->d86_rmindex = x->d86_len; 1514 dtrace_get_SIB(x, mode, reg, r_m); 1515 x->d86_got_modrm = 1; 1516 } 1517 } 1518 1519 /* 1520 * Adjust register selection based on any REX prefix bits present. 1521 */ 1522 /*ARGSUSED*/ 1523 static void 1524 dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m) 1525 { 1526 if (reg != NULL && r_m == NULL) { 1527 if (rex_prefix & REX_B) 1528 *reg += 8; 1529 } else { 1530 if (reg != NULL && (REX_R & rex_prefix) != 0) 1531 *reg += 8; 1532 if (r_m != NULL && (REX_B & rex_prefix) != 0) 1533 *r_m += 8; 1534 } 1535 } 1536 1537 /* 1538 * Get an immediate operand of the given size, with sign extension. 1539 */ 1540 static void 1541 dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex) 1542 { 1543 int i; 1544 int byte; 1545 int valsize; 1546 1547 if (x->d86_numopnds < opindex + 1) 1548 x->d86_numopnds = opindex + 1; 1549 1550 switch (wbit) { 1551 case BYTE_OPND: 1552 valsize = 1; 1553 break; 1554 case LONG_OPND: 1555 if (x->d86_opnd_size == SIZE16) 1556 valsize = 2; 1557 else if (x->d86_opnd_size == SIZE32) 1558 valsize = 4; 1559 else 1560 valsize = 8; 1561 break; 1562 case MM_OPND: 1563 case XMM_OPND: 1564 case SEG_OPND: 1565 case CONTROL_OPND: 1566 case DEBUG_OPND: 1567 case TEST_OPND: 1568 valsize = size; 1569 break; 1570 case WORD_OPND: 1571 valsize = 2; 1572 break; 1573 } 1574 if (valsize < size) 1575 valsize = size; 1576 1577 if (x->d86_error) 1578 return; 1579 x->d86_opnd[opindex].d86_value = 0; 1580 for (i = 0; i < size; ++i) { 1581 byte = x->d86_get_byte(x->d86_data); 1582 if (byte < 0) { 1583 x->d86_error = 1; 1584 return; 1585 } 1586 x->d86_bytes[x->d86_len++] = byte; 1587 x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8); 1588 } 1589 /* Do sign extension */ 1590 if (x->d86_bytes[x->d86_len - 1] & 0x80) { 1591 for (; i < sizeof (uint64_t); i++) 1592 x->d86_opnd[opindex].d86_value |= 1593 (uint64_t)0xff << (i * 8); 1594 } 1595 #ifdef DIS_TEXT 1596 x->d86_opnd[opindex].d86_mode = MODE_SIGNED; 1597 x->d86_opnd[opindex].d86_value_size = valsize; 1598 x->d86_imm_bytes += size; 1599 #endif 1600 } 1601 1602 /* 1603 * Get an ip relative operand of the given size, with sign extension. 1604 */ 1605 static void 1606 dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex) 1607 { 1608 dtrace_imm_opnd(x, wbit, size, opindex); 1609 #ifdef DIS_TEXT 1610 x->d86_opnd[opindex].d86_mode = MODE_IPREL; 1611 #endif 1612 } 1613 1614 /* 1615 * Check to see if there is a segment override prefix pending. 1616 * If so, print it in the current 'operand' location and set 1617 * the override flag back to false. 1618 */ 1619 /*ARGSUSED*/ 1620 static void 1621 dtrace_check_override(dis86_t *x, int opindex) 1622 { 1623 #ifdef DIS_TEXT 1624 if (x->d86_seg_prefix) { 1625 (void) strlcat(x->d86_opnd[opindex].d86_prefix, 1626 x->d86_seg_prefix, PFIXLEN); 1627 } 1628 #endif 1629 x->d86_seg_prefix = NULL; 1630 } 1631 1632 1633 /* 1634 * Process a single instruction Register or Memory operand. 1635 * 1636 * mode = addressing mode from ModRM byte 1637 * r_m = r_m (or reg if mode == 3) field from ModRM byte 1638 * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use. 1639 * o = index of operand that we are processing (0, 1 or 2) 1640 * 1641 * the value of reg or r_m must have already been adjusted for any REX prefix. 1642 */ 1643 /*ARGSUSED*/ 1644 static void 1645 dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex) 1646 { 1647 int have_SIB = 0; /* flag presence of scale-index-byte */ 1648 uint_t ss; /* scale-factor from opcode */ 1649 uint_t index; /* index register number */ 1650 uint_t base; /* base register number */ 1651 int dispsize; /* size of displacement in bytes */ 1652 #ifdef DIS_TEXT 1653 char *opnd = x->d86_opnd[opindex].d86_opnd; 1654 #endif 1655 1656 if (x->d86_numopnds < opindex + 1) 1657 x->d86_numopnds = opindex + 1; 1658 1659 if (x->d86_error) 1660 return; 1661 1662 /* 1663 * first handle a simple register 1664 */ 1665 if (mode == REG_ONLY) { 1666 #ifdef DIS_TEXT 1667 switch (wbit) { 1668 case MM_OPND: 1669 (void) strlcat(opnd, dis_MMREG[r_m], OPLEN); 1670 break; 1671 case XMM_OPND: 1672 (void) strlcat(opnd, dis_XMMREG[r_m], OPLEN); 1673 break; 1674 case SEG_OPND: 1675 (void) strlcat(opnd, dis_SEGREG[r_m], OPLEN); 1676 break; 1677 case CONTROL_OPND: 1678 (void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN); 1679 break; 1680 case DEBUG_OPND: 1681 (void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN); 1682 break; 1683 case TEST_OPND: 1684 (void) strlcat(opnd, dis_TESTREG[r_m], OPLEN); 1685 break; 1686 case BYTE_OPND: 1687 if (x->d86_rex_prefix == 0) 1688 (void) strlcat(opnd, dis_REG8[r_m], OPLEN); 1689 else 1690 (void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN); 1691 break; 1692 case WORD_OPND: 1693 (void) strlcat(opnd, dis_REG16[r_m], OPLEN); 1694 break; 1695 case LONG_OPND: 1696 if (x->d86_opnd_size == SIZE16) 1697 (void) strlcat(opnd, dis_REG16[r_m], OPLEN); 1698 else if (x->d86_opnd_size == SIZE32) 1699 (void) strlcat(opnd, dis_REG32[r_m], OPLEN); 1700 else 1701 (void) strlcat(opnd, dis_REG64[r_m], OPLEN); 1702 break; 1703 } 1704 #endif /* DIS_TEXT */ 1705 return; 1706 } 1707 1708 /* 1709 * if symbolic representation, skip override prefix, if any 1710 */ 1711 dtrace_check_override(x, opindex); 1712 1713 /* 1714 * Handle 16 bit memory references first, since they decode 1715 * the mode values more simply. 1716 * mode 1 is r_m + 8 bit displacement 1717 * mode 2 is r_m + 16 bit displacement 1718 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp 1719 */ 1720 if (x->d86_addr_size == SIZE16) { 1721 if ((mode == 0 && r_m == 6) || mode == 2) 1722 dtrace_imm_opnd(x, WORD_OPND, 2, opindex); 1723 else if (mode == 1) 1724 dtrace_imm_opnd(x, BYTE_OPND, 1, opindex); 1725 #ifdef DIS_TEXT 1726 if (mode == 0 && r_m == 6) 1727 x->d86_opnd[opindex].d86_mode = MODE_SIGNED; 1728 else if (mode == 0) 1729 x->d86_opnd[opindex].d86_mode = MODE_NONE; 1730 else 1731 x->d86_opnd[opindex].d86_mode = MODE_OFFSET; 1732 (void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN); 1733 #endif 1734 return; 1735 } 1736 1737 /* 1738 * 32 and 64 bit addressing modes are more complex since they 1739 * can involve an SIB (scaled index and base) byte to decode. 1740 */ 1741 if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) { 1742 have_SIB = 1; 1743 dtrace_get_SIB(x, &ss, &index, &base); 1744 if (x->d86_error) 1745 return; 1746 if (base != 5 || mode != 0) 1747 if (x->d86_rex_prefix & REX_B) 1748 base += 8; 1749 if (x->d86_rex_prefix & REX_X) 1750 index += 8; 1751 } else { 1752 base = r_m; 1753 } 1754 1755 /* 1756 * Compute the displacement size and get its bytes 1757 */ 1758 dispsize = 0; 1759 1760 if (mode == 1) 1761 dispsize = 1; 1762 else if (mode == 2) 1763 dispsize = 4; 1764 else if ((r_m & 7) == EBP_REGNO || 1765 (have_SIB && (base & 7) == EBP_REGNO)) 1766 dispsize = 4; 1767 1768 if (dispsize > 0) { 1769 dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND, 1770 dispsize, opindex); 1771 if (x->d86_error) 1772 return; 1773 } 1774 1775 #ifdef DIS_TEXT 1776 if (dispsize > 0) 1777 x->d86_opnd[opindex].d86_mode = MODE_OFFSET; 1778 1779 if (have_SIB == 0) { 1780 if (x->d86_mode == SIZE32) { 1781 if (mode == 0) 1782 (void) strlcat(opnd, dis_addr32_mode0[r_m], 1783 OPLEN); 1784 else 1785 (void) strlcat(opnd, dis_addr32_mode12[r_m], 1786 OPLEN); 1787 } else { 1788 if (mode == 0) { 1789 (void) strlcat(opnd, dis_addr64_mode0[r_m], 1790 OPLEN); 1791 if (r_m == 5) { 1792 x->d86_opnd[opindex].d86_mode = 1793 MODE_RIPREL; 1794 } 1795 } else { 1796 (void) strlcat(opnd, dis_addr64_mode12[r_m], 1797 OPLEN); 1798 } 1799 } 1800 } else { 1801 uint_t need_paren = 0; 1802 char **regs; 1803 if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */ 1804 regs = (char **)dis_REG32; 1805 else 1806 regs = (char **)dis_REG64; 1807 1808 /* 1809 * print the base (if any) 1810 */ 1811 if (base == EBP_REGNO && mode == 0) { 1812 if (index != ESP_REGNO) { 1813 (void) strlcat(opnd, "(", OPLEN); 1814 need_paren = 1; 1815 } 1816 } else { 1817 (void) strlcat(opnd, "(", OPLEN); 1818 (void) strlcat(opnd, regs[base], OPLEN); 1819 need_paren = 1; 1820 } 1821 1822 /* 1823 * print the index (if any) 1824 */ 1825 if (index != ESP_REGNO) { 1826 (void) strlcat(opnd, ",", OPLEN); 1827 (void) strlcat(opnd, regs[index], OPLEN); 1828 (void) strlcat(opnd, dis_scale_factor[ss], OPLEN); 1829 } else 1830 if (need_paren) 1831 (void) strlcat(opnd, ")", OPLEN); 1832 } 1833 #endif 1834 } 1835 1836 /* 1837 * Operand sequence for standard instruction involving one register 1838 * and one register/memory operand. 1839 * wbit indicates a byte(0) or opnd_size(1) operation 1840 * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r") 1841 */ 1842 #define STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit) { \ 1843 dtrace_get_modrm(x, &mode, ®, &r_m); \ 1844 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 1845 dtrace_get_operand(x, mode, r_m, wbit, vbit); \ 1846 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit); \ 1847 } 1848 1849 /* 1850 * Similar to above, but allows for the two operands to be of different 1851 * classes (ie. wbit). 1852 * wbit is for the r_m operand 1853 * w2 is for the reg operand 1854 */ 1855 #define MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit) { \ 1856 dtrace_get_modrm(x, &mode, ®, &r_m); \ 1857 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 1858 dtrace_get_operand(x, mode, r_m, wbit, vbit); \ 1859 dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit); \ 1860 } 1861 1862 /* 1863 * Similar, but for 2 operands plus an immediate. 1864 * vbit indicates direction 1865 * 0 for "opcode imm, r, r_m" or 1866 * 1 for "opcode imm, r_m, r" 1867 */ 1868 #define THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \ 1869 dtrace_get_modrm(x, &mode, ®, &r_m); \ 1870 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 1871 dtrace_get_operand(x, mode, r_m, wbit, 2-vbit); \ 1872 dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit); \ 1873 dtrace_imm_opnd(x, wbit, immsize, 0); \ 1874 } 1875 1876 /* 1877 * Similar, but for 2 operands plus two immediates. 1878 */ 1879 #define FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \ 1880 dtrace_get_modrm(x, &mode, ®, &r_m); \ 1881 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 1882 dtrace_get_operand(x, mode, r_m, wbit, 2); \ 1883 dtrace_get_operand(x, REG_ONLY, reg, w2, 3); \ 1884 dtrace_imm_opnd(x, wbit, immsize, 1); \ 1885 dtrace_imm_opnd(x, wbit, immsize, 0); \ 1886 } 1887 1888 /* 1889 * 1 operands plus two immediates. 1890 */ 1891 #define ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \ 1892 dtrace_get_modrm(x, &mode, ®, &r_m); \ 1893 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \ 1894 dtrace_get_operand(x, mode, r_m, wbit, 2); \ 1895 dtrace_imm_opnd(x, wbit, immsize, 1); \ 1896 dtrace_imm_opnd(x, wbit, immsize, 0); \ 1897 } 1898 1899 /* 1900 * Dissassemble a single x86 or amd64 instruction. 1901 * 1902 * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64) 1903 * for interpreting instructions. 1904 * 1905 * returns non-zero for bad opcode 1906 */ 1907 int 1908 dtrace_disx86(dis86_t *x, uint_t cpu_mode) 1909 { 1910 instable_t *dp; /* decode table being used */ 1911 #ifdef DIS_TEXT 1912 uint_t i; 1913 #endif 1914 #ifdef DIS_MEM 1915 uint_t nomem = 0; 1916 #define NOMEM (nomem = 1) 1917 #else 1918 #define NOMEM /* nothing */ 1919 #endif 1920 uint_t opnd_size; /* SIZE16, SIZE32 or SIZE64 */ 1921 uint_t addr_size; /* SIZE16, SIZE32 or SIZE64 */ 1922 uint_t wbit; /* opcode wbit, 0 is 8 bit, !0 for opnd_size */ 1923 uint_t w2; /* wbit value for second operand */ 1924 uint_t vbit; 1925 uint_t mode = 0; /* mode value from ModRM byte */ 1926 uint_t reg; /* reg value from ModRM byte */ 1927 uint_t r_m; /* r_m value from ModRM byte */ 1928 1929 uint_t opcode1; /* high nibble of 1st byte */ 1930 uint_t opcode2; /* low nibble of 1st byte */ 1931 uint_t opcode3; /* extra opcode bits usually from ModRM byte */ 1932 uint_t opcode4; /* high nibble of 2nd byte */ 1933 uint_t opcode5; /* low nibble of 2nd byte */ 1934 uint_t opcode6; /* high nibble of 3rd byte */ 1935 uint_t opcode7; /* low nibble of 3rd byte */ 1936 uint_t opcode_bytes = 1; 1937 1938 /* 1939 * legacy prefixes come in 5 flavors, you should have only one of each 1940 */ 1941 uint_t opnd_size_prefix = 0; 1942 uint_t addr_size_prefix = 0; 1943 uint_t segment_prefix = 0; 1944 uint_t lock_prefix = 0; 1945 uint_t rep_prefix = 0; 1946 uint_t rex_prefix = 0; /* amd64 register extension prefix */ 1947 size_t off; 1948 1949 instable_t dp_mmx; 1950 1951 x->d86_len = 0; 1952 x->d86_rmindex = -1; 1953 x->d86_error = 0; 1954 #ifdef DIS_TEXT 1955 x->d86_numopnds = 0; 1956 x->d86_seg_prefix = NULL; 1957 x->d86_mnem[0] = 0; 1958 for (i = 0; i < 4; ++i) { 1959 x->d86_opnd[i].d86_opnd[0] = 0; 1960 x->d86_opnd[i].d86_prefix[0] = 0; 1961 x->d86_opnd[i].d86_value_size = 0; 1962 x->d86_opnd[i].d86_value = 0; 1963 x->d86_opnd[i].d86_mode = MODE_NONE; 1964 } 1965 #endif 1966 x->d86_error = 0; 1967 x->d86_memsize = 0; 1968 1969 if (cpu_mode == SIZE16) { 1970 opnd_size = SIZE16; 1971 addr_size = SIZE16; 1972 } else if (cpu_mode == SIZE32) { 1973 opnd_size = SIZE32; 1974 addr_size = SIZE32; 1975 } else { 1976 opnd_size = SIZE32; 1977 addr_size = SIZE64; 1978 } 1979 1980 /* 1981 * Get one opcode byte and check for zero padding that follows 1982 * jump tables. 1983 */ 1984 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 1985 goto error; 1986 1987 if (opcode1 == 0 && opcode2 == 0 && 1988 x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) { 1989 #ifdef DIS_TEXT 1990 (void) strncpy(x->d86_mnem, ".byte\t0", OPLEN); 1991 #endif 1992 goto done; 1993 } 1994 1995 /* 1996 * Gather up legacy x86 prefix bytes. 1997 */ 1998 for (;;) { 1999 uint_t *which_prefix = NULL; 2000 2001 dp = (instable_t *)&dis_distable[opcode1][opcode2]; 2002 2003 switch (dp->it_adrmode) { 2004 case PREFIX: 2005 which_prefix = &rep_prefix; 2006 break; 2007 case LOCK: 2008 which_prefix = &lock_prefix; 2009 break; 2010 case OVERRIDE: 2011 which_prefix = &segment_prefix; 2012 #ifdef DIS_TEXT 2013 x->d86_seg_prefix = (char *)dp->it_name; 2014 #endif 2015 if (dp->it_invalid64 && cpu_mode == SIZE64) 2016 goto error; 2017 break; 2018 case AM: 2019 which_prefix = &addr_size_prefix; 2020 break; 2021 case DM: 2022 which_prefix = &opnd_size_prefix; 2023 break; 2024 } 2025 if (which_prefix == NULL) 2026 break; 2027 *which_prefix = (opcode1 << 4) | opcode2; 2028 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2029 goto error; 2030 } 2031 2032 /* 2033 * Handle amd64 mode PREFIX values. 2034 * Some of the segment prefixes are no-ops. (only FS/GS actually work) 2035 * We might have a REX prefix (opcodes 0x40-0x4f) 2036 */ 2037 if (cpu_mode == SIZE64) { 2038 if (segment_prefix != 0x64 && segment_prefix != 0x65) 2039 segment_prefix = 0; 2040 2041 if (opcode1 == 0x4) { 2042 rex_prefix = (opcode1 << 4) | opcode2; 2043 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0) 2044 goto error; 2045 dp = (instable_t *)&dis_distable[opcode1][opcode2]; 2046 } 2047 } 2048 2049 /* 2050 * Deal with selection of operand and address size now. 2051 * Note that the REX.W bit being set causes opnd_size_prefix to be 2052 * ignored. 2053 */ 2054 if (cpu_mode == SIZE64) { 2055 if (rex_prefix & REX_W) 2056 opnd_size = SIZE64; 2057 else if (opnd_size_prefix) 2058 opnd_size = SIZE16; 2059 2060 if (addr_size_prefix) 2061 addr_size = SIZE32; 2062 } else if (cpu_mode == SIZE32) { 2063 if (opnd_size_prefix) 2064 opnd_size = SIZE16; 2065 if (addr_size_prefix) 2066 addr_size = SIZE16; 2067 } else { 2068 if (opnd_size_prefix) 2069 opnd_size = SIZE32; 2070 if (addr_size_prefix) 2071 addr_size = SIZE32; 2072 } 2073 2074 /* 2075 * The pause instruction - a repz'd nop. This doesn't fit 2076 * with any of the other prefix goop added for SSE, so we'll 2077 * special-case it here. 2078 */ 2079 if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) { 2080 rep_prefix = 0; 2081 dp = (instable_t *)&dis_opPause; 2082 } 2083 2084 /* 2085 * Some 386 instructions have 2 bytes of opcode before the mod_r/m 2086 * byte so we may need to perform a table indirection. 2087 */ 2088 if (dp->it_indirect == (instable_t *)dis_op0F) { 2089 if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0) 2090 goto error; 2091 opcode_bytes = 2; 2092 if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) { 2093 uint_t subcode; 2094 2095 if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0) 2096 goto error; 2097 opcode_bytes = 3; 2098 subcode = ((opcode6 & 0x3) << 1) | 2099 ((opcode7 & 0x8) >> 3); 2100 dp = (instable_t *)&dis_op0F7123[opcode5][subcode]; 2101 } else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) { 2102 dp = (instable_t *)&dis_op0FC8[0]; 2103 } else if ((opcode4 == 0x3) && (opcode5 == 0xA)) { 2104 opcode_bytes = 3; 2105 if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0) 2106 goto error; 2107 if (opnd_size == SIZE16) 2108 opnd_size = SIZE32; 2109 2110 dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7]; 2111 #ifdef DIS_TEXT 2112 if (strcmp(dp->it_name, "INVALID") == 0) 2113 goto error; 2114 #endif 2115 switch (dp->it_adrmode) { 2116 case XMMP_66r: 2117 case XMMPRM_66r: 2118 case XMM3PM_66r: 2119 if (opnd_size_prefix == 0) { 2120 goto error; 2121 } 2122 break; 2123 case XMMP_66o: 2124 if (opnd_size_prefix == 0) { 2125 /* SSSE3 MMX instructions */ 2126 dp_mmx = *dp; 2127 dp = &dp_mmx; 2128 dp->it_adrmode = MMOPM_66o; 2129 #ifdef DIS_MEM 2130 dp->it_size = 8; 2131 #endif 2132 } 2133 break; 2134 default: 2135 goto error; 2136 } 2137 } else if ((opcode4 == 0x3) && (opcode5 == 0x8)) { 2138 opcode_bytes = 3; 2139 if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0) 2140 goto error; 2141 dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7]; 2142 2143 /* 2144 * Both crc32 and movbe have the same 3rd opcode 2145 * byte of either 0xF0 or 0xF1, so we use another 2146 * indirection to distinguish between the two. 2147 */ 2148 if (dp->it_indirect == (instable_t *)dis_op0F38F0 || 2149 dp->it_indirect == (instable_t *)dis_op0F38F1) { 2150 2151 dp = dp->it_indirect; 2152 if (rep_prefix != 0xF2) { 2153 /* It is movbe */ 2154 dp++; 2155 } 2156 } 2157 #ifdef DIS_TEXT 2158 if (strcmp(dp->it_name, "INVALID") == 0) 2159 goto error; 2160 #endif 2161 switch (dp->it_adrmode) { 2162 case XMM_66r: 2163 case XMMM_66r: 2164 if (opnd_size_prefix == 0) { 2165 goto error; 2166 } 2167 break; 2168 case XMM_66o: 2169 if (opnd_size_prefix == 0) { 2170 /* SSSE3 MMX instructions */ 2171 dp_mmx = *dp; 2172 dp = &dp_mmx; 2173 dp->it_adrmode = MM; 2174 #ifdef DIS_MEM 2175 dp->it_size = 8; 2176 #endif 2177 } 2178 break; 2179 case CRC32: 2180 if (rep_prefix != 0xF2) { 2181 goto error; 2182 } 2183 rep_prefix = 0; 2184 break; 2185 case MOVBE: 2186 if (rep_prefix != 0x0) { 2187 goto error; 2188 } 2189 break; 2190 default: 2191 goto error; 2192 } 2193 } else { 2194 dp = (instable_t *)&dis_op0F[opcode4][opcode5]; 2195 } 2196 } 2197 2198 /* 2199 * If still not at a TERM decode entry, then a ModRM byte 2200 * exists and its fields further decode the instruction. 2201 */ 2202 x->d86_got_modrm = 0; 2203 if (dp->it_indirect != TERM) { 2204 dtrace_get_modrm(x, &mode, &opcode3, &r_m); 2205 if (x->d86_error) 2206 goto error; 2207 reg = opcode3; 2208 2209 /* 2210 * decode 287 instructions (D8-DF) from opcodeN 2211 */ 2212 if (opcode1 == 0xD && opcode2 >= 0x8) { 2213 if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4) 2214 dp = (instable_t *)&dis_opFP5[r_m]; 2215 else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4) 2216 dp = (instable_t *)&dis_opFP7[opcode3]; 2217 else if (opcode2 == 0xB && mode == 0x3) 2218 dp = (instable_t *)&dis_opFP6[opcode3]; 2219 else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4) 2220 dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m]; 2221 else if (mode == 0x3) 2222 dp = (instable_t *) 2223 &dis_opFP3[opcode2 - 8][opcode3]; 2224 else 2225 dp = (instable_t *) 2226 &dis_opFP1n2[opcode2 - 8][opcode3]; 2227 } else { 2228 dp = (instable_t *)dp->it_indirect + opcode3; 2229 } 2230 } 2231 2232 /* 2233 * In amd64 bit mode, ARPL opcode is changed to MOVSXD 2234 * (sign extend 32bit to 64 bit) 2235 */ 2236 if (cpu_mode == SIZE64 && opcode1 == 0x6 && opcode2 == 0x3) 2237 dp = (instable_t *)&dis_opMOVSLD; 2238 2239 /* 2240 * at this point we should have a correct (or invalid) opcode 2241 */ 2242 if (cpu_mode == SIZE64 && dp->it_invalid64 || 2243 cpu_mode != SIZE64 && dp->it_invalid32) 2244 goto error; 2245 if (dp->it_indirect != TERM) 2246 goto error; 2247 2248 /* 2249 * deal with MMX/SSE opcodes which are changed by prefixes 2250 */ 2251 switch (dp->it_adrmode) { 2252 case MMO: 2253 case MMOIMPL: 2254 case MMO3P: 2255 case MMOM3: 2256 case MMOMS: 2257 case MMOPM: 2258 case MMOPRM: 2259 case MMOS: 2260 case XMMO: 2261 case XMMOM: 2262 case XMMOMS: 2263 case XMMOPM: 2264 case XMMOS: 2265 case XMMOMX: 2266 case XMMOX3: 2267 case XMMOXMM: 2268 /* 2269 * This is horrible. Some SIMD instructions take the 2270 * form 0x0F 0x?? ..., which is easily decoded using the 2271 * existing tables. Other SIMD instructions use various 2272 * prefix bytes to overload existing instructions. For 2273 * Example, addps is F0, 58, whereas addss is F3 (repz), 2274 * F0, 58. Presumably someone got a raise for this. 2275 * 2276 * If we see one of the instructions which can be 2277 * modified in this way (if we've got one of the SIMDO* 2278 * address modes), we'll check to see if the last prefix 2279 * was a repz. If it was, we strip the prefix from the 2280 * mnemonic, and we indirect using the dis_opSIMDrepz 2281 * table. 2282 */ 2283 2284 /* 2285 * Calculate our offset in dis_op0F 2286 */ 2287 if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F)) 2288 goto error; 2289 2290 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) / 2291 sizeof (instable_t); 2292 2293 /* 2294 * Rewrite if this instruction used one of the magic prefixes. 2295 */ 2296 if (rep_prefix) { 2297 if (rep_prefix == 0xf2) 2298 dp = (instable_t *)&dis_opSIMDrepnz[off]; 2299 else 2300 dp = (instable_t *)&dis_opSIMDrepz[off]; 2301 rep_prefix = 0; 2302 } else if (opnd_size_prefix) { 2303 dp = (instable_t *)&dis_opSIMDdata16[off]; 2304 opnd_size_prefix = 0; 2305 if (opnd_size == SIZE16) 2306 opnd_size = SIZE32; 2307 } 2308 break; 2309 2310 case MMOSH: 2311 /* 2312 * As with the "normal" SIMD instructions, the MMX 2313 * shuffle instructions are overloaded. These 2314 * instructions, however, are special in that they use 2315 * an extra byte, and thus an extra table. As of this 2316 * writing, they only use the opnd_size prefix. 2317 */ 2318 2319 /* 2320 * Calculate our offset in dis_op0F7123 2321 */ 2322 if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 > 2323 sizeof (dis_op0F7123)) 2324 goto error; 2325 2326 if (opnd_size_prefix) { 2327 off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) / 2328 sizeof (instable_t); 2329 dp = (instable_t *)&dis_opSIMD7123[off]; 2330 opnd_size_prefix = 0; 2331 if (opnd_size == SIZE16) 2332 opnd_size = SIZE32; 2333 } 2334 break; 2335 case MRw: 2336 if (rep_prefix) { 2337 if (rep_prefix == 0xf3) { 2338 2339 /* 2340 * Calculate our offset in dis_op0F 2341 */ 2342 if ((uintptr_t)dp - (uintptr_t)dis_op0F 2343 > sizeof (dis_op0F)) 2344 goto error; 2345 2346 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) / 2347 sizeof (instable_t); 2348 2349 dp = (instable_t *)&dis_opSIMDrepz[off]; 2350 rep_prefix = 0; 2351 } else { 2352 goto error; 2353 } 2354 } 2355 break; 2356 } 2357 2358 /* 2359 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64. 2360 */ 2361 if (cpu_mode == SIZE64) 2362 if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop)) 2363 opnd_size = SIZE64; 2364 2365 #ifdef DIS_TEXT 2366 /* 2367 * At this point most instructions can format the opcode mnemonic 2368 * including the prefixes. 2369 */ 2370 if (lock_prefix) 2371 (void) strlcat(x->d86_mnem, "lock ", OPLEN); 2372 2373 if (rep_prefix == 0xf2) 2374 (void) strlcat(x->d86_mnem, "repnz ", OPLEN); 2375 else if (rep_prefix == 0xf3) 2376 (void) strlcat(x->d86_mnem, "repz ", OPLEN); 2377 2378 if (cpu_mode == SIZE64 && addr_size_prefix) 2379 (void) strlcat(x->d86_mnem, "addr32 ", OPLEN); 2380 2381 if (dp->it_adrmode != CBW && 2382 dp->it_adrmode != CWD && 2383 dp->it_adrmode != XMMSFNC) { 2384 if (strcmp(dp->it_name, "INVALID") == 0) 2385 goto error; 2386 (void) strlcat(x->d86_mnem, dp->it_name, OPLEN); 2387 if (dp->it_suffix) { 2388 char *types[] = {"", "w", "l", "q"}; 2389 if (opcode_bytes == 2 && opcode4 == 4) { 2390 /* It's a cmovx.yy. Replace the suffix x */ 2391 for (i = 5; i < OPLEN; i++) { 2392 if (x->d86_mnem[i] == '.') 2393 break; 2394 } 2395 x->d86_mnem[i - 1] = *types[opnd_size]; 2396 } else if ((opnd_size == 2) && (opcode_bytes == 3) && 2397 ((opcode6 == 1 && opcode7 == 6) || 2398 (opcode6 == 2 && opcode7 == 2))) { 2399 /* 2400 * To handle PINSRD and PEXTRD 2401 */ 2402 (void) strlcat(x->d86_mnem, "d", OPLEN); 2403 } else { 2404 (void) strlcat(x->d86_mnem, types[opnd_size], 2405 OPLEN); 2406 } 2407 } 2408 } 2409 #endif 2410 2411 /* 2412 * Process operands based on the addressing modes. 2413 */ 2414 x->d86_mode = cpu_mode; 2415 x->d86_rex_prefix = rex_prefix; 2416 x->d86_opnd_size = opnd_size; 2417 x->d86_addr_size = addr_size; 2418 vbit = 0; /* initialize for mem/reg -> reg */ 2419 switch (dp->it_adrmode) { 2420 /* 2421 * amd64 instruction to sign extend 32 bit reg/mem operands 2422 * into 64 bit register values 2423 */ 2424 case MOVSXZ: 2425 #ifdef DIS_TEXT 2426 if (rex_prefix == 0) 2427 (void) strncpy(x->d86_mnem, "movzld", OPLEN); 2428 #endif 2429 dtrace_get_modrm(x, &mode, ®, &r_m); 2430 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2431 x->d86_opnd_size = SIZE64; 2432 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 2433 x->d86_opnd_size = opnd_size = SIZE32; 2434 wbit = LONG_OPND; 2435 dtrace_get_operand(x, mode, r_m, wbit, 0); 2436 break; 2437 2438 /* 2439 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF) 2440 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7) 2441 * wbit lives in 2nd byte, note that operands 2442 * are different sized 2443 */ 2444 case MOVZ: 2445 if (rex_prefix & REX_W) { 2446 /* target register size = 64 bit */ 2447 x->d86_mnem[5] = 'q'; 2448 } 2449 dtrace_get_modrm(x, &mode, ®, &r_m); 2450 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2451 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 2452 x->d86_opnd_size = opnd_size = SIZE16; 2453 wbit = WBIT(opcode5); 2454 dtrace_get_operand(x, mode, r_m, wbit, 0); 2455 break; 2456 case CRC32: 2457 opnd_size = SIZE32; 2458 if (rex_prefix & REX_W) 2459 opnd_size = SIZE64; 2460 x->d86_opnd_size = opnd_size; 2461 2462 dtrace_get_modrm(x, &mode, ®, &r_m); 2463 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2464 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 2465 wbit = WBIT(opcode7); 2466 if (opnd_size_prefix) 2467 x->d86_opnd_size = opnd_size = SIZE16; 2468 dtrace_get_operand(x, mode, r_m, wbit, 0); 2469 break; 2470 case MOVBE: 2471 opnd_size = SIZE32; 2472 if (rex_prefix & REX_W) 2473 opnd_size = SIZE64; 2474 x->d86_opnd_size = opnd_size; 2475 2476 dtrace_get_modrm(x, &mode, ®, &r_m); 2477 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2478 wbit = WBIT(opcode7); 2479 if (opnd_size_prefix) 2480 x->d86_opnd_size = opnd_size = SIZE16; 2481 if (wbit) { 2482 /* reg -> mem */ 2483 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0); 2484 dtrace_get_operand(x, mode, r_m, wbit, 1); 2485 } else { 2486 /* mem -> reg */ 2487 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 2488 dtrace_get_operand(x, mode, r_m, wbit, 0); 2489 } 2490 break; 2491 2492 /* 2493 * imul instruction, with either 8-bit or longer immediate 2494 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s) 2495 */ 2496 case IMUL: 2497 wbit = LONG_OPND; 2498 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 2499 OPSIZE(opnd_size, opcode2 == 0x9), 1); 2500 break; 2501 2502 /* memory or register operand to register, with 'w' bit */ 2503 case MRw: 2504 wbit = WBIT(opcode2); 2505 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0); 2506 break; 2507 2508 /* register to memory or register operand, with 'w' bit */ 2509 /* arpl happens to fit here also because it is odd */ 2510 case RMw: 2511 if (opcode_bytes == 2) 2512 wbit = WBIT(opcode5); 2513 else 2514 wbit = WBIT(opcode2); 2515 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 2516 break; 2517 2518 /* xaddb instruction */ 2519 case XADDB: 2520 wbit = 0; 2521 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 2522 break; 2523 2524 /* MMX register to memory or register operand */ 2525 case MMS: 2526 case MMOS: 2527 #ifdef DIS_TEXT 2528 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND; 2529 #else 2530 wbit = LONG_OPND; 2531 #endif 2532 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1); 2533 break; 2534 2535 /* MMX register to memory */ 2536 case MMOMS: 2537 dtrace_get_modrm(x, &mode, ®, &r_m); 2538 if (mode == REG_ONLY) 2539 goto error; 2540 wbit = MM_OPND; 2541 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1); 2542 break; 2543 2544 /* Double shift. Has immediate operand specifying the shift. */ 2545 case DSHIFT: 2546 wbit = LONG_OPND; 2547 dtrace_get_modrm(x, &mode, ®, &r_m); 2548 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2549 dtrace_get_operand(x, mode, r_m, wbit, 2); 2550 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 2551 dtrace_imm_opnd(x, wbit, 1, 0); 2552 break; 2553 2554 /* 2555 * Double shift. With no immediate operand, specifies using %cl. 2556 */ 2557 case DSHIFTcl: 2558 wbit = LONG_OPND; 2559 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 2560 break; 2561 2562 /* immediate to memory or register operand */ 2563 case IMlw: 2564 wbit = WBIT(opcode2); 2565 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2566 dtrace_get_operand(x, mode, r_m, wbit, 1); 2567 /* 2568 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83 2569 */ 2570 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0); 2571 break; 2572 2573 /* immediate to memory or register operand with the */ 2574 /* 'w' bit present */ 2575 case IMw: 2576 wbit = WBIT(opcode2); 2577 dtrace_get_modrm(x, &mode, ®, &r_m); 2578 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2579 dtrace_get_operand(x, mode, r_m, wbit, 1); 2580 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0); 2581 break; 2582 2583 /* immediate to register with register in low 3 bits */ 2584 /* of op code */ 2585 case IR: 2586 /* w-bit here (with regs) is bit 3 */ 2587 wbit = opcode2 >>3 & 0x1; 2588 reg = REGNO(opcode2); 2589 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 2590 mode = REG_ONLY; 2591 r_m = reg; 2592 dtrace_get_operand(x, mode, r_m, wbit, 1); 2593 dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0); 2594 break; 2595 2596 /* MMX immediate shift of register */ 2597 case MMSH: 2598 case MMOSH: 2599 wbit = MM_OPND; 2600 goto mm_shift; /* in next case */ 2601 2602 /* SIMD immediate shift of register */ 2603 case XMMSH: 2604 wbit = XMM_OPND; 2605 mm_shift: 2606 reg = REGNO(opcode7); 2607 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 2608 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1); 2609 dtrace_imm_opnd(x, wbit, 1, 0); 2610 NOMEM; 2611 break; 2612 2613 /* accumulator to memory operand */ 2614 case AO: 2615 vbit = 1; 2616 /*FALLTHROUGH*/ 2617 2618 /* memory operand to accumulator */ 2619 case OA: 2620 wbit = WBIT(opcode2); 2621 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit); 2622 dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit); 2623 #ifdef DIS_TEXT 2624 x->d86_opnd[vbit].d86_mode = MODE_OFFSET; 2625 #endif 2626 break; 2627 2628 2629 /* segment register to memory or register operand */ 2630 case SM: 2631 vbit = 1; 2632 /*FALLTHROUGH*/ 2633 2634 /* memory or register operand to segment register */ 2635 case MS: 2636 dtrace_get_modrm(x, &mode, ®, &r_m); 2637 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2638 dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit); 2639 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit); 2640 break; 2641 2642 /* 2643 * rotate or shift instructions, which may shift by 1 or 2644 * consult the cl register, depending on the 'v' bit 2645 */ 2646 case Mv: 2647 vbit = VBIT(opcode2); 2648 wbit = WBIT(opcode2); 2649 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2650 dtrace_get_operand(x, mode, r_m, wbit, 1); 2651 #ifdef DIS_TEXT 2652 if (vbit) { 2653 (void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN); 2654 } else { 2655 x->d86_opnd[0].d86_mode = MODE_SIGNED; 2656 x->d86_opnd[0].d86_value_size = 1; 2657 x->d86_opnd[0].d86_value = 1; 2658 } 2659 #endif 2660 break; 2661 /* 2662 * immediate rotate or shift instructions 2663 */ 2664 case MvI: 2665 wbit = WBIT(opcode2); 2666 normal_imm_mem: 2667 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2668 dtrace_get_operand(x, mode, r_m, wbit, 1); 2669 dtrace_imm_opnd(x, wbit, 1, 0); 2670 break; 2671 2672 /* bit test instructions */ 2673 case MIb: 2674 wbit = LONG_OPND; 2675 goto normal_imm_mem; 2676 2677 /* single memory or register operand with 'w' bit present */ 2678 case Mw: 2679 wbit = WBIT(opcode2); 2680 just_mem: 2681 dtrace_get_modrm(x, &mode, ®, &r_m); 2682 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2683 dtrace_get_operand(x, mode, r_m, wbit, 0); 2684 break; 2685 2686 case SWAPGS: 2687 if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) { 2688 #ifdef DIS_TEXT 2689 (void) strncpy(x->d86_mnem, "swapgs", OPLEN); 2690 #endif 2691 NOMEM; 2692 break; 2693 } 2694 /*FALLTHROUGH*/ 2695 2696 /* prefetch instruction - memory operand, but no memory acess */ 2697 case PREF: 2698 NOMEM; 2699 /*FALLTHROUGH*/ 2700 2701 /* single memory or register operand */ 2702 case M: 2703 wbit = LONG_OPND; 2704 goto just_mem; 2705 2706 /* single memory or register byte operand */ 2707 case Mb: 2708 wbit = BYTE_OPND; 2709 goto just_mem; 2710 2711 case MONITOR_MWAIT: 2712 if (mode == 3) { 2713 if (r_m == 0) { 2714 #ifdef DIS_TEXT 2715 (void) strncpy(x->d86_mnem, "monitor", OPLEN); 2716 #endif 2717 NOMEM; 2718 break; 2719 } else if (r_m == 1) { 2720 #ifdef DIS_TEXT 2721 (void) strncpy(x->d86_mnem, "mwait", OPLEN); 2722 #endif 2723 NOMEM; 2724 break; 2725 } else { 2726 goto error; 2727 } 2728 } 2729 /*FALLTHROUGH*/ 2730 2731 case MO: 2732 /* Similar to M, but only memory (no direct registers) */ 2733 wbit = LONG_OPND; 2734 dtrace_get_modrm(x, &mode, ®, &r_m); 2735 if (mode == 3) 2736 goto error; 2737 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 2738 dtrace_get_operand(x, mode, r_m, wbit, 0); 2739 break; 2740 2741 /* move special register to register or reverse if vbit */ 2742 case SREG: 2743 switch (opcode5) { 2744 2745 case 2: 2746 vbit = 1; 2747 /*FALLTHROUGH*/ 2748 case 0: 2749 wbit = CONTROL_OPND; 2750 break; 2751 2752 case 3: 2753 vbit = 1; 2754 /*FALLTHROUGH*/ 2755 case 1: 2756 wbit = DEBUG_OPND; 2757 break; 2758 2759 case 6: 2760 vbit = 1; 2761 /*FALLTHROUGH*/ 2762 case 4: 2763 wbit = TEST_OPND; 2764 break; 2765 2766 } 2767 dtrace_get_modrm(x, &mode, ®, &r_m); 2768 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2769 dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit); 2770 dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit); 2771 NOMEM; 2772 break; 2773 2774 /* 2775 * single register operand with register in the low 3 2776 * bits of op code 2777 */ 2778 case R: 2779 if (opcode_bytes == 2) 2780 reg = REGNO(opcode5); 2781 else 2782 reg = REGNO(opcode2); 2783 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 2784 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0); 2785 NOMEM; 2786 break; 2787 2788 /* 2789 * register to accumulator with register in the low 3 2790 * bits of op code, xchg instructions 2791 */ 2792 case RA: 2793 NOMEM; 2794 reg = REGNO(opcode2); 2795 dtrace_rex_adjust(rex_prefix, mode, ®, NULL); 2796 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0); 2797 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1); 2798 break; 2799 2800 /* 2801 * single segment register operand, with register in 2802 * bits 3-4 of op code byte 2803 */ 2804 case SEG: 2805 NOMEM; 2806 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3; 2807 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0); 2808 break; 2809 2810 /* 2811 * single segment register operand, with register in 2812 * bits 3-5 of op code 2813 */ 2814 case LSEG: 2815 NOMEM; 2816 /* long seg reg from opcode */ 2817 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7; 2818 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0); 2819 break; 2820 2821 /* memory or register operand to register */ 2822 case MR: 2823 wbit = LONG_OPND; 2824 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0); 2825 break; 2826 2827 case RM: 2828 wbit = LONG_OPND; 2829 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1); 2830 break; 2831 2832 /* MMX/SIMD-Int memory or mm reg to mm reg */ 2833 case MM: 2834 case MMO: 2835 #ifdef DIS_TEXT 2836 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND; 2837 #else 2838 wbit = LONG_OPND; 2839 #endif 2840 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0); 2841 break; 2842 2843 case MMOIMPL: 2844 #ifdef DIS_TEXT 2845 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND; 2846 #else 2847 wbit = LONG_OPND; 2848 #endif 2849 dtrace_get_modrm(x, &mode, ®, &r_m); 2850 if (mode != REG_ONLY) 2851 goto error; 2852 2853 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 2854 dtrace_get_operand(x, mode, r_m, wbit, 0); 2855 dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1); 2856 mode = 0; /* change for memory access size... */ 2857 break; 2858 2859 /* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */ 2860 case MMO3P: 2861 wbit = MM_OPND; 2862 goto xmm3p; 2863 case XMM3P: 2864 wbit = XMM_OPND; 2865 xmm3p: 2866 dtrace_get_modrm(x, &mode, ®, &r_m); 2867 if (mode != REG_ONLY) 2868 goto error; 2869 2870 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1, 2871 1); 2872 NOMEM; 2873 break; 2874 2875 case XMM3PM_66r: 2876 THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND, 2877 1, 0); 2878 break; 2879 2880 /* MMX/SIMD-Int predicated r32/mem to mm reg */ 2881 case MMOPRM: 2882 wbit = LONG_OPND; 2883 w2 = MM_OPND; 2884 goto xmmprm; 2885 case XMMPRM: 2886 case XMMPRM_66r: 2887 wbit = LONG_OPND; 2888 w2 = XMM_OPND; 2889 xmmprm: 2890 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1); 2891 break; 2892 2893 /* MMX/SIMD-Int predicated mm/mem to mm reg */ 2894 case MMOPM: 2895 case MMOPM_66o: 2896 wbit = w2 = MM_OPND; 2897 goto xmmprm; 2898 2899 /* MMX/SIMD-Int mm reg to r32 */ 2900 case MMOM3: 2901 NOMEM; 2902 dtrace_get_modrm(x, &mode, ®, &r_m); 2903 if (mode != REG_ONLY) 2904 goto error; 2905 wbit = MM_OPND; 2906 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0); 2907 break; 2908 2909 /* SIMD memory or xmm reg operand to xmm reg */ 2910 case XMM: 2911 case XMM_66o: 2912 case XMM_66r: 2913 case XMMO: 2914 case XMMXIMPL: 2915 wbit = XMM_OPND; 2916 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0); 2917 2918 if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY) 2919 goto error; 2920 2921 #ifdef DIS_TEXT 2922 /* 2923 * movlps and movhlps share opcodes. They differ in the 2924 * addressing modes allowed for their operands. 2925 * movhps and movlhps behave similarly. 2926 */ 2927 if (mode == REG_ONLY) { 2928 if (strcmp(dp->it_name, "movlps") == 0) 2929 (void) strncpy(x->d86_mnem, "movhlps", OPLEN); 2930 else if (strcmp(dp->it_name, "movhps") == 0) 2931 (void) strncpy(x->d86_mnem, "movlhps", OPLEN); 2932 } 2933 #endif 2934 if (dp->it_adrmode == XMMXIMPL) 2935 mode = 0; /* change for memory access size... */ 2936 break; 2937 2938 /* SIMD xmm reg to memory or xmm reg */ 2939 case XMMS: 2940 case XMMOS: 2941 case XMMMS: 2942 case XMMOMS: 2943 dtrace_get_modrm(x, &mode, ®, &r_m); 2944 #ifdef DIS_TEXT 2945 if ((strcmp(dp->it_name, "movlps") == 0 || 2946 strcmp(dp->it_name, "movhps") == 0 || 2947 strcmp(dp->it_name, "movntps") == 0) && 2948 mode == REG_ONLY) 2949 goto error; 2950 #endif 2951 wbit = XMM_OPND; 2952 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1); 2953 break; 2954 2955 /* SIMD memory to xmm reg */ 2956 case XMMM: 2957 case XMMM_66r: 2958 case XMMOM: 2959 wbit = XMM_OPND; 2960 dtrace_get_modrm(x, &mode, ®, &r_m); 2961 #ifdef DIS_TEXT 2962 if (mode == REG_ONLY) { 2963 if (strcmp(dp->it_name, "movhps") == 0) 2964 (void) strncpy(x->d86_mnem, "movlhps", OPLEN); 2965 else 2966 goto error; 2967 } 2968 #endif 2969 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0); 2970 break; 2971 2972 /* SIMD memory or r32 to xmm reg */ 2973 case XMM3MX: 2974 wbit = LONG_OPND; 2975 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0); 2976 break; 2977 2978 case XMM3MXS: 2979 wbit = LONG_OPND; 2980 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1); 2981 break; 2982 2983 /* SIMD memory or mm reg to xmm reg */ 2984 case XMMOMX: 2985 /* SIMD mm to xmm */ 2986 case XMMMX: 2987 wbit = MM_OPND; 2988 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0); 2989 break; 2990 2991 /* SIMD memory or xmm reg to mm reg */ 2992 case XMMXMM: 2993 case XMMOXMM: 2994 case XMMXM: 2995 wbit = XMM_OPND; 2996 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0); 2997 break; 2998 2999 3000 /* SIMD memory or xmm reg to r32 */ 3001 case XMMXM3: 3002 wbit = XMM_OPND; 3003 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0); 3004 break; 3005 3006 /* SIMD xmm to r32 */ 3007 case XMMX3: 3008 case XMMOX3: 3009 dtrace_get_modrm(x, &mode, ®, &r_m); 3010 if (mode != REG_ONLY) 3011 goto error; 3012 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3013 dtrace_get_operand(x, mode, r_m, XMM_OPND, 0); 3014 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1); 3015 NOMEM; 3016 break; 3017 3018 /* SIMD predicated memory or xmm reg with/to xmm reg */ 3019 case XMMP: 3020 case XMMP_66r: 3021 case XMMP_66o: 3022 case XMMOPM: 3023 wbit = XMM_OPND; 3024 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1, 3025 1); 3026 3027 #ifdef DIS_TEXT 3028 /* 3029 * cmpps and cmpss vary their instruction name based 3030 * on the value of imm8. Other XMMP instructions, 3031 * such as shufps, require explicit specification of 3032 * the predicate. 3033 */ 3034 if (dp->it_name[0] == 'c' && 3035 dp->it_name[1] == 'm' && 3036 dp->it_name[2] == 'p' && 3037 strlen(dp->it_name) == 5) { 3038 uchar_t pred = x->d86_opnd[0].d86_value & 0xff; 3039 3040 if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *))) 3041 goto error; 3042 3043 (void) strncpy(x->d86_mnem, "cmp", OPLEN); 3044 (void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred], 3045 OPLEN); 3046 (void) strlcat(x->d86_mnem, 3047 dp->it_name + strlen(dp->it_name) - 2, 3048 OPLEN); 3049 x->d86_opnd[0] = x->d86_opnd[1]; 3050 x->d86_opnd[1] = x->d86_opnd[2]; 3051 x->d86_numopnds = 2; 3052 } 3053 #endif 3054 break; 3055 3056 case XMMX2I: 3057 FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND, 3058 1); 3059 NOMEM; 3060 break; 3061 3062 case XMM2I: 3063 ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1); 3064 NOMEM; 3065 break; 3066 3067 /* immediate operand to accumulator */ 3068 case IA: 3069 wbit = WBIT(opcode2); 3070 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1); 3071 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0); 3072 NOMEM; 3073 break; 3074 3075 /* memory or register operand to accumulator */ 3076 case MA: 3077 wbit = WBIT(opcode2); 3078 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3079 dtrace_get_operand(x, mode, r_m, wbit, 0); 3080 break; 3081 3082 /* si register to di register used to reference memory */ 3083 case SD: 3084 #ifdef DIS_TEXT 3085 dtrace_check_override(x, 0); 3086 x->d86_numopnds = 2; 3087 if (addr_size == SIZE64) { 3088 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)", 3089 OPLEN); 3090 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)", 3091 OPLEN); 3092 } else if (addr_size == SIZE32) { 3093 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)", 3094 OPLEN); 3095 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)", 3096 OPLEN); 3097 } else { 3098 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)", 3099 OPLEN); 3100 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)", 3101 OPLEN); 3102 } 3103 #endif 3104 wbit = LONG_OPND; 3105 break; 3106 3107 /* accumulator to di register */ 3108 case AD: 3109 wbit = WBIT(opcode2); 3110 #ifdef DIS_TEXT 3111 dtrace_check_override(x, 1); 3112 x->d86_numopnds = 2; 3113 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0); 3114 if (addr_size == SIZE64) 3115 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)", 3116 OPLEN); 3117 else if (addr_size == SIZE32) 3118 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)", 3119 OPLEN); 3120 else 3121 (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)", 3122 OPLEN); 3123 #endif 3124 break; 3125 3126 /* si register to accumulator */ 3127 case SA: 3128 wbit = WBIT(opcode2); 3129 #ifdef DIS_TEXT 3130 dtrace_check_override(x, 0); 3131 x->d86_numopnds = 2; 3132 if (addr_size == SIZE64) 3133 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)", 3134 OPLEN); 3135 else if (addr_size == SIZE32) 3136 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)", 3137 OPLEN); 3138 else 3139 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)", 3140 OPLEN); 3141 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1); 3142 #endif 3143 break; 3144 3145 /* 3146 * single operand, a 16/32 bit displacement 3147 */ 3148 case D: 3149 wbit = LONG_OPND; 3150 dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0); 3151 NOMEM; 3152 break; 3153 3154 /* jmp/call indirect to memory or register operand */ 3155 case INM: 3156 #ifdef DIS_TEXT 3157 (void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN); 3158 #endif 3159 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m); 3160 dtrace_get_operand(x, mode, r_m, LONG_OPND, 0); 3161 wbit = LONG_OPND; 3162 break; 3163 3164 /* 3165 * for long jumps and long calls -- a new code segment 3166 * register and an offset in IP -- stored in object 3167 * code in reverse order. Note - not valid in amd64 3168 */ 3169 case SO: 3170 dtrace_check_override(x, 1); 3171 wbit = LONG_OPND; 3172 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1); 3173 #ifdef DIS_TEXT 3174 x->d86_opnd[1].d86_mode = MODE_SIGNED; 3175 #endif 3176 /* will now get segment operand */ 3177 dtrace_imm_opnd(x, wbit, 2, 0); 3178 break; 3179 3180 /* 3181 * jmp/call. single operand, 8 bit displacement. 3182 * added to current EIP in 'compofff' 3183 */ 3184 case BD: 3185 dtrace_disp_opnd(x, BYTE_OPND, 1, 0); 3186 NOMEM; 3187 break; 3188 3189 /* single 32/16 bit immediate operand */ 3190 case I: 3191 wbit = LONG_OPND; 3192 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0); 3193 break; 3194 3195 /* single 8 bit immediate operand */ 3196 case Ib: 3197 wbit = LONG_OPND; 3198 dtrace_imm_opnd(x, wbit, 1, 0); 3199 break; 3200 3201 case ENTER: 3202 wbit = LONG_OPND; 3203 dtrace_imm_opnd(x, wbit, 2, 0); 3204 dtrace_imm_opnd(x, wbit, 1, 1); 3205 switch (opnd_size) { 3206 case SIZE64: 3207 x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8; 3208 break; 3209 case SIZE32: 3210 x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4; 3211 break; 3212 case SIZE16: 3213 x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2; 3214 break; 3215 } 3216 3217 break; 3218 3219 /* 16-bit immediate operand */ 3220 case RET: 3221 wbit = LONG_OPND; 3222 dtrace_imm_opnd(x, wbit, 2, 0); 3223 break; 3224 3225 /* single 8 bit port operand */ 3226 case P: 3227 dtrace_check_override(x, 0); 3228 dtrace_imm_opnd(x, BYTE_OPND, 1, 0); 3229 NOMEM; 3230 break; 3231 3232 /* single operand, dx register (variable port instruction) */ 3233 case V: 3234 x->d86_numopnds = 1; 3235 dtrace_check_override(x, 0); 3236 #ifdef DIS_TEXT 3237 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN); 3238 #endif 3239 NOMEM; 3240 break; 3241 3242 /* 3243 * The int instruction, which has two forms: 3244 * int 3 (breakpoint) or 3245 * int n, where n is indicated in the subsequent 3246 * byte (format Ib). The int 3 instruction (opcode 0xCC), 3247 * where, although the 3 looks like an operand, 3248 * it is implied by the opcode. It must be converted 3249 * to the correct base and output. 3250 */ 3251 case INT3: 3252 #ifdef DIS_TEXT 3253 x->d86_numopnds = 1; 3254 x->d86_opnd[0].d86_mode = MODE_SIGNED; 3255 x->d86_opnd[0].d86_value_size = 1; 3256 x->d86_opnd[0].d86_value = 3; 3257 #endif 3258 NOMEM; 3259 break; 3260 3261 /* single 8 bit immediate operand */ 3262 case INTx: 3263 dtrace_imm_opnd(x, BYTE_OPND, 1, 0); 3264 NOMEM; 3265 break; 3266 3267 /* an unused byte must be discarded */ 3268 case U: 3269 if (x->d86_get_byte(x->d86_data) < 0) 3270 goto error; 3271 x->d86_len++; 3272 NOMEM; 3273 break; 3274 3275 case CBW: 3276 #ifdef DIS_TEXT 3277 if (opnd_size == SIZE16) 3278 (void) strlcat(x->d86_mnem, "cbtw", OPLEN); 3279 else if (opnd_size == SIZE32) 3280 (void) strlcat(x->d86_mnem, "cwtl", OPLEN); 3281 else 3282 (void) strlcat(x->d86_mnem, "cltq", OPLEN); 3283 #endif 3284 wbit = LONG_OPND; 3285 NOMEM; 3286 break; 3287 3288 case CWD: 3289 #ifdef DIS_TEXT 3290 if (opnd_size == SIZE16) 3291 (void) strlcat(x->d86_mnem, "cwtd", OPLEN); 3292 else if (opnd_size == SIZE32) 3293 (void) strlcat(x->d86_mnem, "cltd", OPLEN); 3294 else 3295 (void) strlcat(x->d86_mnem, "cqtd", OPLEN); 3296 #endif 3297 wbit = LONG_OPND; 3298 NOMEM; 3299 break; 3300 3301 case XMMSFNC: 3302 /* 3303 * sfence is sfence if mode is REG_ONLY. If mode isn't 3304 * REG_ONLY, mnemonic should be 'clflush'. 3305 */ 3306 dtrace_get_modrm(x, &mode, ®, &r_m); 3307 3308 /* sfence doesn't take operands */ 3309 #ifdef DIS_TEXT 3310 if (mode == REG_ONLY) { 3311 (void) strlcat(x->d86_mnem, "sfence", OPLEN); 3312 } else { 3313 (void) strlcat(x->d86_mnem, "clflush", OPLEN); 3314 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3315 dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0); 3316 NOMEM; 3317 } 3318 #else 3319 if (mode != REG_ONLY) { 3320 dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); 3321 dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0); 3322 NOMEM; 3323 } 3324 #endif 3325 break; 3326 3327 /* 3328 * no disassembly, the mnemonic was all there was so go on 3329 */ 3330 case NORM: 3331 if (dp->it_invalid32 && cpu_mode != SIZE64) 3332 goto error; 3333 NOMEM; 3334 /*FALLTHROUGH*/ 3335 case IMPLMEM: 3336 break; 3337 3338 case XMMFENCE: 3339 /* 3340 * Only the following exact byte sequences are allowed: 3341 * 3342 * 0f ae e8 lfence 3343 * 0f ae f0 mfence 3344 */ 3345 if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 && 3346 (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0) 3347 goto error; 3348 3349 break; 3350 3351 3352 /* float reg */ 3353 case F: 3354 #ifdef DIS_TEXT 3355 x->d86_numopnds = 1; 3356 (void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN); 3357 x->d86_opnd[0].d86_opnd[4] = r_m + '0'; 3358 #endif 3359 NOMEM; 3360 break; 3361 3362 /* float reg to float reg, with ret bit present */ 3363 case FF: 3364 vbit = opcode2 >> 2 & 0x1; /* vbit = 1: st -> st(i) */ 3365 /*FALLTHROUGH*/ 3366 case FFC: /* case for vbit always = 0 */ 3367 #ifdef DIS_TEXT 3368 x->d86_numopnds = 2; 3369 (void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN); 3370 (void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN); 3371 x->d86_opnd[vbit].d86_opnd[4] = r_m + '0'; 3372 #endif 3373 NOMEM; 3374 break; 3375 3376 /* an invalid op code */ 3377 case AM: 3378 case DM: 3379 case OVERRIDE: 3380 case PREFIX: 3381 case UNKNOWN: 3382 NOMEM; 3383 default: 3384 goto error; 3385 } /* end switch */ 3386 if (x->d86_error) 3387 goto error; 3388 3389 done: 3390 #ifdef DIS_MEM 3391 /* 3392 * compute the size of any memory accessed by the instruction 3393 */ 3394 if (x->d86_memsize != 0) { 3395 return (0); 3396 } else if (dp->it_stackop) { 3397 switch (opnd_size) { 3398 case SIZE16: 3399 x->d86_memsize = 2; 3400 break; 3401 case SIZE32: 3402 x->d86_memsize = 4; 3403 break; 3404 case SIZE64: 3405 x->d86_memsize = 8; 3406 break; 3407 } 3408 } else if (nomem || mode == REG_ONLY) { 3409 x->d86_memsize = 0; 3410 3411 } else if (dp->it_size != 0) { 3412 /* 3413 * In 64 bit mode descriptor table entries 3414 * go up to 10 bytes and popf/pushf are always 8 bytes 3415 */ 3416 if (x->d86_mode == SIZE64 && dp->it_size == 6) 3417 x->d86_memsize = 10; 3418 else if (x->d86_mode == SIZE64 && opcode1 == 0x9 && 3419 (opcode2 == 0xc || opcode2 == 0xd)) 3420 x->d86_memsize = 8; 3421 else 3422 x->d86_memsize = dp->it_size; 3423 3424 } else if (wbit == 0) { 3425 x->d86_memsize = 1; 3426 3427 } else if (wbit == LONG_OPND) { 3428 if (opnd_size == SIZE64) 3429 x->d86_memsize = 8; 3430 else if (opnd_size == SIZE32) 3431 x->d86_memsize = 4; 3432 else 3433 x->d86_memsize = 2; 3434 3435 } else if (wbit == SEG_OPND) { 3436 x->d86_memsize = 4; 3437 3438 } else { 3439 x->d86_memsize = 8; 3440 } 3441 #endif 3442 return (0); 3443 3444 error: 3445 #ifdef DIS_TEXT 3446 (void) strlcat(x->d86_mnem, "undef", OPLEN); 3447 #endif 3448 return (1); 3449 } 3450 3451 #ifdef DIS_TEXT 3452 3453 /* 3454 * Some instructions should have immediate operands printed 3455 * as unsigned integers. We compare against this table. 3456 */ 3457 static char *unsigned_ops[] = { 3458 "or", "and", "xor", "test", "in", "out", "lcall", "ljmp", 3459 "rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl", 3460 0 3461 }; 3462 3463 3464 static int 3465 isunsigned_op(char *opcode) 3466 { 3467 char *where; 3468 int i; 3469 int is_unsigned = 0; 3470 3471 /* 3472 * Work back to start of last mnemonic, since we may have 3473 * prefixes on some opcodes. 3474 */ 3475 where = opcode + strlen(opcode) - 1; 3476 while (where > opcode && *where != ' ') 3477 --where; 3478 if (*where == ' ') 3479 ++where; 3480 3481 for (i = 0; unsigned_ops[i]; ++i) { 3482 if (strncmp(where, unsigned_ops[i], 3483 strlen(unsigned_ops[i]))) 3484 continue; 3485 is_unsigned = 1; 3486 break; 3487 } 3488 return (is_unsigned); 3489 } 3490 3491 /* 3492 * Print a numeric immediate into end of buf, maximum length buflen. 3493 * The immediate may be an address or a displacement. Mask is set 3494 * for address size. If the immediate is a "small negative", or 3495 * if it's a negative displacement of any magnitude, print as -<absval>. 3496 * Respect the "octal" flag. "Small negative" is defined as "in the 3497 * interval [NEG_LIMIT, 0)". 3498 * 3499 * Also, "isunsigned_op()" instructions never print negatives. 3500 * 3501 * Return whether we decided to print a negative value or not. 3502 */ 3503 3504 #define NEG_LIMIT -255 3505 enum {IMM, DISP}; 3506 enum {POS, TRY_NEG}; 3507 3508 static int 3509 print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf, 3510 size_t buflen, int disp, int try_neg) 3511 { 3512 int curlen; 3513 int64_t sv = (int64_t)usv; 3514 int octal = dis->d86_flags & DIS_F_OCTAL; 3515 3516 curlen = strlen(buf); 3517 3518 if (try_neg == TRY_NEG && sv < 0 && 3519 (disp || sv >= NEG_LIMIT) && 3520 !isunsigned_op(dis->d86_mnem)) { 3521 dis->d86_sprintf_func(buf + curlen, buflen - curlen, 3522 octal ? "-0%llo" : "-0x%llx", (-sv) & mask); 3523 return (1); 3524 } else { 3525 if (disp == DISP) 3526 dis->d86_sprintf_func(buf + curlen, buflen - curlen, 3527 octal ? "+0%llo" : "+0x%llx", usv & mask); 3528 else 3529 dis->d86_sprintf_func(buf + curlen, buflen - curlen, 3530 octal ? "0%llo" : "0x%llx", usv & mask); 3531 return (0); 3532 3533 } 3534 } 3535 3536 3537 static int 3538 log2(int size) 3539 { 3540 switch (size) { 3541 case 1: return (0); 3542 case 2: return (1); 3543 case 4: return (2); 3544 case 8: return (3); 3545 } 3546 return (0); 3547 } 3548 3549 /* ARGSUSED */ 3550 void 3551 dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf, 3552 size_t buflen) 3553 { 3554 uint64_t reltgt = 0; 3555 uint64_t tgt = 0; 3556 int curlen; 3557 int (*lookup)(void *, uint64_t, char *, size_t); 3558 int i; 3559 int64_t sv; 3560 uint64_t usv, mask, save_mask, save_usv; 3561 static uint64_t masks[] = 3562 {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL}; 3563 save_usv = 0; 3564 3565 dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem); 3566 3567 /* 3568 * For PC-relative jumps, the pc is really the next pc after executing 3569 * this instruction, so increment it appropriately. 3570 */ 3571 pc += dis->d86_len; 3572 3573 for (i = 0; i < dis->d86_numopnds; i++) { 3574 d86opnd_t *op = &dis->d86_opnd[i]; 3575 3576 if (i != 0) 3577 (void) strlcat(buf, ",", buflen); 3578 3579 (void) strlcat(buf, op->d86_prefix, buflen); 3580 3581 /* 3582 * sv is for the signed, possibly-truncated immediate or 3583 * displacement; usv retains the original size and 3584 * unsignedness for symbol lookup. 3585 */ 3586 3587 sv = usv = op->d86_value; 3588 3589 /* 3590 * About masks: for immediates that represent 3591 * addresses, the appropriate display size is 3592 * the effective address size of the instruction. 3593 * This includes MODE_OFFSET, MODE_IPREL, and 3594 * MODE_RIPREL. Immediates that are simply 3595 * immediate values should display in the operand's 3596 * size, however, since they don't represent addresses. 3597 */ 3598 3599 /* d86_addr_size is SIZEnn, which is log2(real size) */ 3600 mask = masks[dis->d86_addr_size]; 3601 3602 /* d86_value_size and d86_imm_bytes are in bytes */ 3603 if (op->d86_mode == MODE_SIGNED || 3604 op->d86_mode == MODE_IMPLIED) 3605 mask = masks[log2(op->d86_value_size)]; 3606 3607 switch (op->d86_mode) { 3608 3609 case MODE_NONE: 3610 3611 (void) strlcat(buf, op->d86_opnd, buflen); 3612 break; 3613 3614 case MODE_SIGNED: 3615 case MODE_IMPLIED: 3616 case MODE_OFFSET: 3617 3618 tgt = usv; 3619 3620 if (dis->d86_seg_prefix) 3621 (void) strlcat(buf, dis->d86_seg_prefix, 3622 buflen); 3623 3624 if (op->d86_mode == MODE_SIGNED || 3625 op->d86_mode == MODE_IMPLIED) { 3626 (void) strlcat(buf, "$", buflen); 3627 } 3628 3629 if (print_imm(dis, usv, mask, buf, buflen, 3630 IMM, TRY_NEG) && 3631 (op->d86_mode == MODE_SIGNED || 3632 op->d86_mode == MODE_IMPLIED)) { 3633 3634 /* 3635 * We printed a negative value for an 3636 * immediate that wasn't a 3637 * displacement. Note that fact so we can 3638 * print the positive value as an 3639 * annotation. 3640 */ 3641 3642 save_usv = usv; 3643 save_mask = mask; 3644 } 3645 (void) strlcat(buf, op->d86_opnd, buflen); 3646 3647 break; 3648 3649 case MODE_IPREL: 3650 case MODE_RIPREL: 3651 3652 reltgt = pc + sv; 3653 3654 switch (mode) { 3655 case SIZE16: 3656 reltgt = (uint16_t)reltgt; 3657 break; 3658 case SIZE32: 3659 reltgt = (uint32_t)reltgt; 3660 break; 3661 } 3662 3663 (void) print_imm(dis, usv, mask, buf, buflen, 3664 DISP, TRY_NEG); 3665 3666 if (op->d86_mode == MODE_RIPREL) 3667 (void) strlcat(buf, "(%rip)", buflen); 3668 break; 3669 } 3670 } 3671 3672 /* 3673 * The symbol lookups may result in false positives, 3674 * particularly on object files, where small numbers may match 3675 * the 0-relative non-relocated addresses of symbols. 3676 */ 3677 3678 lookup = dis->d86_sym_lookup; 3679 if (tgt != 0) { 3680 if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 && 3681 lookup(dis->d86_data, tgt, NULL, 0) == 0) { 3682 (void) strlcat(buf, "\t<", buflen); 3683 curlen = strlen(buf); 3684 lookup(dis->d86_data, tgt, buf + curlen, 3685 buflen - curlen); 3686 (void) strlcat(buf, ">", buflen); 3687 } 3688 3689 /* 3690 * If we printed a negative immediate above, print the 3691 * positive in case our heuristic was unhelpful 3692 */ 3693 if (save_usv) { 3694 (void) strlcat(buf, "\t<", buflen); 3695 (void) print_imm(dis, save_usv, save_mask, buf, buflen, 3696 IMM, POS); 3697 (void) strlcat(buf, ">", buflen); 3698 } 3699 } 3700 3701 if (reltgt != 0) { 3702 /* Print symbol or effective address for reltgt */ 3703 3704 (void) strlcat(buf, "\t<", buflen); 3705 curlen = strlen(buf); 3706 lookup(dis->d86_data, reltgt, buf + curlen, 3707 buflen - curlen); 3708 (void) strlcat(buf, ">", buflen); 3709 } 3710 } 3711 3712 #endif /* DIS_TEXT */ 3713