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