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
decode_invalid(CPUX86State * env,struct x86_decode * decode)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
sign(uint64_t val,int size)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
decode_bytes(CPUX86State * env,struct x86_decode * decode,int size)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
decode_byte(CPUX86State * env,struct x86_decode * decode)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
decode_word(CPUX86State * env,struct x86_decode * decode)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
decode_dword(CPUX86State * env,struct x86_decode * decode)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
decode_qword(CPUX86State * env,struct x86_decode * decode)98 static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode)
99 {
100 return decode_bytes(env, decode, 8);
101 }
102
decode_modrm_rm(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_modrm_reg(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_rax(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_immediate(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * var,int size)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
decode_imm8(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_imm8_signed(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_imm16(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_imm(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_imm_signed(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_imm_1(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_imm_0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_pushseg(CPUX86State * env,struct x86_decode * decode)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
decode_popseg(CPUX86State * env,struct x86_decode * decode)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
decode_incgroup(CPUX86State * env,struct x86_decode * decode)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
decode_decgroup(CPUX86State * env,struct x86_decode * decode)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
decode_incgroup2(CPUX86State * env,struct x86_decode * decode)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
decode_pushgroup(CPUX86State * env,struct x86_decode * decode)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
decode_popgroup(CPUX86State * env,struct x86_decode * decode)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
decode_jxx(CPUX86State * env,struct x86_decode * decode)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
decode_farjmp(CPUX86State * env,struct x86_decode * decode)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
decode_addgroup(CPUX86State * env,struct x86_decode * decode)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
decode_rotgroup(CPUX86State * env,struct x86_decode * decode)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
decode_f7group(CPUX86State * env,struct x86_decode * decode)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
decode_xchgroup(CPUX86State * env,struct x86_decode * decode)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
decode_movgroup(CPUX86State * env,struct x86_decode * decode)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
fetch_moffs(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_movgroup8(CPUX86State * env,struct x86_decode * decode)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
decode_rcx(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_x87_ins(CPUX86State * env,struct x86_decode * decode)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
decode_ffgroup(CPUX86State * env,struct x86_decode * decode)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
decode_sldtgroup(CPUX86State * env,struct x86_decode * decode)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
decode_lidtgroup(CPUX86State * env,struct x86_decode * decode)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
decode_btgroup(CPUX86State * env,struct x86_decode * decode)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
decode_x87_general(CPUX86State * env,struct x86_decode * decode)563 static void decode_x87_general(CPUX86State *env, struct x86_decode *decode)
564 {
565 decode->is_fpu = true;
566 }
567
decode_x87_modrm_floatp(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_x87_modrm_intp(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_x87_modrm_bytep(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_x87_modrm_st0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_decode_x87_modrm_st0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_aegroup(CPUX86State * env,struct x86_decode * decode)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
decode_bswap(CPUX86State * env,struct x86_decode * decode)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
decode_d9_4(CPUX86State * env,struct x86_decode * decode)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
decode_db_4(CPUX86State * env,struct x86_decode * decode)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
calc_modrm_operand16(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
get_reg_ref(CPUX86State * env,int reg,int rex_present,int is_extended,int size)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
get_reg_val(CPUX86State * env,int reg,int rex_present,int is_extended,int size)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
get_sib_val(CPUX86State * env,struct x86_decode * decode,X86Seg * sel)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
calc_modrm_operand32(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
calc_modrm_operand64(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
calc_modrm_operand(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)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
decode_prefix(CPUX86State * env,struct x86_decode * decode)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
set_addressing_size(CPUX86State * env,struct x86_decode * decode)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
set_operand_size(CPUX86State * env,struct x86_decode * decode)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
decode_sib(CPUX86State * env,struct x86_decode * decode)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
decode_displacement(CPUX86State * env,struct x86_decode * decode)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
decode_modrm(CPUX86State * env,struct x86_decode * decode)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
decode_opcode_general(CPUX86State * env,struct x86_decode * decode,uint8_t opcode,struct decode_tbl * inst_decoder)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
decode_opcode_1(CPUX86State * env,struct x86_decode * decode,uint8_t opcode)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
decode_opcode_2(CPUX86State * env,struct x86_decode * decode,uint8_t opcode)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
decode_opcodes(CPUX86State * env,struct x86_decode * decode)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
decode_instruction(CPUX86State * env,struct x86_decode * decode)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
init_decoder(void)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
decode_cmd_to_string(enum x86_decode_cmd cmd)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
decode_linear_addr(CPUX86State * env,struct x86_decode * decode,target_ulong addr,X86Seg seg)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