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