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