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