xref: /openbmc/qemu/target/i386/hvf/x86_decode.c (revision 3e246da2c3f85298b52f8a1154b832acf36aa656)
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