2 * Copyright © 2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * @APPLE_LICENSE_HEADER_END@
32 * This file contains the i386 disassembler routine used at NeXT Computer, Inc.
33 * to match the the assembler used at NeXT. It was addapted from a set of
34 * source files with the following copyright which is retained below.
37 Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
41 Permission to use, copy, modify, and distribute this software and
42 its documentation for any purpose and without fee is hereby
43 granted, provided that the above copyright notice appears in all
44 copies and that both the copyright notice and this permission notice
45 appear in supporting documentation, and that the name of Intel
46 not be used in advertising or publicity pertaining to distribution
47 of the software without specific, written prior permission.
49 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
50 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
51 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
52 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
53 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
54 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
55 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
59 #include <mach-o/loader.h>
60 #include <mach-o/nlist.h>
61 #include <mach-o/reloc.h>
62 #include "stuff/symbol.h"
63 #include "stuff/bytesex.h"
65 #include "ofile_print.h"
66 #include "i386_disasm.h"
68 #define MAX_MNEMONIC 16 /* Maximum number of chars per mnemonic, plus a byte for '\0' */
69 #define MAX_RESULT 14 /* Maximum number of char in a register */
70 /* result expression "(%ebx,%ecx,8)" */
72 #define WBIT(x) (x & 0x1) /* to get w bit */
73 #define REGNO(x) (x & 0x7) /* to get 3 bit register */
74 #define VBIT(x) ((x)>>1 & 0x1) /* to get 'v' bit */
75 #define OPSIZE(data16,wbit,maybe64) ((wbit) ? ((data16) ? 2: ((maybe64) ? 8 : 4)) : 1 )
76 #define REX_W(x) (((x) & 0x8) == 0x8) /* true if the REX.W bit is set --> 64-bit operand size */
77 #define REX_R(x) (((x) & 0x4) == 0x4) /* true if the REX.R bit is set --> ModRM reg extension */
78 #define REX_X(x) (((x) & 0x2) == 0x2) /* true if the REX.X bit is set --> SIB index extension */
79 #define REX_B(x) (((x) & 0x1) == 0x1) /* true if the REX.B bit is set --> ModRM r/m, SIB base, or opcode reg extension */
81 #define REG_ONLY 3 /* mode indicates a single register with */
82 /* no displacement is an operand */
83 #define BYTEOPERAND 0 /* value of the w-bit indicating a byte */
84 /* operand (1-byte) */
85 #define LONGOPERAND 1 /* value of the w-bit indicating a long */
86 /* operand (2-bytes or 4-bytes) */
91 * This is the structure that is used for storing all the op code information.
94 char name
[MAX_MNEMONIC
];
95 const struct instable
*indirect
;
98 const struct instable
*arch64
;
100 #define TERM 0 /* used to indicate that the 'indirect' field of the */
101 /* 'instable' terminates - no pointer. */
102 #define INVALID {"",TERM,UNKNOWN,0}
104 * These are defined this way to make the initializations in the tables simpler
105 * and more readable for differences between 32-bit and 64-bit architectures.
107 #define INVALID_32 "",TERM,UNKNOWN,0
108 static const struct instable op_invalid_64
= {"",TERM
,/* UNKNOWN */0,0};
109 #define INVALID_64 (&op_invalid_64)
112 #define HAS_SUFFIX 0x1 /* For instructions which may have a 'w', 'l', or 'q' suffix */
113 #define IS_POINTER_SIZED 0x2 /* For instructions which implicitly have operands which are sizeof(void *) */
115 static void get_operand(
119 uint32_t *value_size
,
121 const cpu_type_t cputype
,
125 const enum bool data16
,
126 const enum bool addr16
,
127 const enum bool sse2
,
129 const unsigned int rex
,
135 const struct relocation_info
*sorted_relocs
,
136 const uint32_t nsorted_relocs
,
137 const struct nlist
*symbols
,
138 const struct nlist_64
*symbols64
,
139 const uint32_t nsymbols
,
141 const uint32_t strings_size
,
142 const struct symbol
*sorted_symbols
,
143 const uint32_t nsorted_symbols
,
144 const enum bool verbose
);
146 static void immediate(
155 const cpu_type_t cputype
,
157 const struct relocation_info
*sorted_relocs
,
158 const uint32_t nsorted_relocs
,
159 const struct nlist
*symbols
,
160 const struct nlist_64
*symbols64
,
161 const uint32_t nsymbols
,
163 const uint32_t strings_size
,
164 const struct symbol
*sorted_symbols
,
165 const uint32_t nsorted_symbols
,
166 const enum bool verbose
);
168 static void displacement(
172 const uint32_t value_size
,
177 const cpu_type_t cputype
,
179 const struct relocation_info
*sorted_relocs
,
180 const uint32_t nsorted_relocs
,
181 const struct nlist
*symbols
,
182 const struct nlist_64
*symbols64
,
183 const uint32_t nsymbols
,
185 const uint32_t strings_size
,
186 const struct symbol
*sorted_symbols
,
187 const uint32_t nsorted_symbols
,
188 const enum bool verbose
);
190 static void get_symbol(
194 const cpu_type_t cputype
,
195 const uint32_t sect_offset
,
196 const uint64_t value
,
197 const struct relocation_info
*relocs
,
198 const uint32_t nrelocs
,
199 const struct nlist
*symbols
,
200 const struct nlist_64
*symbols64
,
201 const uint32_t nsymbols
,
203 const uint32_t strings_size
,
204 const struct symbol
*sorted_symbols
,
205 const uint32_t nsorted_symbols
,
206 const enum bool verbose
);
208 static void print_operand(
213 unsigned int value_size
,
217 static uint64_t get_value(
223 static void modrm_byte(
229 #define GET_OPERAND(symadd, symsub, value, value_size, result) \
230 get_operand((symadd), (symsub), (value), (value_size), (result), \
231 cputype, mode, r_m, wbit, data16, addr16, sse2, mmx, rex, \
232 sect, sect_addr, &length, &left, addr, sorted_relocs, \
233 nsorted_relocs, symbols, symbols64, nsymbols, strings, \
234 strings_size, sorted_symbols, nsorted_symbols, verbose)
236 #define DISPLACEMENT(symadd, symsub, value, value_size) \
237 displacement((symadd), (symsub), (value), (value_size), sect, \
238 sect_addr, &length, &left, cputype, addr, sorted_relocs, \
239 nsorted_relocs, symbols, symbols64, nsymbols, strings, \
240 strings_size, sorted_symbols, nsorted_symbols, verbose)
242 #define IMMEDIATE(symadd, symsub, value, value_size) \
243 immediate((symadd), (symsub), (value), (value_size), sect, sect_addr, \
244 &length, &left, cputype, addr, sorted_relocs, \
245 nsorted_relocs, symbols, symbols64, nsymbols, strings, \
246 strings_size, sorted_symbols, nsorted_symbols, verbose)
248 #define GET_SYMBOL(symadd, symsub, offset, sect_offset, value) \
249 get_symbol((symadd), (symsub), (offset), cputype, (sect_offset), \
250 (value), sorted_relocs, nsorted_relocs, symbols, symbols64, \
251 nsymbols, strings, strings_size, sorted_symbols, \
252 nsorted_symbols, verbose)
254 #define GUESS_SYMBOL(value) \
255 guess_symbol((value), sorted_symbols, nsorted_symbols, verbose)
258 * These are the instruction formats as they appear in the disassembly tables.
259 * Here they are given numerical values for use in the actual disassembly of
290 #define DSHIFT 29 /* for double shift that has an 8-bit immediate */
294 #define O 33 /* for call */
295 #define JTAB 34 /* jump table (not used at NeXT) */
296 #define IMUL 35 /* for 186 iimul instr */
297 #define CBW 36 /* so that data16 can be evaluated for cbw and its variants */
298 #define MvI 37 /* for 186 logicals */
299 #define ENTER 38 /* for 186 enter instr */
300 #define RMw 39 /* for 286 arpl instr */
301 #define Ib 40 /* for push immediate byte */
302 #define F 41 /* for 287 instructions */
303 #define FF 42 /* for 287 instructions */
304 #define DM 43 /* 16-bit data */
305 #define AM 44 /* 16-bit addr */
306 #define LSEG 45 /* for 3-bit seg reg encoding */
307 #define MIb 46 /* for 386 logicals */
308 #define SREG 47 /* for 386 special registers */
309 #define PREFIX 48 /* an instruction prefix like REP, LOCK */
310 #define INT3 49 /* The int 3 instruction, which has a fake operand */
311 #define DSHIFTcl 50 /* for double shift that implicitly uses %cl */
312 #define CWD 51 /* so that data16 can be evaluated for cwd and vars */
313 #define RET 52 /* single immediate 16-bit operand */
314 #define MOVZ 53 /* for movs and movz, with different size operands */
315 #define XINST 54 /* for cmpxchg and xadd */
316 #define BSWAP 55 /* for bswap */
323 #define SSE2 62 /* SSE2 instruction with possible 3rd opcode byte */
324 #define SSE2i 63 /* SSE2 instruction with 8-bit immediate */
325 #define SSE2i1 64 /* SSE2 with one operand and 8-bit immediate */
326 #define SSE2tm 65 /* SSE2 with dest to memory */
327 #define SSE2tfm 66 /* SSE2 with dest to memory or memory to dest */
328 #define PFCH 67 /* prefetch instructions */
329 #define SFEN 68 /* sfence & clflush */
330 #define Mnol 69 /* no 'l' suffix, fildl, fistpl */
331 #define AMD3DNOW 70 /* 3DNow! instruction (SSE2 format with a suffix) */
332 #define PFCH3DNOW 71 /* 3DNow! prefetch instruction */
333 #define REX 72 /* 64-bit REX prefix */
334 #define IR64 73 /* IR with a 64-bit immediate if REX.W is set */
335 #define MNI 74 /* MNI instruction, differentiated by 2nd and 3rd opcode bytes */
336 #define MNIi 75 /* MNI instruction with 8-bit immediate, differentiated by 2nd and 3rd opcode bytes */
337 #define SSE4 76 /* SSE4 instruction with 3rd & 4th opcode bytes */
338 #define SSE4i 77 /* SSE4 instruction with 8-bit immediate */
339 #define SSE4itm 78 /* SSE4 with dest to memory and 8-bit immediate */
340 #define SSE4ifm 79 /* SSE4 with src from memory and 8-bit immediate */
341 #define SSE4MRw 80 /* SSE4.2 memory or register operand to register */
342 #define SSE4CRC 81 /* SSE4.2 crc memory or register operand to register */
343 #define SSE4CRCb 82 /* SSE4.2 crc byte memory or register operand to register */
346 * In 16-bit addressing mode:
347 * Register operands may be indicated by a distinguished field.
348 * An '8' bit register is selected if the 'w' bit is equal to 0,
349 * and a '16' bit register is selected if the 'w' bit is equal to
350 * 1 and also if there is no 'w' bit.
352 static const char * const REG16
[8][2] = {
355 /* 000 */ {"%al", "%ax"},
356 /* 001 */ {"%cl", "%cx"},
357 /* 010 */ {"%dl", "%dx"},
358 /* 011 */ {"%bl", "%bx"},
359 /* 100 */ {"%ah", "%sp"},
360 /* 101 */ {"%ch", "%bp"},
361 /* 110 */ {"%dh", "%si"},
362 /* 111 */ {"%bh", "%di"}
366 * In 32-bit or 64-bit addressing mode:
367 * Register operands may be indicated by a distinguished field.
368 * An '8' bit register is selected if the 'w' bit is equal to 0,
369 * and a '32' bit register is selected if the 'w' bit is equal to
370 * 1 and also if there is no 'w' bit.
372 static const char * const REG32
[16][3] = {
373 /* w bit 0 1 1 + REX.W */
375 /* 0000 */ {"%al", "%eax", "%rax"},
376 /* 0001 */ {"%cl", "%ecx", "%rcx"},
377 /* 0010 */ {"%dl", "%edx", "%rdx"},
378 /* 0011 */ {"%bl", "%ebx", "%rbx"},
379 /* 0100 */ {"%ah", "%esp", "%rsp"},
380 /* 0101 */ {"%ch", "%ebp", "%rbp"},
381 /* 0110 */ {"%dh", "%esi", "%rsi"},
382 /* 0111 */ {"%bh", "%edi", "%rdi"},
383 /* 1000 */ {"%r8b", "%r8d", "%r8"},
384 /* 1001 */ {"%r9b", "%r9d", "%r9"},
385 /* 1010 */ {"%r10b", "%r10d", "%r10"},
386 /* 1011 */ {"%r11b", "%r11d", "%r11"},
387 /* 1100 */ {"%r12b", "%r12d", "%r12"},
388 /* 1101 */ {"%r13b", "%r13d", "%r13"},
389 /* 1110 */ {"%r14b", "%r14d", "%r14"},
390 /* 1111 */ {"%r15b", "%r15d", "%r15"}
393 /* For SSE4CRCb (i.e. crc32) instruction the byte regs when there is a REX */
394 static const char * const REG64_BYTE
[16] = {
415 * This initialized array will be indexed by the 'r/m' and 'mod'
416 * fields, to determine the size of the displacement in each mode.
418 static const char dispsize16
[8][4] = {
419 /* mod 00 01 10 11 */
421 /* 000 */ {0, 1, 2, 0},
422 /* 001 */ {0, 1, 2, 0},
423 /* 010 */ {0, 1, 2, 0},
424 /* 011 */ {0, 1, 2, 0},
425 /* 100 */ {0, 1, 2, 0},
426 /* 101 */ {0, 1, 2, 0},
427 /* 110 */ {2, 1, 2, 0},
428 /* 111 */ {0, 1, 2, 0}
433 * This initialized array will be indexed by the 'r/m' and 'mod'
434 * fields, to determine the size of the displacement in this mode.
436 static const char dispsize32
[8][4] = {
437 /* mod 00 01 10 11 */
439 /* 000 */ {0, 1, 4, 0},
440 /* 001 */ {0, 1, 4, 0},
441 /* 010 */ {0, 1, 4, 0},
442 /* 011 */ {0, 1, 4, 0},
443 /* 100 */ {0, 1, 4, 0},
444 /* 101 */ {4, 1, 4, 0},
445 /* 110 */ {0, 1, 4, 0},
446 /* 111 */ {0, 1, 4, 0}
450 * When data16 has been specified, the following array specifies the registers
451 * for the different addressing modes. Indexed first by mode, then by register
454 static const char * const regname16
[4][8] = {
455 /*reg 000 001 010 011 100 101 110 111 */
457 /*00*/{"%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "", "%bx"},
458 /*01*/{"%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"},
459 /*10*/{"%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"},
460 /*11*/{"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di"}
464 * When data16 has not been specified, fields, to determine the addressing mode,
465 * and will also provide strings for printing.
467 static const char * const regname32
[4][8] = {
468 /*reg 000 001 010 011 100 101 110 111 */
470 /*00 */{"%eax", "%ecx", "%edx", "%ebx", "%esp", "", "%esi", "%edi"},
471 /*01 */{"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"},
472 /*10 */{"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"},
473 /*11 */{"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"}
477 * When data16 has not been specified, fields, to determine the addressing mode,
478 * and will also provide strings for printing.
480 static const char * const regname64
[4][16] = {
481 /*reg 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 */
483 /*00 */{"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"},
484 /*01 */{"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"},
485 /*10 */{"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"},
486 /*11 */{"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"}
490 * If r/m==100 then the following byte (the s-i-b byte) must be decoded
492 static const char * const scale_factor
[4] = {
499 static const char * const indexname
[8] = {
510 static const char * const indexname64
[16] = {
530 * Segment registers are selected by a two or three bit field.
532 static const char * const SEGREG
[8] = {
546 static const char * const DEBUGREG
[] = {
547 "%db0", "%db1", "%db2", "%db3", "%db4", "%db5", "%db6", "%db7",
548 "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
551 static const char * const LLVM_MC_DEBUGREG
[] = {
552 "%dr0", "%dr1", "%dr2", "%dr3", "%dr4", "%dr5", "%dr6", "%dr7",
553 "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
556 static const char * const CONTROLREG
[] = {
557 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
558 "%cr8", "%cr9", "%cr10", "%cr11", "%cr12", "%cr13", "%cr14", "%cr15"
561 static const char * const LLVM_MC_32_CONTROLREG
[] = {
562 "%ecr0", "%ecr1", "%ecr2", "%ecr3", "%ecr4", "%ecr5", "%ecr6", "%ecr7",
563 "%ecr8", "%ecr9", "%ecr10", "%ecr11", "%ecr12", "%ecr13", "%ecr14",
567 static const char * const LLVM_MC_64_CONTROLREG
[] = {
568 "%rcr0", "%rcr1", "%rcr2", "%rcr3", "%rcr4", "%rcr5", "%rcr6", "%rcr7",
569 "%rcr8", "%rcr9", "%rcr10", "%rcr11", "%rcr12", "%rcr13", "%rcr14",
573 static const char * const TESTREG
[8] = {
574 "%tr0", "%tr1", "%tr2", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
578 * Decode table for 0x0F00 opcodes
580 static const struct instable op0F00
[8] = {
581 /* [0] */ {"sldt",TERM
,M
,0}, {"str",TERM
,M
,0},
582 {"lldt",TERM
,M
,0}, {"ltr",TERM
,M
,0},
583 /* [4] */ {"verr",TERM
,M
,0}, {"verw",TERM
,M
,0},
589 * Decode table for 0x0F01 opcodes
591 static const struct instable op0F01
[8] = {
592 /* [0] */ {"sgdt",TERM
,M
,1}, {"sidt",TERM
,M
,1},
593 {"lgdt",TERM
,M
,1}, {"lidt",TERM
,M
,1},
594 /* [4] */ {"smsw",TERM
,M
,0}, INVALID
,
595 {"lmsw",TERM
,M
,0}, {"invlpg",TERM
,M
,0},
599 * Decode table for 0x0F38 opcodes
601 static const struct instable op0F38
[256] = {
602 /* [00] */ {"pshufb",TERM
,MNI
,0}, {"phaddw",TERM
,MNI
,0},
603 {"phaddd",TERM
,MNI
,0}, {"phaddsw",TERM
,MNI
,0},
604 /* [04] */ {"pmaddubsw",TERM
,MNI
,0}, {"phsubw",TERM
,MNI
,0},
605 {"phsubd",TERM
,MNI
,0}, {"phsubsw",TERM
,MNI
,0},
606 /* [08] */ {"psignb",TERM
,MNI
,0}, {"psignw",TERM
,MNI
,0},
607 {"psignd",TERM
,MNI
,0}, {"pmulhrsw",TERM
,MNI
,0},
608 /* [0C] */ INVALID
, INVALID
,
610 /* [10] */ {"pblendvb",TERM
,SSE4
,0}, INVALID
,
612 /* [14] */ {"blendvps",TERM
,SSE4
,0},{"blendvpd",TERM
,SSE4
,0},
613 INVALID
, {"ptest",TERM
,SSE4
,0},
614 /* [18] */ INVALID
, INVALID
,
616 /* [1C] */ {"pabsb",TERM
,MNI
,0}, {"pabsw",TERM
,MNI
,0},
617 {"pabsd",TERM
,MNI
,0}, INVALID
,
618 /* [20] */ {"pmovsxbw",TERM
,SSE4
,0}, {"pmovsxbd",TERM
,SSE4
,0},
619 {"pmovsxbq",TERM
,SSE4
,0}, {"pmovsxwd",TERM
,SSE4
,0},
620 /* [24] */ {"pmovsxwq",TERM
,SSE4
,0}, {"pmovsxdq",TERM
,SSE4
,0},
622 /* [28] */ {"pmuldq",TERM
,SSE4
,0}, {"pcmpeqq",TERM
,SSE4
,0},
623 {"movntdqa",TERM
,SSE4
,0}, {"packusdw",TERM
,SSE4
,0},
624 /* [2C] */ INVALID
, INVALID
,
626 /* [30] */ {"pmovzxbw",TERM
,SSE4
,0}, {"pmovzxbd",TERM
,SSE4
,0},
627 {"pmovzxbq",TERM
,SSE4
,0}, {"pmovzxwd",TERM
,SSE4
,0},
628 /* [34] */ {"pmovzxwq",TERM
,SSE4
,0}, {"pmovzxdq",TERM
,SSE4
,0},
629 INVALID
, {"pcmpgtq",TERM
,SSE4
,0},
630 /* [38] */ {"pminsb",TERM
,SSE4
,0}, {"pminsd",TERM
,SSE4
,0},
631 {"pminuw",TERM
,SSE4
,0}, {"pminud",TERM
,SSE4
,0},
632 /* [3C] */ {"pmaxsb",TERM
,SSE4
,0}, {"pmaxsd",TERM
,SSE4
,0},
633 {"pmaxuw",TERM
,SSE4
,0}, {"pmaxud",TERM
,SSE4
,0},
634 /* [40] */ {"pmulld",TERM
,SSE4
,0}, {"phminposuw",TERM
,SSE4
,0},
636 /* [44] */ INVALID
, INVALID
,
638 /* [48] */ INVALID
, INVALID
,
640 /* [4C] */ INVALID
, INVALID
,
642 /* [50] */ INVALID
, INVALID
,
644 /* [54] */ INVALID
, INVALID
,
646 /* [58] */ INVALID
, INVALID
,
648 /* [5C] */ INVALID
, INVALID
,
650 /* [60] */ INVALID
, INVALID
,
652 /* [64] */ INVALID
, INVALID
,
654 /* [68] */ INVALID
, INVALID
,
656 /* [6C] */ INVALID
, INVALID
,
658 /* [70] */ INVALID
, INVALID
,
660 /* [74] */ INVALID
, INVALID
,
662 /* [78] */ INVALID
, INVALID
,
664 /* [7C] */ INVALID
, INVALID
,
666 /* [80] */ {"invept",TERM
,MR
,0}, {"invvpid",TERM
,MR
,0},
668 /* [84] */ INVALID
, INVALID
,
670 /* [88] */ INVALID
, INVALID
,
672 /* [8C] */ INVALID
, INVALID
,
674 /* [90] */ INVALID
, INVALID
,
676 /* [94] */ INVALID
, INVALID
,
678 /* [98] */ INVALID
, INVALID
,
680 /* [9C] */ INVALID
, INVALID
,
682 /* [A0] */ INVALID
, INVALID
,
684 /* [A4] */ INVALID
, INVALID
,
686 /* [A8] */ INVALID
, INVALID
,
688 /* [AC] */ INVALID
, INVALID
,
690 /* [B0] */ INVALID
, INVALID
,
692 /* [B4] */ INVALID
, INVALID
,
694 /* [B8] */ INVALID
, INVALID
,
696 /* [BC] */ INVALID
, INVALID
,
698 /* [C0] */ INVALID
, INVALID
,
700 /* [C4] */ INVALID
, INVALID
,
702 /* [C8] */ INVALID
, INVALID
,
704 /* [CC] */ INVALID
, INVALID
,
706 /* [D0] */ INVALID
, INVALID
,
708 /* [D4] */ INVALID
, INVALID
,
710 /* [D8] */ INVALID
, INVALID
,
711 INVALID
, {"aesimc",TERM
,SSE4
,0},
712 /* [DC] */ {"aesenc",TERM
,SSE4
,0}, {"aesenclast",TERM
,SSE4
,0},
713 {"aesdec",TERM
,SSE4
,0}, {"aesdeclast",TERM
,SSE4
,0},
714 /* [E0] */ INVALID
, INVALID
,
716 /* [E4] */ INVALID
, INVALID
,
718 /* [E8] */ INVALID
, INVALID
,
720 /* [EC] */ INVALID
, INVALID
,
722 /* [F0] */ {"crc32b",TERM
,SSE4CRCb
,0}, {"crc32",TERM
,SSE4CRC
,1},
724 /* [F4] */ INVALID
, INVALID
,
726 /* [F8] */ INVALID
, INVALID
,
728 /* [FC] */ INVALID
, INVALID
,
733 * Decode table for 0x0F3A opcodes
735 static const struct instable op0F3A
[224] = {
736 /* [00] */ INVALID
, INVALID
,
738 /* [04] */ INVALID
, INVALID
,
740 /* [08] */ {"roundps",TERM
,SSE4i
,0}, {"roundpd",TERM
,SSE4i
,0},
741 {"roundss",TERM
,SSE4i
,0}, {"roundsd",TERM
,SSE4i
,0},
742 /* [0C] */ {"blendps",TERM
,SSE4i
,0}, {"blendpd",TERM
,SSE4i
,0},
743 {"pblendw",TERM
,SSE4i
,0}, {"palignr",TERM
,MNIi
,0},
744 /* [10] */ INVALID
, INVALID
,
746 /* [14] */ {"pextrb",TERM
,SSE4itm
,0}, {"pextrw",TERM
,SSE4itm
,0},
747 {"pextr",TERM
,SSE4itm
,0}, {"extractps",TERM
,SSE4itm
,0},
748 /* [18] */ INVALID
, INVALID
,
750 /* [1C] */ INVALID
, INVALID
,
752 /* [20] */ {"pinsrb",TERM
,SSE4ifm
,0}, {"insertps",TERM
,SSE4i
,0},
753 {"pinsr",TERM
,SSE4ifm
,0}, INVALID
,
754 /* [24] */ INVALID
, INVALID
,
756 /* [28] */ INVALID
, INVALID
,
758 /* [2C] */ INVALID
, INVALID
,
760 /* [30] */ INVALID
, INVALID
,
762 /* [34] */ INVALID
, INVALID
,
764 /* [38] */ INVALID
, INVALID
,
766 /* [3C] */ INVALID
, INVALID
,
768 /* [40] */ {"dpps",TERM
,SSE4i
,0}, {"dppd",TERM
,SSE4i
,0},
769 {"mpsadbw",TERM
,SSE4i
,0}, INVALID
,
770 /* [44] */ INVALID
, INVALID
,
772 /* [48] */ INVALID
, INVALID
,
774 /* [4C] */ INVALID
, INVALID
,
776 /* [50] */ INVALID
, INVALID
,
778 /* [54] */ INVALID
, INVALID
,
780 /* [58] */ INVALID
, INVALID
,
782 /* [5C] */ INVALID
, INVALID
,
784 /* [60] */ {"pcmpestrm",TERM
,SSE4i
,0}, {"pcmpestri",TERM
,SSE4i
,0},
785 {"pcmpistrm",TERM
,SSE4i
,0}, {"pcmpistri",TERM
,SSE4i
,0},
786 /* [64] */ INVALID
, INVALID
,
788 /* [68] */ INVALID
, INVALID
,
790 /* [6C] */ INVALID
, INVALID
,
792 /* [70] */ INVALID
, INVALID
,
794 /* [74] */ INVALID
, INVALID
,
796 /* [78] */ INVALID
, INVALID
,
798 /* [7C] */ INVALID
, INVALID
,
800 /* [80] */ INVALID
, INVALID
,
802 /* [84] */ INVALID
, INVALID
,
804 /* [88] */ INVALID
, INVALID
,
806 /* [8C] */ INVALID
, INVALID
,
808 /* [90] */ INVALID
, INVALID
,
810 /* [94] */ INVALID
, INVALID
,
812 /* [98] */ INVALID
, INVALID
,
814 /* [9C] */ INVALID
, INVALID
,
816 /* [A0] */ INVALID
, INVALID
,
818 /* [A4] */ INVALID
, INVALID
,
820 /* [A8] */ INVALID
, INVALID
,
822 /* [AC] */ INVALID
, INVALID
,
824 /* [B0] */ INVALID
, INVALID
,
826 /* [B4] */ INVALID
, INVALID
,
828 /* [B8] */ INVALID
, INVALID
,
830 /* [BC] */ INVALID
, INVALID
,
832 /* [C0] */ INVALID
, INVALID
,
834 /* [C4] */ INVALID
, INVALID
,
836 /* [C8] */ INVALID
, INVALID
,
838 /* [CC] */ INVALID
, INVALID
,
840 /* [D0] */ INVALID
, INVALID
,
842 /* [D4] */ INVALID
, INVALID
,
844 /* [D8] */ INVALID
, INVALID
,
846 /* [DC] */ INVALID
, INVALID
,
847 INVALID
, {"aeskeygenassist",TERM
,SSE4i
,0},
850 static const struct instable op_monitor
= {"monitor",TERM
,GO_ON
,0};
851 static const struct instable op_mwait
= {"mwait",TERM
,GO_ON
,0};
852 static const struct instable op_rdtscp
= {"rdtscp",TERM
,GO_ON
,0};
854 /* These opcode tables entries are only used for the 64-bit architecture */
855 static const struct instable op_swapgs
= {"swapgs",TERM
,GO_ON
,0};
856 static const struct instable op_syscall
= {"syscall",TERM
,GO_ON
,0};
857 static const struct instable op_sysret
= {"sysret",TERM
,GO_ON
,0};
858 static const struct instable opREX
= {"",TERM
,REX
,0};
859 static const struct instable op_movsl
= {"movsl",TERM
,MOVZ
,1};
862 * Decode table for 0x0F0F opcodes
863 * Unlike the other decode tables, this one maps suffixes.
865 static const struct instable op0F0F
[16][16] = {
866 /* [00] */ { INVALID
, INVALID
,
868 /* [04] */ INVALID
, INVALID
,
870 /* [08] */ INVALID
, INVALID
,
872 /* [0C] */ {"pi2fw",TERM
,AMD3DNOW
,0}, {"pi2fd",TERM
,AMD3DNOW
,0},
874 /* [10] */ { INVALID
, INVALID
,
876 /* [14] */ INVALID
, INVALID
,
878 /* [18] */ INVALID
, INVALID
,
880 /* [1C] */ {"pf2iw",TERM
,AMD3DNOW
,0}, {"pf2id",TERM
,AMD3DNOW
,0},
882 /* [20] */ { INVALID
, INVALID
,
884 /* [24] */ INVALID
, INVALID
,
886 /* [28] */ INVALID
, INVALID
,
888 /* [2C] */ INVALID
, INVALID
,
890 /* [30] */ { INVALID
, INVALID
,
892 /* [34] */ INVALID
, INVALID
,
894 /* [38] */ INVALID
, INVALID
,
896 /* [3C] */ INVALID
, INVALID
,
898 /* [40] */ { INVALID
, INVALID
,
900 /* [44] */ INVALID
, INVALID
,
902 /* [48] */ INVALID
, INVALID
,
904 /* [4C] */ INVALID
, INVALID
,
906 /* [50] */ { INVALID
, INVALID
,
908 /* [54] */ INVALID
, INVALID
,
910 /* [58] */ INVALID
, INVALID
,
912 /* [5C] */ INVALID
, INVALID
,
914 /* [60] */ { INVALID
, INVALID
,
916 /* [64] */ INVALID
, INVALID
,
918 /* [68] */ INVALID
, INVALID
,
920 /* [6C] */ INVALID
, INVALID
,
922 /* [70] */ { INVALID
, INVALID
,
924 /* [74] */ INVALID
, INVALID
,
926 /* [78] */ INVALID
, INVALID
,
928 /* [7C] */ INVALID
, INVALID
,
930 /* [80] */ { INVALID
, INVALID
,
932 /* [84] */ INVALID
, INVALID
,
934 /* [88] */ INVALID
, INVALID
,
935 {"pfnacc",TERM
,AMD3DNOW
,0}, INVALID
,
936 /* [8C] */ INVALID
, INVALID
,
937 {"pfpnacc",TERM
,AMD3DNOW
,0}, INVALID
},
938 /* [90] */ { {"pfcmpge",TERM
,AMD3DNOW
,0}, INVALID
,
940 /* [94] */ {"pfmin",TERM
,AMD3DNOW
,0}, INVALID
,
941 {"pfrcp",TERM
,AMD3DNOW
,0}, {"pfrsqrt",TERM
,AMD3DNOW
,0},
942 /* [98] */ INVALID
, INVALID
,
943 {"pfsub",TERM
,AMD3DNOW
,0}, INVALID
,
944 /* [9C] */ INVALID
, INVALID
,
945 {"pfadd",TERM
,AMD3DNOW
,0}, INVALID
},
946 /* [A0] */ { {"pfcmpgt",TERM
,AMD3DNOW
,0}, INVALID
,
948 /* [A4] */ {"pfmax",TERM
,AMD3DNOW
,0}, INVALID
,
949 {"pfrcpit1",TERM
,AMD3DNOW
,0}, {"pfrsqit1",TERM
,AMD3DNOW
,0},
950 /* [A8] */ INVALID
, INVALID
,
951 {"pfsubr",TERM
,AMD3DNOW
,0}, INVALID
,
952 /* [AC] */ INVALID
, INVALID
,
953 {"pfacc",TERM
,AMD3DNOW
,0}, INVALID
},
954 /* [B0] */ { {"pfcmpeq",TERM
,AMD3DNOW
,0}, INVALID
,
956 /* [B4] */ {"pfmul",TERM
,AMD3DNOW
,0}, INVALID
,
957 {"pfrcpit2",TERM
,AMD3DNOW
,0}, {"pmulhrw",TERM
,AMD3DNOW
,0},
958 /* [B8] */ INVALID
, INVALID
,
959 INVALID
, {"pswapd",TERM
,AMD3DNOW
,0},
960 /* [BC] */ INVALID
, INVALID
,
961 INVALID
, {"pavgusb",TERM
,AMD3DNOW
,0} },
962 /* [C0] */ { INVALID
, INVALID
,
964 /* [C4] */ INVALID
, INVALID
,
966 /* [C8] */ INVALID
, INVALID
,
968 /* [CC] */ INVALID
, INVALID
,
970 /* [D0] */ { INVALID
, INVALID
,
972 /* [D4] */ INVALID
, INVALID
,
974 /* [D8] */ INVALID
, INVALID
,
976 /* [DC] */ INVALID
, INVALID
,
978 /* [E0] */ { INVALID
, INVALID
,
980 /* [E4] */ INVALID
, INVALID
,
982 /* [E8] */ INVALID
, INVALID
,
984 /* [EC] */ INVALID
, INVALID
,
986 /* [F0] */ { INVALID
, INVALID
,
988 /* [F4] */ INVALID
, INVALID
,
990 /* [F8] */ INVALID
, INVALID
,
992 /* [FC] */ INVALID
, INVALID
,
997 * Decode table for 0x0FBA opcodes
999 static const struct instable op0FBA
[8] = {
1000 /* [0] */ INVALID
, INVALID
,
1002 /* [4] */ {"bt",TERM
,MIb
,1}, {"bts",TERM
,MIb
,1},
1003 {"btr",TERM
,MIb
,1}, {"btc",TERM
,MIb
,1},
1007 * Decode table for 0x0FAE opcodes
1009 static const struct instable op0FAE
[8] = {
1010 /* [0] */ {"fxsave",TERM
,M
,0}, {"fxrstor",TERM
,M
,0},
1011 {"ldmxcsr",TERM
,M
,0}, {"stmxcsr",TERM
,M
,0},
1012 /* [4] */ INVALID
, {"lfence",TERM
,GO_ON
,0},
1013 {"mfence",TERM
,GO_ON
,0},{"clflush",TERM
,SFEN
,0},
1017 * Decode table for 0x0F opcodes
1019 static const struct instable op0F
[16][16] = {
1020 /* [00] */ { {"",op0F00
,TERM
,0}, {"",op0F01
,TERM
,0},
1021 {"lar",TERM
,MR
,0}, {"lsl",TERM
,MR
,0},
1022 /* [04] */ INVALID
, {INVALID_32
,&op_syscall
},
1023 {"clts",TERM
,GO_ON
,0}, {INVALID_32
,&op_sysret
},
1024 /* [08] */ {"invd",TERM
,GO_ON
,0}, {"wbinvd",TERM
,GO_ON
,0},
1025 INVALID
, {"ud2",TERM
,GO_ON
,0},
1026 /* [0C] */ INVALID
, {"prefetch",TERM
,PFCH3DNOW
,1},
1027 {"femms",TERM
,GO_ON
,0},
1028 {"",(const struct instable
*)op0F0F
,TERM
,0} },
1029 /* [10] */ { {"mov",TERM
,SSE2
,0}, {"mov",TERM
,SSE2tm
,0},
1030 {"mov",TERM
,SSE2
,0}, {"movl",TERM
,SSE2tm
,0},
1031 /* [14] */ {"unpckl",TERM
,SSE2
,0}, {"unpckh",TERM
,SSE2
,0},
1032 {"mov",TERM
,SSE2
,0}, {"movh",TERM
,SSE2tm
,0},
1033 /* [18] */ {"prefetch",TERM
,PFCH
,1},INVALID
,
1035 /* [1C] */ INVALID
, INVALID
,
1036 INVALID
, {"nop",TERM
,M
,1} },
1037 /* [20] */ { {"mov",TERM
,SREG
,0x03}, {"mov",TERM
,SREG
,0x03},
1038 {"mov",TERM
,SREG
,0x03}, {"mov",TERM
,SREG
,0x03},
1039 /* [24] */ {"mov",TERM
,SREG
,0x03}, INVALID
,
1040 {"mov",TERM
,SREG
,0x03}, INVALID
,
1041 /* [28] */ {"mova",TERM
,SSE2
,0}, {"mova",TERM
,SSE2tm
,0},
1042 {"cvt",TERM
,SSE2
,0}, {"movnt",TERM
,SSE2tm
,0},
1043 /* [2C] */ {"cvt",TERM
,SSE2
,0}, {"cvt",TERM
,SSE2
,0} ,
1044 {"ucomi",TERM
,SSE2
,0}, {"comi",TERM
,SSE2
,0} },
1045 /* [30] */ { {"wrmsr",TERM
,GO_ON
,0}, {"rdtsc",TERM
,GO_ON
,0},
1046 {"rdmsr",TERM
,GO_ON
,0}, {"rdpmc",TERM
,GO_ON
,0},
1047 /* [34] */ {"sysenter",TERM
,GO_ON
,0},{"sysexit",TERM
,GO_ON
,0},
1049 /* [38] */ {"",op0F38
,TERM
,0}, INVALID
,
1050 {"",op0F3A
,TERM
,0}, INVALID
,
1051 /* [3C] */ INVALID
, INVALID
,
1053 /* [40] */ { {"cmovo",TERM
,MRw
,1}, {"cmovno",TERM
,MRw
,1},
1054 {"cmovb",TERM
,MRw
,1}, {"cmovae",TERM
,MRw
,1},
1055 /* [44] */ {"cmove",TERM
,MRw
,1}, {"cmovne",TERM
,MRw
,1},
1056 {"cmovbe",TERM
,MRw
,1}, {"cmova",TERM
,MRw
,1},
1057 /* [48] */ {"cmovs",TERM
,MRw
,1}, {"cmovns",TERM
,MRw
,1},
1058 {"cmovp",TERM
,MRw
,1}, {"cmovnp",TERM
,MRw
,1},
1059 /* [4C] */ {"cmovl",TERM
,MRw
,1}, {"cmovge",TERM
,MRw
,1},
1060 {"cmovle",TERM
,MRw
,1}, {"cmovg",TERM
,MRw
,1} },
1061 /* [50] */ { {"movmsk",TERM
,SSE2
,0}, {"sqrt",TERM
,SSE2
,0},
1062 {"rsqrt",TERM
,SSE2
,0}, {"rcp",TERM
,SSE2
,0},
1063 /* [54] */ {"and",TERM
,SSE2
,0}, {"andn",TERM
,SSE2
,0},
1064 {"or",TERM
,SSE2
,0}, {"xor",TERM
,SSE2
,0},
1065 /* [58] */ {"add",TERM
,SSE2
,0}, {"mul",TERM
,SSE2
,0},
1066 {"cvt",TERM
,SSE2
,0}, {"cvt",TERM
,SSE2
,0},
1067 /* [5C] */ {"sub",TERM
,SSE2
,0}, {"min",TERM
,SSE2
,0},
1068 {"div",TERM
,SSE2
,0}, {"max",TERM
,SSE2
,0} },
1069 /* [60] */ { {"punpcklbw",TERM
,SSE2
,0},{"punpcklwd",TERM
,SSE2
,0},
1070 {"punpckldq",TERM
,SSE2
,0},{"packsswb",TERM
,SSE2
,0},
1071 /* [64] */ {"pcmpgtb",TERM
,SSE2
,0},{"pcmpgtw",TERM
,SSE2
,0},
1072 {"pcmpgtd",TERM
,SSE2
,0},{"packuswb",TERM
,SSE2
,0},
1073 /* [68] */ {"punpckhbw",TERM
,SSE2
,0},{"punpckhwd",TERM
,SSE2
,0},
1074 {"punpckhdq",TERM
,SSE2
,0},{"packssdw",TERM
,SSE2
,0},
1075 /* [6C] */ {"punpckl",TERM
,SSE2
,0},{"punpckh",TERM
,SSE2
,0},
1076 {"movd",TERM
,SSE2
,0}, {"mov",TERM
,SSE2
,0} },
1077 /* [70] */ { {"pshu",TERM
,SSE2i
,0}, {"ps",TERM
,SSE2i1
,0},
1078 {"ps",TERM
,SSE2i1
,0}, {"ps",TERM
,SSE2i1
,0},
1079 /* [74] */ {"pcmpeqb",TERM
,SSE2
,0},{"pcmpeqw",TERM
,SSE2
,0},
1080 {"pcmpeqd",TERM
,SSE2
,0},{"emms",TERM
,GO_ON
,0},
1081 /* [78] */ {"vmread",TERM
,RMw
,0}, {"vmwrite",TERM
,MRw
,0},
1083 /* [7C] */ {"haddp",TERM
,SSE2
,0}, {"hsubp",TERM
,SSE2
,0},
1084 {"mov",TERM
,SSE2tfm
,0}, {"mov",TERM
,SSE2tm
,0} },
1085 /* [80] */ { {"jo",TERM
,D
,0x02}, {"jno",TERM
,D
,0x02},
1086 {"jb",TERM
,D
,0x02}, {"jae",TERM
,D
,0x02},
1087 /* [84] */ {"je",TERM
,D
,0x02}, {"jne",TERM
,D
,0x02},
1088 {"jbe",TERM
,D
,0x02}, {"ja",TERM
,D
,0x02},
1089 /* [88] */ {"js",TERM
,D
,0x02}, {"jns",TERM
,D
,0x02},
1090 {"jp",TERM
,D
,0x02}, {"jnp",TERM
,D
,0x02},
1091 /* [8C] */ {"jl",TERM
,D
,0x02}, {"jge",TERM
,D
,0x02},
1092 {"jle",TERM
,D
,0x02}, {"jg",TERM
,D
,0x02} },
1093 /* [90] */ { {"seto",TERM
,Mb
,0}, {"setno",TERM
,Mb
,0},
1094 {"setb",TERM
,Mb
,0}, {"setae",TERM
,Mb
,0},
1095 /* [94] */ {"sete",TERM
,Mb
,0}, {"setne",TERM
,Mb
,0},
1096 {"setbe",TERM
,Mb
,0}, {"seta",TERM
,Mb
,0},
1097 /* [98] */ {"sets",TERM
,Mb
,0}, {"setns",TERM
,Mb
,0},
1098 {"setp",TERM
,Mb
,0}, {"setnp",TERM
,Mb
,0},
1099 /* [9C] */ {"setl",TERM
,Mb
,0}, {"setge",TERM
,Mb
,0},
1100 {"setle",TERM
,Mb
,0}, {"setg",TERM
,Mb
,0} },
1101 /* [A0] */ { {"push",TERM
,LSEG
,0x03},{"pop",TERM
,LSEG
,0x03},
1102 {"cpuid",TERM
,GO_ON
,0}, {"bt",TERM
,RMw
,1},
1103 /* [A4] */ {"shld",TERM
,DSHIFT
,1}, {"shld",TERM
,DSHIFTcl
,1},
1105 /* [A8] */ {"push",TERM
,LSEG
,0x03},{"pop",TERM
,LSEG
,0x03},
1106 {"rsm",TERM
,GO_ON
,0, INVALID_64
}, {"bts",TERM
,RMw
,1},
1107 /* [AC] */ {"shrd",TERM
,DSHIFT
,1}, {"shrd",TERM
,DSHIFTcl
,1},
1108 {"",op0FAE
,TERM
,0}, {"imul",TERM
,MRw
,1} },
1109 /* [B0] */ { {"cmpxchgb",TERM
,XINST
,0},{"cmpxchg",TERM
,XINST
,1},
1110 {"lss",TERM
,MR
,0}, {"btr",TERM
,RMw
,1},
1111 /* [B4] */ {"lfs",TERM
,MR
,0}, {"lgs",TERM
,MR
,0},
1112 {"movzb",TERM
,MOVZ
,1}, {"movzw",TERM
,MOVZ
,1},
1113 /* [B8] */ {"popcnt",TERM
,SSE4MRw
,0}, INVALID
,
1114 {"",op0FBA
,TERM
,0}, {"btc",TERM
,RMw
,1},
1115 /* [BC] */ {"bsf",TERM
,MRw
,1}, {"bsr",TERM
,MRw
,1},
1116 {"movsb",TERM
,MOVZ
,1}, {"movsw",TERM
,MOVZ
,1} },
1117 /* [C0] */ { {"xaddb",TERM
,XINST
,0}, {"xadd",TERM
,XINST
,1},
1118 {"cmp",TERM
,SSE2i
,0}, {"movnti",TERM
,RMw
,0},
1119 /* [C4] */ {"pinsrw",TERM
,SSE2i
,0},{"pextrw",TERM
,SSE2i
,0},
1120 {"shuf",TERM
,SSE2i
,0}, {"cmpxchg8b",TERM
,M
,0},
1121 /* [C8] */ {"bswap",TERM
,BSWAP
,0}, {"bswap",TERM
,BSWAP
,0},
1122 {"bswap",TERM
,BSWAP
,0}, {"bswap",TERM
,BSWAP
,0},
1123 /* [CC] */ {"bswap",TERM
,BSWAP
,0}, {"bswap",TERM
,BSWAP
,0},
1124 {"bswap",TERM
,BSWAP
,0}, {"bswap",TERM
,BSWAP
,0} },
1125 /* [D0] */ { {"addsubp",TERM
,SSE2
,0},{"psrlw",TERM
,SSE2
,0},
1126 {"psrld",TERM
,SSE2
,0}, {"psrlq",TERM
,SSE2
,0},
1127 /* [D4] */ {"paddq",TERM
,SSE2
,0}, {"pmullw",TERM
,SSE2
,0},
1128 {"mov",TERM
,SSE2tm
,0}, {"pmovmskb",TERM
,SSE2
,0},
1129 /* [D8] */ {"psubusb",TERM
,SSE2
,0},{"psubusw",TERM
,SSE2
,0},
1130 {"pminub",TERM
,SSE2
,0}, {"pand",TERM
,SSE2
,0},
1131 /* [DC] */ {"paddusb",TERM
,SSE2
,0},{"paddusw",TERM
,SSE2
,0},
1132 {"pmaxub",TERM
,SSE2
,0}, {"pandn",TERM
,SSE2
,0} },
1133 /* [E0] */ { {"pavgb",TERM
,SSE2
,0}, {"psraw",TERM
,SSE2
,0},
1134 {"psrad",TERM
,SSE2
,0}, {"pavgw",TERM
,SSE2
,0},
1135 /* [E4] */ {"pmulhuw",TERM
,SSE2
,0},{"pmulhw",TERM
,SSE2
,0},
1136 {"cvt",TERM
,SSE2
,0}, {"movn",TERM
,SSE2tm
,0},
1137 /* [E8] */ {"psubsb",TERM
,SSE2
,0}, {"psubsw",TERM
,SSE2
,0},
1138 {"pminsw",TERM
,SSE2
,0}, {"por",TERM
,SSE2
,0},
1139 /* [EC] */ {"paddsb",TERM
,SSE2
,0}, {"paddsw",TERM
,SSE2
,0},
1140 {"pmaxsw",TERM
,SSE2
,0}, {"pxor",TERM
,SSE2
,0} },
1141 /* [F0] */ { {"lddqu",TERM
,SSE2
,0}, {"psllw",TERM
,SSE2
,0},
1142 {"pslld",TERM
,SSE2
,0}, {"psllq",TERM
,SSE2
,0},
1143 /* [F4] */ {"pmuludq",TERM
,SSE2
,0},{"pmaddwd",TERM
,SSE2
,0},
1144 {"psadbw",TERM
,SSE2
,0}, {"maskmov",TERM
,SSE2
,0},
1145 /* [F8] */ {"psubb",TERM
,SSE2
,0}, {"psubw",TERM
,SSE2
,0},
1146 {"psubd",TERM
,SSE2
,0}, {"psubq",TERM
,SSE2
,0},
1147 /* [FC] */ {"paddb",TERM
,SSE2
,0}, {"paddw",TERM
,SSE2
,0},
1148 {"paddd",TERM
,SSE2
,0}, INVALID
},
1152 * Decode table for 0x80 opcodes
1154 static const struct instable op80
[8] = {
1155 /* [0] */ {"addb",TERM
,IMlw
,0}, {"orb",TERM
,IMw
,0},
1156 {"adcb",TERM
,IMlw
,0}, {"sbbb",TERM
,IMlw
,0},
1157 /* [4] */ {"andb",TERM
,IMw
,0}, {"subb",TERM
,IMlw
,0},
1158 {"xorb",TERM
,IMw
,0}, {"cmpb",TERM
,IMlw
,0},
1162 * Decode table for 0x81 opcodes.
1164 static const struct instable op81
[8] = {
1165 /* [0] */ {"add",TERM
,IMlw
,1}, {"or",TERM
,IMw
,1},
1166 {"adc",TERM
,IMlw
,1}, {"sbb",TERM
,IMlw
,1},
1167 /* [4] */ {"and",TERM
,IMw
,1}, {"sub",TERM
,IMlw
,1},
1168 {"xor",TERM
,IMw
,1}, {"cmp",TERM
,IMlw
,1},
1172 * Decode table for 0x82 opcodes.
1174 static const struct instable op82
[8] = {
1175 /* [0] */ {"addb",TERM
,IMlw
,0}, INVALID
,
1176 {"adcb",TERM
,IMlw
,0}, {"sbbb",TERM
,IMlw
,0},
1177 /* [4] */ INVALID
, {"subb",TERM
,IMlw
,0},
1178 INVALID
, {"cmpb",TERM
,IMlw
,0},
1182 * Decode table for 0x83 opcodes.
1184 static const struct instable op83
[8] = {
1185 /* [0] */ {"add",TERM
,IMlw
,1}, {"or",TERM
,IMlw
,1},
1186 {"adc",TERM
,IMlw
,1}, {"sbb",TERM
,IMlw
,1},
1187 /* [4] */ {"and",TERM
,IMlw
,1}, {"sub",TERM
,IMlw
,1},
1188 {"xor",TERM
,IMlw
,1}, {"cmp",TERM
,IMlw
,1},
1192 * Decode table for 0xC0 opcodes.
1194 static const struct instable opC0
[8] = {
1195 /* [0] */ {"rolb",TERM
,MvI
,0}, {"rorb",TERM
,MvI
,0},
1196 {"rclb",TERM
,MvI
,0}, {"rcrb",TERM
,MvI
,0},
1197 /* [4] */ {"shlb",TERM
,MvI
,0}, {"shrb",TERM
,MvI
,0},
1198 INVALID
, {"sarb",TERM
,MvI
,0},
1202 * Decode table for 0xD0 opcodes.
1204 static const struct instable opD0
[8] = {
1205 /* [0] */ {"rolb",TERM
,Mv
,0}, {"rorb",TERM
,Mv
,0},
1206 {"rclb",TERM
,Mv
,0}, {"rcrb",TERM
,Mv
,0},
1207 /* [4] */ {"shlb",TERM
,Mv
,0}, {"shrb",TERM
,Mv
,0},
1208 INVALID
, {"sarb",TERM
,Mv
,0},
1212 * Decode table for 0xC1 opcodes.
1213 * 186 instruction set
1215 static const struct instable opC1
[8] = {
1216 /* [0] */ {"rol",TERM
,MvI
,1}, {"ror",TERM
,MvI
,1},
1217 {"rcl",TERM
,MvI
,1}, {"rcr",TERM
,MvI
,1},
1218 /* [4] */ {"shl",TERM
,MvI
,1}, {"shr",TERM
,MvI
,1},
1219 INVALID
, {"sar",TERM
,MvI
,1},
1223 * Decode table for 0xD1 opcodes.
1225 static const struct instable opD1
[8] = {
1226 /* [0] */ {"rol",TERM
,Mv
,1}, {"ror",TERM
,Mv
,1},
1227 {"rcl",TERM
,Mv
,1}, {"rcr",TERM
,Mv
,1},
1228 /* [4] */ {"shl",TERM
,Mv
,1}, {"shr",TERM
,Mv
,1},
1229 INVALID
, {"sar",TERM
,Mv
,1},
1233 * Decode table for 0xD2 opcodes.
1235 static const struct instable opD2
[8] = {
1236 /* [0] */ {"rolb",TERM
,Mv
,0}, {"rorb",TERM
,Mv
,0},
1237 {"rclb",TERM
,Mv
,0}, {"rcrb",TERM
,Mv
,0},
1238 /* [4] */ {"shlb",TERM
,Mv
,0}, {"shrb",TERM
,Mv
,0},
1239 INVALID
, {"sarb",TERM
,Mv
,0},
1243 * Decode table for 0xD3 opcodes.
1245 static const struct instable opD3
[8] = {
1246 /* [0] */ {"rol",TERM
,Mv
,1}, {"ror",TERM
,Mv
,1},
1247 {"rcl",TERM
,Mv
,1}, {"rcr",TERM
,Mv
,1},
1248 /* [4] */ {"shl",TERM
,Mv
,1}, {"shr",TERM
,Mv
,1},
1249 INVALID
, {"sar",TERM
,Mv
,1},
1253 * Decode table for 0xF6 opcodes.
1255 static const struct instable opF6
[8] = {
1256 /* [0] */ {"testb",TERM
,IMw
,0}, INVALID
,
1257 {"notb",TERM
,Mw
,0}, {"negb",TERM
,Mw
,0},
1258 /* [4] */ {"mulb",TERM
,MA
,0}, {"imulb",TERM
,MA
,0},
1259 {"divb",TERM
,MA
,0}, {"idivb",TERM
,MA
,0},
1263 * Decode table for 0xF7 opcodes.
1265 static const struct instable opF7
[8] = {
1266 /* [0] */ {"test",TERM
,IMw
,1}, INVALID
,
1267 {"not",TERM
,Mw
,1}, {"neg",TERM
,Mw
,1},
1268 /* [4] */ {"mul",TERM
,MA
,1}, {"imul",TERM
,MA
,1},
1269 {"div",TERM
,MA
,1}, {"idiv",TERM
,MA
,1},
1273 * Decode table for 0xFE opcodes.
1275 static const struct instable opFE
[8] = {
1276 /* [0] */ {"incb",TERM
,Mw
,0}, {"decb",TERM
,Mw
,0},
1278 /* [4] */ INVALID
, INVALID
,
1283 * Decode table for 0xFF opcodes.
1285 static const struct instable opFF
[8] = {
1286 /* [0] */ {"inc",TERM
,Mw
,1}, {"dec",TERM
,Mw
,1},
1287 {"call",TERM
,INM
,1}, {"lcall",TERM
,INMl
,1},
1288 /* [4] */ {"jmp",TERM
,INM
,1}, {"ljmp",TERM
,INMl
,1},
1289 {"push",TERM
,M
,0x03}, INVALID
,
1292 /* for 287 instructions, which are a mess to decode */
1293 static const struct instable opFP1n2
[8][8] = {
1294 /* bit pattern: 1101 1xxx MODxx xR/M */
1295 /* [0,0] */ { {"fadds",TERM
,M
,0}, {"fmuls",TERM
,M
,0},
1296 {"fcoms",TERM
,M
,0}, {"fcomps",TERM
,M
,0},
1297 /* [0,4] */ {"fsubs",TERM
,M
,0}, {"fsubrs",TERM
,M
,0},
1298 {"fdivs",TERM
,M
,0}, {"fdivrs",TERM
,M
,0} },
1299 /* [1,0] */ { {"flds",TERM
,M
,0}, INVALID
,
1300 {"fsts",TERM
,M
,0}, {"fstps",TERM
,M
,0},
1301 /* [1,4] */ {"fldenv",TERM
,M
,1}, {"fldcw",TERM
,M
,0},
1302 {"fnstenv",TERM
,M
,1}, {"fnstcw",TERM
,M
,0} },
1303 /* [2,0] */ { {"fiaddl",TERM
,M
,0}, {"fimull",TERM
,M
,0},
1304 {"ficoml",TERM
,M
,0}, {"ficompl",TERM
,M
,0},
1305 /* [2,4] */ {"fisubl",TERM
,M
,0}, {"fisubrl",TERM
,M
,0},
1306 {"fidivl",TERM
,M
,0}, {"fidivrl",TERM
,M
,0} },
1307 /* [3,0] */ { {"fildl",TERM
,Mnol
,0}, {"fisttpl",TERM
,M
,0},
1308 {"fistl",TERM
,M
,0}, {"fistpl",TERM
,Mnol
,0},
1309 /* [3,4] */ INVALID
, {"fldt",TERM
,M
,0},
1310 INVALID
, {"fstpt",TERM
,M
,0} },
1311 /* [4,0] */ { {"faddl",TERM
,M
,0}, {"fmull",TERM
,M
,0},
1312 {"fcoml",TERM
,M
,0}, {"fcompl",TERM
,M
,0},
1313 /* [4,1] */ {"fsubl",TERM
,M
,0}, {"fsubrl",TERM
,M
,0},
1314 {"fdivl",TERM
,M
,0}, {"fdivrl",TERM
,M
,0} },
1315 /* [5,0] */ { {"fldl",TERM
,M
,0}, {"fisttpll",TERM
,M
,0},
1316 {"fstl",TERM
,M
,0}, {"fstpl",TERM
,M
,0},
1317 /* [5,4] */ {"frstor",TERM
,M
,1}, INVALID
,
1318 {"fnsave",TERM
,M
,1}, {"fnstsw",TERM
,M
,0} },
1319 /* [6,0] */ { {"fiadds",TERM
,M
,0}, {"fimuls",TERM
,M
,0},
1320 {"ficoms",TERM
,M
,0}, {"ficomps",TERM
,M
,0},
1321 /* [6,4] */ {"fisubs",TERM
,M
,0}, {"fisubrs",TERM
,M
,0},
1322 {"fidivs",TERM
,M
,0}, {"fidivrs",TERM
,M
,0} },
1323 /* [7,0] */ { {"filds",TERM
,M
,0}, {"fisttps",TERM
,M
,0},
1324 {"fists",TERM
,M
,0}, {"fistps",TERM
,M
,0},
1325 /* [7,4] */ {"fbld",TERM
,M
,0}, {"fildq",TERM
,M
,0},
1326 {"fbstp",TERM
,M
,0}, {"fistpq",TERM
,M
,0} },
1329 static const struct instable opFP3
[8][8] = {
1330 /* bit pattern: 1101 1xxx 11xx xREG */
1331 /* [0,0] */ { {"fadd",TERM
,FF
,0}, {"fmul",TERM
,FF
,0},
1332 {"fcom",TERM
,F
,0}, {"fcomp",TERM
,F
,0},
1333 /* [0,4] */ {"fsub",TERM
,FF
,0}, {"fsubr",TERM
,FF
,0},
1334 {"fdiv",TERM
,FF
,0}, {"fdivr",TERM
,FF
,0} },
1335 /* [1,0] */ { {"fld",TERM
,F
,0}, {"fxch",TERM
,F
,0},
1336 {"fnop",TERM
,GO_ON
,0}, {"fstp",TERM
,F
,0},
1337 /* [1,4] */ INVALID
, INVALID
,
1339 /* [2,0] */ { {"fcmovb",TERM
,FF
,0}, {"fcmove",TERM
,FF
,0},
1340 {"fcmovbe",TERM
,FF
,0}, {"fcmovu",TERM
,FF
,0},
1341 /* [2,4] */ INVALID
, {"fucompp",TERM
,GO_ON
,0},
1343 /* [3,0] */ { {"fcmovnb",TERM
,FF
,0}, {"fcmovne",TERM
,FF
,0},
1344 {"fcmovnbe",TERM
,FF
,0}, {"fcmovnu",TERM
,FF
,0},
1345 /* [3,4] */ INVALID
, {"fucomi",TERM
,FF
,0},
1346 {"fcomi",TERM
,FF
,0}, INVALID
},
1347 /* [4,0] */ { {"fadd",TERM
,FF
,0}, {"fmul",TERM
,FF
,0},
1348 {"fcom",TERM
,F
,0}, {"fcomp",TERM
,F
,0},
1349 /* [4,4] */ {"fsub",TERM
,FF
,0}, {"fsubr",TERM
,FF
,0},
1350 {"fdiv",TERM
,FF
,0}, {"fdivr",TERM
,FF
,0} },
1351 /* [5,0] */ { {"ffree",TERM
,F
,0}, {"fxch",TERM
,F
,0},
1352 {"fst",TERM
,F
,0}, {"fstp",TERM
,F
,0},
1353 /* [5,4] */ {"fucom",TERM
,F
,0}, {"fucomp",TERM
,F
,0},
1355 /* [6,0] */ { {"faddp",TERM
,FF
,0}, {"fmulp",TERM
,FF
,0},
1356 {"fcomp",TERM
,F
,0}, {"fcompp",TERM
,GO_ON
,0},
1357 /* [6,4] */ {"fsubp",TERM
,FF
,0}, {"fsubrp",TERM
,FF
,0},
1358 {"fdivp",TERM
,FF
,0}, {"fdivrp",TERM
,FF
,0} },
1359 /* [7,0] */ { {"ffreep",TERM
,F
,0}, {"fxch",TERM
,F
,0},
1360 {"fstp",TERM
,F
,0}, {"fstp",TERM
,F
,0},
1361 /* [7,4] */ {"fnstsw",TERM
,M
,0}, {"fucomip",TERM
,FF
,0},
1362 {"fcomip",TERM
,FF
,0}, INVALID
},
1365 static const struct instable opFP4
[4][8] = {
1366 /* bit pattern: 1101 1001 111x xxxx */
1367 /* [0,0] */ { {"fchs",TERM
,GO_ON
,0}, {"fabs",TERM
,GO_ON
,0},
1369 /* [0,4] */ {"ftst",TERM
,GO_ON
,0}, {"fxam",TERM
,GO_ON
,0},
1371 /* [1,0] */ { {"fld1",TERM
,GO_ON
,0}, {"fldl2t",TERM
,GO_ON
,0},
1372 {"fldl2e",TERM
,GO_ON
,0},{"fldpi",TERM
,GO_ON
,0},
1373 /* [1,4] */ {"fldlg2",TERM
,GO_ON
,0},{"fldln2",TERM
,GO_ON
,0},
1374 {"fldz",TERM
,GO_ON
,0}, INVALID
},
1375 /* [2,0] */ { {"f2xm1",TERM
,GO_ON
,0}, {"fyl2x",TERM
,GO_ON
,0},
1376 {"fptan",TERM
,GO_ON
,0}, {"fpatan",TERM
,GO_ON
,0},
1377 /* [2,4] */ {"fxtract",TERM
,GO_ON
,0},{"fprem1",TERM
,GO_ON
,0},
1378 {"fdecstp",TERM
,GO_ON
,0},{"fincstp",TERM
,GO_ON
,0} },
1379 /* [3,0] */ { {"fprem",TERM
,GO_ON
,0}, {"fyl2xp1",TERM
,GO_ON
,0},
1380 {"fsqrt",TERM
,GO_ON
,0}, {"fsincos",TERM
,GO_ON
,0},
1381 /* [3,4] */ {"frndint",TERM
,GO_ON
,0},{"fscale",TERM
,GO_ON
,0},
1382 {"fsin",TERM
,GO_ON
,0}, {"fcos",TERM
,GO_ON
,0} },
1385 static const struct instable opFP5
[8] = {
1386 /* bit pattern: 1101 1011 1110 0xxx */
1387 /* [0] */ INVALID
, INVALID
,
1388 {"fnclex",TERM
,GO_ON
,0},{"fninit",TERM
,GO_ON
,0},
1389 /* [4] */ {"fsetpm",TERM
,GO_ON
,0},INVALID
,
1394 * Main decode table for the op codes. The first two nibbles
1395 * will be used as an index into the table. If there is a
1396 * a need to further decode an instruction, the array to be
1397 * referenced is indicated with the other two entries being
1400 static const struct instable distable
[16][16] = {
1401 /* [0,0] */ { {"addb",TERM
,RMw
,0}, {"add",TERM
,RMw
,1},
1402 {"addb",TERM
,MRw
,0}, {"add",TERM
,MRw
,1},
1403 /* [0,4] */ {"addb",TERM
,IA
,0}, {"add",TERM
,IA
,1},
1404 {"push",TERM
,SEG
,0x03,INVALID_64
},
1405 {"pop",TERM
,SEG
,0x03,INVALID_64
},
1406 /* [0,8] */ {"orb",TERM
,RMw
,0}, {"or",TERM
,RMw
,1},
1407 {"orb",TERM
,MRw
,0}, {"or",TERM
,MRw
,1},
1408 /* [0,C] */ {"orb",TERM
,IA
,0}, {"or",TERM
,IA
,1},
1409 {"push",TERM
,SEG
,0x03,INVALID_64
},
1410 {"",(const struct instable
*)op0F
,TERM
,0} },
1411 /* [1,0] */ { {"adcb",TERM
,RMw
,0}, {"adc",TERM
,RMw
,1},
1412 {"adcb",TERM
,MRw
,0}, {"adc",TERM
,MRw
,1},
1413 /* [1,4] */ {"adcb",TERM
,IA
,0}, {"adc",TERM
,IA
,1},
1414 {"push",TERM
,SEG
,0x03,INVALID_64
},
1415 {"pop",TERM
,SEG
,0x03,INVALID_64
},
1416 /* [1,8] */ {"sbbb",TERM
,RMw
,0}, {"sbb",TERM
,RMw
,1},
1417 {"sbbb",TERM
,MRw
,0}, {"sbb",TERM
,MRw
,1},
1418 /* [1,C] */ {"sbbb",TERM
,IA
,0}, {"sbb",TERM
,IA
,1},
1419 {"push",TERM
,SEG
,0x03,INVALID_64
},
1420 {"pop",TERM
,SEG
,0x03,INVALID_64
} },
1421 /* [2,0] */ { {"andb",TERM
,RMw
,0}, {"and",TERM
,RMw
,1},
1422 {"andb",TERM
,MRw
,0}, {"and",TERM
,MRw
,1},
1423 /* [2,4] */ {"andb",TERM
,IA
,0}, {"and",TERM
,IA
,1},
1424 {"%es:",TERM
,OVERRIDE
,0},
1425 {"daa",TERM
,GO_ON
,0,INVALID_64
},
1426 /* [2,8] */ {"subb",TERM
,RMw
,0}, {"sub",TERM
,RMw
,1},
1427 {"subb",TERM
,MRw
,0}, {"sub",TERM
,MRw
,1},
1428 /* [2,C] */ {"subb",TERM
,IA
,0}, {"sub",TERM
,IA
,1},
1429 {"%cs:",TERM
,OVERRIDE
,0},
1430 {"das",TERM
,GO_ON
,0,INVALID_64
} },
1431 /* [3,0] */ { {"xorb",TERM
,RMw
,0}, {"xor",TERM
,RMw
,1},
1432 {"xorb",TERM
,MRw
,0}, {"xor",TERM
,MRw
,1},
1433 /* [3,4] */ {"xorb",TERM
,IA
,0}, {"xor",TERM
,IA
,1},
1434 {"%ss:",TERM
,OVERRIDE
,0},
1435 {"aaa",TERM
,GO_ON
,0,INVALID_64
},
1436 /* [3,8] */ {"cmpb",TERM
,RMw
,0}, {"cmp",TERM
,RMw
,1},
1437 {"cmpb",TERM
,MRw
,0}, {"cmp",TERM
,MRw
,1},
1438 /* [3,C] */ {"cmpb",TERM
,IA
,0}, {"cmp",TERM
,IA
,1},
1439 {"%ds:",TERM
,OVERRIDE
,0},
1440 {"aas",TERM
,GO_ON
,0,INVALID_64
} },
1441 /* [4,0] */ { {"inc",TERM
,R
,1,&opREX
},{"inc",TERM
,R
,1,&opREX
},
1442 {"inc",TERM
,R
,1,&opREX
},{"inc",TERM
,R
,1,&opREX
},
1443 /* [4,4] */ {"inc",TERM
,R
,1,&opREX
},{"inc",TERM
,R
,1,&opREX
},
1444 {"inc",TERM
,R
,1,&opREX
},{"inc",TERM
,R
,1,&opREX
},
1445 /* [4,8] */ {"dec",TERM
,R
,1,&opREX
},{"dec",TERM
,R
,1,&opREX
},
1446 {"dec",TERM
,R
,1,&opREX
},{"dec",TERM
,R
,1,&opREX
},
1447 /* [4,C] */ {"dec",TERM
,R
,1,&opREX
},{"dec",TERM
,R
,1,&opREX
},
1448 {"dec",TERM
,R
,1,&opREX
},{"dec",TERM
,R
,1,&opREX
} },
1449 /* [5,0] */ { {"push",TERM
,R
,0x03}, {"push",TERM
,R
,0x03},
1450 {"push",TERM
,R
,0x03}, {"push",TERM
,R
,0x03},
1451 /* [5,4] */ {"push",TERM
,R
,0x03}, {"push",TERM
,R
,0x03},
1452 {"push",TERM
,R
,0x03}, {"push",TERM
,R
,0x03},
1453 /* [5,8] */ {"pop",TERM
,R
,0x03}, {"pop",TERM
,R
,0x03},
1454 {"pop",TERM
,R
,0x03}, {"pop",TERM
,R
,0x03},
1455 /* [5,C] */ {"pop",TERM
,R
,0x03}, {"pop",TERM
,R
,0x03},
1456 {"pop",TERM
,R
,0x03}, {"pop",TERM
,R
,0x03} },
1457 /* [6,0] */ { {"pusha",TERM
,GO_ON
,1,INVALID_64
},
1458 {"popa",TERM
,GO_ON
,1,INVALID_64
},
1459 {"bound",TERM
,MR
,0,INVALID_64
},
1460 {"arpl",TERM
,RMw
,0,&op_movsl
},
1461 /* [6,4] */ {"%fs:",TERM
,OVERRIDE
,0},
1462 {"%gs:",TERM
,OVERRIDE
,0},
1463 {"data16",TERM
,DM
,0}, {"addr16",TERM
,AM
,0},
1464 /* [6,8] */ {"push",TERM
,I
,0x03}, {"imul",TERM
,IMUL
,1},
1465 {"push",TERM
,Ib
,0x03}, {"imul",TERM
,IMUL
,1},
1466 /* [6,C] */ {"insb",TERM
,GO_ON
,0}, {"ins",TERM
,GO_ON
,1},
1467 {"outsb",TERM
,GO_ON
,0}, {"outs",TERM
,GO_ON
,1} },
1468 /* [7,0] */ { {"jo",TERM
,BD
,0}, {"jno",TERM
,BD
,0},
1469 {"jb",TERM
,BD
,0}, {"jae",TERM
,BD
,0},
1470 /* [7,4] */ {"je",TERM
,BD
,0}, {"jne",TERM
,BD
,0},
1471 {"jbe",TERM
,BD
,0}, {"ja",TERM
,BD
,0},
1472 /* [7,8] */ {"js",TERM
,BD
,0}, {"jns",TERM
,BD
,0},
1473 {"jp",TERM
,BD
,0}, {"jnp",TERM
,BD
,0},
1474 /* [7,C] */ {"jl",TERM
,BD
,0}, {"jge",TERM
,BD
,0},
1475 {"jle",TERM
,BD
,0}, {"jg",TERM
,BD
,0} },
1476 /* [8,0] */ { {"",op80
,TERM
,0}, {"",op81
,TERM
,0},
1477 {"",op82
,TERM
,0}, {"",op83
,TERM
,0},
1478 /* [8,4] */ {"testb",TERM
,MRw
,0}, {"test",TERM
,MRw
,1},
1479 {"xchgb",TERM
,MRw
,0}, {"xchg",TERM
,MRw
,1},
1480 /* [8,8] */ {"movb",TERM
,RMw
,0}, {"mov",TERM
,RMw
,1},
1481 {"movb",TERM
,MRw
,0}, {"mov",TERM
,MRw
,1},
1482 /* [8,C] */ {"mov",TERM
,SM
,1}, {"lea",TERM
,MR
,1},
1483 {"mov",TERM
,MS
,1}, {"pop",TERM
,M
,0x03} },
1484 /* [9,0] */ { {"nop",TERM
,GO_ON
,0}, {"xchg",TERM
,RA
,1},
1485 {"xchg",TERM
,RA
,1}, {"xchg",TERM
,RA
,1},
1486 /* [9,4] */ {"xchg",TERM
,RA
,1}, {"xchg",TERM
,RA
,0},
1487 {"xchg",TERM
,RA
,1}, {"xchg",TERM
,RA
,1},
1488 /* [9,8] */ {"",TERM
,CBW
,0}, {"",TERM
,CWD
,0},
1489 {"lcall",TERM
,SO
,0}, {"wait/",TERM
,PREFIX
,0},
1490 /* [9,C] */ {"pushf",TERM
,GO_ON
,0}, {"popf",TERM
,GO_ON
,0},
1491 {"sahf",TERM
,GO_ON
,0}, {"lahf",TERM
,GO_ON
,0} },
1492 /* [A,0] */ { {"movb",TERM
,OA
,0}, {"mov",TERM
,OA
,1},
1493 {"movb",TERM
,AO
,0}, {"mov",TERM
,AO
,1},
1494 /* [A,4] */ {"movsb",TERM
,SD
,0}, {"movs",TERM
,SD
,1},
1495 {"cmpsb",TERM
,SD
,0}, {"cmps",TERM
,SD
,1},
1496 /* [A,8] */ {"testb",TERM
,IA
,0}, {"test",TERM
,IA
,1},
1497 {"stosb",TERM
,AD
,0}, {"stos",TERM
,AD
,1},
1498 /* [A,C] */ {"lodsb",TERM
,SA
,0}, {"lods",TERM
,SA
,1},
1499 {"scasb",TERM
,AD
,0}, {"scas",TERM
,AD
,1} },
1500 /* [B,0] */ { {"movb",TERM
,IR
,0}, {"movb",TERM
,IR
,0},
1501 {"movb",TERM
,IR
,0}, {"movb",TERM
,IR
,0},
1502 /* [B,4] */ {"movb",TERM
,IR
,0}, {"movb",TERM
,IR
,0},
1503 {"movb",TERM
,IR
,0}, {"movb",TERM
,IR
,0},
1504 /* [B,8] */ {"mov",TERM
,IR64
,1}, {"mov",TERM
,IR64
,1},
1505 {"mov",TERM
,IR64
,1}, {"mov",TERM
,IR64
,1},
1506 /* [B,C] */ {"mov",TERM
,IR64
,1}, {"mov",TERM
,IR64
,1},
1507 {"mov",TERM
,IR64
,1}, {"mov",TERM
,IR64
,1} },
1508 /* [C,0] */ { {"",opC0
,TERM
,0}, {"",opC1
,TERM
,0},
1509 {"ret",TERM
,RET
,1}, {"ret",TERM
,GO_ON
,0},
1510 /* [C,4] */ {"les",TERM
,MR
,0,INVALID_64
},
1511 {"lds",TERM
,MR
,0,INVALID_64
},
1512 {"movb",TERM
,IMw
,0}, {"mov",TERM
,IMw
,1},
1513 /* [C,8] */ {"enter",TERM
,ENTER
,0}, {"leave",TERM
,GO_ON
,0},
1514 {"lret",TERM
,RET
,1}, {"lret",TERM
,GO_ON
,0},
1515 /* [C,C] */ {"int",TERM
,INT3
,0}, {"int",TERM
,Ib
,0},
1516 {"into",TERM
,GO_ON
,0,INVALID_64
},
1517 {"iret",TERM
,GO_ON
,0} },
1518 /* [D,0] */ { {"",opD0
,TERM
,0}, {"",opD1
,TERM
,0},
1519 {"",opD2
,TERM
,0}, {"",opD3
,TERM
,0},
1520 /* [D,4] */ {"aam",TERM
,U
,0,INVALID_64
},
1521 {"aad",TERM
,U
,0,INVALID_64
},
1522 {"falc",TERM
,GO_ON
,0}, {"xlat",TERM
,GO_ON
,0},
1523 /* 287 instructions. Note that although the indirect field */
1524 /* indicates opFP1n2 for further decoding, this is not necessarily */
1525 /* the case since the opFP arrays are not partitioned according to key1 */
1526 /* and key2. opFP1n2 is given only to indicate that we haven't */
1527 /* finished decoding the instruction. */
1528 /* [D,8] */ {"",(const struct instable
*)opFP1n2
,TERM
,0},
1529 {"",(const struct instable
*)opFP1n2
,TERM
,0},
1530 {"",(const struct instable
*)opFP1n2
,TERM
,0},
1531 {"",(const struct instable
*)opFP1n2
,TERM
,0},
1532 /* [D,C] */ {"",(const struct instable
*)opFP1n2
,TERM
,0},
1533 {"",(const struct instable
*)opFP1n2
,TERM
,0},
1534 {"",(const struct instable
*)opFP1n2
,TERM
,0},
1535 {"",(const struct instable
*)opFP1n2
,TERM
,0} },
1536 /* [E,0] */ { {"loopnz",TERM
,BD
,0}, {"loopz",TERM
,BD
,0},
1537 {"loop",TERM
,BD
,0}, {"jcxz",TERM
,BD
,0},
1538 /* [E,4] */ {"inb",TERM
,Pi
,0}, {"in",TERM
,Pi
,1},
1539 {"outb",TERM
,Po
,0}, {"out",TERM
,Po
,1},
1540 /* [E,8] */ {"call",TERM
,D
,0x03}, {"jmp",TERM
,D
,0x02},
1541 {"ljmp",TERM
,SO
,0}, {"jmp",TERM
,BD
,0},
1542 /* [E,C] */ {"inb",TERM
,Vi
,0}, {"in",TERM
,Vi
,1},
1543 {"outb",TERM
,Vo
,0}, {"out",TERM
,Vo
,1} },
1544 /* [F,0] */ { {"lock/",TERM
,PREFIX
,0}, INVALID
,
1545 {"repnz/",TERM
,PREFIX
,0}, {"repz/",TERM
,PREFIX
,0},
1546 /* [F,4] */ {"hlt",TERM
,GO_ON
,0}, {"cmc",TERM
,GO_ON
,0},
1547 {"",opF6
,TERM
,0}, {"",opF7
,TERM
,0},
1548 /* [F,8] */ {"clc",TERM
,GO_ON
,0}, {"stc",TERM
,GO_ON
,0},
1549 {"cli",TERM
,GO_ON
,0}, {"sti",TERM
,GO_ON
,0},
1550 /* [F,C] */ {"cld",TERM
,GO_ON
,0}, {"std",TERM
,GO_ON
,0},
1551 {"",opFE
,TERM
,0}, {"",opFF
,TERM
,0} },
1554 static const char *get_reg_name(int reg
, int wbit
, int data16
, int rex
)
1556 const char *reg_name
;
1558 // A REX prefix takes precedent over a 66h prefix.
1560 reg_name
= REG32
[reg
+ (REX_R(rex
) << 3)][wbit
+ REX_W(rex
)];
1561 } else if (data16
) {
1562 reg_name
= REG16
[reg
][wbit
];
1564 reg_name
= REG32
[reg
][wbit
];
1570 static const char *get_r_m_name(int r_m
, int wbit
, int data16
, int rex
)
1572 const char *reg_name
;
1574 // A REX prefix takes precedent over a 66h prefix.
1576 reg_name
= REG32
[r_m
+ (REX_B(rex
) << 3)][wbit
+ REX_W(rex
)];
1577 } else if (data16
) {
1578 reg_name
= REG16
[r_m
][wbit
];
1580 reg_name
= REG32
[r_m
][wbit
];
1586 // Returns the xmm register number referenced by reg and rex.
1587 static unsigned int xmm_reg(int reg
, int rex
)
1589 return (reg
+ (REX_R(rex
) << 3));
1592 // Returns the xmm register number referenced by r_m and rex.
1593 static unsigned int xmm_rm(int r_m
, int rex
)
1595 return (r_m
+ (REX_B(rex
) << 3));
1599 * i386_disassemble()
1607 enum byte_sex object_byte_sex
,
1608 struct relocation_info
*sorted_relocs
,
1609 uint32_t nsorted_relocs
,
1610 struct nlist
*symbols
,
1611 struct nlist_64
*symbols64
,
1613 struct symbol
*sorted_symbols
,
1614 uint32_t nsorted_symbols
,
1616 uint32_t strings_size
,
1617 uint32_t *indirect_symbols
,
1618 uint32_t nindirect_symbols
,
1620 struct load_command
*load_commands
,
1622 uint32_t sizeofcmds
,
1626 char mnemonic
[MAX_MNEMONIC
+2]; /* one extra for suffix */
1628 const char *symbol0
, *symbol1
;
1629 const char *symadd0
, *symsub0
, *symadd1
, *symsub1
;
1630 uint32_t value0
, value1
;
1631 uint64_t imm0
, imm1
;
1632 uint32_t value0_size
, value1_size
;
1633 char result0
[MAX_RESULT
], result1
[MAX_RESULT
];
1634 const char *indirect_symbol_name
;
1638 unsigned char opcode_suffix
;
1639 /* nibbles (4 bits) of the opcode */
1640 unsigned opcode1
, opcode2
, opcode3
, opcode4
, opcode5
, prefix_byte
;
1641 const struct instable
*dp
, *prefix_dp
;
1642 uint32_t wbit
, vbit
;
1643 enum bool got_modrm_byte
;
1644 uint32_t mode
, reg
, r_m
;
1645 const char *reg_name
;
1646 enum bool data16
; /* 16- or 32-bit data */
1647 enum bool addr16
; /* 16- or 32-bit addressing */
1648 enum bool sse2
; /* sse2 instruction using xmmreg's */
1649 enum bool mmx
; /* mmx instruction using mmreg's */
1650 unsigned char rex
; /* x86-64 REX prefix */
1653 printf("(end of section)\n");
1657 memset(mnemonic
, '\0', sizeof(mnemonic
));
1665 memset(result0
, '\0', sizeof(result0
));
1666 memset(result1
, '\0', sizeof(result1
));
1677 opcode4
= 0; /* to remove a compiler warning only */
1678 opcode5
= 0; /* to remove a compiler warning only */
1685 * As long as there is a prefix, the default segment register,
1686 * addressing-mode, or data-mode in the instruction will be overridden.
1687 * This may be more general than the chip actually is.
1692 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1693 opcode1
= byte
>> 4 & 0xf;
1694 opcode2
= byte
& 0xf;
1696 dp
= &distable
[opcode1
][opcode2
];
1697 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
&&
1701 if(dp
->adr_mode
== PREFIX
){
1702 if(prefix_dp
!= NULL
)
1703 printf("%s", dp
->name
);
1704 else if(llvm_mc
== TRUE
&& byte
== 0x9b){
1711 else if(dp
->adr_mode
== AM
){
1715 else if(dp
->adr_mode
== DM
){
1719 else if(dp
->adr_mode
== OVERRIDE
){
1723 else if(dp
->adr_mode
== REX
){
1726 * REX is a prefix, but we don't set prefix_byte here because
1727 * we use that to detect things related to the other prefixes
1728 * and we don't want the existence of those bytes to be hidden
1729 * by the presence of a REX prefix.
1736 got_modrm_byte
= FALSE
;
1739 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
1740 * byte so we need to perform a table indirection.
1742 if(dp
->indirect
== (const struct instable
*)op0F
){
1743 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1744 opcode4
= byte
>> 4 & 0xf;
1745 opcode5
= byte
& 0xf;
1746 dp
= &op0F
[opcode4
][opcode5
];
1747 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
&&
1750 if(dp
->indirect
== op0F38
|| dp
->indirect
== op0F3A
){
1752 * MNI instructions are SSE2ish instructions with an
1753 * extra byte. Do the extra indirection here.
1755 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1756 dp
= &dp
->indirect
[byte
];
1759 * SSE and SSE2 instructions have 3 bytes of opcode and the
1760 * "third opcode byte" is before the other two (where the prefix
1761 * byte would be). This is why the prefix byte is saved above and
1762 * the printing of the last prefix is delayed.
1764 if(dp
->adr_mode
== SSE2
||
1765 dp
->adr_mode
== SSE2i
||
1766 dp
->adr_mode
== SSE2i1
||
1767 dp
->adr_mode
== SSE2tm
||
1768 dp
->adr_mode
== SSE2tfm
||
1769 dp
->adr_mode
== SSE4
||
1770 dp
->adr_mode
== SSE4i
||
1771 dp
->adr_mode
== SSE4MRw
||
1772 dp
->adr_mode
== SSE4CRC
||
1773 dp
->adr_mode
== SSE4CRCb
||
1774 (byte
== 0xc7 && prefix_byte
== 0xf3)){ /* for vmxon */
1779 * 3DNow! instructions have 2 bytes of opcode followed by their
1780 * operands and then an instruction-specific suffix byte.
1782 if(dp
->indirect
== (const struct instable
*)op0F0F
){
1785 if(got_modrm_byte
== FALSE
){
1786 got_modrm_byte
= TRUE
;
1787 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1788 modrm_byte(&mode
, ®
, &r_m
, byte
);
1790 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
,
1792 opcode_suffix
= get_value(sizeof(char), sect
, &length
,
1794 dp
= &op0F0F
[opcode_suffix
>> 4][opcode_suffix
& 0x0F];
1796 else if(dp
->indirect
== (const struct instable
*)op0F01
){
1797 if(got_modrm_byte
== FALSE
){
1798 got_modrm_byte
= TRUE
;
1799 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1800 modrm_byte(&mode
, ®
, &r_m
, byte
);
1808 else if(byte
== 0xc9){
1813 else if(byte
== 0xf9){
1818 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
){
1819 if(opcode3
== 0x7 && got_modrm_byte
&&
1820 mode
== REG_ONLY
&& r_m
== 0) {
1825 * To get the 'q' suffix on all 0F 01 /0-3 opcodes in 64
1826 * bit mode we set the REX_W here.
1828 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
&&
1829 (opcode3
== 0 || opcode3
== 1 || opcode3
== 2 ||
1835 * Since the opcode is not an SSE or SSE2 instruction that
1836 * uses the prefix byte as the "third opcode byte" print the
1837 * delayed last prefix if any.
1839 if(prefix_dp
!= NULL
)
1840 printf("%s", prefix_dp
->name
);
1846 * The "pause" Spin Loop Hint instruction is a "repz" prefix
1847 * followed by a nop (0x90).
1849 if(prefix_dp
!= NULL
&& prefix_byte
== 0xf3 &&
1850 opcode1
== 0x9 && opcode2
== 0x0){
1855 * Since the opcode is not an SSE or SSE2 instruction print the
1856 * delayed last prefix if any.
1858 if(prefix_dp
!= NULL
){
1860 * If the prefix is "repz" and the instruction is ins, outs,
1861 * movs, lods, or stos then the name used is "rep".
1863 if(strcmp(prefix_dp
->name
, "repz/") == 0 &&
1864 (byte
== 0x6c || byte
== 0x6d || /* ins */
1865 byte
== 0x6e || byte
== 0x6f || /* outs */
1866 byte
== 0xa4 || byte
== 0xa5 || /* movs */
1867 byte
== 0xac || byte
== 0xad || /* lods */
1868 byte
== 0xaa || byte
== 0xab)) /* stos */
1871 printf("%s", prefix_dp
->name
);
1875 if(dp
->indirect
!= TERM
){
1877 * This must have been an opcode for which several instructions
1878 * exist. The opcode3 field further decodes the instruction.
1880 if(got_modrm_byte
== FALSE
){
1881 got_modrm_byte
= TRUE
;
1882 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1883 modrm_byte(&mode
, (uint32_t *)&opcode3
, &r_m
, byte
);
1886 * decode 287 instructions (D8-DF) from opcodeN
1888 if(opcode1
== 0xD && opcode2
>= 0x8){
1889 /* instruction form 5 */
1890 if(opcode2
== 0xB && mode
== 0x3 && opcode3
== 4)
1892 else if(opcode2
== 0xB && mode
== 0x3 && opcode3
> 6){
1893 printf(".byte 0x%01x%01x, 0x%01x%01x 0x%02x #bad opcode\n",
1894 (unsigned int)opcode1
, (unsigned int)opcode2
,
1895 (unsigned int)opcode4
, (unsigned int)opcode5
,
1896 (unsigned int)byte
);
1899 /* instruction form 4 */
1900 else if(opcode2
== 0x9 && mode
== 0x3 && opcode3
>= 4)
1901 dp
= &opFP4
[opcode3
-4][r_m
];
1902 /* instruction form 3 */
1903 else if(mode
== 0x3)
1904 dp
= &opFP3
[opcode2
-8][opcode3
];
1905 else /* instruction form 1 and 2 */
1906 dp
= &opFP1n2
[opcode2
-8][opcode3
];
1909 dp
= dp
->indirect
+ opcode3
;
1910 /* now dp points the proper subdecode table entry */
1913 if(dp
->indirect
!= TERM
){
1914 printf(".byte 0x%02x #bad opcode\n", (unsigned int)byte
);
1919 * Some addressing modes are implicitly 64-bit. Set REX.W for those
1920 * so we don't have to change the logic for them later.
1922 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
){
1923 if((dp
->flags
& IS_POINTER_SIZED
) != 0){
1924 rex
|= 0x8; /* Set REX.W if it isn't already set */
1928 /* setup the mnemonic with a possible suffix */
1929 if(dp
->adr_mode
!= CBW
&& dp
->adr_mode
!= CWD
){
1930 if((dp
->flags
& HAS_SUFFIX
) != 0){
1932 sprintf(mnemonic
, "%sw", dp
->name
);
1934 if(dp
->adr_mode
== Mnol
|| dp
->adr_mode
== INM
||
1935 dp
->adr_mode
== SM
|| dp
->adr_mode
== MS
)
1936 sprintf(mnemonic
, "%s", dp
->name
);
1937 else if(REX_W(rex
) != 0)
1938 sprintf(mnemonic
, "%sq", dp
->name
);
1940 sprintf(mnemonic
, "%sl", dp
->name
);
1944 sprintf(mnemonic
, "%s", dp
->name
);
1946 if(dp
->adr_mode
== BD
){
1947 if(strcmp(seg
, "%cs:") == 0){
1948 sprintf(mnemonic
, "%s,pn", mnemonic
);
1951 else if(strcmp(seg
, "%ds:") == 0){
1952 sprintf(mnemonic
, "%s,pt", mnemonic
);
1959 * Each instruction has a particular instruction syntax format
1960 * stored in the disassembly tables. The assignment of formats
1961 * to instructions was made by the author. Individual formats
1962 * are explained as they are encountered in the following
1965 switch(dp
-> adr_mode
){
1968 reg
= opcode5
& 0x7;
1970 reg_name
= REG32
[reg
+ (REX_B(rex
) << 3)][1 + REX_W(rex
)];
1972 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
1973 printf("%s\t%s\n", mnemonic
, reg_name
);
1977 wbit
= WBIT(opcode5
);
1978 if(got_modrm_byte
== FALSE
){
1979 got_modrm_byte
= TRUE
;
1980 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1981 modrm_byte(&mode
, ®
, &r_m
, byte
);
1983 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
1984 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
1985 printf("%s\t%s,", mnemonic
, reg_name
);
1986 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
1990 /* movsbl movsbw (0x0FBE) or movswl (0x0FBF) */
1991 /* movzbl movzbw (0x0FB6) or mobzwl (0x0FB7) */
1992 /* wbit lives in 2nd byte, note that operands are different sized */
1994 /* Get second operand first so data16 can be destroyed */
1995 if(got_modrm_byte
== FALSE
){
1996 got_modrm_byte
= TRUE
;
1997 byte
= get_value(sizeof(char), sect
, &length
, &left
);
1998 modrm_byte(&mode
, ®
, &r_m
, byte
);
2000 reg_name
= get_reg_name(reg
, LONGOPERAND
, data16
, rex
);
2001 wbit
= WBIT(opcode5
);
2003 /* movslq (0x63) Move doubleword to quadword with sign-extension */
2004 if(opcode1
!= 0x6 && opcode2
!= 0x3)
2006 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2007 printf("%s\t", mnemonic
);
2008 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
2010 printf("%s\n", reg_name
);
2013 /* imul instruction, with either 8-bit or longer immediate */
2015 if(got_modrm_byte
== FALSE
){
2016 got_modrm_byte
= TRUE
;
2017 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2018 modrm_byte(&mode
, ®
, &r_m
, byte
);
2021 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
, result1
);
2022 /* opcode 0x6B for byte, sign-extended displacement,
2024 value0_size
= OPSIZE(data16
, opcode2
== 0x9, 0);
2025 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
2026 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
2027 printf("%s\t$", mnemonic
);
2028 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
2029 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
, result1
,
2031 printf("%s\n", reg_name
);
2034 /* memory or register operand to register, with 'w' bit */
2038 * If this is vmwrite in a 64-bit object the 0F 79
2039 * opcode it results in a 64-bit operand.
2040 * So to get the 64-bit register names in the disassembly we
2041 * set the REX.W bit to indicate 64-bit operand size.
2043 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
&&
2044 opcode1
== 0x0 && opcode2
== 0xf &&
2045 opcode4
== 0x7 && opcode5
== 0x9)
2047 wbit
= WBIT(opcode2
);
2048 if(got_modrm_byte
== FALSE
){
2049 got_modrm_byte
= TRUE
;
2050 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2051 modrm_byte(&mode
, ®
, &r_m
, byte
);
2053 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2054 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
2055 printf("%s\t", mnemonic
);
2056 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
2058 printf("%s\n", reg_name
);
2061 /* register to memory or register operand, with 'w' bit */
2062 /* arpl happens to fit here also because it is odd */
2065 * If this is vmread in a 64-bit object the 0F 78
2066 * opcode it results in a 64-bit operand.
2067 * So to get the 64-bit register names in the disassembly we
2068 * set the REX.W bit to indicate 64-bit operand size.
2070 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
&&
2071 opcode1
== 0x0 && opcode2
== 0xf &&
2072 opcode4
== 0x7 && opcode5
== 0x8)
2074 /* arpl, 0x63, always uses r16's */
2075 if(opcode1
== 0x6 && opcode2
== 0x3)
2077 wbit
= WBIT(opcode2
);
2078 if(got_modrm_byte
== FALSE
){
2079 got_modrm_byte
= TRUE
;
2080 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2081 modrm_byte(&mode
, ®
, &r_m
, byte
);
2083 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2084 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
2085 printf("%s\t%s,", mnemonic
, reg_name
);
2086 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
2090 /* SSE2 instructions with further prefix decoding dest to memory or
2091 memory to dest depending on the opcode */
2094 if(got_modrm_byte
== FALSE
){
2095 got_modrm_byte
= TRUE
;
2096 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2097 modrm_byte(&mode
, ®
, &r_m
, byte
);
2099 switch(opcode4
<< 4 | opcode5
){
2100 case 0x7e: /* movq & movd */
2101 if(prefix_byte
== 0x66){
2102 /* movd from xmm to r/m32 */
2103 printf("%sd\t%%xmm%u,", mnemonic
, xmm_reg(reg
, rex
));
2105 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
,
2107 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2110 else if(prefix_byte
== 0xf0){
2111 /* movq from mm to mm/m64 */
2112 printf("%sd\t%%mm%u,", mnemonic
, reg
);
2114 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
,
2116 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
,
2119 else if(prefix_byte
== 0xf3){
2120 /* movq from xmm2/mem64 to xmm1 */
2121 printf("%sq\t", mnemonic
);
2123 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
,
2125 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2127 printf("%%xmm%u\n", xmm_reg(reg
, rex
));
2129 else{ /* no prefix_byte */
2130 /* movd from mm to r/m32 */
2131 printf("%sd\t%%mm%u,", mnemonic
, reg
);
2133 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
,
2135 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
,
2141 /* SSE2 instructions with further prefix decoding dest to memory */
2144 if(got_modrm_byte
== FALSE
){
2145 got_modrm_byte
= TRUE
;
2146 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2147 modrm_byte(&mode
, ®
, &r_m
, byte
);
2149 sprintf(result0
, "%%xmm%u", xmm_reg(reg
, rex
));
2150 switch(opcode4
<< 4 | opcode5
){
2151 case 0x11: /* movupd & movups */
2154 if(prefix_byte
== 0x66)
2155 printf("%supd\t", mnemonic
);
2156 else if(prefix_byte
== 0xf2)
2157 printf("%ssd\t", mnemonic
);
2158 else if(prefix_byte
== 0xf3)
2159 printf("%sss\t", mnemonic
);
2160 else /* no prefix_byte */
2161 printf("%sups\t", mnemonic
);
2163 case 0x13: /* movlpd & movlps */
2164 case 0x17: /* movhpd & movhps */
2165 case 0x29: /* movapd & movasd */
2166 case 0x2b: /* movntpd & movntsd */
2168 if(prefix_byte
== 0x66)
2169 printf("%spd\t", mnemonic
);
2170 else if(prefix_byte
== 0xf2)
2171 printf("%ssd\t", mnemonic
);
2172 else if(prefix_byte
== 0xf3)
2173 printf("%sss\t", mnemonic
);
2174 else /* no prefix_byte */
2175 printf("%sps\t", mnemonic
);
2177 case 0xd6: /* movq */
2178 if(prefix_byte
== 0x66){
2180 printf("%sq\t", mnemonic
);
2182 else if(prefix_byte
== 0xf2){
2183 printf("%sdq2q\t", mnemonic
);
2185 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
,
2187 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2189 sprintf(result1
, "%%mm%u", reg
);
2190 printf("%s\n", result1
);
2193 else if(prefix_byte
== 0xf3){
2194 printf("%sq2dq\t", mnemonic
);
2196 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
,
2198 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2200 sprintf(result1
, "%%xmm%u", reg
);
2201 printf("%s\n", result1
);
2205 case 0x7f: /* movdqa, movdqu, movq */
2207 if(prefix_byte
== 0x66)
2208 printf("%sdqa\t", mnemonic
);
2209 else if(prefix_byte
== 0xf3)
2210 printf("%sdqu\t", mnemonic
);
2212 sprintf(result0
, "%%mm%u", reg
);
2213 printf("%sq\t", mnemonic
);
2217 case 0xe7: /* movntdq & movntq */
2218 if(prefix_byte
== 0x66){
2219 printf("%stdq\t", mnemonic
);
2221 else{ /* no prefix_byte */
2222 sprintf(result0
, "%%mm%u", reg
);
2223 printf("%stq\t", mnemonic
);
2228 printf("%s,", result0
);
2229 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
, result1
);
2230 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
,
2234 /* MNI instructions */
2237 if(got_modrm_byte
== FALSE
){
2238 got_modrm_byte
= TRUE
;
2239 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2240 modrm_byte(&mode
, ®
, &r_m
, byte
);
2242 if(prefix_byte
== 0x66){
2244 sprintf(result1
, "%%xmm%u", xmm_reg(reg
, rex
));
2246 else{ /* no prefix byte */
2248 sprintf(result1
, "%%mm%u", reg
);
2250 printf("%s\t", mnemonic
);
2251 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2252 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2254 printf("%s\n", result1
);
2257 /* MNI instructions with 8-bit immediate */
2260 if (got_modrm_byte
== FALSE
) {
2261 got_modrm_byte
= TRUE
;
2262 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2263 modrm_byte(&mode
, ®
, &r_m
, byte
);
2265 if(prefix_byte
== 0x66){
2267 sprintf(result1
, "%%xmm%u", xmm_reg(reg
, rex
));
2269 else{ /* no prefix byte */
2271 sprintf(result1
, "%%mm%u", reg
);
2273 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2274 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2275 printf("%s\t$0x%x,", mnemonic
, byte
);
2277 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2279 printf("%s\n", result1
);
2282 /* SSE2 instructions with further prefix decoding */
2285 if(got_modrm_byte
== FALSE
){
2286 got_modrm_byte
= TRUE
;
2287 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2288 modrm_byte(&mode
, ®
, &r_m
, byte
);
2290 sprintf(result1
, "%%xmm%u", xmm_reg(reg
, rex
));
2291 switch(opcode4
<< 4 | opcode5
){
2292 case 0x14: /* unpcklpd & unpcklps */
2293 case 0x15: /* unpckhpd & unpckhps */
2294 case 0x28: /* movapd & movasd */
2295 case 0x51: /* sqrtpd, sqrtsd, sqrtss & sqrtps */
2296 case 0x52: /* rsqrtss & rsqrtps */
2297 case 0x53: /* rcpss & rcpps */
2298 case 0x54: /* andpd & andsd */
2299 case 0x55: /* andnpd & andnsd */
2300 case 0x56: /* orpd & orps */
2301 case 0x57: /* xorpd & xorps */
2302 case 0x58: /* addpd & addsd */
2303 case 0x59: /* mulpd, mulsd, mulss & mulps */
2304 case 0x5c: /* subpd, subsd, subss & subps */
2305 case 0x5d: /* minpd, minsd, minss & minps */
2306 case 0x5e: /* divpd, divsd, divss & divps */
2307 case 0x5f: /* maxpd, maxsd, maxss & maxps */
2309 if(prefix_byte
== 0x66)
2310 printf("%spd\t", mnemonic
);
2311 else if(prefix_byte
== 0xf2)
2312 printf("%ssd\t", mnemonic
);
2313 else if(prefix_byte
== 0xf3)
2314 printf("%sss\t", mnemonic
);
2315 else /* no prefix_byte */
2316 printf("%sps\t", mnemonic
);
2318 case 0x12: /* movlpd, movlps & movhlps */
2320 if(prefix_byte
== 0x66)
2321 printf("%slpd\t", mnemonic
);
2322 else if(prefix_byte
== 0xf2)
2323 printf("movddup\t");
2324 else if(prefix_byte
== 0xf3)
2325 printf("movsldup\t");
2326 else{ /* no prefix_byte */
2327 if(mode
== REG_ONLY
)
2328 printf("%shlps\t", mnemonic
);
2330 printf("%slps\t", mnemonic
);
2333 case 0x16: /* movhpd, movhps & movlhps */
2335 if(prefix_byte
== 0x66)
2336 printf("%shpd\t", mnemonic
);
2337 else if(prefix_byte
== 0xf2)
2338 printf("%shsd\t", mnemonic
);
2339 else if(prefix_byte
== 0xf3)
2340 printf("movshdup\t");
2341 else{ /* no prefix_byte */
2342 if(mode
== REG_ONLY
)
2343 printf("%slhps\t", mnemonic
);
2345 printf("%shps\t", mnemonic
);
2348 case 0x50: /* movmskpd & movmskps */
2350 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2351 strcpy(result1
, reg_name
);
2352 if(prefix_byte
== 0x66)
2353 printf("%spd\t", mnemonic
);
2354 else /* no prefix_byte */
2355 printf("%sps\t", mnemonic
);
2357 case 0x10: /* movupd & movups */
2360 if(prefix_byte
== 0x66)
2361 printf("%supd\t", mnemonic
);
2362 else if(prefix_byte
== 0xf2)
2363 printf("%ssd\t", mnemonic
);
2364 else if(prefix_byte
== 0xf3)
2365 printf("%sss\t", mnemonic
);
2366 else /* no prefix_byte */
2367 printf("%sups\t", mnemonic
);
2369 case 0x2a: /* cvtpi2pd, cvtsi2sd, cvtsi2ss & cvtpi2ps */
2370 if(prefix_byte
== 0x66){
2372 printf("%spi2pd\t", mnemonic
);
2374 else if(prefix_byte
== 0xf2){
2376 printf("%ssi2sd\t", mnemonic
);
2378 else if(prefix_byte
== 0xf3){
2380 printf("%ssi2ss\t", mnemonic
);
2382 else{ /* no prefix_byte */
2384 printf("%spi2ps\t", mnemonic
);
2387 case 0x2c: /* cvttpd2pi, cvttsd2si, cvttss2si & cvttps2pi */
2388 if(prefix_byte
== 0x66){
2390 printf("%stpd2pi\t", mnemonic
);
2391 sprintf(result1
, "%%mm%u", reg
);
2393 else if(prefix_byte
== 0xf2){
2395 printf("%stsd2si\t", mnemonic
);
2396 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2397 strcpy(result1
, reg_name
);
2399 else if(prefix_byte
== 0xf3){
2401 printf("%stss2si\t", mnemonic
);
2402 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2403 strcpy(result1
, reg_name
);
2405 else{ /* no prefix_byte */
2407 printf("%stps2pi\t", mnemonic
);
2408 sprintf(result1
, "%%mm%u", reg
);
2411 case 0x2d: /* cvtpd2pi, cvtsd2si, cvtss2si & cvtps2pi */
2412 if(prefix_byte
== 0x66){
2414 printf("%spd2pi\t", mnemonic
);
2415 sprintf(result1
, "%%mm%u", reg
);
2417 else if(prefix_byte
== 0xf2){
2419 printf("%ssd2si\t", mnemonic
);
2420 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2421 strcpy(result1
, reg_name
);
2423 else if(prefix_byte
== 0xf3){
2425 printf("%sss2si\t", mnemonic
);
2426 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2427 strcpy(result1
, reg_name
);
2429 else{ /* no prefix_byte */
2431 printf("%sps2pi\t", mnemonic
);
2432 sprintf(result1
, "%%mm%u", reg
);
2435 case 0x2e: /* ucomisd & ucomiss */
2436 case 0x2f: /* comisd & comiss */
2438 if(prefix_byte
== 0x66)
2439 printf("%ssd\t", mnemonic
);
2440 else /* no prefix_byte */
2441 printf("%sss\t", mnemonic
);
2443 case 0xe0: /* pavgb */
2444 case 0xe3: /* pavgw */
2445 if(prefix_byte
== 0x66){
2447 printf("%s\t", mnemonic
);
2449 else{ /* no prefix_byte */
2450 sprintf(result1
, "%%mm%u", reg
);
2451 printf("%s\t", mnemonic
);
2455 case 0xe6: /* cvttpd2dq, cvtdq2pd & cvtpd2dq */
2457 if(prefix_byte
== 0x66)
2458 printf("%stpd2dq\t", mnemonic
);
2459 if(prefix_byte
== 0xf3)
2460 printf("%sdq2pd\t", mnemonic
);
2461 else if(prefix_byte
== 0xf2)
2462 printf("%spd2dq\t", mnemonic
);
2464 case 0x5a: /* cvtpd2ps, cvtsd2ss, cvtss2sd & cvtps2pd */
2466 if(prefix_byte
== 0x66)
2467 printf("%spd2ps\t", mnemonic
);
2468 else if(prefix_byte
== 0xf2)
2469 printf("%ssd2ss\t", mnemonic
);
2470 else if(prefix_byte
== 0xf3)
2471 printf("%sss2sd\t", mnemonic
);
2472 else /* no prefix_byte */
2473 printf("%sps2pd\t", mnemonic
);
2475 case 0x5b: /* cvtdq2ps, cvttps2dq & cvtps2dq */
2477 if(prefix_byte
== 0x66)
2478 printf("%sps2dq\t", mnemonic
);
2479 else if(prefix_byte
== 0xf3)
2480 printf("%stps2dq\t", mnemonic
);
2481 else /* no prefix_byte */
2482 printf("%sdq2ps\t", mnemonic
);
2484 case 0x60: /* punpcklbw */
2485 case 0x61: /* punpcklwd */
2486 case 0x62: /* punpckldq */
2487 case 0x63: /* packsswb */
2488 case 0x64: /* pcmpgtb */
2489 case 0x65: /* pcmpgtw */
2490 case 0x66: /* pcmpgtd */
2491 case 0x67: /* packuswb */
2492 case 0x68: /* punpckhbw */
2493 case 0x69: /* punpckhwd */
2494 case 0x6a: /* punpckhdq */
2495 case 0x6b: /* packssdw */
2496 case 0x74: /* pcmpeqb */
2497 case 0x75: /* pcmpeqw */
2498 case 0x76: /* pcmpeqd */
2499 case 0xd1: /* psrlw */
2500 case 0xd2: /* psrld */
2501 case 0xd3: /* psrlq */
2502 case 0xd4: /* paddq */
2503 case 0xd5: /* pmullw */
2504 case 0xd8: /* psubusb */
2505 case 0xd9: /* psubusw */
2506 case 0xdb: /* pand */
2507 case 0xdc: /* paddusb */
2508 case 0xdd: /* paddusw */
2509 case 0xdf: /* pandn */
2510 case 0xe1: /* psraw */
2511 case 0xe2: /* psrad */
2512 case 0xe5: /* pmulhw */
2513 case 0xe8: /* psubsb */
2514 case 0xe9: /* psubsw */
2515 case 0xeb: /* por */
2516 case 0xec: /* paddsb */
2517 case 0xed: /* paddsw */
2518 case 0xef: /* pxor */
2519 case 0xf1: /* psllw */
2520 case 0xf2: /* pslld */
2521 case 0xf3: /* psllq */
2522 case 0xf5: /* pmaddwd */
2523 case 0xf8: /* psubb */
2524 case 0xf9: /* psubw */
2525 case 0xfa: /* psubd */
2526 case 0xfb: /* psubq */
2527 case 0xfc: /* paddb */
2528 case 0xfd: /* paddw */
2529 case 0xfe: /* paddd */
2530 if(prefix_byte
== 0x66){
2531 printf("%s\t", mnemonic
);
2534 else{ /* no prefix_byte */
2535 sprintf(result1
, "%%mm%u", reg
);
2536 printf("%s\t", mnemonic
);
2540 case 0x6c: /* punpcklqdq */
2541 case 0x6d: /* punpckhqdq */
2543 if(prefix_byte
== 0x66)
2544 printf("%sqdq\t", mnemonic
);
2546 case 0x6f: /* movdqa, movdqu & movq */
2547 if(prefix_byte
== 0x66){
2549 printf("%sdqa\t", mnemonic
);
2551 else if(prefix_byte
== 0xf3){
2553 printf("%sdqu\t", mnemonic
);
2555 else{ /* no prefix_byte */
2556 sprintf(result1
, "%%mm%u", reg
);
2557 printf("%sq\t", mnemonic
);
2561 case 0xd6: /* movdq2q & movq2dq */
2562 if(prefix_byte
== 0xf2){
2563 sprintf(result1
, "%%mm%u", reg
);
2564 printf("%sdq2q\t", mnemonic
);
2567 else if(prefix_byte
== 0xf3){
2568 printf("%sq2dq\t", mnemonic
);
2572 case 0x6e: /* movd */
2573 if(prefix_byte
== 0x66){
2574 printf("%s\t", mnemonic
);
2577 else{ /* no prefix_byte */
2578 sprintf(result1
, "%%mm%u", reg
);
2579 printf("%s\t", mnemonic
);
2583 case 0xd0: /* addsubpd */
2584 case 0x7c: /* haddp */
2585 case 0x7d: /* hsubp */
2586 if(prefix_byte
== 0x66){
2587 printf("%sd\t", mnemonic
);
2590 else if(prefix_byte
== 0xf2){
2591 printf("%ss\t", mnemonic
);
2594 else{ /* no prefix_byte */
2595 sprintf(result1
, "%%mm%u", reg
);
2596 printf("%s\t", mnemonic
);
2600 case 0xd7: /* pmovmskb */
2601 if(prefix_byte
== 0x66){
2602 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2603 printf("%s\t%%xmm%u,%s\n", mnemonic
, xmm_rm(r_m
, rex
),
2607 else{ /* no prefix_byte */
2608 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2609 printf("%s\t%%mm%u,%s\n", mnemonic
, r_m
, reg_name
);
2613 case 0xda: /* pminub */
2614 case 0xde: /* pmaxub */
2615 case 0xe4: /* pmulhuw */
2616 case 0xea: /* pminsw */
2617 case 0xee: /* pmaxsw */
2618 case 0xf4: /* pmuludq */
2619 case 0xf6: /* psadbw */
2620 if(prefix_byte
== 0x66){
2622 printf("%s\t", mnemonic
);
2624 else{ /* no prefix_byte */
2625 sprintf(result1
, "%%mm%u", reg
);
2626 printf("%s\t", mnemonic
);
2630 case 0xf0: /* lddqu */
2631 printf("%s\t", mnemonic
);
2634 case 0xf7: /* maskmovdqu & maskmovq */
2636 if(prefix_byte
== 0x66)
2637 printf("%sdqu\t", mnemonic
);
2638 else{ /* no prefix_byte */
2639 printf("%sq\t%%mm%u,%%mm%u\n", mnemonic
, r_m
, reg
);
2644 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2645 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2647 printf("%s\n", result1
);
2650 /* SSE4 instructions */
2655 if(got_modrm_byte
== FALSE
){
2656 got_modrm_byte
= TRUE
;
2657 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2658 modrm_byte(&mode
, ®
, &r_m
, byte
);
2660 printf("%s\t", mnemonic
);
2661 sprintf(result1
, "%%xmm%u", xmm_reg(reg
, rex
));
2662 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2663 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2665 printf("%s\n", result1
);
2668 /* SSE4 instructions with 8 bit immediate */
2673 if(got_modrm_byte
== FALSE
){
2674 got_modrm_byte
= TRUE
;
2675 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2676 modrm_byte(&mode
, ®
, &r_m
, byte
);
2678 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2679 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2680 printf("%s\t$0x%x,", mnemonic
, byte
);
2681 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2683 printf("%%xmm%u\n", xmm_reg(reg
, rex
));
2686 /* SSE4 instructions with dest to memory and 8-bit immediate */
2691 if(got_modrm_byte
== FALSE
){
2692 got_modrm_byte
= TRUE
;
2693 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2694 modrm_byte(&mode
, ®
, &r_m
, byte
);
2696 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2697 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2698 if(dp
== &op0F3A
[0x16]){
2700 printf("%sq\t$0x%x,", mnemonic
, byte
);
2702 printf("%sd\t$0x%x,", mnemonic
, byte
);
2705 printf("%s\t$0x%x,", mnemonic
, byte
);
2706 printf("%%xmm%u,", xmm_reg(reg
, rex
));
2707 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2711 /* SSE4 instructions with src from memory and 8-bit immediate */
2716 if(got_modrm_byte
== FALSE
){
2717 got_modrm_byte
= TRUE
;
2718 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2719 modrm_byte(&mode
, ®
, &r_m
, byte
);
2721 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2722 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2723 if(dp
== &op0F3A
[0x22]){
2725 printf("%sq\t$0x%x,", mnemonic
, byte
);
2727 printf("%sd\t$0x%x,", mnemonic
, byte
);
2730 printf("%s\t$0x%x,", mnemonic
, byte
);
2731 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2733 printf("%%xmm%u\n", xmm_reg(reg
, rex
));
2736 /* SSE4.2 instructions memory or register operand to register */
2739 if(got_modrm_byte
== FALSE
){
2740 got_modrm_byte
= TRUE
;
2741 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2742 modrm_byte(&mode
, ®
, &r_m
, byte
);
2745 * This is to get the byte register names for SSE4CRCb opcodes.
2747 if(mode
== REG_ONLY
){
2748 strcpy(result0
, REG64_BYTE
[(REX_B(rex
) << 3) | r_m
]);
2755 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2756 reg_name
= get_reg_name(reg
, 1 /* wbit */, 0 /* data16 */, rex
);
2757 printf("%s\t", mnemonic
);
2758 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
2760 printf("%s\n", reg_name
);
2765 if(got_modrm_byte
== FALSE
){
2766 got_modrm_byte
= TRUE
;
2767 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2768 modrm_byte(&mode
, ®
, &r_m
, byte
);
2770 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2771 reg_name
= get_reg_name(reg
, 1 /* wbit */, 0 /* data16 */, rex
);
2772 printf("%s\t", mnemonic
);
2773 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
2775 printf("%s\n", reg_name
);
2778 /* SSE2 instructions with 8 bit immediate with further prefix decoding*/
2781 if(got_modrm_byte
== FALSE
){
2782 got_modrm_byte
= TRUE
;
2783 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2784 modrm_byte(&mode
, ®
, &r_m
, byte
);
2787 if((opcode4
<< 4 | opcode5
) == 0x70 && prefix_byte
== 0)
2790 else if((opcode4
<< 4 | opcode5
) == 0xc4)
2794 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2795 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2797 switch(opcode4
<< 4 | opcode5
){
2798 case 0x70: /* pshufd, pshuflw, pshufhw & pshufw */
2799 if(prefix_byte
== 0x66)
2800 printf("%sfd\t$0x%x,", mnemonic
, byte
);
2801 else if(prefix_byte
== 0xf2)
2802 printf("%sflw\t$0x%x,", mnemonic
, byte
);
2803 else if(prefix_byte
== 0xf3)
2804 printf("%sfhw\t$0x%x,", mnemonic
, byte
);
2805 else{ /* no prefix_byte */
2806 printf("%sfw\t$0x%x,", mnemonic
, byte
);
2807 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2809 printf("%%mm%u\n", reg
);
2813 case 0xc4: /* pinsrw */
2814 if(prefix_byte
== 0x66){
2815 printf("%s\t$0x%x,", mnemonic
, byte
);
2817 else{ /* no prefix_byte */
2818 printf("%s\t$0x%x,", mnemonic
, byte
);
2819 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2821 printf("%%mm%u\n", reg
);
2825 case 0xc5: /* pextrw */
2826 if(prefix_byte
== 0x66){
2827 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2828 printf("%s\t$0x%x,%%xmm%u,%s\n", mnemonic
, byte
,
2829 xmm_rm(r_m
, rex
), reg_name
);
2832 else{ /* no prefix_byte */
2833 reg_name
= get_reg_name(reg
, 1, data16
, rex
);
2834 printf("%s\t$0x%x,%%mm%u,%s\n", mnemonic
, byte
, r_m
,
2840 if(prefix_byte
== 0x66)
2841 printf("%spd\t$0x%x,", mnemonic
, byte
);
2842 else if(prefix_byte
== 0xf2)
2843 printf("%ssd\t$0x%x,", mnemonic
, byte
);
2844 else if(prefix_byte
== 0xf3)
2845 printf("%sss\t$0x%x,", mnemonic
, byte
);
2846 else /* no prefix_byte */
2847 printf("%sps\t$0x%x,", mnemonic
, byte
);
2850 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2852 printf("%%xmm%u\n", xmm_reg(reg
, rex
));
2855 /* SSE2 instructions with 8 bit immediate and only 1 reg */
2857 if(got_modrm_byte
== FALSE
){
2858 got_modrm_byte
= TRUE
;
2859 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2860 modrm_byte(&mode
, ®
, &r_m
, byte
);
2862 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2863 switch(opcode4
<< 4 | opcode5
){
2864 case 0x71: /* psrlw, psllw, psraw & psrld */
2865 if(prefix_byte
== 0x66){
2867 printf("%srlw\t$0x%x,", mnemonic
, byte
);
2869 printf("%sraw\t$0x%x,", mnemonic
, byte
);
2871 printf("%sllw\t$0x%x,", mnemonic
, byte
);
2873 else{ /* no prefix_byte */
2875 printf("%srlw\t$0x%x,", mnemonic
, byte
);
2877 printf("%sraw\t$0x%x,", mnemonic
, byte
);
2879 printf("%sllw\t$0x%x,", mnemonic
, byte
);
2880 printf("%%mm%u\n", r_m
);
2884 case 0x72: /* psrld, pslld & psrad */
2885 if(prefix_byte
== 0x66){
2887 printf("%srld\t$0x%x,", mnemonic
, byte
);
2889 printf("%srad\t$0x%x,", mnemonic
, byte
);
2891 printf("%slld\t$0x%x,", mnemonic
, byte
);
2893 else{ /* no prefix_byte */
2895 printf("%srld\t$0x%x,", mnemonic
, byte
);
2897 printf("%srad\t$0x%x,", mnemonic
, byte
);
2899 printf("%slld\t$0x%x,", mnemonic
, byte
);
2900 printf("%%mm%u\n", r_m
);
2904 case 0x73: /* pslldq & psrldq, psrlq & psllq */
2905 if(prefix_byte
== 0x66){
2907 printf("%slldq\t$0x%x,", mnemonic
, byte
);
2909 printf("%srldq\t$0x%x,", mnemonic
, byte
);
2911 printf("%srlq\t$0x%x,", mnemonic
, byte
);
2913 printf("%sllq\t$0x%x,", mnemonic
, byte
);
2915 else{ /* no prefix_byte */
2917 printf("%srlq\t$0x%x,", mnemonic
, byte
);
2919 printf("%sllq\t$0x%x,", mnemonic
, byte
);
2920 printf("%%mm%u\n", r_m
);
2925 printf("%%xmm%u\n", xmm_rm(r_m
, rex
));
2928 /* 3DNow instructions */
2930 printf("%s\t", mnemonic
);
2931 sprintf(result1
, "%%mm%u", reg
);
2932 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2934 printf("%s\n", result1
);
2937 /* prefetch instructions */
2939 if(got_modrm_byte
== FALSE
){
2940 got_modrm_byte
= TRUE
;
2941 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2942 modrm_byte(&mode
, ®
, &r_m
, byte
);
2946 printf("%snta", dp
->name
);
2949 printf("%st0", dp
->name
);
2952 printf("%st1", dp
->name
);
2955 printf("%st2", dp
->name
);
2961 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2962 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2966 /* 3DNow! prefetch instructions */
2968 if(got_modrm_byte
== FALSE
){
2969 got_modrm_byte
= TRUE
;
2970 byte
= get_value(sizeof(char), sect
, &length
, &left
);
2971 modrm_byte(&mode
, ®
, &r_m
, byte
);
2975 printf("%s\t", dp
->name
);
2978 printf("%sw\t", dp
->name
);
2981 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2982 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2986 /* sfence & clflush */
2988 if(mode
== REG_ONLY
&& r_m
== 0){
2992 printf("%s\t", mnemonic
);
2994 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
2995 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
,
2999 /* Double shift. Has immediate operand specifying the shift. */
3001 if(got_modrm_byte
== FALSE
){
3002 got_modrm_byte
= TRUE
;
3003 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3004 modrm_byte(&mode
, ®
, &r_m
, byte
);
3007 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
, result1
);
3008 value0_size
= sizeof(char);
3009 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3010 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
3011 printf("%s\t$", mnemonic
);
3012 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3013 printf("%s,", reg_name
);
3014 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
, result1
,
3018 /* Double shift. With no immediate operand, specifies using %cl. */
3020 if(got_modrm_byte
== FALSE
){
3021 got_modrm_byte
= TRUE
;
3022 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3023 modrm_byte(&mode
, ®
, &r_m
, byte
);
3026 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3027 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
3028 printf("%s\t%%cl,%s,", mnemonic
, reg_name
);
3029 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3033 /* immediate to memory or register operand */
3035 wbit
= WBIT(opcode2
);
3036 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
, result1
);
3037 /* A long immediate is expected for opcode 0x81, not 0x80 & 0x83 */
3038 value0_size
= OPSIZE(data16
, opcode2
== 1, 0);
3039 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3040 printf("%s\t$", mnemonic
);
3041 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3042 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
, result1
,
3046 /* immediate to memory or register operand with the 'w' bit present */
3048 if(got_modrm_byte
== FALSE
){
3049 got_modrm_byte
= TRUE
;
3050 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3051 modrm_byte(&mode
, ®
, &r_m
, byte
);
3053 wbit
= WBIT(opcode2
);
3054 GET_OPERAND(&symadd1
, &symsub1
, &value1
, &value1_size
, result1
);
3055 value0_size
= OPSIZE(data16
, wbit
, 0);
3056 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3057 printf("%s\t$", mnemonic
);
3058 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3059 print_operand(seg
, symadd1
, symsub1
, value1
, value1_size
, result1
,
3063 /* immediate to register with register in low 3 bits of op code */
3065 wbit
= (opcode2
>> 3) & 0x1; /* w-bit here (with regs) is bit 3 */
3066 reg
= REGNO(opcode2
);
3067 value0_size
= OPSIZE(data16
, wbit
, 0);
3068 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3069 reg_name
= get_r_m_name(reg
, wbit
, data16
, rex
);
3070 printf("%s\t$", mnemonic
);
3071 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3072 printf("%s\n", reg_name
);
3075 /* immediate to register with register in low 3 bits of op code,
3076 possibly with a 64-bit immediate */
3078 wbit
= (opcode2
>> 3) & 0x1; /* w-bit here (with regs) is bit 3 */
3079 reg
= REGNO(opcode2
);
3080 value0_size
= OPSIZE(data16
, wbit
, REX_W(rex
));
3081 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3082 reg_name
= get_r_m_name(reg
, wbit
, data16
, rex
);
3083 printf("%s\t$", mnemonic
);
3084 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3085 printf("%s\n", reg_name
);
3088 /* memory operand to accumulator */
3090 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
){
3091 value0_size
= OPSIZE(addr16
, LONGOPERAND
, 1);
3092 strcpy(mnemonic
, "movabsl");
3095 value0_size
= OPSIZE(addr16
, LONGOPERAND
, 0);
3096 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3097 printf("%s\t", mnemonic
);
3098 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3099 wbit
= WBIT(opcode2
);
3100 reg_name
= get_reg_name(0, wbit
, data16
, rex
);
3101 printf("%s\n", reg_name
);
3104 /* accumulator to memory operand */
3106 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
){
3107 value0_size
= OPSIZE(addr16
, LONGOPERAND
, 1);
3108 strcpy(mnemonic
, "movabsl");
3111 value0_size
= OPSIZE(addr16
, LONGOPERAND
, 0);
3112 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3113 wbit
= WBIT(opcode2
);
3114 reg_name
= get_reg_name(0, wbit
, data16
, rex
);
3115 printf("%s\t%s,", mnemonic
, reg_name
);
3116 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "", "\n");
3119 /* memory or register operand to segment register */
3121 if(got_modrm_byte
== FALSE
){
3122 got_modrm_byte
= TRUE
;
3123 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3124 modrm_byte(&mode
, ®
, &r_m
, byte
);
3127 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3128 printf("%s\t", mnemonic
);
3129 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3131 printf("%s\n", SEGREG
[reg
]);
3134 /* segment register to memory or register operand */
3136 if(got_modrm_byte
== FALSE
){
3137 got_modrm_byte
= TRUE
;
3138 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3139 modrm_byte(&mode
, ®
, &r_m
, byte
);
3142 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3143 printf("%s\t%s,", mnemonic
, SEGREG
[reg
]);
3144 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3148 /* rotate or shift instrutions, which may shift by 1 or */
3149 /* consult the cl register, depending on the 'v' bit */
3151 vbit
= VBIT(opcode2
);
3152 wbit
= WBIT(opcode2
);
3153 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3154 /* When vbit is set, register is an operand, otherwise just $0x1 */
3155 reg_name
= vbit
? "%cl," : "" ;
3156 printf("%s\t%s", mnemonic
, reg_name
);
3157 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3161 /* immediate rotate or shift instrutions, which may or */
3162 /* may not consult the cl register, depending on the 'v' bit */
3164 vbit
= VBIT(opcode2
);
3165 wbit
= WBIT(opcode2
);
3166 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3167 value1_size
= sizeof(char);
3168 IMMEDIATE(&symadd1
, &symsub1
, &imm0
, value1_size
);
3169 /* When vbit is set, register is an operand, otherwise just $0x1 */
3170 reg_name
= vbit
? "%cl," : "" ;
3171 printf("%s\t$", mnemonic
);
3172 print_operand("", symadd1
, symsub1
, imm0
, value1_size
, "", ",");
3173 printf("%s", reg_name
);
3174 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3180 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3181 value1_size
= sizeof(char);
3182 IMMEDIATE(&symadd1
, &symsub1
, &imm0
, value1_size
);
3183 printf("%s\t$", mnemonic
);
3184 print_operand("", symadd1
, symsub1
, imm0
, value1_size
, "", ",");
3185 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3189 /* single memory or register operand with 'w' bit present */
3191 wbit
= WBIT(opcode2
);
3192 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3193 printf("%s\t", mnemonic
);
3194 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3198 /* single memory or register operand but don't use 'l' suffix */
3200 /* single memory or register operand */
3202 if(opcode1
== 0x0 && opcode2
== 0xf &&
3203 opcode4
== 0x0 && opcode5
== 0x1){
3209 printf("vmlaunch\n");
3212 printf("vmresume\n");
3219 if(opcode1
== 0x0 && opcode2
== 0xf && byte
== 0xc7){
3220 if(prefix_byte
== 0x66)
3221 sprintf(mnemonic
, "vmclear");
3222 else if(prefix_byte
== 0xf3)
3223 sprintf(mnemonic
, "vmxon");
3225 if(got_modrm_byte
== FALSE
){
3226 got_modrm_byte
= TRUE
;
3227 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3228 modrm_byte(&mode
, ®
, &r_m
, byte
);
3231 sprintf(mnemonic
, "vmptrld");
3233 sprintf(mnemonic
, "vmptrst");
3234 else if(reg
== 1 && REX_W(rex
))
3235 sprintf(mnemonic
, "cmpxchg16b");
3239 * Hacks for lldt, lmsw, ltr, verr and verw which take only a
3242 if(opcode1
== 0 && opcode2
== 0xf && opcode4
== 0 && opcode5
== 1 &&
3245 if(opcode1
== 0 && opcode2
== 0xf && opcode4
== 0 && opcode5
== 0 &&
3246 (opcode3
== 2 || opcode3
== 3 || opcode3
== 4 || opcode3
== 5))
3249 * Hacks for fnstsw which take only a r/m16 operand.
3251 if((opcode1
== 0xd && opcode2
== 0xf && byte
== 0xe0) ||
3252 (opcode1
== 0xd && opcode2
== 0xd && opcode3
== 0x7))
3254 if(got_modrm_byte
== FALSE
){
3255 got_modrm_byte
= TRUE
;
3256 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3257 modrm_byte(&mode
, ®
, &r_m
, byte
);
3260 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3261 printf("%s\t", mnemonic
);
3262 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3266 /* single memory or register operand */
3268 if(got_modrm_byte
== FALSE
){
3269 got_modrm_byte
= TRUE
;
3270 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3271 modrm_byte(&mode
, ®
, &r_m
, byte
);
3274 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3275 printf("%s\t", mnemonic
);
3276 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3280 case SREG
: /* special register */
3281 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3282 modrm_byte(&mode
, ®
, &r_m
, byte
);
3289 if(llvm_mc
== TRUE
){
3290 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
)
3291 reg_name
= LLVM_MC_64_CONTROLREG
[reg
+(REX_R(rex
) << 3)];
3293 reg_name
= LLVM_MC_32_CONTROLREG
[reg
+(REX_R(rex
) << 3)];
3296 reg_name
= CONTROLREG
[reg
+ (REX_R(rex
) << 3)];
3304 reg_name
= LLVM_MC_DEBUGREG
[reg
+ (REX_R(rex
) << 3)];
3306 reg_name
= DEBUGREG
[reg
+ (REX_R(rex
) << 3)];
3312 reg_name
= TESTREG
[reg
];
3316 printf("%s\t%s,%s\n", mnemonic
, get_r_m_name(r_m
, 1, data16
,
3320 printf("%s\t%s,%s\n", mnemonic
, reg_name
, get_r_m_name(r_m
, 1,
3325 /* single register operand with register in the low 3 */
3326 /* bits of op code */
3328 reg
= REGNO(opcode2
);
3329 reg_name
= get_r_m_name(reg
, LONGOPERAND
, data16
, rex
);
3330 printf("%s\t%s\n", mnemonic
, reg_name
);
3333 /* register to accumulator with register in the low 3 */
3334 /* bits of op code, xchg instructions */
3336 reg
= REGNO(opcode2
);
3338 reg_name
= REG32
[reg
+ (REX_B(rex
) << 3)]
3339 [LONGOPERAND
+ REX_W(rex
)];
3341 reg_name
= get_reg_name(reg
, LONGOPERAND
, data16
, rex
);
3343 printf("%s\t%s,%s\n", mnemonic
, reg_name
, "%rax");
3345 printf("%s\t%s,%s\n", mnemonic
, reg_name
, (data16
?
3349 /* single segment register operand, with reg in bits 3-4 of op code */
3351 reg
= byte
>> 3 & 0x3; /* segment register */
3352 printf("%s\t%s\n", mnemonic
, SEGREG
[reg
]);
3355 /* single segment register operand, with register in */
3356 /* bits 3-5 of op code */
3358 reg
= byte
>> 3 & 0x7; /* long seg reg from opcode */
3359 printf("%s\t%s\n", mnemonic
, SEGREG
[reg
]);
3362 /* memory or register operand to register */
3365 * invvpid and invept outside 64-bit mode the register operand is
3366 * always 32 bits, since this is encoded with 0x66 (operand-size
3367 * override) it would have set data16. So clear that to get the
3368 * correct value from reg_name().
3370 if((opcode1
== 0x0 && opcode2
== 0xf &&
3371 opcode4
== 0x3 && opcode5
== 0x8 && prefix_byte
== 0x66) &&
3372 (byte
== 0x81 || byte
== 0x80) &&
3373 (cputype
& CPU_ARCH_ABI64
) != CPU_ARCH_ABI64
)
3375 if(got_modrm_byte
== FALSE
){
3376 got_modrm_byte
= TRUE
;
3377 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3378 modrm_byte(&mode
, ®
, &r_m
, byte
);
3381 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3382 reg_name
= get_reg_name(reg
, wbit
, data16
, rex
);
3383 printf("%s\t", mnemonic
);
3384 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3386 printf("%s\n", reg_name
);
3389 /* immediate operand to accumulator */
3391 value0_size
= OPSIZE(data16
, WBIT(opcode2
), 0);
3392 switch(value0_size
) {
3393 case 1: reg_name
= "%al"; break;
3394 case 2: reg_name
= "%ax"; break;
3395 case 4: reg_name
= "%eax"; break;
3397 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3398 printf("%s\t$", mnemonic
);
3399 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",");
3400 printf("%s\n", reg_name
);
3403 /* memory or register operand to accumulator */
3405 wbit
= WBIT(opcode2
);
3406 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3407 printf("%s\t", mnemonic
);
3408 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3412 /* si register to di register */
3415 printf("%s\t%s(%%si),(%%di)\n", mnemonic
, seg
);
3417 printf("%s\t%s(%%esi),(%%edi)\n", mnemonic
, seg
);
3420 /* accumulator to di register */
3422 wbit
= WBIT(opcode2
);
3423 reg_name
= get_reg_name(0, wbit
, data16
, rex
);
3425 printf("%s\t%s,%s(%%di)\n", mnemonic
, reg_name
, seg
);
3427 printf("%s\t%s,%s(%%edi)\n", mnemonic
, reg_name
, seg
);
3430 /* si register to accumulator */
3432 wbit
= WBIT(opcode2
);
3433 reg_name
= get_reg_name(0, wbit
, data16
, rex
);
3435 printf("%s\t%s(%%si),%s\n", mnemonic
, seg
, reg_name
);
3437 printf("%s\t%s(%%esi),%s\n", mnemonic
, seg
, reg_name
);
3440 /* single operand, a 16/32 bit displacement */
3442 value0_size
= OPSIZE(data16
, LONGOPERAND
, 0);
3443 DISPLACEMENT(&symadd0
, &symsub0
, &imm0
, value0_size
);
3444 printf("%s\t", mnemonic
);
3445 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "", "");
3447 indirect_symbol_name
= guess_indirect_symbol(imm0
,
3448 ncmds
, sizeofcmds
, load_commands
, object_byte_sex
,
3449 indirect_symbols
, nindirect_symbols
, symbols
, symbols64
,
3450 nsymbols
, strings
,strings_size
);
3451 if(indirect_symbol_name
!= NULL
)
3452 printf("\t; symbol stub for: %s", indirect_symbol_name
);
3457 /* indirect to memory or register operand */
3460 * If this is call (near) in a 64-bit object the FF /2 opcode
3461 * results in a 64-bit operand even without a rex prefix byte.
3462 * So to get the 64-bit register names in the disassembly we
3463 * set the REX.W bit to indicate 64-bit operand size.
3465 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
&&
3466 opcode1
== 0xf && opcode2
== 0xf &&
3467 (opcode3
== 2 || opcode3
== 4))
3470 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3471 if((mode
== 0 && (r_m
== 5 || r_m
== 4)) || mode
== 1 ||
3472 mode
== 2 || mode
== 3)
3473 printf("%s\t*", mnemonic
);
3475 printf("%s\t", mnemonic
);
3476 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3480 /* indirect to memory or register operand (for lcall and ljmp) */
3483 GET_OPERAND(&symadd0
, &symsub0
, &value0
, &value0_size
, result0
);
3484 printf("%s\t*", mnemonic
);
3485 print_operand(seg
, symadd0
, symsub0
, value0
, value0_size
, result0
,
3490 * For long jumps and long calls -- a new code segment
3491 * register and an offset in IP -- stored in object
3492 * code in reverse order
3495 value1_size
= OPSIZE(data16
, LONGOPERAND
, 0);
3496 IMMEDIATE(&symadd1
, &symsub1
, &imm1
, value1_size
);
3497 value0_size
= sizeof(short);
3498 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3499 printf("%s\t$", mnemonic
);
3500 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",$");
3501 print_operand(seg
, symadd1
, symsub1
, imm1
, value1_size
, "", "\n");
3504 /* jmp/call. single operand, 8 bit displacement */
3507 * The "Jump if rCX Zero" instruction is 0xe3 but is "jcxz" as in
3508 * the table only in 32-bit mode with a Address-size override
3509 * prefix. Without a prefix it is "jecxz" in 32-bit mode. In
3510 * 64-bit mode with a prefix it is "jecxz" and without it is
3513 if(opcode1
== 0xe && opcode2
== 0x3){
3514 if((cputype
& CPU_ARCH_ABI64
) != CPU_ARCH_ABI64
){
3516 sprintf(mnemonic
, "jecxz");
3518 else if ((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
){
3520 sprintf(mnemonic
, "jecxz");
3522 sprintf(mnemonic
, "jrcxz");
3525 value0_size
= sizeof(char);
3526 DISPLACEMENT(&symadd0
, &symsub0
, &imm0
, value0_size
);
3527 printf("%s\t", mnemonic
);
3528 print_operand(seg
, symadd0
, symsub0
, imm0
, sizeof(int32_t), "",
3532 /* single 32/16 bit immediate operand */
3534 value0_size
= OPSIZE(data16
, LONGOPERAND
, 0);
3535 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3536 printf("%s\t$", mnemonic
);
3537 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", "\n");
3540 /* single 8 bit immediate operand */
3542 value0_size
= sizeof(char);
3543 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3544 printf("%s\t$", mnemonic
);
3545 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", "\n");
3549 value0_size
= sizeof(short);
3550 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3551 value1_size
= sizeof(char);
3552 IMMEDIATE(&symadd1
, &symsub1
, &imm1
, value1_size
);
3553 printf("%s\t$", mnemonic
);
3554 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", ",$");
3555 print_operand("", symadd1
, symsub1
, imm1
, value1_size
, "", "\n");
3558 /* 16-bit immediate operand */
3560 value0_size
= sizeof(short);
3561 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3562 printf("%s\t$", mnemonic
);
3563 print_operand("", symadd0
, symsub0
, imm0
, value0_size
, "", "\n");
3566 /* single 8 bit port operand */
3568 value0_size
= sizeof(char);
3569 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3570 printf("%s\t$", mnemonic
);
3571 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "", "\n");
3574 /* single 8 bit (input) port operand */
3576 value0_size
= sizeof(char);
3577 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3578 printf("%s\t$", mnemonic
);
3580 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "",
3583 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "",
3586 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "",
3590 /* single 8 bit (output) port operand */
3592 value0_size
= sizeof(char);
3593 IMMEDIATE(&symadd0
, &symsub0
, &imm0
, value0_size
);
3595 printf("%s\t%%al,$", mnemonic
);
3597 printf("%s\t%%ax,$", mnemonic
);
3599 printf("%s\t%%eax,$", mnemonic
);
3600 print_operand(seg
, symadd0
, symsub0
, imm0
, value0_size
, "", "\n");
3603 /* single operand, dx register (variable port instruction) */
3605 printf("%s\t%s(%%dx)\n", mnemonic
, seg
);
3608 /* single operand, dx register (variable (input) port instruction) */
3611 printf("%s\t%s%%dx,%%al\n", mnemonic
, seg
);
3613 printf("%s\t%s%%dx,%%ax\n", mnemonic
, seg
);
3615 printf("%s\t%s%%dx,%%eax\n", mnemonic
, seg
);
3618 /* single operand, dx register (variable (output) port instruction)*/
3621 printf("%s\t%s%%al,%%dx\n", mnemonic
, seg
);
3623 printf("%s\t%s%%ax,%%dx\n", mnemonic
, seg
);
3625 printf("%s\t%s%%eax,%%dx\n", mnemonic
, seg
);
3628 /* The int instruction, which has two forms: int 3 (breakpoint) or */
3629 /* int n, where n is indicated in the subsequent byte (format Ib). */
3630 /* The int 3 instruction (opcode 0xCC), where, although the 3 looks */
3631 /* like an operand, it is implied by the opcode. It must be converted */
3632 /* to the correct base and output. */
3634 printf("%s\t$0x3\n", mnemonic
);
3637 /* just an opcode and an unused byte that must be discarded */
3639 byte
= get_value(sizeof(char), sect
, &length
, &left
);
3640 if(opcode1
== 0xd && (opcode2
== 0x5 || opcode2
== 0x4) &&
3642 printf("%s\t$0x%x\n", mnemonic
, byte
);
3644 printf("%s\n", mnemonic
);
3650 else if(data16
== TRUE
)
3659 else if(data16
== TRUE
)
3665 /* no disassembly, the mnemonic was all there was so go on */
3667 printf("%s\n", mnemonic
);
3672 printf("%s\t%%st(%1.1u)\n", mnemonic
, r_m
);
3675 /* float reg to float reg, with ret bit present */
3677 /* return result bit for 287 instructions */
3678 if(((opcode2
>> 2) & 0x1) == 0x1 && opcode2
!= 0xf)
3679 printf("%s\t%%st,%%st(%1.1u)\n", mnemonic
, r_m
);
3681 printf("%s\t%%st(%1.1u),%%st\n", mnemonic
, r_m
);
3684 /* an invalid op code */
3691 printf(".byte 0x%02x", 0xff & sect
[0]);
3692 for(i
= 1; i
< length
; i
++)
3693 printf(", 0x%02x", 0xff & sect
[i
]);
3694 printf(" #bad opcode\n");
3700 * get_operand() is used to return the symbolic operand for an operand that is
3701 * encoded with a mod r/m byte.
3706 const char **symadd
,
3707 const char **symsub
,
3709 uint32_t *value_size
,
3712 const cpu_type_t cputype
,
3713 const uint32_t mode
,
3715 const uint32_t wbit
,
3716 const enum bool data16
,
3717 const enum bool addr16
,
3718 const enum bool sse2
,
3719 const enum bool mmx
,
3720 const unsigned int rex
,
3727 const uint32_t addr
,
3728 const struct relocation_info
*sorted_relocs
,
3729 const uint32_t nsorted_relocs
,
3730 const struct nlist
*symbols
,
3731 const struct nlist_64
*symbols64
,
3732 const uint32_t nsymbols
,
3733 const char *strings
,
3734 const uint32_t strings_size
,
3736 const struct symbol
*sorted_symbols
,
3737 const uint32_t nsorted_symbols
,
3738 const enum bool verbose
)
3740 enum bool s_i_b
; /* flag presence of scale-index-byte */
3741 unsigned char byte
; /* the scale-index-byte */
3742 uint32_t ss
; /* scale-factor from scale-index-byte */
3743 uint32_t index
; /* index register number from scale-index-byte*/
3744 uint32_t base
; /* base register number from scale-index-byte */
3745 uint32_t sect_offset
;
3756 /* check for the presence of the s-i-b byte */
3757 if(r_m
== ESP
&& mode
!= REG_ONLY
&&
3758 (((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
) || addr16
== FALSE
)){
3760 byte
= get_value(sizeof(char), sect
, length
, left
);
3761 modrm_byte(&ss
, &index
, &base
, byte
);
3766 if(addr16
&& (cputype
& CPU_ARCH_ABI64
) != CPU_ARCH_ABI64
)
3767 *value_size
= dispsize16
[r_m
][mode
];
3769 *value_size
= dispsize32
[r_m
][mode
];
3771 if(s_i_b
== TRUE
&& mode
== 0 && base
== EBP
)
3772 *value_size
= sizeof(int32_t);
3774 if(*value_size
!= 0){
3775 sect_offset
= addr
+ *length
- sect_addr
;
3776 *value
= get_value(*value_size
, sect
, length
, left
);
3777 GET_SYMBOL(symadd
, symsub
, &offset
, sect_offset
, *value
);
3778 if(*symadd
!= NULL
){
3782 *symadd
= GUESS_SYMBOL(*value
);
3789 if(((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
) && !addr16
){
3790 /* If the scale factor is 1, don't display it. */
3793 * If mode is 0 and base is 5 (regardless of the rex bit)
3794 * there is no base register, and if the index is
3795 * also 4 then the operand is just a displacement.
3797 if(mode
== 0 && base
== 5 && index
== 4){
3801 sprintf(result
, "(%s%s)", regname64
[mode
][base
+
3802 (REX_B(rex
) << 3)], indexname64
[index
+
3803 (REX_X(rex
) << 3)]);
3808 * If mode is 0 and base is 5 (regardless of the rex bit)
3809 * there is no base register.
3811 if(mode
== 0 && base
== 5){
3812 sprintf(result
, "(%s,%s)", indexname64
[index
+
3813 (REX_X(rex
) << 3)], scale_factor
[ss
]);
3816 sprintf(result
, "(%s%s,%s)", regname64
[mode
][base
+
3817 (REX_B(rex
) << 3)], indexname64
[index
+
3818 (REX_X(rex
) << 3)], scale_factor
[ss
]);
3823 /* If the scale factor is 1, don't display it. */
3826 * If mode is 0 and base is 5 it there is no base register,
3827 * and if the index is also 4 then the operand is just a
3830 if(mode
== 0 && base
== 5 && index
== 4){
3834 sprintf(result
, "(%s%s)", regname32
[mode
][base
],
3839 sprintf(result
, "(%s%s,%s)", regname32
[mode
][base
],
3840 indexname
[index
], scale_factor
[ss
]);
3844 else{ /* no s-i-b */
3845 if(mode
== REG_ONLY
){
3847 sprintf(result
, "%%xmm%u", xmm_rm(r_m
, rex
));
3848 else if(mmx
== TRUE
)
3849 sprintf(result
, "%%mm%u", r_m
);
3850 else if (data16
== FALSE
|| rex
!= 0)
3851 /* The presence of a REX byte overrides 66h. */
3852 strcpy(result
, REG32
[r_m
+ (REX_B(rex
) << 3)][wbit
+
3855 strcpy(result
, REG16
[r_m
][wbit
]);
3857 else{ /* Modes 00, 01, or 10 */
3858 if(r_m
== EBP
&& mode
== 0){ /* displacement only */
3859 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
)
3861 * In 64-bit mode, mod=00 and r/m=101 defines
3862 * RIP-relative addressing with a 32-bit displacement.
3863 * In 32-bit mode, it's just a 32-bit displacement. See
3864 * section 2.2.1.6 ("RIP-Relative Addressing") of Volume
3865 * 2A of the Intel IA-32 manual.
3867 sprintf(result
, "(%%rip)");
3872 /* Modes 00, 01, or 10, not displacement only, no s-i-b */
3873 if(addr16
== TRUE
) {
3874 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
)
3876 * In 64-bit mode, the address size prefix drops us
3877 * down to 32-bit, not 16-bit.
3879 sprintf(result
, "(%s)", regname32
[mode
][r_m
]);
3881 sprintf(result
, "(%s)", regname16
[mode
][r_m
]);
3884 if((cputype
& CPU_ARCH_ABI64
) == CPU_ARCH_ABI64
)
3885 sprintf(result
, "(%s)", regname64
[mode
][r_m
+
3886 (REX_B(rex
) << 3)]);
3888 sprintf(result
, "(%s)", regname32
[mode
][r_m
]);
3896 * immediate() is used to return the symbolic operand for an immediate operand.
3901 const char **symadd
,
3902 const char **symsub
,
3904 uint32_t value_size
,
3911 const cpu_type_t cputype
,
3912 const uint32_t addr
,
3913 const struct relocation_info
*sorted_relocs
,
3914 const uint32_t nsorted_relocs
,
3915 const struct nlist
*symbols
,
3916 const struct nlist_64
*symbols64
,
3917 const uint32_t nsymbols
,
3918 const char *strings
,
3919 const uint32_t strings_size
,
3921 const struct symbol
*sorted_symbols
,
3922 const uint32_t nsorted_symbols
,
3923 const enum bool verbose
)
3925 uint32_t sect_offset
;
3928 sect_offset
= addr
+ *length
- sect_addr
;
3929 *value
= get_value(value_size
, sect
, length
, left
);
3930 GET_SYMBOL(symadd
, symsub
, &offset
, sect_offset
, *value
);
3931 if(*symadd
== NULL
){
3932 *symadd
= GUESS_SYMBOL(*value
);
3936 else if(*symsub
!= NULL
){
3942 * displacement() is used to return the symbolic operand for an operand that is
3943 * encoded as a displacement from the program counter.
3948 const char **symadd
,
3949 const char **symsub
,
3951 const uint32_t value_size
,
3958 const cpu_type_t cputype
,
3959 const uint64_t addr
,
3960 const struct relocation_info
*sorted_relocs
,
3961 const uint32_t nsorted_relocs
,
3962 const struct nlist
*symbols
,
3963 const struct nlist_64
*symbols64
,
3964 const uint32_t nsymbols
,
3965 const char *strings
,
3966 const uint32_t strings_size
,
3968 const struct symbol
*sorted_symbols
,
3969 const uint32_t nsorted_symbols
,
3970 const enum bool verbose
)
3972 uint32_t sect_offset
;
3974 uint64_t guess_addr
;
3976 sect_offset
= addr
+ *length
- sect_addr
;
3977 *value
= get_value(value_size
, sect
, length
, left
);
3981 *value
= *value
| 0xffffffffffffff00ULL
;
3984 if((*value
) & 0x8000)
3985 *value
= *value
| 0xffffffffffff0000ULL
;
3988 if((cputype
& CPU_ARCH_ABI64
) != CPU_ARCH_ABI64
)
3989 *value
+= addr
+ *length
;
3991 GET_SYMBOL(symadd
, symsub
, &offset
, sect_offset
, *value
);
3992 if(*symadd
== NULL
){
3993 if((cputype
& CPU_ARCH_ABI64
) != CPU_ARCH_ABI64
){
3994 *symadd
= GUESS_SYMBOL(*value
);
3999 guess_addr
= *value
;
4000 if((*value
) & 0x80000000)
4001 guess_addr
|= 0xffffffff00000000ULL
;
4002 guess_addr
+= addr
+ *length
;
4003 *symadd
= GUESS_SYMBOL(guess_addr
);
4007 *value
+= addr
+ *length
;
4010 else if(*symsub
!= NULL
){
4016 * get_symbol() returns the name of a symbol (or NULL) based on the relocation
4017 * information at the specified address.
4022 const char **symadd
,
4023 const char **symsub
,
4026 const cpu_type_t cputype
,
4027 const uint32_t sect_offset
,
4028 const uint64_t value
,
4029 const struct relocation_info
*relocs
,
4030 const uint32_t nrelocs
,
4031 const struct nlist
*symbols
,
4032 const struct nlist_64
*symbols64
,
4033 const uint32_t nsymbols
,
4034 const char *strings
,
4035 const uint32_t strings_size
,
4036 const struct symbol
*sorted_symbols
,
4037 const uint32_t nsorted_symbols
,
4038 const enum bool verbose
)
4041 unsigned int r_symbolnum
;
4043 struct scattered_relocation_info
*sreloc
, *pair
;
4044 const char *name
, *add
, *sub
;
4046 static char add_buffer
[11]; /* max is "0x1234678\0" */
4047 static char sub_buffer
[11];
4053 if(verbose
== FALSE
)
4056 for(i
= 0; i
< nrelocs
; i
++){
4057 if((cputype
& CPU_ARCH_ABI64
) != CPU_ARCH_ABI64
&&
4058 ((relocs
[i
].r_address
) & R_SCATTERED
) != 0){
4059 sreloc
= (struct scattered_relocation_info
*)(relocs
+ i
);
4060 if(sreloc
->r_type
== GENERIC_RELOC_PAIR
){
4061 fprintf(stderr
, "Stray GENERIC_RELOC_PAIR relocation entry "
4065 if(sreloc
->r_type
== GENERIC_RELOC_VANILLA
){
4066 if(sreloc
->r_address
== sect_offset
){
4067 name
= guess_symbol(sreloc
->r_value
,
4073 *offset
= value
- sreloc
->r_value
;
4079 if(sreloc
->r_type
!= GENERIC_RELOC_SECTDIFF
&&
4080 sreloc
->r_type
!= GENERIC_RELOC_LOCAL_SECTDIFF
){
4081 fprintf(stderr
, "Unknown relocation r_type for entry "
4085 if(i
+ 1 < nrelocs
){
4086 pair
= (struct scattered_relocation_info
*)(relocs
+ i
+ 1);
4087 if(pair
->r_scattered
== 0 ||
4088 pair
->r_type
!= GENERIC_RELOC_PAIR
){
4089 fprintf(stderr
, "No GENERIC_RELOC_PAIR relocation "
4090 "entry after entry %u\n", i
);
4095 fprintf(stderr
, "No GENERIC_RELOC_PAIR relocation entry "
4096 "after entry %u\n", i
);
4099 i
++; /* skip the pair reloc */
4101 if(sreloc
->r_address
== sect_offset
){
4102 add
= guess_symbol(sreloc
->r_value
, sorted_symbols
,
4103 nsorted_symbols
, verbose
);
4104 sub
= guess_symbol(pair
->r_value
, sorted_symbols
,
4105 nsorted_symbols
, verbose
);
4107 sprintf(add_buffer
, "0x%x",
4108 (unsigned int)sreloc
->r_value
);
4112 sprintf(sub_buffer
, "0x%x",
4113 (unsigned int)pair
->r_value
);
4118 *offset
= value
- (sreloc
->r_value
- pair
->r_value
);
4123 if((uint32_t)relocs
[i
].r_address
== sect_offset
){
4124 r_symbolnum
= relocs
[i
].r_symbolnum
;
4125 if(relocs
[i
].r_extern
){
4126 if(r_symbolnum
>= nsymbols
)
4129 n_strx
= symbols
[r_symbolnum
].n_un
.n_strx
;
4131 n_strx
= symbols64
[r_symbolnum
].n_un
.n_strx
;
4132 if(n_strx
<= 0 || n_strx
>= strings_size
)
4134 *symadd
= strings
+ n_strx
;
4144 * print_operand() prints an operand from it's broken out symbolic
4154 unsigned int value_size
,
4160 if(value_size
!= 0){
4162 printf("%s%s-%s+0x%0*llx%s%s", seg
, symadd
, symsub
,
4163 (int)value_size
* 2, value
, result
, tail
);
4165 printf("%s%s-%s%s%s",seg
, symadd
, symsub
, result
, tail
);
4168 printf("%s%s%s%s", seg
, symadd
, result
, tail
);
4172 if(value_size
!= 0){
4174 printf("%s%s+0x%0*llx%s%s", seg
, symadd
,
4175 (int)value_size
* 2, value
, result
, tail
);
4177 printf("%s%s%s%s", seg
, symadd
, result
, tail
);
4180 printf("%s%s%s%s", seg
, symadd
, result
, tail
);
4185 if(value_size
!= 0){
4186 printf("%s0x%0*llx%s%s", seg
, (int)value_size
*2, value
, result
,
4190 printf("%s%s%s", seg
, result
, tail
);
4196 * get_value() gets a value of size from sect + length and decrease left by the
4197 * size and increase length by size. The size of the value can be 1, 2, 4, or 8
4198 * bytes and the value is in little endian byte order. The value is always
4199 * returned as a uint64_t and is not sign extended.
4204 const uint32_t size
, /* size of the value to get as a number of bytes (in)*/
4205 const char *sect
, /* pointer to the raw data of the section (in) */
4206 uint32_t *length
, /* number of bytes taken from the sect (in/out) */
4207 uint32_t *left
) /* number of bytes left in sect after length (in/out) */
4217 for(i
= 0; i
< size
; i
++) {
4220 byte
= sect
[*length
];
4224 value
|= (uint64_t)byte
<< (8*i
);
4230 * modrm_byte() breaks a byte out into its mode, reg and r/m bits.
4240 *r_m
= byte
& 0x7; /* r/m field from the byte */
4241 *reg
= byte
>> 3 & 0x7; /* register field from the byte */
4242 *mode
= byte
>> 6 & 0x3; /* mode field from the byte */