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