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