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