qemu/target/i386/hvf/x86_decode.h
<<
>>
Prefs
   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.1 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
  24typedef 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_OVERRIDE =       0x2e,
  31    PREFIX_SS_SEG_OVERRIDE =       0x36,
  32    PREFIX_DS_SEG_OVERRIDE =       0x3e,
  33    PREFIX_ES_SEG_OVERRIDE =       0x26,
  34    PREFIX_FS_SEG_OVERRIDE =       0x64,
  35    PREFIX_GS_SEG_OVERRIDE =       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
  44enum 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
 212const char *decode_cmd_to_string(enum x86_decode_cmd cmd);
 213
 214typedef 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
 225typedef 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
 236typedef 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
 249typedef 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
 262typedef 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
 272typedef 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
 302uint64_t sign(uint64_t val, int size);
 303
 304uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode);
 305
 306target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
 307                         int is_extended, int size);
 308target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
 309                         int is_extended, int size);
 310void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
 311                        struct x86_decode_op *op);
 312target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
 313                               target_ulong addr, enum X86Seg seg);
 314
 315void init_decoder(void);
 316void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
 317                          struct x86_decode_op *op);
 318void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
 319                          struct x86_decode_op *op);
 320void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
 321                          struct x86_decode_op *op);
 322void set_addressing_size(CPUX86State *env, struct x86_decode *decode);
 323void set_operand_size(CPUX86State *env, struct x86_decode *decode);
 324
 325#endif
 326