1 /////////////////////////////////////////////////////////////////////////
2 // $Id: disasm.h 12420 2014-07-18 11:14:25Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //   Copyright (c) 2005-2014 Stanislav Shwartsman
6 //          Written by Stanislav Shwartsman [sshwarts at sourceforge net]
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21 //
22 /////////////////////////////////////////////////////////////////////////
23 
24 #ifndef _BX_DISASM_H_
25 #define _BX_DISASM_H_
26 
27 #include "config.h"
28 
29 #define BX_DECODE_MODRM(modrm_byte, mod, opcode, rm) { \
30   mod    = (modrm_byte >> 6) & 0x03; \
31   opcode = (modrm_byte >> 3) & 0x07; \
32   rm     =  modrm_byte & 0x07;       \
33 }
34 
35 #define BX_DECODE_SIB(sib_byte, scale, index, base) { \
36   scale =  sib_byte >> 6;          \
37   index = (sib_byte >> 3) & 0x07;  \
38   base  =  sib_byte & 0x07;        \
39 }
40 
41 /* Instruction set attributes (duplicated in cpu.h) */
42 #define IA_X87              (BX_CONST64(1) << 0)   /* FPU (X87) instruction */
43 #define IA_486              (BX_CONST64(1) << 1)   /* 486 new instruction */
44 #define IA_PENTIUM          (BX_CONST64(1) << 2)   /* Pentium new instruction */
45 #define IA_P6               (BX_CONST64(1) << 3)   /* P6 new instruction */
46 #define IA_MMX              (BX_CONST64(1) << 4)   /* MMX instruction */
47 #define IA_3DNOW            (BX_CONST64(1) << 5)   /* 3DNow! instruction (AMD) */
48 #define IA_SYSCALL_SYSRET   (BX_CONST64(1) << 6)   /* SYSCALL/SYSRET in legacy mode (AMD) */
49 #define IA_SYSENTER_SYSEXIT (BX_CONST64(1) << 7)   /* SYSENTER/SYSEXIT instruction */
50 #define IA_CLFLUSH          (BX_CONST64(1) << 8)   /* CLFLUSH instruction */
51 #define IA_SSE              (BX_CONST64(1) << 9)   /* SSE  instruction */
52 #define IA_SSE2             (BX_CONST64(1) << 10)  /* SSE2 instruction */
53 #define IA_SSE3             (BX_CONST64(1) << 11)  /* SSE3 instruction */
54 #define IA_SSSE3            (BX_CONST64(1) << 12)  /* SSSE3 instruction */
55 #define IA_SSE4_1           (BX_CONST64(1) << 13)  /* SSE4_1 instruction */
56 #define IA_SSE4_2           (BX_CONST64(1) << 14)  /* SSE4_2 instruction */
57 #define IA_POPCNT           (BX_CONST64(1) << 15)  /* POPCNT instruction */
58 #define IA_MONITOR_MWAIT    (BX_CONST64(1) << 16)  /* MONITOR/MWAIT instruction */
59 #define IA_VMX              (BX_CONST64(1) << 17)  /* VMX instruction */
60 #define IA_SMX              (BX_CONST64(1) << 18)  /* SMX instruction */
61 #define IA_LM_LAHF_SAHF     (BX_CONST64(1) << 19)  /* Long Mode LAHF/SAHF instruction */
62 #define IA_CMPXCHG16B       (BX_CONST64(1) << 20)  /* CMPXCHG16B instruction */
63 #define IA_RDTSCP           (BX_CONST64(1) << 21)  /* RDTSCP instruction */
64 #define IA_XSAVE            (BX_CONST64(1) << 22)  /* XSAVE/XRSTOR extensions instruction */
65 #define IA_XSAVEOPT         (BX_CONST64(1) << 23)  /* XSAVEOPT instruction */
66 #define IA_AES_PCLMULQDQ    (BX_CONST64(1) << 24)  /* AES+PCLMULQDQ instruction */
67 #define IA_MOVBE            (BX_CONST64(1) << 25)  /* MOVBE Intel Atom(R) instruction */
68 #define IA_FSGSBASE         (BX_CONST64(1) << 26)  /* FS/GS BASE access instruction */
69 #define IA_INVPCID          (BX_CONST64(1) << 27)  /* INVPCID instruction */
70 #define IA_AVX              (BX_CONST64(1) << 28)  /* AVX instruction */
71 #define IA_AVX2             (BX_CONST64(1) << 29)  /* AVX2 instruction */
72 #define IA_AVX_F16C         (BX_CONST64(1) << 30)  /* AVX F16 convert instruction */
73 #define IA_AVX_FMA          (BX_CONST64(1) << 31)  /* AVX FMA instruction */
74 #define IA_SSE4A            (BX_CONST64(1) << 32)  /* SSE4A instruction (AMD) */
75 #define IA_LZCNT            (BX_CONST64(1) << 33)  /* LZCNT instruction */
76 #define IA_BMI1             (BX_CONST64(1) << 34)  /* BMI1 instruction */
77 #define IA_BMI2             (BX_CONST64(1) << 35)  /* BMI2 instruction */
78 #define IA_FMA4             (BX_CONST64(1) << 36)  /* FMA4 instruction (AMD) */
79 #define IA_XOP              (BX_CONST64(1) << 37)  /* XOP instruction (AMD) */
80 #define IA_TBM              (BX_CONST64(1) << 38)  /* TBM instruction (AMD) */
81 #define IA_SVM              (BX_CONST64(1) << 39)  /* SVM instruction (AMD) */
82 #define IA_RDRAND           (BX_CONST64(1) << 40)  /* RDRAND instruction */
83 #define IA_ADX              (BX_CONST64(1) << 41)  /* ADCX/ADOX instruction */
84 #define IA_SMAP             (BX_CONST64(1) << 42)  /* SMAP support */
85 #define IA_RDSEED           (BX_CONST64(1) << 43)  /* RDSEED instruction */
86 #define IA_SHA              (BX_CONST64(1) << 44)  /* SHA instruction */
87 #define IA_AVX512           (BX_CONST64(1) << 45)  /* AVX-512 instruction */
88 #define IA_AVX512_CD        (BX_CONST64(1) << 46)  /* AVX-512 Conflict Detection instruction */
89 #define IA_AVX512_PF        (BX_CONST64(1) << 47)  /* AVX-512 Sparse Prefetch instruction */
90 #define IA_AVX512_ER        (BX_CONST64(1) << 48)  /* AVX-512 Exponential/Reciprocal instruction */
91 #define IA_AVX512_DQ        (BX_CONST64(1) << 49)  /* AVX-512DQ instruction */
92 #define IA_AVX512_BW        (BX_CONST64(1) << 50)  /* AVX-512 Byte/Word instruction */
93 #define IA_CLFLUSHOPT       (BX_CONST64(1) << 51)  /* CLFLUSHOPT instruction */
94 #define IA_XSAVEC           (BX_CONST64(1) << 52)  /* XSAVEC instruction */
95 #define IA_XSAVES           (BX_CONST64(1) << 53)  /* XSAVES instruction */
96 
97 /* general purpose bit register */
98 enum {
99 	rAX_REG,
100 	rCX_REG,
101 	rDX_REG,
102 	rBX_REG,
103 	rSP_REG,
104 	rBP_REG,
105 	rSI_REG,
106 	rDI_REG
107 };
108 
109 /* segment register */
110 enum {
111 	ES_REG,
112 	CS_REG,
113 	SS_REG,
114 	DS_REG,
115 	FS_REG,
116 	GS_REG,
117         INVALID_SEG1,
118         INVALID_SEG2
119 };
120 
121 class disassembler;
122 struct x86_insn;
123 
124 typedef void (disassembler::*BxDisasmPtr_t)(const x86_insn *insn);
125 typedef void (disassembler::*BxDisasmResolveModrmPtr_t)(const x86_insn *insn, unsigned attr);
126 
127 struct BxDisasmOpcodeInfo_t
128 {
129     const char *IntelOpcode;
130     const char *AttOpcode;
131     BxDisasmPtr_t Operand1;
132     BxDisasmPtr_t Operand2;
133     BxDisasmPtr_t Operand3;
134     BxDisasmPtr_t Operand4;
135     Bit64u Feature;
136 };
137 
138 struct BxDisasmOpcodeTable_t
139 {
140     Bit32u Attr;
141     const void *OpcodeInfo;
142 };
143 
144 // segment override not used
145 #define NO_SEG_OVERRIDE 0xFF
146 
147 // datasize attributes
148 #define   X_SIZE      0x00 /* no size */
149 #define   B_SIZE      0x01 /* byte */
150 #define   W_SIZE      0x02 /* word */
151 #define   D_SIZE      0x03 /* double word */
152 #define   Q_SIZE      0x04 /* quad word */
153 #define   Z_SIZE      0x05 /* double word in 32-bit mode, quad word in 64-bit mode */
154 #define   T_SIZE      0x06 /* 10-byte x87 floating point */
155 #define XMM_SIZE      0x07 /* double quad word (XMM) */
156 #define YMM_SIZE      0x08 /* quadruple quad word (YMM) */
157 
158 #define VSIB_Index    0x80
159 
160 // branch hint attribute
161 #define BRANCH_HINT 0x1000
162 
163 struct x86_insn
164 {
165 public:
166   x86_insn(bx_bool is32, bx_bool is64);
167 
is_seg_overridex86_insn168   bx_bool is_seg_override() const {
169      return (seg_override != NO_SEG_OVERRIDE);
170  }
171 
172 public:
173   bx_bool is_32, is_64;
174   bx_bool as_32, as_64;
175   bx_bool os_32, os_64;
176 
177   Bit8u extend8b;
178   Bit8u rex_r, rex_x, rex_b;
179   Bit8u seg_override;
180   unsigned b1;
181   unsigned ilen;
182 
183 #define BX_AVX_VL128 0
184 #define BX_AVX_VL256 1
185   Bit8u vex_vvv, vex_l, vex_w;
186   int is_vex; // 0 - no VEX used, 1 - VEX is used, -1 - invalid VEX
187   int is_evex; // 0 - no EVEX used, 1 - EVEX is used, -1 - invalid EVEX
188   int is_xop; // 0 - no XOP used, 1 - XOP is used, -1 - invalid XOP
189   Bit8u modrm, mod, nnn, rm;
190   Bit8u sib, scale, index, base;
191   union {
192      Bit16u displ16;
193      Bit32u displ32;
194   } displacement;
195 
196   bx_bool evex_b;
197   bx_bool evex_z;
198   unsigned evex_ll_rc;
199 };
200 
x86_insn(bx_bool is32,bx_bool is64)201 BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
202 {
203   is_32 = is32;
204   is_64 = is64;
205 
206   if (is_64) {
207     os_64 = 0;
208     as_64 = 1;
209     os_32 = 1;
210     as_32 = 1;
211   }
212   else {
213     os_64 = 0;
214     as_64 = 0;
215     os_32 = is_32;
216     as_32 = is_32;
217   }
218 
219   extend8b = 0;
220   rex_r = rex_b = rex_x = 0;
221   seg_override = NO_SEG_OVERRIDE;
222   ilen = 0;
223   b1 = 0;
224 
225   is_vex = 0;
226   is_evex = 0;
227   is_xop = 0;
228   vex_vvv = 0;
229   vex_l = BX_AVX_VL128;
230   vex_w = 0;
231   modrm = mod = nnn = rm = 0;
232   sib = scale = index = base = 0;
233   displacement.displ32 = 0;
234 
235   evex_b = 0;
236   evex_ll_rc = 0;
237   evex_z = 0;
238 }
239 
240 class disassembler {
241 public:
disassembler()242   disassembler(): offset_mode_hex(0), print_mem_datasize(1) { set_syntax_intel(); }
243 
244   unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf);
245 
disasm16(bx_address cs_base,bx_address ip,const Bit8u * instr,char * disbuf)246   unsigned disasm16(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
247     { return disasm(0, 0, cs_base, ip, instr, disbuf); }
248 
disasm32(bx_address cs_base,bx_address ip,const Bit8u * instr,char * disbuf)249   unsigned disasm32(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
250     { return disasm(1, 0, cs_base, ip, instr, disbuf); }
251 
disasm64(bx_address cs_base,bx_address ip,const Bit8u * instr,char * disbuf)252   unsigned disasm64(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
253     { return disasm(1, 1, cs_base, ip, instr, disbuf); }
254 
255   x86_insn decode(bx_bool is_32, bx_bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf);
256 
decode16(bx_address cs_base,bx_address ip,const Bit8u * instr,char * disbuf)257   x86_insn decode16(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
258     { return decode(0, 0, cs_base, ip, instr, disbuf); }
259 
decode32(bx_address cs_base,bx_address ip,const Bit8u * instr,char * disbuf)260   x86_insn decode32(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
261     { return decode(1, 0, cs_base, ip, instr, disbuf); }
262 
decode64(bx_address cs_base,bx_address ip,const Bit8u * instr,char * disbuf)263   x86_insn decode64(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
264     { return decode(1, 1, cs_base, ip, instr, disbuf); }
265 
266   void set_syntax_intel();
267   void set_syntax_att();
268 
set_offset_mode_hex(bx_bool mode)269   void set_offset_mode_hex(bx_bool mode) { offset_mode_hex = mode; }
set_mem_datasize_print(bx_bool mode)270   void set_mem_datasize_print(bx_bool mode) { print_mem_datasize = mode; }
271 
272   void toggle_syntax_mode();
273 
274 private:
275   bx_bool intel_mode, offset_mode_hex, print_mem_datasize;
276 
277   const char **general_16bit_regname;
278   const char **general_8bit_regname;
279   const char **general_32bit_regname;
280   const char **general_8bit_regname_rex;
281   const char **general_64bit_regname;
282 
283   const char **segment_name;
284   const char **index16;
285   const char **vector_reg_name;
286 
287   const char *sreg_mod00_base32[16];
288   const char *sreg_mod01or10_base32[16];
289   const char *sreg_mod00_rm16[8];
290   const char *sreg_mod01or10_rm16[8];
291 
292 private:
293 
294   bx_address db_eip, db_cs_base;
295 
296   const Bit8u *instruction;        // for fetching of next byte of instruction
297 
298   char *disbufptr;
299 
300   BxDisasmResolveModrmPtr_t resolve_modrm;
301 
fetch_byte()302   BX_CPP_INLINE Bit8u  fetch_byte() {
303     db_eip++;
304     return(*instruction++);
305   };
306 
peek_byte()307   BX_CPP_INLINE Bit8u  peek_byte() {
308     return(*instruction);
309   };
310 
fetch_word()311   BX_CPP_INLINE Bit16u fetch_word() {
312     Bit8u b0 = * (Bit8u *) instruction++;
313     Bit8u b1 = * (Bit8u *) instruction++;
314     Bit16u ret16 = (b1<<8) | b0;
315     db_eip += 2;
316     return(ret16);
317   };
318 
fetch_dword()319   BX_CPP_INLINE Bit32u fetch_dword() {
320     Bit8u b0 = * (Bit8u *) instruction++;
321     Bit8u b1 = * (Bit8u *) instruction++;
322     Bit8u b2 = * (Bit8u *) instruction++;
323     Bit8u b3 = * (Bit8u *) instruction++;
324     Bit32u ret32 = (b3<<24) | (b2<<16) | (b1<<8) | b0;
325     db_eip += 4;
326     return(ret32);
327   };
328 
fetch_qword()329   BX_CPP_INLINE Bit64u fetch_qword() {
330     Bit64u d0 = fetch_dword();
331     Bit64u d1 = fetch_dword();
332     Bit64u ret64 = (d1<<32) | d0;
333     return(ret64);
334   };
335 
336   void dis_putc(char symbol);
337   void dis_sprintf(const char *fmt, ...);
338   void decode_modrm(x86_insn *insn);
339   unsigned decode_vex(x86_insn *insn);
340   unsigned decode_evex(x86_insn *insn);
341   unsigned decode_xop(x86_insn *insn);
342 
343   void resolve16_mod0   (const x86_insn *insn, unsigned mode);
344   void resolve16_mod1or2(const x86_insn *insn, unsigned mode);
345 
346   void resolve32_mod0   (const x86_insn *insn, unsigned mode);
347   void resolve32_mod1or2(const x86_insn *insn, unsigned mode);
348 
349   void resolve32_mod0_rm4   (const x86_insn *insn, unsigned mode);
350   void resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode);
351 
352   void resolve64_mod0   (const x86_insn *insn, unsigned mode);
353   void resolve64_mod1or2(const x86_insn *insn, unsigned mode);
354 
355   void resolve64_mod0_rm4   (const x86_insn *insn, unsigned mode);
356   void resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode);
357 
358   void initialize_modrm_segregs();
359 
360   void print_datasize(unsigned mode);
361 
362   void print_memory_access16(int datasize,
363           const char *seg, const char *index, Bit16u disp);
364   void print_memory_access32(int datasize,
365           const char *seg, const char *base, const char *index, int scale, Bit32s disp);
366   void print_memory_access64(int datasize,
367           const char *seg, const char *base, const char *index, int scale, Bit32s disp);
368 
369   void print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
370   void print_disassembly_att  (const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
371 
372 public:
373 
374 /*
375  * Codes for Addressing Method:
376  * ---------------------------
377  * A  - Direct address. The instruction has no ModR/M byte; the address
378  *      of the operand is encoded in the instruction; and no base register,
379  *      index register, or scaling factor can be applied.
380  * C  - The reg field of the ModR/M byte selects a control register.
381  * D  - The reg field of the ModR/M byte selects a debug register.
382  * E  - A ModR/M byte follows the opcode and specifies the operand. The
383  *      operand is either a general-purpose register or a memory address.
384  *      In case of the register operand, the R/M field of the ModR/M byte
385  *      selects a general register.
386  * F  - Flags Register.
387  * G  - The reg field of the ModR/M byte selects a general register.
388  * I  - Immediate data. The operand value is encoded in subsequent bytes of
389  *      the instruction.
390  * J  - The instruction contains a relative offset to be added to the
391  *      instruction pointer register.
392  * M  - The ModR/M byte may refer only to memory.
393  * N  - The R/M field of the ModR/M byte selects a packed-quadword  MMX
394         technology register.
395  * O  - The instruction has no ModR/M byte; the offset of the operand is
396  *      coded as a word or double word (depending on address size attribute)
397  *      in the instruction. No base register, index register, or scaling
398  *      factor can be applied.
399  * P  - The reg field of the ModR/M byte selects a packed quadword MMX
400  *      technology register.
401  * Q  - A ModR/M byte follows the opcode and specifies the operand. The
402  *      operand is either an MMX technology register or a memory address.
403  *      If it is a memory address, the address is computed from a segment
404  *      register and any of the following values: a base register, an
405  *      index register, a scaling factor, and a displacement.
406  * R  - The mod field of the ModR/M byte may refer only to a general register.
407  * S  - The reg field of the ModR/M byte selects a segment register.
408  * T  - The reg field of the ModR/M byte selects a test register.
409  * U  - The R/M field of the ModR/M byte selects a 128-bit XMM/256-bit YMM register.
410  * V  - The reg field of the ModR/M byte selects a 128-bit XMM/256-bit YMM register.
411  * W  - A ModR/M byte follows the opcode and specifies the operand. The
412  *      operand is either a 128-bit XMM/256-bit YMM register or a memory address.
413  *      If it is a memory address, the address is computed from a segment
414  *      register and any of the following values: a base register, an
415  *      index register, a scaling factor, and a displacement.
416  * X  - Memory addressed by the DS:rSI register pair.
417  * Y  - Memory addressed by the ES:rDI register pair.
418  */
419 
420 /*
421  * Codes for Operand Type:
422  * ----------------------
423  * a  - Two one-word operands in memory or two double-word operands in
424  *      memory, depending on operand-size attribute (used only by the BOUND
425  *      instruction).
426  * b  - Byte, regardless of operand-size attribute.
427  * d  - Doubleword, regardless of operand-size attribute.
428  * dq - Double-quadword, regardless of operand-size attribute.
429  * p  - 32-bit or 48-bit pointer, depending on operand-size attribute.
430  * pd - 128-bit/256-bit packed double-precision floating-point data.
431  * pi - Quadword MMX technology register (packed integer)
432  * ps - 128-bit/256-bit packed single-precision floating-point data.
433  * q  - Quadword, regardless of operand-size attribute.
434  * s  - 6-byte or 10-byte pseudo-descriptor.
435  * si - Doubleword integer register (scalar integer)
436  * ss - Scalar element of a packed single-precision floating data.
437  * sd - Scalar element of a packed double-precision floating data.
438  * v  - Word, doubleword or quadword, depending on operand-size attribute.
439  * w  - Word, regardless of operand-size attr.
440  * y  - Doubleword or quadword (in 64-bit mode) depending on 32/64 bit
441  *      operand size.
442  */
443 
444   // far call/jmp
445   void Apw(const x86_insn *insn);
446   void Apd(const x86_insn *insn);
447 
448   // 8-bit general purpose registers
449   void AL_Reg(const x86_insn *insn);
450   void CL_Reg(const x86_insn *insn);
451 
452   // 16-bit general purpose registers
453   void AX_Reg(const x86_insn *insn);
454   void DX_Reg(const x86_insn *insn);
455 
456   // 32-bit general purpose registers
457   void EAX_Reg(const x86_insn *insn);
458 
459   // 64-bit general purpose registers
460   void RAX_Reg(const x86_insn *insn);
461   void RCX_Reg(const x86_insn *insn);
462 
463   // segment registers
464   void CS(const x86_insn *insn);
465   void DS(const x86_insn *insn);
466   void ES(const x86_insn *insn);
467   void SS(const x86_insn *insn);
468   void FS(const x86_insn *insn);
469   void GS(const x86_insn *insn);
470 
471   // segment registers
472   void Sw(const x86_insn *insn);
473 
474   // control register
475   void Cd(const x86_insn *insn);
476   void Cq(const x86_insn *insn);
477 
478   // debug register
479   void Dd(const x86_insn *insn);
480   void Dq(const x86_insn *insn);
481 
482   //  8-bit general purpose register
483   void Reg8(const x86_insn *insn);
484 
485   // 16-bit general purpose register
486   void RX(const x86_insn *insn);
487 
488   // 32-bit general purpose register
489   void ERX(const x86_insn *insn);
490 
491   // 64-bit general purpose register
492   void RRX(const x86_insn *insn);
493 
494   // general purpose register or memory operand
495   void Eb(const x86_insn *insn);
496   void Ew(const x86_insn *insn);
497   void Ed(const x86_insn *insn);
498   void Eq(const x86_insn *insn);
499   void Ey(const x86_insn *insn);
500   void Ebd(const x86_insn *insn);
501   void Ewd(const x86_insn *insn);
502   void Edq(const x86_insn *insn);
503 
504   // general purpose register
505   void Gb(const x86_insn *insn);
506   void Gw(const x86_insn *insn);
507   void Gd(const x86_insn *insn);
508   void Gq(const x86_insn *insn);
509   void Gy(const x86_insn *insn);
510 
511   // vex encoded general purpose register
512   void By(const x86_insn *insn);
513 
514   // immediate
515   void I1(const x86_insn *insn);
516   void Ib(const x86_insn *insn);
517   void Iw(const x86_insn *insn);
518   void Id(const x86_insn *insn);
519   void Iq(const x86_insn *insn);
520 
521   // double immediate
522   void IbIb(const x86_insn *insn);
523   void IwIb(const x86_insn *insn);
524 
525   // sign extended immediate
526   void sIbw(const x86_insn *insn);
527   void sIbd(const x86_insn *insn);
528   void sIbq(const x86_insn *insn);
529   void sIdq(const x86_insn *insn);
530 
531   // floating point
532   void ST0(const x86_insn *insn);
533   void STi(const x86_insn *insn);
534 
535   // general purpose register
536   void Rw(const x86_insn *insn);
537   void Rd(const x86_insn *insn);
538   void Rq(const x86_insn *insn);
539   void Ry(const x86_insn *insn);
540 
541   // mmx register
542   void Pq(const x86_insn *insn);
543 
544   // mmx register or memory operand
545   void Qd(const x86_insn *insn);
546   void Qq(const x86_insn *insn);
547   void Vq(const x86_insn *insn);
548   void Nq(const x86_insn *insn);
549 
550   // xmm/ymm register
551   void Ups(const x86_insn *insn);
552   void Upd(const x86_insn *insn);
553   void Udq(const x86_insn *insn);
554   void Uq(const x86_insn *insn);
555 
556   void Vdq(const x86_insn *insn);
557   void Vss(const x86_insn *insn);
558   void Vsd(const x86_insn *insn);
559   void Vps(const x86_insn *insn);
560   void Vpd(const x86_insn *insn);
561   // xmm/ymm register through imm byte
562   void VIb(const x86_insn *insn);
563 
564   // xmm/ymm register or memory operand
565   void Wb(const x86_insn *insn);
566   void Ww(const x86_insn *insn);
567   void Wd(const x86_insn *insn);
568   void Wq(const x86_insn *insn);
569 
570   void Wdq(const x86_insn *insn);
571   void Wss(const x86_insn *insn);
572   void Wsd(const x86_insn *insn);
573   void Wps(const x86_insn *insn);
574   void Wpd(const x86_insn *insn);
575 
576   // vex encoded xmm/ymm register
577   void Hdq(const x86_insn *insn);
578   void Hps(const x86_insn *insn);
579   void Hpd(const x86_insn *insn);
580   void Hss(const x86_insn *insn);
581   void Hsd(const x86_insn *insn);
582 
583   // direct memory access
584   void OP_O(const x86_insn *insn, unsigned size);
585   void Ob(const x86_insn *insn);
586   void Ow(const x86_insn *insn);
587   void Od(const x86_insn *insn);
588   void Oq(const x86_insn *insn);
589 
590   // memory operand
591   void OP_M(const x86_insn *insn, unsigned size);
592   void Ma(const x86_insn *insn);
593   void Mp(const x86_insn *insn);
594   void Ms(const x86_insn *insn);
595   void Mx(const x86_insn *insn);
596   void Mb(const x86_insn *insn);
597   void Mw(const x86_insn *insn);
598   void Md(const x86_insn *insn);
599   void Mq(const x86_insn *insn);
600   void Mt(const x86_insn *insn);
601   void Mdq(const x86_insn *insn);
602   void Mps(const x86_insn *insn);
603   void Mpd(const x86_insn *insn);
604   void Mss(const x86_insn *insn);
605   void Msd(const x86_insn *insn);
606 
607   // gather VSib
608   void VSib(const x86_insn *insn);
609 
610   // string instructions
611   void OP_X(const x86_insn *insn, unsigned size);
612   void Xb(const x86_insn *insn);
613   void Xw(const x86_insn *insn);
614   void Xd(const x86_insn *insn);
615   void Xq(const x86_insn *insn);
616 
617   // string instructions
618   void OP_Y(const x86_insn *insn, unsigned size);
619   void Yb(const x86_insn *insn);
620   void Yw(const x86_insn *insn);
621   void Yd(const x86_insn *insn);
622   void Yq(const x86_insn *insn);
623 
624   // maskmovdq/maskmovdqu
625   void OP_sY(const x86_insn *insn, unsigned size);
626   void sYq(const x86_insn *insn);
627   void sYdq(const x86_insn *insn);
628 
629   // jump offset
630   void Jb(const x86_insn *insn);
631   void Jw(const x86_insn *insn);
632   void Jd(const x86_insn *insn);
633 };
634 
635 #endif
636