127458df8SWei Liu /*
227458df8SWei Liu * Copyright (C) 2016 Veertu Inc,
327458df8SWei Liu * Copyright (C) 2017 Google Inc,
427458df8SWei Liu *
527458df8SWei Liu * This program is free software; you can redistribute it and/or
627458df8SWei Liu * modify it under the terms of the GNU Lesser General Public
727458df8SWei Liu * License as published by the Free Software Foundation; either
827458df8SWei Liu * version 2.1 of the License, or (at your option) any later version.
927458df8SWei Liu *
1027458df8SWei Liu * This program is distributed in the hope that it will be useful,
1127458df8SWei Liu * but WITHOUT ANY WARRANTY; without even the implied warranty of
1227458df8SWei Liu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1327458df8SWei Liu * Lesser General Public License for more details.
1427458df8SWei Liu *
1527458df8SWei Liu * You should have received a copy of the GNU Lesser General Public
1627458df8SWei Liu * License along with this program; if not, see <http://www.gnu.org/licenses/>.
1727458df8SWei Liu */
1827458df8SWei Liu
1927458df8SWei Liu #include "qemu/osdep.h"
2027458df8SWei Liu
2127458df8SWei Liu #include "panic.h"
2227458df8SWei Liu #include "x86_decode.h"
2327458df8SWei Liu #include "x86_emu.h"
2427458df8SWei Liu
2527458df8SWei Liu #define OPCODE_ESCAPE 0xf
2627458df8SWei Liu
decode_invalid(CPUX86State * env,struct x86_decode * decode)2727458df8SWei Liu static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
2827458df8SWei Liu {
297abf0d95SPaolo Bonzini printf(TARGET_FMT_lx ": failed to decode instruction ", env->eip);
3027458df8SWei Liu for (int i = 0; i < decode->opcode_len; i++) {
3127458df8SWei Liu printf("%x ", decode->opcode[i]);
3227458df8SWei Liu }
3327458df8SWei Liu printf("\n");
3427458df8SWei Liu VM_PANIC("decoder failed\n");
3527458df8SWei Liu }
3627458df8SWei Liu
sign(uint64_t val,int size)3727458df8SWei Liu uint64_t sign(uint64_t val, int size)
3827458df8SWei Liu {
3927458df8SWei Liu switch (size) {
4027458df8SWei Liu case 1:
4127458df8SWei Liu val = (int8_t)val;
4227458df8SWei Liu break;
4327458df8SWei Liu case 2:
4427458df8SWei Liu val = (int16_t)val;
4527458df8SWei Liu break;
4627458df8SWei Liu case 4:
4727458df8SWei Liu val = (int32_t)val;
4827458df8SWei Liu break;
4927458df8SWei Liu case 8:
5027458df8SWei Liu val = (int64_t)val;
5127458df8SWei Liu break;
5227458df8SWei Liu default:
5327458df8SWei Liu VM_PANIC_EX("%s invalid size %d\n", __func__, size);
5427458df8SWei Liu break;
5527458df8SWei Liu }
5627458df8SWei Liu return val;
5727458df8SWei Liu }
5827458df8SWei Liu
decode_bytes(CPUX86State * env,struct x86_decode * decode,int size)5927458df8SWei Liu static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
6027458df8SWei Liu int size)
6127458df8SWei Liu {
6227458df8SWei Liu uint64_t val = 0;
6327458df8SWei Liu
6427458df8SWei Liu switch (size) {
6527458df8SWei Liu case 1:
6627458df8SWei Liu case 2:
6727458df8SWei Liu case 4:
6827458df8SWei Liu case 8:
6927458df8SWei Liu break;
7027458df8SWei Liu default:
7127458df8SWei Liu VM_PANIC_EX("%s invalid size %d\n", __func__, size);
7227458df8SWei Liu break;
7327458df8SWei Liu }
7427458df8SWei Liu target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len;
7527458df8SWei Liu emul_ops->read_mem(env_cpu(env), &val, va, size);
7627458df8SWei Liu decode->len += size;
7727458df8SWei Liu
7827458df8SWei Liu return val;
7927458df8SWei Liu }
8027458df8SWei Liu
decode_byte(CPUX86State * env,struct x86_decode * decode)8127458df8SWei Liu static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode)
8227458df8SWei Liu {
8327458df8SWei Liu return (uint8_t)decode_bytes(env, decode, 1);
8427458df8SWei Liu }
8527458df8SWei Liu
decode_word(CPUX86State * env,struct x86_decode * decode)8627458df8SWei Liu static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode)
8727458df8SWei Liu {
8827458df8SWei Liu return (uint16_t)decode_bytes(env, decode, 2);
8927458df8SWei Liu }
9027458df8SWei Liu
decode_dword(CPUX86State * env,struct x86_decode * decode)9127458df8SWei Liu static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode)
9227458df8SWei Liu {
9327458df8SWei Liu return (uint32_t)decode_bytes(env, decode, 4);
9427458df8SWei Liu }
9527458df8SWei Liu
decode_qword(CPUX86State * env,struct x86_decode * decode)9627458df8SWei Liu static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode)
9727458df8SWei Liu {
9827458df8SWei Liu return decode_bytes(env, decode, 8);
9927458df8SWei Liu }
10027458df8SWei Liu
decode_modrm_rm(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)10127458df8SWei Liu static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode,
10227458df8SWei Liu struct x86_decode_op *op)
10327458df8SWei Liu {
10427458df8SWei Liu op->type = X86_VAR_RM;
10527458df8SWei Liu }
10627458df8SWei Liu
decode_modrm_reg(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)10727458df8SWei Liu static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode,
10827458df8SWei Liu struct x86_decode_op *op)
10927458df8SWei Liu {
11027458df8SWei Liu op->type = X86_VAR_REG;
11127458df8SWei Liu op->reg = decode->modrm.reg;
112*77a2dba4SPaolo Bonzini op->regptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
11327458df8SWei Liu decode->operand_size);
11427458df8SWei Liu }
11527458df8SWei Liu
decode_rax(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)11627458df8SWei Liu static void decode_rax(CPUX86State *env, struct x86_decode *decode,
11727458df8SWei Liu struct x86_decode_op *op)
11827458df8SWei Liu {
11927458df8SWei Liu op->type = X86_VAR_REG;
12027458df8SWei Liu op->reg = R_EAX;
12127458df8SWei Liu /* Since reg is always AX, REX prefix has no impact. */
122*77a2dba4SPaolo Bonzini op->regptr = get_reg_ref(env, op->reg, false, 0,
12327458df8SWei Liu decode->operand_size);
12427458df8SWei Liu }
12527458df8SWei Liu
decode_immediate(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * var,int size)12627458df8SWei Liu static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode,
12727458df8SWei Liu struct x86_decode_op *var, int size)
12827458df8SWei Liu {
12927458df8SWei Liu var->type = X86_VAR_IMMEDIATE;
13027458df8SWei Liu var->size = size;
13127458df8SWei Liu switch (size) {
13227458df8SWei Liu case 1:
13327458df8SWei Liu var->val = decode_byte(env, decode);
13427458df8SWei Liu break;
13527458df8SWei Liu case 2:
13627458df8SWei Liu var->val = decode_word(env, decode);
13727458df8SWei Liu break;
13827458df8SWei Liu case 4:
13927458df8SWei Liu var->val = decode_dword(env, decode);
14027458df8SWei Liu break;
14127458df8SWei Liu case 8:
14227458df8SWei Liu var->val = decode_qword(env, decode);
14327458df8SWei Liu break;
14427458df8SWei Liu default:
14527458df8SWei Liu VM_PANIC_EX("bad size %d\n", size);
14627458df8SWei Liu }
14727458df8SWei Liu }
14827458df8SWei Liu
decode_imm8(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)14927458df8SWei Liu static void decode_imm8(CPUX86State *env, struct x86_decode *decode,
15027458df8SWei Liu struct x86_decode_op *op)
15127458df8SWei Liu {
15227458df8SWei Liu decode_immediate(env, decode, op, 1);
15327458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
15427458df8SWei Liu }
15527458df8SWei Liu
decode_imm8_signed(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)15627458df8SWei Liu static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode,
15727458df8SWei Liu struct x86_decode_op *op)
15827458df8SWei Liu {
15927458df8SWei Liu decode_immediate(env, decode, op, 1);
16027458df8SWei Liu op->val = sign(op->val, 1);
16127458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
16227458df8SWei Liu }
16327458df8SWei Liu
decode_imm16(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)16427458df8SWei Liu static void decode_imm16(CPUX86State *env, struct x86_decode *decode,
16527458df8SWei Liu struct x86_decode_op *op)
16627458df8SWei Liu {
16727458df8SWei Liu decode_immediate(env, decode, op, 2);
16827458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
16927458df8SWei Liu }
17027458df8SWei Liu
17127458df8SWei Liu
decode_imm(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)17227458df8SWei Liu static void decode_imm(CPUX86State *env, struct x86_decode *decode,
17327458df8SWei Liu struct x86_decode_op *op)
17427458df8SWei Liu {
17527458df8SWei Liu if (8 == decode->operand_size) {
17627458df8SWei Liu decode_immediate(env, decode, op, 4);
17727458df8SWei Liu op->val = sign(op->val, decode->operand_size);
17827458df8SWei Liu } else {
17927458df8SWei Liu decode_immediate(env, decode, op, decode->operand_size);
18027458df8SWei Liu }
18127458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
18227458df8SWei Liu }
18327458df8SWei Liu
decode_imm_signed(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)18427458df8SWei Liu static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode,
18527458df8SWei Liu struct x86_decode_op *op)
18627458df8SWei Liu {
18727458df8SWei Liu decode_immediate(env, decode, op, decode->operand_size);
18827458df8SWei Liu op->val = sign(op->val, decode->operand_size);
18927458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
19027458df8SWei Liu }
19127458df8SWei Liu
decode_imm_1(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)19227458df8SWei Liu static void decode_imm_1(CPUX86State *env, struct x86_decode *decode,
19327458df8SWei Liu struct x86_decode_op *op)
19427458df8SWei Liu {
19527458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
19627458df8SWei Liu op->val = 1;
19727458df8SWei Liu }
19827458df8SWei Liu
decode_imm_0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)19927458df8SWei Liu static void decode_imm_0(CPUX86State *env, struct x86_decode *decode,
20027458df8SWei Liu struct x86_decode_op *op)
20127458df8SWei Liu {
20227458df8SWei Liu op->type = X86_VAR_IMMEDIATE;
20327458df8SWei Liu op->val = 0;
20427458df8SWei Liu }
20527458df8SWei Liu
20627458df8SWei Liu
decode_pushseg(CPUX86State * env,struct x86_decode * decode)20727458df8SWei Liu static void decode_pushseg(CPUX86State *env, struct x86_decode *decode)
20827458df8SWei Liu {
20927458df8SWei Liu uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
21027458df8SWei Liu
21127458df8SWei Liu decode->op[0].type = X86_VAR_REG;
21227458df8SWei Liu switch (op) {
21327458df8SWei Liu case 0xe:
21427458df8SWei Liu decode->op[0].reg = R_CS;
21527458df8SWei Liu break;
21627458df8SWei Liu case 0x16:
21727458df8SWei Liu decode->op[0].reg = R_SS;
21827458df8SWei Liu break;
21927458df8SWei Liu case 0x1e:
22027458df8SWei Liu decode->op[0].reg = R_DS;
22127458df8SWei Liu break;
22227458df8SWei Liu case 0x06:
22327458df8SWei Liu decode->op[0].reg = R_ES;
22427458df8SWei Liu break;
22527458df8SWei Liu case 0xa0:
22627458df8SWei Liu decode->op[0].reg = R_FS;
22727458df8SWei Liu break;
22827458df8SWei Liu case 0xa8:
22927458df8SWei Liu decode->op[0].reg = R_GS;
23027458df8SWei Liu break;
23127458df8SWei Liu }
23227458df8SWei Liu }
23327458df8SWei Liu
decode_popseg(CPUX86State * env,struct x86_decode * decode)23427458df8SWei Liu static void decode_popseg(CPUX86State *env, struct x86_decode *decode)
23527458df8SWei Liu {
23627458df8SWei Liu uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
23727458df8SWei Liu
23827458df8SWei Liu decode->op[0].type = X86_VAR_REG;
23927458df8SWei Liu switch (op) {
24027458df8SWei Liu case 0xf:
24127458df8SWei Liu decode->op[0].reg = R_CS;
24227458df8SWei Liu break;
24327458df8SWei Liu case 0x17:
24427458df8SWei Liu decode->op[0].reg = R_SS;
24527458df8SWei Liu break;
24627458df8SWei Liu case 0x1f:
24727458df8SWei Liu decode->op[0].reg = R_DS;
24827458df8SWei Liu break;
24927458df8SWei Liu case 0x07:
25027458df8SWei Liu decode->op[0].reg = R_ES;
25127458df8SWei Liu break;
25227458df8SWei Liu case 0xa1:
25327458df8SWei Liu decode->op[0].reg = R_FS;
25427458df8SWei Liu break;
25527458df8SWei Liu case 0xa9:
25627458df8SWei Liu decode->op[0].reg = R_GS;
25727458df8SWei Liu break;
25827458df8SWei Liu }
25927458df8SWei Liu }
26027458df8SWei Liu
decode_incgroup(CPUX86State * env,struct x86_decode * decode)26127458df8SWei Liu static void decode_incgroup(CPUX86State *env, struct x86_decode *decode)
26227458df8SWei Liu {
26327458df8SWei Liu decode->op[0].type = X86_VAR_REG;
26427458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0x40;
265*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
26627458df8SWei Liu decode->rex.b, decode->operand_size);
26727458df8SWei Liu }
26827458df8SWei Liu
decode_decgroup(CPUX86State * env,struct x86_decode * decode)26927458df8SWei Liu static void decode_decgroup(CPUX86State *env, struct x86_decode *decode)
27027458df8SWei Liu {
27127458df8SWei Liu decode->op[0].type = X86_VAR_REG;
27227458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0x48;
273*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
27427458df8SWei Liu decode->rex.b, decode->operand_size);
27527458df8SWei Liu }
27627458df8SWei Liu
decode_incgroup2(CPUX86State * env,struct x86_decode * decode)27727458df8SWei Liu static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode)
27827458df8SWei Liu {
27927458df8SWei Liu if (!decode->modrm.reg) {
28027458df8SWei Liu decode->cmd = X86_DECODE_CMD_INC;
28127458df8SWei Liu } else if (1 == decode->modrm.reg) {
28227458df8SWei Liu decode->cmd = X86_DECODE_CMD_DEC;
28327458df8SWei Liu }
28427458df8SWei Liu }
28527458df8SWei Liu
decode_pushgroup(CPUX86State * env,struct x86_decode * decode)28627458df8SWei Liu static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode)
28727458df8SWei Liu {
28827458df8SWei Liu decode->op[0].type = X86_VAR_REG;
28927458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0x50;
290*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
29127458df8SWei Liu decode->rex.b, decode->operand_size);
29227458df8SWei Liu }
29327458df8SWei Liu
decode_popgroup(CPUX86State * env,struct x86_decode * decode)29427458df8SWei Liu static void decode_popgroup(CPUX86State *env, struct x86_decode *decode)
29527458df8SWei Liu {
29627458df8SWei Liu decode->op[0].type = X86_VAR_REG;
29727458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0x58;
298*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
29927458df8SWei Liu decode->rex.b, decode->operand_size);
30027458df8SWei Liu }
30127458df8SWei Liu
decode_jxx(CPUX86State * env,struct x86_decode * decode)30227458df8SWei Liu static void decode_jxx(CPUX86State *env, struct x86_decode *decode)
30327458df8SWei Liu {
30427458df8SWei Liu decode->displacement = decode_bytes(env, decode, decode->operand_size);
30527458df8SWei Liu decode->displacement_size = decode->operand_size;
30627458df8SWei Liu }
30727458df8SWei Liu
decode_farjmp(CPUX86State * env,struct x86_decode * decode)30827458df8SWei Liu static void decode_farjmp(CPUX86State *env, struct x86_decode *decode)
30927458df8SWei Liu {
31027458df8SWei Liu decode->op[0].type = X86_VAR_IMMEDIATE;
31127458df8SWei Liu decode->op[0].val = decode_bytes(env, decode, decode->operand_size);
31227458df8SWei Liu decode->displacement = decode_word(env, decode);
31327458df8SWei Liu }
31427458df8SWei Liu
decode_addgroup(CPUX86State * env,struct x86_decode * decode)31527458df8SWei Liu static void decode_addgroup(CPUX86State *env, struct x86_decode *decode)
31627458df8SWei Liu {
31727458df8SWei Liu enum x86_decode_cmd group[] = {
31827458df8SWei Liu X86_DECODE_CMD_ADD,
31927458df8SWei Liu X86_DECODE_CMD_OR,
32027458df8SWei Liu X86_DECODE_CMD_ADC,
32127458df8SWei Liu X86_DECODE_CMD_SBB,
32227458df8SWei Liu X86_DECODE_CMD_AND,
32327458df8SWei Liu X86_DECODE_CMD_SUB,
32427458df8SWei Liu X86_DECODE_CMD_XOR,
32527458df8SWei Liu X86_DECODE_CMD_CMP
32627458df8SWei Liu };
32727458df8SWei Liu decode->cmd = group[decode->modrm.reg];
32827458df8SWei Liu }
32927458df8SWei Liu
decode_rotgroup(CPUX86State * env,struct x86_decode * decode)33027458df8SWei Liu static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode)
33127458df8SWei Liu {
33227458df8SWei Liu enum x86_decode_cmd group[] = {
33327458df8SWei Liu X86_DECODE_CMD_ROL,
33427458df8SWei Liu X86_DECODE_CMD_ROR,
33527458df8SWei Liu X86_DECODE_CMD_RCL,
33627458df8SWei Liu X86_DECODE_CMD_RCR,
33727458df8SWei Liu X86_DECODE_CMD_SHL,
33827458df8SWei Liu X86_DECODE_CMD_SHR,
33927458df8SWei Liu X86_DECODE_CMD_SHL,
34027458df8SWei Liu X86_DECODE_CMD_SAR
34127458df8SWei Liu };
34227458df8SWei Liu decode->cmd = group[decode->modrm.reg];
34327458df8SWei Liu }
34427458df8SWei Liu
decode_f7group(CPUX86State * env,struct x86_decode * decode)34527458df8SWei Liu static void decode_f7group(CPUX86State *env, struct x86_decode *decode)
34627458df8SWei Liu {
34727458df8SWei Liu enum x86_decode_cmd group[] = {
34827458df8SWei Liu X86_DECODE_CMD_TST,
34927458df8SWei Liu X86_DECODE_CMD_TST,
35027458df8SWei Liu X86_DECODE_CMD_NOT,
35127458df8SWei Liu X86_DECODE_CMD_NEG,
35227458df8SWei Liu X86_DECODE_CMD_MUL,
35327458df8SWei Liu X86_DECODE_CMD_IMUL_1,
35427458df8SWei Liu X86_DECODE_CMD_DIV,
35527458df8SWei Liu X86_DECODE_CMD_IDIV
35627458df8SWei Liu };
35727458df8SWei Liu decode->cmd = group[decode->modrm.reg];
35827458df8SWei Liu decode_modrm_rm(env, decode, &decode->op[0]);
35927458df8SWei Liu
36027458df8SWei Liu switch (decode->modrm.reg) {
36127458df8SWei Liu case 0:
36227458df8SWei Liu case 1:
36327458df8SWei Liu decode_imm(env, decode, &decode->op[1]);
36427458df8SWei Liu break;
36527458df8SWei Liu case 2:
36627458df8SWei Liu break;
36727458df8SWei Liu case 3:
36827458df8SWei Liu decode->op[1].type = X86_VAR_IMMEDIATE;
36927458df8SWei Liu decode->op[1].val = 0;
37027458df8SWei Liu break;
37127458df8SWei Liu default:
37227458df8SWei Liu break;
37327458df8SWei Liu }
37427458df8SWei Liu }
37527458df8SWei Liu
decode_xchgroup(CPUX86State * env,struct x86_decode * decode)37627458df8SWei Liu static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode)
37727458df8SWei Liu {
37827458df8SWei Liu decode->op[0].type = X86_VAR_REG;
37927458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0x90;
380*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
38127458df8SWei Liu decode->rex.b, decode->operand_size);
38227458df8SWei Liu }
38327458df8SWei Liu
decode_movgroup(CPUX86State * env,struct x86_decode * decode)38427458df8SWei Liu static void decode_movgroup(CPUX86State *env, struct x86_decode *decode)
38527458df8SWei Liu {
38627458df8SWei Liu decode->op[0].type = X86_VAR_REG;
38727458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0xb8;
388*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
38927458df8SWei Liu decode->rex.b, decode->operand_size);
39027458df8SWei Liu decode_immediate(env, decode, &decode->op[1], decode->operand_size);
39127458df8SWei Liu }
39227458df8SWei Liu
fetch_moffs(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)39327458df8SWei Liu static void fetch_moffs(CPUX86State *env, struct x86_decode *decode,
39427458df8SWei Liu struct x86_decode_op *op)
39527458df8SWei Liu {
39627458df8SWei Liu op->type = X86_VAR_OFFSET;
397*77a2dba4SPaolo Bonzini op->addr = decode_bytes(env, decode, decode->addressing_size);
39827458df8SWei Liu }
39927458df8SWei Liu
decode_movgroup8(CPUX86State * env,struct x86_decode * decode)40027458df8SWei Liu static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode)
40127458df8SWei Liu {
40227458df8SWei Liu decode->op[0].type = X86_VAR_REG;
40327458df8SWei Liu decode->op[0].reg = decode->opcode[0] - 0xb0;
404*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
40527458df8SWei Liu decode->rex.b, decode->operand_size);
40627458df8SWei Liu decode_immediate(env, decode, &decode->op[1], decode->operand_size);
40727458df8SWei Liu }
40827458df8SWei Liu
decode_rcx(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)40927458df8SWei Liu static void decode_rcx(CPUX86State *env, struct x86_decode *decode,
41027458df8SWei Liu struct x86_decode_op *op)
41127458df8SWei Liu {
41227458df8SWei Liu op->type = X86_VAR_REG;
41327458df8SWei Liu op->reg = R_ECX;
414*77a2dba4SPaolo Bonzini op->regptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b,
41527458df8SWei Liu decode->operand_size);
41627458df8SWei Liu }
41727458df8SWei Liu
41827458df8SWei Liu struct decode_tbl {
41927458df8SWei Liu uint8_t opcode;
42027458df8SWei Liu enum x86_decode_cmd cmd;
42127458df8SWei Liu uint8_t operand_size;
42227458df8SWei Liu bool is_modrm;
42327458df8SWei Liu void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
42427458df8SWei Liu struct x86_decode_op *op1);
42527458df8SWei Liu void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
42627458df8SWei Liu struct x86_decode_op *op2);
42727458df8SWei Liu void (*decode_op3)(CPUX86State *env, struct x86_decode *decode,
42827458df8SWei Liu struct x86_decode_op *op3);
42927458df8SWei Liu void (*decode_op4)(CPUX86State *env, struct x86_decode *decode,
43027458df8SWei Liu struct x86_decode_op *op4);
43127458df8SWei Liu void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
43227458df8SWei Liu };
43327458df8SWei Liu
43427458df8SWei Liu struct decode_x87_tbl {
43527458df8SWei Liu uint8_t opcode;
43627458df8SWei Liu uint8_t modrm_reg;
43727458df8SWei Liu uint8_t modrm_mod;
43827458df8SWei Liu enum x86_decode_cmd cmd;
43927458df8SWei Liu uint8_t operand_size;
44027458df8SWei Liu bool rev;
44127458df8SWei Liu bool pop;
44227458df8SWei Liu void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
44327458df8SWei Liu struct x86_decode_op *op1);
44427458df8SWei Liu void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
44527458df8SWei Liu struct x86_decode_op *op2);
44627458df8SWei Liu void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
44727458df8SWei Liu };
44827458df8SWei Liu
44927458df8SWei Liu struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
45027458df8SWei Liu decode_invalid};
45127458df8SWei Liu
45227458df8SWei Liu struct decode_tbl _decode_tbl1[256];
45327458df8SWei Liu struct decode_tbl _decode_tbl2[256];
45427458df8SWei Liu struct decode_x87_tbl _decode_tbl3[256];
45527458df8SWei Liu
decode_x87_ins(CPUX86State * env,struct x86_decode * decode)45627458df8SWei Liu static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode)
45727458df8SWei Liu {
45827458df8SWei Liu struct decode_x87_tbl *decoder;
45927458df8SWei Liu
46027458df8SWei Liu decode->is_fpu = true;
46127458df8SWei Liu int mode = decode->modrm.mod == 3 ? 1 : 0;
46227458df8SWei Liu int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) |
46327458df8SWei Liu decode->modrm.reg;
46427458df8SWei Liu
46527458df8SWei Liu decoder = &_decode_tbl3[index];
46627458df8SWei Liu
46727458df8SWei Liu decode->cmd = decoder->cmd;
46827458df8SWei Liu if (decoder->operand_size) {
46927458df8SWei Liu decode->operand_size = decoder->operand_size;
47027458df8SWei Liu }
47127458df8SWei Liu decode->fpop_stack = decoder->pop;
47227458df8SWei Liu decode->frev = decoder->rev;
47327458df8SWei Liu
47427458df8SWei Liu if (decoder->decode_op1) {
47527458df8SWei Liu decoder->decode_op1(env, decode, &decode->op[0]);
47627458df8SWei Liu }
47727458df8SWei Liu if (decoder->decode_op2) {
47827458df8SWei Liu decoder->decode_op2(env, decode, &decode->op[1]);
47927458df8SWei Liu }
48027458df8SWei Liu if (decoder->decode_postfix) {
48127458df8SWei Liu decoder->decode_postfix(env, decode);
48227458df8SWei Liu }
48327458df8SWei Liu
48427458df8SWei Liu VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n",
48527458df8SWei Liu decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg,
48627458df8SWei Liu decoder->modrm_mod);
48727458df8SWei Liu }
48827458df8SWei Liu
decode_ffgroup(CPUX86State * env,struct x86_decode * decode)48927458df8SWei Liu static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode)
49027458df8SWei Liu {
49127458df8SWei Liu enum x86_decode_cmd group[] = {
49227458df8SWei Liu X86_DECODE_CMD_INC,
49327458df8SWei Liu X86_DECODE_CMD_DEC,
49427458df8SWei Liu X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT,
49527458df8SWei Liu X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT,
49627458df8SWei Liu X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT,
49727458df8SWei Liu X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT,
49827458df8SWei Liu X86_DECODE_CMD_PUSH,
49927458df8SWei Liu X86_DECODE_CMD_INVL,
50027458df8SWei Liu X86_DECODE_CMD_INVL
50127458df8SWei Liu };
50227458df8SWei Liu decode->cmd = group[decode->modrm.reg];
50327458df8SWei Liu }
50427458df8SWei Liu
decode_sldtgroup(CPUX86State * env,struct x86_decode * decode)50527458df8SWei Liu static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode)
50627458df8SWei Liu {
50727458df8SWei Liu
50827458df8SWei Liu enum x86_decode_cmd group[] = {
50927458df8SWei Liu X86_DECODE_CMD_SLDT,
51027458df8SWei Liu X86_DECODE_CMD_STR,
51127458df8SWei Liu X86_DECODE_CMD_LLDT,
51227458df8SWei Liu X86_DECODE_CMD_LTR,
51327458df8SWei Liu X86_DECODE_CMD_VERR,
51427458df8SWei Liu X86_DECODE_CMD_VERW,
51527458df8SWei Liu X86_DECODE_CMD_INVL,
51627458df8SWei Liu X86_DECODE_CMD_INVL
51727458df8SWei Liu };
51827458df8SWei Liu decode->cmd = group[decode->modrm.reg];
51927458df8SWei Liu }
52027458df8SWei Liu
decode_lidtgroup(CPUX86State * env,struct x86_decode * decode)52127458df8SWei Liu static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode)
52227458df8SWei Liu {
52327458df8SWei Liu enum x86_decode_cmd group[] = {
52427458df8SWei Liu X86_DECODE_CMD_SGDT,
52527458df8SWei Liu X86_DECODE_CMD_SIDT,
52627458df8SWei Liu X86_DECODE_CMD_LGDT,
52727458df8SWei Liu X86_DECODE_CMD_LIDT,
52827458df8SWei Liu X86_DECODE_CMD_SMSW,
52927458df8SWei Liu X86_DECODE_CMD_LMSW,
53027458df8SWei Liu X86_DECODE_CMD_LMSW,
53127458df8SWei Liu X86_DECODE_CMD_INVLPG
53227458df8SWei Liu };
53327458df8SWei Liu decode->cmd = group[decode->modrm.reg];
53427458df8SWei Liu if (0xf9 == decode->modrm.modrm) {
53527458df8SWei Liu decode->opcode[decode->len++] = decode->modrm.modrm;
53627458df8SWei Liu decode->cmd = X86_DECODE_CMD_RDTSCP;
53727458df8SWei Liu }
53827458df8SWei Liu }
53927458df8SWei Liu
decode_btgroup(CPUX86State * env,struct x86_decode * decode)54027458df8SWei Liu static void decode_btgroup(CPUX86State *env, struct x86_decode *decode)
54127458df8SWei Liu {
54227458df8SWei Liu enum x86_decode_cmd group[] = {
54327458df8SWei Liu X86_DECODE_CMD_INVL,
54427458df8SWei Liu X86_DECODE_CMD_INVL,
54527458df8SWei Liu X86_DECODE_CMD_INVL,
54627458df8SWei Liu X86_DECODE_CMD_INVL,
54727458df8SWei Liu X86_DECODE_CMD_BT,
54827458df8SWei Liu X86_DECODE_CMD_BTS,
54927458df8SWei Liu X86_DECODE_CMD_BTR,
55027458df8SWei Liu X86_DECODE_CMD_BTC
55127458df8SWei Liu };
55227458df8SWei Liu decode->cmd = group[decode->modrm.reg];
55327458df8SWei Liu }
55427458df8SWei Liu
decode_x87_general(CPUX86State * env,struct x86_decode * decode)55527458df8SWei Liu static void decode_x87_general(CPUX86State *env, struct x86_decode *decode)
55627458df8SWei Liu {
55727458df8SWei Liu decode->is_fpu = true;
55827458df8SWei Liu }
55927458df8SWei Liu
decode_x87_modrm_floatp(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)56027458df8SWei Liu static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode,
56127458df8SWei Liu struct x86_decode_op *op)
56227458df8SWei Liu {
56327458df8SWei Liu op->type = X87_VAR_FLOATP;
56427458df8SWei Liu }
56527458df8SWei Liu
decode_x87_modrm_intp(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)56627458df8SWei Liu static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode,
56727458df8SWei Liu struct x86_decode_op *op)
56827458df8SWei Liu {
56927458df8SWei Liu op->type = X87_VAR_INTP;
57027458df8SWei Liu }
57127458df8SWei Liu
decode_x87_modrm_bytep(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)57227458df8SWei Liu static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode,
57327458df8SWei Liu struct x86_decode_op *op)
57427458df8SWei Liu {
57527458df8SWei Liu op->type = X87_VAR_BYTEP;
57627458df8SWei Liu }
57727458df8SWei Liu
decode_x87_modrm_st0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)57827458df8SWei Liu static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode,
57927458df8SWei Liu struct x86_decode_op *op)
58027458df8SWei Liu {
58127458df8SWei Liu op->type = X87_VAR_REG;
58227458df8SWei Liu op->reg = 0;
58327458df8SWei Liu }
58427458df8SWei Liu
decode_decode_x87_modrm_st0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)58527458df8SWei Liu static void decode_decode_x87_modrm_st0(CPUX86State *env,
58627458df8SWei Liu struct x86_decode *decode,
58727458df8SWei Liu struct x86_decode_op *op)
58827458df8SWei Liu {
58927458df8SWei Liu op->type = X87_VAR_REG;
59027458df8SWei Liu op->reg = decode->modrm.modrm & 7;
59127458df8SWei Liu }
59227458df8SWei Liu
59327458df8SWei Liu
decode_aegroup(CPUX86State * env,struct x86_decode * decode)59427458df8SWei Liu static void decode_aegroup(CPUX86State *env, struct x86_decode *decode)
59527458df8SWei Liu {
59627458df8SWei Liu decode->is_fpu = true;
59727458df8SWei Liu switch (decode->modrm.reg) {
59827458df8SWei Liu case 0:
59927458df8SWei Liu decode->cmd = X86_DECODE_CMD_FXSAVE;
60027458df8SWei Liu decode_x87_modrm_bytep(env, decode, &decode->op[0]);
60127458df8SWei Liu break;
60227458df8SWei Liu case 1:
60327458df8SWei Liu decode_x87_modrm_bytep(env, decode, &decode->op[0]);
60427458df8SWei Liu decode->cmd = X86_DECODE_CMD_FXRSTOR;
60527458df8SWei Liu break;
60627458df8SWei Liu case 5:
60727458df8SWei Liu if (decode->modrm.modrm == 0xe8) {
60827458df8SWei Liu decode->cmd = X86_DECODE_CMD_LFENCE;
60927458df8SWei Liu } else {
61027458df8SWei Liu VM_PANIC("xrstor");
61127458df8SWei Liu }
61227458df8SWei Liu break;
61327458df8SWei Liu case 6:
61427458df8SWei Liu VM_PANIC_ON(decode->modrm.modrm != 0xf0);
61527458df8SWei Liu decode->cmd = X86_DECODE_CMD_MFENCE;
61627458df8SWei Liu break;
61727458df8SWei Liu case 7:
61827458df8SWei Liu if (decode->modrm.modrm == 0xf8) {
61927458df8SWei Liu decode->cmd = X86_DECODE_CMD_SFENCE;
62027458df8SWei Liu } else {
62127458df8SWei Liu decode->cmd = X86_DECODE_CMD_CLFLUSH;
62227458df8SWei Liu }
62327458df8SWei Liu break;
62427458df8SWei Liu default:
62527458df8SWei Liu VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg);
62627458df8SWei Liu break;
62727458df8SWei Liu }
62827458df8SWei Liu }
62927458df8SWei Liu
decode_bswap(CPUX86State * env,struct x86_decode * decode)63027458df8SWei Liu static void decode_bswap(CPUX86State *env, struct x86_decode *decode)
63127458df8SWei Liu {
63227458df8SWei Liu decode->op[0].type = X86_VAR_REG;
63327458df8SWei Liu decode->op[0].reg = decode->opcode[1] - 0xc8;
634*77a2dba4SPaolo Bonzini decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
63527458df8SWei Liu decode->rex.b, decode->operand_size);
63627458df8SWei Liu }
63727458df8SWei Liu
decode_d9_4(CPUX86State * env,struct x86_decode * decode)63827458df8SWei Liu static void decode_d9_4(CPUX86State *env, struct x86_decode *decode)
63927458df8SWei Liu {
64027458df8SWei Liu switch (decode->modrm.modrm) {
64127458df8SWei Liu case 0xe0:
64227458df8SWei Liu /* FCHS */
64327458df8SWei Liu decode->cmd = X86_DECODE_CMD_FCHS;
64427458df8SWei Liu break;
64527458df8SWei Liu case 0xe1:
64627458df8SWei Liu decode->cmd = X86_DECODE_CMD_FABS;
64727458df8SWei Liu break;
64827458df8SWei Liu case 0xe4:
64927458df8SWei Liu VM_PANIC("FTST");
65027458df8SWei Liu break;
65127458df8SWei Liu case 0xe5:
65227458df8SWei Liu /* FXAM */
65327458df8SWei Liu decode->cmd = X86_DECODE_CMD_FXAM;
65427458df8SWei Liu break;
65527458df8SWei Liu default:
65627458df8SWei Liu VM_PANIC("FLDENV");
65727458df8SWei Liu break;
65827458df8SWei Liu }
65927458df8SWei Liu }
66027458df8SWei Liu
decode_db_4(CPUX86State * env,struct x86_decode * decode)66127458df8SWei Liu static void decode_db_4(CPUX86State *env, struct x86_decode *decode)
66227458df8SWei Liu {
66327458df8SWei Liu switch (decode->modrm.modrm) {
66427458df8SWei Liu case 0xe0:
66527458df8SWei Liu VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0],
66627458df8SWei Liu decode->modrm.modrm);
66727458df8SWei Liu break;
66827458df8SWei Liu case 0xe1:
66927458df8SWei Liu VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0],
67027458df8SWei Liu decode->modrm.modrm);
67127458df8SWei Liu break;
67227458df8SWei Liu case 0xe2:
67327458df8SWei Liu VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0],
67427458df8SWei Liu decode->modrm.modrm);
67527458df8SWei Liu break;
67627458df8SWei Liu case 0xe3:
67727458df8SWei Liu decode->cmd = X86_DECODE_CMD_FNINIT;
67827458df8SWei Liu break;
67927458df8SWei Liu case 0xe4:
68027458df8SWei Liu decode->cmd = X86_DECODE_CMD_FNSETPM;
68127458df8SWei Liu break;
68227458df8SWei Liu default:
68327458df8SWei Liu VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0],
68427458df8SWei Liu decode->modrm.modrm);
68527458df8SWei Liu break;
68627458df8SWei Liu }
68727458df8SWei Liu }
68827458df8SWei Liu
68927458df8SWei Liu
69027458df8SWei Liu struct decode_tbl _1op_inst[] = {
69127458df8SWei Liu {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
692c901905eSPaolo Bonzini NULL, NULL},
69327458df8SWei Liu {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
694c901905eSPaolo Bonzini NULL, NULL},
69527458df8SWei Liu {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
696c901905eSPaolo Bonzini NULL, NULL},
69727458df8SWei Liu {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL,
698c901905eSPaolo Bonzini NULL, NULL},
69927458df8SWei Liu {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL,
700c901905eSPaolo Bonzini NULL},
70127458df8SWei Liu {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL,
702c901905eSPaolo Bonzini NULL},
70327458df8SWei Liu {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL,
704c901905eSPaolo Bonzini decode_pushseg},
70527458df8SWei Liu {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL,
706c901905eSPaolo Bonzini decode_popseg},
70727458df8SWei Liu {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
708c901905eSPaolo Bonzini NULL, NULL},
70927458df8SWei Liu {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
710c901905eSPaolo Bonzini NULL, NULL},
71127458df8SWei Liu {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
712c901905eSPaolo Bonzini NULL, NULL},
71327458df8SWei Liu {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm,
714c901905eSPaolo Bonzini NULL, NULL, NULL},
71527458df8SWei Liu {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8,
716c901905eSPaolo Bonzini NULL, NULL, NULL},
71727458df8SWei Liu {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm,
718c901905eSPaolo Bonzini NULL, NULL, NULL},
71927458df8SWei Liu
72027458df8SWei Liu {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
721c901905eSPaolo Bonzini NULL, NULL, NULL, decode_pushseg},
72227458df8SWei Liu {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false,
723c901905eSPaolo Bonzini NULL, NULL, NULL, decode_popseg},
72427458df8SWei Liu
72527458df8SWei Liu {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg,
726c901905eSPaolo Bonzini NULL, NULL, NULL},
72727458df8SWei Liu {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg,
728c901905eSPaolo Bonzini NULL, NULL, NULL},
72927458df8SWei Liu {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm,
730c901905eSPaolo Bonzini NULL, NULL, NULL},
73127458df8SWei Liu {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm,
732c901905eSPaolo Bonzini NULL, NULL, NULL},
73327458df8SWei Liu {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm,
734c901905eSPaolo Bonzini NULL, NULL, NULL},
73527458df8SWei Liu {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm,
736c901905eSPaolo Bonzini NULL, NULL, NULL},
73727458df8SWei Liu
73827458df8SWei Liu {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
739c901905eSPaolo Bonzini NULL, NULL, NULL, decode_pushseg},
74027458df8SWei Liu {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false,
741c901905eSPaolo Bonzini NULL, NULL, NULL, decode_popseg},
74227458df8SWei Liu
74327458df8SWei Liu {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg,
744c901905eSPaolo Bonzini NULL, NULL, NULL},
74527458df8SWei Liu {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg,
746c901905eSPaolo Bonzini NULL, NULL, NULL},
74727458df8SWei Liu {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm,
748c901905eSPaolo Bonzini NULL, NULL, NULL},
74927458df8SWei Liu {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm,
750c901905eSPaolo Bonzini NULL, NULL, NULL},
75127458df8SWei Liu {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8,
752c901905eSPaolo Bonzini NULL, NULL, NULL},
75327458df8SWei Liu {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm,
754c901905eSPaolo Bonzini NULL, NULL, NULL},
75527458df8SWei Liu
75627458df8SWei Liu {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
757c901905eSPaolo Bonzini NULL, NULL, NULL, decode_pushseg},
75827458df8SWei Liu {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false,
759c901905eSPaolo Bonzini NULL, NULL, NULL, decode_popseg},
76027458df8SWei Liu
76127458df8SWei Liu {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg,
762c901905eSPaolo Bonzini NULL, NULL, NULL},
76327458df8SWei Liu {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg,
764c901905eSPaolo Bonzini NULL, NULL, NULL},
76527458df8SWei Liu {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm,
766c901905eSPaolo Bonzini NULL, NULL, NULL},
76727458df8SWei Liu {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm,
768c901905eSPaolo Bonzini NULL, NULL, NULL},
76927458df8SWei Liu {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm,
770c901905eSPaolo Bonzini NULL, NULL, NULL},
77127458df8SWei Liu {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm,
772c901905eSPaolo Bonzini NULL, NULL, NULL},
77327458df8SWei Liu {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg,
774c901905eSPaolo Bonzini NULL, NULL, NULL},
77527458df8SWei Liu {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg,
776c901905eSPaolo Bonzini NULL, NULL, NULL},
77727458df8SWei Liu {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm,
778c901905eSPaolo Bonzini NULL, NULL, NULL},
77927458df8SWei Liu {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm,
780c901905eSPaolo Bonzini NULL, NULL, NULL},
78127458df8SWei Liu {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm,
782c901905eSPaolo Bonzini NULL, NULL, NULL},
78327458df8SWei Liu {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm,
784c901905eSPaolo Bonzini NULL, NULL, NULL},
78527458df8SWei Liu {0x2f, X86_DECODE_CMD_DAS, 0, false,
786c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
78727458df8SWei Liu {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg,
788c901905eSPaolo Bonzini NULL, NULL, NULL},
78927458df8SWei Liu {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg,
790c901905eSPaolo Bonzini NULL, NULL, NULL},
79127458df8SWei Liu {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm,
792c901905eSPaolo Bonzini NULL, NULL, NULL},
79327458df8SWei Liu {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm,
794c901905eSPaolo Bonzini NULL, NULL, NULL},
79527458df8SWei Liu {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm,
796c901905eSPaolo Bonzini NULL, NULL, NULL},
79727458df8SWei Liu {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm,
798c901905eSPaolo Bonzini NULL, NULL, NULL},
79927458df8SWei Liu
80027458df8SWei Liu {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg,
801c901905eSPaolo Bonzini NULL, NULL, NULL},
80227458df8SWei Liu {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg,
803c901905eSPaolo Bonzini NULL, NULL, NULL},
80427458df8SWei Liu {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm,
805c901905eSPaolo Bonzini NULL, NULL, NULL},
80627458df8SWei Liu {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm,
807c901905eSPaolo Bonzini NULL, NULL, NULL},
80827458df8SWei Liu {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8,
809c901905eSPaolo Bonzini NULL, NULL, NULL},
81027458df8SWei Liu {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm,
811c901905eSPaolo Bonzini NULL, NULL, NULL},
81227458df8SWei Liu
81327458df8SWei Liu {0x3f, X86_DECODE_CMD_AAS, 0, false,
814c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
81527458df8SWei Liu
81627458df8SWei Liu {0x40, X86_DECODE_CMD_INC, 0, false,
817c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
81827458df8SWei Liu {0x41, X86_DECODE_CMD_INC, 0, false,
819c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
82027458df8SWei Liu {0x42, X86_DECODE_CMD_INC, 0, false,
821c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
82227458df8SWei Liu {0x43, X86_DECODE_CMD_INC, 0, false,
823c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
82427458df8SWei Liu {0x44, X86_DECODE_CMD_INC, 0, false,
825c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
82627458df8SWei Liu {0x45, X86_DECODE_CMD_INC, 0, false,
827c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
82827458df8SWei Liu {0x46, X86_DECODE_CMD_INC, 0, false,
829c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
83027458df8SWei Liu {0x47, X86_DECODE_CMD_INC, 0, false,
831c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup},
83227458df8SWei Liu
83327458df8SWei Liu {0x48, X86_DECODE_CMD_DEC, 0, false,
834c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
83527458df8SWei Liu {0x49, X86_DECODE_CMD_DEC, 0, false,
836c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
83727458df8SWei Liu {0x4a, X86_DECODE_CMD_DEC, 0, false,
838c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
83927458df8SWei Liu {0x4b, X86_DECODE_CMD_DEC, 0, false,
840c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
84127458df8SWei Liu {0x4c, X86_DECODE_CMD_DEC, 0, false,
842c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
84327458df8SWei Liu {0x4d, X86_DECODE_CMD_DEC, 0, false,
844c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
84527458df8SWei Liu {0x4e, X86_DECODE_CMD_DEC, 0, false,
846c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
84727458df8SWei Liu {0x4f, X86_DECODE_CMD_DEC, 0, false,
848c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup},
84927458df8SWei Liu
85027458df8SWei Liu {0x50, X86_DECODE_CMD_PUSH, 0, false,
851c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
85227458df8SWei Liu {0x51, X86_DECODE_CMD_PUSH, 0, false,
853c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
85427458df8SWei Liu {0x52, X86_DECODE_CMD_PUSH, 0, false,
855c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
85627458df8SWei Liu {0x53, X86_DECODE_CMD_PUSH, 0, false,
857c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
85827458df8SWei Liu {0x54, X86_DECODE_CMD_PUSH, 0, false,
859c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
86027458df8SWei Liu {0x55, X86_DECODE_CMD_PUSH, 0, false,
861c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
86227458df8SWei Liu {0x56, X86_DECODE_CMD_PUSH, 0, false,
863c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
86427458df8SWei Liu {0x57, X86_DECODE_CMD_PUSH, 0, false,
865c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup},
86627458df8SWei Liu
86727458df8SWei Liu {0x58, X86_DECODE_CMD_POP, 0, false,
868c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
86927458df8SWei Liu {0x59, X86_DECODE_CMD_POP, 0, false,
870c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
87127458df8SWei Liu {0x5a, X86_DECODE_CMD_POP, 0, false,
872c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
87327458df8SWei Liu {0x5b, X86_DECODE_CMD_POP, 0, false,
874c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
87527458df8SWei Liu {0x5c, X86_DECODE_CMD_POP, 0, false,
876c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
87727458df8SWei Liu {0x5d, X86_DECODE_CMD_POP, 0, false,
878c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
87927458df8SWei Liu {0x5e, X86_DECODE_CMD_POP, 0, false,
880c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
88127458df8SWei Liu {0x5f, X86_DECODE_CMD_POP, 0, false,
882c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup},
88327458df8SWei Liu
88427458df8SWei Liu {0x60, X86_DECODE_CMD_PUSHA, 0, false,
885c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
88627458df8SWei Liu {0x61, X86_DECODE_CMD_POPA, 0, false,
887c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
88827458df8SWei Liu
88927458df8SWei Liu {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm,
890c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
89127458df8SWei Liu {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed,
892c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
89327458df8SWei Liu {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg,
894c901905eSPaolo Bonzini decode_modrm_rm, decode_imm, NULL, NULL},
89527458df8SWei Liu {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm,
896c901905eSPaolo Bonzini decode_imm8_signed, NULL, NULL},
89727458df8SWei Liu
89827458df8SWei Liu {0x6c, X86_DECODE_CMD_INS, 1, false,
899c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
90027458df8SWei Liu {0x6d, X86_DECODE_CMD_INS, 0, false,
901c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
90227458df8SWei Liu {0x6e, X86_DECODE_CMD_OUTS, 1, false,
903c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
90427458df8SWei Liu {0x6f, X86_DECODE_CMD_OUTS, 0, false,
905c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
90627458df8SWei Liu
90727458df8SWei Liu {0x70, X86_DECODE_CMD_JXX, 1, false,
908c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
90927458df8SWei Liu {0x71, X86_DECODE_CMD_JXX, 1, false,
910c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
91127458df8SWei Liu {0x72, X86_DECODE_CMD_JXX, 1, false,
912c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
91327458df8SWei Liu {0x73, X86_DECODE_CMD_JXX, 1, false,
914c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
91527458df8SWei Liu {0x74, X86_DECODE_CMD_JXX, 1, false,
916c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
91727458df8SWei Liu {0x75, X86_DECODE_CMD_JXX, 1, false,
918c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
91927458df8SWei Liu {0x76, X86_DECODE_CMD_JXX, 1, false,
920c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
92127458df8SWei Liu {0x77, X86_DECODE_CMD_JXX, 1, false,
922c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
92327458df8SWei Liu {0x78, X86_DECODE_CMD_JXX, 1, false,
924c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
92527458df8SWei Liu {0x79, X86_DECODE_CMD_JXX, 1, false,
926c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
92727458df8SWei Liu {0x7a, X86_DECODE_CMD_JXX, 1, false,
928c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
92927458df8SWei Liu {0x7b, X86_DECODE_CMD_JXX, 1, false,
930c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
93127458df8SWei Liu {0x7c, X86_DECODE_CMD_JXX, 1, false,
932c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
93327458df8SWei Liu {0x7d, X86_DECODE_CMD_JXX, 1, false,
934c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
93527458df8SWei Liu {0x7e, X86_DECODE_CMD_JXX, 1, false,
936c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
93727458df8SWei Liu {0x7f, X86_DECODE_CMD_JXX, 1, false,
938c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
93927458df8SWei Liu
94027458df8SWei Liu {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
941c901905eSPaolo Bonzini NULL, NULL, decode_addgroup},
94227458df8SWei Liu {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm,
943c901905eSPaolo Bonzini NULL, NULL, decode_addgroup},
94427458df8SWei Liu {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
945c901905eSPaolo Bonzini NULL, NULL, decode_addgroup},
94627458df8SWei Liu {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed,
947c901905eSPaolo Bonzini NULL, NULL, decode_addgroup},
94827458df8SWei Liu {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg,
949c901905eSPaolo Bonzini NULL, NULL, NULL},
95027458df8SWei Liu {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg,
951c901905eSPaolo Bonzini NULL, NULL, NULL},
95227458df8SWei Liu {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm,
953c901905eSPaolo Bonzini NULL, NULL, NULL},
95427458df8SWei Liu {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm,
955c901905eSPaolo Bonzini NULL, NULL, NULL},
95627458df8SWei Liu {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg,
957c901905eSPaolo Bonzini NULL, NULL, NULL},
95827458df8SWei Liu {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg,
959c901905eSPaolo Bonzini NULL, NULL, NULL},
96027458df8SWei Liu {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm,
961c901905eSPaolo Bonzini NULL, NULL, NULL},
96227458df8SWei Liu {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm,
963c901905eSPaolo Bonzini NULL, NULL, NULL},
96427458df8SWei Liu {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm,
965c901905eSPaolo Bonzini decode_modrm_reg, NULL, NULL, NULL},
96627458df8SWei Liu {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm,
967c901905eSPaolo Bonzini NULL, NULL, NULL},
96827458df8SWei Liu {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg,
969c901905eSPaolo Bonzini decode_modrm_rm, NULL, NULL, NULL},
97027458df8SWei Liu {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm,
971c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
97227458df8SWei Liu
97327458df8SWei Liu {0x90, X86_DECODE_CMD_NOP, 0, false,
974c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
97527458df8SWei Liu {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
976c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
97727458df8SWei Liu {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
978c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
97927458df8SWei Liu {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
980c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
98127458df8SWei Liu {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
982c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
98327458df8SWei Liu {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
984c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
98527458df8SWei Liu {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
986c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
98727458df8SWei Liu {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
988c901905eSPaolo Bonzini NULL, NULL, decode_xchgroup},
98927458df8SWei Liu
99027458df8SWei Liu {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL,
991c901905eSPaolo Bonzini NULL, NULL, NULL},
99227458df8SWei Liu {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL,
993c901905eSPaolo Bonzini NULL, NULL, NULL},
99427458df8SWei Liu
99527458df8SWei Liu {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL,
996c901905eSPaolo Bonzini NULL, NULL, NULL, decode_farjmp},
99727458df8SWei Liu
99827458df8SWei Liu {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL,
999c901905eSPaolo Bonzini NULL, NULL, NULL},
100027458df8SWei Liu /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL,
1001c901905eSPaolo Bonzini NULL, NULL, NULL},*/
100227458df8SWei Liu {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL,
1003c901905eSPaolo Bonzini NULL, NULL, NULL},
100427458df8SWei Liu {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL,
1005c901905eSPaolo Bonzini NULL, NULL, NULL},
100627458df8SWei Liu
100727458df8SWei Liu {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs,
1008c901905eSPaolo Bonzini NULL, NULL, NULL},
100927458df8SWei Liu {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs,
1010c901905eSPaolo Bonzini NULL, NULL, NULL},
101127458df8SWei Liu {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax,
1012c901905eSPaolo Bonzini NULL, NULL, NULL},
101327458df8SWei Liu {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax,
1014c901905eSPaolo Bonzini NULL, NULL, NULL},
101527458df8SWei Liu
101627458df8SWei Liu {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL,
1017c901905eSPaolo Bonzini NULL, NULL, NULL},
101827458df8SWei Liu {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL,
1019c901905eSPaolo Bonzini NULL, NULL, NULL},
102027458df8SWei Liu {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL,
1021c901905eSPaolo Bonzini NULL, NULL, NULL},
102227458df8SWei Liu {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL,
1023c901905eSPaolo Bonzini NULL, NULL, NULL},
102427458df8SWei Liu {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL,
1025c901905eSPaolo Bonzini NULL, NULL, NULL},
102627458df8SWei Liu {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL,
1027c901905eSPaolo Bonzini NULL, NULL, NULL},
102827458df8SWei Liu {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL,
1029c901905eSPaolo Bonzini NULL, NULL, NULL},
103027458df8SWei Liu {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL,
1031c901905eSPaolo Bonzini NULL, NULL, NULL},
103227458df8SWei Liu {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL,
1033c901905eSPaolo Bonzini NULL, NULL, NULL},
103427458df8SWei Liu {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL,
1035c901905eSPaolo Bonzini NULL, NULL, NULL},
103627458df8SWei Liu
103727458df8SWei Liu {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm,
1038c901905eSPaolo Bonzini NULL, NULL, NULL},
103927458df8SWei Liu {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm,
1040c901905eSPaolo Bonzini NULL, NULL, NULL},
104127458df8SWei Liu
104227458df8SWei Liu {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL,
1043c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
104427458df8SWei Liu {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL,
1045c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
104627458df8SWei Liu {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL,
1047c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
104827458df8SWei Liu {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL,
1049c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
105027458df8SWei Liu {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL,
1051c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
105227458df8SWei Liu {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL,
1053c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
105427458df8SWei Liu {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL,
1055c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
105627458df8SWei Liu {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL,
1057c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8},
105827458df8SWei Liu
105927458df8SWei Liu {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL,
1060c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
106127458df8SWei Liu {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL,
1062c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
106327458df8SWei Liu {0xba, X86_DECODE_CMD_MOV, 0, false, NULL,
1064c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
106527458df8SWei Liu {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL,
1066c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
106727458df8SWei Liu {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL,
1068c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
106927458df8SWei Liu {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL,
1070c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
107127458df8SWei Liu {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL,
1072c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
107327458df8SWei Liu {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL,
1074c901905eSPaolo Bonzini NULL, NULL, NULL, decode_movgroup},
107527458df8SWei Liu
107627458df8SWei Liu {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
1077c901905eSPaolo Bonzini NULL, NULL, decode_rotgroup},
107827458df8SWei Liu {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1079c901905eSPaolo Bonzini NULL, NULL, decode_rotgroup},
108027458df8SWei Liu
108127458df8SWei Liu {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16,
1082c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
108327458df8SWei Liu {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL,
1084c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
108527458df8SWei Liu
108627458df8SWei Liu {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm,
1087c901905eSPaolo Bonzini NULL, NULL, NULL},
108827458df8SWei Liu {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm,
1089c901905eSPaolo Bonzini NULL, NULL, NULL},
109027458df8SWei Liu
109127458df8SWei Liu {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8,
1092c901905eSPaolo Bonzini NULL, NULL, NULL},
109327458df8SWei Liu {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm,
1094c901905eSPaolo Bonzini NULL, NULL, NULL},
109527458df8SWei Liu
109627458df8SWei Liu {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8,
1097c901905eSPaolo Bonzini NULL, NULL, NULL},
109827458df8SWei Liu {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL,
1099c901905eSPaolo Bonzini NULL, NULL, NULL},
110027458df8SWei Liu {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL,
1101c901905eSPaolo Bonzini NULL, NULL, NULL},
110227458df8SWei Liu {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL,
1103c901905eSPaolo Bonzini NULL, NULL, NULL},
110427458df8SWei Liu {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL,
1105c901905eSPaolo Bonzini NULL, NULL, NULL},
110627458df8SWei Liu /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL,
1107c901905eSPaolo Bonzini NULL, NULL, NULL},*/
110827458df8SWei Liu
110927458df8SWei Liu {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1,
1110c901905eSPaolo Bonzini NULL, NULL, decode_rotgroup},
111127458df8SWei Liu {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1,
1112c901905eSPaolo Bonzini NULL, NULL, decode_rotgroup},
111327458df8SWei Liu {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx,
1114c901905eSPaolo Bonzini NULL, NULL, decode_rotgroup},
111527458df8SWei Liu {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx,
1116c901905eSPaolo Bonzini NULL, NULL, decode_rotgroup},
111727458df8SWei Liu
111827458df8SWei Liu {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8,
1119c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
112027458df8SWei Liu {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8,
1121c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
112227458df8SWei Liu
112327458df8SWei Liu {0xd7, X86_DECODE_CMD_XLAT, 0, false,
1124c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
112527458df8SWei Liu
112627458df8SWei Liu {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL,
1127c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
112827458df8SWei Liu {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL,
1129c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
113027458df8SWei Liu {0xda, X86_DECODE_CMD_INVL, 0, true, NULL,
1131c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
113227458df8SWei Liu {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL,
1133c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
113427458df8SWei Liu {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL,
1135c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
113627458df8SWei Liu {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL,
1137c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
113827458df8SWei Liu {0xde, X86_DECODE_CMD_INVL, 0, true, NULL,
1139c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
114027458df8SWei Liu {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL,
1141c901905eSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins},
114227458df8SWei Liu
114327458df8SWei Liu {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1144c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
114527458df8SWei Liu {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1146c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
114727458df8SWei Liu {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1148c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
114927458df8SWei Liu
115027458df8SWei Liu {0xe3, X86_DECODE_CMD_JCXZ, 1, false,
1151c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
115227458df8SWei Liu
115327458df8SWei Liu {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8,
1154c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
115527458df8SWei Liu {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8,
1156c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
115727458df8SWei Liu {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8,
1158c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
115927458df8SWei Liu {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8,
1160c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
116127458df8SWei Liu {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed,
1162c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
116327458df8SWei Liu {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed,
1164c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
116527458df8SWei Liu {0xea, X86_DECODE_CMD_JMP_FAR, 0, false,
1166c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_farjmp},
116727458df8SWei Liu {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed,
1168c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
116927458df8SWei Liu {0xec, X86_DECODE_CMD_IN, 1, false,
1170c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
117127458df8SWei Liu {0xed, X86_DECODE_CMD_IN, 0, false,
1172c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
117327458df8SWei Liu {0xee, X86_DECODE_CMD_OUT, 1, false,
1174c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
117527458df8SWei Liu {0xef, X86_DECODE_CMD_OUT, 0, false,
1176c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
117727458df8SWei Liu
117827458df8SWei Liu {0xf4, X86_DECODE_CMD_HLT, 0, false,
1179c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
118027458df8SWei Liu
118127458df8SWei Liu {0xf5, X86_DECODE_CMD_CMC, 0, false,
1182c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
118327458df8SWei Liu
118427458df8SWei Liu {0xf6, X86_DECODE_CMD_INVL, 1, true,
1185c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_f7group},
118627458df8SWei Liu {0xf7, X86_DECODE_CMD_INVL, 0, true,
1187c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_f7group},
118827458df8SWei Liu
118927458df8SWei Liu {0xf8, X86_DECODE_CMD_CLC, 0, false,
1190c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
119127458df8SWei Liu {0xf9, X86_DECODE_CMD_STC, 0, false,
1192c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
119327458df8SWei Liu
119427458df8SWei Liu {0xfa, X86_DECODE_CMD_CLI, 0, false,
1195c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
119627458df8SWei Liu {0xfb, X86_DECODE_CMD_STI, 0, false,
1197c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
119827458df8SWei Liu {0xfc, X86_DECODE_CMD_CLD, 0, false,
1199c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
120027458df8SWei Liu {0xfd, X86_DECODE_CMD_STD, 0, false,
1201c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
120227458df8SWei Liu {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm,
1203c901905eSPaolo Bonzini NULL, NULL, NULL, decode_incgroup2},
120427458df8SWei Liu {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1205c901905eSPaolo Bonzini NULL, NULL, NULL, decode_ffgroup},
120627458df8SWei Liu };
120727458df8SWei Liu
120827458df8SWei Liu struct decode_tbl _2op_inst[] = {
120927458df8SWei Liu {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1210c901905eSPaolo Bonzini NULL, NULL, NULL, decode_sldtgroup},
121127458df8SWei Liu {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1212c901905eSPaolo Bonzini NULL, NULL, NULL, decode_lidtgroup},
121327458df8SWei Liu {0x6, X86_DECODE_CMD_CLTS, 0, false,
1214c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
121527458df8SWei Liu {0x9, X86_DECODE_CMD_WBINVD, 0, false,
1216c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
121727458df8SWei Liu {0x18, X86_DECODE_CMD_PREFETCH, 0, true,
1218c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_x87_general},
121927458df8SWei Liu {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm,
1220c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
122127458df8SWei Liu {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm,
1222c901905eSPaolo Bonzini decode_modrm_reg, NULL, NULL, NULL},
122327458df8SWei Liu {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm,
1224c901905eSPaolo Bonzini decode_modrm_reg, NULL, NULL, NULL},
122527458df8SWei Liu {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg,
1226c901905eSPaolo Bonzini decode_modrm_rm, NULL, NULL, NULL},
122727458df8SWei Liu {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg,
1228c901905eSPaolo Bonzini decode_modrm_rm, NULL, NULL, NULL},
122927458df8SWei Liu {0x30, X86_DECODE_CMD_WRMSR, 0, false,
1230c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
123127458df8SWei Liu {0x31, X86_DECODE_CMD_RDTSC, 0, false,
1232c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
123327458df8SWei Liu {0x32, X86_DECODE_CMD_RDMSR, 0, false,
1234c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
123527458df8SWei Liu {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1236c901905eSPaolo Bonzini NULL, NULL, NULL},
123727458df8SWei Liu {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1238c901905eSPaolo Bonzini NULL, NULL, NULL},
123927458df8SWei Liu {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1240c901905eSPaolo Bonzini NULL, NULL, NULL},
124127458df8SWei Liu {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1242c901905eSPaolo Bonzini NULL, NULL, NULL},
124327458df8SWei Liu {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1244c901905eSPaolo Bonzini NULL, NULL, NULL},
124527458df8SWei Liu {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1246c901905eSPaolo Bonzini NULL, NULL, NULL},
124727458df8SWei Liu {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1248c901905eSPaolo Bonzini NULL, NULL, NULL},
124927458df8SWei Liu {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1250c901905eSPaolo Bonzini NULL, NULL, NULL},
125127458df8SWei Liu {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1252c901905eSPaolo Bonzini NULL, NULL, NULL},
125327458df8SWei Liu {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1254c901905eSPaolo Bonzini NULL, NULL, NULL},
125527458df8SWei Liu {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1256c901905eSPaolo Bonzini NULL, NULL, NULL},
125727458df8SWei Liu {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1258c901905eSPaolo Bonzini NULL, NULL, NULL},
125927458df8SWei Liu {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1260c901905eSPaolo Bonzini NULL, NULL, NULL},
126127458df8SWei Liu {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1262c901905eSPaolo Bonzini NULL, NULL, NULL},
126327458df8SWei Liu {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1264c901905eSPaolo Bonzini NULL, NULL, NULL},
126527458df8SWei Liu {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1266c901905eSPaolo Bonzini NULL, NULL, NULL},
126727458df8SWei Liu {0x77, X86_DECODE_CMD_EMMS, 0, false,
1268c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_x87_general},
126927458df8SWei Liu {0x82, X86_DECODE_CMD_JXX, 0, false,
1270c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
127127458df8SWei Liu {0x83, X86_DECODE_CMD_JXX, 0, false,
1272c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
127327458df8SWei Liu {0x84, X86_DECODE_CMD_JXX, 0, false,
1274c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
127527458df8SWei Liu {0x85, X86_DECODE_CMD_JXX, 0, false,
1276c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
127727458df8SWei Liu {0x86, X86_DECODE_CMD_JXX, 0, false,
1278c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
127927458df8SWei Liu {0x87, X86_DECODE_CMD_JXX, 0, false,
1280c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
128127458df8SWei Liu {0x88, X86_DECODE_CMD_JXX, 0, false,
1282c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
128327458df8SWei Liu {0x89, X86_DECODE_CMD_JXX, 0, false,
1284c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
128527458df8SWei Liu {0x8a, X86_DECODE_CMD_JXX, 0, false,
1286c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
128727458df8SWei Liu {0x8b, X86_DECODE_CMD_JXX, 0, false,
1288c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
128927458df8SWei Liu {0x8c, X86_DECODE_CMD_JXX, 0, false,
1290c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
129127458df8SWei Liu {0x8d, X86_DECODE_CMD_JXX, 0, false,
1292c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
129327458df8SWei Liu {0x8e, X86_DECODE_CMD_JXX, 0, false,
1294c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
129527458df8SWei Liu {0x8f, X86_DECODE_CMD_JXX, 0, false,
1296c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx},
129727458df8SWei Liu {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1298c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
129927458df8SWei Liu {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1300c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
130127458df8SWei Liu {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1302c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
130327458df8SWei Liu {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1304c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
130527458df8SWei Liu {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1306c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
130727458df8SWei Liu {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1308c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
130927458df8SWei Liu {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1310c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
131127458df8SWei Liu {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1312c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
131327458df8SWei Liu {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1314c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
131527458df8SWei Liu {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1316c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
131727458df8SWei Liu {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1318c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
131927458df8SWei Liu {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1320c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
132127458df8SWei Liu {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1322c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
132327458df8SWei Liu {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1324c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
132527458df8SWei Liu {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1326c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
132727458df8SWei Liu {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1328c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
132927458df8SWei Liu
133027458df8SWei Liu {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg,
1331c901905eSPaolo Bonzini NULL, NULL, NULL},
133227458df8SWei Liu {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg,
1333c901905eSPaolo Bonzini NULL, NULL, NULL},
133427458df8SWei Liu
133527458df8SWei Liu {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1336c901905eSPaolo Bonzini NULL, NULL, NULL},
133727458df8SWei Liu {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1338c901905eSPaolo Bonzini NULL, NULL, NULL},
133927458df8SWei Liu {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm,
1340c901905eSPaolo Bonzini NULL, NULL, NULL},
134127458df8SWei Liu {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1342c901905eSPaolo Bonzini NULL, NULL, NULL},
134327458df8SWei Liu {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1344c901905eSPaolo Bonzini NULL, NULL, NULL},
134527458df8SWei Liu {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1346c901905eSPaolo Bonzini NULL, NULL, NULL, decode_pushseg},
134727458df8SWei Liu {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false,
1348c901905eSPaolo Bonzini NULL, NULL, NULL, decode_popseg},
134927458df8SWei Liu {0xa2, X86_DECODE_CMD_CPUID, 0, false,
1350c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, NULL},
135127458df8SWei Liu {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg,
1352c901905eSPaolo Bonzini NULL, NULL, NULL},
135327458df8SWei Liu {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1354c901905eSPaolo Bonzini decode_imm8, NULL, NULL},
135527458df8SWei Liu {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1356c901905eSPaolo Bonzini decode_rcx, NULL, NULL},
135727458df8SWei Liu {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1358c901905eSPaolo Bonzini NULL, NULL, NULL, decode_pushseg},
135927458df8SWei Liu {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false,
1360c901905eSPaolo Bonzini NULL, NULL, NULL, decode_popseg},
136127458df8SWei Liu {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg,
1362c901905eSPaolo Bonzini NULL, NULL, NULL},
136327458df8SWei Liu {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1364c901905eSPaolo Bonzini decode_imm8, NULL, NULL},
136527458df8SWei Liu {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1366c901905eSPaolo Bonzini decode_rcx, NULL, NULL},
136727458df8SWei Liu
136827458df8SWei Liu {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1369c901905eSPaolo Bonzini NULL, NULL, NULL, decode_aegroup},
137027458df8SWei Liu
137127458df8SWei Liu {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm,
1372c901905eSPaolo Bonzini NULL, NULL, NULL},
137327458df8SWei Liu {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm,
1374c901905eSPaolo Bonzini NULL, NULL, NULL},
137527458df8SWei Liu {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg,
1376c901905eSPaolo Bonzini NULL, NULL, NULL},
137727458df8SWei Liu {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1378c901905eSPaolo Bonzini NULL, NULL, decode_btgroup},
137927458df8SWei Liu {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg,
1380c901905eSPaolo Bonzini NULL, NULL, NULL},
138127458df8SWei Liu {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm,
1382c901905eSPaolo Bonzini NULL, NULL, NULL},
138327458df8SWei Liu {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm,
1384c901905eSPaolo Bonzini NULL, NULL, NULL},
138527458df8SWei Liu
138627458df8SWei Liu {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg,
1387c901905eSPaolo Bonzini NULL, NULL, NULL},
138827458df8SWei Liu
138927458df8SWei Liu {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm,
1390c901905eSPaolo Bonzini NULL, NULL, NULL, NULL},
139127458df8SWei Liu
139227458df8SWei Liu {0xc8, X86_DECODE_CMD_BSWAP, 0, false,
1393c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
139427458df8SWei Liu {0xc9, X86_DECODE_CMD_BSWAP, 0, false,
1395c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
139627458df8SWei Liu {0xca, X86_DECODE_CMD_BSWAP, 0, false,
1397c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
139827458df8SWei Liu {0xcb, X86_DECODE_CMD_BSWAP, 0, false,
1399c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
140027458df8SWei Liu {0xcc, X86_DECODE_CMD_BSWAP, 0, false,
1401c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
140227458df8SWei Liu {0xcd, X86_DECODE_CMD_BSWAP, 0, false,
1403c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
140427458df8SWei Liu {0xce, X86_DECODE_CMD_BSWAP, 0, false,
1405c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
140627458df8SWei Liu {0xcf, X86_DECODE_CMD_BSWAP, 0, false,
1407c901905eSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap},
140827458df8SWei Liu };
140927458df8SWei Liu
141027458df8SWei Liu struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL,
14117c93067fSMagnus Kulke NULL, decode_invalid};
141227458df8SWei Liu
141327458df8SWei Liu struct decode_x87_tbl _x87_inst[] = {
141427458df8SWei Liu {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1415c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL},
141627458df8SWei Liu {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1417c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL},
141827458df8SWei Liu {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0,
1419c901905eSPaolo Bonzini decode_decode_x87_modrm_st0, NULL},
142027458df8SWei Liu {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1421c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL},
142227458df8SWei Liu {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0,
1423c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
142427458df8SWei Liu {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1425c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL},
142627458df8SWei Liu {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0,
1427c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
142827458df8SWei Liu {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1429c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL},
143027458df8SWei Liu {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0,
1431c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
143227458df8SWei Liu {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1433c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL},
143427458df8SWei Liu {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0,
1435c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
143627458df8SWei Liu {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1437c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL},
143827458df8SWei Liu
143927458df8SWei Liu {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false,
1440c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL},
144127458df8SWei Liu {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1442c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
144327458df8SWei Liu {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0,
1444c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
144527458df8SWei Liu {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false,
1446c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL},
144727458df8SWei Liu {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false,
1448c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL},
144927458df8SWei Liu {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1450c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
145127458df8SWei Liu {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false,
1452c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL},
145327458df8SWei Liu {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1454c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
145527458df8SWei Liu {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false,
1456c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, decode_d9_4},
145727458df8SWei Liu {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false,
1458c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
14597c93067fSMagnus Kulke {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL},
146027458df8SWei Liu {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false,
1461c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
146227458df8SWei Liu
146327458df8SWei Liu {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false,
1464c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
146527458df8SWei Liu {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false,
1466c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
146727458df8SWei Liu
146827458df8SWei Liu {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1469c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
147027458df8SWei Liu {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1471c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL},
147227458df8SWei Liu {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1473c901905eSPaolo Bonzini decode_decode_x87_modrm_st0, NULL},
147427458df8SWei Liu {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1475c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL},
147627458df8SWei Liu {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1477c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
147827458df8SWei Liu {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1479c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
14807c93067fSMagnus Kulke {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL},
148127458df8SWei Liu {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1482c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL},
148327458df8SWei Liu {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0,
1484c901905eSPaolo Bonzini decode_decode_x87_modrm_st0, NULL},
148527458df8SWei Liu {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1486c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL},
14877c93067fSMagnus Kulke {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL},
148827458df8SWei Liu {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1489c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL},
14907c93067fSMagnus Kulke {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL},
149127458df8SWei Liu {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1492c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL},
149327458df8SWei Liu
149427458df8SWei Liu {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1495c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL},
149627458df8SWei Liu {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1497c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
149827458df8SWei Liu {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1499c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
150027458df8SWei Liu {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1501c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
150227458df8SWei Liu {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1503c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
150427458df8SWei Liu {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1505c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
150627458df8SWei Liu {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1507c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
150827458df8SWei Liu {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL,
1509c901905eSPaolo Bonzini decode_db_4},
15107c93067fSMagnus Kulke {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL},
151127458df8SWei Liu {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false,
1512c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
151327458df8SWei Liu {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false,
1514c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
151527458df8SWei Liu {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true,
1516c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
151727458df8SWei Liu
151827458df8SWei Liu {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1519c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
152027458df8SWei Liu {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false,
1521c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
152227458df8SWei Liu {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false,
1523c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
152427458df8SWei Liu {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false,
1525c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
152627458df8SWei Liu {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false,
1527c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
152827458df8SWei Liu {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false,
1529c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
153027458df8SWei Liu {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false,
1531c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
153227458df8SWei Liu {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false,
1533c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
153427458df8SWei Liu {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false,
1535c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
153627458df8SWei Liu {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false,
1537c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
153827458df8SWei Liu {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false,
1539c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
154027458df8SWei Liu {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false,
1541c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
154227458df8SWei Liu
154327458df8SWei Liu {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false,
1544c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
154527458df8SWei Liu {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1546c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
154727458df8SWei Liu {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false,
1548c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL},
154927458df8SWei Liu {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false,
1550c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
155127458df8SWei Liu {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1552c901905eSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL},
155327458df8SWei Liu {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true,
1554c901905eSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL},
155527458df8SWei Liu {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false,
1556c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
155727458df8SWei Liu {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false,
1558c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
155927458df8SWei Liu {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true,
1560c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
156127458df8SWei Liu {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false,
1562c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
156327458df8SWei Liu {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false,
1564c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
156527458df8SWei Liu
156627458df8SWei Liu {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true,
1567c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
156827458df8SWei Liu {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false,
1569c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
157027458df8SWei Liu {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true,
1571c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
157227458df8SWei Liu {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false,
1573c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
157427458df8SWei Liu {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true,
1575c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
157627458df8SWei Liu {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false,
1577c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
157827458df8SWei Liu {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true,
1579c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
158027458df8SWei Liu {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false,
1581c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
158227458df8SWei Liu {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true,
1583c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
158427458df8SWei Liu {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false,
1585c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
158627458df8SWei Liu {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true,
1587c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
158827458df8SWei Liu {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false,
1589c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
159027458df8SWei Liu
159127458df8SWei Liu {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false,
1592c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
159327458df8SWei Liu {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1594c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
159527458df8SWei Liu {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true,
1596c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
159727458df8SWei Liu {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false,
1598c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
159927458df8SWei Liu {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1600c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
160127458df8SWei Liu {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true,
1602c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
160327458df8SWei Liu {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true,
1604c901905eSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL},
160527458df8SWei Liu {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true,
1606c901905eSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
160727458df8SWei Liu {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false,
1608c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
160927458df8SWei Liu {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true,
1610c901905eSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL},
161127458df8SWei Liu };
161227458df8SWei Liu
calc_modrm_operand16(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)161327458df8SWei Liu void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
161427458df8SWei Liu struct x86_decode_op *op)
161527458df8SWei Liu {
161627458df8SWei Liu target_ulong ptr = 0;
161727458df8SWei Liu X86Seg seg = R_DS;
161827458df8SWei Liu
161927458df8SWei Liu if (!decode->modrm.mod && 6 == decode->modrm.rm) {
162027458df8SWei Liu ptr = decode->displacement;
162127458df8SWei Liu goto calc_addr;
162227458df8SWei Liu }
162327458df8SWei Liu
162427458df8SWei Liu if (decode->displacement_size) {
162527458df8SWei Liu ptr = sign(decode->displacement, decode->displacement_size);
162627458df8SWei Liu }
162727458df8SWei Liu
162827458df8SWei Liu switch (decode->modrm.rm) {
162927458df8SWei Liu case 0:
163027458df8SWei Liu ptr += BX(env) + SI(env);
163127458df8SWei Liu break;
163227458df8SWei Liu case 1:
163327458df8SWei Liu ptr += BX(env) + DI(env);
163427458df8SWei Liu break;
163527458df8SWei Liu case 2:
163627458df8SWei Liu ptr += BP(env) + SI(env);
163727458df8SWei Liu seg = R_SS;
163827458df8SWei Liu break;
163927458df8SWei Liu case 3:
164027458df8SWei Liu ptr += BP(env) + DI(env);
164127458df8SWei Liu seg = R_SS;
164227458df8SWei Liu break;
164327458df8SWei Liu case 4:
164427458df8SWei Liu ptr += SI(env);
164527458df8SWei Liu break;
164627458df8SWei Liu case 5:
164727458df8SWei Liu ptr += DI(env);
164827458df8SWei Liu break;
164927458df8SWei Liu case 6:
165027458df8SWei Liu ptr += BP(env);
165127458df8SWei Liu seg = R_SS;
165227458df8SWei Liu break;
165327458df8SWei Liu case 7:
165427458df8SWei Liu ptr += BX(env);
165527458df8SWei Liu break;
165627458df8SWei Liu }
165727458df8SWei Liu calc_addr:
165827458df8SWei Liu if (X86_DECODE_CMD_LEA == decode->cmd) {
1659*77a2dba4SPaolo Bonzini op->addr = (uint16_t)ptr;
166027458df8SWei Liu } else {
1661*77a2dba4SPaolo Bonzini op->addr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
166227458df8SWei Liu }
166327458df8SWei Liu }
166427458df8SWei Liu
get_reg_ref(CPUX86State * env,int reg,int rex_present,int is_extended,int size)1665*77a2dba4SPaolo Bonzini void *get_reg_ref(CPUX86State *env, int reg, int rex_present,
166627458df8SWei Liu int is_extended, int size)
166727458df8SWei Liu {
1668*77a2dba4SPaolo Bonzini void *ptr = NULL;
166927458df8SWei Liu
167027458df8SWei Liu if (is_extended) {
167127458df8SWei Liu reg |= R_R8;
167227458df8SWei Liu }
167327458df8SWei Liu
167427458df8SWei Liu switch (size) {
167527458df8SWei Liu case 1:
167627458df8SWei Liu if (is_extended || reg < 4 || rex_present) {
1677*77a2dba4SPaolo Bonzini ptr = &RL(env, reg);
167827458df8SWei Liu } else {
1679*77a2dba4SPaolo Bonzini ptr = &RH(env, reg - 4);
168027458df8SWei Liu }
168127458df8SWei Liu break;
168227458df8SWei Liu default:
1683*77a2dba4SPaolo Bonzini ptr = &RRX(env, reg);
168427458df8SWei Liu break;
168527458df8SWei Liu }
168627458df8SWei Liu return ptr;
168727458df8SWei Liu }
168827458df8SWei Liu
get_reg_val(CPUX86State * env,int reg,int rex_present,int is_extended,int size)168927458df8SWei Liu target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
169027458df8SWei Liu int is_extended, int size)
169127458df8SWei Liu {
169227458df8SWei Liu target_ulong val = 0;
169327458df8SWei Liu memcpy(&val,
1694*77a2dba4SPaolo Bonzini get_reg_ref(env, reg, rex_present, is_extended, size),
169527458df8SWei Liu size);
169627458df8SWei Liu return val;
169727458df8SWei Liu }
169827458df8SWei Liu
get_sib_val(CPUX86State * env,struct x86_decode * decode,X86Seg * sel)169927458df8SWei Liu static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode,
170027458df8SWei Liu X86Seg *sel)
170127458df8SWei Liu {
170227458df8SWei Liu target_ulong base = 0;
170327458df8SWei Liu target_ulong scaled_index = 0;
170427458df8SWei Liu int addr_size = decode->addressing_size;
170527458df8SWei Liu int base_reg = decode->sib.base;
170627458df8SWei Liu int index_reg = decode->sib.index;
170727458df8SWei Liu
170827458df8SWei Liu *sel = R_DS;
170927458df8SWei Liu
171027458df8SWei Liu if (decode->modrm.mod || base_reg != R_EBP) {
171127458df8SWei Liu if (decode->rex.b) {
171227458df8SWei Liu base_reg |= R_R8;
171327458df8SWei Liu }
171427458df8SWei Liu if (base_reg == R_ESP || base_reg == R_EBP) {
171527458df8SWei Liu *sel = R_SS;
171627458df8SWei Liu }
171727458df8SWei Liu base = get_reg_val(env, decode->sib.base, decode->rex.rex,
171827458df8SWei Liu decode->rex.b, addr_size);
171927458df8SWei Liu }
172027458df8SWei Liu
172127458df8SWei Liu if (decode->rex.x) {
172227458df8SWei Liu index_reg |= R_R8;
172327458df8SWei Liu }
172427458df8SWei Liu
172527458df8SWei Liu if (index_reg != R_ESP) {
172627458df8SWei Liu scaled_index = get_reg_val(env, index_reg, decode->rex.rex,
172727458df8SWei Liu decode->rex.x, addr_size) <<
172827458df8SWei Liu decode->sib.scale;
172927458df8SWei Liu }
173027458df8SWei Liu return base + scaled_index;
173127458df8SWei Liu }
173227458df8SWei Liu
calc_modrm_operand32(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)173327458df8SWei Liu void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
173427458df8SWei Liu struct x86_decode_op *op)
173527458df8SWei Liu {
173627458df8SWei Liu X86Seg seg = R_DS;
173727458df8SWei Liu target_ulong ptr = 0;
173827458df8SWei Liu int addr_size = decode->addressing_size;
173927458df8SWei Liu
174027458df8SWei Liu if (decode->displacement_size) {
174127458df8SWei Liu ptr = sign(decode->displacement, decode->displacement_size);
174227458df8SWei Liu }
174327458df8SWei Liu
174427458df8SWei Liu if (4 == decode->modrm.rm) {
174527458df8SWei Liu ptr += get_sib_val(env, decode, &seg);
174627458df8SWei Liu } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
174727458df8SWei Liu if (x86_is_long_mode(env_cpu(env))) {
174827458df8SWei Liu ptr += env->eip + decode->len;
174927458df8SWei Liu } else {
175027458df8SWei Liu ptr = decode->displacement;
175127458df8SWei Liu }
175227458df8SWei Liu } else {
175327458df8SWei Liu if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) {
175427458df8SWei Liu seg = R_SS;
175527458df8SWei Liu }
175627458df8SWei Liu ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex,
175727458df8SWei Liu decode->rex.b, addr_size);
175827458df8SWei Liu }
175927458df8SWei Liu
176027458df8SWei Liu if (X86_DECODE_CMD_LEA == decode->cmd) {
1761*77a2dba4SPaolo Bonzini op->addr = (uint32_t)ptr;
176227458df8SWei Liu } else {
1763*77a2dba4SPaolo Bonzini op->addr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
176427458df8SWei Liu }
176527458df8SWei Liu }
176627458df8SWei Liu
calc_modrm_operand64(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)176727458df8SWei Liu void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
176827458df8SWei Liu struct x86_decode_op *op)
176927458df8SWei Liu {
177027458df8SWei Liu X86Seg seg = R_DS;
177127458df8SWei Liu int32_t offset = 0;
177227458df8SWei Liu int mod = decode->modrm.mod;
177327458df8SWei Liu int rm = decode->modrm.rm;
177427458df8SWei Liu target_ulong ptr;
177527458df8SWei Liu int src = decode->modrm.rm;
177627458df8SWei Liu
177727458df8SWei Liu if (decode->displacement_size) {
177827458df8SWei Liu offset = sign(decode->displacement, decode->displacement_size);
177927458df8SWei Liu }
178027458df8SWei Liu
178127458df8SWei Liu if (4 == rm) {
178227458df8SWei Liu ptr = get_sib_val(env, decode, &seg) + offset;
178327458df8SWei Liu } else if (0 == mod && 5 == rm) {
178427458df8SWei Liu ptr = env->eip + decode->len + (int32_t) offset;
178527458df8SWei Liu } else {
178627458df8SWei Liu ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) +
178727458df8SWei Liu (int64_t) offset;
178827458df8SWei Liu }
178927458df8SWei Liu
179027458df8SWei Liu if (X86_DECODE_CMD_LEA == decode->cmd) {
1791*77a2dba4SPaolo Bonzini op->addr = ptr;
179227458df8SWei Liu } else {
1793*77a2dba4SPaolo Bonzini op->addr = decode_linear_addr(env, decode, ptr, seg);
179427458df8SWei Liu }
179527458df8SWei Liu }
179627458df8SWei Liu
179727458df8SWei Liu
calc_modrm_operand(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)179827458df8SWei Liu void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
179927458df8SWei Liu struct x86_decode_op *op)
180027458df8SWei Liu {
180127458df8SWei Liu if (3 == decode->modrm.mod) {
180227458df8SWei Liu op->reg = decode->modrm.reg;
180327458df8SWei Liu op->type = X86_VAR_REG;
1804*77a2dba4SPaolo Bonzini op->regptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
180527458df8SWei Liu decode->rex.b, decode->operand_size);
180627458df8SWei Liu return;
180727458df8SWei Liu }
180827458df8SWei Liu
180927458df8SWei Liu switch (decode->addressing_size) {
181027458df8SWei Liu case 2:
181127458df8SWei Liu calc_modrm_operand16(env, decode, op);
181227458df8SWei Liu break;
181327458df8SWei Liu case 4:
181427458df8SWei Liu calc_modrm_operand32(env, decode, op);
181527458df8SWei Liu break;
181627458df8SWei Liu case 8:
181727458df8SWei Liu calc_modrm_operand64(env, decode, op);
181827458df8SWei Liu break;
181927458df8SWei Liu default:
182027458df8SWei Liu VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
182127458df8SWei Liu break;
182227458df8SWei Liu }
182327458df8SWei Liu }
182427458df8SWei Liu
decode_prefix(CPUX86State * env,struct x86_decode * decode)182527458df8SWei Liu static void decode_prefix(CPUX86State *env, struct x86_decode *decode)
182627458df8SWei Liu {
182727458df8SWei Liu while (1) {
182827458df8SWei Liu /*
182927458df8SWei Liu * REX prefix must come after legacy prefixes.
183027458df8SWei Liu * REX before legacy is ignored.
183127458df8SWei Liu * Clear rex to simulate this.
183227458df8SWei Liu */
183327458df8SWei Liu uint8_t byte = decode_byte(env, decode);
183427458df8SWei Liu switch (byte) {
183527458df8SWei Liu case PREFIX_LOCK:
183627458df8SWei Liu decode->lock = byte;
183727458df8SWei Liu decode->rex.rex = 0;
183827458df8SWei Liu break;
183927458df8SWei Liu case PREFIX_REPN:
184027458df8SWei Liu case PREFIX_REP:
184127458df8SWei Liu decode->rep = byte;
184227458df8SWei Liu decode->rex.rex = 0;
184327458df8SWei Liu break;
184427458df8SWei Liu case PREFIX_CS_SEG_OVERRIDE:
184527458df8SWei Liu case PREFIX_SS_SEG_OVERRIDE:
184627458df8SWei Liu case PREFIX_DS_SEG_OVERRIDE:
184727458df8SWei Liu case PREFIX_ES_SEG_OVERRIDE:
184827458df8SWei Liu case PREFIX_FS_SEG_OVERRIDE:
184927458df8SWei Liu case PREFIX_GS_SEG_OVERRIDE:
185027458df8SWei Liu decode->segment_override = byte;
185127458df8SWei Liu decode->rex.rex = 0;
185227458df8SWei Liu break;
185327458df8SWei Liu case PREFIX_OP_SIZE_OVERRIDE:
185427458df8SWei Liu decode->op_size_override = byte;
185527458df8SWei Liu decode->rex.rex = 0;
185627458df8SWei Liu break;
185727458df8SWei Liu case PREFIX_ADDR_SIZE_OVERRIDE:
185827458df8SWei Liu decode->addr_size_override = byte;
185927458df8SWei Liu decode->rex.rex = 0;
186027458df8SWei Liu break;
186127458df8SWei Liu case PREFIX_REX ... (PREFIX_REX + 0xf):
186227458df8SWei Liu if (x86_is_long_mode(env_cpu(env))) {
186327458df8SWei Liu decode->rex.rex = byte;
186427458df8SWei Liu break;
186527458df8SWei Liu }
186627458df8SWei Liu /* fall through when not in long mode */
186727458df8SWei Liu default:
186827458df8SWei Liu decode->len--;
186927458df8SWei Liu return;
187027458df8SWei Liu }
187127458df8SWei Liu }
187227458df8SWei Liu }
187327458df8SWei Liu
set_addressing_size(CPUX86State * env,struct x86_decode * decode)187427458df8SWei Liu void set_addressing_size(CPUX86State *env, struct x86_decode *decode)
187527458df8SWei Liu {
187627458df8SWei Liu decode->addressing_size = -1;
187727458df8SWei Liu if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
187827458df8SWei Liu if (decode->addr_size_override) {
187927458df8SWei Liu decode->addressing_size = 4;
188027458df8SWei Liu } else {
188127458df8SWei Liu decode->addressing_size = 2;
188227458df8SWei Liu }
188327458df8SWei Liu } else if (!x86_is_long_mode(env_cpu(env))) {
188427458df8SWei Liu /* protected */
188527458df8SWei Liu x86_segment_descriptor cs;
188627458df8SWei Liu emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
188727458df8SWei Liu /* check db */
188827458df8SWei Liu if (cs.db) {
188927458df8SWei Liu if (decode->addr_size_override) {
189027458df8SWei Liu decode->addressing_size = 2;
189127458df8SWei Liu } else {
189227458df8SWei Liu decode->addressing_size = 4;
189327458df8SWei Liu }
189427458df8SWei Liu } else {
189527458df8SWei Liu if (decode->addr_size_override) {
189627458df8SWei Liu decode->addressing_size = 4;
189727458df8SWei Liu } else {
189827458df8SWei Liu decode->addressing_size = 2;
189927458df8SWei Liu }
190027458df8SWei Liu }
190127458df8SWei Liu } else {
190227458df8SWei Liu /* long */
190327458df8SWei Liu if (decode->addr_size_override) {
190427458df8SWei Liu decode->addressing_size = 4;
190527458df8SWei Liu } else {
190627458df8SWei Liu decode->addressing_size = 8;
190727458df8SWei Liu }
190827458df8SWei Liu }
190927458df8SWei Liu }
191027458df8SWei Liu
set_operand_size(CPUX86State * env,struct x86_decode * decode)191127458df8SWei Liu void set_operand_size(CPUX86State *env, struct x86_decode *decode)
191227458df8SWei Liu {
191327458df8SWei Liu decode->operand_size = -1;
191427458df8SWei Liu if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
191527458df8SWei Liu if (decode->op_size_override) {
191627458df8SWei Liu decode->operand_size = 4;
191727458df8SWei Liu } else {
191827458df8SWei Liu decode->operand_size = 2;
191927458df8SWei Liu }
192027458df8SWei Liu } else if (!x86_is_long_mode(env_cpu(env))) {
192127458df8SWei Liu /* protected */
192227458df8SWei Liu x86_segment_descriptor cs;
192327458df8SWei Liu emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
192427458df8SWei Liu /* check db */
192527458df8SWei Liu if (cs.db) {
192627458df8SWei Liu if (decode->op_size_override) {
192727458df8SWei Liu decode->operand_size = 2;
192827458df8SWei Liu } else{
192927458df8SWei Liu decode->operand_size = 4;
193027458df8SWei Liu }
193127458df8SWei Liu } else {
193227458df8SWei Liu if (decode->op_size_override) {
193327458df8SWei Liu decode->operand_size = 4;
193427458df8SWei Liu } else {
193527458df8SWei Liu decode->operand_size = 2;
193627458df8SWei Liu }
193727458df8SWei Liu }
193827458df8SWei Liu } else {
193927458df8SWei Liu /* long */
194027458df8SWei Liu if (decode->op_size_override) {
194127458df8SWei Liu decode->operand_size = 2;
194227458df8SWei Liu } else {
194327458df8SWei Liu decode->operand_size = 4;
194427458df8SWei Liu }
194527458df8SWei Liu
194627458df8SWei Liu if (decode->rex.w) {
194727458df8SWei Liu decode->operand_size = 8;
194827458df8SWei Liu }
194927458df8SWei Liu }
195027458df8SWei Liu }
195127458df8SWei Liu
decode_sib(CPUX86State * env,struct x86_decode * decode)195227458df8SWei Liu static void decode_sib(CPUX86State *env, struct x86_decode *decode)
195327458df8SWei Liu {
195427458df8SWei Liu if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
195527458df8SWei Liu (decode->addressing_size != 2)) {
195627458df8SWei Liu decode->sib.sib = decode_byte(env, decode);
195727458df8SWei Liu decode->sib_present = true;
195827458df8SWei Liu }
195927458df8SWei Liu }
196027458df8SWei Liu
196127458df8SWei Liu /* 16 bit modrm */
196227458df8SWei Liu int disp16_tbl[4][8] = {
196327458df8SWei Liu {0, 0, 0, 0, 0, 0, 2, 0},
196427458df8SWei Liu {1, 1, 1, 1, 1, 1, 1, 1},
196527458df8SWei Liu {2, 2, 2, 2, 2, 2, 2, 2},
196627458df8SWei Liu {0, 0, 0, 0, 0, 0, 0, 0}
196727458df8SWei Liu };
196827458df8SWei Liu
196927458df8SWei Liu /* 32/64-bit modrm */
197027458df8SWei Liu int disp32_tbl[4][8] = {
197127458df8SWei Liu {0, 0, 0, 0, -1, 4, 0, 0},
197227458df8SWei Liu {1, 1, 1, 1, 1, 1, 1, 1},
197327458df8SWei Liu {4, 4, 4, 4, 4, 4, 4, 4},
197427458df8SWei Liu {0, 0, 0, 0, 0, 0, 0, 0}
197527458df8SWei Liu };
197627458df8SWei Liu
decode_displacement(CPUX86State * env,struct x86_decode * decode)197727458df8SWei Liu static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode)
197827458df8SWei Liu {
197927458df8SWei Liu int addressing_size = decode->addressing_size;
198027458df8SWei Liu int mod = decode->modrm.mod;
198127458df8SWei Liu int rm = decode->modrm.rm;
198227458df8SWei Liu
198327458df8SWei Liu decode->displacement_size = 0;
198427458df8SWei Liu switch (addressing_size) {
198527458df8SWei Liu case 2:
198627458df8SWei Liu decode->displacement_size = disp16_tbl[mod][rm];
198727458df8SWei Liu if (decode->displacement_size) {
198827458df8SWei Liu decode->displacement = (uint16_t)decode_bytes(env, decode,
198927458df8SWei Liu decode->displacement_size);
199027458df8SWei Liu }
199127458df8SWei Liu break;
199227458df8SWei Liu case 4:
199327458df8SWei Liu case 8:
199427458df8SWei Liu if (-1 == disp32_tbl[mod][rm]) {
199527458df8SWei Liu if (5 == decode->sib.base) {
199627458df8SWei Liu decode->displacement_size = 4;
199727458df8SWei Liu }
199827458df8SWei Liu } else {
199927458df8SWei Liu decode->displacement_size = disp32_tbl[mod][rm];
200027458df8SWei Liu }
200127458df8SWei Liu
200227458df8SWei Liu if (decode->displacement_size) {
200327458df8SWei Liu decode->displacement = (uint32_t)decode_bytes(env, decode,
200427458df8SWei Liu decode->displacement_size);
200527458df8SWei Liu }
200627458df8SWei Liu break;
200727458df8SWei Liu }
200827458df8SWei Liu }
200927458df8SWei Liu
decode_modrm(CPUX86State * env,struct x86_decode * decode)201027458df8SWei Liu static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode)
201127458df8SWei Liu {
201227458df8SWei Liu decode->modrm.modrm = decode_byte(env, decode);
201327458df8SWei Liu decode->is_modrm = true;
201427458df8SWei Liu
201527458df8SWei Liu decode_sib(env, decode);
201627458df8SWei Liu decode_displacement(env, decode);
201727458df8SWei Liu }
201827458df8SWei Liu
decode_opcode_general(CPUX86State * env,struct x86_decode * decode,uint8_t opcode,struct decode_tbl * inst_decoder)201927458df8SWei Liu static inline void decode_opcode_general(CPUX86State *env,
202027458df8SWei Liu struct x86_decode *decode,
202127458df8SWei Liu uint8_t opcode,
202227458df8SWei Liu struct decode_tbl *inst_decoder)
202327458df8SWei Liu {
202427458df8SWei Liu decode->cmd = inst_decoder->cmd;
202527458df8SWei Liu if (inst_decoder->operand_size) {
202627458df8SWei Liu decode->operand_size = inst_decoder->operand_size;
202727458df8SWei Liu }
202827458df8SWei Liu
202927458df8SWei Liu if (inst_decoder->is_modrm) {
203027458df8SWei Liu decode_modrm(env, decode);
203127458df8SWei Liu }
203227458df8SWei Liu if (inst_decoder->decode_op1) {
203327458df8SWei Liu inst_decoder->decode_op1(env, decode, &decode->op[0]);
203427458df8SWei Liu }
203527458df8SWei Liu if (inst_decoder->decode_op2) {
203627458df8SWei Liu inst_decoder->decode_op2(env, decode, &decode->op[1]);
203727458df8SWei Liu }
203827458df8SWei Liu if (inst_decoder->decode_op3) {
203927458df8SWei Liu inst_decoder->decode_op3(env, decode, &decode->op[2]);
204027458df8SWei Liu }
204127458df8SWei Liu if (inst_decoder->decode_op4) {
204227458df8SWei Liu inst_decoder->decode_op4(env, decode, &decode->op[3]);
204327458df8SWei Liu }
204427458df8SWei Liu if (inst_decoder->decode_postfix) {
204527458df8SWei Liu inst_decoder->decode_postfix(env, decode);
204627458df8SWei Liu }
204727458df8SWei Liu }
204827458df8SWei Liu
decode_opcode_1(CPUX86State * env,struct x86_decode * decode,uint8_t opcode)204927458df8SWei Liu static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode,
205027458df8SWei Liu uint8_t opcode)
205127458df8SWei Liu {
205227458df8SWei Liu struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
205327458df8SWei Liu decode_opcode_general(env, decode, opcode, inst_decoder);
205427458df8SWei Liu }
205527458df8SWei Liu
205627458df8SWei Liu
decode_opcode_2(CPUX86State * env,struct x86_decode * decode,uint8_t opcode)205727458df8SWei Liu static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode,
205827458df8SWei Liu uint8_t opcode)
205927458df8SWei Liu {
206027458df8SWei Liu struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
206127458df8SWei Liu decode_opcode_general(env, decode, opcode, inst_decoder);
206227458df8SWei Liu }
206327458df8SWei Liu
decode_opcodes(CPUX86State * env,struct x86_decode * decode)206427458df8SWei Liu static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
206527458df8SWei Liu {
206627458df8SWei Liu uint8_t opcode;
206727458df8SWei Liu
206827458df8SWei Liu opcode = decode_byte(env, decode);
206927458df8SWei Liu decode->opcode[decode->opcode_len++] = opcode;
207027458df8SWei Liu if (opcode != OPCODE_ESCAPE) {
207127458df8SWei Liu decode_opcode_1(env, decode, opcode);
207227458df8SWei Liu } else {
207327458df8SWei Liu opcode = decode_byte(env, decode);
207427458df8SWei Liu decode->opcode[decode->opcode_len++] = opcode;
207527458df8SWei Liu decode_opcode_2(env, decode, opcode);
207627458df8SWei Liu }
207727458df8SWei Liu }
207827458df8SWei Liu
decode_instruction(CPUX86State * env,struct x86_decode * decode)207927458df8SWei Liu uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
208027458df8SWei Liu {
208127458df8SWei Liu memset(decode, 0, sizeof(*decode));
208227458df8SWei Liu decode_prefix(env, decode);
208327458df8SWei Liu set_addressing_size(env, decode);
208427458df8SWei Liu set_operand_size(env, decode);
208527458df8SWei Liu
208627458df8SWei Liu decode_opcodes(env, decode);
208727458df8SWei Liu
208827458df8SWei Liu return decode->len;
208927458df8SWei Liu }
209027458df8SWei Liu
init_decoder(void)209127458df8SWei Liu void init_decoder(void)
209227458df8SWei Liu {
209327458df8SWei Liu int i;
209427458df8SWei Liu
209527458df8SWei Liu for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) {
209627458df8SWei Liu memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst));
209727458df8SWei Liu }
209827458df8SWei Liu for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
209927458df8SWei Liu memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst));
210027458df8SWei Liu }
210127458df8SWei Liu for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
210227458df8SWei Liu memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87));
210327458df8SWei Liu
210427458df8SWei Liu }
210527458df8SWei Liu for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
210627458df8SWei Liu _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
210727458df8SWei Liu }
210827458df8SWei Liu for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) {
210927458df8SWei Liu _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i];
211027458df8SWei Liu }
211127458df8SWei Liu for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) {
211227458df8SWei Liu int index = ((_x87_inst[i].opcode & 0xf) << 4) |
211327458df8SWei Liu ((_x87_inst[i].modrm_mod & 1) << 3) |
211427458df8SWei Liu _x87_inst[i].modrm_reg;
211527458df8SWei Liu _decode_tbl3[index] = _x87_inst[i];
211627458df8SWei Liu }
211727458df8SWei Liu }
211827458df8SWei Liu
211927458df8SWei Liu
decode_cmd_to_string(enum x86_decode_cmd cmd)212027458df8SWei Liu const char *decode_cmd_to_string(enum x86_decode_cmd cmd)
212127458df8SWei Liu {
212227458df8SWei Liu static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG",
212327458df8SWei Liu "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT",
212427458df8SWei Liu "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD",
212527458df8SWei Liu "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST",
212627458df8SWei Liu "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR",
212727458df8SWei Liu "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG",
212827458df8SWei Liu "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN",
212927458df8SWei Liu "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW",
213027458df8SWei Liu "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR",
213127458df8SWei Liu "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR",
213227458df8SWei Liu "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL",
213327458df8SWei Liu "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS",
213427458df8SWei Liu "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT",
213527458df8SWei Liu "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA",
213627458df8SWei Liu "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT",
213727458df8SWei Liu "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES",
213827458df8SWei Liu "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT",
213927458df8SWei Liu "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW",
214027458df8SWei Liu "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV",
214127458df8SWei Liu "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE",
214227458df8SWei Liu "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW",
214327458df8SWei Liu "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"};
214427458df8SWei Liu return cmds[cmd];
214527458df8SWei Liu }
214627458df8SWei Liu
decode_linear_addr(CPUX86State * env,struct x86_decode * decode,target_ulong addr,X86Seg seg)214727458df8SWei Liu target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
214827458df8SWei Liu target_ulong addr, X86Seg seg)
214927458df8SWei Liu {
215027458df8SWei Liu switch (decode->segment_override) {
215127458df8SWei Liu case PREFIX_CS_SEG_OVERRIDE:
215227458df8SWei Liu seg = R_CS;
215327458df8SWei Liu break;
215427458df8SWei Liu case PREFIX_SS_SEG_OVERRIDE:
215527458df8SWei Liu seg = R_SS;
215627458df8SWei Liu break;
215727458df8SWei Liu case PREFIX_DS_SEG_OVERRIDE:
215827458df8SWei Liu seg = R_DS;
215927458df8SWei Liu break;
216027458df8SWei Liu case PREFIX_ES_SEG_OVERRIDE:
216127458df8SWei Liu seg = R_ES;
216227458df8SWei Liu break;
216327458df8SWei Liu case PREFIX_FS_SEG_OVERRIDE:
216427458df8SWei Liu seg = R_FS;
216527458df8SWei Liu break;
216627458df8SWei Liu case PREFIX_GS_SEG_OVERRIDE:
216727458df8SWei Liu seg = R_GS;
216827458df8SWei Liu break;
216927458df8SWei Liu default:
217027458df8SWei Liu break;
217127458df8SWei Liu }
217227458df8SWei Liu return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg);
217327458df8SWei Liu }
2174