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