1 /* cpu.h x86 cpu-description header-file */ 2 /* (c) in 2005-2006,2017 by Frank Wille */ 3 4 #define LITTLEENDIAN 1 5 #define BIGENDIAN 0 6 #define VASM_CPU_X86 1 7 #define MNEMOHTABSIZE 0x8000 8 9 /* maximum number of operands in one mnemonic */ 10 #define MAX_OPERANDS 3 11 12 /* maximum number of mnemonic-qualifiers per mnemonic */ 13 #define MAX_QUALIFIERS 1 14 15 /* data type to represent a target-address */ 16 typedef int64_t taddr; 17 typedef uint64_t utaddr; 18 19 /* minimum instruction alignment */ 20 #define INST_ALIGN 1 21 22 /* default alignment for n-bit data */ 23 #define DATA_ALIGN(n) 1 24 25 /* default alignment mode for .align directive */ 26 #define CPU_DEF_ALIGN 1 /* alignment in bytes */ 27 28 /* operand class for n-bit data definitions */ 29 int x86_data_operand(int); 30 #define DATA_OPERAND(n) x86_data_operand(n) 31 32 /* make sure operand is cleared upon first entry into parse_operand() */ 33 #define NEED_CLEARED_OPERANDS 1 34 35 36 /* register symbols */ 37 #define HAVE_REGSYMS 38 #define REGSYMHTSIZE 64 39 40 /* reg_flags: */ 41 #define RegRex 0x1 /* Extended register. */ 42 #define RegRex64 0x2 /* Extended 8 bit register. */ 43 44 45 /* type to store each operand */ 46 typedef struct { 47 int type; /* real type of operand */ 48 int parsed_type; /* type recognized by parser */ 49 unsigned int flags; 50 expr *value; /* displacement or immediate value */ 51 regsym *basereg; /* base-reg. for SIB or single register */ 52 regsym *indexreg; 53 expr *scalefactor; 54 regsym *segoverride; 55 int log2_scale; /* 0-3 for scale factor 1,2,4,8 */ 56 } operand; 57 58 /* register operand types */ 59 #define Reg8 0x1 60 #define Reg16 0x2 61 #define Reg32 0x4 62 #define Reg64 0x8 63 64 /* immediate operand types*/ 65 #define Imm8 0x10 66 #define Imm8S 0x20 67 #define Imm16 0x40 68 #define Imm32 0x80 69 #define Imm32S 0x100 70 #define Imm64 0x200 71 #define Imm1 0x400 /* for 1-bit shift-instructions */ 72 73 /* memory operand types */ 74 #define Disp8 0x800 75 #define Disp16 0x1000 76 #define Disp32 0x2000 77 #define Disp32S 0x4000 78 #define Disp64 0x8000 79 #define BaseIndex 0x10000 /* indirect base-register has optional index */ 80 81 /* special operand types */ 82 #define ShiftCntReg 0x20000 /* Shift-count register (%cl) */ 83 #define IOPortReg 0x40000 /* I/O port register (%dx) */ 84 #define CtrlReg 0x80000 85 #define DebugReg 0x100000 86 #define TestReg 0x200000 87 #define Acc 0x400000 /* Accumulator (%al or %ax or %eax) */ 88 #define SegReg2 0x800000 /* Segment register with 2 bits */ 89 #define SegReg3 0x1000000 /* Segment register with 3 bits */ 90 #define MMXReg 0x2000000 91 #define XMMReg 0x4000000 92 #define FloatReg 0x8000000 /* Float register %st(n) */ 93 #define FloatAcc 0x10000000 /* Float stack top %st(0), float-accumulator */ 94 #define EsSeg 0x20000000 /* String instr. oper. with fixed ES seg. */ 95 #define JmpAbs 0x40000000 /* Absolute jump/call instruction */ 96 #define InvMem 0x80000000 /* modrm-byte doesn't support memory form */ 97 98 /* data operands (@@@ define their own flags?) */ 99 #define FloatData (FloatAcc) 100 #define Data8 (Disp8) 101 #define Data16 (Disp16) 102 #define Data32 (Disp32) 103 #define Data64 (Disp64) 104 #define Float32 (Disp32|FloatData) 105 #define Float64 (Disp64|FloatData) 106 107 /* operand type groups */ 108 #define Reg (Reg8|Reg16|Reg32|Reg64) 109 #define WordReg (Reg16|Reg32|Reg64) 110 #define AnyReg (Reg|MMXReg|XMMReg|SegReg2|SegReg3|CtrlReg|DebugReg|TestReg) 111 #define ImpliedReg (IOPortReg|ShiftCntReg|Acc|FloatAcc) 112 #define Imm (Imm8|Imm8S|Imm16|Imm32S|Imm32|Imm64) 113 #define EncImm (Imm8|Imm16|Imm32|Imm32S) 114 #define Disp (Disp8|Disp16|Disp32|Disp32S|Disp64) 115 #define AnyMem (Disp8|Disp16|Disp32|Disp32S|BaseIndex|InvMem) 116 117 /* currently we do not differentiate between those memory types, */ 118 /* but the opcode table is prepared for it */ 119 #define LLongMem AnyMem 120 #define LongMem AnyMem 121 #define ShortMem AnyMem 122 #define WordMem AnyMem 123 #define ByteMem AnyMem 124 125 /* flags */ 126 #define OPER_REG 1 /* operand is a direct register */ 127 #define OPER_PCREL 2 /* PC-relative operand */ 128 129 130 /* x86 opcode prefixes */ 131 #define WAIT_PREFIX 0 132 #define LOCKREP_PREFIX 1 133 #define ADDR_PREFIX 2 134 #define DATA_PREFIX 3 135 #define SEG_PREFIX 4 136 #define REX_PREFIX 5 /* must be the last one */ 137 #define MAX_PREFIXES 6 /* maximum number of prefixes */ 138 139 140 /* x86 segment register numbers */ 141 #define ESEG_REGNUM 0 142 #define CSEG_REGNUM 1 143 #define SSEG_REGNUM 2 144 #define DSEG_REGNUM 3 145 #define FSEG_REGNUM 4 146 #define GSEG_REGNUM 5 147 148 149 /* Mod-R/M byte, which follows the opcode */ 150 typedef struct { 151 unsigned char mode; /* how to interpret regmem & reg */ 152 unsigned char reg; /* register operand or extended opcode */ 153 unsigned char regmem; /* register or memory operand (addr.mode) */ 154 } modrm_byte; 155 156 /* SIB (scale, index, base) byte, which follows modrm_byte in some 157 i386 addressing modes */ 158 typedef struct { 159 unsigned char scale; /* scale-factor (1, 2, 4 or 8) */ 160 unsigned char index; /* index register */ 161 unsigned char base; /* base register */ 162 } sib_byte; 163 164 #define EBP_REGNUM 5 165 #define ESP_REGNUM 4 166 167 /* modrm_byte.regmem for 2-byte opcode escape */ 168 #define TWO_BYTE_ESCAPE (ESP_REGNUM) 169 /* sib_byte.index for no index register */ 170 #define NO_INDEXREG (ESP_REGNUM) 171 /* sib_byte.base for no base register */ 172 #define NO_BASEREG (EBP_REGNUM) 173 #define NO_BASEREG16 6 174 175 176 /* instruction extension */ 177 #define HAVE_INSTRUCTION_EXTENSION 1 178 179 typedef struct { 180 uint32_t base_opcode; 181 unsigned char flags; 182 unsigned char num_prefixes; 183 unsigned char prefix[MAX_PREFIXES]; 184 modrm_byte rm; 185 sib_byte sib; 186 short last_size; 187 } instruction_ext; 188 189 /* flags: */ 190 #define HAS_REG_OPER 0x1 /* inst. has direct-register operands */ 191 #define SUFFIX_CHECKED 0x2 /* suffix assigned and checked */ 192 #define MODRM_BYTE 0x4 /* needs mod/rm byte */ 193 #define SIB_BYTE 0x8 /* needs sib byte */ 194 #define NEGOPT 0x40 /* negatively optimized, bytes gained */ 195 #define POSOPT 0x80 /* positively optimized, bytes gained */ 196 #define OPTFAILED (POSOPT|NEGOPT) /* no longer try to optimize this */ 197 198 /* max_opt_tries: 199 An instruction optimized more frequent than that is been considered 200 'oscillating' (e.g. by effects of alignment-directives) and should 201 no longer be optimized! */ 202 #define MAX_OPT_TRIES 10 203 204 205 /* additional mnemonic data */ 206 typedef struct { 207 uint32_t base_opcode; 208 uint32_t extension_opcode; 209 uint32_t opcode_modifier; 210 uint32_t available; 211 } mnemonic_extension; 212 213 /* extension_opcode */ 214 #define NO_EXTOPCODE 0xffff 215 216 /* cpu available flags: */ 217 #define CPU086 0x1 218 #define CPU186 0x2 219 #define CPU286 0x4 220 #define CPU386 0x8 221 #define CPU486 0x10 222 #define CPU586 0x20 223 #define CPU686 0x40 224 #define CPUP4 0x80 225 #define CPUK6 0x100 226 #define CPUAthlon 0x200 227 #define CPUSledgehammer 0x400 228 #define CPUMMX 0x800 229 #define CPUSSE 0x1000 230 #define CPUSSE2 0x2000 231 #define CPU3dnow 0x4000 232 #define CPUPNI 0x8000 233 #define CPUPadLock 0x10000 234 #define CPU64 0x4000000 235 #define CPUNo64 0x8000000 236 #define CPUAny (CPU086|CPU186|CPU286|CPU386|CPU486|CPU586|CPU686|CPUP4|CPUSledgehammer|CPUMMX|CPUSSE|CPUSSE2|CPUPNI|CPU3dnow|CPUK6|CPUAthlon|CPUPadLock) 237 238 /* opcode_modifier: */ 239 #define W 0x1 /* operands can be words or dwords */ 240 #define M 0x4 /* has Modrm byte */ 241 #define FloatR 0x8 /* swapped src/dest for floats: MUST BE 0x8 */ 242 #define ShortForm 0x10 /* reg. enc. in 3 low-order bits of opcode */ 243 #define FloatMF 0x20 /* FP insn memory format bit, sized by 0x4 */ 244 #define Jmp 0x40 /* relative conditional and uncond. branches */ 245 #define JmpDword 0x80 /* relative 16/32 bit calls */ 246 #define JmpByte 0x100 /* loop and jecxz */ 247 #define JmpInterSeg 0x200 /* inter segment calls and branches */ 248 #define FloatD 0x400 /* direction for FP insns: MUST BE 0x400 */ 249 #define Seg2ShortForm 0x800 /* 2-bit segment reg. encoded in opcode */ 250 #define Seg3ShortForm 0x1000 /* 3-bit segment reg. encoded in opcode */ 251 #define Size16 0x2000 /* needs a size prefix in 32-bit mode */ 252 #define Size32 0x4000 /* needs a size prefix in 16-bit mode */ 253 #define Size64 0x8000 /* needs a size prefix in 16-bit mode */ 254 #define IgnoreSize 0x10000 /* operand size prefix is ignored */ 255 #define DefaultSize 0x20000 /* default instruction size depends on mode */ 256 #define b_Illegal 0x40000 /* b suffix is illegal */ 257 #define w_Illegal 0x80000 /* w suffix is illegal */ 258 #define l_Illegal 0x100000 /* l suffix is illegal */ 259 #define s_Illegal 0x200000 /* s suffix is illegal */ 260 #define q_Illegal 0x400000 /* q suffix is illegal */ 261 #define x_Illegal 0x800000 /* x suffix is illegal */ 262 #define FWait 0x1000000 /* needs an FWAIT prefix */ 263 #define StrInst 0x2000000 /* string instructions */ 264 #define FakeLastReg 0x4000000 /* duplicate last reg. for clr and imul */ 265 #define IsPrefix 0x8000000 /* opcode is a prefix */ 266 #define ImmExt 0x10000000 /* has extension in 8 bit immediate */ 267 #define NoRex64 0x20000000 /* doesn't require REX64 prefix */ 268 #define Rex64 0x40000000 /* requires REX64 prefix */ 269 #define Deprecated 0x80000000 /* deprecated FPU instruction */ 270