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