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