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