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