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