xref: /openbmc/qemu/target/i386/emulate/x86_decode.c (revision 27458df871097d7fc14b19d9e01c35d29737b9b3)
1*27458df8SWei Liu /*
2*27458df8SWei Liu  * Copyright (C) 2016 Veertu Inc,
3*27458df8SWei Liu  * Copyright (C) 2017 Google Inc,
4*27458df8SWei Liu  *
5*27458df8SWei Liu  * This program is free software; you can redistribute it and/or
6*27458df8SWei Liu  * modify it under the terms of the GNU Lesser General Public
7*27458df8SWei Liu  * License as published by the Free Software Foundation; either
8*27458df8SWei Liu  * version 2.1 of the License, or (at your option) any later version.
9*27458df8SWei Liu  *
10*27458df8SWei Liu  * This program is distributed in the hope that it will be useful,
11*27458df8SWei Liu  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*27458df8SWei Liu  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*27458df8SWei Liu  * Lesser General Public License for more details.
14*27458df8SWei Liu  *
15*27458df8SWei Liu  * You should have received a copy of the GNU Lesser General Public
16*27458df8SWei Liu  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
17*27458df8SWei Liu  */
18*27458df8SWei Liu 
19*27458df8SWei Liu #include "qemu/osdep.h"
20*27458df8SWei Liu 
21*27458df8SWei Liu #include "panic.h"
22*27458df8SWei Liu #include "x86_decode.h"
23*27458df8SWei Liu #include "x86_emu.h"
24*27458df8SWei Liu 
25*27458df8SWei Liu #define OPCODE_ESCAPE   0xf
26*27458df8SWei Liu 
27*27458df8SWei Liu static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
28*27458df8SWei Liu {
29*27458df8SWei Liu     printf("%llx: failed to decode instruction ", env->eip);
30*27458df8SWei Liu     for (int i = 0; i < decode->opcode_len; i++) {
31*27458df8SWei Liu         printf("%x ", decode->opcode[i]);
32*27458df8SWei Liu     }
33*27458df8SWei Liu     printf("\n");
34*27458df8SWei Liu     VM_PANIC("decoder failed\n");
35*27458df8SWei Liu }
36*27458df8SWei Liu 
37*27458df8SWei Liu uint64_t sign(uint64_t val, int size)
38*27458df8SWei Liu {
39*27458df8SWei Liu     switch (size) {
40*27458df8SWei Liu     case 1:
41*27458df8SWei Liu         val = (int8_t)val;
42*27458df8SWei Liu         break;
43*27458df8SWei Liu     case 2:
44*27458df8SWei Liu         val = (int16_t)val;
45*27458df8SWei Liu         break;
46*27458df8SWei Liu     case 4:
47*27458df8SWei Liu         val = (int32_t)val;
48*27458df8SWei Liu         break;
49*27458df8SWei Liu     case 8:
50*27458df8SWei Liu         val = (int64_t)val;
51*27458df8SWei Liu         break;
52*27458df8SWei Liu     default:
53*27458df8SWei Liu         VM_PANIC_EX("%s invalid size %d\n", __func__, size);
54*27458df8SWei Liu         break;
55*27458df8SWei Liu     }
56*27458df8SWei Liu     return val;
57*27458df8SWei Liu }
58*27458df8SWei Liu 
59*27458df8SWei Liu static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
60*27458df8SWei Liu                                     int size)
61*27458df8SWei Liu {
62*27458df8SWei Liu     uint64_t val = 0;
63*27458df8SWei Liu 
64*27458df8SWei Liu     switch (size) {
65*27458df8SWei Liu     case 1:
66*27458df8SWei Liu     case 2:
67*27458df8SWei Liu     case 4:
68*27458df8SWei Liu     case 8:
69*27458df8SWei Liu         break;
70*27458df8SWei Liu     default:
71*27458df8SWei Liu         VM_PANIC_EX("%s invalid size %d\n", __func__, size);
72*27458df8SWei Liu         break;
73*27458df8SWei Liu     }
74*27458df8SWei Liu     target_ulong va  = linear_rip(env_cpu(env), env->eip) + decode->len;
75*27458df8SWei Liu     emul_ops->read_mem(env_cpu(env), &val, va, size);
76*27458df8SWei Liu     decode->len += size;
77*27458df8SWei Liu 
78*27458df8SWei Liu     return val;
79*27458df8SWei Liu }
80*27458df8SWei Liu 
81*27458df8SWei Liu static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode)
82*27458df8SWei Liu {
83*27458df8SWei Liu     return (uint8_t)decode_bytes(env, decode, 1);
84*27458df8SWei Liu }
85*27458df8SWei Liu 
86*27458df8SWei Liu static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode)
87*27458df8SWei Liu {
88*27458df8SWei Liu     return (uint16_t)decode_bytes(env, decode, 2);
89*27458df8SWei Liu }
90*27458df8SWei Liu 
91*27458df8SWei Liu static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode)
92*27458df8SWei Liu {
93*27458df8SWei Liu     return (uint32_t)decode_bytes(env, decode, 4);
94*27458df8SWei Liu }
95*27458df8SWei Liu 
96*27458df8SWei Liu static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode)
97*27458df8SWei Liu {
98*27458df8SWei Liu     return decode_bytes(env, decode, 8);
99*27458df8SWei Liu }
100*27458df8SWei Liu 
101*27458df8SWei Liu static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode,
102*27458df8SWei Liu                             struct x86_decode_op *op)
103*27458df8SWei Liu {
104*27458df8SWei Liu     op->type = X86_VAR_RM;
105*27458df8SWei Liu }
106*27458df8SWei Liu 
107*27458df8SWei Liu static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode,
108*27458df8SWei Liu                              struct x86_decode_op *op)
109*27458df8SWei Liu {
110*27458df8SWei Liu     op->type = X86_VAR_REG;
111*27458df8SWei Liu     op->reg = decode->modrm.reg;
112*27458df8SWei Liu     op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
113*27458df8SWei Liu                           decode->operand_size);
114*27458df8SWei Liu }
115*27458df8SWei Liu 
116*27458df8SWei Liu static void decode_rax(CPUX86State *env, struct x86_decode *decode,
117*27458df8SWei Liu                        struct x86_decode_op *op)
118*27458df8SWei Liu {
119*27458df8SWei Liu     op->type = X86_VAR_REG;
120*27458df8SWei Liu     op->reg = R_EAX;
121*27458df8SWei Liu     /* Since reg is always AX, REX prefix has no impact. */
122*27458df8SWei Liu     op->ptr = get_reg_ref(env, op->reg, false, 0,
123*27458df8SWei Liu                           decode->operand_size);
124*27458df8SWei Liu }
125*27458df8SWei Liu 
126*27458df8SWei Liu static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode,
127*27458df8SWei Liu                                     struct x86_decode_op *var, int size)
128*27458df8SWei Liu {
129*27458df8SWei Liu     var->type = X86_VAR_IMMEDIATE;
130*27458df8SWei Liu     var->size = size;
131*27458df8SWei Liu     switch (size) {
132*27458df8SWei Liu     case 1:
133*27458df8SWei Liu         var->val = decode_byte(env, decode);
134*27458df8SWei Liu         break;
135*27458df8SWei Liu     case 2:
136*27458df8SWei Liu         var->val = decode_word(env, decode);
137*27458df8SWei Liu         break;
138*27458df8SWei Liu     case 4:
139*27458df8SWei Liu         var->val = decode_dword(env, decode);
140*27458df8SWei Liu         break;
141*27458df8SWei Liu     case 8:
142*27458df8SWei Liu         var->val = decode_qword(env, decode);
143*27458df8SWei Liu         break;
144*27458df8SWei Liu     default:
145*27458df8SWei Liu         VM_PANIC_EX("bad size %d\n", size);
146*27458df8SWei Liu     }
147*27458df8SWei Liu }
148*27458df8SWei Liu 
149*27458df8SWei Liu static void decode_imm8(CPUX86State *env, struct x86_decode *decode,
150*27458df8SWei Liu                         struct x86_decode_op *op)
151*27458df8SWei Liu {
152*27458df8SWei Liu     decode_immediate(env, decode, op, 1);
153*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
154*27458df8SWei Liu }
155*27458df8SWei Liu 
156*27458df8SWei Liu static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode,
157*27458df8SWei Liu                                struct x86_decode_op *op)
158*27458df8SWei Liu {
159*27458df8SWei Liu     decode_immediate(env, decode, op, 1);
160*27458df8SWei Liu     op->val = sign(op->val, 1);
161*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
162*27458df8SWei Liu }
163*27458df8SWei Liu 
164*27458df8SWei Liu static void decode_imm16(CPUX86State *env, struct x86_decode *decode,
165*27458df8SWei Liu                          struct x86_decode_op *op)
166*27458df8SWei Liu {
167*27458df8SWei Liu     decode_immediate(env, decode, op, 2);
168*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
169*27458df8SWei Liu }
170*27458df8SWei Liu 
171*27458df8SWei Liu 
172*27458df8SWei Liu static void decode_imm(CPUX86State *env, struct x86_decode *decode,
173*27458df8SWei Liu                        struct x86_decode_op *op)
174*27458df8SWei Liu {
175*27458df8SWei Liu     if (8 == decode->operand_size) {
176*27458df8SWei Liu         decode_immediate(env, decode, op, 4);
177*27458df8SWei Liu         op->val = sign(op->val, decode->operand_size);
178*27458df8SWei Liu     } else {
179*27458df8SWei Liu         decode_immediate(env, decode, op, decode->operand_size);
180*27458df8SWei Liu     }
181*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
182*27458df8SWei Liu }
183*27458df8SWei Liu 
184*27458df8SWei Liu static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode,
185*27458df8SWei Liu                               struct x86_decode_op *op)
186*27458df8SWei Liu {
187*27458df8SWei Liu     decode_immediate(env, decode, op, decode->operand_size);
188*27458df8SWei Liu     op->val = sign(op->val, decode->operand_size);
189*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
190*27458df8SWei Liu }
191*27458df8SWei Liu 
192*27458df8SWei Liu static void decode_imm_1(CPUX86State *env, struct x86_decode *decode,
193*27458df8SWei Liu                          struct x86_decode_op *op)
194*27458df8SWei Liu {
195*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
196*27458df8SWei Liu     op->val = 1;
197*27458df8SWei Liu }
198*27458df8SWei Liu 
199*27458df8SWei Liu static void decode_imm_0(CPUX86State *env, struct x86_decode *decode,
200*27458df8SWei Liu                          struct x86_decode_op *op)
201*27458df8SWei Liu {
202*27458df8SWei Liu     op->type = X86_VAR_IMMEDIATE;
203*27458df8SWei Liu     op->val = 0;
204*27458df8SWei Liu }
205*27458df8SWei Liu 
206*27458df8SWei Liu 
207*27458df8SWei Liu static void decode_pushseg(CPUX86State *env, struct x86_decode *decode)
208*27458df8SWei Liu {
209*27458df8SWei Liu     uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
210*27458df8SWei Liu 
211*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
212*27458df8SWei Liu     switch (op) {
213*27458df8SWei Liu     case 0xe:
214*27458df8SWei Liu         decode->op[0].reg = R_CS;
215*27458df8SWei Liu         break;
216*27458df8SWei Liu     case 0x16:
217*27458df8SWei Liu         decode->op[0].reg = R_SS;
218*27458df8SWei Liu         break;
219*27458df8SWei Liu     case 0x1e:
220*27458df8SWei Liu         decode->op[0].reg = R_DS;
221*27458df8SWei Liu         break;
222*27458df8SWei Liu     case 0x06:
223*27458df8SWei Liu         decode->op[0].reg = R_ES;
224*27458df8SWei Liu         break;
225*27458df8SWei Liu     case 0xa0:
226*27458df8SWei Liu         decode->op[0].reg = R_FS;
227*27458df8SWei Liu         break;
228*27458df8SWei Liu     case 0xa8:
229*27458df8SWei Liu         decode->op[0].reg = R_GS;
230*27458df8SWei Liu         break;
231*27458df8SWei Liu     }
232*27458df8SWei Liu }
233*27458df8SWei Liu 
234*27458df8SWei Liu static void decode_popseg(CPUX86State *env, struct x86_decode *decode)
235*27458df8SWei Liu {
236*27458df8SWei Liu     uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
237*27458df8SWei Liu 
238*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
239*27458df8SWei Liu     switch (op) {
240*27458df8SWei Liu     case 0xf:
241*27458df8SWei Liu         decode->op[0].reg = R_CS;
242*27458df8SWei Liu         break;
243*27458df8SWei Liu     case 0x17:
244*27458df8SWei Liu         decode->op[0].reg = R_SS;
245*27458df8SWei Liu         break;
246*27458df8SWei Liu     case 0x1f:
247*27458df8SWei Liu         decode->op[0].reg = R_DS;
248*27458df8SWei Liu         break;
249*27458df8SWei Liu     case 0x07:
250*27458df8SWei Liu         decode->op[0].reg = R_ES;
251*27458df8SWei Liu         break;
252*27458df8SWei Liu     case 0xa1:
253*27458df8SWei Liu         decode->op[0].reg = R_FS;
254*27458df8SWei Liu         break;
255*27458df8SWei Liu     case 0xa9:
256*27458df8SWei Liu         decode->op[0].reg = R_GS;
257*27458df8SWei Liu         break;
258*27458df8SWei Liu     }
259*27458df8SWei Liu }
260*27458df8SWei Liu 
261*27458df8SWei Liu static void decode_incgroup(CPUX86State *env, struct x86_decode *decode)
262*27458df8SWei Liu {
263*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
264*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0x40;
265*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
266*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
267*27458df8SWei Liu }
268*27458df8SWei Liu 
269*27458df8SWei Liu static void decode_decgroup(CPUX86State *env, struct x86_decode *decode)
270*27458df8SWei Liu {
271*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
272*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0x48;
273*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
274*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
275*27458df8SWei Liu }
276*27458df8SWei Liu 
277*27458df8SWei Liu static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode)
278*27458df8SWei Liu {
279*27458df8SWei Liu     if (!decode->modrm.reg) {
280*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_INC;
281*27458df8SWei Liu     } else if (1 == decode->modrm.reg) {
282*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_DEC;
283*27458df8SWei Liu     }
284*27458df8SWei Liu }
285*27458df8SWei Liu 
286*27458df8SWei Liu static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode)
287*27458df8SWei Liu {
288*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
289*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0x50;
290*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
291*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
292*27458df8SWei Liu }
293*27458df8SWei Liu 
294*27458df8SWei Liu static void decode_popgroup(CPUX86State *env, struct x86_decode *decode)
295*27458df8SWei Liu {
296*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
297*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0x58;
298*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
299*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
300*27458df8SWei Liu }
301*27458df8SWei Liu 
302*27458df8SWei Liu static void decode_jxx(CPUX86State *env, struct x86_decode *decode)
303*27458df8SWei Liu {
304*27458df8SWei Liu     decode->displacement = decode_bytes(env, decode, decode->operand_size);
305*27458df8SWei Liu     decode->displacement_size = decode->operand_size;
306*27458df8SWei Liu }
307*27458df8SWei Liu 
308*27458df8SWei Liu static void decode_farjmp(CPUX86State *env, struct x86_decode *decode)
309*27458df8SWei Liu {
310*27458df8SWei Liu     decode->op[0].type = X86_VAR_IMMEDIATE;
311*27458df8SWei Liu     decode->op[0].val = decode_bytes(env, decode, decode->operand_size);
312*27458df8SWei Liu     decode->displacement = decode_word(env, decode);
313*27458df8SWei Liu }
314*27458df8SWei Liu 
315*27458df8SWei Liu static void decode_addgroup(CPUX86State *env, struct x86_decode *decode)
316*27458df8SWei Liu {
317*27458df8SWei Liu     enum x86_decode_cmd group[] = {
318*27458df8SWei Liu         X86_DECODE_CMD_ADD,
319*27458df8SWei Liu         X86_DECODE_CMD_OR,
320*27458df8SWei Liu         X86_DECODE_CMD_ADC,
321*27458df8SWei Liu         X86_DECODE_CMD_SBB,
322*27458df8SWei Liu         X86_DECODE_CMD_AND,
323*27458df8SWei Liu         X86_DECODE_CMD_SUB,
324*27458df8SWei Liu         X86_DECODE_CMD_XOR,
325*27458df8SWei Liu         X86_DECODE_CMD_CMP
326*27458df8SWei Liu     };
327*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
328*27458df8SWei Liu }
329*27458df8SWei Liu 
330*27458df8SWei Liu static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode)
331*27458df8SWei Liu {
332*27458df8SWei Liu     enum x86_decode_cmd group[] = {
333*27458df8SWei Liu         X86_DECODE_CMD_ROL,
334*27458df8SWei Liu         X86_DECODE_CMD_ROR,
335*27458df8SWei Liu         X86_DECODE_CMD_RCL,
336*27458df8SWei Liu         X86_DECODE_CMD_RCR,
337*27458df8SWei Liu         X86_DECODE_CMD_SHL,
338*27458df8SWei Liu         X86_DECODE_CMD_SHR,
339*27458df8SWei Liu         X86_DECODE_CMD_SHL,
340*27458df8SWei Liu         X86_DECODE_CMD_SAR
341*27458df8SWei Liu     };
342*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
343*27458df8SWei Liu }
344*27458df8SWei Liu 
345*27458df8SWei Liu static void decode_f7group(CPUX86State *env, struct x86_decode *decode)
346*27458df8SWei Liu {
347*27458df8SWei Liu     enum x86_decode_cmd group[] = {
348*27458df8SWei Liu         X86_DECODE_CMD_TST,
349*27458df8SWei Liu         X86_DECODE_CMD_TST,
350*27458df8SWei Liu         X86_DECODE_CMD_NOT,
351*27458df8SWei Liu         X86_DECODE_CMD_NEG,
352*27458df8SWei Liu         X86_DECODE_CMD_MUL,
353*27458df8SWei Liu         X86_DECODE_CMD_IMUL_1,
354*27458df8SWei Liu         X86_DECODE_CMD_DIV,
355*27458df8SWei Liu         X86_DECODE_CMD_IDIV
356*27458df8SWei Liu     };
357*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
358*27458df8SWei Liu     decode_modrm_rm(env, decode, &decode->op[0]);
359*27458df8SWei Liu 
360*27458df8SWei Liu     switch (decode->modrm.reg) {
361*27458df8SWei Liu     case 0:
362*27458df8SWei Liu     case 1:
363*27458df8SWei Liu         decode_imm(env, decode, &decode->op[1]);
364*27458df8SWei Liu         break;
365*27458df8SWei Liu     case 2:
366*27458df8SWei Liu         break;
367*27458df8SWei Liu     case 3:
368*27458df8SWei Liu         decode->op[1].type = X86_VAR_IMMEDIATE;
369*27458df8SWei Liu         decode->op[1].val = 0;
370*27458df8SWei Liu         break;
371*27458df8SWei Liu     default:
372*27458df8SWei Liu         break;
373*27458df8SWei Liu     }
374*27458df8SWei Liu }
375*27458df8SWei Liu 
376*27458df8SWei Liu static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode)
377*27458df8SWei Liu {
378*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
379*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0x90;
380*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
381*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
382*27458df8SWei Liu }
383*27458df8SWei Liu 
384*27458df8SWei Liu static void decode_movgroup(CPUX86State *env, struct x86_decode *decode)
385*27458df8SWei Liu {
386*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
387*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0xb8;
388*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
389*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
390*27458df8SWei Liu     decode_immediate(env, decode, &decode->op[1], decode->operand_size);
391*27458df8SWei Liu }
392*27458df8SWei Liu 
393*27458df8SWei Liu static void fetch_moffs(CPUX86State *env, struct x86_decode *decode,
394*27458df8SWei Liu                         struct x86_decode_op *op)
395*27458df8SWei Liu {
396*27458df8SWei Liu     op->type = X86_VAR_OFFSET;
397*27458df8SWei Liu     op->ptr = decode_bytes(env, decode, decode->addressing_size);
398*27458df8SWei Liu }
399*27458df8SWei Liu 
400*27458df8SWei Liu static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode)
401*27458df8SWei Liu {
402*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
403*27458df8SWei Liu     decode->op[0].reg = decode->opcode[0] - 0xb0;
404*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
405*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
406*27458df8SWei Liu     decode_immediate(env, decode, &decode->op[1], decode->operand_size);
407*27458df8SWei Liu }
408*27458df8SWei Liu 
409*27458df8SWei Liu static void decode_rcx(CPUX86State *env, struct x86_decode *decode,
410*27458df8SWei Liu                        struct x86_decode_op *op)
411*27458df8SWei Liu {
412*27458df8SWei Liu     op->type = X86_VAR_REG;
413*27458df8SWei Liu     op->reg = R_ECX;
414*27458df8SWei Liu     op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b,
415*27458df8SWei Liu                           decode->operand_size);
416*27458df8SWei Liu }
417*27458df8SWei Liu 
418*27458df8SWei Liu struct decode_tbl {
419*27458df8SWei Liu     uint8_t opcode;
420*27458df8SWei Liu     enum x86_decode_cmd cmd;
421*27458df8SWei Liu     uint8_t operand_size;
422*27458df8SWei Liu     bool is_modrm;
423*27458df8SWei Liu     void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
424*27458df8SWei Liu                        struct x86_decode_op *op1);
425*27458df8SWei Liu     void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
426*27458df8SWei Liu                        struct x86_decode_op *op2);
427*27458df8SWei Liu     void (*decode_op3)(CPUX86State *env, struct x86_decode *decode,
428*27458df8SWei Liu                        struct x86_decode_op *op3);
429*27458df8SWei Liu     void (*decode_op4)(CPUX86State *env, struct x86_decode *decode,
430*27458df8SWei Liu                        struct x86_decode_op *op4);
431*27458df8SWei Liu     void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
432*27458df8SWei Liu     uint32_t flags_mask;
433*27458df8SWei Liu };
434*27458df8SWei Liu 
435*27458df8SWei Liu struct decode_x87_tbl {
436*27458df8SWei Liu     uint8_t opcode;
437*27458df8SWei Liu     uint8_t modrm_reg;
438*27458df8SWei Liu     uint8_t modrm_mod;
439*27458df8SWei Liu     enum x86_decode_cmd cmd;
440*27458df8SWei Liu     uint8_t operand_size;
441*27458df8SWei Liu     bool rev;
442*27458df8SWei Liu     bool pop;
443*27458df8SWei Liu     void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
444*27458df8SWei Liu                        struct x86_decode_op *op1);
445*27458df8SWei Liu     void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
446*27458df8SWei Liu                        struct x86_decode_op *op2);
447*27458df8SWei Liu     void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
448*27458df8SWei Liu     uint32_t flags_mask;
449*27458df8SWei Liu };
450*27458df8SWei Liu 
451*27458df8SWei Liu struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
452*27458df8SWei Liu                                decode_invalid};
453*27458df8SWei Liu 
454*27458df8SWei Liu struct decode_tbl _decode_tbl1[256];
455*27458df8SWei Liu struct decode_tbl _decode_tbl2[256];
456*27458df8SWei Liu struct decode_x87_tbl _decode_tbl3[256];
457*27458df8SWei Liu 
458*27458df8SWei Liu static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode)
459*27458df8SWei Liu {
460*27458df8SWei Liu     struct decode_x87_tbl *decoder;
461*27458df8SWei Liu 
462*27458df8SWei Liu     decode->is_fpu = true;
463*27458df8SWei Liu     int mode = decode->modrm.mod == 3 ? 1 : 0;
464*27458df8SWei Liu     int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) |
465*27458df8SWei Liu                  decode->modrm.reg;
466*27458df8SWei Liu 
467*27458df8SWei Liu     decoder = &_decode_tbl3[index];
468*27458df8SWei Liu 
469*27458df8SWei Liu     decode->cmd = decoder->cmd;
470*27458df8SWei Liu     if (decoder->operand_size) {
471*27458df8SWei Liu         decode->operand_size = decoder->operand_size;
472*27458df8SWei Liu     }
473*27458df8SWei Liu     decode->flags_mask = decoder->flags_mask;
474*27458df8SWei Liu     decode->fpop_stack = decoder->pop;
475*27458df8SWei Liu     decode->frev = decoder->rev;
476*27458df8SWei Liu 
477*27458df8SWei Liu     if (decoder->decode_op1) {
478*27458df8SWei Liu         decoder->decode_op1(env, decode, &decode->op[0]);
479*27458df8SWei Liu     }
480*27458df8SWei Liu     if (decoder->decode_op2) {
481*27458df8SWei Liu         decoder->decode_op2(env, decode, &decode->op[1]);
482*27458df8SWei Liu     }
483*27458df8SWei Liu     if (decoder->decode_postfix) {
484*27458df8SWei Liu         decoder->decode_postfix(env, decode);
485*27458df8SWei Liu     }
486*27458df8SWei Liu 
487*27458df8SWei Liu     VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n",
488*27458df8SWei Liu                    decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg,
489*27458df8SWei Liu                    decoder->modrm_mod);
490*27458df8SWei Liu }
491*27458df8SWei Liu 
492*27458df8SWei Liu static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode)
493*27458df8SWei Liu {
494*27458df8SWei Liu     enum x86_decode_cmd group[] = {
495*27458df8SWei Liu         X86_DECODE_CMD_INC,
496*27458df8SWei Liu         X86_DECODE_CMD_DEC,
497*27458df8SWei Liu         X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT,
498*27458df8SWei Liu         X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT,
499*27458df8SWei Liu         X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT,
500*27458df8SWei Liu         X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT,
501*27458df8SWei Liu         X86_DECODE_CMD_PUSH,
502*27458df8SWei Liu         X86_DECODE_CMD_INVL,
503*27458df8SWei Liu         X86_DECODE_CMD_INVL
504*27458df8SWei Liu     };
505*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
506*27458df8SWei Liu     if (decode->modrm.reg > 2) {
507*27458df8SWei Liu         decode->flags_mask = 0;
508*27458df8SWei Liu     }
509*27458df8SWei Liu }
510*27458df8SWei Liu 
511*27458df8SWei Liu static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode)
512*27458df8SWei Liu {
513*27458df8SWei Liu 
514*27458df8SWei Liu     enum x86_decode_cmd group[] = {
515*27458df8SWei Liu         X86_DECODE_CMD_SLDT,
516*27458df8SWei Liu         X86_DECODE_CMD_STR,
517*27458df8SWei Liu         X86_DECODE_CMD_LLDT,
518*27458df8SWei Liu         X86_DECODE_CMD_LTR,
519*27458df8SWei Liu         X86_DECODE_CMD_VERR,
520*27458df8SWei Liu         X86_DECODE_CMD_VERW,
521*27458df8SWei Liu         X86_DECODE_CMD_INVL,
522*27458df8SWei Liu         X86_DECODE_CMD_INVL
523*27458df8SWei Liu     };
524*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
525*27458df8SWei Liu }
526*27458df8SWei Liu 
527*27458df8SWei Liu static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode)
528*27458df8SWei Liu {
529*27458df8SWei Liu     enum x86_decode_cmd group[] = {
530*27458df8SWei Liu         X86_DECODE_CMD_SGDT,
531*27458df8SWei Liu         X86_DECODE_CMD_SIDT,
532*27458df8SWei Liu         X86_DECODE_CMD_LGDT,
533*27458df8SWei Liu         X86_DECODE_CMD_LIDT,
534*27458df8SWei Liu         X86_DECODE_CMD_SMSW,
535*27458df8SWei Liu         X86_DECODE_CMD_LMSW,
536*27458df8SWei Liu         X86_DECODE_CMD_LMSW,
537*27458df8SWei Liu         X86_DECODE_CMD_INVLPG
538*27458df8SWei Liu     };
539*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
540*27458df8SWei Liu     if (0xf9 == decode->modrm.modrm) {
541*27458df8SWei Liu         decode->opcode[decode->len++] = decode->modrm.modrm;
542*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_RDTSCP;
543*27458df8SWei Liu     }
544*27458df8SWei Liu }
545*27458df8SWei Liu 
546*27458df8SWei Liu static void decode_btgroup(CPUX86State *env, struct x86_decode *decode)
547*27458df8SWei Liu {
548*27458df8SWei Liu     enum x86_decode_cmd group[] = {
549*27458df8SWei Liu         X86_DECODE_CMD_INVL,
550*27458df8SWei Liu         X86_DECODE_CMD_INVL,
551*27458df8SWei Liu         X86_DECODE_CMD_INVL,
552*27458df8SWei Liu         X86_DECODE_CMD_INVL,
553*27458df8SWei Liu         X86_DECODE_CMD_BT,
554*27458df8SWei Liu         X86_DECODE_CMD_BTS,
555*27458df8SWei Liu         X86_DECODE_CMD_BTR,
556*27458df8SWei Liu         X86_DECODE_CMD_BTC
557*27458df8SWei Liu     };
558*27458df8SWei Liu     decode->cmd = group[decode->modrm.reg];
559*27458df8SWei Liu }
560*27458df8SWei Liu 
561*27458df8SWei Liu static void decode_x87_general(CPUX86State *env, struct x86_decode *decode)
562*27458df8SWei Liu {
563*27458df8SWei Liu     decode->is_fpu = true;
564*27458df8SWei Liu }
565*27458df8SWei Liu 
566*27458df8SWei Liu static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode,
567*27458df8SWei Liu                                     struct x86_decode_op *op)
568*27458df8SWei Liu {
569*27458df8SWei Liu     op->type = X87_VAR_FLOATP;
570*27458df8SWei Liu }
571*27458df8SWei Liu 
572*27458df8SWei Liu static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode,
573*27458df8SWei Liu                                   struct x86_decode_op *op)
574*27458df8SWei Liu {
575*27458df8SWei Liu     op->type = X87_VAR_INTP;
576*27458df8SWei Liu }
577*27458df8SWei Liu 
578*27458df8SWei Liu static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode,
579*27458df8SWei Liu                                    struct x86_decode_op *op)
580*27458df8SWei Liu {
581*27458df8SWei Liu     op->type = X87_VAR_BYTEP;
582*27458df8SWei Liu }
583*27458df8SWei Liu 
584*27458df8SWei Liu static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode,
585*27458df8SWei Liu                                  struct x86_decode_op *op)
586*27458df8SWei Liu {
587*27458df8SWei Liu     op->type = X87_VAR_REG;
588*27458df8SWei Liu     op->reg = 0;
589*27458df8SWei Liu }
590*27458df8SWei Liu 
591*27458df8SWei Liu static void decode_decode_x87_modrm_st0(CPUX86State *env,
592*27458df8SWei Liu                                         struct x86_decode *decode,
593*27458df8SWei Liu                                         struct x86_decode_op *op)
594*27458df8SWei Liu {
595*27458df8SWei Liu     op->type = X87_VAR_REG;
596*27458df8SWei Liu     op->reg = decode->modrm.modrm & 7;
597*27458df8SWei Liu }
598*27458df8SWei Liu 
599*27458df8SWei Liu 
600*27458df8SWei Liu static void decode_aegroup(CPUX86State *env, struct x86_decode *decode)
601*27458df8SWei Liu {
602*27458df8SWei Liu     decode->is_fpu = true;
603*27458df8SWei Liu     switch (decode->modrm.reg) {
604*27458df8SWei Liu     case 0:
605*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FXSAVE;
606*27458df8SWei Liu         decode_x87_modrm_bytep(env, decode, &decode->op[0]);
607*27458df8SWei Liu         break;
608*27458df8SWei Liu     case 1:
609*27458df8SWei Liu         decode_x87_modrm_bytep(env, decode, &decode->op[0]);
610*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FXRSTOR;
611*27458df8SWei Liu         break;
612*27458df8SWei Liu     case 5:
613*27458df8SWei Liu         if (decode->modrm.modrm == 0xe8) {
614*27458df8SWei Liu             decode->cmd = X86_DECODE_CMD_LFENCE;
615*27458df8SWei Liu         } else {
616*27458df8SWei Liu             VM_PANIC("xrstor");
617*27458df8SWei Liu         }
618*27458df8SWei Liu         break;
619*27458df8SWei Liu     case 6:
620*27458df8SWei Liu         VM_PANIC_ON(decode->modrm.modrm != 0xf0);
621*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_MFENCE;
622*27458df8SWei Liu         break;
623*27458df8SWei Liu     case 7:
624*27458df8SWei Liu         if (decode->modrm.modrm == 0xf8) {
625*27458df8SWei Liu             decode->cmd = X86_DECODE_CMD_SFENCE;
626*27458df8SWei Liu         } else {
627*27458df8SWei Liu             decode->cmd = X86_DECODE_CMD_CLFLUSH;
628*27458df8SWei Liu         }
629*27458df8SWei Liu         break;
630*27458df8SWei Liu     default:
631*27458df8SWei Liu         VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg);
632*27458df8SWei Liu         break;
633*27458df8SWei Liu     }
634*27458df8SWei Liu }
635*27458df8SWei Liu 
636*27458df8SWei Liu static void decode_bswap(CPUX86State *env, struct x86_decode *decode)
637*27458df8SWei Liu {
638*27458df8SWei Liu     decode->op[0].type = X86_VAR_REG;
639*27458df8SWei Liu     decode->op[0].reg = decode->opcode[1] - 0xc8;
640*27458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
641*27458df8SWei Liu                                     decode->rex.b, decode->operand_size);
642*27458df8SWei Liu }
643*27458df8SWei Liu 
644*27458df8SWei Liu static void decode_d9_4(CPUX86State *env, struct x86_decode *decode)
645*27458df8SWei Liu {
646*27458df8SWei Liu     switch (decode->modrm.modrm) {
647*27458df8SWei Liu     case 0xe0:
648*27458df8SWei Liu         /* FCHS */
649*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FCHS;
650*27458df8SWei Liu         break;
651*27458df8SWei Liu     case 0xe1:
652*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FABS;
653*27458df8SWei Liu         break;
654*27458df8SWei Liu     case 0xe4:
655*27458df8SWei Liu         VM_PANIC("FTST");
656*27458df8SWei Liu         break;
657*27458df8SWei Liu     case 0xe5:
658*27458df8SWei Liu         /* FXAM */
659*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FXAM;
660*27458df8SWei Liu         break;
661*27458df8SWei Liu     default:
662*27458df8SWei Liu         VM_PANIC("FLDENV");
663*27458df8SWei Liu         break;
664*27458df8SWei Liu     }
665*27458df8SWei Liu }
666*27458df8SWei Liu 
667*27458df8SWei Liu static void decode_db_4(CPUX86State *env, struct x86_decode *decode)
668*27458df8SWei Liu {
669*27458df8SWei Liu     switch (decode->modrm.modrm) {
670*27458df8SWei Liu     case 0xe0:
671*27458df8SWei Liu         VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0],
672*27458df8SWei Liu                     decode->modrm.modrm);
673*27458df8SWei Liu         break;
674*27458df8SWei Liu     case 0xe1:
675*27458df8SWei Liu         VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0],
676*27458df8SWei Liu                     decode->modrm.modrm);
677*27458df8SWei Liu         break;
678*27458df8SWei Liu     case 0xe2:
679*27458df8SWei Liu         VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0],
680*27458df8SWei Liu                     decode->modrm.modrm);
681*27458df8SWei Liu         break;
682*27458df8SWei Liu     case 0xe3:
683*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FNINIT;
684*27458df8SWei Liu         break;
685*27458df8SWei Liu     case 0xe4:
686*27458df8SWei Liu         decode->cmd = X86_DECODE_CMD_FNSETPM;
687*27458df8SWei Liu         break;
688*27458df8SWei Liu     default:
689*27458df8SWei Liu         VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0],
690*27458df8SWei Liu                     decode->modrm.modrm);
691*27458df8SWei Liu         break;
692*27458df8SWei Liu     }
693*27458df8SWei Liu }
694*27458df8SWei Liu 
695*27458df8SWei Liu 
696*27458df8SWei Liu #define RFLAGS_MASK_NONE    0
697*27458df8SWei Liu #define RFLAGS_MASK_OSZAPC  (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
698*27458df8SWei Liu #define RFLAGS_MASK_LAHF    (CC_S | CC_Z | CC_A | CC_P | CC_C)
699*27458df8SWei Liu #define RFLAGS_MASK_CF      (CC_C)
700*27458df8SWei Liu #define RFLAGS_MASK_IF      (IF_MASK)
701*27458df8SWei Liu #define RFLAGS_MASK_TF      (TF_MASK)
702*27458df8SWei Liu #define RFLAGS_MASK_DF      (DF_MASK)
703*27458df8SWei Liu #define RFLAGS_MASK_ZF      (CC_Z)
704*27458df8SWei Liu 
705*27458df8SWei Liu struct decode_tbl _1op_inst[] = {
706*27458df8SWei Liu     {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
707*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
708*27458df8SWei Liu     {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
709*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
710*27458df8SWei Liu     {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
711*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
712*27458df8SWei Liu     {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL,
713*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
714*27458df8SWei Liu     {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL,
715*27458df8SWei Liu      NULL, RFLAGS_MASK_OSZAPC},
716*27458df8SWei Liu     {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL,
717*27458df8SWei Liu      NULL, RFLAGS_MASK_OSZAPC},
718*27458df8SWei Liu     {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL,
719*27458df8SWei Liu      decode_pushseg, RFLAGS_MASK_NONE},
720*27458df8SWei Liu     {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL,
721*27458df8SWei Liu      decode_popseg, RFLAGS_MASK_NONE},
722*27458df8SWei Liu     {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
723*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
724*27458df8SWei Liu     {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
725*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
726*27458df8SWei Liu     {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
727*27458df8SWei Liu      NULL, NULL, RFLAGS_MASK_OSZAPC},
728*27458df8SWei Liu     {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm,
729*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
730*27458df8SWei Liu     {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8,
731*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
732*27458df8SWei Liu     {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm,
733*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
734*27458df8SWei Liu 
735*27458df8SWei Liu     {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
736*27458df8SWei Liu      NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
737*27458df8SWei Liu     {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false,
738*27458df8SWei Liu      NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
739*27458df8SWei Liu 
740*27458df8SWei Liu     {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg,
741*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
742*27458df8SWei Liu     {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg,
743*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
744*27458df8SWei Liu     {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm,
745*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
746*27458df8SWei Liu     {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm,
747*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
748*27458df8SWei Liu     {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm,
749*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
750*27458df8SWei Liu     {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm,
751*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
752*27458df8SWei Liu 
753*27458df8SWei Liu     {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
754*27458df8SWei Liu      NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
755*27458df8SWei Liu     {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false,
756*27458df8SWei Liu      NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
757*27458df8SWei Liu 
758*27458df8SWei Liu     {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg,
759*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
760*27458df8SWei Liu     {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg,
761*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
762*27458df8SWei Liu     {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm,
763*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
764*27458df8SWei Liu     {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm,
765*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
766*27458df8SWei Liu     {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8,
767*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
768*27458df8SWei Liu     {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm,
769*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
770*27458df8SWei Liu 
771*27458df8SWei Liu     {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
772*27458df8SWei Liu      NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
773*27458df8SWei Liu     {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false,
774*27458df8SWei Liu      NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
775*27458df8SWei Liu 
776*27458df8SWei Liu     {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg,
777*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
778*27458df8SWei Liu     {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg,
779*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
780*27458df8SWei Liu     {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm,
781*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
782*27458df8SWei Liu     {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm,
783*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
784*27458df8SWei Liu     {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm,
785*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
786*27458df8SWei Liu     {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm,
787*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
788*27458df8SWei Liu     {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg,
789*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
790*27458df8SWei Liu     {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg,
791*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
792*27458df8SWei Liu     {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm,
793*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
794*27458df8SWei Liu     {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm,
795*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
796*27458df8SWei Liu     {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm,
797*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
798*27458df8SWei Liu     {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm,
799*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
800*27458df8SWei Liu     {0x2f, X86_DECODE_CMD_DAS, 0, false,
801*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
802*27458df8SWei Liu     {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg,
803*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
804*27458df8SWei Liu     {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg,
805*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
806*27458df8SWei Liu     {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm,
807*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
808*27458df8SWei Liu     {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm,
809*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
810*27458df8SWei Liu     {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm,
811*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
812*27458df8SWei Liu     {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm,
813*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
814*27458df8SWei Liu 
815*27458df8SWei Liu     {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg,
816*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
817*27458df8SWei Liu     {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg,
818*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
819*27458df8SWei Liu     {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm,
820*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
821*27458df8SWei Liu     {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm,
822*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
823*27458df8SWei Liu     {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8,
824*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
825*27458df8SWei Liu     {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm,
826*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
827*27458df8SWei Liu 
828*27458df8SWei Liu     {0x3f, X86_DECODE_CMD_AAS, 0, false,
829*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
830*27458df8SWei Liu 
831*27458df8SWei Liu     {0x40, X86_DECODE_CMD_INC, 0, false,
832*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
833*27458df8SWei Liu     {0x41, X86_DECODE_CMD_INC, 0, false,
834*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
835*27458df8SWei Liu     {0x42, X86_DECODE_CMD_INC, 0, false,
836*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
837*27458df8SWei Liu     {0x43, X86_DECODE_CMD_INC, 0, false,
838*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
839*27458df8SWei Liu     {0x44, X86_DECODE_CMD_INC, 0, false,
840*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
841*27458df8SWei Liu     {0x45, X86_DECODE_CMD_INC, 0, false,
842*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
843*27458df8SWei Liu     {0x46, X86_DECODE_CMD_INC, 0, false,
844*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
845*27458df8SWei Liu     {0x47, X86_DECODE_CMD_INC, 0, false,
846*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
847*27458df8SWei Liu 
848*27458df8SWei Liu     {0x48, X86_DECODE_CMD_DEC, 0, false,
849*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
850*27458df8SWei Liu     {0x49, X86_DECODE_CMD_DEC, 0, false,
851*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
852*27458df8SWei Liu     {0x4a, X86_DECODE_CMD_DEC, 0, false,
853*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
854*27458df8SWei Liu     {0x4b, X86_DECODE_CMD_DEC, 0, false,
855*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
856*27458df8SWei Liu     {0x4c, X86_DECODE_CMD_DEC, 0, false,
857*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
858*27458df8SWei Liu     {0x4d, X86_DECODE_CMD_DEC, 0, false,
859*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
860*27458df8SWei Liu     {0x4e, X86_DECODE_CMD_DEC, 0, false,
861*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
862*27458df8SWei Liu     {0x4f, X86_DECODE_CMD_DEC, 0, false,
863*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
864*27458df8SWei Liu 
865*27458df8SWei Liu     {0x50, X86_DECODE_CMD_PUSH, 0, false,
866*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
867*27458df8SWei Liu     {0x51, X86_DECODE_CMD_PUSH, 0, false,
868*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
869*27458df8SWei Liu     {0x52, X86_DECODE_CMD_PUSH, 0, false,
870*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
871*27458df8SWei Liu     {0x53, X86_DECODE_CMD_PUSH, 0, false,
872*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
873*27458df8SWei Liu     {0x54, X86_DECODE_CMD_PUSH, 0, false,
874*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
875*27458df8SWei Liu     {0x55, X86_DECODE_CMD_PUSH, 0, false,
876*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
877*27458df8SWei Liu     {0x56, X86_DECODE_CMD_PUSH, 0, false,
878*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
879*27458df8SWei Liu     {0x57, X86_DECODE_CMD_PUSH, 0, false,
880*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
881*27458df8SWei Liu 
882*27458df8SWei Liu     {0x58, X86_DECODE_CMD_POP, 0, false,
883*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
884*27458df8SWei Liu     {0x59, X86_DECODE_CMD_POP, 0, false,
885*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
886*27458df8SWei Liu     {0x5a, X86_DECODE_CMD_POP, 0, false,
887*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
888*27458df8SWei Liu     {0x5b, X86_DECODE_CMD_POP, 0, false,
889*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
890*27458df8SWei Liu     {0x5c, X86_DECODE_CMD_POP, 0, false,
891*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
892*27458df8SWei Liu     {0x5d, X86_DECODE_CMD_POP, 0, false,
893*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
894*27458df8SWei Liu     {0x5e, X86_DECODE_CMD_POP, 0, false,
895*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
896*27458df8SWei Liu     {0x5f, X86_DECODE_CMD_POP, 0, false,
897*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
898*27458df8SWei Liu 
899*27458df8SWei Liu     {0x60, X86_DECODE_CMD_PUSHA, 0, false,
900*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
901*27458df8SWei Liu     {0x61, X86_DECODE_CMD_POPA, 0, false,
902*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
903*27458df8SWei Liu 
904*27458df8SWei Liu     {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm,
905*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
906*27458df8SWei Liu     {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed,
907*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
908*27458df8SWei Liu     {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg,
909*27458df8SWei Liu      decode_modrm_rm, decode_imm, NULL, NULL, RFLAGS_MASK_OSZAPC},
910*27458df8SWei Liu     {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm,
911*27458df8SWei Liu      decode_imm8_signed, NULL, NULL, RFLAGS_MASK_OSZAPC},
912*27458df8SWei Liu 
913*27458df8SWei Liu     {0x6c, X86_DECODE_CMD_INS, 1, false,
914*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
915*27458df8SWei Liu     {0x6d, X86_DECODE_CMD_INS, 0, false,
916*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
917*27458df8SWei Liu     {0x6e, X86_DECODE_CMD_OUTS, 1, false,
918*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
919*27458df8SWei Liu     {0x6f, X86_DECODE_CMD_OUTS, 0, false,
920*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
921*27458df8SWei Liu 
922*27458df8SWei Liu     {0x70, X86_DECODE_CMD_JXX, 1, false,
923*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
924*27458df8SWei Liu     {0x71, X86_DECODE_CMD_JXX, 1, false,
925*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
926*27458df8SWei Liu     {0x72, X86_DECODE_CMD_JXX, 1, false,
927*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
928*27458df8SWei Liu     {0x73, X86_DECODE_CMD_JXX, 1, false,
929*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
930*27458df8SWei Liu     {0x74, X86_DECODE_CMD_JXX, 1, false,
931*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
932*27458df8SWei Liu     {0x75, X86_DECODE_CMD_JXX, 1, false,
933*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
934*27458df8SWei Liu     {0x76, X86_DECODE_CMD_JXX, 1, false,
935*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
936*27458df8SWei Liu     {0x77, X86_DECODE_CMD_JXX, 1, false,
937*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
938*27458df8SWei Liu     {0x78, X86_DECODE_CMD_JXX, 1, false,
939*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
940*27458df8SWei Liu     {0x79, X86_DECODE_CMD_JXX, 1, false,
941*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
942*27458df8SWei Liu     {0x7a, X86_DECODE_CMD_JXX, 1, false,
943*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
944*27458df8SWei Liu     {0x7b, X86_DECODE_CMD_JXX, 1, false,
945*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
946*27458df8SWei Liu     {0x7c, X86_DECODE_CMD_JXX, 1, false,
947*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
948*27458df8SWei Liu     {0x7d, X86_DECODE_CMD_JXX, 1, false,
949*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
950*27458df8SWei Liu     {0x7e, X86_DECODE_CMD_JXX, 1, false,
951*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
952*27458df8SWei Liu     {0x7f, X86_DECODE_CMD_JXX, 1, false,
953*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
954*27458df8SWei Liu 
955*27458df8SWei Liu     {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
956*27458df8SWei Liu      NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
957*27458df8SWei Liu     {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm,
958*27458df8SWei Liu      NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
959*27458df8SWei Liu     {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
960*27458df8SWei Liu      NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
961*27458df8SWei Liu     {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed,
962*27458df8SWei Liu      NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
963*27458df8SWei Liu     {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg,
964*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
965*27458df8SWei Liu     {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg,
966*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
967*27458df8SWei Liu     {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm,
968*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
969*27458df8SWei Liu     {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm,
970*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
971*27458df8SWei Liu     {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg,
972*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
973*27458df8SWei Liu     {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg,
974*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
975*27458df8SWei Liu     {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm,
976*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
977*27458df8SWei Liu     {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm,
978*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
979*27458df8SWei Liu     {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm,
980*27458df8SWei Liu      decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
981*27458df8SWei Liu     {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm,
982*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
983*27458df8SWei Liu     {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg,
984*27458df8SWei Liu      decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
985*27458df8SWei Liu     {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm,
986*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
987*27458df8SWei Liu 
988*27458df8SWei Liu     {0x90, X86_DECODE_CMD_NOP, 0, false,
989*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
990*27458df8SWei Liu     {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
991*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
992*27458df8SWei Liu     {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
993*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
994*27458df8SWei Liu     {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
995*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
996*27458df8SWei Liu     {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
997*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
998*27458df8SWei Liu     {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
999*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1000*27458df8SWei Liu     {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
1001*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1002*27458df8SWei Liu     {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
1003*27458df8SWei Liu      NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1004*27458df8SWei Liu 
1005*27458df8SWei Liu     {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL,
1006*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1007*27458df8SWei Liu     {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL,
1008*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1009*27458df8SWei Liu 
1010*27458df8SWei Liu     {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL,
1011*27458df8SWei Liu      NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE},
1012*27458df8SWei Liu 
1013*27458df8SWei Liu     {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL,
1014*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1015*27458df8SWei Liu     /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL,
1016*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_POPF},*/
1017*27458df8SWei Liu     {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL,
1018*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1019*27458df8SWei Liu     {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL,
1020*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_LAHF},
1021*27458df8SWei Liu 
1022*27458df8SWei Liu     {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs,
1023*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1024*27458df8SWei Liu     {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs,
1025*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1026*27458df8SWei Liu     {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax,
1027*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1028*27458df8SWei Liu     {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax,
1029*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1030*27458df8SWei Liu 
1031*27458df8SWei Liu     {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL,
1032*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1033*27458df8SWei Liu     {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL,
1034*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1035*27458df8SWei Liu     {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL,
1036*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1037*27458df8SWei Liu     {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL,
1038*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1039*27458df8SWei Liu     {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL,
1040*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1041*27458df8SWei Liu     {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL,
1042*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1043*27458df8SWei Liu     {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL,
1044*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1045*27458df8SWei Liu     {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL,
1046*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1047*27458df8SWei Liu     {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL,
1048*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1049*27458df8SWei Liu     {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL,
1050*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1051*27458df8SWei Liu 
1052*27458df8SWei Liu     {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm,
1053*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1054*27458df8SWei Liu     {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm,
1055*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1056*27458df8SWei Liu 
1057*27458df8SWei Liu     {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL,
1058*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1059*27458df8SWei Liu     {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL,
1060*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1061*27458df8SWei Liu     {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL,
1062*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1063*27458df8SWei Liu     {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL,
1064*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1065*27458df8SWei Liu     {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL,
1066*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1067*27458df8SWei Liu     {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL,
1068*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1069*27458df8SWei Liu     {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL,
1070*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1071*27458df8SWei Liu     {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL,
1072*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1073*27458df8SWei Liu 
1074*27458df8SWei Liu     {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL,
1075*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1076*27458df8SWei Liu     {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL,
1077*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1078*27458df8SWei Liu     {0xba, X86_DECODE_CMD_MOV, 0, false, NULL,
1079*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1080*27458df8SWei Liu     {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL,
1081*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1082*27458df8SWei Liu     {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL,
1083*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1084*27458df8SWei Liu     {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL,
1085*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1086*27458df8SWei Liu     {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL,
1087*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1088*27458df8SWei Liu     {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL,
1089*27458df8SWei Liu      NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1090*27458df8SWei Liu 
1091*27458df8SWei Liu     {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
1092*27458df8SWei Liu      NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1093*27458df8SWei Liu     {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1094*27458df8SWei Liu      NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1095*27458df8SWei Liu 
1096*27458df8SWei Liu     {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16,
1097*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1098*27458df8SWei Liu     {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL,
1099*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1100*27458df8SWei Liu 
1101*27458df8SWei Liu     {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm,
1102*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1103*27458df8SWei Liu     {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm,
1104*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1105*27458df8SWei Liu 
1106*27458df8SWei Liu     {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8,
1107*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1108*27458df8SWei Liu     {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm,
1109*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1110*27458df8SWei Liu 
1111*27458df8SWei Liu     {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8,
1112*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1113*27458df8SWei Liu     {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL,
1114*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1115*27458df8SWei Liu     {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL,
1116*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1117*27458df8SWei Liu     {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL,
1118*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1119*27458df8SWei Liu     {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL,
1120*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1121*27458df8SWei Liu     /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL,
1122*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_IRET},*/
1123*27458df8SWei Liu 
1124*27458df8SWei Liu     {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1,
1125*27458df8SWei Liu      NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1126*27458df8SWei Liu     {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1,
1127*27458df8SWei Liu      NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1128*27458df8SWei Liu     {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx,
1129*27458df8SWei Liu      NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1130*27458df8SWei Liu     {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx,
1131*27458df8SWei Liu      NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1132*27458df8SWei Liu 
1133*27458df8SWei Liu     {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8,
1134*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1135*27458df8SWei Liu     {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8,
1136*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1137*27458df8SWei Liu 
1138*27458df8SWei Liu     {0xd7, X86_DECODE_CMD_XLAT, 0, false,
1139*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1140*27458df8SWei Liu 
1141*27458df8SWei Liu     {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL,
1142*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1143*27458df8SWei Liu     {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL,
1144*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1145*27458df8SWei Liu     {0xda, X86_DECODE_CMD_INVL, 0, true, NULL,
1146*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1147*27458df8SWei Liu     {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL,
1148*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1149*27458df8SWei Liu     {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL,
1150*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1151*27458df8SWei Liu     {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL,
1152*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1153*27458df8SWei Liu     {0xde, X86_DECODE_CMD_INVL, 0, true, NULL,
1154*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1155*27458df8SWei Liu     {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL,
1156*27458df8SWei Liu      NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1157*27458df8SWei Liu 
1158*27458df8SWei Liu     {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1159*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1160*27458df8SWei Liu     {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1161*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1162*27458df8SWei Liu     {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1163*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1164*27458df8SWei Liu 
1165*27458df8SWei Liu     {0xe3, X86_DECODE_CMD_JCXZ, 1, false,
1166*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1167*27458df8SWei Liu 
1168*27458df8SWei Liu     {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8,
1169*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1170*27458df8SWei Liu     {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8,
1171*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1172*27458df8SWei Liu     {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8,
1173*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1174*27458df8SWei Liu     {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8,
1175*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1176*27458df8SWei Liu     {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed,
1177*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1178*27458df8SWei Liu     {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed,
1179*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1180*27458df8SWei Liu     {0xea, X86_DECODE_CMD_JMP_FAR, 0, false,
1181*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE},
1182*27458df8SWei Liu     {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed,
1183*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1184*27458df8SWei Liu     {0xec, X86_DECODE_CMD_IN, 1, false,
1185*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1186*27458df8SWei Liu     {0xed, X86_DECODE_CMD_IN, 0, false,
1187*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1188*27458df8SWei Liu     {0xee, X86_DECODE_CMD_OUT, 1, false,
1189*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1190*27458df8SWei Liu     {0xef, X86_DECODE_CMD_OUT, 0, false,
1191*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1192*27458df8SWei Liu 
1193*27458df8SWei Liu     {0xf4, X86_DECODE_CMD_HLT, 0, false,
1194*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1195*27458df8SWei Liu 
1196*27458df8SWei Liu     {0xf5, X86_DECODE_CMD_CMC, 0, false,
1197*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
1198*27458df8SWei Liu 
1199*27458df8SWei Liu     {0xf6, X86_DECODE_CMD_INVL, 1, true,
1200*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC},
1201*27458df8SWei Liu     {0xf7, X86_DECODE_CMD_INVL, 0, true,
1202*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC},
1203*27458df8SWei Liu 
1204*27458df8SWei Liu     {0xf8, X86_DECODE_CMD_CLC, 0, false,
1205*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
1206*27458df8SWei Liu     {0xf9, X86_DECODE_CMD_STC, 0, false,
1207*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
1208*27458df8SWei Liu 
1209*27458df8SWei Liu     {0xfa, X86_DECODE_CMD_CLI, 0, false,
1210*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF},
1211*27458df8SWei Liu     {0xfb, X86_DECODE_CMD_STI, 0, false,
1212*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF},
1213*27458df8SWei Liu     {0xfc, X86_DECODE_CMD_CLD, 0, false,
1214*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF},
1215*27458df8SWei Liu     {0xfd, X86_DECODE_CMD_STD, 0, false,
1216*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF},
1217*27458df8SWei Liu     {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm,
1218*27458df8SWei Liu      NULL, NULL, NULL, decode_incgroup2, RFLAGS_MASK_OSZAPC},
1219*27458df8SWei Liu     {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1220*27458df8SWei Liu      NULL, NULL, NULL, decode_ffgroup, RFLAGS_MASK_OSZAPC},
1221*27458df8SWei Liu };
1222*27458df8SWei Liu 
1223*27458df8SWei Liu struct decode_tbl _2op_inst[] = {
1224*27458df8SWei Liu     {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1225*27458df8SWei Liu      NULL, NULL, NULL, decode_sldtgroup, RFLAGS_MASK_NONE},
1226*27458df8SWei Liu     {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1227*27458df8SWei Liu      NULL, NULL, NULL, decode_lidtgroup, RFLAGS_MASK_NONE},
1228*27458df8SWei Liu     {0x6, X86_DECODE_CMD_CLTS, 0, false,
1229*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_TF},
1230*27458df8SWei Liu     {0x9, X86_DECODE_CMD_WBINVD, 0, false,
1231*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1232*27458df8SWei Liu     {0x18, X86_DECODE_CMD_PREFETCH, 0, true,
1233*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE},
1234*27458df8SWei Liu     {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm,
1235*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1236*27458df8SWei Liu     {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm,
1237*27458df8SWei Liu      decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1238*27458df8SWei Liu     {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm,
1239*27458df8SWei Liu      decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1240*27458df8SWei Liu     {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg,
1241*27458df8SWei Liu      decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1242*27458df8SWei Liu     {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg,
1243*27458df8SWei Liu      decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1244*27458df8SWei Liu     {0x30, X86_DECODE_CMD_WRMSR, 0, false,
1245*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1246*27458df8SWei Liu     {0x31, X86_DECODE_CMD_RDTSC, 0, false,
1247*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1248*27458df8SWei Liu     {0x32, X86_DECODE_CMD_RDMSR, 0, false,
1249*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1250*27458df8SWei Liu     {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1251*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1252*27458df8SWei Liu     {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1253*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1254*27458df8SWei Liu     {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1255*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1256*27458df8SWei Liu     {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1257*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1258*27458df8SWei Liu     {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1259*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1260*27458df8SWei Liu     {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1261*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1262*27458df8SWei Liu     {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1263*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1264*27458df8SWei Liu     {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1265*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1266*27458df8SWei Liu     {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1267*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1268*27458df8SWei Liu     {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1269*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1270*27458df8SWei Liu     {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1271*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1272*27458df8SWei Liu     {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1273*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1274*27458df8SWei Liu     {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1275*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1276*27458df8SWei Liu     {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1277*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1278*27458df8SWei Liu     {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1279*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1280*27458df8SWei Liu     {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1281*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1282*27458df8SWei Liu     {0x77, X86_DECODE_CMD_EMMS, 0, false,
1283*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE},
1284*27458df8SWei Liu     {0x82, X86_DECODE_CMD_JXX, 0, false,
1285*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1286*27458df8SWei Liu     {0x83, X86_DECODE_CMD_JXX, 0, false,
1287*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1288*27458df8SWei Liu     {0x84, X86_DECODE_CMD_JXX, 0, false,
1289*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1290*27458df8SWei Liu     {0x85, X86_DECODE_CMD_JXX, 0, false,
1291*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1292*27458df8SWei Liu     {0x86, X86_DECODE_CMD_JXX, 0, false,
1293*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1294*27458df8SWei Liu     {0x87, X86_DECODE_CMD_JXX, 0, false,
1295*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1296*27458df8SWei Liu     {0x88, X86_DECODE_CMD_JXX, 0, false,
1297*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1298*27458df8SWei Liu     {0x89, X86_DECODE_CMD_JXX, 0, false,
1299*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1300*27458df8SWei Liu     {0x8a, X86_DECODE_CMD_JXX, 0, false,
1301*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1302*27458df8SWei Liu     {0x8b, X86_DECODE_CMD_JXX, 0, false,
1303*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1304*27458df8SWei Liu     {0x8c, X86_DECODE_CMD_JXX, 0, false,
1305*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1306*27458df8SWei Liu     {0x8d, X86_DECODE_CMD_JXX, 0, false,
1307*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1308*27458df8SWei Liu     {0x8e, X86_DECODE_CMD_JXX, 0, false,
1309*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1310*27458df8SWei Liu     {0x8f, X86_DECODE_CMD_JXX, 0, false,
1311*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1312*27458df8SWei Liu     {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1313*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1314*27458df8SWei Liu     {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1315*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1316*27458df8SWei Liu     {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1317*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1318*27458df8SWei Liu     {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1319*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1320*27458df8SWei Liu     {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1321*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1322*27458df8SWei Liu     {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1323*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1324*27458df8SWei Liu     {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1325*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1326*27458df8SWei Liu     {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1327*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1328*27458df8SWei Liu     {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1329*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1330*27458df8SWei Liu     {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1331*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1332*27458df8SWei Liu     {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1333*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1334*27458df8SWei Liu     {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1335*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1336*27458df8SWei Liu     {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1337*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1338*27458df8SWei Liu     {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1339*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1340*27458df8SWei Liu     {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1341*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1342*27458df8SWei Liu     {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1343*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1344*27458df8SWei Liu 
1345*27458df8SWei Liu     {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg,
1346*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1347*27458df8SWei Liu     {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg,
1348*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1349*27458df8SWei Liu 
1350*27458df8SWei Liu     {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1351*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1352*27458df8SWei Liu     {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1353*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1354*27458df8SWei Liu     {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm,
1355*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1356*27458df8SWei Liu     {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1357*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1358*27458df8SWei Liu     {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1359*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1360*27458df8SWei Liu     {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1361*27458df8SWei Liu      NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
1362*27458df8SWei Liu     {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false,
1363*27458df8SWei Liu      NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
1364*27458df8SWei Liu     {0xa2, X86_DECODE_CMD_CPUID, 0, false,
1365*27458df8SWei Liu      NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1366*27458df8SWei Liu     {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg,
1367*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_CF},
1368*27458df8SWei Liu     {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1369*27458df8SWei Liu      decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC},
1370*27458df8SWei Liu     {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1371*27458df8SWei Liu      decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC},
1372*27458df8SWei Liu     {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1373*27458df8SWei Liu      NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
1374*27458df8SWei Liu     {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false,
1375*27458df8SWei Liu      NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
1376*27458df8SWei Liu     {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg,
1377*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_CF},
1378*27458df8SWei Liu     {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1379*27458df8SWei Liu      decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC},
1380*27458df8SWei Liu     {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1381*27458df8SWei Liu      decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC},
1382*27458df8SWei Liu 
1383*27458df8SWei Liu     {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1384*27458df8SWei Liu      NULL, NULL, NULL, decode_aegroup, RFLAGS_MASK_NONE},
1385*27458df8SWei Liu 
1386*27458df8SWei Liu     {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm,
1387*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1388*27458df8SWei Liu     {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm,
1389*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_NONE},
1390*27458df8SWei Liu     {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg,
1391*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1392*27458df8SWei Liu     {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1393*27458df8SWei Liu      NULL, NULL, decode_btgroup, RFLAGS_MASK_OSZAPC},
1394*27458df8SWei Liu     {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg,
1395*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1396*27458df8SWei Liu     {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm,
1397*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1398*27458df8SWei Liu     {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm,
1399*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1400*27458df8SWei Liu 
1401*27458df8SWei Liu     {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg,
1402*27458df8SWei Liu      NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1403*27458df8SWei Liu 
1404*27458df8SWei Liu     {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm,
1405*27458df8SWei Liu      NULL, NULL, NULL, NULL, RFLAGS_MASK_ZF},
1406*27458df8SWei Liu 
1407*27458df8SWei Liu     {0xc8, X86_DECODE_CMD_BSWAP, 0, false,
1408*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1409*27458df8SWei Liu     {0xc9, X86_DECODE_CMD_BSWAP, 0, false,
1410*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1411*27458df8SWei Liu     {0xca, X86_DECODE_CMD_BSWAP, 0, false,
1412*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1413*27458df8SWei Liu     {0xcb, X86_DECODE_CMD_BSWAP, 0, false,
1414*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1415*27458df8SWei Liu     {0xcc, X86_DECODE_CMD_BSWAP, 0, false,
1416*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1417*27458df8SWei Liu     {0xcd, X86_DECODE_CMD_BSWAP, 0, false,
1418*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1419*27458df8SWei Liu     {0xce, X86_DECODE_CMD_BSWAP, 0, false,
1420*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1421*27458df8SWei Liu     {0xcf, X86_DECODE_CMD_BSWAP, 0, false,
1422*27458df8SWei Liu      NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1423*27458df8SWei Liu };
1424*27458df8SWei Liu 
1425*27458df8SWei Liu struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL,
1426*27458df8SWei Liu                                        NULL, decode_invalid, 0};
1427*27458df8SWei Liu 
1428*27458df8SWei Liu struct decode_x87_tbl _x87_inst[] = {
1429*27458df8SWei Liu     {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1430*27458df8SWei Liu      decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1431*27458df8SWei Liu     {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1432*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1433*27458df8SWei Liu     {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0,
1434*27458df8SWei Liu      decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1435*27458df8SWei Liu     {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1436*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1437*27458df8SWei Liu     {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0,
1438*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1439*27458df8SWei Liu     {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1440*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1441*27458df8SWei Liu     {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0,
1442*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1443*27458df8SWei Liu     {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1444*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1445*27458df8SWei Liu     {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0,
1446*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1447*27458df8SWei Liu     {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1448*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1449*27458df8SWei Liu     {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0,
1450*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1451*27458df8SWei Liu     {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1452*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1453*27458df8SWei Liu 
1454*27458df8SWei Liu     {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false,
1455*27458df8SWei Liu      decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1456*27458df8SWei Liu     {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1457*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1458*27458df8SWei Liu     {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0,
1459*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1460*27458df8SWei Liu     {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false,
1461*27458df8SWei Liu      decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1462*27458df8SWei Liu     {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false,
1463*27458df8SWei Liu      decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1464*27458df8SWei Liu     {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1465*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1466*27458df8SWei Liu     {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false,
1467*27458df8SWei Liu      decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1468*27458df8SWei Liu     {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1469*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1470*27458df8SWei Liu     {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false,
1471*27458df8SWei Liu      decode_x87_modrm_st0, NULL, decode_d9_4, RFLAGS_MASK_NONE},
1472*27458df8SWei Liu     {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false,
1473*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1474*27458df8SWei Liu     {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL,
1475*27458df8SWei Liu      RFLAGS_MASK_NONE},
1476*27458df8SWei Liu     {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false,
1477*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1478*27458df8SWei Liu 
1479*27458df8SWei Liu     {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false,
1480*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1481*27458df8SWei Liu     {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false,
1482*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1483*27458df8SWei Liu 
1484*27458df8SWei Liu     {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1485*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1486*27458df8SWei Liu     {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1487*27458df8SWei Liu      decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1488*27458df8SWei Liu     {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1489*27458df8SWei Liu      decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1490*27458df8SWei Liu     {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1491*27458df8SWei Liu      decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1492*27458df8SWei Liu     {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1493*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1494*27458df8SWei Liu     {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1495*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1496*27458df8SWei Liu     {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1497*27458df8SWei Liu      RFLAGS_MASK_NONE},
1498*27458df8SWei Liu     {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1499*27458df8SWei Liu      decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1500*27458df8SWei Liu     {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0,
1501*27458df8SWei Liu      decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1502*27458df8SWei Liu     {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1503*27458df8SWei Liu      decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1504*27458df8SWei Liu     {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1505*27458df8SWei Liu      RFLAGS_MASK_NONE},
1506*27458df8SWei Liu     {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1507*27458df8SWei Liu      decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1508*27458df8SWei Liu     {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1509*27458df8SWei Liu      RFLAGS_MASK_NONE},
1510*27458df8SWei Liu     {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1511*27458df8SWei Liu      decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1512*27458df8SWei Liu 
1513*27458df8SWei Liu     {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1514*27458df8SWei Liu      decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1515*27458df8SWei Liu     {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1516*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1517*27458df8SWei Liu     {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1518*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1519*27458df8SWei Liu     {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1520*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1521*27458df8SWei Liu     {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1522*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1523*27458df8SWei Liu     {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1524*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1525*27458df8SWei Liu     {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1526*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1527*27458df8SWei Liu     {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL,
1528*27458df8SWei Liu      decode_db_4, RFLAGS_MASK_NONE},
1529*27458df8SWei Liu     {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1530*27458df8SWei Liu      RFLAGS_MASK_NONE},
1531*27458df8SWei Liu     {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false,
1532*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1533*27458df8SWei Liu     {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false,
1534*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1535*27458df8SWei Liu     {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true,
1536*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1537*27458df8SWei Liu 
1538*27458df8SWei Liu     {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1539*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1540*27458df8SWei Liu     {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false,
1541*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1542*27458df8SWei Liu     {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false,
1543*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1544*27458df8SWei Liu     {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false,
1545*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1546*27458df8SWei Liu     {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false,
1547*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1548*27458df8SWei Liu     {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false,
1549*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1550*27458df8SWei Liu     {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false,
1551*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1552*27458df8SWei Liu     {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false,
1553*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1554*27458df8SWei Liu     {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false,
1555*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1556*27458df8SWei Liu     {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false,
1557*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1558*27458df8SWei Liu     {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false,
1559*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1560*27458df8SWei Liu     {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false,
1561*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1562*27458df8SWei Liu 
1563*27458df8SWei Liu     {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false,
1564*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1565*27458df8SWei Liu     {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1566*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1567*27458df8SWei Liu     {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false,
1568*27458df8SWei Liu      decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1569*27458df8SWei Liu     {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false,
1570*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1571*27458df8SWei Liu     {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1572*27458df8SWei Liu      decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1573*27458df8SWei Liu     {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true,
1574*27458df8SWei Liu      decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1575*27458df8SWei Liu     {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false,
1576*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1577*27458df8SWei Liu     {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false,
1578*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1579*27458df8SWei Liu     {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true,
1580*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1581*27458df8SWei Liu     {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false,
1582*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1583*27458df8SWei Liu     {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false,
1584*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1585*27458df8SWei Liu 
1586*27458df8SWei Liu     {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true,
1587*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1588*27458df8SWei Liu     {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false,
1589*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1590*27458df8SWei Liu     {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true,
1591*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1592*27458df8SWei Liu     {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false,
1593*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1594*27458df8SWei Liu     {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true,
1595*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1596*27458df8SWei Liu     {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false,
1597*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1598*27458df8SWei Liu     {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true,
1599*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1600*27458df8SWei Liu     {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false,
1601*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1602*27458df8SWei Liu     {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true,
1603*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1604*27458df8SWei Liu     {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false,
1605*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1606*27458df8SWei Liu     {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true,
1607*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1608*27458df8SWei Liu     {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false,
1609*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1610*27458df8SWei Liu 
1611*27458df8SWei Liu     {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false,
1612*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1613*27458df8SWei Liu     {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1614*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1615*27458df8SWei Liu     {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true,
1616*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1617*27458df8SWei Liu     {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false,
1618*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1619*27458df8SWei Liu     {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1620*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1621*27458df8SWei Liu     {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true,
1622*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1623*27458df8SWei Liu     {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true,
1624*27458df8SWei Liu      decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1625*27458df8SWei Liu     {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true,
1626*27458df8SWei Liu      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1627*27458df8SWei Liu     {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false,
1628*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1629*27458df8SWei Liu     {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true,
1630*27458df8SWei Liu      decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1631*27458df8SWei Liu };
1632*27458df8SWei Liu 
1633*27458df8SWei Liu void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
1634*27458df8SWei Liu                           struct x86_decode_op *op)
1635*27458df8SWei Liu {
1636*27458df8SWei Liu     target_ulong ptr = 0;
1637*27458df8SWei Liu     X86Seg seg = R_DS;
1638*27458df8SWei Liu 
1639*27458df8SWei Liu     if (!decode->modrm.mod && 6 == decode->modrm.rm) {
1640*27458df8SWei Liu         ptr = decode->displacement;
1641*27458df8SWei Liu         goto calc_addr;
1642*27458df8SWei Liu     }
1643*27458df8SWei Liu 
1644*27458df8SWei Liu     if (decode->displacement_size) {
1645*27458df8SWei Liu         ptr = sign(decode->displacement, decode->displacement_size);
1646*27458df8SWei Liu     }
1647*27458df8SWei Liu 
1648*27458df8SWei Liu     switch (decode->modrm.rm) {
1649*27458df8SWei Liu     case 0:
1650*27458df8SWei Liu         ptr += BX(env) + SI(env);
1651*27458df8SWei Liu         break;
1652*27458df8SWei Liu     case 1:
1653*27458df8SWei Liu         ptr += BX(env) + DI(env);
1654*27458df8SWei Liu         break;
1655*27458df8SWei Liu     case 2:
1656*27458df8SWei Liu         ptr += BP(env) + SI(env);
1657*27458df8SWei Liu         seg = R_SS;
1658*27458df8SWei Liu         break;
1659*27458df8SWei Liu     case 3:
1660*27458df8SWei Liu         ptr += BP(env) + DI(env);
1661*27458df8SWei Liu         seg = R_SS;
1662*27458df8SWei Liu         break;
1663*27458df8SWei Liu     case 4:
1664*27458df8SWei Liu         ptr += SI(env);
1665*27458df8SWei Liu         break;
1666*27458df8SWei Liu     case 5:
1667*27458df8SWei Liu         ptr += DI(env);
1668*27458df8SWei Liu         break;
1669*27458df8SWei Liu     case 6:
1670*27458df8SWei Liu         ptr += BP(env);
1671*27458df8SWei Liu         seg = R_SS;
1672*27458df8SWei Liu         break;
1673*27458df8SWei Liu     case 7:
1674*27458df8SWei Liu         ptr += BX(env);
1675*27458df8SWei Liu         break;
1676*27458df8SWei Liu     }
1677*27458df8SWei Liu calc_addr:
1678*27458df8SWei Liu     if (X86_DECODE_CMD_LEA == decode->cmd) {
1679*27458df8SWei Liu         op->ptr = (uint16_t)ptr;
1680*27458df8SWei Liu     } else {
1681*27458df8SWei Liu         op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
1682*27458df8SWei Liu     }
1683*27458df8SWei Liu }
1684*27458df8SWei Liu 
1685*27458df8SWei Liu target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
1686*27458df8SWei Liu                          int is_extended, int size)
1687*27458df8SWei Liu {
1688*27458df8SWei Liu     target_ulong ptr = 0;
1689*27458df8SWei Liu 
1690*27458df8SWei Liu     if (is_extended) {
1691*27458df8SWei Liu         reg |= R_R8;
1692*27458df8SWei Liu     }
1693*27458df8SWei Liu 
1694*27458df8SWei Liu     switch (size) {
1695*27458df8SWei Liu     case 1:
1696*27458df8SWei Liu         if (is_extended || reg < 4 || rex_present) {
1697*27458df8SWei Liu             ptr = (target_ulong)&RL(env, reg);
1698*27458df8SWei Liu         } else {
1699*27458df8SWei Liu             ptr = (target_ulong)&RH(env, reg - 4);
1700*27458df8SWei Liu         }
1701*27458df8SWei Liu         break;
1702*27458df8SWei Liu     default:
1703*27458df8SWei Liu         ptr = (target_ulong)&RRX(env, reg);
1704*27458df8SWei Liu         break;
1705*27458df8SWei Liu     }
1706*27458df8SWei Liu     return ptr;
1707*27458df8SWei Liu }
1708*27458df8SWei Liu 
1709*27458df8SWei Liu target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
1710*27458df8SWei Liu                          int is_extended, int size)
1711*27458df8SWei Liu {
1712*27458df8SWei Liu     target_ulong val = 0;
1713*27458df8SWei Liu     memcpy(&val,
1714*27458df8SWei Liu            (void *)get_reg_ref(env, reg, rex_present, is_extended, size),
1715*27458df8SWei Liu            size);
1716*27458df8SWei Liu     return val;
1717*27458df8SWei Liu }
1718*27458df8SWei Liu 
1719*27458df8SWei Liu static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode,
1720*27458df8SWei Liu                           X86Seg *sel)
1721*27458df8SWei Liu {
1722*27458df8SWei Liu     target_ulong base = 0;
1723*27458df8SWei Liu     target_ulong scaled_index = 0;
1724*27458df8SWei Liu     int addr_size = decode->addressing_size;
1725*27458df8SWei Liu     int base_reg = decode->sib.base;
1726*27458df8SWei Liu     int index_reg = decode->sib.index;
1727*27458df8SWei Liu 
1728*27458df8SWei Liu     *sel = R_DS;
1729*27458df8SWei Liu 
1730*27458df8SWei Liu     if (decode->modrm.mod || base_reg != R_EBP) {
1731*27458df8SWei Liu         if (decode->rex.b) {
1732*27458df8SWei Liu             base_reg |= R_R8;
1733*27458df8SWei Liu         }
1734*27458df8SWei Liu         if (base_reg == R_ESP || base_reg == R_EBP) {
1735*27458df8SWei Liu             *sel = R_SS;
1736*27458df8SWei Liu         }
1737*27458df8SWei Liu         base = get_reg_val(env, decode->sib.base, decode->rex.rex,
1738*27458df8SWei Liu                            decode->rex.b, addr_size);
1739*27458df8SWei Liu     }
1740*27458df8SWei Liu 
1741*27458df8SWei Liu     if (decode->rex.x) {
1742*27458df8SWei Liu         index_reg |= R_R8;
1743*27458df8SWei Liu     }
1744*27458df8SWei Liu 
1745*27458df8SWei Liu     if (index_reg != R_ESP) {
1746*27458df8SWei Liu         scaled_index = get_reg_val(env, index_reg, decode->rex.rex,
1747*27458df8SWei Liu                                    decode->rex.x, addr_size) <<
1748*27458df8SWei Liu                                    decode->sib.scale;
1749*27458df8SWei Liu     }
1750*27458df8SWei Liu     return base + scaled_index;
1751*27458df8SWei Liu }
1752*27458df8SWei Liu 
1753*27458df8SWei Liu void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
1754*27458df8SWei Liu                           struct x86_decode_op *op)
1755*27458df8SWei Liu {
1756*27458df8SWei Liu     X86Seg seg = R_DS;
1757*27458df8SWei Liu     target_ulong ptr = 0;
1758*27458df8SWei Liu     int addr_size = decode->addressing_size;
1759*27458df8SWei Liu 
1760*27458df8SWei Liu     if (decode->displacement_size) {
1761*27458df8SWei Liu         ptr = sign(decode->displacement, decode->displacement_size);
1762*27458df8SWei Liu     }
1763*27458df8SWei Liu 
1764*27458df8SWei Liu     if (4 == decode->modrm.rm) {
1765*27458df8SWei Liu         ptr += get_sib_val(env, decode, &seg);
1766*27458df8SWei Liu     } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
1767*27458df8SWei Liu         if (x86_is_long_mode(env_cpu(env))) {
1768*27458df8SWei Liu             ptr += env->eip + decode->len;
1769*27458df8SWei Liu         } else {
1770*27458df8SWei Liu             ptr = decode->displacement;
1771*27458df8SWei Liu         }
1772*27458df8SWei Liu     } else {
1773*27458df8SWei Liu         if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) {
1774*27458df8SWei Liu             seg = R_SS;
1775*27458df8SWei Liu         }
1776*27458df8SWei Liu         ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex,
1777*27458df8SWei Liu                            decode->rex.b, addr_size);
1778*27458df8SWei Liu     }
1779*27458df8SWei Liu 
1780*27458df8SWei Liu     if (X86_DECODE_CMD_LEA == decode->cmd) {
1781*27458df8SWei Liu         op->ptr = (uint32_t)ptr;
1782*27458df8SWei Liu     } else {
1783*27458df8SWei Liu         op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
1784*27458df8SWei Liu     }
1785*27458df8SWei Liu }
1786*27458df8SWei Liu 
1787*27458df8SWei Liu void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
1788*27458df8SWei Liu                           struct x86_decode_op *op)
1789*27458df8SWei Liu {
1790*27458df8SWei Liu     X86Seg seg = R_DS;
1791*27458df8SWei Liu     int32_t offset = 0;
1792*27458df8SWei Liu     int mod = decode->modrm.mod;
1793*27458df8SWei Liu     int rm = decode->modrm.rm;
1794*27458df8SWei Liu     target_ulong ptr;
1795*27458df8SWei Liu     int src = decode->modrm.rm;
1796*27458df8SWei Liu 
1797*27458df8SWei Liu     if (decode->displacement_size) {
1798*27458df8SWei Liu         offset = sign(decode->displacement, decode->displacement_size);
1799*27458df8SWei Liu     }
1800*27458df8SWei Liu 
1801*27458df8SWei Liu     if (4 == rm) {
1802*27458df8SWei Liu         ptr = get_sib_val(env, decode, &seg) + offset;
1803*27458df8SWei Liu     } else if (0 == mod && 5 == rm) {
1804*27458df8SWei Liu         ptr = env->eip + decode->len + (int32_t) offset;
1805*27458df8SWei Liu     } else {
1806*27458df8SWei Liu         ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) +
1807*27458df8SWei Liu               (int64_t) offset;
1808*27458df8SWei Liu     }
1809*27458df8SWei Liu 
1810*27458df8SWei Liu     if (X86_DECODE_CMD_LEA == decode->cmd) {
1811*27458df8SWei Liu         op->ptr = ptr;
1812*27458df8SWei Liu     } else {
1813*27458df8SWei Liu         op->ptr = decode_linear_addr(env, decode, ptr, seg);
1814*27458df8SWei Liu     }
1815*27458df8SWei Liu }
1816*27458df8SWei Liu 
1817*27458df8SWei Liu 
1818*27458df8SWei Liu void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
1819*27458df8SWei Liu                         struct x86_decode_op *op)
1820*27458df8SWei Liu {
1821*27458df8SWei Liu     if (3 == decode->modrm.mod) {
1822*27458df8SWei Liu         op->reg = decode->modrm.reg;
1823*27458df8SWei Liu         op->type = X86_VAR_REG;
1824*27458df8SWei Liu         op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
1825*27458df8SWei Liu                               decode->rex.b, decode->operand_size);
1826*27458df8SWei Liu         return;
1827*27458df8SWei Liu     }
1828*27458df8SWei Liu 
1829*27458df8SWei Liu     switch (decode->addressing_size) {
1830*27458df8SWei Liu     case 2:
1831*27458df8SWei Liu         calc_modrm_operand16(env, decode, op);
1832*27458df8SWei Liu         break;
1833*27458df8SWei Liu     case 4:
1834*27458df8SWei Liu         calc_modrm_operand32(env, decode, op);
1835*27458df8SWei Liu         break;
1836*27458df8SWei Liu     case 8:
1837*27458df8SWei Liu         calc_modrm_operand64(env, decode, op);
1838*27458df8SWei Liu         break;
1839*27458df8SWei Liu     default:
1840*27458df8SWei Liu         VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
1841*27458df8SWei Liu         break;
1842*27458df8SWei Liu     }
1843*27458df8SWei Liu }
1844*27458df8SWei Liu 
1845*27458df8SWei Liu static void decode_prefix(CPUX86State *env, struct x86_decode *decode)
1846*27458df8SWei Liu {
1847*27458df8SWei Liu     while (1) {
1848*27458df8SWei Liu         /*
1849*27458df8SWei Liu          * REX prefix must come after legacy prefixes.
1850*27458df8SWei Liu          * REX before legacy is ignored.
1851*27458df8SWei Liu          * Clear rex to simulate this.
1852*27458df8SWei Liu          */
1853*27458df8SWei Liu         uint8_t byte = decode_byte(env, decode);
1854*27458df8SWei Liu         switch (byte) {
1855*27458df8SWei Liu         case PREFIX_LOCK:
1856*27458df8SWei Liu             decode->lock = byte;
1857*27458df8SWei Liu             decode->rex.rex = 0;
1858*27458df8SWei Liu             break;
1859*27458df8SWei Liu         case PREFIX_REPN:
1860*27458df8SWei Liu         case PREFIX_REP:
1861*27458df8SWei Liu             decode->rep = byte;
1862*27458df8SWei Liu             decode->rex.rex = 0;
1863*27458df8SWei Liu             break;
1864*27458df8SWei Liu         case PREFIX_CS_SEG_OVERRIDE:
1865*27458df8SWei Liu         case PREFIX_SS_SEG_OVERRIDE:
1866*27458df8SWei Liu         case PREFIX_DS_SEG_OVERRIDE:
1867*27458df8SWei Liu         case PREFIX_ES_SEG_OVERRIDE:
1868*27458df8SWei Liu         case PREFIX_FS_SEG_OVERRIDE:
1869*27458df8SWei Liu         case PREFIX_GS_SEG_OVERRIDE:
1870*27458df8SWei Liu             decode->segment_override = byte;
1871*27458df8SWei Liu             decode->rex.rex = 0;
1872*27458df8SWei Liu             break;
1873*27458df8SWei Liu         case PREFIX_OP_SIZE_OVERRIDE:
1874*27458df8SWei Liu             decode->op_size_override = byte;
1875*27458df8SWei Liu             decode->rex.rex = 0;
1876*27458df8SWei Liu             break;
1877*27458df8SWei Liu         case PREFIX_ADDR_SIZE_OVERRIDE:
1878*27458df8SWei Liu             decode->addr_size_override = byte;
1879*27458df8SWei Liu             decode->rex.rex = 0;
1880*27458df8SWei Liu             break;
1881*27458df8SWei Liu         case PREFIX_REX ... (PREFIX_REX + 0xf):
1882*27458df8SWei Liu             if (x86_is_long_mode(env_cpu(env))) {
1883*27458df8SWei Liu                 decode->rex.rex = byte;
1884*27458df8SWei Liu                 break;
1885*27458df8SWei Liu             }
1886*27458df8SWei Liu             /* fall through when not in long mode */
1887*27458df8SWei Liu         default:
1888*27458df8SWei Liu             decode->len--;
1889*27458df8SWei Liu             return;
1890*27458df8SWei Liu         }
1891*27458df8SWei Liu     }
1892*27458df8SWei Liu }
1893*27458df8SWei Liu 
1894*27458df8SWei Liu void set_addressing_size(CPUX86State *env, struct x86_decode *decode)
1895*27458df8SWei Liu {
1896*27458df8SWei Liu     decode->addressing_size = -1;
1897*27458df8SWei Liu     if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
1898*27458df8SWei Liu         if (decode->addr_size_override) {
1899*27458df8SWei Liu             decode->addressing_size = 4;
1900*27458df8SWei Liu         } else {
1901*27458df8SWei Liu             decode->addressing_size = 2;
1902*27458df8SWei Liu         }
1903*27458df8SWei Liu     } else if (!x86_is_long_mode(env_cpu(env))) {
1904*27458df8SWei Liu         /* protected */
1905*27458df8SWei Liu         x86_segment_descriptor cs;
1906*27458df8SWei Liu         emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
1907*27458df8SWei Liu         /* check db */
1908*27458df8SWei Liu         if (cs.db) {
1909*27458df8SWei Liu             if (decode->addr_size_override) {
1910*27458df8SWei Liu                 decode->addressing_size = 2;
1911*27458df8SWei Liu             } else {
1912*27458df8SWei Liu                 decode->addressing_size = 4;
1913*27458df8SWei Liu             }
1914*27458df8SWei Liu         } else {
1915*27458df8SWei Liu             if (decode->addr_size_override) {
1916*27458df8SWei Liu                 decode->addressing_size = 4;
1917*27458df8SWei Liu             } else {
1918*27458df8SWei Liu                 decode->addressing_size = 2;
1919*27458df8SWei Liu             }
1920*27458df8SWei Liu         }
1921*27458df8SWei Liu     } else {
1922*27458df8SWei Liu         /* long */
1923*27458df8SWei Liu         if (decode->addr_size_override) {
1924*27458df8SWei Liu             decode->addressing_size = 4;
1925*27458df8SWei Liu         } else {
1926*27458df8SWei Liu             decode->addressing_size = 8;
1927*27458df8SWei Liu         }
1928*27458df8SWei Liu     }
1929*27458df8SWei Liu }
1930*27458df8SWei Liu 
1931*27458df8SWei Liu void set_operand_size(CPUX86State *env, struct x86_decode *decode)
1932*27458df8SWei Liu {
1933*27458df8SWei Liu     decode->operand_size = -1;
1934*27458df8SWei Liu     if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
1935*27458df8SWei Liu         if (decode->op_size_override) {
1936*27458df8SWei Liu             decode->operand_size = 4;
1937*27458df8SWei Liu         } else {
1938*27458df8SWei Liu             decode->operand_size = 2;
1939*27458df8SWei Liu         }
1940*27458df8SWei Liu     } else if (!x86_is_long_mode(env_cpu(env))) {
1941*27458df8SWei Liu         /* protected */
1942*27458df8SWei Liu         x86_segment_descriptor cs;
1943*27458df8SWei Liu         emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
1944*27458df8SWei Liu         /* check db */
1945*27458df8SWei Liu         if (cs.db) {
1946*27458df8SWei Liu             if (decode->op_size_override) {
1947*27458df8SWei Liu                 decode->operand_size = 2;
1948*27458df8SWei Liu             } else{
1949*27458df8SWei Liu                 decode->operand_size = 4;
1950*27458df8SWei Liu             }
1951*27458df8SWei Liu         } else {
1952*27458df8SWei Liu             if (decode->op_size_override) {
1953*27458df8SWei Liu                 decode->operand_size = 4;
1954*27458df8SWei Liu             } else {
1955*27458df8SWei Liu                 decode->operand_size = 2;
1956*27458df8SWei Liu             }
1957*27458df8SWei Liu         }
1958*27458df8SWei Liu     } else {
1959*27458df8SWei Liu         /* long */
1960*27458df8SWei Liu         if (decode->op_size_override) {
1961*27458df8SWei Liu             decode->operand_size = 2;
1962*27458df8SWei Liu         } else {
1963*27458df8SWei Liu             decode->operand_size = 4;
1964*27458df8SWei Liu         }
1965*27458df8SWei Liu 
1966*27458df8SWei Liu         if (decode->rex.w) {
1967*27458df8SWei Liu             decode->operand_size = 8;
1968*27458df8SWei Liu         }
1969*27458df8SWei Liu     }
1970*27458df8SWei Liu }
1971*27458df8SWei Liu 
1972*27458df8SWei Liu static void decode_sib(CPUX86State *env, struct x86_decode *decode)
1973*27458df8SWei Liu {
1974*27458df8SWei Liu     if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
1975*27458df8SWei Liu         (decode->addressing_size != 2)) {
1976*27458df8SWei Liu         decode->sib.sib = decode_byte(env, decode);
1977*27458df8SWei Liu         decode->sib_present = true;
1978*27458df8SWei Liu     }
1979*27458df8SWei Liu }
1980*27458df8SWei Liu 
1981*27458df8SWei Liu /* 16 bit modrm */
1982*27458df8SWei Liu int disp16_tbl[4][8] = {
1983*27458df8SWei Liu     {0, 0, 0, 0, 0, 0, 2, 0},
1984*27458df8SWei Liu     {1, 1, 1, 1, 1, 1, 1, 1},
1985*27458df8SWei Liu     {2, 2, 2, 2, 2, 2, 2, 2},
1986*27458df8SWei Liu     {0, 0, 0, 0, 0, 0, 0, 0}
1987*27458df8SWei Liu };
1988*27458df8SWei Liu 
1989*27458df8SWei Liu /* 32/64-bit modrm */
1990*27458df8SWei Liu int disp32_tbl[4][8] = {
1991*27458df8SWei Liu     {0, 0, 0, 0, -1, 4, 0, 0},
1992*27458df8SWei Liu     {1, 1, 1, 1, 1, 1, 1, 1},
1993*27458df8SWei Liu     {4, 4, 4, 4, 4, 4, 4, 4},
1994*27458df8SWei Liu     {0, 0, 0, 0, 0, 0, 0, 0}
1995*27458df8SWei Liu };
1996*27458df8SWei Liu 
1997*27458df8SWei Liu static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode)
1998*27458df8SWei Liu {
1999*27458df8SWei Liu     int addressing_size = decode->addressing_size;
2000*27458df8SWei Liu     int mod = decode->modrm.mod;
2001*27458df8SWei Liu     int rm = decode->modrm.rm;
2002*27458df8SWei Liu 
2003*27458df8SWei Liu     decode->displacement_size = 0;
2004*27458df8SWei Liu     switch (addressing_size) {
2005*27458df8SWei Liu     case 2:
2006*27458df8SWei Liu         decode->displacement_size = disp16_tbl[mod][rm];
2007*27458df8SWei Liu         if (decode->displacement_size) {
2008*27458df8SWei Liu             decode->displacement = (uint16_t)decode_bytes(env, decode,
2009*27458df8SWei Liu                                     decode->displacement_size);
2010*27458df8SWei Liu         }
2011*27458df8SWei Liu         break;
2012*27458df8SWei Liu     case 4:
2013*27458df8SWei Liu     case 8:
2014*27458df8SWei Liu         if (-1 == disp32_tbl[mod][rm]) {
2015*27458df8SWei Liu             if (5 == decode->sib.base) {
2016*27458df8SWei Liu                 decode->displacement_size = 4;
2017*27458df8SWei Liu             }
2018*27458df8SWei Liu         } else {
2019*27458df8SWei Liu             decode->displacement_size = disp32_tbl[mod][rm];
2020*27458df8SWei Liu         }
2021*27458df8SWei Liu 
2022*27458df8SWei Liu         if (decode->displacement_size) {
2023*27458df8SWei Liu             decode->displacement = (uint32_t)decode_bytes(env, decode,
2024*27458df8SWei Liu                                                 decode->displacement_size);
2025*27458df8SWei Liu         }
2026*27458df8SWei Liu         break;
2027*27458df8SWei Liu     }
2028*27458df8SWei Liu }
2029*27458df8SWei Liu 
2030*27458df8SWei Liu static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode)
2031*27458df8SWei Liu {
2032*27458df8SWei Liu     decode->modrm.modrm = decode_byte(env, decode);
2033*27458df8SWei Liu     decode->is_modrm = true;
2034*27458df8SWei Liu 
2035*27458df8SWei Liu     decode_sib(env, decode);
2036*27458df8SWei Liu     decode_displacement(env, decode);
2037*27458df8SWei Liu }
2038*27458df8SWei Liu 
2039*27458df8SWei Liu static inline void decode_opcode_general(CPUX86State *env,
2040*27458df8SWei Liu                                          struct x86_decode *decode,
2041*27458df8SWei Liu                                          uint8_t opcode,
2042*27458df8SWei Liu                                          struct decode_tbl *inst_decoder)
2043*27458df8SWei Liu {
2044*27458df8SWei Liu     decode->cmd = inst_decoder->cmd;
2045*27458df8SWei Liu     if (inst_decoder->operand_size) {
2046*27458df8SWei Liu         decode->operand_size = inst_decoder->operand_size;
2047*27458df8SWei Liu     }
2048*27458df8SWei Liu     decode->flags_mask = inst_decoder->flags_mask;
2049*27458df8SWei Liu 
2050*27458df8SWei Liu     if (inst_decoder->is_modrm) {
2051*27458df8SWei Liu         decode_modrm(env, decode);
2052*27458df8SWei Liu     }
2053*27458df8SWei Liu     if (inst_decoder->decode_op1) {
2054*27458df8SWei Liu         inst_decoder->decode_op1(env, decode, &decode->op[0]);
2055*27458df8SWei Liu     }
2056*27458df8SWei Liu     if (inst_decoder->decode_op2) {
2057*27458df8SWei Liu         inst_decoder->decode_op2(env, decode, &decode->op[1]);
2058*27458df8SWei Liu     }
2059*27458df8SWei Liu     if (inst_decoder->decode_op3) {
2060*27458df8SWei Liu         inst_decoder->decode_op3(env, decode, &decode->op[2]);
2061*27458df8SWei Liu     }
2062*27458df8SWei Liu     if (inst_decoder->decode_op4) {
2063*27458df8SWei Liu         inst_decoder->decode_op4(env, decode, &decode->op[3]);
2064*27458df8SWei Liu     }
2065*27458df8SWei Liu     if (inst_decoder->decode_postfix) {
2066*27458df8SWei Liu         inst_decoder->decode_postfix(env, decode);
2067*27458df8SWei Liu     }
2068*27458df8SWei Liu }
2069*27458df8SWei Liu 
2070*27458df8SWei Liu static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode,
2071*27458df8SWei Liu                                    uint8_t opcode)
2072*27458df8SWei Liu {
2073*27458df8SWei Liu     struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
2074*27458df8SWei Liu     decode_opcode_general(env, decode, opcode, inst_decoder);
2075*27458df8SWei Liu }
2076*27458df8SWei Liu 
2077*27458df8SWei Liu 
2078*27458df8SWei Liu static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode,
2079*27458df8SWei Liu                                    uint8_t opcode)
2080*27458df8SWei Liu {
2081*27458df8SWei Liu     struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
2082*27458df8SWei Liu     decode_opcode_general(env, decode, opcode, inst_decoder);
2083*27458df8SWei Liu }
2084*27458df8SWei Liu 
2085*27458df8SWei Liu static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
2086*27458df8SWei Liu {
2087*27458df8SWei Liu     uint8_t opcode;
2088*27458df8SWei Liu 
2089*27458df8SWei Liu     opcode = decode_byte(env, decode);
2090*27458df8SWei Liu     decode->opcode[decode->opcode_len++] = opcode;
2091*27458df8SWei Liu     if (opcode != OPCODE_ESCAPE) {
2092*27458df8SWei Liu         decode_opcode_1(env, decode, opcode);
2093*27458df8SWei Liu     } else {
2094*27458df8SWei Liu         opcode = decode_byte(env, decode);
2095*27458df8SWei Liu         decode->opcode[decode->opcode_len++] = opcode;
2096*27458df8SWei Liu         decode_opcode_2(env, decode, opcode);
2097*27458df8SWei Liu     }
2098*27458df8SWei Liu }
2099*27458df8SWei Liu 
2100*27458df8SWei Liu uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
2101*27458df8SWei Liu {
2102*27458df8SWei Liu     memset(decode, 0, sizeof(*decode));
2103*27458df8SWei Liu     decode_prefix(env, decode);
2104*27458df8SWei Liu     set_addressing_size(env, decode);
2105*27458df8SWei Liu     set_operand_size(env, decode);
2106*27458df8SWei Liu 
2107*27458df8SWei Liu     decode_opcodes(env, decode);
2108*27458df8SWei Liu 
2109*27458df8SWei Liu     return decode->len;
2110*27458df8SWei Liu }
2111*27458df8SWei Liu 
2112*27458df8SWei Liu void init_decoder(void)
2113*27458df8SWei Liu {
2114*27458df8SWei Liu     int i;
2115*27458df8SWei Liu 
2116*27458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) {
2117*27458df8SWei Liu         memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst));
2118*27458df8SWei Liu     }
2119*27458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
2120*27458df8SWei Liu         memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst));
2121*27458df8SWei Liu     }
2122*27458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
2123*27458df8SWei Liu         memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87));
2124*27458df8SWei Liu 
2125*27458df8SWei Liu     }
2126*27458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
2127*27458df8SWei Liu         _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
2128*27458df8SWei Liu     }
2129*27458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) {
2130*27458df8SWei Liu         _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i];
2131*27458df8SWei Liu     }
2132*27458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) {
2133*27458df8SWei Liu         int index = ((_x87_inst[i].opcode & 0xf) << 4) |
2134*27458df8SWei Liu                     ((_x87_inst[i].modrm_mod & 1) << 3) |
2135*27458df8SWei Liu                     _x87_inst[i].modrm_reg;
2136*27458df8SWei Liu         _decode_tbl3[index] = _x87_inst[i];
2137*27458df8SWei Liu     }
2138*27458df8SWei Liu }
2139*27458df8SWei Liu 
2140*27458df8SWei Liu 
2141*27458df8SWei Liu const char *decode_cmd_to_string(enum x86_decode_cmd cmd)
2142*27458df8SWei Liu {
2143*27458df8SWei Liu     static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG",
2144*27458df8SWei Liu         "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT",
2145*27458df8SWei Liu         "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD",
2146*27458df8SWei Liu         "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST",
2147*27458df8SWei Liu         "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR",
2148*27458df8SWei Liu         "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG",
2149*27458df8SWei Liu         "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN",
2150*27458df8SWei Liu         "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW",
2151*27458df8SWei Liu         "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR",
2152*27458df8SWei Liu         "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR",
2153*27458df8SWei Liu         "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL",
2154*27458df8SWei Liu         "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS",
2155*27458df8SWei Liu         "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT",
2156*27458df8SWei Liu         "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA",
2157*27458df8SWei Liu         "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT",
2158*27458df8SWei Liu         "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES",
2159*27458df8SWei Liu         "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT",
2160*27458df8SWei Liu         "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW",
2161*27458df8SWei Liu         "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV",
2162*27458df8SWei Liu         "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE",
2163*27458df8SWei Liu         "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW",
2164*27458df8SWei Liu         "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"};
2165*27458df8SWei Liu     return cmds[cmd];
2166*27458df8SWei Liu }
2167*27458df8SWei Liu 
2168*27458df8SWei Liu target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
2169*27458df8SWei Liu                                target_ulong addr, X86Seg seg)
2170*27458df8SWei Liu {
2171*27458df8SWei Liu     switch (decode->segment_override) {
2172*27458df8SWei Liu     case PREFIX_CS_SEG_OVERRIDE:
2173*27458df8SWei Liu         seg = R_CS;
2174*27458df8SWei Liu         break;
2175*27458df8SWei Liu     case PREFIX_SS_SEG_OVERRIDE:
2176*27458df8SWei Liu         seg = R_SS;
2177*27458df8SWei Liu         break;
2178*27458df8SWei Liu     case PREFIX_DS_SEG_OVERRIDE:
2179*27458df8SWei Liu         seg = R_DS;
2180*27458df8SWei Liu         break;
2181*27458df8SWei Liu     case PREFIX_ES_SEG_OVERRIDE:
2182*27458df8SWei Liu         seg = R_ES;
2183*27458df8SWei Liu         break;
2184*27458df8SWei Liu     case PREFIX_FS_SEG_OVERRIDE:
2185*27458df8SWei Liu         seg = R_FS;
2186*27458df8SWei Liu         break;
2187*27458df8SWei Liu     case PREFIX_GS_SEG_OVERRIDE:
2188*27458df8SWei Liu         seg = R_GS;
2189*27458df8SWei Liu         break;
2190*27458df8SWei Liu     default:
2191*27458df8SWei Liu         break;
2192*27458df8SWei Liu     }
2193*27458df8SWei Liu     return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg);
2194*27458df8SWei Liu }
2195