xref: /qemu/target/i386/hvf/x86_decode.h (revision 2e8f72ac)
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 
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     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_present,
307                          int is_extended, int size);
308 target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
309                          int is_extended, 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