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