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