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