1*27458df8SWei Liu /* 2*27458df8SWei Liu * Copyright (C) 2016 Veertu Inc, 3*27458df8SWei Liu * 4*27458df8SWei Liu * This program is free software; you can redistribute it and/or 5*27458df8SWei Liu * modify it under the terms of the GNU Lesser General Public 6*27458df8SWei Liu * License as published by the Free Software Foundation; either 7*27458df8SWei Liu * version 2.1 of the License, or (at your option) any later version. 8*27458df8SWei Liu * 9*27458df8SWei Liu * This program is distributed in the hope that it will be useful, 10*27458df8SWei Liu * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*27458df8SWei Liu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12*27458df8SWei Liu * Lesser General Public License for more details. 13*27458df8SWei Liu * 14*27458df8SWei Liu * You should have received a copy of the GNU Lesser General Public 15*27458df8SWei Liu * License along with this program; if not, see <http://www.gnu.org/licenses/>. 16*27458df8SWei Liu */ 17*27458df8SWei Liu 18*27458df8SWei Liu #ifndef X86_EMU_DECODE_H 19*27458df8SWei Liu #define X86_EMU_DECODE_H 20*27458df8SWei Liu 21*27458df8SWei Liu #include "cpu.h" 22*27458df8SWei Liu #include "x86.h" 23*27458df8SWei Liu 24*27458df8SWei Liu typedef enum x86_prefix { 25*27458df8SWei Liu /* group 1 */ 26*27458df8SWei Liu PREFIX_LOCK = 0xf0, 27*27458df8SWei Liu PREFIX_REPN = 0xf2, 28*27458df8SWei Liu PREFIX_REP = 0xf3, 29*27458df8SWei Liu /* group 2 */ 30*27458df8SWei Liu PREFIX_CS_SEG_OVERRIDE = 0x2e, 31*27458df8SWei Liu PREFIX_SS_SEG_OVERRIDE = 0x36, 32*27458df8SWei Liu PREFIX_DS_SEG_OVERRIDE = 0x3e, 33*27458df8SWei Liu PREFIX_ES_SEG_OVERRIDE = 0x26, 34*27458df8SWei Liu PREFIX_FS_SEG_OVERRIDE = 0x64, 35*27458df8SWei Liu PREFIX_GS_SEG_OVERRIDE = 0x65, 36*27458df8SWei Liu /* group 3 */ 37*27458df8SWei Liu PREFIX_OP_SIZE_OVERRIDE = 0x66, 38*27458df8SWei Liu /* group 4 */ 39*27458df8SWei Liu PREFIX_ADDR_SIZE_OVERRIDE = 0x67, 40*27458df8SWei Liu 41*27458df8SWei Liu PREFIX_REX = 0x40, 42*27458df8SWei Liu } x86_prefix; 43*27458df8SWei Liu 44*27458df8SWei Liu enum x86_decode_cmd { 45*27458df8SWei Liu X86_DECODE_CMD_INVL = 0, 46*27458df8SWei Liu 47*27458df8SWei Liu X86_DECODE_CMD_PUSH, 48*27458df8SWei Liu X86_DECODE_CMD_PUSH_SEG, 49*27458df8SWei Liu X86_DECODE_CMD_POP, 50*27458df8SWei Liu X86_DECODE_CMD_POP_SEG, 51*27458df8SWei Liu X86_DECODE_CMD_MOV, 52*27458df8SWei Liu X86_DECODE_CMD_MOVSX, 53*27458df8SWei Liu X86_DECODE_CMD_MOVZX, 54*27458df8SWei Liu X86_DECODE_CMD_CALL_NEAR, 55*27458df8SWei Liu X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT, 56*27458df8SWei Liu X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT, 57*27458df8SWei Liu X86_DECODE_CMD_CALL_FAR, 58*27458df8SWei Liu X86_DECODE_RET_NEAR, 59*27458df8SWei Liu X86_DECODE_RET_FAR, 60*27458df8SWei Liu X86_DECODE_CMD_ADD, 61*27458df8SWei Liu X86_DECODE_CMD_OR, 62*27458df8SWei Liu X86_DECODE_CMD_ADC, 63*27458df8SWei Liu X86_DECODE_CMD_SBB, 64*27458df8SWei Liu X86_DECODE_CMD_AND, 65*27458df8SWei Liu X86_DECODE_CMD_SUB, 66*27458df8SWei Liu X86_DECODE_CMD_XOR, 67*27458df8SWei Liu X86_DECODE_CMD_CMP, 68*27458df8SWei Liu X86_DECODE_CMD_INC, 69*27458df8SWei Liu X86_DECODE_CMD_DEC, 70*27458df8SWei Liu X86_DECODE_CMD_TST, 71*27458df8SWei Liu X86_DECODE_CMD_NOT, 72*27458df8SWei Liu X86_DECODE_CMD_NEG, 73*27458df8SWei Liu X86_DECODE_CMD_JMP_NEAR, 74*27458df8SWei Liu X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT, 75*27458df8SWei Liu X86_DECODE_CMD_JMP_FAR, 76*27458df8SWei Liu X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT, 77*27458df8SWei Liu X86_DECODE_CMD_LEA, 78*27458df8SWei Liu X86_DECODE_CMD_JXX, 79*27458df8SWei Liu X86_DECODE_CMD_JCXZ, 80*27458df8SWei Liu X86_DECODE_CMD_SETXX, 81*27458df8SWei Liu X86_DECODE_CMD_MOV_TO_SEG, 82*27458df8SWei Liu X86_DECODE_CMD_MOV_FROM_SEG, 83*27458df8SWei Liu X86_DECODE_CMD_CLI, 84*27458df8SWei Liu X86_DECODE_CMD_STI, 85*27458df8SWei Liu X86_DECODE_CMD_CLD, 86*27458df8SWei Liu X86_DECODE_CMD_STD, 87*27458df8SWei Liu X86_DECODE_CMD_STC, 88*27458df8SWei Liu X86_DECODE_CMD_CLC, 89*27458df8SWei Liu X86_DECODE_CMD_OUT, 90*27458df8SWei Liu X86_DECODE_CMD_IN, 91*27458df8SWei Liu X86_DECODE_CMD_INS, 92*27458df8SWei Liu X86_DECODE_CMD_OUTS, 93*27458df8SWei Liu X86_DECODE_CMD_LIDT, 94*27458df8SWei Liu X86_DECODE_CMD_SIDT, 95*27458df8SWei Liu X86_DECODE_CMD_LGDT, 96*27458df8SWei Liu X86_DECODE_CMD_SGDT, 97*27458df8SWei Liu X86_DECODE_CMD_SMSW, 98*27458df8SWei Liu X86_DECODE_CMD_LMSW, 99*27458df8SWei Liu X86_DECODE_CMD_RDTSCP, 100*27458df8SWei Liu X86_DECODE_CMD_INVLPG, 101*27458df8SWei Liu X86_DECODE_CMD_MOV_TO_CR, 102*27458df8SWei Liu X86_DECODE_CMD_MOV_FROM_CR, 103*27458df8SWei Liu X86_DECODE_CMD_MOV_TO_DR, 104*27458df8SWei Liu X86_DECODE_CMD_MOV_FROM_DR, 105*27458df8SWei Liu X86_DECODE_CMD_PUSHF, 106*27458df8SWei Liu X86_DECODE_CMD_POPF, 107*27458df8SWei Liu X86_DECODE_CMD_CPUID, 108*27458df8SWei Liu X86_DECODE_CMD_ROL, 109*27458df8SWei Liu X86_DECODE_CMD_ROR, 110*27458df8SWei Liu X86_DECODE_CMD_RCL, 111*27458df8SWei Liu X86_DECODE_CMD_RCR, 112*27458df8SWei Liu X86_DECODE_CMD_SHL, 113*27458df8SWei Liu X86_DECODE_CMD_SAL, 114*27458df8SWei Liu X86_DECODE_CMD_SHR, 115*27458df8SWei Liu X86_DECODE_CMD_SHRD, 116*27458df8SWei Liu X86_DECODE_CMD_SHLD, 117*27458df8SWei Liu X86_DECODE_CMD_SAR, 118*27458df8SWei Liu X86_DECODE_CMD_DIV, 119*27458df8SWei Liu X86_DECODE_CMD_IDIV, 120*27458df8SWei Liu X86_DECODE_CMD_MUL, 121*27458df8SWei Liu X86_DECODE_CMD_IMUL_3, 122*27458df8SWei Liu X86_DECODE_CMD_IMUL_2, 123*27458df8SWei Liu X86_DECODE_CMD_IMUL_1, 124*27458df8SWei Liu X86_DECODE_CMD_MOVS, 125*27458df8SWei Liu X86_DECODE_CMD_CMPS, 126*27458df8SWei Liu X86_DECODE_CMD_SCAS, 127*27458df8SWei Liu X86_DECODE_CMD_LODS, 128*27458df8SWei Liu X86_DECODE_CMD_STOS, 129*27458df8SWei Liu X86_DECODE_CMD_BSWAP, 130*27458df8SWei Liu X86_DECODE_CMD_XCHG, 131*27458df8SWei Liu X86_DECODE_CMD_RDTSC, 132*27458df8SWei Liu X86_DECODE_CMD_RDMSR, 133*27458df8SWei Liu X86_DECODE_CMD_WRMSR, 134*27458df8SWei Liu X86_DECODE_CMD_ENTER, 135*27458df8SWei Liu X86_DECODE_CMD_LEAVE, 136*27458df8SWei Liu X86_DECODE_CMD_BT, 137*27458df8SWei Liu X86_DECODE_CMD_BTS, 138*27458df8SWei Liu X86_DECODE_CMD_BTC, 139*27458df8SWei Liu X86_DECODE_CMD_BTR, 140*27458df8SWei Liu X86_DECODE_CMD_BSF, 141*27458df8SWei Liu X86_DECODE_CMD_BSR, 142*27458df8SWei Liu X86_DECODE_CMD_IRET, 143*27458df8SWei Liu X86_DECODE_CMD_INT, 144*27458df8SWei Liu X86_DECODE_CMD_POPA, 145*27458df8SWei Liu X86_DECODE_CMD_PUSHA, 146*27458df8SWei Liu X86_DECODE_CMD_CWD, 147*27458df8SWei Liu X86_DECODE_CMD_CBW, 148*27458df8SWei Liu X86_DECODE_CMD_DAS, 149*27458df8SWei Liu X86_DECODE_CMD_AAD, 150*27458df8SWei Liu X86_DECODE_CMD_AAM, 151*27458df8SWei Liu X86_DECODE_CMD_AAS, 152*27458df8SWei Liu X86_DECODE_CMD_LOOP, 153*27458df8SWei Liu X86_DECODE_CMD_SLDT, 154*27458df8SWei Liu X86_DECODE_CMD_STR, 155*27458df8SWei Liu X86_DECODE_CMD_LLDT, 156*27458df8SWei Liu X86_DECODE_CMD_LTR, 157*27458df8SWei Liu X86_DECODE_CMD_VERR, 158*27458df8SWei Liu X86_DECODE_CMD_VERW, 159*27458df8SWei Liu X86_DECODE_CMD_SAHF, 160*27458df8SWei Liu X86_DECODE_CMD_LAHF, 161*27458df8SWei Liu X86_DECODE_CMD_WBINVD, 162*27458df8SWei Liu X86_DECODE_CMD_LDS, 163*27458df8SWei Liu X86_DECODE_CMD_LSS, 164*27458df8SWei Liu X86_DECODE_CMD_LES, 165*27458df8SWei Liu X86_DECODE_XMD_LGS, 166*27458df8SWei Liu X86_DECODE_CMD_LFS, 167*27458df8SWei Liu X86_DECODE_CMD_CMC, 168*27458df8SWei Liu X86_DECODE_CMD_XLAT, 169*27458df8SWei Liu X86_DECODE_CMD_NOP, 170*27458df8SWei Liu X86_DECODE_CMD_CMOV, 171*27458df8SWei Liu X86_DECODE_CMD_CLTS, 172*27458df8SWei Liu X86_DECODE_CMD_XADD, 173*27458df8SWei Liu X86_DECODE_CMD_HLT, 174*27458df8SWei Liu X86_DECODE_CMD_CMPXCHG8B, 175*27458df8SWei Liu X86_DECODE_CMD_CMPXCHG, 176*27458df8SWei Liu X86_DECODE_CMD_POPCNT, 177*27458df8SWei Liu 178*27458df8SWei Liu X86_DECODE_CMD_FNINIT, 179*27458df8SWei Liu X86_DECODE_CMD_FLD, 180*27458df8SWei Liu X86_DECODE_CMD_FLDxx, 181*27458df8SWei Liu X86_DECODE_CMD_FNSTCW, 182*27458df8SWei Liu X86_DECODE_CMD_FNSTSW, 183*27458df8SWei Liu X86_DECODE_CMD_FNSETPM, 184*27458df8SWei Liu X86_DECODE_CMD_FSAVE, 185*27458df8SWei Liu X86_DECODE_CMD_FRSTOR, 186*27458df8SWei Liu X86_DECODE_CMD_FXSAVE, 187*27458df8SWei Liu X86_DECODE_CMD_FXRSTOR, 188*27458df8SWei Liu X86_DECODE_CMD_FDIV, 189*27458df8SWei Liu X86_DECODE_CMD_FMUL, 190*27458df8SWei Liu X86_DECODE_CMD_FSUB, 191*27458df8SWei Liu X86_DECODE_CMD_FADD, 192*27458df8SWei Liu X86_DECODE_CMD_EMMS, 193*27458df8SWei Liu X86_DECODE_CMD_MFENCE, 194*27458df8SWei Liu X86_DECODE_CMD_SFENCE, 195*27458df8SWei Liu X86_DECODE_CMD_LFENCE, 196*27458df8SWei Liu X86_DECODE_CMD_PREFETCH, 197*27458df8SWei Liu X86_DECODE_CMD_CLFLUSH, 198*27458df8SWei Liu X86_DECODE_CMD_FST, 199*27458df8SWei Liu X86_DECODE_CMD_FABS, 200*27458df8SWei Liu X86_DECODE_CMD_FUCOM, 201*27458df8SWei Liu X86_DECODE_CMD_FUCOMI, 202*27458df8SWei Liu X86_DECODE_CMD_FLDCW, 203*27458df8SWei Liu X86_DECODE_CMD_FXCH, 204*27458df8SWei Liu X86_DECODE_CMD_FCHS, 205*27458df8SWei Liu X86_DECODE_CMD_FCMOV, 206*27458df8SWei Liu X86_DECODE_CMD_FRNDINT, 207*27458df8SWei Liu X86_DECODE_CMD_FXAM, 208*27458df8SWei Liu 209*27458df8SWei Liu X86_DECODE_CMD_LAST, 210*27458df8SWei Liu }; 211*27458df8SWei Liu 212*27458df8SWei Liu const char *decode_cmd_to_string(enum x86_decode_cmd cmd); 213*27458df8SWei Liu 214*27458df8SWei Liu typedef struct x86_modrm { 215*27458df8SWei Liu union { 216*27458df8SWei Liu uint8_t modrm; 217*27458df8SWei Liu struct { 218*27458df8SWei Liu uint8_t rm:3; 219*27458df8SWei Liu uint8_t reg:3; 220*27458df8SWei Liu uint8_t mod:2; 221*27458df8SWei Liu }; 222*27458df8SWei Liu }; 223*27458df8SWei Liu } __attribute__ ((__packed__)) x86_modrm; 224*27458df8SWei Liu 225*27458df8SWei Liu typedef struct x86_sib { 226*27458df8SWei Liu union { 227*27458df8SWei Liu uint8_t sib; 228*27458df8SWei Liu struct { 229*27458df8SWei Liu uint8_t base:3; 230*27458df8SWei Liu uint8_t index:3; 231*27458df8SWei Liu uint8_t scale:2; 232*27458df8SWei Liu }; 233*27458df8SWei Liu }; 234*27458df8SWei Liu } __attribute__ ((__packed__)) x86_sib; 235*27458df8SWei Liu 236*27458df8SWei Liu typedef struct x86_rex { 237*27458df8SWei Liu union { 238*27458df8SWei Liu uint8_t rex; 239*27458df8SWei Liu struct { 240*27458df8SWei Liu uint8_t b:1; 241*27458df8SWei Liu uint8_t x:1; 242*27458df8SWei Liu uint8_t r:1; 243*27458df8SWei Liu uint8_t w:1; 244*27458df8SWei Liu uint8_t unused:4; 245*27458df8SWei Liu }; 246*27458df8SWei Liu }; 247*27458df8SWei Liu } __attribute__ ((__packed__)) x86_rex; 248*27458df8SWei Liu 249*27458df8SWei Liu typedef enum x86_var_type { 250*27458df8SWei Liu X86_VAR_IMMEDIATE, 251*27458df8SWei Liu X86_VAR_OFFSET, 252*27458df8SWei Liu X86_VAR_REG, 253*27458df8SWei Liu X86_VAR_RM, 254*27458df8SWei Liu 255*27458df8SWei Liu /* for floating point computations */ 256*27458df8SWei Liu X87_VAR_REG, 257*27458df8SWei Liu X87_VAR_FLOATP, 258*27458df8SWei Liu X87_VAR_INTP, 259*27458df8SWei Liu X87_VAR_BYTEP, 260*27458df8SWei Liu } x86_var_type; 261*27458df8SWei Liu 262*27458df8SWei Liu typedef struct x86_decode_op { 263*27458df8SWei Liu enum x86_var_type type; 264*27458df8SWei Liu int size; 265*27458df8SWei Liu 266*27458df8SWei Liu int reg; 267*27458df8SWei Liu target_ulong val; 268*27458df8SWei Liu 269*27458df8SWei Liu target_ulong ptr; 270*27458df8SWei Liu } x86_decode_op; 271*27458df8SWei Liu 272*27458df8SWei Liu typedef struct x86_decode { 273*27458df8SWei Liu int len; 274*27458df8SWei Liu uint8_t opcode[4]; 275*27458df8SWei Liu uint8_t opcode_len; 276*27458df8SWei Liu enum x86_decode_cmd cmd; 277*27458df8SWei Liu int addressing_size; 278*27458df8SWei Liu int operand_size; 279*27458df8SWei Liu int lock; 280*27458df8SWei Liu int rep; 281*27458df8SWei Liu int op_size_override; 282*27458df8SWei Liu int addr_size_override; 283*27458df8SWei Liu int segment_override; 284*27458df8SWei Liu int control_change_inst; 285*27458df8SWei Liu bool fwait; 286*27458df8SWei Liu bool fpop_stack; 287*27458df8SWei Liu bool frev; 288*27458df8SWei Liu 289*27458df8SWei Liu uint32_t displacement; 290*27458df8SWei Liu uint8_t displacement_size; 291*27458df8SWei Liu struct x86_rex rex; 292*27458df8SWei Liu bool is_modrm; 293*27458df8SWei Liu bool sib_present; 294*27458df8SWei Liu struct x86_sib sib; 295*27458df8SWei Liu struct x86_modrm modrm; 296*27458df8SWei Liu struct x86_decode_op op[4]; 297*27458df8SWei Liu bool is_fpu; 298*27458df8SWei Liu uint32_t flags_mask; 299*27458df8SWei Liu 300*27458df8SWei Liu } x86_decode; 301*27458df8SWei Liu 302*27458df8SWei Liu uint64_t sign(uint64_t val, int size); 303*27458df8SWei Liu 304*27458df8SWei Liu uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode); 305*27458df8SWei Liu 306*27458df8SWei Liu target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, 307*27458df8SWei Liu int is_extended, int size); 308*27458df8SWei Liu target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present, 309*27458df8SWei Liu int is_extended, int size); 310*27458df8SWei Liu void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode, 311*27458df8SWei Liu struct x86_decode_op *op); 312*27458df8SWei Liu target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode, 313*27458df8SWei Liu target_ulong addr, enum X86Seg seg); 314*27458df8SWei Liu 315*27458df8SWei Liu void init_decoder(void); 316*27458df8SWei Liu void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, 317*27458df8SWei Liu struct x86_decode_op *op); 318*27458df8SWei Liu void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode, 319*27458df8SWei Liu struct x86_decode_op *op); 320*27458df8SWei Liu void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode, 321*27458df8SWei Liu struct x86_decode_op *op); 322*27458df8SWei Liu void set_addressing_size(CPUX86State *env, struct x86_decode *decode); 323*27458df8SWei Liu void set_operand_size(CPUX86State *env, struct x86_decode *decode); 324*27458df8SWei Liu 325*27458df8SWei Liu #endif 326