xref: /openbmc/qemu/target/i386/emulate/x86_decode.c (revision c901905ea6703a2feb5867537a8559dc129447f7)
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 
2727458df8SWei Liu static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
2827458df8SWei Liu {
2927458df8SWei Liu     printf("%llx: 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 
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 
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 
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 
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 
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 
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 
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 
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;
11227458df8SWei Liu     op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
11327458df8SWei Liu                           decode->operand_size);
11427458df8SWei Liu }
11527458df8SWei Liu 
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. */
12227458df8SWei Liu     op->ptr = get_reg_ref(env, op->reg, false, 0,
12327458df8SWei Liu                           decode->operand_size);
12427458df8SWei Liu }
12527458df8SWei Liu 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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;
26527458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
26627458df8SWei Liu                                     decode->rex.b, decode->operand_size);
26727458df8SWei Liu }
26827458df8SWei Liu 
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;
27327458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
27427458df8SWei Liu                                     decode->rex.b, decode->operand_size);
27527458df8SWei Liu }
27627458df8SWei Liu 
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 
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;
29027458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
29127458df8SWei Liu                                     decode->rex.b, decode->operand_size);
29227458df8SWei Liu }
29327458df8SWei Liu 
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;
29827458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
29927458df8SWei Liu                                     decode->rex.b, decode->operand_size);
30027458df8SWei Liu }
30127458df8SWei Liu 
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 
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 
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 
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 
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 
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;
38027458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
38127458df8SWei Liu                                     decode->rex.b, decode->operand_size);
38227458df8SWei Liu }
38327458df8SWei Liu 
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;
38827458df8SWei Liu     decode->op[0].ptr = 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 
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;
39727458df8SWei Liu     op->ptr = decode_bytes(env, decode, decode->addressing_size);
39827458df8SWei Liu }
39927458df8SWei Liu 
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;
40427458df8SWei Liu     decode->op[0].ptr = 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 
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;
41427458df8SWei Liu     op->ptr = 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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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;
63427458df8SWei Liu     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
63527458df8SWei Liu                                     decode->rex.b, decode->operand_size);
63627458df8SWei Liu }
63727458df8SWei Liu 
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 
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,
692*c901905eSPaolo Bonzini      NULL, NULL},
69327458df8SWei Liu     {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
694*c901905eSPaolo Bonzini      NULL, NULL},
69527458df8SWei Liu     {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
696*c901905eSPaolo Bonzini      NULL, NULL},
69727458df8SWei Liu     {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL,
698*c901905eSPaolo Bonzini      NULL, NULL},
69927458df8SWei Liu     {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL,
700*c901905eSPaolo Bonzini      NULL},
70127458df8SWei Liu     {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL,
702*c901905eSPaolo Bonzini      NULL},
70327458df8SWei Liu     {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL,
704*c901905eSPaolo Bonzini      decode_pushseg},
70527458df8SWei Liu     {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL,
706*c901905eSPaolo Bonzini      decode_popseg},
70727458df8SWei Liu     {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
708*c901905eSPaolo Bonzini      NULL, NULL},
70927458df8SWei Liu     {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
710*c901905eSPaolo Bonzini      NULL, NULL},
71127458df8SWei Liu     {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
712*c901905eSPaolo Bonzini      NULL, NULL},
71327458df8SWei Liu     {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm,
714*c901905eSPaolo Bonzini      NULL, NULL, NULL},
71527458df8SWei Liu     {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8,
716*c901905eSPaolo Bonzini      NULL, NULL, NULL},
71727458df8SWei Liu     {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm,
718*c901905eSPaolo Bonzini      NULL, NULL, NULL},
71927458df8SWei Liu 
72027458df8SWei Liu     {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
721*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
72227458df8SWei Liu     {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false,
723*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
72427458df8SWei Liu 
72527458df8SWei Liu     {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg,
726*c901905eSPaolo Bonzini      NULL, NULL, NULL},
72727458df8SWei Liu     {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg,
728*c901905eSPaolo Bonzini      NULL, NULL, NULL},
72927458df8SWei Liu     {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm,
730*c901905eSPaolo Bonzini      NULL, NULL, NULL},
73127458df8SWei Liu     {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm,
732*c901905eSPaolo Bonzini      NULL, NULL, NULL},
73327458df8SWei Liu     {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm,
734*c901905eSPaolo Bonzini      NULL, NULL, NULL},
73527458df8SWei Liu     {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm,
736*c901905eSPaolo Bonzini      NULL, NULL, NULL},
73727458df8SWei Liu 
73827458df8SWei Liu     {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
739*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
74027458df8SWei Liu     {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false,
741*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
74227458df8SWei Liu 
74327458df8SWei Liu     {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg,
744*c901905eSPaolo Bonzini      NULL, NULL, NULL},
74527458df8SWei Liu     {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg,
746*c901905eSPaolo Bonzini      NULL, NULL, NULL},
74727458df8SWei Liu     {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm,
748*c901905eSPaolo Bonzini      NULL, NULL, NULL},
74927458df8SWei Liu     {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm,
750*c901905eSPaolo Bonzini      NULL, NULL, NULL},
75127458df8SWei Liu     {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8,
752*c901905eSPaolo Bonzini      NULL, NULL, NULL},
75327458df8SWei Liu     {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm,
754*c901905eSPaolo Bonzini      NULL, NULL, NULL},
75527458df8SWei Liu 
75627458df8SWei Liu     {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
757*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
75827458df8SWei Liu     {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false,
759*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
76027458df8SWei Liu 
76127458df8SWei Liu     {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg,
762*c901905eSPaolo Bonzini      NULL, NULL, NULL},
76327458df8SWei Liu     {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg,
764*c901905eSPaolo Bonzini      NULL, NULL, NULL},
76527458df8SWei Liu     {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm,
766*c901905eSPaolo Bonzini      NULL, NULL, NULL},
76727458df8SWei Liu     {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm,
768*c901905eSPaolo Bonzini      NULL, NULL, NULL},
76927458df8SWei Liu     {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm,
770*c901905eSPaolo Bonzini      NULL, NULL, NULL},
77127458df8SWei Liu     {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm,
772*c901905eSPaolo Bonzini      NULL, NULL, NULL},
77327458df8SWei Liu     {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg,
774*c901905eSPaolo Bonzini      NULL, NULL, NULL},
77527458df8SWei Liu     {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg,
776*c901905eSPaolo Bonzini      NULL, NULL, NULL},
77727458df8SWei Liu     {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm,
778*c901905eSPaolo Bonzini      NULL, NULL, NULL},
77927458df8SWei Liu     {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm,
780*c901905eSPaolo Bonzini      NULL, NULL, NULL},
78127458df8SWei Liu     {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm,
782*c901905eSPaolo Bonzini      NULL, NULL, NULL},
78327458df8SWei Liu     {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm,
784*c901905eSPaolo Bonzini      NULL, NULL, NULL},
78527458df8SWei Liu     {0x2f, X86_DECODE_CMD_DAS, 0, false,
786*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
78727458df8SWei Liu     {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg,
788*c901905eSPaolo Bonzini      NULL, NULL, NULL},
78927458df8SWei Liu     {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg,
790*c901905eSPaolo Bonzini      NULL, NULL, NULL},
79127458df8SWei Liu     {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm,
792*c901905eSPaolo Bonzini      NULL, NULL, NULL},
79327458df8SWei Liu     {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm,
794*c901905eSPaolo Bonzini      NULL, NULL, NULL},
79527458df8SWei Liu     {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm,
796*c901905eSPaolo Bonzini      NULL, NULL, NULL},
79727458df8SWei Liu     {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm,
798*c901905eSPaolo Bonzini      NULL, NULL, NULL},
79927458df8SWei Liu 
80027458df8SWei Liu     {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg,
801*c901905eSPaolo Bonzini      NULL, NULL, NULL},
80227458df8SWei Liu     {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg,
803*c901905eSPaolo Bonzini      NULL, NULL, NULL},
80427458df8SWei Liu     {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm,
805*c901905eSPaolo Bonzini      NULL, NULL, NULL},
80627458df8SWei Liu     {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm,
807*c901905eSPaolo Bonzini      NULL, NULL, NULL},
80827458df8SWei Liu     {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8,
809*c901905eSPaolo Bonzini      NULL, NULL, NULL},
81027458df8SWei Liu     {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm,
811*c901905eSPaolo Bonzini      NULL, NULL, NULL},
81227458df8SWei Liu 
81327458df8SWei Liu     {0x3f, X86_DECODE_CMD_AAS, 0, false,
814*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
81527458df8SWei Liu 
81627458df8SWei Liu     {0x40, X86_DECODE_CMD_INC, 0, false,
817*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
81827458df8SWei Liu     {0x41, X86_DECODE_CMD_INC, 0, false,
819*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
82027458df8SWei Liu     {0x42, X86_DECODE_CMD_INC, 0, false,
821*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
82227458df8SWei Liu     {0x43, X86_DECODE_CMD_INC, 0, false,
823*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
82427458df8SWei Liu     {0x44, X86_DECODE_CMD_INC, 0, false,
825*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
82627458df8SWei Liu     {0x45, X86_DECODE_CMD_INC, 0, false,
827*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
82827458df8SWei Liu     {0x46, X86_DECODE_CMD_INC, 0, false,
829*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
83027458df8SWei Liu     {0x47, X86_DECODE_CMD_INC, 0, false,
831*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
83227458df8SWei Liu 
83327458df8SWei Liu     {0x48, X86_DECODE_CMD_DEC, 0, false,
834*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
83527458df8SWei Liu     {0x49, X86_DECODE_CMD_DEC, 0, false,
836*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
83727458df8SWei Liu     {0x4a, X86_DECODE_CMD_DEC, 0, false,
838*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
83927458df8SWei Liu     {0x4b, X86_DECODE_CMD_DEC, 0, false,
840*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
84127458df8SWei Liu     {0x4c, X86_DECODE_CMD_DEC, 0, false,
842*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
84327458df8SWei Liu     {0x4d, X86_DECODE_CMD_DEC, 0, false,
844*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
84527458df8SWei Liu     {0x4e, X86_DECODE_CMD_DEC, 0, false,
846*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
84727458df8SWei Liu     {0x4f, X86_DECODE_CMD_DEC, 0, false,
848*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
84927458df8SWei Liu 
85027458df8SWei Liu     {0x50, X86_DECODE_CMD_PUSH, 0, false,
851*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
85227458df8SWei Liu     {0x51, X86_DECODE_CMD_PUSH, 0, false,
853*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
85427458df8SWei Liu     {0x52, X86_DECODE_CMD_PUSH, 0, false,
855*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
85627458df8SWei Liu     {0x53, X86_DECODE_CMD_PUSH, 0, false,
857*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
85827458df8SWei Liu     {0x54, X86_DECODE_CMD_PUSH, 0, false,
859*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
86027458df8SWei Liu     {0x55, X86_DECODE_CMD_PUSH, 0, false,
861*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
86227458df8SWei Liu     {0x56, X86_DECODE_CMD_PUSH, 0, false,
863*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
86427458df8SWei Liu     {0x57, X86_DECODE_CMD_PUSH, 0, false,
865*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
86627458df8SWei Liu 
86727458df8SWei Liu     {0x58, X86_DECODE_CMD_POP, 0, false,
868*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
86927458df8SWei Liu     {0x59, X86_DECODE_CMD_POP, 0, false,
870*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
87127458df8SWei Liu     {0x5a, X86_DECODE_CMD_POP, 0, false,
872*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
87327458df8SWei Liu     {0x5b, X86_DECODE_CMD_POP, 0, false,
874*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
87527458df8SWei Liu     {0x5c, X86_DECODE_CMD_POP, 0, false,
876*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
87727458df8SWei Liu     {0x5d, X86_DECODE_CMD_POP, 0, false,
878*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
87927458df8SWei Liu     {0x5e, X86_DECODE_CMD_POP, 0, false,
880*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
88127458df8SWei Liu     {0x5f, X86_DECODE_CMD_POP, 0, false,
882*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
88327458df8SWei Liu 
88427458df8SWei Liu     {0x60, X86_DECODE_CMD_PUSHA, 0, false,
885*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
88627458df8SWei Liu     {0x61, X86_DECODE_CMD_POPA, 0, false,
887*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
88827458df8SWei Liu 
88927458df8SWei Liu     {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm,
890*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
89127458df8SWei Liu     {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed,
892*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
89327458df8SWei Liu     {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg,
894*c901905eSPaolo Bonzini      decode_modrm_rm, decode_imm, NULL, NULL},
89527458df8SWei Liu     {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm,
896*c901905eSPaolo Bonzini      decode_imm8_signed, NULL, NULL},
89727458df8SWei Liu 
89827458df8SWei Liu     {0x6c, X86_DECODE_CMD_INS, 1, false,
899*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
90027458df8SWei Liu     {0x6d, X86_DECODE_CMD_INS, 0, false,
901*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
90227458df8SWei Liu     {0x6e, X86_DECODE_CMD_OUTS, 1, false,
903*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
90427458df8SWei Liu     {0x6f, X86_DECODE_CMD_OUTS, 0, false,
905*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
90627458df8SWei Liu 
90727458df8SWei Liu     {0x70, X86_DECODE_CMD_JXX, 1, false,
908*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
90927458df8SWei Liu     {0x71, X86_DECODE_CMD_JXX, 1, false,
910*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
91127458df8SWei Liu     {0x72, X86_DECODE_CMD_JXX, 1, false,
912*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
91327458df8SWei Liu     {0x73, X86_DECODE_CMD_JXX, 1, false,
914*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
91527458df8SWei Liu     {0x74, X86_DECODE_CMD_JXX, 1, false,
916*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
91727458df8SWei Liu     {0x75, X86_DECODE_CMD_JXX, 1, false,
918*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
91927458df8SWei Liu     {0x76, X86_DECODE_CMD_JXX, 1, false,
920*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
92127458df8SWei Liu     {0x77, X86_DECODE_CMD_JXX, 1, false,
922*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
92327458df8SWei Liu     {0x78, X86_DECODE_CMD_JXX, 1, false,
924*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
92527458df8SWei Liu     {0x79, X86_DECODE_CMD_JXX, 1, false,
926*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
92727458df8SWei Liu     {0x7a, X86_DECODE_CMD_JXX, 1, false,
928*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
92927458df8SWei Liu     {0x7b, X86_DECODE_CMD_JXX, 1, false,
930*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
93127458df8SWei Liu     {0x7c, X86_DECODE_CMD_JXX, 1, false,
932*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
93327458df8SWei Liu     {0x7d, X86_DECODE_CMD_JXX, 1, false,
934*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
93527458df8SWei Liu     {0x7e, X86_DECODE_CMD_JXX, 1, false,
936*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
93727458df8SWei Liu     {0x7f, X86_DECODE_CMD_JXX, 1, false,
938*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
93927458df8SWei Liu 
94027458df8SWei Liu     {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
941*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
94227458df8SWei Liu     {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm,
943*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
94427458df8SWei Liu     {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
945*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
94627458df8SWei Liu     {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed,
947*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
94827458df8SWei Liu     {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg,
949*c901905eSPaolo Bonzini      NULL, NULL, NULL},
95027458df8SWei Liu     {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg,
951*c901905eSPaolo Bonzini      NULL, NULL, NULL},
95227458df8SWei Liu     {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm,
953*c901905eSPaolo Bonzini      NULL, NULL, NULL},
95427458df8SWei Liu     {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm,
955*c901905eSPaolo Bonzini      NULL, NULL, NULL},
95627458df8SWei Liu     {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg,
957*c901905eSPaolo Bonzini      NULL, NULL, NULL},
95827458df8SWei Liu     {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg,
959*c901905eSPaolo Bonzini      NULL, NULL, NULL},
96027458df8SWei Liu     {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm,
961*c901905eSPaolo Bonzini      NULL, NULL, NULL},
96227458df8SWei Liu     {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm,
963*c901905eSPaolo Bonzini      NULL, NULL, NULL},
96427458df8SWei Liu     {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm,
965*c901905eSPaolo Bonzini      decode_modrm_reg, NULL, NULL, NULL},
96627458df8SWei Liu     {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm,
967*c901905eSPaolo Bonzini      NULL, NULL, NULL},
96827458df8SWei Liu     {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg,
969*c901905eSPaolo Bonzini      decode_modrm_rm, NULL, NULL, NULL},
97027458df8SWei Liu     {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm,
971*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
97227458df8SWei Liu 
97327458df8SWei Liu     {0x90, X86_DECODE_CMD_NOP, 0, false,
974*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
97527458df8SWei Liu     {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
976*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
97727458df8SWei Liu     {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
978*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
97927458df8SWei Liu     {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
980*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
98127458df8SWei Liu     {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
982*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
98327458df8SWei Liu     {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
984*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
98527458df8SWei Liu     {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
986*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
98727458df8SWei Liu     {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
988*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
98927458df8SWei Liu 
99027458df8SWei Liu     {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL,
991*c901905eSPaolo Bonzini      NULL, NULL, NULL},
99227458df8SWei Liu     {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL,
993*c901905eSPaolo Bonzini      NULL, NULL, NULL},
99427458df8SWei Liu 
99527458df8SWei Liu     {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL,
996*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_farjmp},
99727458df8SWei Liu 
99827458df8SWei Liu     {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL,
999*c901905eSPaolo Bonzini      NULL, NULL, NULL},
100027458df8SWei Liu     /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL,
1001*c901905eSPaolo Bonzini      NULL, NULL, NULL},*/
100227458df8SWei Liu     {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL,
1003*c901905eSPaolo Bonzini      NULL, NULL, NULL},
100427458df8SWei Liu     {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL,
1005*c901905eSPaolo Bonzini      NULL, NULL, NULL},
100627458df8SWei Liu 
100727458df8SWei Liu     {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs,
1008*c901905eSPaolo Bonzini      NULL, NULL, NULL},
100927458df8SWei Liu     {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs,
1010*c901905eSPaolo Bonzini      NULL, NULL, NULL},
101127458df8SWei Liu     {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax,
1012*c901905eSPaolo Bonzini      NULL, NULL, NULL},
101327458df8SWei Liu     {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax,
1014*c901905eSPaolo Bonzini      NULL, NULL, NULL},
101527458df8SWei Liu 
101627458df8SWei Liu     {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL,
1017*c901905eSPaolo Bonzini      NULL, NULL, NULL},
101827458df8SWei Liu     {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL,
1019*c901905eSPaolo Bonzini      NULL, NULL, NULL},
102027458df8SWei Liu     {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL,
1021*c901905eSPaolo Bonzini      NULL, NULL, NULL},
102227458df8SWei Liu     {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL,
1023*c901905eSPaolo Bonzini      NULL, NULL, NULL},
102427458df8SWei Liu     {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL,
1025*c901905eSPaolo Bonzini      NULL, NULL, NULL},
102627458df8SWei Liu     {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL,
1027*c901905eSPaolo Bonzini      NULL, NULL, NULL},
102827458df8SWei Liu     {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL,
1029*c901905eSPaolo Bonzini      NULL, NULL, NULL},
103027458df8SWei Liu     {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL,
1031*c901905eSPaolo Bonzini      NULL, NULL, NULL},
103227458df8SWei Liu     {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL,
1033*c901905eSPaolo Bonzini      NULL, NULL, NULL},
103427458df8SWei Liu     {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL,
1035*c901905eSPaolo Bonzini      NULL, NULL, NULL},
103627458df8SWei Liu 
103727458df8SWei Liu     {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm,
1038*c901905eSPaolo Bonzini      NULL, NULL, NULL},
103927458df8SWei Liu     {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm,
1040*c901905eSPaolo Bonzini      NULL, NULL, NULL},
104127458df8SWei Liu 
104227458df8SWei Liu     {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL,
1043*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
104427458df8SWei Liu     {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL,
1045*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
104627458df8SWei Liu     {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL,
1047*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
104827458df8SWei Liu     {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL,
1049*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
105027458df8SWei Liu     {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL,
1051*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
105227458df8SWei Liu     {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL,
1053*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
105427458df8SWei Liu     {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL,
1055*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
105627458df8SWei Liu     {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL,
1057*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
105827458df8SWei Liu 
105927458df8SWei Liu     {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL,
1060*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
106127458df8SWei Liu     {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL,
1062*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
106327458df8SWei Liu     {0xba, X86_DECODE_CMD_MOV, 0, false, NULL,
1064*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
106527458df8SWei Liu     {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL,
1066*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
106727458df8SWei Liu     {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL,
1068*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
106927458df8SWei Liu     {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL,
1070*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
107127458df8SWei Liu     {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL,
1072*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
107327458df8SWei Liu     {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL,
1074*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
107527458df8SWei Liu 
107627458df8SWei Liu     {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
1077*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
107827458df8SWei Liu     {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1079*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
108027458df8SWei Liu 
108127458df8SWei Liu     {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16,
1082*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
108327458df8SWei Liu     {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL,
1084*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
108527458df8SWei Liu 
108627458df8SWei Liu     {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm,
1087*c901905eSPaolo Bonzini      NULL, NULL, NULL},
108827458df8SWei Liu     {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm,
1089*c901905eSPaolo Bonzini      NULL, NULL, NULL},
109027458df8SWei Liu 
109127458df8SWei Liu     {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8,
1092*c901905eSPaolo Bonzini      NULL, NULL, NULL},
109327458df8SWei Liu     {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm,
1094*c901905eSPaolo Bonzini      NULL, NULL, NULL},
109527458df8SWei Liu 
109627458df8SWei Liu     {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8,
1097*c901905eSPaolo Bonzini      NULL, NULL, NULL},
109827458df8SWei Liu     {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL,
1099*c901905eSPaolo Bonzini      NULL, NULL, NULL},
110027458df8SWei Liu     {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL,
1101*c901905eSPaolo Bonzini      NULL, NULL, NULL},
110227458df8SWei Liu     {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL,
1103*c901905eSPaolo Bonzini      NULL, NULL, NULL},
110427458df8SWei Liu     {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL,
1105*c901905eSPaolo Bonzini      NULL, NULL, NULL},
110627458df8SWei Liu     /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL,
1107*c901905eSPaolo Bonzini      NULL, NULL, NULL},*/
110827458df8SWei Liu 
110927458df8SWei Liu     {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1,
1110*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
111127458df8SWei Liu     {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1,
1112*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
111327458df8SWei Liu     {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx,
1114*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
111527458df8SWei Liu     {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx,
1116*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
111727458df8SWei Liu 
111827458df8SWei Liu     {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8,
1119*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
112027458df8SWei Liu     {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8,
1121*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
112227458df8SWei Liu 
112327458df8SWei Liu     {0xd7, X86_DECODE_CMD_XLAT, 0, false,
1124*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
112527458df8SWei Liu 
112627458df8SWei Liu     {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL,
1127*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
112827458df8SWei Liu     {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL,
1129*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
113027458df8SWei Liu     {0xda, X86_DECODE_CMD_INVL, 0, true, NULL,
1131*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
113227458df8SWei Liu     {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL,
1133*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
113427458df8SWei Liu     {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL,
1135*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
113627458df8SWei Liu     {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL,
1137*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
113827458df8SWei Liu     {0xde, X86_DECODE_CMD_INVL, 0, true, NULL,
1139*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
114027458df8SWei Liu     {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL,
1141*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
114227458df8SWei Liu 
114327458df8SWei Liu     {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1144*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
114527458df8SWei Liu     {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1146*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
114727458df8SWei Liu     {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1148*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
114927458df8SWei Liu 
115027458df8SWei Liu     {0xe3, X86_DECODE_CMD_JCXZ, 1, false,
1151*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
115227458df8SWei Liu 
115327458df8SWei Liu     {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8,
1154*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
115527458df8SWei Liu     {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8,
1156*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
115727458df8SWei Liu     {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8,
1158*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
115927458df8SWei Liu     {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8,
1160*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
116127458df8SWei Liu     {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed,
1162*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
116327458df8SWei Liu     {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed,
1164*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
116527458df8SWei Liu     {0xea, X86_DECODE_CMD_JMP_FAR, 0, false,
1166*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_farjmp},
116727458df8SWei Liu     {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed,
1168*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
116927458df8SWei Liu     {0xec, X86_DECODE_CMD_IN, 1, false,
1170*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
117127458df8SWei Liu     {0xed, X86_DECODE_CMD_IN, 0, false,
1172*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
117327458df8SWei Liu     {0xee, X86_DECODE_CMD_OUT, 1, false,
1174*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
117527458df8SWei Liu     {0xef, X86_DECODE_CMD_OUT, 0, false,
1176*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
117727458df8SWei Liu 
117827458df8SWei Liu     {0xf4, X86_DECODE_CMD_HLT, 0, false,
1179*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
118027458df8SWei Liu 
118127458df8SWei Liu     {0xf5, X86_DECODE_CMD_CMC, 0, false,
1182*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
118327458df8SWei Liu 
118427458df8SWei Liu     {0xf6, X86_DECODE_CMD_INVL, 1, true,
1185*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_f7group},
118627458df8SWei Liu     {0xf7, X86_DECODE_CMD_INVL, 0, true,
1187*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_f7group},
118827458df8SWei Liu 
118927458df8SWei Liu     {0xf8, X86_DECODE_CMD_CLC, 0, false,
1190*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
119127458df8SWei Liu     {0xf9, X86_DECODE_CMD_STC, 0, false,
1192*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
119327458df8SWei Liu 
119427458df8SWei Liu     {0xfa, X86_DECODE_CMD_CLI, 0, false,
1195*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
119627458df8SWei Liu     {0xfb, X86_DECODE_CMD_STI, 0, false,
1197*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
119827458df8SWei Liu     {0xfc, X86_DECODE_CMD_CLD, 0, false,
1199*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
120027458df8SWei Liu     {0xfd, X86_DECODE_CMD_STD, 0, false,
1201*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
120227458df8SWei Liu     {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm,
1203*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_incgroup2},
120427458df8SWei Liu     {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1205*c901905eSPaolo 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,
1210*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_sldtgroup},
121127458df8SWei Liu     {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1212*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_lidtgroup},
121327458df8SWei Liu     {0x6, X86_DECODE_CMD_CLTS, 0, false,
1214*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
121527458df8SWei Liu     {0x9, X86_DECODE_CMD_WBINVD, 0, false,
1216*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
121727458df8SWei Liu     {0x18, X86_DECODE_CMD_PREFETCH, 0, true,
1218*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_x87_general},
121927458df8SWei Liu     {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm,
1220*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
122127458df8SWei Liu     {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm,
1222*c901905eSPaolo Bonzini      decode_modrm_reg, NULL, NULL, NULL},
122327458df8SWei Liu     {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm,
1224*c901905eSPaolo Bonzini      decode_modrm_reg, NULL, NULL, NULL},
122527458df8SWei Liu     {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg,
1226*c901905eSPaolo Bonzini      decode_modrm_rm, NULL, NULL, NULL},
122727458df8SWei Liu     {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg,
1228*c901905eSPaolo Bonzini      decode_modrm_rm, NULL, NULL, NULL},
122927458df8SWei Liu     {0x30, X86_DECODE_CMD_WRMSR, 0, false,
1230*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
123127458df8SWei Liu     {0x31, X86_DECODE_CMD_RDTSC, 0, false,
1232*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
123327458df8SWei Liu     {0x32, X86_DECODE_CMD_RDMSR, 0, false,
1234*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
123527458df8SWei Liu     {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1236*c901905eSPaolo Bonzini      NULL, NULL, NULL},
123727458df8SWei Liu     {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1238*c901905eSPaolo Bonzini      NULL, NULL, NULL},
123927458df8SWei Liu     {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1240*c901905eSPaolo Bonzini      NULL, NULL, NULL},
124127458df8SWei Liu     {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1242*c901905eSPaolo Bonzini      NULL, NULL, NULL},
124327458df8SWei Liu     {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1244*c901905eSPaolo Bonzini      NULL, NULL, NULL},
124527458df8SWei Liu     {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1246*c901905eSPaolo Bonzini      NULL, NULL, NULL},
124727458df8SWei Liu     {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1248*c901905eSPaolo Bonzini      NULL, NULL, NULL},
124927458df8SWei Liu     {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1250*c901905eSPaolo Bonzini      NULL, NULL, NULL},
125127458df8SWei Liu     {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1252*c901905eSPaolo Bonzini      NULL, NULL, NULL},
125327458df8SWei Liu     {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1254*c901905eSPaolo Bonzini      NULL, NULL, NULL},
125527458df8SWei Liu     {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1256*c901905eSPaolo Bonzini      NULL, NULL, NULL},
125727458df8SWei Liu     {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1258*c901905eSPaolo Bonzini      NULL, NULL, NULL},
125927458df8SWei Liu     {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1260*c901905eSPaolo Bonzini      NULL, NULL, NULL},
126127458df8SWei Liu     {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1262*c901905eSPaolo Bonzini      NULL, NULL, NULL},
126327458df8SWei Liu     {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1264*c901905eSPaolo Bonzini      NULL, NULL, NULL},
126527458df8SWei Liu     {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1266*c901905eSPaolo Bonzini      NULL, NULL, NULL},
126727458df8SWei Liu     {0x77, X86_DECODE_CMD_EMMS, 0, false,
1268*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_x87_general},
126927458df8SWei Liu     {0x82, X86_DECODE_CMD_JXX, 0, false,
1270*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
127127458df8SWei Liu     {0x83, X86_DECODE_CMD_JXX, 0, false,
1272*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
127327458df8SWei Liu     {0x84, X86_DECODE_CMD_JXX, 0, false,
1274*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
127527458df8SWei Liu     {0x85, X86_DECODE_CMD_JXX, 0, false,
1276*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
127727458df8SWei Liu     {0x86, X86_DECODE_CMD_JXX, 0, false,
1278*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
127927458df8SWei Liu     {0x87, X86_DECODE_CMD_JXX, 0, false,
1280*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
128127458df8SWei Liu     {0x88, X86_DECODE_CMD_JXX, 0, false,
1282*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
128327458df8SWei Liu     {0x89, X86_DECODE_CMD_JXX, 0, false,
1284*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
128527458df8SWei Liu     {0x8a, X86_DECODE_CMD_JXX, 0, false,
1286*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
128727458df8SWei Liu     {0x8b, X86_DECODE_CMD_JXX, 0, false,
1288*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
128927458df8SWei Liu     {0x8c, X86_DECODE_CMD_JXX, 0, false,
1290*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
129127458df8SWei Liu     {0x8d, X86_DECODE_CMD_JXX, 0, false,
1292*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
129327458df8SWei Liu     {0x8e, X86_DECODE_CMD_JXX, 0, false,
1294*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
129527458df8SWei Liu     {0x8f, X86_DECODE_CMD_JXX, 0, false,
1296*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
129727458df8SWei Liu     {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1298*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
129927458df8SWei Liu     {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1300*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
130127458df8SWei Liu     {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1302*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
130327458df8SWei Liu     {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1304*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
130527458df8SWei Liu     {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1306*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
130727458df8SWei Liu     {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1308*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
130927458df8SWei Liu     {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1310*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
131127458df8SWei Liu     {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1312*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
131327458df8SWei Liu     {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1314*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
131527458df8SWei Liu     {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1316*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
131727458df8SWei Liu     {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1318*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
131927458df8SWei Liu     {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1320*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
132127458df8SWei Liu     {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1322*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
132327458df8SWei Liu     {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1324*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
132527458df8SWei Liu     {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1326*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
132727458df8SWei Liu     {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1328*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
132927458df8SWei Liu 
133027458df8SWei Liu     {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg,
1331*c901905eSPaolo Bonzini      NULL, NULL, NULL},
133227458df8SWei Liu     {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg,
1333*c901905eSPaolo Bonzini      NULL, NULL, NULL},
133427458df8SWei Liu 
133527458df8SWei Liu     {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1336*c901905eSPaolo Bonzini      NULL, NULL, NULL},
133727458df8SWei Liu     {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1338*c901905eSPaolo Bonzini      NULL, NULL, NULL},
133927458df8SWei Liu     {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm,
1340*c901905eSPaolo Bonzini      NULL, NULL, NULL},
134127458df8SWei Liu     {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1342*c901905eSPaolo Bonzini      NULL, NULL, NULL},
134327458df8SWei Liu     {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1344*c901905eSPaolo Bonzini      NULL, NULL, NULL},
134527458df8SWei Liu     {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1346*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
134727458df8SWei Liu     {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false,
1348*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
134927458df8SWei Liu     {0xa2, X86_DECODE_CMD_CPUID, 0, false,
1350*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
135127458df8SWei Liu     {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg,
1352*c901905eSPaolo Bonzini      NULL, NULL, NULL},
135327458df8SWei Liu     {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1354*c901905eSPaolo Bonzini      decode_imm8, NULL, NULL},
135527458df8SWei Liu     {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1356*c901905eSPaolo Bonzini      decode_rcx, NULL, NULL},
135727458df8SWei Liu     {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1358*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
135927458df8SWei Liu     {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false,
1360*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
136127458df8SWei Liu     {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg,
1362*c901905eSPaolo Bonzini      NULL, NULL, NULL},
136327458df8SWei Liu     {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1364*c901905eSPaolo Bonzini      decode_imm8, NULL, NULL},
136527458df8SWei Liu     {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1366*c901905eSPaolo Bonzini      decode_rcx, NULL, NULL},
136727458df8SWei Liu 
136827458df8SWei Liu     {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1369*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_aegroup},
137027458df8SWei Liu 
137127458df8SWei Liu     {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm,
1372*c901905eSPaolo Bonzini      NULL, NULL, NULL},
137327458df8SWei Liu     {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm,
1374*c901905eSPaolo Bonzini      NULL, NULL, NULL},
137527458df8SWei Liu     {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg,
1376*c901905eSPaolo Bonzini      NULL, NULL, NULL},
137727458df8SWei Liu     {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1378*c901905eSPaolo Bonzini      NULL, NULL, decode_btgroup},
137927458df8SWei Liu     {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg,
1380*c901905eSPaolo Bonzini      NULL, NULL, NULL},
138127458df8SWei Liu     {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm,
1382*c901905eSPaolo Bonzini      NULL, NULL, NULL},
138327458df8SWei Liu     {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm,
1384*c901905eSPaolo Bonzini      NULL, NULL, NULL},
138527458df8SWei Liu 
138627458df8SWei Liu     {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg,
1387*c901905eSPaolo Bonzini      NULL, NULL, NULL},
138827458df8SWei Liu 
138927458df8SWei Liu     {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm,
1390*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
139127458df8SWei Liu 
139227458df8SWei Liu     {0xc8, X86_DECODE_CMD_BSWAP, 0, false,
1393*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
139427458df8SWei Liu     {0xc9, X86_DECODE_CMD_BSWAP, 0, false,
1395*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
139627458df8SWei Liu     {0xca, X86_DECODE_CMD_BSWAP, 0, false,
1397*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
139827458df8SWei Liu     {0xcb, X86_DECODE_CMD_BSWAP, 0, false,
1399*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
140027458df8SWei Liu     {0xcc, X86_DECODE_CMD_BSWAP, 0, false,
1401*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
140227458df8SWei Liu     {0xcd, X86_DECODE_CMD_BSWAP, 0, false,
1403*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
140427458df8SWei Liu     {0xce, X86_DECODE_CMD_BSWAP, 0, false,
1405*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
140627458df8SWei Liu     {0xcf, X86_DECODE_CMD_BSWAP, 0, false,
1407*c901905eSPaolo 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,
141127458df8SWei Liu                                        NULL, decode_invalid, 0};
141227458df8SWei Liu 
141327458df8SWei Liu struct decode_x87_tbl _x87_inst[] = {
141427458df8SWei Liu     {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1415*c901905eSPaolo 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,
1417*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
141827458df8SWei Liu     {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0,
1419*c901905eSPaolo Bonzini      decode_decode_x87_modrm_st0, NULL},
142027458df8SWei Liu     {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1421*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
142227458df8SWei Liu     {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0,
1423*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
142427458df8SWei Liu     {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1425*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
142627458df8SWei Liu     {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0,
1427*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
142827458df8SWei Liu     {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1429*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
143027458df8SWei Liu     {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0,
1431*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
143227458df8SWei Liu     {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1433*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
143427458df8SWei Liu     {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0,
1435*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
143627458df8SWei Liu     {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1437*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
143827458df8SWei Liu 
143927458df8SWei Liu     {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false,
1440*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
144127458df8SWei Liu     {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1442*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
144327458df8SWei Liu     {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0,
1444*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
144527458df8SWei Liu     {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false,
1446*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
144727458df8SWei Liu     {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false,
1448*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
144927458df8SWei Liu     {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1450*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
145127458df8SWei Liu     {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false,
1452*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
145327458df8SWei Liu     {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1454*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
145527458df8SWei Liu     {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false,
1456*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, decode_d9_4},
145727458df8SWei Liu     {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false,
1458*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
145927458df8SWei Liu     {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL,
146027458df8SWei Liu      RFLAGS_MASK_NONE},
146127458df8SWei Liu     {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false,
1462*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
146327458df8SWei Liu 
146427458df8SWei Liu     {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false,
1465*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
146627458df8SWei Liu     {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false,
1467*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
146827458df8SWei Liu 
146927458df8SWei Liu     {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1470*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
147127458df8SWei Liu     {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1472*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
147327458df8SWei Liu     {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1474*c901905eSPaolo Bonzini      decode_decode_x87_modrm_st0, NULL},
147527458df8SWei Liu     {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1476*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
147727458df8SWei Liu     {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1478*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
147927458df8SWei Liu     {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1480*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
148127458df8SWei Liu     {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
148227458df8SWei Liu      RFLAGS_MASK_NONE},
148327458df8SWei Liu     {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1484*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
148527458df8SWei Liu     {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0,
1486*c901905eSPaolo Bonzini      decode_decode_x87_modrm_st0, NULL},
148727458df8SWei Liu     {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1488*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
148927458df8SWei Liu     {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
149027458df8SWei Liu      RFLAGS_MASK_NONE},
149127458df8SWei Liu     {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1492*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
149327458df8SWei Liu     {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
149427458df8SWei Liu      RFLAGS_MASK_NONE},
149527458df8SWei Liu     {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1496*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
149727458df8SWei Liu 
149827458df8SWei Liu     {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1499*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
150027458df8SWei Liu     {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1501*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
150227458df8SWei Liu     {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1503*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
150427458df8SWei Liu     {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1505*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
150627458df8SWei Liu     {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1507*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
150827458df8SWei Liu     {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1509*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
151027458df8SWei Liu     {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1511*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
151227458df8SWei Liu     {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL,
1513*c901905eSPaolo Bonzini      decode_db_4},
151427458df8SWei Liu     {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
151527458df8SWei Liu      RFLAGS_MASK_NONE},
151627458df8SWei Liu     {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false,
1517*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
151827458df8SWei Liu     {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false,
1519*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
152027458df8SWei Liu     {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true,
1521*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
152227458df8SWei Liu 
152327458df8SWei Liu     {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1524*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
152527458df8SWei Liu     {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false,
1526*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
152727458df8SWei Liu     {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false,
1528*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
152927458df8SWei Liu     {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false,
1530*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
153127458df8SWei Liu     {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false,
1532*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
153327458df8SWei Liu     {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false,
1534*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
153527458df8SWei Liu     {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false,
1536*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
153727458df8SWei Liu     {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false,
1538*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
153927458df8SWei Liu     {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false,
1540*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
154127458df8SWei Liu     {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false,
1542*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
154327458df8SWei Liu     {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false,
1544*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
154527458df8SWei Liu     {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false,
1546*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
154727458df8SWei Liu 
154827458df8SWei Liu     {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false,
1549*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
155027458df8SWei Liu     {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1551*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
155227458df8SWei Liu     {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false,
1553*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
155427458df8SWei Liu     {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false,
1555*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
155627458df8SWei Liu     {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1557*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
155827458df8SWei Liu     {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true,
1559*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
156027458df8SWei Liu     {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false,
1561*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
156227458df8SWei Liu     {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false,
1563*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
156427458df8SWei Liu     {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true,
1565*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
156627458df8SWei Liu     {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false,
1567*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
156827458df8SWei Liu     {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false,
1569*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
157027458df8SWei Liu 
157127458df8SWei Liu     {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true,
1572*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
157327458df8SWei Liu     {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false,
1574*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
157527458df8SWei Liu     {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true,
1576*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
157727458df8SWei Liu     {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false,
1578*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
157927458df8SWei Liu     {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true,
1580*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
158127458df8SWei Liu     {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false,
1582*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
158327458df8SWei Liu     {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true,
1584*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
158527458df8SWei Liu     {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false,
1586*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
158727458df8SWei Liu     {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true,
1588*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
158927458df8SWei Liu     {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false,
1590*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
159127458df8SWei Liu     {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true,
1592*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
159327458df8SWei Liu     {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false,
1594*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
159527458df8SWei Liu 
159627458df8SWei Liu     {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false,
1597*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
159827458df8SWei Liu     {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1599*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
160027458df8SWei Liu     {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true,
1601*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
160227458df8SWei Liu     {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false,
1603*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
160427458df8SWei Liu     {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1605*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
160627458df8SWei Liu     {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true,
1607*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
160827458df8SWei Liu     {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true,
1609*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
161027458df8SWei Liu     {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true,
1611*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
161227458df8SWei Liu     {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false,
1613*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
161427458df8SWei Liu     {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true,
1615*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
161627458df8SWei Liu };
161727458df8SWei Liu 
161827458df8SWei Liu void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
161927458df8SWei Liu                           struct x86_decode_op *op)
162027458df8SWei Liu {
162127458df8SWei Liu     target_ulong ptr = 0;
162227458df8SWei Liu     X86Seg seg = R_DS;
162327458df8SWei Liu 
162427458df8SWei Liu     if (!decode->modrm.mod && 6 == decode->modrm.rm) {
162527458df8SWei Liu         ptr = decode->displacement;
162627458df8SWei Liu         goto calc_addr;
162727458df8SWei Liu     }
162827458df8SWei Liu 
162927458df8SWei Liu     if (decode->displacement_size) {
163027458df8SWei Liu         ptr = sign(decode->displacement, decode->displacement_size);
163127458df8SWei Liu     }
163227458df8SWei Liu 
163327458df8SWei Liu     switch (decode->modrm.rm) {
163427458df8SWei Liu     case 0:
163527458df8SWei Liu         ptr += BX(env) + SI(env);
163627458df8SWei Liu         break;
163727458df8SWei Liu     case 1:
163827458df8SWei Liu         ptr += BX(env) + DI(env);
163927458df8SWei Liu         break;
164027458df8SWei Liu     case 2:
164127458df8SWei Liu         ptr += BP(env) + SI(env);
164227458df8SWei Liu         seg = R_SS;
164327458df8SWei Liu         break;
164427458df8SWei Liu     case 3:
164527458df8SWei Liu         ptr += BP(env) + DI(env);
164627458df8SWei Liu         seg = R_SS;
164727458df8SWei Liu         break;
164827458df8SWei Liu     case 4:
164927458df8SWei Liu         ptr += SI(env);
165027458df8SWei Liu         break;
165127458df8SWei Liu     case 5:
165227458df8SWei Liu         ptr += DI(env);
165327458df8SWei Liu         break;
165427458df8SWei Liu     case 6:
165527458df8SWei Liu         ptr += BP(env);
165627458df8SWei Liu         seg = R_SS;
165727458df8SWei Liu         break;
165827458df8SWei Liu     case 7:
165927458df8SWei Liu         ptr += BX(env);
166027458df8SWei Liu         break;
166127458df8SWei Liu     }
166227458df8SWei Liu calc_addr:
166327458df8SWei Liu     if (X86_DECODE_CMD_LEA == decode->cmd) {
166427458df8SWei Liu         op->ptr = (uint16_t)ptr;
166527458df8SWei Liu     } else {
166627458df8SWei Liu         op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
166727458df8SWei Liu     }
166827458df8SWei Liu }
166927458df8SWei Liu 
167027458df8SWei Liu target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
167127458df8SWei Liu                          int is_extended, int size)
167227458df8SWei Liu {
167327458df8SWei Liu     target_ulong ptr = 0;
167427458df8SWei Liu 
167527458df8SWei Liu     if (is_extended) {
167627458df8SWei Liu         reg |= R_R8;
167727458df8SWei Liu     }
167827458df8SWei Liu 
167927458df8SWei Liu     switch (size) {
168027458df8SWei Liu     case 1:
168127458df8SWei Liu         if (is_extended || reg < 4 || rex_present) {
168227458df8SWei Liu             ptr = (target_ulong)&RL(env, reg);
168327458df8SWei Liu         } else {
168427458df8SWei Liu             ptr = (target_ulong)&RH(env, reg - 4);
168527458df8SWei Liu         }
168627458df8SWei Liu         break;
168727458df8SWei Liu     default:
168827458df8SWei Liu         ptr = (target_ulong)&RRX(env, reg);
168927458df8SWei Liu         break;
169027458df8SWei Liu     }
169127458df8SWei Liu     return ptr;
169227458df8SWei Liu }
169327458df8SWei Liu 
169427458df8SWei Liu target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
169527458df8SWei Liu                          int is_extended, int size)
169627458df8SWei Liu {
169727458df8SWei Liu     target_ulong val = 0;
169827458df8SWei Liu     memcpy(&val,
169927458df8SWei Liu            (void *)get_reg_ref(env, reg, rex_present, is_extended, size),
170027458df8SWei Liu            size);
170127458df8SWei Liu     return val;
170227458df8SWei Liu }
170327458df8SWei Liu 
170427458df8SWei Liu static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode,
170527458df8SWei Liu                           X86Seg *sel)
170627458df8SWei Liu {
170727458df8SWei Liu     target_ulong base = 0;
170827458df8SWei Liu     target_ulong scaled_index = 0;
170927458df8SWei Liu     int addr_size = decode->addressing_size;
171027458df8SWei Liu     int base_reg = decode->sib.base;
171127458df8SWei Liu     int index_reg = decode->sib.index;
171227458df8SWei Liu 
171327458df8SWei Liu     *sel = R_DS;
171427458df8SWei Liu 
171527458df8SWei Liu     if (decode->modrm.mod || base_reg != R_EBP) {
171627458df8SWei Liu         if (decode->rex.b) {
171727458df8SWei Liu             base_reg |= R_R8;
171827458df8SWei Liu         }
171927458df8SWei Liu         if (base_reg == R_ESP || base_reg == R_EBP) {
172027458df8SWei Liu             *sel = R_SS;
172127458df8SWei Liu         }
172227458df8SWei Liu         base = get_reg_val(env, decode->sib.base, decode->rex.rex,
172327458df8SWei Liu                            decode->rex.b, addr_size);
172427458df8SWei Liu     }
172527458df8SWei Liu 
172627458df8SWei Liu     if (decode->rex.x) {
172727458df8SWei Liu         index_reg |= R_R8;
172827458df8SWei Liu     }
172927458df8SWei Liu 
173027458df8SWei Liu     if (index_reg != R_ESP) {
173127458df8SWei Liu         scaled_index = get_reg_val(env, index_reg, decode->rex.rex,
173227458df8SWei Liu                                    decode->rex.x, addr_size) <<
173327458df8SWei Liu                                    decode->sib.scale;
173427458df8SWei Liu     }
173527458df8SWei Liu     return base + scaled_index;
173627458df8SWei Liu }
173727458df8SWei Liu 
173827458df8SWei Liu void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
173927458df8SWei Liu                           struct x86_decode_op *op)
174027458df8SWei Liu {
174127458df8SWei Liu     X86Seg seg = R_DS;
174227458df8SWei Liu     target_ulong ptr = 0;
174327458df8SWei Liu     int addr_size = decode->addressing_size;
174427458df8SWei Liu 
174527458df8SWei Liu     if (decode->displacement_size) {
174627458df8SWei Liu         ptr = sign(decode->displacement, decode->displacement_size);
174727458df8SWei Liu     }
174827458df8SWei Liu 
174927458df8SWei Liu     if (4 == decode->modrm.rm) {
175027458df8SWei Liu         ptr += get_sib_val(env, decode, &seg);
175127458df8SWei Liu     } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
175227458df8SWei Liu         if (x86_is_long_mode(env_cpu(env))) {
175327458df8SWei Liu             ptr += env->eip + decode->len;
175427458df8SWei Liu         } else {
175527458df8SWei Liu             ptr = decode->displacement;
175627458df8SWei Liu         }
175727458df8SWei Liu     } else {
175827458df8SWei Liu         if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) {
175927458df8SWei Liu             seg = R_SS;
176027458df8SWei Liu         }
176127458df8SWei Liu         ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex,
176227458df8SWei Liu                            decode->rex.b, addr_size);
176327458df8SWei Liu     }
176427458df8SWei Liu 
176527458df8SWei Liu     if (X86_DECODE_CMD_LEA == decode->cmd) {
176627458df8SWei Liu         op->ptr = (uint32_t)ptr;
176727458df8SWei Liu     } else {
176827458df8SWei Liu         op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
176927458df8SWei Liu     }
177027458df8SWei Liu }
177127458df8SWei Liu 
177227458df8SWei Liu void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
177327458df8SWei Liu                           struct x86_decode_op *op)
177427458df8SWei Liu {
177527458df8SWei Liu     X86Seg seg = R_DS;
177627458df8SWei Liu     int32_t offset = 0;
177727458df8SWei Liu     int mod = decode->modrm.mod;
177827458df8SWei Liu     int rm = decode->modrm.rm;
177927458df8SWei Liu     target_ulong ptr;
178027458df8SWei Liu     int src = decode->modrm.rm;
178127458df8SWei Liu 
178227458df8SWei Liu     if (decode->displacement_size) {
178327458df8SWei Liu         offset = sign(decode->displacement, decode->displacement_size);
178427458df8SWei Liu     }
178527458df8SWei Liu 
178627458df8SWei Liu     if (4 == rm) {
178727458df8SWei Liu         ptr = get_sib_val(env, decode, &seg) + offset;
178827458df8SWei Liu     } else if (0 == mod && 5 == rm) {
178927458df8SWei Liu         ptr = env->eip + decode->len + (int32_t) offset;
179027458df8SWei Liu     } else {
179127458df8SWei Liu         ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) +
179227458df8SWei Liu               (int64_t) offset;
179327458df8SWei Liu     }
179427458df8SWei Liu 
179527458df8SWei Liu     if (X86_DECODE_CMD_LEA == decode->cmd) {
179627458df8SWei Liu         op->ptr = ptr;
179727458df8SWei Liu     } else {
179827458df8SWei Liu         op->ptr = decode_linear_addr(env, decode, ptr, seg);
179927458df8SWei Liu     }
180027458df8SWei Liu }
180127458df8SWei Liu 
180227458df8SWei Liu 
180327458df8SWei Liu void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
180427458df8SWei Liu                         struct x86_decode_op *op)
180527458df8SWei Liu {
180627458df8SWei Liu     if (3 == decode->modrm.mod) {
180727458df8SWei Liu         op->reg = decode->modrm.reg;
180827458df8SWei Liu         op->type = X86_VAR_REG;
180927458df8SWei Liu         op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
181027458df8SWei Liu                               decode->rex.b, decode->operand_size);
181127458df8SWei Liu         return;
181227458df8SWei Liu     }
181327458df8SWei Liu 
181427458df8SWei Liu     switch (decode->addressing_size) {
181527458df8SWei Liu     case 2:
181627458df8SWei Liu         calc_modrm_operand16(env, decode, op);
181727458df8SWei Liu         break;
181827458df8SWei Liu     case 4:
181927458df8SWei Liu         calc_modrm_operand32(env, decode, op);
182027458df8SWei Liu         break;
182127458df8SWei Liu     case 8:
182227458df8SWei Liu         calc_modrm_operand64(env, decode, op);
182327458df8SWei Liu         break;
182427458df8SWei Liu     default:
182527458df8SWei Liu         VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
182627458df8SWei Liu         break;
182727458df8SWei Liu     }
182827458df8SWei Liu }
182927458df8SWei Liu 
183027458df8SWei Liu static void decode_prefix(CPUX86State *env, struct x86_decode *decode)
183127458df8SWei Liu {
183227458df8SWei Liu     while (1) {
183327458df8SWei Liu         /*
183427458df8SWei Liu          * REX prefix must come after legacy prefixes.
183527458df8SWei Liu          * REX before legacy is ignored.
183627458df8SWei Liu          * Clear rex to simulate this.
183727458df8SWei Liu          */
183827458df8SWei Liu         uint8_t byte = decode_byte(env, decode);
183927458df8SWei Liu         switch (byte) {
184027458df8SWei Liu         case PREFIX_LOCK:
184127458df8SWei Liu             decode->lock = byte;
184227458df8SWei Liu             decode->rex.rex = 0;
184327458df8SWei Liu             break;
184427458df8SWei Liu         case PREFIX_REPN:
184527458df8SWei Liu         case PREFIX_REP:
184627458df8SWei Liu             decode->rep = byte;
184727458df8SWei Liu             decode->rex.rex = 0;
184827458df8SWei Liu             break;
184927458df8SWei Liu         case PREFIX_CS_SEG_OVERRIDE:
185027458df8SWei Liu         case PREFIX_SS_SEG_OVERRIDE:
185127458df8SWei Liu         case PREFIX_DS_SEG_OVERRIDE:
185227458df8SWei Liu         case PREFIX_ES_SEG_OVERRIDE:
185327458df8SWei Liu         case PREFIX_FS_SEG_OVERRIDE:
185427458df8SWei Liu         case PREFIX_GS_SEG_OVERRIDE:
185527458df8SWei Liu             decode->segment_override = byte;
185627458df8SWei Liu             decode->rex.rex = 0;
185727458df8SWei Liu             break;
185827458df8SWei Liu         case PREFIX_OP_SIZE_OVERRIDE:
185927458df8SWei Liu             decode->op_size_override = byte;
186027458df8SWei Liu             decode->rex.rex = 0;
186127458df8SWei Liu             break;
186227458df8SWei Liu         case PREFIX_ADDR_SIZE_OVERRIDE:
186327458df8SWei Liu             decode->addr_size_override = byte;
186427458df8SWei Liu             decode->rex.rex = 0;
186527458df8SWei Liu             break;
186627458df8SWei Liu         case PREFIX_REX ... (PREFIX_REX + 0xf):
186727458df8SWei Liu             if (x86_is_long_mode(env_cpu(env))) {
186827458df8SWei Liu                 decode->rex.rex = byte;
186927458df8SWei Liu                 break;
187027458df8SWei Liu             }
187127458df8SWei Liu             /* fall through when not in long mode */
187227458df8SWei Liu         default:
187327458df8SWei Liu             decode->len--;
187427458df8SWei Liu             return;
187527458df8SWei Liu         }
187627458df8SWei Liu     }
187727458df8SWei Liu }
187827458df8SWei Liu 
187927458df8SWei Liu void set_addressing_size(CPUX86State *env, struct x86_decode *decode)
188027458df8SWei Liu {
188127458df8SWei Liu     decode->addressing_size = -1;
188227458df8SWei Liu     if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
188327458df8SWei Liu         if (decode->addr_size_override) {
188427458df8SWei Liu             decode->addressing_size = 4;
188527458df8SWei Liu         } else {
188627458df8SWei Liu             decode->addressing_size = 2;
188727458df8SWei Liu         }
188827458df8SWei Liu     } else if (!x86_is_long_mode(env_cpu(env))) {
188927458df8SWei Liu         /* protected */
189027458df8SWei Liu         x86_segment_descriptor cs;
189127458df8SWei Liu         emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
189227458df8SWei Liu         /* check db */
189327458df8SWei Liu         if (cs.db) {
189427458df8SWei Liu             if (decode->addr_size_override) {
189527458df8SWei Liu                 decode->addressing_size = 2;
189627458df8SWei Liu             } else {
189727458df8SWei Liu                 decode->addressing_size = 4;
189827458df8SWei Liu             }
189927458df8SWei Liu         } else {
190027458df8SWei Liu             if (decode->addr_size_override) {
190127458df8SWei Liu                 decode->addressing_size = 4;
190227458df8SWei Liu             } else {
190327458df8SWei Liu                 decode->addressing_size = 2;
190427458df8SWei Liu             }
190527458df8SWei Liu         }
190627458df8SWei Liu     } else {
190727458df8SWei Liu         /* long */
190827458df8SWei Liu         if (decode->addr_size_override) {
190927458df8SWei Liu             decode->addressing_size = 4;
191027458df8SWei Liu         } else {
191127458df8SWei Liu             decode->addressing_size = 8;
191227458df8SWei Liu         }
191327458df8SWei Liu     }
191427458df8SWei Liu }
191527458df8SWei Liu 
191627458df8SWei Liu void set_operand_size(CPUX86State *env, struct x86_decode *decode)
191727458df8SWei Liu {
191827458df8SWei Liu     decode->operand_size = -1;
191927458df8SWei Liu     if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
192027458df8SWei Liu         if (decode->op_size_override) {
192127458df8SWei Liu             decode->operand_size = 4;
192227458df8SWei Liu         } else {
192327458df8SWei Liu             decode->operand_size = 2;
192427458df8SWei Liu         }
192527458df8SWei Liu     } else if (!x86_is_long_mode(env_cpu(env))) {
192627458df8SWei Liu         /* protected */
192727458df8SWei Liu         x86_segment_descriptor cs;
192827458df8SWei Liu         emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
192927458df8SWei Liu         /* check db */
193027458df8SWei Liu         if (cs.db) {
193127458df8SWei Liu             if (decode->op_size_override) {
193227458df8SWei Liu                 decode->operand_size = 2;
193327458df8SWei Liu             } else{
193427458df8SWei Liu                 decode->operand_size = 4;
193527458df8SWei Liu             }
193627458df8SWei Liu         } else {
193727458df8SWei Liu             if (decode->op_size_override) {
193827458df8SWei Liu                 decode->operand_size = 4;
193927458df8SWei Liu             } else {
194027458df8SWei Liu                 decode->operand_size = 2;
194127458df8SWei Liu             }
194227458df8SWei Liu         }
194327458df8SWei Liu     } else {
194427458df8SWei Liu         /* long */
194527458df8SWei Liu         if (decode->op_size_override) {
194627458df8SWei Liu             decode->operand_size = 2;
194727458df8SWei Liu         } else {
194827458df8SWei Liu             decode->operand_size = 4;
194927458df8SWei Liu         }
195027458df8SWei Liu 
195127458df8SWei Liu         if (decode->rex.w) {
195227458df8SWei Liu             decode->operand_size = 8;
195327458df8SWei Liu         }
195427458df8SWei Liu     }
195527458df8SWei Liu }
195627458df8SWei Liu 
195727458df8SWei Liu static void decode_sib(CPUX86State *env, struct x86_decode *decode)
195827458df8SWei Liu {
195927458df8SWei Liu     if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
196027458df8SWei Liu         (decode->addressing_size != 2)) {
196127458df8SWei Liu         decode->sib.sib = decode_byte(env, decode);
196227458df8SWei Liu         decode->sib_present = true;
196327458df8SWei Liu     }
196427458df8SWei Liu }
196527458df8SWei Liu 
196627458df8SWei Liu /* 16 bit modrm */
196727458df8SWei Liu int disp16_tbl[4][8] = {
196827458df8SWei Liu     {0, 0, 0, 0, 0, 0, 2, 0},
196927458df8SWei Liu     {1, 1, 1, 1, 1, 1, 1, 1},
197027458df8SWei Liu     {2, 2, 2, 2, 2, 2, 2, 2},
197127458df8SWei Liu     {0, 0, 0, 0, 0, 0, 0, 0}
197227458df8SWei Liu };
197327458df8SWei Liu 
197427458df8SWei Liu /* 32/64-bit modrm */
197527458df8SWei Liu int disp32_tbl[4][8] = {
197627458df8SWei Liu     {0, 0, 0, 0, -1, 4, 0, 0},
197727458df8SWei Liu     {1, 1, 1, 1, 1, 1, 1, 1},
197827458df8SWei Liu     {4, 4, 4, 4, 4, 4, 4, 4},
197927458df8SWei Liu     {0, 0, 0, 0, 0, 0, 0, 0}
198027458df8SWei Liu };
198127458df8SWei Liu 
198227458df8SWei Liu static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode)
198327458df8SWei Liu {
198427458df8SWei Liu     int addressing_size = decode->addressing_size;
198527458df8SWei Liu     int mod = decode->modrm.mod;
198627458df8SWei Liu     int rm = decode->modrm.rm;
198727458df8SWei Liu 
198827458df8SWei Liu     decode->displacement_size = 0;
198927458df8SWei Liu     switch (addressing_size) {
199027458df8SWei Liu     case 2:
199127458df8SWei Liu         decode->displacement_size = disp16_tbl[mod][rm];
199227458df8SWei Liu         if (decode->displacement_size) {
199327458df8SWei Liu             decode->displacement = (uint16_t)decode_bytes(env, decode,
199427458df8SWei Liu                                     decode->displacement_size);
199527458df8SWei Liu         }
199627458df8SWei Liu         break;
199727458df8SWei Liu     case 4:
199827458df8SWei Liu     case 8:
199927458df8SWei Liu         if (-1 == disp32_tbl[mod][rm]) {
200027458df8SWei Liu             if (5 == decode->sib.base) {
200127458df8SWei Liu                 decode->displacement_size = 4;
200227458df8SWei Liu             }
200327458df8SWei Liu         } else {
200427458df8SWei Liu             decode->displacement_size = disp32_tbl[mod][rm];
200527458df8SWei Liu         }
200627458df8SWei Liu 
200727458df8SWei Liu         if (decode->displacement_size) {
200827458df8SWei Liu             decode->displacement = (uint32_t)decode_bytes(env, decode,
200927458df8SWei Liu                                                 decode->displacement_size);
201027458df8SWei Liu         }
201127458df8SWei Liu         break;
201227458df8SWei Liu     }
201327458df8SWei Liu }
201427458df8SWei Liu 
201527458df8SWei Liu static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode)
201627458df8SWei Liu {
201727458df8SWei Liu     decode->modrm.modrm = decode_byte(env, decode);
201827458df8SWei Liu     decode->is_modrm = true;
201927458df8SWei Liu 
202027458df8SWei Liu     decode_sib(env, decode);
202127458df8SWei Liu     decode_displacement(env, decode);
202227458df8SWei Liu }
202327458df8SWei Liu 
202427458df8SWei Liu static inline void decode_opcode_general(CPUX86State *env,
202527458df8SWei Liu                                          struct x86_decode *decode,
202627458df8SWei Liu                                          uint8_t opcode,
202727458df8SWei Liu                                          struct decode_tbl *inst_decoder)
202827458df8SWei Liu {
202927458df8SWei Liu     decode->cmd = inst_decoder->cmd;
203027458df8SWei Liu     if (inst_decoder->operand_size) {
203127458df8SWei Liu         decode->operand_size = inst_decoder->operand_size;
203227458df8SWei Liu     }
203327458df8SWei Liu 
203427458df8SWei Liu     if (inst_decoder->is_modrm) {
203527458df8SWei Liu         decode_modrm(env, decode);
203627458df8SWei Liu     }
203727458df8SWei Liu     if (inst_decoder->decode_op1) {
203827458df8SWei Liu         inst_decoder->decode_op1(env, decode, &decode->op[0]);
203927458df8SWei Liu     }
204027458df8SWei Liu     if (inst_decoder->decode_op2) {
204127458df8SWei Liu         inst_decoder->decode_op2(env, decode, &decode->op[1]);
204227458df8SWei Liu     }
204327458df8SWei Liu     if (inst_decoder->decode_op3) {
204427458df8SWei Liu         inst_decoder->decode_op3(env, decode, &decode->op[2]);
204527458df8SWei Liu     }
204627458df8SWei Liu     if (inst_decoder->decode_op4) {
204727458df8SWei Liu         inst_decoder->decode_op4(env, decode, &decode->op[3]);
204827458df8SWei Liu     }
204927458df8SWei Liu     if (inst_decoder->decode_postfix) {
205027458df8SWei Liu         inst_decoder->decode_postfix(env, decode);
205127458df8SWei Liu     }
205227458df8SWei Liu }
205327458df8SWei Liu 
205427458df8SWei Liu static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode,
205527458df8SWei Liu                                    uint8_t opcode)
205627458df8SWei Liu {
205727458df8SWei Liu     struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
205827458df8SWei Liu     decode_opcode_general(env, decode, opcode, inst_decoder);
205927458df8SWei Liu }
206027458df8SWei Liu 
206127458df8SWei Liu 
206227458df8SWei Liu static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode,
206327458df8SWei Liu                                    uint8_t opcode)
206427458df8SWei Liu {
206527458df8SWei Liu     struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
206627458df8SWei Liu     decode_opcode_general(env, decode, opcode, inst_decoder);
206727458df8SWei Liu }
206827458df8SWei Liu 
206927458df8SWei Liu static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
207027458df8SWei Liu {
207127458df8SWei Liu     uint8_t opcode;
207227458df8SWei Liu 
207327458df8SWei Liu     opcode = decode_byte(env, decode);
207427458df8SWei Liu     decode->opcode[decode->opcode_len++] = opcode;
207527458df8SWei Liu     if (opcode != OPCODE_ESCAPE) {
207627458df8SWei Liu         decode_opcode_1(env, decode, opcode);
207727458df8SWei Liu     } else {
207827458df8SWei Liu         opcode = decode_byte(env, decode);
207927458df8SWei Liu         decode->opcode[decode->opcode_len++] = opcode;
208027458df8SWei Liu         decode_opcode_2(env, decode, opcode);
208127458df8SWei Liu     }
208227458df8SWei Liu }
208327458df8SWei Liu 
208427458df8SWei Liu uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
208527458df8SWei Liu {
208627458df8SWei Liu     memset(decode, 0, sizeof(*decode));
208727458df8SWei Liu     decode_prefix(env, decode);
208827458df8SWei Liu     set_addressing_size(env, decode);
208927458df8SWei Liu     set_operand_size(env, decode);
209027458df8SWei Liu 
209127458df8SWei Liu     decode_opcodes(env, decode);
209227458df8SWei Liu 
209327458df8SWei Liu     return decode->len;
209427458df8SWei Liu }
209527458df8SWei Liu 
209627458df8SWei Liu void init_decoder(void)
209727458df8SWei Liu {
209827458df8SWei Liu     int i;
209927458df8SWei Liu 
210027458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) {
210127458df8SWei Liu         memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst));
210227458df8SWei Liu     }
210327458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
210427458df8SWei Liu         memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst));
210527458df8SWei Liu     }
210627458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
210727458df8SWei Liu         memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87));
210827458df8SWei Liu 
210927458df8SWei Liu     }
211027458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
211127458df8SWei Liu         _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
211227458df8SWei Liu     }
211327458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) {
211427458df8SWei Liu         _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i];
211527458df8SWei Liu     }
211627458df8SWei Liu     for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) {
211727458df8SWei Liu         int index = ((_x87_inst[i].opcode & 0xf) << 4) |
211827458df8SWei Liu                     ((_x87_inst[i].modrm_mod & 1) << 3) |
211927458df8SWei Liu                     _x87_inst[i].modrm_reg;
212027458df8SWei Liu         _decode_tbl3[index] = _x87_inst[i];
212127458df8SWei Liu     }
212227458df8SWei Liu }
212327458df8SWei Liu 
212427458df8SWei Liu 
212527458df8SWei Liu const char *decode_cmd_to_string(enum x86_decode_cmd cmd)
212627458df8SWei Liu {
212727458df8SWei Liu     static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG",
212827458df8SWei Liu         "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT",
212927458df8SWei Liu         "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD",
213027458df8SWei Liu         "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST",
213127458df8SWei Liu         "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR",
213227458df8SWei Liu         "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG",
213327458df8SWei Liu         "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN",
213427458df8SWei Liu         "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW",
213527458df8SWei Liu         "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR",
213627458df8SWei Liu         "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR",
213727458df8SWei Liu         "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL",
213827458df8SWei Liu         "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS",
213927458df8SWei Liu         "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT",
214027458df8SWei Liu         "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA",
214127458df8SWei Liu         "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT",
214227458df8SWei Liu         "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES",
214327458df8SWei Liu         "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT",
214427458df8SWei Liu         "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW",
214527458df8SWei Liu         "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV",
214627458df8SWei Liu         "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE",
214727458df8SWei Liu         "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW",
214827458df8SWei Liu         "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"};
214927458df8SWei Liu     return cmds[cmd];
215027458df8SWei Liu }
215127458df8SWei Liu 
215227458df8SWei Liu target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
215327458df8SWei Liu                                target_ulong addr, X86Seg seg)
215427458df8SWei Liu {
215527458df8SWei Liu     switch (decode->segment_override) {
215627458df8SWei Liu     case PREFIX_CS_SEG_OVERRIDE:
215727458df8SWei Liu         seg = R_CS;
215827458df8SWei Liu         break;
215927458df8SWei Liu     case PREFIX_SS_SEG_OVERRIDE:
216027458df8SWei Liu         seg = R_SS;
216127458df8SWei Liu         break;
216227458df8SWei Liu     case PREFIX_DS_SEG_OVERRIDE:
216327458df8SWei Liu         seg = R_DS;
216427458df8SWei Liu         break;
216527458df8SWei Liu     case PREFIX_ES_SEG_OVERRIDE:
216627458df8SWei Liu         seg = R_ES;
216727458df8SWei Liu         break;
216827458df8SWei Liu     case PREFIX_FS_SEG_OVERRIDE:
216927458df8SWei Liu         seg = R_FS;
217027458df8SWei Liu         break;
217127458df8SWei Liu     case PREFIX_GS_SEG_OVERRIDE:
217227458df8SWei Liu         seg = R_GS;
217327458df8SWei Liu         break;
217427458df8SWei Liu     default:
217527458df8SWei Liu         break;
217627458df8SWei Liu     }
217727458df8SWei Liu     return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg);
217827458df8SWei Liu }
2179