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