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