169e0a03cSPaolo Bonzini /*
269e0a03cSPaolo Bonzini * Copyright (C) 2016 Veertu Inc,
369e0a03cSPaolo Bonzini * Copyright (C) 2017 Google Inc,
469e0a03cSPaolo Bonzini *
569e0a03cSPaolo Bonzini * This program is free software; you can redistribute it and/or
669e0a03cSPaolo Bonzini * modify it under the terms of the GNU Lesser General Public
769e0a03cSPaolo Bonzini * License as published by the Free Software Foundation; either
88af82b8eSChetan Pant * version 2.1 of the License, or (at your option) any later version.
969e0a03cSPaolo Bonzini *
1069e0a03cSPaolo Bonzini * This program is distributed in the hope that it will be useful,
1169e0a03cSPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of
1269e0a03cSPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1369e0a03cSPaolo Bonzini * Lesser General Public License for more details.
1469e0a03cSPaolo Bonzini *
1569e0a03cSPaolo Bonzini * You should have received a copy of the GNU Lesser General Public
1669e0a03cSPaolo Bonzini * License along with this program; if not, see <http://www.gnu.org/licenses/>.
1769e0a03cSPaolo Bonzini */
1869e0a03cSPaolo Bonzini
1969e0a03cSPaolo Bonzini #include "qemu/osdep.h"
2069e0a03cSPaolo Bonzini
21895f9fdfSPaolo Bonzini #include "panic.h"
2269e0a03cSPaolo Bonzini #include "x86_decode.h"
2369e0a03cSPaolo Bonzini #include "vmx.h"
2469e0a03cSPaolo Bonzini #include "x86_mmu.h"
2569e0a03cSPaolo Bonzini #include "x86_descr.h"
2669e0a03cSPaolo Bonzini
2769e0a03cSPaolo Bonzini #define OPCODE_ESCAPE 0xf
2869e0a03cSPaolo Bonzini
decode_invalid(CPUX86State * env,struct x86_decode * decode)2969e0a03cSPaolo Bonzini static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
3069e0a03cSPaolo Bonzini {
312d5f696cSRoman Bolshakov printf("%llx: failed to decode instruction ", env->eip);
3269e0a03cSPaolo Bonzini for (int i = 0; i < decode->opcode_len; i++) {
3369e0a03cSPaolo Bonzini printf("%x ", decode->opcode[i]);
3469e0a03cSPaolo Bonzini }
3569e0a03cSPaolo Bonzini printf("\n");
3669e0a03cSPaolo Bonzini VM_PANIC("decoder failed\n");
3769e0a03cSPaolo Bonzini }
3869e0a03cSPaolo Bonzini
sign(uint64_t val,int size)3969e0a03cSPaolo Bonzini uint64_t sign(uint64_t val, int size)
4069e0a03cSPaolo Bonzini {
4169e0a03cSPaolo Bonzini switch (size) {
4269e0a03cSPaolo Bonzini case 1:
4369e0a03cSPaolo Bonzini val = (int8_t)val;
4469e0a03cSPaolo Bonzini break;
4569e0a03cSPaolo Bonzini case 2:
4669e0a03cSPaolo Bonzini val = (int16_t)val;
4769e0a03cSPaolo Bonzini break;
4869e0a03cSPaolo Bonzini case 4:
4969e0a03cSPaolo Bonzini val = (int32_t)val;
5069e0a03cSPaolo Bonzini break;
5169e0a03cSPaolo Bonzini case 8:
5269e0a03cSPaolo Bonzini val = (int64_t)val;
5369e0a03cSPaolo Bonzini break;
5469e0a03cSPaolo Bonzini default:
5569e0a03cSPaolo Bonzini VM_PANIC_EX("%s invalid size %d\n", __func__, size);
5669e0a03cSPaolo Bonzini break;
5769e0a03cSPaolo Bonzini }
5869e0a03cSPaolo Bonzini return val;
5969e0a03cSPaolo Bonzini }
6069e0a03cSPaolo Bonzini
decode_bytes(CPUX86State * env,struct x86_decode * decode,int size)6169e0a03cSPaolo Bonzini static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
6269e0a03cSPaolo Bonzini int size)
6369e0a03cSPaolo Bonzini {
64ff2de166SPaolo Bonzini target_ulong val = 0;
6569e0a03cSPaolo Bonzini
6669e0a03cSPaolo Bonzini switch (size) {
6769e0a03cSPaolo Bonzini case 1:
6869e0a03cSPaolo Bonzini case 2:
6969e0a03cSPaolo Bonzini case 4:
7069e0a03cSPaolo Bonzini case 8:
7169e0a03cSPaolo Bonzini break;
7269e0a03cSPaolo Bonzini default:
7369e0a03cSPaolo Bonzini VM_PANIC_EX("%s invalid size %d\n", __func__, size);
7469e0a03cSPaolo Bonzini break;
7569e0a03cSPaolo Bonzini }
765d32173fSRoman Bolshakov target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len;
7729a0af61SRichard Henderson vmx_read_mem(env_cpu(env), &val, va, size);
7869e0a03cSPaolo Bonzini decode->len += size;
7969e0a03cSPaolo Bonzini
8069e0a03cSPaolo Bonzini return val;
8169e0a03cSPaolo Bonzini }
8269e0a03cSPaolo Bonzini
decode_byte(CPUX86State * env,struct x86_decode * decode)8369e0a03cSPaolo Bonzini static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode)
8469e0a03cSPaolo Bonzini {
8569e0a03cSPaolo Bonzini return (uint8_t)decode_bytes(env, decode, 1);
8669e0a03cSPaolo Bonzini }
8769e0a03cSPaolo Bonzini
decode_word(CPUX86State * env,struct x86_decode * decode)8869e0a03cSPaolo Bonzini static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode)
8969e0a03cSPaolo Bonzini {
9069e0a03cSPaolo Bonzini return (uint16_t)decode_bytes(env, decode, 2);
9169e0a03cSPaolo Bonzini }
9269e0a03cSPaolo Bonzini
decode_dword(CPUX86State * env,struct x86_decode * decode)9369e0a03cSPaolo Bonzini static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode)
9469e0a03cSPaolo Bonzini {
9569e0a03cSPaolo Bonzini return (uint32_t)decode_bytes(env, decode, 4);
9669e0a03cSPaolo Bonzini }
9769e0a03cSPaolo Bonzini
decode_qword(CPUX86State * env,struct x86_decode * decode)9869e0a03cSPaolo Bonzini static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode)
9969e0a03cSPaolo Bonzini {
10069e0a03cSPaolo Bonzini return decode_bytes(env, decode, 8);
10169e0a03cSPaolo Bonzini }
10269e0a03cSPaolo Bonzini
decode_modrm_rm(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)10369e0a03cSPaolo Bonzini static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode,
10469e0a03cSPaolo Bonzini struct x86_decode_op *op)
10569e0a03cSPaolo Bonzini {
10669e0a03cSPaolo Bonzini op->type = X86_VAR_RM;
10769e0a03cSPaolo Bonzini }
10869e0a03cSPaolo Bonzini
decode_modrm_reg(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)10969e0a03cSPaolo Bonzini static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode,
11069e0a03cSPaolo Bonzini struct x86_decode_op *op)
11169e0a03cSPaolo Bonzini {
11269e0a03cSPaolo Bonzini op->type = X86_VAR_REG;
11369e0a03cSPaolo Bonzini op->reg = decode->modrm.reg;
114b4e1af89SRoman Bolshakov op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
115b4e1af89SRoman Bolshakov decode->operand_size);
11669e0a03cSPaolo Bonzini }
11769e0a03cSPaolo Bonzini
decode_rax(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)11869e0a03cSPaolo Bonzini static void decode_rax(CPUX86State *env, struct x86_decode *decode,
11969e0a03cSPaolo Bonzini struct x86_decode_op *op)
12069e0a03cSPaolo Bonzini {
12169e0a03cSPaolo Bonzini op->type = X86_VAR_REG;
1226701d81dSPaolo Bonzini op->reg = R_EAX;
1238c3b0e9eSCameron Esfahani /* Since reg is always AX, REX prefix has no impact. */
1248c3b0e9eSCameron Esfahani op->ptr = get_reg_ref(env, op->reg, false, 0,
125b4e1af89SRoman Bolshakov decode->operand_size);
12669e0a03cSPaolo Bonzini }
12769e0a03cSPaolo Bonzini
decode_immediate(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * var,int size)12869e0a03cSPaolo Bonzini static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode,
12969e0a03cSPaolo Bonzini struct x86_decode_op *var, int size)
13069e0a03cSPaolo Bonzini {
13169e0a03cSPaolo Bonzini var->type = X86_VAR_IMMEDIATE;
13269e0a03cSPaolo Bonzini var->size = size;
13369e0a03cSPaolo Bonzini switch (size) {
13469e0a03cSPaolo Bonzini case 1:
13569e0a03cSPaolo Bonzini var->val = decode_byte(env, decode);
13669e0a03cSPaolo Bonzini break;
13769e0a03cSPaolo Bonzini case 2:
13869e0a03cSPaolo Bonzini var->val = decode_word(env, decode);
13969e0a03cSPaolo Bonzini break;
14069e0a03cSPaolo Bonzini case 4:
14169e0a03cSPaolo Bonzini var->val = decode_dword(env, decode);
14269e0a03cSPaolo Bonzini break;
14369e0a03cSPaolo Bonzini case 8:
14469e0a03cSPaolo Bonzini var->val = decode_qword(env, decode);
14569e0a03cSPaolo Bonzini break;
14669e0a03cSPaolo Bonzini default:
14769e0a03cSPaolo Bonzini VM_PANIC_EX("bad size %d\n", size);
14869e0a03cSPaolo Bonzini }
14969e0a03cSPaolo Bonzini }
15069e0a03cSPaolo Bonzini
decode_imm8(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)15169e0a03cSPaolo Bonzini static void decode_imm8(CPUX86State *env, struct x86_decode *decode,
15269e0a03cSPaolo Bonzini struct x86_decode_op *op)
15369e0a03cSPaolo Bonzini {
15469e0a03cSPaolo Bonzini decode_immediate(env, decode, op, 1);
15569e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
15669e0a03cSPaolo Bonzini }
15769e0a03cSPaolo Bonzini
decode_imm8_signed(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)15869e0a03cSPaolo Bonzini static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode,
15969e0a03cSPaolo Bonzini struct x86_decode_op *op)
16069e0a03cSPaolo Bonzini {
16169e0a03cSPaolo Bonzini decode_immediate(env, decode, op, 1);
16269e0a03cSPaolo Bonzini op->val = sign(op->val, 1);
16369e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
16469e0a03cSPaolo Bonzini }
16569e0a03cSPaolo Bonzini
decode_imm16(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)16669e0a03cSPaolo Bonzini static void decode_imm16(CPUX86State *env, struct x86_decode *decode,
16769e0a03cSPaolo Bonzini struct x86_decode_op *op)
16869e0a03cSPaolo Bonzini {
16969e0a03cSPaolo Bonzini decode_immediate(env, decode, op, 2);
17069e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
17169e0a03cSPaolo Bonzini }
17269e0a03cSPaolo Bonzini
17369e0a03cSPaolo Bonzini
decode_imm(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)17469e0a03cSPaolo Bonzini static void decode_imm(CPUX86State *env, struct x86_decode *decode,
17569e0a03cSPaolo Bonzini struct x86_decode_op *op)
17669e0a03cSPaolo Bonzini {
17769e0a03cSPaolo Bonzini if (8 == decode->operand_size) {
17869e0a03cSPaolo Bonzini decode_immediate(env, decode, op, 4);
17969e0a03cSPaolo Bonzini op->val = sign(op->val, decode->operand_size);
18069e0a03cSPaolo Bonzini } else {
18169e0a03cSPaolo Bonzini decode_immediate(env, decode, op, decode->operand_size);
18269e0a03cSPaolo Bonzini }
18369e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
18469e0a03cSPaolo Bonzini }
18569e0a03cSPaolo Bonzini
decode_imm_signed(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)18669e0a03cSPaolo Bonzini static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode,
18769e0a03cSPaolo Bonzini struct x86_decode_op *op)
18869e0a03cSPaolo Bonzini {
18969e0a03cSPaolo Bonzini decode_immediate(env, decode, op, decode->operand_size);
19069e0a03cSPaolo Bonzini op->val = sign(op->val, decode->operand_size);
19169e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
19269e0a03cSPaolo Bonzini }
19369e0a03cSPaolo Bonzini
decode_imm_1(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)19469e0a03cSPaolo Bonzini static void decode_imm_1(CPUX86State *env, struct x86_decode *decode,
19569e0a03cSPaolo Bonzini struct x86_decode_op *op)
19669e0a03cSPaolo Bonzini {
19769e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
19869e0a03cSPaolo Bonzini op->val = 1;
19969e0a03cSPaolo Bonzini }
20069e0a03cSPaolo Bonzini
decode_imm_0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)20169e0a03cSPaolo Bonzini static void decode_imm_0(CPUX86State *env, struct x86_decode *decode,
20269e0a03cSPaolo Bonzini struct x86_decode_op *op)
20369e0a03cSPaolo Bonzini {
20469e0a03cSPaolo Bonzini op->type = X86_VAR_IMMEDIATE;
20569e0a03cSPaolo Bonzini op->val = 0;
20669e0a03cSPaolo Bonzini }
20769e0a03cSPaolo Bonzini
20869e0a03cSPaolo Bonzini
decode_pushseg(CPUX86State * env,struct x86_decode * decode)20969e0a03cSPaolo Bonzini static void decode_pushseg(CPUX86State *env, struct x86_decode *decode)
21069e0a03cSPaolo Bonzini {
21169e0a03cSPaolo Bonzini uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
21269e0a03cSPaolo Bonzini
21369e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
21469e0a03cSPaolo Bonzini switch (op) {
21569e0a03cSPaolo Bonzini case 0xe:
2166701d81dSPaolo Bonzini decode->op[0].reg = R_CS;
21769e0a03cSPaolo Bonzini break;
21869e0a03cSPaolo Bonzini case 0x16:
2196701d81dSPaolo Bonzini decode->op[0].reg = R_SS;
22069e0a03cSPaolo Bonzini break;
22169e0a03cSPaolo Bonzini case 0x1e:
2226701d81dSPaolo Bonzini decode->op[0].reg = R_DS;
22369e0a03cSPaolo Bonzini break;
22469e0a03cSPaolo Bonzini case 0x06:
2256701d81dSPaolo Bonzini decode->op[0].reg = R_ES;
22669e0a03cSPaolo Bonzini break;
22769e0a03cSPaolo Bonzini case 0xa0:
2286701d81dSPaolo Bonzini decode->op[0].reg = R_FS;
22969e0a03cSPaolo Bonzini break;
23069e0a03cSPaolo Bonzini case 0xa8:
2316701d81dSPaolo Bonzini decode->op[0].reg = R_GS;
23269e0a03cSPaolo Bonzini break;
23369e0a03cSPaolo Bonzini }
23469e0a03cSPaolo Bonzini }
23569e0a03cSPaolo Bonzini
decode_popseg(CPUX86State * env,struct x86_decode * decode)23669e0a03cSPaolo Bonzini static void decode_popseg(CPUX86State *env, struct x86_decode *decode)
23769e0a03cSPaolo Bonzini {
23869e0a03cSPaolo Bonzini uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
23969e0a03cSPaolo Bonzini
24069e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
24169e0a03cSPaolo Bonzini switch (op) {
24269e0a03cSPaolo Bonzini case 0xf:
2436701d81dSPaolo Bonzini decode->op[0].reg = R_CS;
24469e0a03cSPaolo Bonzini break;
24569e0a03cSPaolo Bonzini case 0x17:
2466701d81dSPaolo Bonzini decode->op[0].reg = R_SS;
24769e0a03cSPaolo Bonzini break;
24869e0a03cSPaolo Bonzini case 0x1f:
2496701d81dSPaolo Bonzini decode->op[0].reg = R_DS;
25069e0a03cSPaolo Bonzini break;
25169e0a03cSPaolo Bonzini case 0x07:
2526701d81dSPaolo Bonzini decode->op[0].reg = R_ES;
25369e0a03cSPaolo Bonzini break;
25469e0a03cSPaolo Bonzini case 0xa1:
2556701d81dSPaolo Bonzini decode->op[0].reg = R_FS;
25669e0a03cSPaolo Bonzini break;
25769e0a03cSPaolo Bonzini case 0xa9:
2586701d81dSPaolo Bonzini decode->op[0].reg = R_GS;
25969e0a03cSPaolo Bonzini break;
26069e0a03cSPaolo Bonzini }
26169e0a03cSPaolo Bonzini }
26269e0a03cSPaolo Bonzini
decode_incgroup(CPUX86State * env,struct x86_decode * decode)26369e0a03cSPaolo Bonzini static void decode_incgroup(CPUX86State *env, struct x86_decode *decode)
26469e0a03cSPaolo Bonzini {
26569e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
26669e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0x40;
267b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
268b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
26969e0a03cSPaolo Bonzini }
27069e0a03cSPaolo Bonzini
decode_decgroup(CPUX86State * env,struct x86_decode * decode)27169e0a03cSPaolo Bonzini static void decode_decgroup(CPUX86State *env, struct x86_decode *decode)
27269e0a03cSPaolo Bonzini {
27369e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
27469e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0x48;
275b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
276b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
27769e0a03cSPaolo Bonzini }
27869e0a03cSPaolo Bonzini
decode_incgroup2(CPUX86State * env,struct x86_decode * decode)27969e0a03cSPaolo Bonzini static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode)
28069e0a03cSPaolo Bonzini {
28169e0a03cSPaolo Bonzini if (!decode->modrm.reg) {
28269e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_INC;
28369e0a03cSPaolo Bonzini } else if (1 == decode->modrm.reg) {
28469e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_DEC;
28569e0a03cSPaolo Bonzini }
28669e0a03cSPaolo Bonzini }
28769e0a03cSPaolo Bonzini
decode_pushgroup(CPUX86State * env,struct x86_decode * decode)28869e0a03cSPaolo Bonzini static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode)
28969e0a03cSPaolo Bonzini {
29069e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
29169e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0x50;
292b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
293b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
29469e0a03cSPaolo Bonzini }
29569e0a03cSPaolo Bonzini
decode_popgroup(CPUX86State * env,struct x86_decode * decode)29669e0a03cSPaolo Bonzini static void decode_popgroup(CPUX86State *env, struct x86_decode *decode)
29769e0a03cSPaolo Bonzini {
29869e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
29969e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0x58;
300b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
301b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
30269e0a03cSPaolo Bonzini }
30369e0a03cSPaolo Bonzini
decode_jxx(CPUX86State * env,struct x86_decode * decode)30469e0a03cSPaolo Bonzini static void decode_jxx(CPUX86State *env, struct x86_decode *decode)
30569e0a03cSPaolo Bonzini {
30669e0a03cSPaolo Bonzini decode->displacement = decode_bytes(env, decode, decode->operand_size);
30769e0a03cSPaolo Bonzini decode->displacement_size = decode->operand_size;
30869e0a03cSPaolo Bonzini }
30969e0a03cSPaolo Bonzini
decode_farjmp(CPUX86State * env,struct x86_decode * decode)31069e0a03cSPaolo Bonzini static void decode_farjmp(CPUX86State *env, struct x86_decode *decode)
31169e0a03cSPaolo Bonzini {
31269e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_IMMEDIATE;
31369e0a03cSPaolo Bonzini decode->op[0].val = decode_bytes(env, decode, decode->operand_size);
31469e0a03cSPaolo Bonzini decode->displacement = decode_word(env, decode);
31569e0a03cSPaolo Bonzini }
31669e0a03cSPaolo Bonzini
decode_addgroup(CPUX86State * env,struct x86_decode * decode)31769e0a03cSPaolo Bonzini static void decode_addgroup(CPUX86State *env, struct x86_decode *decode)
31869e0a03cSPaolo Bonzini {
31969e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
32069e0a03cSPaolo Bonzini X86_DECODE_CMD_ADD,
32169e0a03cSPaolo Bonzini X86_DECODE_CMD_OR,
32269e0a03cSPaolo Bonzini X86_DECODE_CMD_ADC,
32369e0a03cSPaolo Bonzini X86_DECODE_CMD_SBB,
32469e0a03cSPaolo Bonzini X86_DECODE_CMD_AND,
32569e0a03cSPaolo Bonzini X86_DECODE_CMD_SUB,
32669e0a03cSPaolo Bonzini X86_DECODE_CMD_XOR,
32769e0a03cSPaolo Bonzini X86_DECODE_CMD_CMP
32869e0a03cSPaolo Bonzini };
32969e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
33069e0a03cSPaolo Bonzini }
33169e0a03cSPaolo Bonzini
decode_rotgroup(CPUX86State * env,struct x86_decode * decode)33269e0a03cSPaolo Bonzini static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode)
33369e0a03cSPaolo Bonzini {
33469e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
33569e0a03cSPaolo Bonzini X86_DECODE_CMD_ROL,
33669e0a03cSPaolo Bonzini X86_DECODE_CMD_ROR,
33769e0a03cSPaolo Bonzini X86_DECODE_CMD_RCL,
33869e0a03cSPaolo Bonzini X86_DECODE_CMD_RCR,
33969e0a03cSPaolo Bonzini X86_DECODE_CMD_SHL,
34069e0a03cSPaolo Bonzini X86_DECODE_CMD_SHR,
34169e0a03cSPaolo Bonzini X86_DECODE_CMD_SHL,
34269e0a03cSPaolo Bonzini X86_DECODE_CMD_SAR
34369e0a03cSPaolo Bonzini };
34469e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
34569e0a03cSPaolo Bonzini }
34669e0a03cSPaolo Bonzini
decode_f7group(CPUX86State * env,struct x86_decode * decode)34769e0a03cSPaolo Bonzini static void decode_f7group(CPUX86State *env, struct x86_decode *decode)
34869e0a03cSPaolo Bonzini {
34969e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
35069e0a03cSPaolo Bonzini X86_DECODE_CMD_TST,
35169e0a03cSPaolo Bonzini X86_DECODE_CMD_TST,
35269e0a03cSPaolo Bonzini X86_DECODE_CMD_NOT,
35369e0a03cSPaolo Bonzini X86_DECODE_CMD_NEG,
35469e0a03cSPaolo Bonzini X86_DECODE_CMD_MUL,
35569e0a03cSPaolo Bonzini X86_DECODE_CMD_IMUL_1,
35669e0a03cSPaolo Bonzini X86_DECODE_CMD_DIV,
35769e0a03cSPaolo Bonzini X86_DECODE_CMD_IDIV
35869e0a03cSPaolo Bonzini };
35969e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
36069e0a03cSPaolo Bonzini decode_modrm_rm(env, decode, &decode->op[0]);
36169e0a03cSPaolo Bonzini
36269e0a03cSPaolo Bonzini switch (decode->modrm.reg) {
36369e0a03cSPaolo Bonzini case 0:
36469e0a03cSPaolo Bonzini case 1:
36569e0a03cSPaolo Bonzini decode_imm(env, decode, &decode->op[1]);
36669e0a03cSPaolo Bonzini break;
36769e0a03cSPaolo Bonzini case 2:
36869e0a03cSPaolo Bonzini break;
36969e0a03cSPaolo Bonzini case 3:
37069e0a03cSPaolo Bonzini decode->op[1].type = X86_VAR_IMMEDIATE;
37169e0a03cSPaolo Bonzini decode->op[1].val = 0;
37269e0a03cSPaolo Bonzini break;
37369e0a03cSPaolo Bonzini default:
37469e0a03cSPaolo Bonzini break;
37569e0a03cSPaolo Bonzini }
37669e0a03cSPaolo Bonzini }
37769e0a03cSPaolo Bonzini
decode_xchgroup(CPUX86State * env,struct x86_decode * decode)37869e0a03cSPaolo Bonzini static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode)
37969e0a03cSPaolo Bonzini {
38069e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
38169e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0x90;
382b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
383b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
38469e0a03cSPaolo Bonzini }
38569e0a03cSPaolo Bonzini
decode_movgroup(CPUX86State * env,struct x86_decode * decode)38669e0a03cSPaolo Bonzini static void decode_movgroup(CPUX86State *env, struct x86_decode *decode)
38769e0a03cSPaolo Bonzini {
38869e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
38969e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0xb8;
390b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
391b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
39269e0a03cSPaolo Bonzini decode_immediate(env, decode, &decode->op[1], decode->operand_size);
39369e0a03cSPaolo Bonzini }
39469e0a03cSPaolo Bonzini
fetch_moffs(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)39569e0a03cSPaolo Bonzini static void fetch_moffs(CPUX86State *env, struct x86_decode *decode,
39669e0a03cSPaolo Bonzini struct x86_decode_op *op)
39769e0a03cSPaolo Bonzini {
39869e0a03cSPaolo Bonzini op->type = X86_VAR_OFFSET;
39969e0a03cSPaolo Bonzini op->ptr = decode_bytes(env, decode, decode->addressing_size);
40069e0a03cSPaolo Bonzini }
40169e0a03cSPaolo Bonzini
decode_movgroup8(CPUX86State * env,struct x86_decode * decode)40269e0a03cSPaolo Bonzini static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode)
40369e0a03cSPaolo Bonzini {
40469e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
40569e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[0] - 0xb0;
406b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
407b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
40869e0a03cSPaolo Bonzini decode_immediate(env, decode, &decode->op[1], decode->operand_size);
40969e0a03cSPaolo Bonzini }
41069e0a03cSPaolo Bonzini
decode_rcx(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)41169e0a03cSPaolo Bonzini static void decode_rcx(CPUX86State *env, struct x86_decode *decode,
41269e0a03cSPaolo Bonzini struct x86_decode_op *op)
41369e0a03cSPaolo Bonzini {
41469e0a03cSPaolo Bonzini op->type = X86_VAR_REG;
4156701d81dSPaolo Bonzini op->reg = R_ECX;
416b4e1af89SRoman Bolshakov op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b,
417b4e1af89SRoman Bolshakov decode->operand_size);
41869e0a03cSPaolo Bonzini }
41969e0a03cSPaolo Bonzini
42069e0a03cSPaolo Bonzini struct decode_tbl {
42169e0a03cSPaolo Bonzini uint8_t opcode;
42269e0a03cSPaolo Bonzini enum x86_decode_cmd cmd;
42369e0a03cSPaolo Bonzini uint8_t operand_size;
42469e0a03cSPaolo Bonzini bool is_modrm;
42569e0a03cSPaolo Bonzini void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
42669e0a03cSPaolo Bonzini struct x86_decode_op *op1);
42769e0a03cSPaolo Bonzini void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
42869e0a03cSPaolo Bonzini struct x86_decode_op *op2);
42969e0a03cSPaolo Bonzini void (*decode_op3)(CPUX86State *env, struct x86_decode *decode,
43069e0a03cSPaolo Bonzini struct x86_decode_op *op3);
43169e0a03cSPaolo Bonzini void (*decode_op4)(CPUX86State *env, struct x86_decode *decode,
43269e0a03cSPaolo Bonzini struct x86_decode_op *op4);
43369e0a03cSPaolo Bonzini void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
434ff2de166SPaolo Bonzini uint32_t flags_mask;
43569e0a03cSPaolo Bonzini };
43669e0a03cSPaolo Bonzini
43769e0a03cSPaolo Bonzini struct decode_x87_tbl {
43869e0a03cSPaolo Bonzini uint8_t opcode;
43969e0a03cSPaolo Bonzini uint8_t modrm_reg;
44069e0a03cSPaolo Bonzini uint8_t modrm_mod;
44169e0a03cSPaolo Bonzini enum x86_decode_cmd cmd;
44269e0a03cSPaolo Bonzini uint8_t operand_size;
44369e0a03cSPaolo Bonzini bool rev;
44469e0a03cSPaolo Bonzini bool pop;
44569e0a03cSPaolo Bonzini void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
44669e0a03cSPaolo Bonzini struct x86_decode_op *op1);
44769e0a03cSPaolo Bonzini void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
44869e0a03cSPaolo Bonzini struct x86_decode_op *op2);
44969e0a03cSPaolo Bonzini void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
450ff2de166SPaolo Bonzini uint32_t flags_mask;
45169e0a03cSPaolo Bonzini };
45269e0a03cSPaolo Bonzini
45369e0a03cSPaolo Bonzini struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
45469e0a03cSPaolo Bonzini decode_invalid};
45569e0a03cSPaolo Bonzini
45683ea23cdSRoman Bolshakov struct decode_tbl _decode_tbl1[256];
45783ea23cdSRoman Bolshakov struct decode_tbl _decode_tbl2[256];
45883ea23cdSRoman Bolshakov struct decode_x87_tbl _decode_tbl3[256];
45969e0a03cSPaolo Bonzini
decode_x87_ins(CPUX86State * env,struct x86_decode * decode)46069e0a03cSPaolo Bonzini static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode)
46169e0a03cSPaolo Bonzini {
46269e0a03cSPaolo Bonzini struct decode_x87_tbl *decoder;
46369e0a03cSPaolo Bonzini
46469e0a03cSPaolo Bonzini decode->is_fpu = true;
46569e0a03cSPaolo Bonzini int mode = decode->modrm.mod == 3 ? 1 : 0;
46669e0a03cSPaolo Bonzini int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) |
46769e0a03cSPaolo Bonzini decode->modrm.reg;
46869e0a03cSPaolo Bonzini
46969e0a03cSPaolo Bonzini decoder = &_decode_tbl3[index];
47069e0a03cSPaolo Bonzini
47169e0a03cSPaolo Bonzini decode->cmd = decoder->cmd;
47269e0a03cSPaolo Bonzini if (decoder->operand_size) {
47369e0a03cSPaolo Bonzini decode->operand_size = decoder->operand_size;
47469e0a03cSPaolo Bonzini }
47569e0a03cSPaolo Bonzini decode->flags_mask = decoder->flags_mask;
47669e0a03cSPaolo Bonzini decode->fpop_stack = decoder->pop;
47769e0a03cSPaolo Bonzini decode->frev = decoder->rev;
47869e0a03cSPaolo Bonzini
47969e0a03cSPaolo Bonzini if (decoder->decode_op1) {
48069e0a03cSPaolo Bonzini decoder->decode_op1(env, decode, &decode->op[0]);
48169e0a03cSPaolo Bonzini }
48269e0a03cSPaolo Bonzini if (decoder->decode_op2) {
48369e0a03cSPaolo Bonzini decoder->decode_op2(env, decode, &decode->op[1]);
48469e0a03cSPaolo Bonzini }
48569e0a03cSPaolo Bonzini if (decoder->decode_postfix) {
48669e0a03cSPaolo Bonzini decoder->decode_postfix(env, decode);
48769e0a03cSPaolo Bonzini }
48869e0a03cSPaolo Bonzini
48969e0a03cSPaolo Bonzini VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n",
49069e0a03cSPaolo Bonzini decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg,
49169e0a03cSPaolo Bonzini decoder->modrm_mod);
49269e0a03cSPaolo Bonzini }
49369e0a03cSPaolo Bonzini
decode_ffgroup(CPUX86State * env,struct x86_decode * decode)49469e0a03cSPaolo Bonzini static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode)
49569e0a03cSPaolo Bonzini {
49669e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
49769e0a03cSPaolo Bonzini X86_DECODE_CMD_INC,
49869e0a03cSPaolo Bonzini X86_DECODE_CMD_DEC,
49969e0a03cSPaolo Bonzini X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT,
50069e0a03cSPaolo Bonzini X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT,
50169e0a03cSPaolo Bonzini X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT,
50269e0a03cSPaolo Bonzini X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT,
50369e0a03cSPaolo Bonzini X86_DECODE_CMD_PUSH,
50469e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL,
50569e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL
50669e0a03cSPaolo Bonzini };
50769e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
50869e0a03cSPaolo Bonzini if (decode->modrm.reg > 2) {
50969e0a03cSPaolo Bonzini decode->flags_mask = 0;
51069e0a03cSPaolo Bonzini }
51169e0a03cSPaolo Bonzini }
51269e0a03cSPaolo Bonzini
decode_sldtgroup(CPUX86State * env,struct x86_decode * decode)51369e0a03cSPaolo Bonzini static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode)
51469e0a03cSPaolo Bonzini {
51569e0a03cSPaolo Bonzini
51669e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
51769e0a03cSPaolo Bonzini X86_DECODE_CMD_SLDT,
51869e0a03cSPaolo Bonzini X86_DECODE_CMD_STR,
51969e0a03cSPaolo Bonzini X86_DECODE_CMD_LLDT,
52069e0a03cSPaolo Bonzini X86_DECODE_CMD_LTR,
52169e0a03cSPaolo Bonzini X86_DECODE_CMD_VERR,
52269e0a03cSPaolo Bonzini X86_DECODE_CMD_VERW,
52369e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL,
52469e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL
52569e0a03cSPaolo Bonzini };
52669e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
52769e0a03cSPaolo Bonzini }
52869e0a03cSPaolo Bonzini
decode_lidtgroup(CPUX86State * env,struct x86_decode * decode)52969e0a03cSPaolo Bonzini static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode)
53069e0a03cSPaolo Bonzini {
53169e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
53269e0a03cSPaolo Bonzini X86_DECODE_CMD_SGDT,
53369e0a03cSPaolo Bonzini X86_DECODE_CMD_SIDT,
53469e0a03cSPaolo Bonzini X86_DECODE_CMD_LGDT,
53569e0a03cSPaolo Bonzini X86_DECODE_CMD_LIDT,
53669e0a03cSPaolo Bonzini X86_DECODE_CMD_SMSW,
53769e0a03cSPaolo Bonzini X86_DECODE_CMD_LMSW,
53869e0a03cSPaolo Bonzini X86_DECODE_CMD_LMSW,
53969e0a03cSPaolo Bonzini X86_DECODE_CMD_INVLPG
54069e0a03cSPaolo Bonzini };
54169e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
54269e0a03cSPaolo Bonzini if (0xf9 == decode->modrm.modrm) {
54369e0a03cSPaolo Bonzini decode->opcode[decode->len++] = decode->modrm.modrm;
54469e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_RDTSCP;
54569e0a03cSPaolo Bonzini }
54669e0a03cSPaolo Bonzini }
54769e0a03cSPaolo Bonzini
decode_btgroup(CPUX86State * env,struct x86_decode * decode)54869e0a03cSPaolo Bonzini static void decode_btgroup(CPUX86State *env, struct x86_decode *decode)
54969e0a03cSPaolo Bonzini {
55069e0a03cSPaolo Bonzini enum x86_decode_cmd group[] = {
55169e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL,
55269e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL,
55369e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL,
55469e0a03cSPaolo Bonzini X86_DECODE_CMD_INVL,
55569e0a03cSPaolo Bonzini X86_DECODE_CMD_BT,
55669e0a03cSPaolo Bonzini X86_DECODE_CMD_BTS,
55769e0a03cSPaolo Bonzini X86_DECODE_CMD_BTR,
55869e0a03cSPaolo Bonzini X86_DECODE_CMD_BTC
55969e0a03cSPaolo Bonzini };
56069e0a03cSPaolo Bonzini decode->cmd = group[decode->modrm.reg];
56169e0a03cSPaolo Bonzini }
56269e0a03cSPaolo Bonzini
decode_x87_general(CPUX86State * env,struct x86_decode * decode)56369e0a03cSPaolo Bonzini static void decode_x87_general(CPUX86State *env, struct x86_decode *decode)
56469e0a03cSPaolo Bonzini {
56569e0a03cSPaolo Bonzini decode->is_fpu = true;
56669e0a03cSPaolo Bonzini }
56769e0a03cSPaolo Bonzini
decode_x87_modrm_floatp(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)56869e0a03cSPaolo Bonzini static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode,
56969e0a03cSPaolo Bonzini struct x86_decode_op *op)
57069e0a03cSPaolo Bonzini {
57169e0a03cSPaolo Bonzini op->type = X87_VAR_FLOATP;
57269e0a03cSPaolo Bonzini }
57369e0a03cSPaolo Bonzini
decode_x87_modrm_intp(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)57469e0a03cSPaolo Bonzini static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode,
57569e0a03cSPaolo Bonzini struct x86_decode_op *op)
57669e0a03cSPaolo Bonzini {
57769e0a03cSPaolo Bonzini op->type = X87_VAR_INTP;
57869e0a03cSPaolo Bonzini }
57969e0a03cSPaolo Bonzini
decode_x87_modrm_bytep(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)58069e0a03cSPaolo Bonzini static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode,
58169e0a03cSPaolo Bonzini struct x86_decode_op *op)
58269e0a03cSPaolo Bonzini {
58369e0a03cSPaolo Bonzini op->type = X87_VAR_BYTEP;
58469e0a03cSPaolo Bonzini }
58569e0a03cSPaolo Bonzini
decode_x87_modrm_st0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)58669e0a03cSPaolo Bonzini static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode,
58769e0a03cSPaolo Bonzini struct x86_decode_op *op)
58869e0a03cSPaolo Bonzini {
58969e0a03cSPaolo Bonzini op->type = X87_VAR_REG;
59069e0a03cSPaolo Bonzini op->reg = 0;
59169e0a03cSPaolo Bonzini }
59269e0a03cSPaolo Bonzini
decode_decode_x87_modrm_st0(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)59369e0a03cSPaolo Bonzini static void decode_decode_x87_modrm_st0(CPUX86State *env,
59469e0a03cSPaolo Bonzini struct x86_decode *decode,
59569e0a03cSPaolo Bonzini struct x86_decode_op *op)
59669e0a03cSPaolo Bonzini {
59769e0a03cSPaolo Bonzini op->type = X87_VAR_REG;
59869e0a03cSPaolo Bonzini op->reg = decode->modrm.modrm & 7;
59969e0a03cSPaolo Bonzini }
60069e0a03cSPaolo Bonzini
60169e0a03cSPaolo Bonzini
decode_aegroup(CPUX86State * env,struct x86_decode * decode)60269e0a03cSPaolo Bonzini static void decode_aegroup(CPUX86State *env, struct x86_decode *decode)
60369e0a03cSPaolo Bonzini {
60469e0a03cSPaolo Bonzini decode->is_fpu = true;
60569e0a03cSPaolo Bonzini switch (decode->modrm.reg) {
60669e0a03cSPaolo Bonzini case 0:
60769e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FXSAVE;
60869e0a03cSPaolo Bonzini decode_x87_modrm_bytep(env, decode, &decode->op[0]);
60969e0a03cSPaolo Bonzini break;
61069e0a03cSPaolo Bonzini case 1:
61169e0a03cSPaolo Bonzini decode_x87_modrm_bytep(env, decode, &decode->op[0]);
61269e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FXRSTOR;
61369e0a03cSPaolo Bonzini break;
61469e0a03cSPaolo Bonzini case 5:
61569e0a03cSPaolo Bonzini if (decode->modrm.modrm == 0xe8) {
61669e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_LFENCE;
61769e0a03cSPaolo Bonzini } else {
61869e0a03cSPaolo Bonzini VM_PANIC("xrstor");
61969e0a03cSPaolo Bonzini }
62069e0a03cSPaolo Bonzini break;
62169e0a03cSPaolo Bonzini case 6:
62269e0a03cSPaolo Bonzini VM_PANIC_ON(decode->modrm.modrm != 0xf0);
62369e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_MFENCE;
62469e0a03cSPaolo Bonzini break;
62569e0a03cSPaolo Bonzini case 7:
62669e0a03cSPaolo Bonzini if (decode->modrm.modrm == 0xf8) {
62769e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_SFENCE;
62869e0a03cSPaolo Bonzini } else {
62969e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_CLFLUSH;
63069e0a03cSPaolo Bonzini }
63169e0a03cSPaolo Bonzini break;
63269e0a03cSPaolo Bonzini default:
63374682782SPaolo Bonzini VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg);
63469e0a03cSPaolo Bonzini break;
63569e0a03cSPaolo Bonzini }
63669e0a03cSPaolo Bonzini }
63769e0a03cSPaolo Bonzini
decode_bswap(CPUX86State * env,struct x86_decode * decode)63869e0a03cSPaolo Bonzini static void decode_bswap(CPUX86State *env, struct x86_decode *decode)
63969e0a03cSPaolo Bonzini {
64069e0a03cSPaolo Bonzini decode->op[0].type = X86_VAR_REG;
64169e0a03cSPaolo Bonzini decode->op[0].reg = decode->opcode[1] - 0xc8;
642b4e1af89SRoman Bolshakov decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
643b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
64469e0a03cSPaolo Bonzini }
64569e0a03cSPaolo Bonzini
decode_d9_4(CPUX86State * env,struct x86_decode * decode)64669e0a03cSPaolo Bonzini static void decode_d9_4(CPUX86State *env, struct x86_decode *decode)
64769e0a03cSPaolo Bonzini {
64869e0a03cSPaolo Bonzini switch (decode->modrm.modrm) {
64969e0a03cSPaolo Bonzini case 0xe0:
65069e0a03cSPaolo Bonzini /* FCHS */
65169e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FCHS;
65269e0a03cSPaolo Bonzini break;
65369e0a03cSPaolo Bonzini case 0xe1:
65469e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FABS;
65569e0a03cSPaolo Bonzini break;
65669e0a03cSPaolo Bonzini case 0xe4:
65774682782SPaolo Bonzini VM_PANIC("FTST");
65869e0a03cSPaolo Bonzini break;
65969e0a03cSPaolo Bonzini case 0xe5:
66069e0a03cSPaolo Bonzini /* FXAM */
66169e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FXAM;
66269e0a03cSPaolo Bonzini break;
66369e0a03cSPaolo Bonzini default:
66474682782SPaolo Bonzini VM_PANIC("FLDENV");
66569e0a03cSPaolo Bonzini break;
66669e0a03cSPaolo Bonzini }
66769e0a03cSPaolo Bonzini }
66869e0a03cSPaolo Bonzini
decode_db_4(CPUX86State * env,struct x86_decode * decode)66969e0a03cSPaolo Bonzini static void decode_db_4(CPUX86State *env, struct x86_decode *decode)
67069e0a03cSPaolo Bonzini {
67169e0a03cSPaolo Bonzini switch (decode->modrm.modrm) {
67269e0a03cSPaolo Bonzini case 0xe0:
67374682782SPaolo Bonzini VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0],
67469e0a03cSPaolo Bonzini decode->modrm.modrm);
67569e0a03cSPaolo Bonzini break;
67669e0a03cSPaolo Bonzini case 0xe1:
67774682782SPaolo Bonzini VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0],
67869e0a03cSPaolo Bonzini decode->modrm.modrm);
67969e0a03cSPaolo Bonzini break;
68069e0a03cSPaolo Bonzini case 0xe2:
68174682782SPaolo Bonzini VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0],
68269e0a03cSPaolo Bonzini decode->modrm.modrm);
68369e0a03cSPaolo Bonzini break;
68469e0a03cSPaolo Bonzini case 0xe3:
68569e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FNINIT;
68669e0a03cSPaolo Bonzini break;
68769e0a03cSPaolo Bonzini case 0xe4:
68869e0a03cSPaolo Bonzini decode->cmd = X86_DECODE_CMD_FNSETPM;
68969e0a03cSPaolo Bonzini break;
69069e0a03cSPaolo Bonzini default:
69174682782SPaolo Bonzini VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0],
69269e0a03cSPaolo Bonzini decode->modrm.modrm);
69369e0a03cSPaolo Bonzini break;
69469e0a03cSPaolo Bonzini }
69569e0a03cSPaolo Bonzini }
69669e0a03cSPaolo Bonzini
69769e0a03cSPaolo Bonzini
69869e0a03cSPaolo Bonzini #define RFLAGS_MASK_NONE 0
699ea48ae91SRoman Bolshakov #define RFLAGS_MASK_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
700ea48ae91SRoman Bolshakov #define RFLAGS_MASK_LAHF (CC_S | CC_Z | CC_A | CC_P | CC_C)
701ea48ae91SRoman Bolshakov #define RFLAGS_MASK_CF (CC_C)
702ea48ae91SRoman Bolshakov #define RFLAGS_MASK_IF (IF_MASK)
703ea48ae91SRoman Bolshakov #define RFLAGS_MASK_TF (TF_MASK)
704ea48ae91SRoman Bolshakov #define RFLAGS_MASK_DF (DF_MASK)
705ea48ae91SRoman Bolshakov #define RFLAGS_MASK_ZF (CC_Z)
70669e0a03cSPaolo Bonzini
70769e0a03cSPaolo Bonzini struct decode_tbl _1op_inst[] = {
70869e0a03cSPaolo Bonzini {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
70969e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
71069e0a03cSPaolo Bonzini {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
71169e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
71269e0a03cSPaolo Bonzini {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
71369e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
71469e0a03cSPaolo Bonzini {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL,
71569e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
71669e0a03cSPaolo Bonzini {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL,
71769e0a03cSPaolo Bonzini NULL, RFLAGS_MASK_OSZAPC},
71869e0a03cSPaolo Bonzini {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL,
71969e0a03cSPaolo Bonzini NULL, RFLAGS_MASK_OSZAPC},
72069e0a03cSPaolo Bonzini {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL,
72169e0a03cSPaolo Bonzini decode_pushseg, RFLAGS_MASK_NONE},
72269e0a03cSPaolo Bonzini {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL,
72369e0a03cSPaolo Bonzini decode_popseg, RFLAGS_MASK_NONE},
72469e0a03cSPaolo Bonzini {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
72569e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
72669e0a03cSPaolo Bonzini {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
72769e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
72869e0a03cSPaolo Bonzini {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
72969e0a03cSPaolo Bonzini NULL, NULL, RFLAGS_MASK_OSZAPC},
73069e0a03cSPaolo Bonzini {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm,
73169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
73269e0a03cSPaolo Bonzini {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8,
73369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
73469e0a03cSPaolo Bonzini {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm,
73569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
73669e0a03cSPaolo Bonzini
73769e0a03cSPaolo Bonzini {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
73869e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
73969e0a03cSPaolo Bonzini {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false,
74069e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
74169e0a03cSPaolo Bonzini
74269e0a03cSPaolo Bonzini {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg,
74369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
74469e0a03cSPaolo Bonzini {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg,
74569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
74669e0a03cSPaolo Bonzini {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm,
74769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
74869e0a03cSPaolo Bonzini {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm,
74969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
75069e0a03cSPaolo Bonzini {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm,
75169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
75269e0a03cSPaolo Bonzini {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm,
75369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
75469e0a03cSPaolo Bonzini
75569e0a03cSPaolo Bonzini {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
75669e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
75769e0a03cSPaolo Bonzini {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false,
75869e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
75969e0a03cSPaolo Bonzini
76069e0a03cSPaolo Bonzini {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg,
76169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
76269e0a03cSPaolo Bonzini {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg,
76369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
76469e0a03cSPaolo Bonzini {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm,
76569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
76669e0a03cSPaolo Bonzini {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm,
76769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
76869e0a03cSPaolo Bonzini {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8,
76969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
77069e0a03cSPaolo Bonzini {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm,
77169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
77269e0a03cSPaolo Bonzini
77369e0a03cSPaolo Bonzini {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
77469e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
77569e0a03cSPaolo Bonzini {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false,
77669e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
77769e0a03cSPaolo Bonzini
77869e0a03cSPaolo Bonzini {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg,
77969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
78069e0a03cSPaolo Bonzini {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg,
78169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
78269e0a03cSPaolo Bonzini {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm,
78369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
78469e0a03cSPaolo Bonzini {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm,
78569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
78669e0a03cSPaolo Bonzini {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm,
78769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
78869e0a03cSPaolo Bonzini {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm,
78969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
79069e0a03cSPaolo Bonzini {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg,
79169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
79269e0a03cSPaolo Bonzini {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg,
79369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
79469e0a03cSPaolo Bonzini {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm,
79569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
79669e0a03cSPaolo Bonzini {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm,
79769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
79869e0a03cSPaolo Bonzini {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm,
79969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
80069e0a03cSPaolo Bonzini {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm,
80169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
80269e0a03cSPaolo Bonzini {0x2f, X86_DECODE_CMD_DAS, 0, false,
80369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
80469e0a03cSPaolo Bonzini {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg,
80569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
80669e0a03cSPaolo Bonzini {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg,
80769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
80869e0a03cSPaolo Bonzini {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm,
80969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
81069e0a03cSPaolo Bonzini {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm,
81169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
81269e0a03cSPaolo Bonzini {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm,
81369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
81469e0a03cSPaolo Bonzini {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm,
81569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
81669e0a03cSPaolo Bonzini
81769e0a03cSPaolo Bonzini {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg,
81869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
81969e0a03cSPaolo Bonzini {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg,
82069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
82169e0a03cSPaolo Bonzini {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm,
82269e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
82369e0a03cSPaolo Bonzini {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm,
82469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
82569e0a03cSPaolo Bonzini {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8,
82669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
82769e0a03cSPaolo Bonzini {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm,
82869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
82969e0a03cSPaolo Bonzini
83069e0a03cSPaolo Bonzini {0x3f, X86_DECODE_CMD_AAS, 0, false,
83169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
83269e0a03cSPaolo Bonzini
83369e0a03cSPaolo Bonzini {0x40, X86_DECODE_CMD_INC, 0, false,
83469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
83569e0a03cSPaolo Bonzini {0x41, X86_DECODE_CMD_INC, 0, false,
83669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
83769e0a03cSPaolo Bonzini {0x42, X86_DECODE_CMD_INC, 0, false,
83869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
83969e0a03cSPaolo Bonzini {0x43, X86_DECODE_CMD_INC, 0, false,
84069e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
84169e0a03cSPaolo Bonzini {0x44, X86_DECODE_CMD_INC, 0, false,
84269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
84369e0a03cSPaolo Bonzini {0x45, X86_DECODE_CMD_INC, 0, false,
84469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
84569e0a03cSPaolo Bonzini {0x46, X86_DECODE_CMD_INC, 0, false,
84669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
84769e0a03cSPaolo Bonzini {0x47, X86_DECODE_CMD_INC, 0, false,
84869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
84969e0a03cSPaolo Bonzini
85069e0a03cSPaolo Bonzini {0x48, X86_DECODE_CMD_DEC, 0, false,
85169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
85269e0a03cSPaolo Bonzini {0x49, X86_DECODE_CMD_DEC, 0, false,
85369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
85469e0a03cSPaolo Bonzini {0x4a, X86_DECODE_CMD_DEC, 0, false,
85569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
85669e0a03cSPaolo Bonzini {0x4b, X86_DECODE_CMD_DEC, 0, false,
85769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
85869e0a03cSPaolo Bonzini {0x4c, X86_DECODE_CMD_DEC, 0, false,
85969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
86069e0a03cSPaolo Bonzini {0x4d, X86_DECODE_CMD_DEC, 0, false,
86169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
86269e0a03cSPaolo Bonzini {0x4e, X86_DECODE_CMD_DEC, 0, false,
86369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
86469e0a03cSPaolo Bonzini {0x4f, X86_DECODE_CMD_DEC, 0, false,
86569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
86669e0a03cSPaolo Bonzini
86769e0a03cSPaolo Bonzini {0x50, X86_DECODE_CMD_PUSH, 0, false,
86869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
86969e0a03cSPaolo Bonzini {0x51, X86_DECODE_CMD_PUSH, 0, false,
87069e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
87169e0a03cSPaolo Bonzini {0x52, X86_DECODE_CMD_PUSH, 0, false,
87269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
87369e0a03cSPaolo Bonzini {0x53, X86_DECODE_CMD_PUSH, 0, false,
87469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
87569e0a03cSPaolo Bonzini {0x54, X86_DECODE_CMD_PUSH, 0, false,
87669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
87769e0a03cSPaolo Bonzini {0x55, X86_DECODE_CMD_PUSH, 0, false,
87869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
87969e0a03cSPaolo Bonzini {0x56, X86_DECODE_CMD_PUSH, 0, false,
88069e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
88169e0a03cSPaolo Bonzini {0x57, X86_DECODE_CMD_PUSH, 0, false,
88269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
88369e0a03cSPaolo Bonzini
88469e0a03cSPaolo Bonzini {0x58, X86_DECODE_CMD_POP, 0, false,
88569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
88669e0a03cSPaolo Bonzini {0x59, X86_DECODE_CMD_POP, 0, false,
88769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
88869e0a03cSPaolo Bonzini {0x5a, X86_DECODE_CMD_POP, 0, false,
88969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
89069e0a03cSPaolo Bonzini {0x5b, X86_DECODE_CMD_POP, 0, false,
89169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
89269e0a03cSPaolo Bonzini {0x5c, X86_DECODE_CMD_POP, 0, false,
89369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
89469e0a03cSPaolo Bonzini {0x5d, X86_DECODE_CMD_POP, 0, false,
89569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
89669e0a03cSPaolo Bonzini {0x5e, X86_DECODE_CMD_POP, 0, false,
89769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
89869e0a03cSPaolo Bonzini {0x5f, X86_DECODE_CMD_POP, 0, false,
89969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
90069e0a03cSPaolo Bonzini
90169e0a03cSPaolo Bonzini {0x60, X86_DECODE_CMD_PUSHA, 0, false,
90269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
90369e0a03cSPaolo Bonzini {0x61, X86_DECODE_CMD_POPA, 0, false,
90469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
90569e0a03cSPaolo Bonzini
90669e0a03cSPaolo Bonzini {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm,
90769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
90869e0a03cSPaolo Bonzini {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed,
90969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
91069e0a03cSPaolo Bonzini {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg,
91169e0a03cSPaolo Bonzini decode_modrm_rm, decode_imm, NULL, NULL, RFLAGS_MASK_OSZAPC},
91269e0a03cSPaolo Bonzini {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm,
91369e0a03cSPaolo Bonzini decode_imm8_signed, NULL, NULL, RFLAGS_MASK_OSZAPC},
91469e0a03cSPaolo Bonzini
91569e0a03cSPaolo Bonzini {0x6c, X86_DECODE_CMD_INS, 1, false,
91669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
91769e0a03cSPaolo Bonzini {0x6d, X86_DECODE_CMD_INS, 0, false,
91869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
91969e0a03cSPaolo Bonzini {0x6e, X86_DECODE_CMD_OUTS, 1, false,
92069e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
92169e0a03cSPaolo Bonzini {0x6f, X86_DECODE_CMD_OUTS, 0, false,
92269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
92369e0a03cSPaolo Bonzini
92469e0a03cSPaolo Bonzini {0x70, X86_DECODE_CMD_JXX, 1, false,
92569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
92669e0a03cSPaolo Bonzini {0x71, X86_DECODE_CMD_JXX, 1, false,
92769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
92869e0a03cSPaolo Bonzini {0x72, X86_DECODE_CMD_JXX, 1, false,
92969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
93069e0a03cSPaolo Bonzini {0x73, X86_DECODE_CMD_JXX, 1, false,
93169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
93269e0a03cSPaolo Bonzini {0x74, X86_DECODE_CMD_JXX, 1, false,
93369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
93469e0a03cSPaolo Bonzini {0x75, X86_DECODE_CMD_JXX, 1, false,
93569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
93669e0a03cSPaolo Bonzini {0x76, X86_DECODE_CMD_JXX, 1, false,
93769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
93869e0a03cSPaolo Bonzini {0x77, X86_DECODE_CMD_JXX, 1, false,
93969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
94069e0a03cSPaolo Bonzini {0x78, X86_DECODE_CMD_JXX, 1, false,
94169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
94269e0a03cSPaolo Bonzini {0x79, X86_DECODE_CMD_JXX, 1, false,
94369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
94469e0a03cSPaolo Bonzini {0x7a, X86_DECODE_CMD_JXX, 1, false,
94569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
94669e0a03cSPaolo Bonzini {0x7b, X86_DECODE_CMD_JXX, 1, false,
94769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
94869e0a03cSPaolo Bonzini {0x7c, X86_DECODE_CMD_JXX, 1, false,
94969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
95069e0a03cSPaolo Bonzini {0x7d, X86_DECODE_CMD_JXX, 1, false,
95169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
95269e0a03cSPaolo Bonzini {0x7e, X86_DECODE_CMD_JXX, 1, false,
95369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
95469e0a03cSPaolo Bonzini {0x7f, X86_DECODE_CMD_JXX, 1, false,
95569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
95669e0a03cSPaolo Bonzini
95769e0a03cSPaolo Bonzini {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
95869e0a03cSPaolo Bonzini NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
95969e0a03cSPaolo Bonzini {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm,
96069e0a03cSPaolo Bonzini NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
96169e0a03cSPaolo Bonzini {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
96269e0a03cSPaolo Bonzini NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
96369e0a03cSPaolo Bonzini {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed,
96469e0a03cSPaolo Bonzini NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
96569e0a03cSPaolo Bonzini {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg,
96669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
96769e0a03cSPaolo Bonzini {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg,
96869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
96969e0a03cSPaolo Bonzini {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm,
97069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
97169e0a03cSPaolo Bonzini {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm,
97269e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
97369e0a03cSPaolo Bonzini {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg,
97469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
97569e0a03cSPaolo Bonzini {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg,
97669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
97769e0a03cSPaolo Bonzini {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm,
97869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
97969e0a03cSPaolo Bonzini {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm,
98069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
98169e0a03cSPaolo Bonzini {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm,
98269e0a03cSPaolo Bonzini decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
98369e0a03cSPaolo Bonzini {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm,
98469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
98569e0a03cSPaolo Bonzini {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg,
98669e0a03cSPaolo Bonzini decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
98769e0a03cSPaolo Bonzini {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm,
98869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
98969e0a03cSPaolo Bonzini
99069e0a03cSPaolo Bonzini {0x90, X86_DECODE_CMD_NOP, 0, false,
99169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
99269e0a03cSPaolo Bonzini {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
99369e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
99469e0a03cSPaolo Bonzini {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
99569e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
99669e0a03cSPaolo Bonzini {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
99769e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
99869e0a03cSPaolo Bonzini {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
99969e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
100069e0a03cSPaolo Bonzini {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
100169e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
100269e0a03cSPaolo Bonzini {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
100369e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
100469e0a03cSPaolo Bonzini {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
100569e0a03cSPaolo Bonzini NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
100669e0a03cSPaolo Bonzini
100769e0a03cSPaolo Bonzini {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL,
100869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
100969e0a03cSPaolo Bonzini {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL,
101069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
101169e0a03cSPaolo Bonzini
101269e0a03cSPaolo Bonzini {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL,
101369e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE},
101469e0a03cSPaolo Bonzini
101569e0a03cSPaolo Bonzini {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL,
101669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
101769e0a03cSPaolo Bonzini /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL,
101869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_POPF},*/
101969e0a03cSPaolo Bonzini {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL,
102069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
102169e0a03cSPaolo Bonzini {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL,
102269e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_LAHF},
102369e0a03cSPaolo Bonzini
102469e0a03cSPaolo Bonzini {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs,
102569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
102669e0a03cSPaolo Bonzini {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs,
102769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
102869e0a03cSPaolo Bonzini {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax,
102969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
103069e0a03cSPaolo Bonzini {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax,
103169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
103269e0a03cSPaolo Bonzini
103369e0a03cSPaolo Bonzini {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL,
103469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
103569e0a03cSPaolo Bonzini {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL,
103669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
103769e0a03cSPaolo Bonzini {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL,
103869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
103969e0a03cSPaolo Bonzini {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL,
104069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
104169e0a03cSPaolo Bonzini {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL,
104269e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
104369e0a03cSPaolo Bonzini {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL,
104469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
104569e0a03cSPaolo Bonzini {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL,
104669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
104769e0a03cSPaolo Bonzini {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL,
104869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
104969e0a03cSPaolo Bonzini {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL,
105069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
105169e0a03cSPaolo Bonzini {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL,
105269e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
105369e0a03cSPaolo Bonzini
105469e0a03cSPaolo Bonzini {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm,
105569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
105669e0a03cSPaolo Bonzini {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm,
105769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
105869e0a03cSPaolo Bonzini
105969e0a03cSPaolo Bonzini {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL,
106069e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
106169e0a03cSPaolo Bonzini {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL,
106269e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
106369e0a03cSPaolo Bonzini {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL,
106469e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
106569e0a03cSPaolo Bonzini {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL,
106669e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
106769e0a03cSPaolo Bonzini {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL,
106869e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
106969e0a03cSPaolo Bonzini {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL,
107069e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
107169e0a03cSPaolo Bonzini {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL,
107269e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
107369e0a03cSPaolo Bonzini {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL,
107469e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
107569e0a03cSPaolo Bonzini
107669e0a03cSPaolo Bonzini {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL,
107769e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
107869e0a03cSPaolo Bonzini {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL,
107969e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
108069e0a03cSPaolo Bonzini {0xba, X86_DECODE_CMD_MOV, 0, false, NULL,
108169e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
108269e0a03cSPaolo Bonzini {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL,
108369e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
108469e0a03cSPaolo Bonzini {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL,
108569e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
108669e0a03cSPaolo Bonzini {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL,
108769e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
108869e0a03cSPaolo Bonzini {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL,
108969e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
109069e0a03cSPaolo Bonzini {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL,
109169e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
109269e0a03cSPaolo Bonzini
109369e0a03cSPaolo Bonzini {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
109469e0a03cSPaolo Bonzini NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
109569e0a03cSPaolo Bonzini {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
109669e0a03cSPaolo Bonzini NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
109769e0a03cSPaolo Bonzini
109869e0a03cSPaolo Bonzini {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16,
109969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
110069e0a03cSPaolo Bonzini {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL,
110169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
110269e0a03cSPaolo Bonzini
110369e0a03cSPaolo Bonzini {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm,
110469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
110569e0a03cSPaolo Bonzini {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm,
110669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
110769e0a03cSPaolo Bonzini
110869e0a03cSPaolo Bonzini {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8,
110969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
111069e0a03cSPaolo Bonzini {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm,
111169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
111269e0a03cSPaolo Bonzini
111369e0a03cSPaolo Bonzini {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8,
111469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
111569e0a03cSPaolo Bonzini {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL,
111669e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
111769e0a03cSPaolo Bonzini {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL,
111869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
111969e0a03cSPaolo Bonzini {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL,
112069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
112169e0a03cSPaolo Bonzini {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL,
112269e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
112369e0a03cSPaolo Bonzini /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL,
112469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_IRET},*/
112569e0a03cSPaolo Bonzini
112669e0a03cSPaolo Bonzini {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1,
112769e0a03cSPaolo Bonzini NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
112869e0a03cSPaolo Bonzini {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1,
112969e0a03cSPaolo Bonzini NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
113069e0a03cSPaolo Bonzini {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx,
113169e0a03cSPaolo Bonzini NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
113269e0a03cSPaolo Bonzini {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx,
113369e0a03cSPaolo Bonzini NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
113469e0a03cSPaolo Bonzini
113569e0a03cSPaolo Bonzini {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8,
113669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
113769e0a03cSPaolo Bonzini {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8,
113869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
113969e0a03cSPaolo Bonzini
114069e0a03cSPaolo Bonzini {0xd7, X86_DECODE_CMD_XLAT, 0, false,
114169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
114269e0a03cSPaolo Bonzini
114369e0a03cSPaolo Bonzini {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL,
114469e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
114569e0a03cSPaolo Bonzini {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL,
114669e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
114769e0a03cSPaolo Bonzini {0xda, X86_DECODE_CMD_INVL, 0, true, NULL,
114869e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
114969e0a03cSPaolo Bonzini {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL,
115069e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
115169e0a03cSPaolo Bonzini {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL,
115269e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
115369e0a03cSPaolo Bonzini {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL,
115469e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
115569e0a03cSPaolo Bonzini {0xde, X86_DECODE_CMD_INVL, 0, true, NULL,
115669e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
115769e0a03cSPaolo Bonzini {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL,
115869e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
115969e0a03cSPaolo Bonzini
116069e0a03cSPaolo Bonzini {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
116169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
116269e0a03cSPaolo Bonzini {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
116369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
116469e0a03cSPaolo Bonzini {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
116569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
116669e0a03cSPaolo Bonzini
116769e0a03cSPaolo Bonzini {0xe3, X86_DECODE_CMD_JCXZ, 1, false,
116869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
116969e0a03cSPaolo Bonzini
117069e0a03cSPaolo Bonzini {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8,
117169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
117269e0a03cSPaolo Bonzini {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8,
117369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
117469e0a03cSPaolo Bonzini {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8,
117569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
117669e0a03cSPaolo Bonzini {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8,
117769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
117869e0a03cSPaolo Bonzini {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed,
117969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
118069e0a03cSPaolo Bonzini {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed,
118169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
118269e0a03cSPaolo Bonzini {0xea, X86_DECODE_CMD_JMP_FAR, 0, false,
118369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE},
118469e0a03cSPaolo Bonzini {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed,
118569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
118669e0a03cSPaolo Bonzini {0xec, X86_DECODE_CMD_IN, 1, false,
118769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
118869e0a03cSPaolo Bonzini {0xed, X86_DECODE_CMD_IN, 0, false,
118969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
119069e0a03cSPaolo Bonzini {0xee, X86_DECODE_CMD_OUT, 1, false,
119169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
119269e0a03cSPaolo Bonzini {0xef, X86_DECODE_CMD_OUT, 0, false,
119369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
119469e0a03cSPaolo Bonzini
119569e0a03cSPaolo Bonzini {0xf4, X86_DECODE_CMD_HLT, 0, false,
119669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
119769e0a03cSPaolo Bonzini
119869e0a03cSPaolo Bonzini {0xf5, X86_DECODE_CMD_CMC, 0, false,
119969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
120069e0a03cSPaolo Bonzini
120169e0a03cSPaolo Bonzini {0xf6, X86_DECODE_CMD_INVL, 1, true,
120269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC},
120369e0a03cSPaolo Bonzini {0xf7, X86_DECODE_CMD_INVL, 0, true,
120469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC},
120569e0a03cSPaolo Bonzini
120669e0a03cSPaolo Bonzini {0xf8, X86_DECODE_CMD_CLC, 0, false,
120769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
120869e0a03cSPaolo Bonzini {0xf9, X86_DECODE_CMD_STC, 0, false,
120969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
121069e0a03cSPaolo Bonzini
121169e0a03cSPaolo Bonzini {0xfa, X86_DECODE_CMD_CLI, 0, false,
121269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF},
121369e0a03cSPaolo Bonzini {0xfb, X86_DECODE_CMD_STI, 0, false,
121469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF},
121569e0a03cSPaolo Bonzini {0xfc, X86_DECODE_CMD_CLD, 0, false,
121669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF},
121769e0a03cSPaolo Bonzini {0xfd, X86_DECODE_CMD_STD, 0, false,
121869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF},
121969e0a03cSPaolo Bonzini {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm,
122069e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_incgroup2, RFLAGS_MASK_OSZAPC},
122169e0a03cSPaolo Bonzini {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
122269e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_ffgroup, RFLAGS_MASK_OSZAPC},
122369e0a03cSPaolo Bonzini };
122469e0a03cSPaolo Bonzini
122569e0a03cSPaolo Bonzini struct decode_tbl _2op_inst[] = {
122669e0a03cSPaolo Bonzini {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
122769e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_sldtgroup, RFLAGS_MASK_NONE},
122869e0a03cSPaolo Bonzini {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
122969e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_lidtgroup, RFLAGS_MASK_NONE},
123069e0a03cSPaolo Bonzini {0x6, X86_DECODE_CMD_CLTS, 0, false,
123169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_TF},
123269e0a03cSPaolo Bonzini {0x9, X86_DECODE_CMD_WBINVD, 0, false,
123369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
123469e0a03cSPaolo Bonzini {0x18, X86_DECODE_CMD_PREFETCH, 0, true,
123569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE},
123669e0a03cSPaolo Bonzini {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm,
123769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
123869e0a03cSPaolo Bonzini {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm,
123969e0a03cSPaolo Bonzini decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
124069e0a03cSPaolo Bonzini {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm,
124169e0a03cSPaolo Bonzini decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
124269e0a03cSPaolo Bonzini {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg,
124369e0a03cSPaolo Bonzini decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
124469e0a03cSPaolo Bonzini {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg,
124569e0a03cSPaolo Bonzini decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
124669e0a03cSPaolo Bonzini {0x30, X86_DECODE_CMD_WRMSR, 0, false,
124769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
124869e0a03cSPaolo Bonzini {0x31, X86_DECODE_CMD_RDTSC, 0, false,
124969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
125069e0a03cSPaolo Bonzini {0x32, X86_DECODE_CMD_RDMSR, 0, false,
125169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
125269e0a03cSPaolo Bonzini {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
125369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
125469e0a03cSPaolo Bonzini {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
125569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
125669e0a03cSPaolo Bonzini {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
125769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
125869e0a03cSPaolo Bonzini {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
125969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
126069e0a03cSPaolo Bonzini {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
126169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
126269e0a03cSPaolo Bonzini {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
126369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
126469e0a03cSPaolo Bonzini {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
126569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
126669e0a03cSPaolo Bonzini {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
126769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
126869e0a03cSPaolo Bonzini {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
126969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
127069e0a03cSPaolo Bonzini {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
127169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
127269e0a03cSPaolo Bonzini {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
127369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
127469e0a03cSPaolo Bonzini {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
127569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
127669e0a03cSPaolo Bonzini {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
127769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
127869e0a03cSPaolo Bonzini {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
127969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
128069e0a03cSPaolo Bonzini {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
128169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
128269e0a03cSPaolo Bonzini {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
128369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
128469e0a03cSPaolo Bonzini {0x77, X86_DECODE_CMD_EMMS, 0, false,
128569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE},
128669e0a03cSPaolo Bonzini {0x82, X86_DECODE_CMD_JXX, 0, false,
128769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
128869e0a03cSPaolo Bonzini {0x83, X86_DECODE_CMD_JXX, 0, false,
128969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
129069e0a03cSPaolo Bonzini {0x84, X86_DECODE_CMD_JXX, 0, false,
129169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
129269e0a03cSPaolo Bonzini {0x85, X86_DECODE_CMD_JXX, 0, false,
129369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
129469e0a03cSPaolo Bonzini {0x86, X86_DECODE_CMD_JXX, 0, false,
129569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
129669e0a03cSPaolo Bonzini {0x87, X86_DECODE_CMD_JXX, 0, false,
129769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
129869e0a03cSPaolo Bonzini {0x88, X86_DECODE_CMD_JXX, 0, false,
129969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
130069e0a03cSPaolo Bonzini {0x89, X86_DECODE_CMD_JXX, 0, false,
130169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
130269e0a03cSPaolo Bonzini {0x8a, X86_DECODE_CMD_JXX, 0, false,
130369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
130469e0a03cSPaolo Bonzini {0x8b, X86_DECODE_CMD_JXX, 0, false,
130569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
130669e0a03cSPaolo Bonzini {0x8c, X86_DECODE_CMD_JXX, 0, false,
130769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
130869e0a03cSPaolo Bonzini {0x8d, X86_DECODE_CMD_JXX, 0, false,
130969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
131069e0a03cSPaolo Bonzini {0x8e, X86_DECODE_CMD_JXX, 0, false,
131169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
131269e0a03cSPaolo Bonzini {0x8f, X86_DECODE_CMD_JXX, 0, false,
131369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
131469e0a03cSPaolo Bonzini {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
131569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
131669e0a03cSPaolo Bonzini {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
131769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
131869e0a03cSPaolo Bonzini {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
131969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
132069e0a03cSPaolo Bonzini {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
132169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
132269e0a03cSPaolo Bonzini {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
132369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
132469e0a03cSPaolo Bonzini {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
132569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
132669e0a03cSPaolo Bonzini {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
132769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
132869e0a03cSPaolo Bonzini {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
132969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
133069e0a03cSPaolo Bonzini {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
133169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
133269e0a03cSPaolo Bonzini {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
133369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
133469e0a03cSPaolo Bonzini {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
133569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
133669e0a03cSPaolo Bonzini {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
133769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
133869e0a03cSPaolo Bonzini {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
133969e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
134069e0a03cSPaolo Bonzini {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
134169e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
134269e0a03cSPaolo Bonzini {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
134369e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
134469e0a03cSPaolo Bonzini {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
134569e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
134669e0a03cSPaolo Bonzini
134769e0a03cSPaolo Bonzini {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg,
134869e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
134969e0a03cSPaolo Bonzini {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg,
135069e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
135169e0a03cSPaolo Bonzini
135269e0a03cSPaolo Bonzini {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
135369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
135469e0a03cSPaolo Bonzini {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
135569e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
135669e0a03cSPaolo Bonzini {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm,
135769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
135869e0a03cSPaolo Bonzini {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
135969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
136069e0a03cSPaolo Bonzini {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
136169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
136269e0a03cSPaolo Bonzini {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
136369e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
136469e0a03cSPaolo Bonzini {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false,
136569e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
136669e0a03cSPaolo Bonzini {0xa2, X86_DECODE_CMD_CPUID, 0, false,
136769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
136869e0a03cSPaolo Bonzini {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg,
136969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_CF},
137069e0a03cSPaolo Bonzini {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
137169e0a03cSPaolo Bonzini decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC},
137269e0a03cSPaolo Bonzini {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
137369e0a03cSPaolo Bonzini decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC},
137469e0a03cSPaolo Bonzini {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
137569e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
137669e0a03cSPaolo Bonzini {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false,
137769e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
137869e0a03cSPaolo Bonzini {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg,
137969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_CF},
138069e0a03cSPaolo Bonzini {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
138169e0a03cSPaolo Bonzini decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC},
138269e0a03cSPaolo Bonzini {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
138369e0a03cSPaolo Bonzini decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC},
138469e0a03cSPaolo Bonzini
138569e0a03cSPaolo Bonzini {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
138669e0a03cSPaolo Bonzini NULL, NULL, NULL, decode_aegroup, RFLAGS_MASK_NONE},
138769e0a03cSPaolo Bonzini
138869e0a03cSPaolo Bonzini {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm,
138969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
139069e0a03cSPaolo Bonzini {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm,
139169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_NONE},
139269e0a03cSPaolo Bonzini {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg,
139369e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
139469e0a03cSPaolo Bonzini {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
139569e0a03cSPaolo Bonzini NULL, NULL, decode_btgroup, RFLAGS_MASK_OSZAPC},
139669e0a03cSPaolo Bonzini {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg,
139769e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
139869e0a03cSPaolo Bonzini {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm,
139969e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
140069e0a03cSPaolo Bonzini {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm,
140169e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
140269e0a03cSPaolo Bonzini
140369e0a03cSPaolo Bonzini {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg,
140469e0a03cSPaolo Bonzini NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
140569e0a03cSPaolo Bonzini
140669e0a03cSPaolo Bonzini {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm,
140769e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, RFLAGS_MASK_ZF},
140869e0a03cSPaolo Bonzini
140969e0a03cSPaolo Bonzini {0xc8, X86_DECODE_CMD_BSWAP, 0, false,
141069e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
141169e0a03cSPaolo Bonzini {0xc9, X86_DECODE_CMD_BSWAP, 0, false,
141269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
141369e0a03cSPaolo Bonzini {0xca, X86_DECODE_CMD_BSWAP, 0, false,
141469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
141569e0a03cSPaolo Bonzini {0xcb, X86_DECODE_CMD_BSWAP, 0, false,
141669e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
141769e0a03cSPaolo Bonzini {0xcc, X86_DECODE_CMD_BSWAP, 0, false,
141869e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
141969e0a03cSPaolo Bonzini {0xcd, X86_DECODE_CMD_BSWAP, 0, false,
142069e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
142169e0a03cSPaolo Bonzini {0xce, X86_DECODE_CMD_BSWAP, 0, false,
142269e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
142369e0a03cSPaolo Bonzini {0xcf, X86_DECODE_CMD_BSWAP, 0, false,
142469e0a03cSPaolo Bonzini NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
142569e0a03cSPaolo Bonzini };
142669e0a03cSPaolo Bonzini
142769e0a03cSPaolo Bonzini struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL,
142869e0a03cSPaolo Bonzini NULL, decode_invalid, 0};
142969e0a03cSPaolo Bonzini
143069e0a03cSPaolo Bonzini struct decode_x87_tbl _x87_inst[] = {
143169e0a03cSPaolo Bonzini {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
143269e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
143369e0a03cSPaolo Bonzini {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
143469e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
143569e0a03cSPaolo Bonzini {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0,
143669e0a03cSPaolo Bonzini decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
143769e0a03cSPaolo Bonzini {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
143869e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
143969e0a03cSPaolo Bonzini {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0,
144069e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
144169e0a03cSPaolo Bonzini {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
144269e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
144369e0a03cSPaolo Bonzini {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0,
144469e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
144569e0a03cSPaolo Bonzini {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
144669e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
144769e0a03cSPaolo Bonzini {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0,
144869e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
144969e0a03cSPaolo Bonzini {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
145069e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
145169e0a03cSPaolo Bonzini {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0,
145269e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
145369e0a03cSPaolo Bonzini {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
145469e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
145569e0a03cSPaolo Bonzini
145669e0a03cSPaolo Bonzini {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false,
145769e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
145869e0a03cSPaolo Bonzini {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
145969e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
146069e0a03cSPaolo Bonzini {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0,
146169e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
146269e0a03cSPaolo Bonzini {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false,
146369e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
146469e0a03cSPaolo Bonzini {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false,
146569e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
146669e0a03cSPaolo Bonzini {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
146769e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
146869e0a03cSPaolo Bonzini {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false,
146969e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
147069e0a03cSPaolo Bonzini {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
147169e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
147269e0a03cSPaolo Bonzini {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false,
147369e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, decode_d9_4, RFLAGS_MASK_NONE},
147469e0a03cSPaolo Bonzini {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false,
147569e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
147669e0a03cSPaolo Bonzini {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL,
147769e0a03cSPaolo Bonzini RFLAGS_MASK_NONE},
147869e0a03cSPaolo Bonzini {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false,
147969e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
148069e0a03cSPaolo Bonzini
148169e0a03cSPaolo Bonzini {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false,
148269e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
148369e0a03cSPaolo Bonzini {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false,
148469e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
148569e0a03cSPaolo Bonzini
148669e0a03cSPaolo Bonzini {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
148769e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
148869e0a03cSPaolo Bonzini {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
148969e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
149069e0a03cSPaolo Bonzini {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
149169e0a03cSPaolo Bonzini decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
149269e0a03cSPaolo Bonzini {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
149369e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
149469e0a03cSPaolo Bonzini {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
149569e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
149669e0a03cSPaolo Bonzini {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
149769e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
149869e0a03cSPaolo Bonzini {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
149969e0a03cSPaolo Bonzini RFLAGS_MASK_NONE},
150069e0a03cSPaolo Bonzini {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
150169e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
150269e0a03cSPaolo Bonzini {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0,
150369e0a03cSPaolo Bonzini decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
150469e0a03cSPaolo Bonzini {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
150569e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
150669e0a03cSPaolo Bonzini {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
150769e0a03cSPaolo Bonzini RFLAGS_MASK_NONE},
150869e0a03cSPaolo Bonzini {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
150969e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
151069e0a03cSPaolo Bonzini {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
151169e0a03cSPaolo Bonzini RFLAGS_MASK_NONE},
151269e0a03cSPaolo Bonzini {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
151369e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
151469e0a03cSPaolo Bonzini
151569e0a03cSPaolo Bonzini {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
151669e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
151769e0a03cSPaolo Bonzini {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
151869e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
151969e0a03cSPaolo Bonzini {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
152069e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
152169e0a03cSPaolo Bonzini {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
152269e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
152369e0a03cSPaolo Bonzini {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
152469e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
152569e0a03cSPaolo Bonzini {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
152669e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
152769e0a03cSPaolo Bonzini {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
152869e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
152969e0a03cSPaolo Bonzini {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL,
153069e0a03cSPaolo Bonzini decode_db_4, RFLAGS_MASK_NONE},
153169e0a03cSPaolo Bonzini {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
153269e0a03cSPaolo Bonzini RFLAGS_MASK_NONE},
153369e0a03cSPaolo Bonzini {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false,
153469e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
153569e0a03cSPaolo Bonzini {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false,
153669e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
153769e0a03cSPaolo Bonzini {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true,
153869e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
153969e0a03cSPaolo Bonzini
154069e0a03cSPaolo Bonzini {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
154169e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
154269e0a03cSPaolo Bonzini {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false,
154369e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
154469e0a03cSPaolo Bonzini {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false,
154569e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
154669e0a03cSPaolo Bonzini {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false,
154769e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
154869e0a03cSPaolo Bonzini {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false,
154969e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
155069e0a03cSPaolo Bonzini {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false,
155169e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
155269e0a03cSPaolo Bonzini {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false,
155369e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
155469e0a03cSPaolo Bonzini {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false,
155569e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
155669e0a03cSPaolo Bonzini {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false,
155769e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
155869e0a03cSPaolo Bonzini {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false,
155969e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
156069e0a03cSPaolo Bonzini {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false,
156169e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
156269e0a03cSPaolo Bonzini {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false,
156369e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
156469e0a03cSPaolo Bonzini
156569e0a03cSPaolo Bonzini {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false,
156669e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
156769e0a03cSPaolo Bonzini {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
156869e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
156969e0a03cSPaolo Bonzini {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false,
157069e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
157169e0a03cSPaolo Bonzini {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false,
157269e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
157369e0a03cSPaolo Bonzini {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
157469e0a03cSPaolo Bonzini decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
157569e0a03cSPaolo Bonzini {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true,
157669e0a03cSPaolo Bonzini decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
157769e0a03cSPaolo Bonzini {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false,
157869e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
157969e0a03cSPaolo Bonzini {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false,
158069e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
158169e0a03cSPaolo Bonzini {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true,
158269e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
158369e0a03cSPaolo Bonzini {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false,
158469e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
158569e0a03cSPaolo Bonzini {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false,
158669e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
158769e0a03cSPaolo Bonzini
158869e0a03cSPaolo Bonzini {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true,
158969e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
159069e0a03cSPaolo Bonzini {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false,
159169e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
159269e0a03cSPaolo Bonzini {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true,
159369e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
159469e0a03cSPaolo Bonzini {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false,
159569e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
159669e0a03cSPaolo Bonzini {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true,
159769e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
159869e0a03cSPaolo Bonzini {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false,
159969e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
160069e0a03cSPaolo Bonzini {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true,
160169e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
160269e0a03cSPaolo Bonzini {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false,
160369e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
160469e0a03cSPaolo Bonzini {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true,
160569e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
160669e0a03cSPaolo Bonzini {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false,
160769e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
160869e0a03cSPaolo Bonzini {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true,
160969e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
161069e0a03cSPaolo Bonzini {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false,
161169e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
161269e0a03cSPaolo Bonzini
161369e0a03cSPaolo Bonzini {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false,
161469e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
161569e0a03cSPaolo Bonzini {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
161669e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
161769e0a03cSPaolo Bonzini {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true,
161869e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
161969e0a03cSPaolo Bonzini {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false,
162069e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
162169e0a03cSPaolo Bonzini {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
162269e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
162369e0a03cSPaolo Bonzini {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true,
162469e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
162569e0a03cSPaolo Bonzini {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true,
162669e0a03cSPaolo Bonzini decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
162769e0a03cSPaolo Bonzini {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true,
162869e0a03cSPaolo Bonzini decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
162969e0a03cSPaolo Bonzini {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false,
163069e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
163169e0a03cSPaolo Bonzini {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true,
163269e0a03cSPaolo Bonzini decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
163369e0a03cSPaolo Bonzini };
163469e0a03cSPaolo Bonzini
calc_modrm_operand16(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)163569e0a03cSPaolo Bonzini void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
163669e0a03cSPaolo Bonzini struct x86_decode_op *op)
163769e0a03cSPaolo Bonzini {
1638ff2de166SPaolo Bonzini target_ulong ptr = 0;
16396701d81dSPaolo Bonzini X86Seg seg = R_DS;
164069e0a03cSPaolo Bonzini
164169e0a03cSPaolo Bonzini if (!decode->modrm.mod && 6 == decode->modrm.rm) {
16421edead0fSRoman Bolshakov ptr = decode->displacement;
164369e0a03cSPaolo Bonzini goto calc_addr;
164469e0a03cSPaolo Bonzini }
164569e0a03cSPaolo Bonzini
164669e0a03cSPaolo Bonzini if (decode->displacement_size) {
164769e0a03cSPaolo Bonzini ptr = sign(decode->displacement, decode->displacement_size);
164869e0a03cSPaolo Bonzini }
164969e0a03cSPaolo Bonzini
165069e0a03cSPaolo Bonzini switch (decode->modrm.rm) {
165169e0a03cSPaolo Bonzini case 0:
165269e0a03cSPaolo Bonzini ptr += BX(env) + SI(env);
165369e0a03cSPaolo Bonzini break;
165469e0a03cSPaolo Bonzini case 1:
165569e0a03cSPaolo Bonzini ptr += BX(env) + DI(env);
165669e0a03cSPaolo Bonzini break;
165769e0a03cSPaolo Bonzini case 2:
165869e0a03cSPaolo Bonzini ptr += BP(env) + SI(env);
16596701d81dSPaolo Bonzini seg = R_SS;
166069e0a03cSPaolo Bonzini break;
166169e0a03cSPaolo Bonzini case 3:
166269e0a03cSPaolo Bonzini ptr += BP(env) + DI(env);
16636701d81dSPaolo Bonzini seg = R_SS;
166469e0a03cSPaolo Bonzini break;
166569e0a03cSPaolo Bonzini case 4:
166669e0a03cSPaolo Bonzini ptr += SI(env);
166769e0a03cSPaolo Bonzini break;
166869e0a03cSPaolo Bonzini case 5:
166969e0a03cSPaolo Bonzini ptr += DI(env);
167069e0a03cSPaolo Bonzini break;
167169e0a03cSPaolo Bonzini case 6:
167269e0a03cSPaolo Bonzini ptr += BP(env);
16736701d81dSPaolo Bonzini seg = R_SS;
167469e0a03cSPaolo Bonzini break;
167569e0a03cSPaolo Bonzini case 7:
167669e0a03cSPaolo Bonzini ptr += BX(env);
167769e0a03cSPaolo Bonzini break;
167869e0a03cSPaolo Bonzini }
167969e0a03cSPaolo Bonzini calc_addr:
168069e0a03cSPaolo Bonzini if (X86_DECODE_CMD_LEA == decode->cmd) {
168169e0a03cSPaolo Bonzini op->ptr = (uint16_t)ptr;
168269e0a03cSPaolo Bonzini } else {
168369e0a03cSPaolo Bonzini op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
168469e0a03cSPaolo Bonzini }
168569e0a03cSPaolo Bonzini }
168669e0a03cSPaolo Bonzini
get_reg_ref(CPUX86State * env,int reg,int rex_present,int is_extended,int size)16878c3b0e9eSCameron Esfahani target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
16888c3b0e9eSCameron Esfahani int is_extended, int size)
168969e0a03cSPaolo Bonzini {
1690ff2de166SPaolo Bonzini target_ulong ptr = 0;
169169e0a03cSPaolo Bonzini
169269e0a03cSPaolo Bonzini if (is_extended) {
16936701d81dSPaolo Bonzini reg |= R_R8;
169469e0a03cSPaolo Bonzini }
169569e0a03cSPaolo Bonzini
169669e0a03cSPaolo Bonzini switch (size) {
169769e0a03cSPaolo Bonzini case 1:
16988c3b0e9eSCameron Esfahani if (is_extended || reg < 4 || rex_present) {
1699ff2de166SPaolo Bonzini ptr = (target_ulong)&RL(env, reg);
170069e0a03cSPaolo Bonzini } else {
1701ff2de166SPaolo Bonzini ptr = (target_ulong)&RH(env, reg - 4);
170269e0a03cSPaolo Bonzini }
170369e0a03cSPaolo Bonzini break;
170469e0a03cSPaolo Bonzini default:
1705ff2de166SPaolo Bonzini ptr = (target_ulong)&RRX(env, reg);
170669e0a03cSPaolo Bonzini break;
170769e0a03cSPaolo Bonzini }
170869e0a03cSPaolo Bonzini return ptr;
170969e0a03cSPaolo Bonzini }
171069e0a03cSPaolo Bonzini
get_reg_val(CPUX86State * env,int reg,int rex_present,int is_extended,int size)17118c3b0e9eSCameron Esfahani target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
17128c3b0e9eSCameron Esfahani int is_extended, int size)
171369e0a03cSPaolo Bonzini {
1714ff2de166SPaolo Bonzini target_ulong val = 0;
17158c3b0e9eSCameron Esfahani memcpy(&val,
17168c3b0e9eSCameron Esfahani (void *)get_reg_ref(env, reg, rex_present, is_extended, size),
17178c3b0e9eSCameron Esfahani size);
171869e0a03cSPaolo Bonzini return val;
171969e0a03cSPaolo Bonzini }
172069e0a03cSPaolo Bonzini
get_sib_val(CPUX86State * env,struct x86_decode * decode,X86Seg * sel)1721ff2de166SPaolo Bonzini static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode,
17226701d81dSPaolo Bonzini X86Seg *sel)
172369e0a03cSPaolo Bonzini {
1724ff2de166SPaolo Bonzini target_ulong base = 0;
1725ff2de166SPaolo Bonzini target_ulong scaled_index = 0;
172669e0a03cSPaolo Bonzini int addr_size = decode->addressing_size;
172769e0a03cSPaolo Bonzini int base_reg = decode->sib.base;
172869e0a03cSPaolo Bonzini int index_reg = decode->sib.index;
172969e0a03cSPaolo Bonzini
17306701d81dSPaolo Bonzini *sel = R_DS;
173169e0a03cSPaolo Bonzini
17326701d81dSPaolo Bonzini if (decode->modrm.mod || base_reg != R_EBP) {
173369e0a03cSPaolo Bonzini if (decode->rex.b) {
17346701d81dSPaolo Bonzini base_reg |= R_R8;
173569e0a03cSPaolo Bonzini }
17366701d81dSPaolo Bonzini if (base_reg == R_ESP || base_reg == R_EBP) {
17376701d81dSPaolo Bonzini *sel = R_SS;
173869e0a03cSPaolo Bonzini }
1739b4e1af89SRoman Bolshakov base = get_reg_val(env, decode->sib.base, decode->rex.rex,
1740b4e1af89SRoman Bolshakov decode->rex.b, addr_size);
174169e0a03cSPaolo Bonzini }
174269e0a03cSPaolo Bonzini
174369e0a03cSPaolo Bonzini if (decode->rex.x) {
17446701d81dSPaolo Bonzini index_reg |= R_R8;
174569e0a03cSPaolo Bonzini }
174669e0a03cSPaolo Bonzini
17476701d81dSPaolo Bonzini if (index_reg != R_ESP) {
1748b4e1af89SRoman Bolshakov scaled_index = get_reg_val(env, index_reg, decode->rex.rex,
1749b4e1af89SRoman Bolshakov decode->rex.x, addr_size) <<
175069e0a03cSPaolo Bonzini decode->sib.scale;
175169e0a03cSPaolo Bonzini }
175269e0a03cSPaolo Bonzini return base + scaled_index;
175369e0a03cSPaolo Bonzini }
175469e0a03cSPaolo Bonzini
calc_modrm_operand32(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)175569e0a03cSPaolo Bonzini void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
175669e0a03cSPaolo Bonzini struct x86_decode_op *op)
175769e0a03cSPaolo Bonzini {
17586701d81dSPaolo Bonzini X86Seg seg = R_DS;
1759ff2de166SPaolo Bonzini target_ulong ptr = 0;
176069e0a03cSPaolo Bonzini int addr_size = decode->addressing_size;
176169e0a03cSPaolo Bonzini
176269e0a03cSPaolo Bonzini if (decode->displacement_size) {
176369e0a03cSPaolo Bonzini ptr = sign(decode->displacement, decode->displacement_size);
176469e0a03cSPaolo Bonzini }
176569e0a03cSPaolo Bonzini
176669e0a03cSPaolo Bonzini if (4 == decode->modrm.rm) {
176769e0a03cSPaolo Bonzini ptr += get_sib_val(env, decode, &seg);
176869e0a03cSPaolo Bonzini } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
176929a0af61SRichard Henderson if (x86_is_long_mode(env_cpu(env))) {
17705d32173fSRoman Bolshakov ptr += env->eip + decode->len;
177169e0a03cSPaolo Bonzini } else {
177269e0a03cSPaolo Bonzini ptr = decode->displacement;
177369e0a03cSPaolo Bonzini }
177469e0a03cSPaolo Bonzini } else {
17756701d81dSPaolo Bonzini if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) {
17766701d81dSPaolo Bonzini seg = R_SS;
177769e0a03cSPaolo Bonzini }
1778b4e1af89SRoman Bolshakov ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex,
1779b4e1af89SRoman Bolshakov decode->rex.b, addr_size);
178069e0a03cSPaolo Bonzini }
178169e0a03cSPaolo Bonzini
178269e0a03cSPaolo Bonzini if (X86_DECODE_CMD_LEA == decode->cmd) {
178369e0a03cSPaolo Bonzini op->ptr = (uint32_t)ptr;
178469e0a03cSPaolo Bonzini } else {
178569e0a03cSPaolo Bonzini op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
178669e0a03cSPaolo Bonzini }
178769e0a03cSPaolo Bonzini }
178869e0a03cSPaolo Bonzini
calc_modrm_operand64(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)178969e0a03cSPaolo Bonzini void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
179069e0a03cSPaolo Bonzini struct x86_decode_op *op)
179169e0a03cSPaolo Bonzini {
17926701d81dSPaolo Bonzini X86Seg seg = R_DS;
179369e0a03cSPaolo Bonzini int32_t offset = 0;
179469e0a03cSPaolo Bonzini int mod = decode->modrm.mod;
179569e0a03cSPaolo Bonzini int rm = decode->modrm.rm;
1796ff2de166SPaolo Bonzini target_ulong ptr;
179769e0a03cSPaolo Bonzini int src = decode->modrm.rm;
179869e0a03cSPaolo Bonzini
179969e0a03cSPaolo Bonzini if (decode->displacement_size) {
180069e0a03cSPaolo Bonzini offset = sign(decode->displacement, decode->displacement_size);
180169e0a03cSPaolo Bonzini }
180269e0a03cSPaolo Bonzini
180369e0a03cSPaolo Bonzini if (4 == rm) {
180469e0a03cSPaolo Bonzini ptr = get_sib_val(env, decode, &seg) + offset;
180569e0a03cSPaolo Bonzini } else if (0 == mod && 5 == rm) {
18065d32173fSRoman Bolshakov ptr = env->eip + decode->len + (int32_t) offset;
180769e0a03cSPaolo Bonzini } else {
1808b4e1af89SRoman Bolshakov ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) +
1809b4e1af89SRoman Bolshakov (int64_t) offset;
181069e0a03cSPaolo Bonzini }
181169e0a03cSPaolo Bonzini
181269e0a03cSPaolo Bonzini if (X86_DECODE_CMD_LEA == decode->cmd) {
181369e0a03cSPaolo Bonzini op->ptr = ptr;
181469e0a03cSPaolo Bonzini } else {
181569e0a03cSPaolo Bonzini op->ptr = decode_linear_addr(env, decode, ptr, seg);
181669e0a03cSPaolo Bonzini }
181769e0a03cSPaolo Bonzini }
181869e0a03cSPaolo Bonzini
181969e0a03cSPaolo Bonzini
calc_modrm_operand(CPUX86State * env,struct x86_decode * decode,struct x86_decode_op * op)182069e0a03cSPaolo Bonzini void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
182169e0a03cSPaolo Bonzini struct x86_decode_op *op)
182269e0a03cSPaolo Bonzini {
182369e0a03cSPaolo Bonzini if (3 == decode->modrm.mod) {
182469e0a03cSPaolo Bonzini op->reg = decode->modrm.reg;
182569e0a03cSPaolo Bonzini op->type = X86_VAR_REG;
1826b4e1af89SRoman Bolshakov op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
1827b4e1af89SRoman Bolshakov decode->rex.b, decode->operand_size);
182869e0a03cSPaolo Bonzini return;
182969e0a03cSPaolo Bonzini }
183069e0a03cSPaolo Bonzini
183169e0a03cSPaolo Bonzini switch (decode->addressing_size) {
183269e0a03cSPaolo Bonzini case 2:
183369e0a03cSPaolo Bonzini calc_modrm_operand16(env, decode, op);
183469e0a03cSPaolo Bonzini break;
183569e0a03cSPaolo Bonzini case 4:
183669e0a03cSPaolo Bonzini calc_modrm_operand32(env, decode, op);
183769e0a03cSPaolo Bonzini break;
183869e0a03cSPaolo Bonzini case 8:
183969e0a03cSPaolo Bonzini calc_modrm_operand64(env, decode, op);
184069e0a03cSPaolo Bonzini break;
184169e0a03cSPaolo Bonzini default:
184269e0a03cSPaolo Bonzini VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
184369e0a03cSPaolo Bonzini break;
184469e0a03cSPaolo Bonzini }
184569e0a03cSPaolo Bonzini }
184669e0a03cSPaolo Bonzini
decode_prefix(CPUX86State * env,struct x86_decode * decode)184769e0a03cSPaolo Bonzini static void decode_prefix(CPUX86State *env, struct x86_decode *decode)
184869e0a03cSPaolo Bonzini {
184969e0a03cSPaolo Bonzini while (1) {
18508c3b0e9eSCameron Esfahani /*
18518c3b0e9eSCameron Esfahani * REX prefix must come after legacy prefixes.
18528c3b0e9eSCameron Esfahani * REX before legacy is ignored.
18538c3b0e9eSCameron Esfahani * Clear rex to simulate this.
18548c3b0e9eSCameron Esfahani */
185569e0a03cSPaolo Bonzini uint8_t byte = decode_byte(env, decode);
185669e0a03cSPaolo Bonzini switch (byte) {
185769e0a03cSPaolo Bonzini case PREFIX_LOCK:
185869e0a03cSPaolo Bonzini decode->lock = byte;
18598c3b0e9eSCameron Esfahani decode->rex.rex = 0;
186069e0a03cSPaolo Bonzini break;
186169e0a03cSPaolo Bonzini case PREFIX_REPN:
186269e0a03cSPaolo Bonzini case PREFIX_REP:
186369e0a03cSPaolo Bonzini decode->rep = byte;
18648c3b0e9eSCameron Esfahani decode->rex.rex = 0;
186569e0a03cSPaolo Bonzini break;
18668c3b0e9eSCameron Esfahani case PREFIX_CS_SEG_OVERRIDE:
18678c3b0e9eSCameron Esfahani case PREFIX_SS_SEG_OVERRIDE:
18688c3b0e9eSCameron Esfahani case PREFIX_DS_SEG_OVERRIDE:
18698c3b0e9eSCameron Esfahani case PREFIX_ES_SEG_OVERRIDE:
18708c3b0e9eSCameron Esfahani case PREFIX_FS_SEG_OVERRIDE:
18718c3b0e9eSCameron Esfahani case PREFIX_GS_SEG_OVERRIDE:
187269e0a03cSPaolo Bonzini decode->segment_override = byte;
18738c3b0e9eSCameron Esfahani decode->rex.rex = 0;
187469e0a03cSPaolo Bonzini break;
187569e0a03cSPaolo Bonzini case PREFIX_OP_SIZE_OVERRIDE:
187669e0a03cSPaolo Bonzini decode->op_size_override = byte;
18778c3b0e9eSCameron Esfahani decode->rex.rex = 0;
187869e0a03cSPaolo Bonzini break;
187969e0a03cSPaolo Bonzini case PREFIX_ADDR_SIZE_OVERRIDE:
188069e0a03cSPaolo Bonzini decode->addr_size_override = byte;
18818c3b0e9eSCameron Esfahani decode->rex.rex = 0;
188269e0a03cSPaolo Bonzini break;
188369e0a03cSPaolo Bonzini case PREFIX_REX ... (PREFIX_REX + 0xf):
188429a0af61SRichard Henderson if (x86_is_long_mode(env_cpu(env))) {
188569e0a03cSPaolo Bonzini decode->rex.rex = byte;
188669e0a03cSPaolo Bonzini break;
188769e0a03cSPaolo Bonzini }
188869e0a03cSPaolo Bonzini /* fall through when not in long mode */
188969e0a03cSPaolo Bonzini default:
189069e0a03cSPaolo Bonzini decode->len--;
189169e0a03cSPaolo Bonzini return;
189269e0a03cSPaolo Bonzini }
189369e0a03cSPaolo Bonzini }
189469e0a03cSPaolo Bonzini }
189569e0a03cSPaolo Bonzini
set_addressing_size(CPUX86State * env,struct x86_decode * decode)189669e0a03cSPaolo Bonzini void set_addressing_size(CPUX86State *env, struct x86_decode *decode)
189769e0a03cSPaolo Bonzini {
189869e0a03cSPaolo Bonzini decode->addressing_size = -1;
189929a0af61SRichard Henderson if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
190069e0a03cSPaolo Bonzini if (decode->addr_size_override) {
190169e0a03cSPaolo Bonzini decode->addressing_size = 4;
190269e0a03cSPaolo Bonzini } else {
190369e0a03cSPaolo Bonzini decode->addressing_size = 2;
190469e0a03cSPaolo Bonzini }
190529a0af61SRichard Henderson } else if (!x86_is_long_mode(env_cpu(env))) {
190669e0a03cSPaolo Bonzini /* protected */
190769e0a03cSPaolo Bonzini struct vmx_segment cs;
190829a0af61SRichard Henderson vmx_read_segment_descriptor(env_cpu(env), &cs, R_CS);
190969e0a03cSPaolo Bonzini /* check db */
191069e0a03cSPaolo Bonzini if ((cs.ar >> 14) & 1) {
191169e0a03cSPaolo Bonzini if (decode->addr_size_override) {
191269e0a03cSPaolo Bonzini decode->addressing_size = 2;
191369e0a03cSPaolo Bonzini } else {
191469e0a03cSPaolo Bonzini decode->addressing_size = 4;
191569e0a03cSPaolo Bonzini }
191669e0a03cSPaolo Bonzini } else {
191769e0a03cSPaolo Bonzini if (decode->addr_size_override) {
191869e0a03cSPaolo Bonzini decode->addressing_size = 4;
191969e0a03cSPaolo Bonzini } else {
192069e0a03cSPaolo Bonzini decode->addressing_size = 2;
192169e0a03cSPaolo Bonzini }
192269e0a03cSPaolo Bonzini }
192369e0a03cSPaolo Bonzini } else {
192469e0a03cSPaolo Bonzini /* long */
192569e0a03cSPaolo Bonzini if (decode->addr_size_override) {
192669e0a03cSPaolo Bonzini decode->addressing_size = 4;
192769e0a03cSPaolo Bonzini } else {
192869e0a03cSPaolo Bonzini decode->addressing_size = 8;
192969e0a03cSPaolo Bonzini }
193069e0a03cSPaolo Bonzini }
193169e0a03cSPaolo Bonzini }
193269e0a03cSPaolo Bonzini
set_operand_size(CPUX86State * env,struct x86_decode * decode)193369e0a03cSPaolo Bonzini void set_operand_size(CPUX86State *env, struct x86_decode *decode)
193469e0a03cSPaolo Bonzini {
193569e0a03cSPaolo Bonzini decode->operand_size = -1;
193629a0af61SRichard Henderson if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
193769e0a03cSPaolo Bonzini if (decode->op_size_override) {
193869e0a03cSPaolo Bonzini decode->operand_size = 4;
193969e0a03cSPaolo Bonzini } else {
194069e0a03cSPaolo Bonzini decode->operand_size = 2;
194169e0a03cSPaolo Bonzini }
194229a0af61SRichard Henderson } else if (!x86_is_long_mode(env_cpu(env))) {
194369e0a03cSPaolo Bonzini /* protected */
194469e0a03cSPaolo Bonzini struct vmx_segment cs;
194529a0af61SRichard Henderson vmx_read_segment_descriptor(env_cpu(env), &cs, R_CS);
194669e0a03cSPaolo Bonzini /* check db */
194769e0a03cSPaolo Bonzini if ((cs.ar >> 14) & 1) {
194869e0a03cSPaolo Bonzini if (decode->op_size_override) {
194969e0a03cSPaolo Bonzini decode->operand_size = 2;
195069e0a03cSPaolo Bonzini } else{
195169e0a03cSPaolo Bonzini decode->operand_size = 4;
195269e0a03cSPaolo Bonzini }
195369e0a03cSPaolo Bonzini } else {
195469e0a03cSPaolo Bonzini if (decode->op_size_override) {
195569e0a03cSPaolo Bonzini decode->operand_size = 4;
195669e0a03cSPaolo Bonzini } else {
195769e0a03cSPaolo Bonzini decode->operand_size = 2;
195869e0a03cSPaolo Bonzini }
195969e0a03cSPaolo Bonzini }
196069e0a03cSPaolo Bonzini } else {
196169e0a03cSPaolo Bonzini /* long */
196269e0a03cSPaolo Bonzini if (decode->op_size_override) {
196369e0a03cSPaolo Bonzini decode->operand_size = 2;
196469e0a03cSPaolo Bonzini } else {
196569e0a03cSPaolo Bonzini decode->operand_size = 4;
196669e0a03cSPaolo Bonzini }
196769e0a03cSPaolo Bonzini
196869e0a03cSPaolo Bonzini if (decode->rex.w) {
196969e0a03cSPaolo Bonzini decode->operand_size = 8;
197069e0a03cSPaolo Bonzini }
197169e0a03cSPaolo Bonzini }
197269e0a03cSPaolo Bonzini }
197369e0a03cSPaolo Bonzini
decode_sib(CPUX86State * env,struct x86_decode * decode)197469e0a03cSPaolo Bonzini static void decode_sib(CPUX86State *env, struct x86_decode *decode)
197569e0a03cSPaolo Bonzini {
197669e0a03cSPaolo Bonzini if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
197769e0a03cSPaolo Bonzini (decode->addressing_size != 2)) {
197869e0a03cSPaolo Bonzini decode->sib.sib = decode_byte(env, decode);
197969e0a03cSPaolo Bonzini decode->sib_present = true;
198069e0a03cSPaolo Bonzini }
198169e0a03cSPaolo Bonzini }
198269e0a03cSPaolo Bonzini
198369e0a03cSPaolo Bonzini /* 16 bit modrm */
198469e0a03cSPaolo Bonzini int disp16_tbl[4][8] = {
198569e0a03cSPaolo Bonzini {0, 0, 0, 0, 0, 0, 2, 0},
198669e0a03cSPaolo Bonzini {1, 1, 1, 1, 1, 1, 1, 1},
198769e0a03cSPaolo Bonzini {2, 2, 2, 2, 2, 2, 2, 2},
198869e0a03cSPaolo Bonzini {0, 0, 0, 0, 0, 0, 0, 0}
198969e0a03cSPaolo Bonzini };
199069e0a03cSPaolo Bonzini
199169e0a03cSPaolo Bonzini /* 32/64-bit modrm */
199269e0a03cSPaolo Bonzini int disp32_tbl[4][8] = {
199369e0a03cSPaolo Bonzini {0, 0, 0, 0, -1, 4, 0, 0},
199469e0a03cSPaolo Bonzini {1, 1, 1, 1, 1, 1, 1, 1},
199569e0a03cSPaolo Bonzini {4, 4, 4, 4, 4, 4, 4, 4},
199669e0a03cSPaolo Bonzini {0, 0, 0, 0, 0, 0, 0, 0}
199769e0a03cSPaolo Bonzini };
199869e0a03cSPaolo Bonzini
decode_displacement(CPUX86State * env,struct x86_decode * decode)199969e0a03cSPaolo Bonzini static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode)
200069e0a03cSPaolo Bonzini {
200169e0a03cSPaolo Bonzini int addressing_size = decode->addressing_size;
200269e0a03cSPaolo Bonzini int mod = decode->modrm.mod;
200369e0a03cSPaolo Bonzini int rm = decode->modrm.rm;
200469e0a03cSPaolo Bonzini
200569e0a03cSPaolo Bonzini decode->displacement_size = 0;
200669e0a03cSPaolo Bonzini switch (addressing_size) {
200769e0a03cSPaolo Bonzini case 2:
200869e0a03cSPaolo Bonzini decode->displacement_size = disp16_tbl[mod][rm];
200969e0a03cSPaolo Bonzini if (decode->displacement_size) {
201069e0a03cSPaolo Bonzini decode->displacement = (uint16_t)decode_bytes(env, decode,
201169e0a03cSPaolo Bonzini decode->displacement_size);
201269e0a03cSPaolo Bonzini }
201369e0a03cSPaolo Bonzini break;
201469e0a03cSPaolo Bonzini case 4:
201569e0a03cSPaolo Bonzini case 8:
201669e0a03cSPaolo Bonzini if (-1 == disp32_tbl[mod][rm]) {
201769e0a03cSPaolo Bonzini if (5 == decode->sib.base) {
201869e0a03cSPaolo Bonzini decode->displacement_size = 4;
201969e0a03cSPaolo Bonzini }
202069e0a03cSPaolo Bonzini } else {
202169e0a03cSPaolo Bonzini decode->displacement_size = disp32_tbl[mod][rm];
202269e0a03cSPaolo Bonzini }
202369e0a03cSPaolo Bonzini
202469e0a03cSPaolo Bonzini if (decode->displacement_size) {
202569e0a03cSPaolo Bonzini decode->displacement = (uint32_t)decode_bytes(env, decode,
202669e0a03cSPaolo Bonzini decode->displacement_size);
202769e0a03cSPaolo Bonzini }
202869e0a03cSPaolo Bonzini break;
202969e0a03cSPaolo Bonzini }
203069e0a03cSPaolo Bonzini }
203169e0a03cSPaolo Bonzini
decode_modrm(CPUX86State * env,struct x86_decode * decode)203269e0a03cSPaolo Bonzini static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode)
203369e0a03cSPaolo Bonzini {
203469e0a03cSPaolo Bonzini decode->modrm.modrm = decode_byte(env, decode);
203569e0a03cSPaolo Bonzini decode->is_modrm = true;
203669e0a03cSPaolo Bonzini
203769e0a03cSPaolo Bonzini decode_sib(env, decode);
203869e0a03cSPaolo Bonzini decode_displacement(env, decode);
203969e0a03cSPaolo Bonzini }
204069e0a03cSPaolo Bonzini
decode_opcode_general(CPUX86State * env,struct x86_decode * decode,uint8_t opcode,struct decode_tbl * inst_decoder)204169e0a03cSPaolo Bonzini static inline void decode_opcode_general(CPUX86State *env,
204269e0a03cSPaolo Bonzini struct x86_decode *decode,
204369e0a03cSPaolo Bonzini uint8_t opcode,
204469e0a03cSPaolo Bonzini struct decode_tbl *inst_decoder)
204569e0a03cSPaolo Bonzini {
204669e0a03cSPaolo Bonzini decode->cmd = inst_decoder->cmd;
204769e0a03cSPaolo Bonzini if (inst_decoder->operand_size) {
204869e0a03cSPaolo Bonzini decode->operand_size = inst_decoder->operand_size;
204969e0a03cSPaolo Bonzini }
205069e0a03cSPaolo Bonzini decode->flags_mask = inst_decoder->flags_mask;
205169e0a03cSPaolo Bonzini
205269e0a03cSPaolo Bonzini if (inst_decoder->is_modrm) {
205369e0a03cSPaolo Bonzini decode_modrm(env, decode);
205469e0a03cSPaolo Bonzini }
205569e0a03cSPaolo Bonzini if (inst_decoder->decode_op1) {
205669e0a03cSPaolo Bonzini inst_decoder->decode_op1(env, decode, &decode->op[0]);
205769e0a03cSPaolo Bonzini }
205869e0a03cSPaolo Bonzini if (inst_decoder->decode_op2) {
205969e0a03cSPaolo Bonzini inst_decoder->decode_op2(env, decode, &decode->op[1]);
206069e0a03cSPaolo Bonzini }
206169e0a03cSPaolo Bonzini if (inst_decoder->decode_op3) {
206269e0a03cSPaolo Bonzini inst_decoder->decode_op3(env, decode, &decode->op[2]);
206369e0a03cSPaolo Bonzini }
206469e0a03cSPaolo Bonzini if (inst_decoder->decode_op4) {
206569e0a03cSPaolo Bonzini inst_decoder->decode_op4(env, decode, &decode->op[3]);
206669e0a03cSPaolo Bonzini }
206769e0a03cSPaolo Bonzini if (inst_decoder->decode_postfix) {
206869e0a03cSPaolo Bonzini inst_decoder->decode_postfix(env, decode);
206969e0a03cSPaolo Bonzini }
207069e0a03cSPaolo Bonzini }
207169e0a03cSPaolo Bonzini
decode_opcode_1(CPUX86State * env,struct x86_decode * decode,uint8_t opcode)207269e0a03cSPaolo Bonzini static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode,
207369e0a03cSPaolo Bonzini uint8_t opcode)
207469e0a03cSPaolo Bonzini {
207569e0a03cSPaolo Bonzini struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
207669e0a03cSPaolo Bonzini decode_opcode_general(env, decode, opcode, inst_decoder);
207769e0a03cSPaolo Bonzini }
207869e0a03cSPaolo Bonzini
207969e0a03cSPaolo Bonzini
decode_opcode_2(CPUX86State * env,struct x86_decode * decode,uint8_t opcode)208069e0a03cSPaolo Bonzini static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode,
208169e0a03cSPaolo Bonzini uint8_t opcode)
208269e0a03cSPaolo Bonzini {
208369e0a03cSPaolo Bonzini struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
208469e0a03cSPaolo Bonzini decode_opcode_general(env, decode, opcode, inst_decoder);
208569e0a03cSPaolo Bonzini }
208669e0a03cSPaolo Bonzini
decode_opcodes(CPUX86State * env,struct x86_decode * decode)208769e0a03cSPaolo Bonzini static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
208869e0a03cSPaolo Bonzini {
208969e0a03cSPaolo Bonzini uint8_t opcode;
209069e0a03cSPaolo Bonzini
209169e0a03cSPaolo Bonzini opcode = decode_byte(env, decode);
209269e0a03cSPaolo Bonzini decode->opcode[decode->opcode_len++] = opcode;
209369e0a03cSPaolo Bonzini if (opcode != OPCODE_ESCAPE) {
209469e0a03cSPaolo Bonzini decode_opcode_1(env, decode, opcode);
209569e0a03cSPaolo Bonzini } else {
209669e0a03cSPaolo Bonzini opcode = decode_byte(env, decode);
209769e0a03cSPaolo Bonzini decode->opcode[decode->opcode_len++] = opcode;
209869e0a03cSPaolo Bonzini decode_opcode_2(env, decode, opcode);
209969e0a03cSPaolo Bonzini }
210069e0a03cSPaolo Bonzini }
210169e0a03cSPaolo Bonzini
decode_instruction(CPUX86State * env,struct x86_decode * decode)210269e0a03cSPaolo Bonzini uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
210369e0a03cSPaolo Bonzini {
2104715f396dSPaolo Bonzini memset(decode, 0, sizeof(*decode));
210569e0a03cSPaolo Bonzini decode_prefix(env, decode);
210669e0a03cSPaolo Bonzini set_addressing_size(env, decode);
210769e0a03cSPaolo Bonzini set_operand_size(env, decode);
210869e0a03cSPaolo Bonzini
210969e0a03cSPaolo Bonzini decode_opcodes(env, decode);
211069e0a03cSPaolo Bonzini
211169e0a03cSPaolo Bonzini return decode->len;
211269e0a03cSPaolo Bonzini }
211369e0a03cSPaolo Bonzini
init_decoder(void)2114*0e4e622eSPhil Dennis-Jordan void init_decoder(void)
211569e0a03cSPaolo Bonzini {
211669e0a03cSPaolo Bonzini int i;
211769e0a03cSPaolo Bonzini
21188c3b0e9eSCameron Esfahani for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) {
21198c3b0e9eSCameron Esfahani memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst));
212069e0a03cSPaolo Bonzini }
212169e0a03cSPaolo Bonzini for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
21228c3b0e9eSCameron Esfahani memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst));
212369e0a03cSPaolo Bonzini }
212469e0a03cSPaolo Bonzini for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
21258c3b0e9eSCameron Esfahani memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87));
212669e0a03cSPaolo Bonzini
212769e0a03cSPaolo Bonzini }
212869e0a03cSPaolo Bonzini for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
212969e0a03cSPaolo Bonzini _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
213069e0a03cSPaolo Bonzini }
213169e0a03cSPaolo Bonzini for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) {
213269e0a03cSPaolo Bonzini _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i];
213369e0a03cSPaolo Bonzini }
213469e0a03cSPaolo Bonzini for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) {
213569e0a03cSPaolo Bonzini int index = ((_x87_inst[i].opcode & 0xf) << 4) |
213669e0a03cSPaolo Bonzini ((_x87_inst[i].modrm_mod & 1) << 3) |
213769e0a03cSPaolo Bonzini _x87_inst[i].modrm_reg;
213869e0a03cSPaolo Bonzini _decode_tbl3[index] = _x87_inst[i];
213969e0a03cSPaolo Bonzini }
214069e0a03cSPaolo Bonzini }
214169e0a03cSPaolo Bonzini
214269e0a03cSPaolo Bonzini
decode_cmd_to_string(enum x86_decode_cmd cmd)214369e0a03cSPaolo Bonzini const char *decode_cmd_to_string(enum x86_decode_cmd cmd)
214469e0a03cSPaolo Bonzini {
214569e0a03cSPaolo Bonzini static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG",
214669e0a03cSPaolo Bonzini "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT",
214769e0a03cSPaolo Bonzini "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD",
214869e0a03cSPaolo Bonzini "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST",
214969e0a03cSPaolo Bonzini "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR",
215069e0a03cSPaolo Bonzini "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG",
215169e0a03cSPaolo Bonzini "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN",
215269e0a03cSPaolo Bonzini "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW",
215369e0a03cSPaolo Bonzini "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR",
215469e0a03cSPaolo Bonzini "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR",
215569e0a03cSPaolo Bonzini "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL",
215669e0a03cSPaolo Bonzini "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS",
215769e0a03cSPaolo Bonzini "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT",
215869e0a03cSPaolo Bonzini "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA",
215969e0a03cSPaolo Bonzini "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT",
216069e0a03cSPaolo Bonzini "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES",
216169e0a03cSPaolo Bonzini "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT",
216269e0a03cSPaolo Bonzini "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW",
216369e0a03cSPaolo Bonzini "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV",
216469e0a03cSPaolo Bonzini "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE",
216569e0a03cSPaolo Bonzini "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW",
216669e0a03cSPaolo Bonzini "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"};
216769e0a03cSPaolo Bonzini return cmds[cmd];
216869e0a03cSPaolo Bonzini }
216969e0a03cSPaolo Bonzini
decode_linear_addr(CPUX86State * env,struct x86_decode * decode,target_ulong addr,X86Seg seg)2170ff2de166SPaolo Bonzini target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
2171ff2de166SPaolo Bonzini target_ulong addr, X86Seg seg)
217269e0a03cSPaolo Bonzini {
217369e0a03cSPaolo Bonzini switch (decode->segment_override) {
21748c3b0e9eSCameron Esfahani case PREFIX_CS_SEG_OVERRIDE:
21756701d81dSPaolo Bonzini seg = R_CS;
217669e0a03cSPaolo Bonzini break;
21778c3b0e9eSCameron Esfahani case PREFIX_SS_SEG_OVERRIDE:
21786701d81dSPaolo Bonzini seg = R_SS;
217969e0a03cSPaolo Bonzini break;
21808c3b0e9eSCameron Esfahani case PREFIX_DS_SEG_OVERRIDE:
21816701d81dSPaolo Bonzini seg = R_DS;
218269e0a03cSPaolo Bonzini break;
21838c3b0e9eSCameron Esfahani case PREFIX_ES_SEG_OVERRIDE:
21846701d81dSPaolo Bonzini seg = R_ES;
218569e0a03cSPaolo Bonzini break;
21868c3b0e9eSCameron Esfahani case PREFIX_FS_SEG_OVERRIDE:
21876701d81dSPaolo Bonzini seg = R_FS;
218869e0a03cSPaolo Bonzini break;
21898c3b0e9eSCameron Esfahani case PREFIX_GS_SEG_OVERRIDE:
21906701d81dSPaolo Bonzini seg = R_GS;
219169e0a03cSPaolo Bonzini break;
219269e0a03cSPaolo Bonzini default:
219369e0a03cSPaolo Bonzini break;
219469e0a03cSPaolo Bonzini }
219529a0af61SRichard Henderson return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg);
219669e0a03cSPaolo Bonzini }
2197