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