master
h 335 lines 8.64 KB
Raw
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 X86_EMU_DECODE_H
19 #define X86_EMU_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_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
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 union {
270 target_ulong addr;
271 void *regptr;
272 };
273 } x86_decode_op;
274
275 typedef struct x86_insn_stream {
276 const uint8_t *bytes;
277 size_t len;
278 } x86_insn_stream;
279
280 typedef struct x86_decode {
281 int len;
282 uint8_t opcode[4];
283 uint8_t opcode_len;
284 enum x86_decode_cmd cmd;
285 int addressing_size;
286 int operand_size;
287 int lock;
288 int rep;
289 int op_size_override;
290 int addr_size_override;
291 int segment_override;
292 int control_change_inst;
293 bool fwait;
294 bool fpop_stack;
295 bool frev;
296
297 uint32_t displacement;
298 uint8_t displacement_size;
299 struct x86_rex rex;
300 bool is_modrm;
301 bool sib_present;
302 struct x86_sib sib;
303 struct x86_modrm modrm;
304 struct x86_decode_op op[4];
305 bool is_fpu;
306
307 x86_insn_stream *stream;
308 } x86_decode;
309
310 uint64_t sign(uint64_t val, int size);
311
312 uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode);
313 uint32_t decode_instruction_stream(CPUX86State *env, struct x86_decode *decode,
314 struct x86_insn_stream *stream);
315
316 void *get_reg_ref(CPUX86State *env, int reg, int rex_present,
317 int is_extended, int size);
318 target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
319 int is_extended, int size);
320 void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
321 struct x86_decode_op *op);
322 target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
323 target_ulong addr, enum X86Seg seg);
324
325 void init_decoder(void);
326 void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
327 struct x86_decode_op *op);
328 void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
329 struct x86_decode_op *op);
330 void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
331 struct x86_decode_op *op);
332 void set_addressing_size(CPUX86State *env, struct x86_decode *decode);
333 void set_operand_size(CPUX86State *env, struct x86_decode *decode);
334
335 #endif