]>
Commit | Line | Data |
---|---|---|
c97d6d2c SAGDR |
1 | /* |
2 | * Copyright (C) 2016 Veertu Inc, | |
3 | * Copyright (C) 2017 Google Inc, | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or | |
996feed4 SAGDR |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either | |
8 | * version 2 of the License, or (at your option) any later version. | |
c97d6d2c SAGDR |
9 | * |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
996feed4 SAGDR |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. | |
c97d6d2c | 14 | * |
996feed4 SAGDR |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this program; if not, see <http://www.gnu.org/licenses/>. | |
c97d6d2c SAGDR |
17 | */ |
18 | ||
19 | #include "qemu/osdep.h" | |
20 | ||
f9fea777 | 21 | #include "qemu-common.h" |
895f9fdf | 22 | #include "panic.h" |
c97d6d2c | 23 | #include "x86_decode.h" |
c97d6d2c | 24 | #include "vmx.h" |
c97d6d2c SAGDR |
25 | #include "x86_mmu.h" |
26 | #include "x86_descr.h" | |
27 | ||
28 | #define OPCODE_ESCAPE 0xf | |
29 | ||
30 | static void decode_invalid(CPUX86State *env, struct x86_decode *decode) | |
31 | { | |
32 | printf("%llx: failed to decode instruction ", env->hvf_emul->fetch_rip - | |
33 | decode->len); | |
34 | for (int i = 0; i < decode->opcode_len; i++) { | |
35 | printf("%x ", decode->opcode[i]); | |
36 | } | |
37 | printf("\n"); | |
38 | VM_PANIC("decoder failed\n"); | |
39 | } | |
40 | ||
41 | uint64_t sign(uint64_t val, int size) | |
42 | { | |
43 | switch (size) { | |
44 | case 1: | |
45 | val = (int8_t)val; | |
46 | break; | |
47 | case 2: | |
48 | val = (int16_t)val; | |
49 | break; | |
50 | case 4: | |
51 | val = (int32_t)val; | |
52 | break; | |
53 | case 8: | |
54 | val = (int64_t)val; | |
55 | break; | |
56 | default: | |
57 | VM_PANIC_EX("%s invalid size %d\n", __func__, size); | |
58 | break; | |
59 | } | |
60 | return val; | |
61 | } | |
62 | ||
63 | static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode, | |
64 | int size) | |
65 | { | |
ff2de166 | 66 | target_ulong val = 0; |
c97d6d2c SAGDR |
67 | |
68 | switch (size) { | |
69 | case 1: | |
70 | case 2: | |
71 | case 4: | |
72 | case 8: | |
73 | break; | |
74 | default: | |
75 | VM_PANIC_EX("%s invalid size %d\n", __func__, size); | |
76 | break; | |
77 | } | |
ff2de166 | 78 | target_ulong va = linear_rip(ENV_GET_CPU(env), RIP(env)) + decode->len; |
c97d6d2c SAGDR |
79 | vmx_read_mem(ENV_GET_CPU(env), &val, va, size); |
80 | decode->len += size; | |
81 | ||
82 | return val; | |
83 | } | |
84 | ||
85 | static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode) | |
86 | { | |
87 | return (uint8_t)decode_bytes(env, decode, 1); | |
88 | } | |
89 | ||
90 | static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode) | |
91 | { | |
92 | return (uint16_t)decode_bytes(env, decode, 2); | |
93 | } | |
94 | ||
95 | static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode) | |
96 | { | |
97 | return (uint32_t)decode_bytes(env, decode, 4); | |
98 | } | |
99 | ||
100 | static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode) | |
101 | { | |
102 | return decode_bytes(env, decode, 8); | |
103 | } | |
104 | ||
105 | static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode, | |
106 | struct x86_decode_op *op) | |
107 | { | |
108 | op->type = X86_VAR_RM; | |
109 | } | |
110 | ||
111 | static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode, | |
112 | struct x86_decode_op *op) | |
113 | { | |
114 | op->type = X86_VAR_REG; | |
115 | op->reg = decode->modrm.reg; | |
b4e1af89 RB |
116 | op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r, |
117 | decode->operand_size); | |
c97d6d2c SAGDR |
118 | } |
119 | ||
120 | static void decode_rax(CPUX86State *env, struct x86_decode *decode, | |
121 | struct x86_decode_op *op) | |
122 | { | |
123 | op->type = X86_VAR_REG; | |
6701d81d | 124 | op->reg = R_EAX; |
b4e1af89 RB |
125 | op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, 0, |
126 | decode->operand_size); | |
c97d6d2c SAGDR |
127 | } |
128 | ||
129 | static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode, | |
130 | struct x86_decode_op *var, int size) | |
131 | { | |
132 | var->type = X86_VAR_IMMEDIATE; | |
133 | var->size = size; | |
134 | switch (size) { | |
135 | case 1: | |
136 | var->val = decode_byte(env, decode); | |
137 | break; | |
138 | case 2: | |
139 | var->val = decode_word(env, decode); | |
140 | break; | |
141 | case 4: | |
142 | var->val = decode_dword(env, decode); | |
143 | break; | |
144 | case 8: | |
145 | var->val = decode_qword(env, decode); | |
146 | break; | |
147 | default: | |
148 | VM_PANIC_EX("bad size %d\n", size); | |
149 | } | |
150 | } | |
151 | ||
152 | static void decode_imm8(CPUX86State *env, struct x86_decode *decode, | |
153 | struct x86_decode_op *op) | |
154 | { | |
155 | decode_immediate(env, decode, op, 1); | |
156 | op->type = X86_VAR_IMMEDIATE; | |
157 | } | |
158 | ||
159 | static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode, | |
160 | struct x86_decode_op *op) | |
161 | { | |
162 | decode_immediate(env, decode, op, 1); | |
163 | op->val = sign(op->val, 1); | |
164 | op->type = X86_VAR_IMMEDIATE; | |
165 | } | |
166 | ||
167 | static void decode_imm16(CPUX86State *env, struct x86_decode *decode, | |
168 | struct x86_decode_op *op) | |
169 | { | |
170 | decode_immediate(env, decode, op, 2); | |
171 | op->type = X86_VAR_IMMEDIATE; | |
172 | } | |
173 | ||
174 | ||
175 | static void decode_imm(CPUX86State *env, struct x86_decode *decode, | |
176 | struct x86_decode_op *op) | |
177 | { | |
178 | if (8 == decode->operand_size) { | |
179 | decode_immediate(env, decode, op, 4); | |
180 | op->val = sign(op->val, decode->operand_size); | |
181 | } else { | |
182 | decode_immediate(env, decode, op, decode->operand_size); | |
183 | } | |
184 | op->type = X86_VAR_IMMEDIATE; | |
185 | } | |
186 | ||
187 | static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode, | |
188 | struct x86_decode_op *op) | |
189 | { | |
190 | decode_immediate(env, decode, op, decode->operand_size); | |
191 | op->val = sign(op->val, decode->operand_size); | |
192 | op->type = X86_VAR_IMMEDIATE; | |
193 | } | |
194 | ||
195 | static void decode_imm_1(CPUX86State *env, struct x86_decode *decode, | |
196 | struct x86_decode_op *op) | |
197 | { | |
198 | op->type = X86_VAR_IMMEDIATE; | |
199 | op->val = 1; | |
200 | } | |
201 | ||
202 | static void decode_imm_0(CPUX86State *env, struct x86_decode *decode, | |
203 | struct x86_decode_op *op) | |
204 | { | |
205 | op->type = X86_VAR_IMMEDIATE; | |
206 | op->val = 0; | |
207 | } | |
208 | ||
209 | ||
210 | static void decode_pushseg(CPUX86State *env, struct x86_decode *decode) | |
211 | { | |
212 | uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0]; | |
213 | ||
214 | decode->op[0].type = X86_VAR_REG; | |
215 | switch (op) { | |
216 | case 0xe: | |
6701d81d | 217 | decode->op[0].reg = R_CS; |
c97d6d2c SAGDR |
218 | break; |
219 | case 0x16: | |
6701d81d | 220 | decode->op[0].reg = R_SS; |
c97d6d2c SAGDR |
221 | break; |
222 | case 0x1e: | |
6701d81d | 223 | decode->op[0].reg = R_DS; |
c97d6d2c SAGDR |
224 | break; |
225 | case 0x06: | |
6701d81d | 226 | decode->op[0].reg = R_ES; |
c97d6d2c SAGDR |
227 | break; |
228 | case 0xa0: | |
6701d81d | 229 | decode->op[0].reg = R_FS; |
c97d6d2c SAGDR |
230 | break; |
231 | case 0xa8: | |
6701d81d | 232 | decode->op[0].reg = R_GS; |
c97d6d2c SAGDR |
233 | break; |
234 | } | |
235 | } | |
236 | ||
237 | static void decode_popseg(CPUX86State *env, struct x86_decode *decode) | |
238 | { | |
239 | uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0]; | |
240 | ||
241 | decode->op[0].type = X86_VAR_REG; | |
242 | switch (op) { | |
243 | case 0xf: | |
6701d81d | 244 | decode->op[0].reg = R_CS; |
c97d6d2c SAGDR |
245 | break; |
246 | case 0x17: | |
6701d81d | 247 | decode->op[0].reg = R_SS; |
c97d6d2c SAGDR |
248 | break; |
249 | case 0x1f: | |
6701d81d | 250 | decode->op[0].reg = R_DS; |
c97d6d2c SAGDR |
251 | break; |
252 | case 0x07: | |
6701d81d | 253 | decode->op[0].reg = R_ES; |
c97d6d2c SAGDR |
254 | break; |
255 | case 0xa1: | |
6701d81d | 256 | decode->op[0].reg = R_FS; |
c97d6d2c SAGDR |
257 | break; |
258 | case 0xa9: | |
6701d81d | 259 | decode->op[0].reg = R_GS; |
c97d6d2c SAGDR |
260 | break; |
261 | } | |
262 | } | |
263 | ||
264 | static void decode_incgroup(CPUX86State *env, struct x86_decode *decode) | |
265 | { | |
266 | decode->op[0].type = X86_VAR_REG; | |
267 | decode->op[0].reg = decode->opcode[0] - 0x40; | |
b4e1af89 RB |
268 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
269 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
270 | } |
271 | ||
272 | static void decode_decgroup(CPUX86State *env, struct x86_decode *decode) | |
273 | { | |
274 | decode->op[0].type = X86_VAR_REG; | |
275 | decode->op[0].reg = decode->opcode[0] - 0x48; | |
b4e1af89 RB |
276 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
277 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
278 | } |
279 | ||
280 | static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode) | |
281 | { | |
282 | if (!decode->modrm.reg) { | |
283 | decode->cmd = X86_DECODE_CMD_INC; | |
284 | } else if (1 == decode->modrm.reg) { | |
285 | decode->cmd = X86_DECODE_CMD_DEC; | |
286 | } | |
287 | } | |
288 | ||
289 | static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode) | |
290 | { | |
291 | decode->op[0].type = X86_VAR_REG; | |
292 | decode->op[0].reg = decode->opcode[0] - 0x50; | |
b4e1af89 RB |
293 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
294 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
295 | } |
296 | ||
297 | static void decode_popgroup(CPUX86State *env, struct x86_decode *decode) | |
298 | { | |
299 | decode->op[0].type = X86_VAR_REG; | |
300 | decode->op[0].reg = decode->opcode[0] - 0x58; | |
b4e1af89 RB |
301 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
302 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
303 | } |
304 | ||
305 | static void decode_jxx(CPUX86State *env, struct x86_decode *decode) | |
306 | { | |
307 | decode->displacement = decode_bytes(env, decode, decode->operand_size); | |
308 | decode->displacement_size = decode->operand_size; | |
309 | } | |
310 | ||
311 | static void decode_farjmp(CPUX86State *env, struct x86_decode *decode) | |
312 | { | |
313 | decode->op[0].type = X86_VAR_IMMEDIATE; | |
314 | decode->op[0].val = decode_bytes(env, decode, decode->operand_size); | |
315 | decode->displacement = decode_word(env, decode); | |
316 | } | |
317 | ||
318 | static void decode_addgroup(CPUX86State *env, struct x86_decode *decode) | |
319 | { | |
320 | enum x86_decode_cmd group[] = { | |
321 | X86_DECODE_CMD_ADD, | |
322 | X86_DECODE_CMD_OR, | |
323 | X86_DECODE_CMD_ADC, | |
324 | X86_DECODE_CMD_SBB, | |
325 | X86_DECODE_CMD_AND, | |
326 | X86_DECODE_CMD_SUB, | |
327 | X86_DECODE_CMD_XOR, | |
328 | X86_DECODE_CMD_CMP | |
329 | }; | |
330 | decode->cmd = group[decode->modrm.reg]; | |
331 | } | |
332 | ||
333 | static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode) | |
334 | { | |
335 | enum x86_decode_cmd group[] = { | |
336 | X86_DECODE_CMD_ROL, | |
337 | X86_DECODE_CMD_ROR, | |
338 | X86_DECODE_CMD_RCL, | |
339 | X86_DECODE_CMD_RCR, | |
340 | X86_DECODE_CMD_SHL, | |
341 | X86_DECODE_CMD_SHR, | |
342 | X86_DECODE_CMD_SHL, | |
343 | X86_DECODE_CMD_SAR | |
344 | }; | |
345 | decode->cmd = group[decode->modrm.reg]; | |
346 | } | |
347 | ||
348 | static void decode_f7group(CPUX86State *env, struct x86_decode *decode) | |
349 | { | |
350 | enum x86_decode_cmd group[] = { | |
351 | X86_DECODE_CMD_TST, | |
352 | X86_DECODE_CMD_TST, | |
353 | X86_DECODE_CMD_NOT, | |
354 | X86_DECODE_CMD_NEG, | |
355 | X86_DECODE_CMD_MUL, | |
356 | X86_DECODE_CMD_IMUL_1, | |
357 | X86_DECODE_CMD_DIV, | |
358 | X86_DECODE_CMD_IDIV | |
359 | }; | |
360 | decode->cmd = group[decode->modrm.reg]; | |
361 | decode_modrm_rm(env, decode, &decode->op[0]); | |
362 | ||
363 | switch (decode->modrm.reg) { | |
364 | case 0: | |
365 | case 1: | |
366 | decode_imm(env, decode, &decode->op[1]); | |
367 | break; | |
368 | case 2: | |
369 | break; | |
370 | case 3: | |
371 | decode->op[1].type = X86_VAR_IMMEDIATE; | |
372 | decode->op[1].val = 0; | |
373 | break; | |
374 | default: | |
375 | break; | |
376 | } | |
377 | } | |
378 | ||
379 | static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode) | |
380 | { | |
381 | decode->op[0].type = X86_VAR_REG; | |
382 | decode->op[0].reg = decode->opcode[0] - 0x90; | |
b4e1af89 RB |
383 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
384 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
385 | } |
386 | ||
387 | static void decode_movgroup(CPUX86State *env, struct x86_decode *decode) | |
388 | { | |
389 | decode->op[0].type = X86_VAR_REG; | |
390 | decode->op[0].reg = decode->opcode[0] - 0xb8; | |
b4e1af89 RB |
391 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
392 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
393 | decode_immediate(env, decode, &decode->op[1], decode->operand_size); |
394 | } | |
395 | ||
396 | static void fetch_moffs(CPUX86State *env, struct x86_decode *decode, | |
397 | struct x86_decode_op *op) | |
398 | { | |
399 | op->type = X86_VAR_OFFSET; | |
400 | op->ptr = decode_bytes(env, decode, decode->addressing_size); | |
401 | } | |
402 | ||
403 | static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode) | |
404 | { | |
405 | decode->op[0].type = X86_VAR_REG; | |
406 | decode->op[0].reg = decode->opcode[0] - 0xb0; | |
b4e1af89 RB |
407 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
408 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
409 | decode_immediate(env, decode, &decode->op[1], decode->operand_size); |
410 | } | |
411 | ||
412 | static void decode_rcx(CPUX86State *env, struct x86_decode *decode, | |
413 | struct x86_decode_op *op) | |
414 | { | |
415 | op->type = X86_VAR_REG; | |
6701d81d | 416 | op->reg = R_ECX; |
b4e1af89 RB |
417 | op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b, |
418 | decode->operand_size); | |
c97d6d2c SAGDR |
419 | } |
420 | ||
421 | struct decode_tbl { | |
422 | uint8_t opcode; | |
423 | enum x86_decode_cmd cmd; | |
424 | uint8_t operand_size; | |
425 | bool is_modrm; | |
426 | void (*decode_op1)(CPUX86State *env, struct x86_decode *decode, | |
427 | struct x86_decode_op *op1); | |
428 | void (*decode_op2)(CPUX86State *env, struct x86_decode *decode, | |
429 | struct x86_decode_op *op2); | |
430 | void (*decode_op3)(CPUX86State *env, struct x86_decode *decode, | |
431 | struct x86_decode_op *op3); | |
432 | void (*decode_op4)(CPUX86State *env, struct x86_decode *decode, | |
433 | struct x86_decode_op *op4); | |
434 | void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode); | |
ff2de166 | 435 | uint32_t flags_mask; |
c97d6d2c SAGDR |
436 | }; |
437 | ||
438 | struct decode_x87_tbl { | |
439 | uint8_t opcode; | |
440 | uint8_t modrm_reg; | |
441 | uint8_t modrm_mod; | |
442 | enum x86_decode_cmd cmd; | |
443 | uint8_t operand_size; | |
444 | bool rev; | |
445 | bool pop; | |
446 | void (*decode_op1)(CPUX86State *env, struct x86_decode *decode, | |
447 | struct x86_decode_op *op1); | |
448 | void (*decode_op2)(CPUX86State *env, struct x86_decode *decode, | |
449 | struct x86_decode_op *op2); | |
450 | void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode); | |
ff2de166 | 451 | uint32_t flags_mask; |
c97d6d2c SAGDR |
452 | }; |
453 | ||
454 | struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL, | |
455 | decode_invalid}; | |
456 | ||
83ea23cd RB |
457 | struct decode_tbl _decode_tbl1[256]; |
458 | struct decode_tbl _decode_tbl2[256]; | |
459 | struct decode_x87_tbl _decode_tbl3[256]; | |
c97d6d2c SAGDR |
460 | |
461 | static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode) | |
462 | { | |
463 | struct decode_x87_tbl *decoder; | |
464 | ||
465 | decode->is_fpu = true; | |
466 | int mode = decode->modrm.mod == 3 ? 1 : 0; | |
467 | int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) | | |
468 | decode->modrm.reg; | |
469 | ||
470 | decoder = &_decode_tbl3[index]; | |
471 | ||
472 | decode->cmd = decoder->cmd; | |
473 | if (decoder->operand_size) { | |
474 | decode->operand_size = decoder->operand_size; | |
475 | } | |
476 | decode->flags_mask = decoder->flags_mask; | |
477 | decode->fpop_stack = decoder->pop; | |
478 | decode->frev = decoder->rev; | |
479 | ||
480 | if (decoder->decode_op1) { | |
481 | decoder->decode_op1(env, decode, &decode->op[0]); | |
482 | } | |
483 | if (decoder->decode_op2) { | |
484 | decoder->decode_op2(env, decode, &decode->op[1]); | |
485 | } | |
486 | if (decoder->decode_postfix) { | |
487 | decoder->decode_postfix(env, decode); | |
488 | } | |
489 | ||
490 | VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n", | |
491 | decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg, | |
492 | decoder->modrm_mod); | |
493 | } | |
494 | ||
495 | static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode) | |
496 | { | |
497 | enum x86_decode_cmd group[] = { | |
498 | X86_DECODE_CMD_INC, | |
499 | X86_DECODE_CMD_DEC, | |
500 | X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT, | |
501 | X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT, | |
502 | X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT, | |
503 | X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT, | |
504 | X86_DECODE_CMD_PUSH, | |
505 | X86_DECODE_CMD_INVL, | |
506 | X86_DECODE_CMD_INVL | |
507 | }; | |
508 | decode->cmd = group[decode->modrm.reg]; | |
509 | if (decode->modrm.reg > 2) { | |
510 | decode->flags_mask = 0; | |
511 | } | |
512 | } | |
513 | ||
514 | static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode) | |
515 | { | |
516 | ||
517 | enum x86_decode_cmd group[] = { | |
518 | X86_DECODE_CMD_SLDT, | |
519 | X86_DECODE_CMD_STR, | |
520 | X86_DECODE_CMD_LLDT, | |
521 | X86_DECODE_CMD_LTR, | |
522 | X86_DECODE_CMD_VERR, | |
523 | X86_DECODE_CMD_VERW, | |
524 | X86_DECODE_CMD_INVL, | |
525 | X86_DECODE_CMD_INVL | |
526 | }; | |
527 | decode->cmd = group[decode->modrm.reg]; | |
c97d6d2c SAGDR |
528 | } |
529 | ||
530 | static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode) | |
531 | { | |
532 | enum x86_decode_cmd group[] = { | |
533 | X86_DECODE_CMD_SGDT, | |
534 | X86_DECODE_CMD_SIDT, | |
535 | X86_DECODE_CMD_LGDT, | |
536 | X86_DECODE_CMD_LIDT, | |
537 | X86_DECODE_CMD_SMSW, | |
538 | X86_DECODE_CMD_LMSW, | |
539 | X86_DECODE_CMD_LMSW, | |
540 | X86_DECODE_CMD_INVLPG | |
541 | }; | |
542 | decode->cmd = group[decode->modrm.reg]; | |
543 | if (0xf9 == decode->modrm.modrm) { | |
544 | decode->opcode[decode->len++] = decode->modrm.modrm; | |
545 | decode->cmd = X86_DECODE_CMD_RDTSCP; | |
546 | } | |
547 | } | |
548 | ||
549 | static void decode_btgroup(CPUX86State *env, struct x86_decode *decode) | |
550 | { | |
551 | enum x86_decode_cmd group[] = { | |
552 | X86_DECODE_CMD_INVL, | |
553 | X86_DECODE_CMD_INVL, | |
554 | X86_DECODE_CMD_INVL, | |
555 | X86_DECODE_CMD_INVL, | |
556 | X86_DECODE_CMD_BT, | |
557 | X86_DECODE_CMD_BTS, | |
558 | X86_DECODE_CMD_BTR, | |
559 | X86_DECODE_CMD_BTC | |
560 | }; | |
561 | decode->cmd = group[decode->modrm.reg]; | |
562 | } | |
563 | ||
564 | static void decode_x87_general(CPUX86State *env, struct x86_decode *decode) | |
565 | { | |
566 | decode->is_fpu = true; | |
567 | } | |
568 | ||
569 | static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode, | |
570 | struct x86_decode_op *op) | |
571 | { | |
572 | op->type = X87_VAR_FLOATP; | |
573 | } | |
574 | ||
575 | static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode, | |
576 | struct x86_decode_op *op) | |
577 | { | |
578 | op->type = X87_VAR_INTP; | |
579 | } | |
580 | ||
581 | static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode, | |
582 | struct x86_decode_op *op) | |
583 | { | |
584 | op->type = X87_VAR_BYTEP; | |
585 | } | |
586 | ||
587 | static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode, | |
588 | struct x86_decode_op *op) | |
589 | { | |
590 | op->type = X87_VAR_REG; | |
591 | op->reg = 0; | |
592 | } | |
593 | ||
594 | static void decode_decode_x87_modrm_st0(CPUX86State *env, | |
595 | struct x86_decode *decode, | |
596 | struct x86_decode_op *op) | |
597 | { | |
598 | op->type = X87_VAR_REG; | |
599 | op->reg = decode->modrm.modrm & 7; | |
600 | } | |
601 | ||
602 | ||
603 | static void decode_aegroup(CPUX86State *env, struct x86_decode *decode) | |
604 | { | |
605 | decode->is_fpu = true; | |
606 | switch (decode->modrm.reg) { | |
607 | case 0: | |
608 | decode->cmd = X86_DECODE_CMD_FXSAVE; | |
609 | decode_x87_modrm_bytep(env, decode, &decode->op[0]); | |
610 | break; | |
611 | case 1: | |
612 | decode_x87_modrm_bytep(env, decode, &decode->op[0]); | |
613 | decode->cmd = X86_DECODE_CMD_FXRSTOR; | |
614 | break; | |
615 | case 5: | |
616 | if (decode->modrm.modrm == 0xe8) { | |
617 | decode->cmd = X86_DECODE_CMD_LFENCE; | |
618 | } else { | |
619 | VM_PANIC("xrstor"); | |
620 | } | |
621 | break; | |
622 | case 6: | |
623 | VM_PANIC_ON(decode->modrm.modrm != 0xf0); | |
624 | decode->cmd = X86_DECODE_CMD_MFENCE; | |
625 | break; | |
626 | case 7: | |
627 | if (decode->modrm.modrm == 0xf8) { | |
628 | decode->cmd = X86_DECODE_CMD_SFENCE; | |
629 | } else { | |
630 | decode->cmd = X86_DECODE_CMD_CLFLUSH; | |
631 | } | |
632 | break; | |
633 | default: | |
74682782 | 634 | VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg); |
c97d6d2c SAGDR |
635 | break; |
636 | } | |
637 | } | |
638 | ||
639 | static void decode_bswap(CPUX86State *env, struct x86_decode *decode) | |
640 | { | |
641 | decode->op[0].type = X86_VAR_REG; | |
642 | decode->op[0].reg = decode->opcode[1] - 0xc8; | |
b4e1af89 RB |
643 | decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, |
644 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
645 | } |
646 | ||
647 | static void decode_d9_4(CPUX86State *env, struct x86_decode *decode) | |
648 | { | |
649 | switch (decode->modrm.modrm) { | |
650 | case 0xe0: | |
651 | /* FCHS */ | |
652 | decode->cmd = X86_DECODE_CMD_FCHS; | |
653 | break; | |
654 | case 0xe1: | |
655 | decode->cmd = X86_DECODE_CMD_FABS; | |
656 | break; | |
657 | case 0xe4: | |
74682782 | 658 | VM_PANIC("FTST"); |
c97d6d2c SAGDR |
659 | break; |
660 | case 0xe5: | |
661 | /* FXAM */ | |
662 | decode->cmd = X86_DECODE_CMD_FXAM; | |
663 | break; | |
664 | default: | |
74682782 | 665 | VM_PANIC("FLDENV"); |
c97d6d2c SAGDR |
666 | break; |
667 | } | |
668 | } | |
669 | ||
670 | static void decode_db_4(CPUX86State *env, struct x86_decode *decode) | |
671 | { | |
672 | switch (decode->modrm.modrm) { | |
673 | case 0xe0: | |
74682782 PB |
674 | VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0], |
675 | decode->modrm.modrm); | |
c97d6d2c SAGDR |
676 | break; |
677 | case 0xe1: | |
74682782 PB |
678 | VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0], |
679 | decode->modrm.modrm); | |
c97d6d2c SAGDR |
680 | break; |
681 | case 0xe2: | |
74682782 PB |
682 | VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0], |
683 | decode->modrm.modrm); | |
c97d6d2c SAGDR |
684 | break; |
685 | case 0xe3: | |
686 | decode->cmd = X86_DECODE_CMD_FNINIT; | |
687 | break; | |
688 | case 0xe4: | |
689 | decode->cmd = X86_DECODE_CMD_FNSETPM; | |
690 | break; | |
691 | default: | |
74682782 PB |
692 | VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0], |
693 | decode->modrm.modrm); | |
c97d6d2c SAGDR |
694 | break; |
695 | } | |
696 | } | |
697 | ||
698 | ||
699 | #define RFLAGS_MASK_NONE 0 | |
700 | #define RFLAGS_MASK_OSZAPC (RFLAGS_OF | RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | \ | |
701 | RFLAGS_PF | RFLAGS_CF) | |
702 | #define RFLAGS_MASK_LAHF (RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | RFLAGS_PF | \ | |
703 | RFLAGS_CF) | |
704 | #define RFLAGS_MASK_CF (RFLAGS_CF) | |
705 | #define RFLAGS_MASK_IF (RFLAGS_IF) | |
706 | #define RFLAGS_MASK_TF (RFLAGS_TF) | |
707 | #define RFLAGS_MASK_DF (RFLAGS_DF) | |
708 | #define RFLAGS_MASK_ZF (RFLAGS_ZF) | |
709 | ||
710 | struct decode_tbl _1op_inst[] = { | |
711 | {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL, | |
712 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
713 | {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL, | |
714 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
715 | {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL, | |
716 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
717 | {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL, | |
718 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
719 | {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL, | |
720 | NULL, RFLAGS_MASK_OSZAPC}, | |
721 | {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL, | |
722 | NULL, RFLAGS_MASK_OSZAPC}, | |
723 | {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL, | |
724 | decode_pushseg, RFLAGS_MASK_NONE}, | |
725 | {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL, | |
726 | decode_popseg, RFLAGS_MASK_NONE}, | |
727 | {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL, | |
728 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
729 | {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL, | |
730 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
731 | {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL, | |
732 | NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
733 | {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm, | |
734 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
735 | {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8, | |
736 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
737 | {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm, | |
738 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
739 | ||
740 | {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false, | |
741 | NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, | |
742 | {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false, | |
743 | NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, | |
744 | ||
745 | {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg, | |
746 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
747 | {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg, | |
748 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
749 | {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm, | |
750 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
751 | {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm, | |
752 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
753 | {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm, | |
754 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
755 | {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm, | |
756 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
757 | ||
758 | {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false, | |
759 | NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, | |
760 | {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false, | |
761 | NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, | |
762 | ||
763 | {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg, | |
764 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
765 | {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg, | |
766 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
767 | {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm, | |
768 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
769 | {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm, | |
770 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
771 | {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8, | |
772 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
773 | {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm, | |
774 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
775 | ||
776 | {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false, | |
777 | NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, | |
778 | {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false, | |
779 | NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, | |
780 | ||
781 | {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg, | |
782 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
783 | {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg, | |
784 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
785 | {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm, | |
786 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
787 | {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm, | |
788 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
789 | {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm, | |
790 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
791 | {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm, | |
792 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
793 | {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg, | |
794 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
795 | {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg, | |
796 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
797 | {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm, | |
798 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
799 | {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm, | |
800 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
801 | {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm, | |
802 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
803 | {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm, | |
804 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
805 | {0x2f, X86_DECODE_CMD_DAS, 0, false, | |
806 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
807 | {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg, | |
808 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
809 | {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg, | |
810 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
811 | {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm, | |
812 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
813 | {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm, | |
814 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
815 | {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm, | |
816 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
817 | {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm, | |
818 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
819 | ||
820 | {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg, | |
821 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
822 | {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg, | |
823 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
824 | {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm, | |
825 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
826 | {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm, | |
827 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
828 | {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8, | |
829 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
830 | {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm, | |
831 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
832 | ||
833 | {0x3f, X86_DECODE_CMD_AAS, 0, false, | |
834 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
835 | ||
836 | {0x40, X86_DECODE_CMD_INC, 0, false, | |
837 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
838 | {0x41, X86_DECODE_CMD_INC, 0, false, | |
839 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
840 | {0x42, X86_DECODE_CMD_INC, 0, false, | |
841 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
842 | {0x43, X86_DECODE_CMD_INC, 0, false, | |
843 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
844 | {0x44, X86_DECODE_CMD_INC, 0, false, | |
845 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
846 | {0x45, X86_DECODE_CMD_INC, 0, false, | |
847 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
848 | {0x46, X86_DECODE_CMD_INC, 0, false, | |
849 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
850 | {0x47, X86_DECODE_CMD_INC, 0, false, | |
851 | NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, | |
852 | ||
853 | {0x48, X86_DECODE_CMD_DEC, 0, false, | |
854 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
855 | {0x49, X86_DECODE_CMD_DEC, 0, false, | |
856 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
857 | {0x4a, X86_DECODE_CMD_DEC, 0, false, | |
858 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
859 | {0x4b, X86_DECODE_CMD_DEC, 0, false, | |
860 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
861 | {0x4c, X86_DECODE_CMD_DEC, 0, false, | |
862 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
863 | {0x4d, X86_DECODE_CMD_DEC, 0, false, | |
864 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
865 | {0x4e, X86_DECODE_CMD_DEC, 0, false, | |
866 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
867 | {0x4f, X86_DECODE_CMD_DEC, 0, false, | |
868 | NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, | |
869 | ||
870 | {0x50, X86_DECODE_CMD_PUSH, 0, false, | |
871 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
872 | {0x51, X86_DECODE_CMD_PUSH, 0, false, | |
873 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
874 | {0x52, X86_DECODE_CMD_PUSH, 0, false, | |
875 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
876 | {0x53, X86_DECODE_CMD_PUSH, 0, false, | |
877 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
878 | {0x54, X86_DECODE_CMD_PUSH, 0, false, | |
879 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
880 | {0x55, X86_DECODE_CMD_PUSH, 0, false, | |
881 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
882 | {0x56, X86_DECODE_CMD_PUSH, 0, false, | |
883 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
884 | {0x57, X86_DECODE_CMD_PUSH, 0, false, | |
885 | NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, | |
886 | ||
887 | {0x58, X86_DECODE_CMD_POP, 0, false, | |
888 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
889 | {0x59, X86_DECODE_CMD_POP, 0, false, | |
890 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
891 | {0x5a, X86_DECODE_CMD_POP, 0, false, | |
892 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
893 | {0x5b, X86_DECODE_CMD_POP, 0, false, | |
894 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
895 | {0x5c, X86_DECODE_CMD_POP, 0, false, | |
896 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
897 | {0x5d, X86_DECODE_CMD_POP, 0, false, | |
898 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
899 | {0x5e, X86_DECODE_CMD_POP, 0, false, | |
900 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
901 | {0x5f, X86_DECODE_CMD_POP, 0, false, | |
902 | NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, | |
903 | ||
904 | {0x60, X86_DECODE_CMD_PUSHA, 0, false, | |
905 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
906 | {0x61, X86_DECODE_CMD_POPA, 0, false, | |
907 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
908 | ||
909 | {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm, | |
910 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
911 | {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed, | |
912 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
913 | {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, | |
914 | decode_modrm_rm, decode_imm, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
915 | {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm, | |
916 | decode_imm8_signed, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
917 | ||
918 | {0x6c, X86_DECODE_CMD_INS, 1, false, | |
919 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
920 | {0x6d, X86_DECODE_CMD_INS, 0, false, | |
921 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
922 | {0x6e, X86_DECODE_CMD_OUTS, 1, false, | |
923 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
924 | {0x6f, X86_DECODE_CMD_OUTS, 0, false, | |
925 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
926 | ||
927 | {0x70, X86_DECODE_CMD_JXX, 1, false, | |
928 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
929 | {0x71, X86_DECODE_CMD_JXX, 1, false, | |
930 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
931 | {0x72, X86_DECODE_CMD_JXX, 1, false, | |
932 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
933 | {0x73, X86_DECODE_CMD_JXX, 1, false, | |
934 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
935 | {0x74, X86_DECODE_CMD_JXX, 1, false, | |
936 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
937 | {0x75, X86_DECODE_CMD_JXX, 1, false, | |
938 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
939 | {0x76, X86_DECODE_CMD_JXX, 1, false, | |
940 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
941 | {0x77, X86_DECODE_CMD_JXX, 1, false, | |
942 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
943 | {0x78, X86_DECODE_CMD_JXX, 1, false, | |
944 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
945 | {0x79, X86_DECODE_CMD_JXX, 1, false, | |
946 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
947 | {0x7a, X86_DECODE_CMD_JXX, 1, false, | |
948 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
949 | {0x7b, X86_DECODE_CMD_JXX, 1, false, | |
950 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
951 | {0x7c, X86_DECODE_CMD_JXX, 1, false, | |
952 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
953 | {0x7d, X86_DECODE_CMD_JXX, 1, false, | |
954 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
955 | {0x7e, X86_DECODE_CMD_JXX, 1, false, | |
956 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
957 | {0x7f, X86_DECODE_CMD_JXX, 1, false, | |
958 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
959 | ||
960 | {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, | |
961 | NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, | |
962 | {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm, | |
963 | NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, | |
964 | {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, | |
965 | NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, | |
966 | {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed, | |
967 | NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, | |
968 | {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg, | |
969 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
970 | {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg, | |
971 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
972 | {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm, | |
973 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
974 | {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm, | |
975 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
976 | {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg, | |
977 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
978 | {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg, | |
979 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
980 | {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm, | |
981 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
982 | {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
983 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
984 | {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm, | |
985 | decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
986 | {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm, | |
987 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
988 | {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg, | |
989 | decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
990 | {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm, | |
991 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
992 | ||
993 | {0x90, X86_DECODE_CMD_NOP, 0, false, | |
994 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
995 | {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
996 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
997 | {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
998 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
999 | {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
1000 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
1001 | {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
1002 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
1003 | {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
1004 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
1005 | {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
1006 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
1007 | {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, | |
1008 | NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, | |
1009 | ||
1010 | {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL, | |
1011 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1012 | {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL, | |
1013 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1014 | ||
1015 | {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL, | |
1016 | NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE}, | |
1017 | ||
1018 | {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL, | |
1019 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1020 | /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL, | |
1021 | NULL, NULL, NULL, RFLAGS_MASK_POPF},*/ | |
1022 | {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL, | |
1023 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1024 | {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL, | |
1025 | NULL, NULL, NULL, RFLAGS_MASK_LAHF}, | |
1026 | ||
1027 | {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs, | |
1028 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1029 | {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs, | |
1030 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1031 | {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax, | |
1032 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1033 | {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax, | |
1034 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1035 | ||
1036 | {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL, | |
1037 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1038 | {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL, | |
1039 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1040 | {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL, | |
1041 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1042 | {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL, | |
1043 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1044 | {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL, | |
1045 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1046 | {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL, | |
1047 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1048 | {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL, | |
1049 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1050 | {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL, | |
1051 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1052 | {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL, | |
1053 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1054 | {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL, | |
1055 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1056 | ||
1057 | {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm, | |
1058 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1059 | {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm, | |
1060 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1061 | ||
1062 | {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1063 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1064 | {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1065 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1066 | {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1067 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1068 | {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1069 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1070 | {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1071 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1072 | {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1073 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1074 | {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1075 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1076 | {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL, | |
1077 | NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, | |
1078 | ||
1079 | {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1080 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1081 | {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1082 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1083 | {0xba, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1084 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1085 | {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1086 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1087 | {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1088 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1089 | {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1090 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1091 | {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1092 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1093 | {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL, | |
1094 | NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, | |
1095 | ||
1096 | {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, | |
1097 | NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, | |
1098 | {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8, | |
1099 | NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, | |
1100 | ||
1101 | {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16, | |
1102 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1103 | {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL, | |
1104 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1105 | ||
1106 | {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1107 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1108 | {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1109 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1110 | ||
1111 | {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8, | |
1112 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1113 | {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm, | |
1114 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1115 | ||
1116 | {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8, | |
1117 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1118 | {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL, | |
1119 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1120 | {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL, | |
1121 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1122 | {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL, | |
1123 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1124 | {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL, | |
1125 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1126 | /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL, | |
1127 | NULL, NULL, NULL, RFLAGS_MASK_IRET},*/ | |
1128 | ||
1129 | {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1, | |
1130 | NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, | |
1131 | {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1, | |
1132 | NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, | |
1133 | {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx, | |
1134 | NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, | |
1135 | {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx, | |
1136 | NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, | |
1137 | ||
1138 | {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8, | |
1139 | NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1140 | {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8, | |
1141 | NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1142 | ||
1143 | {0xd7, X86_DECODE_CMD_XLAT, 0, false, | |
1144 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1145 | ||
1146 | {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1147 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1148 | {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1149 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1150 | {0xda, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1151 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1152 | {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1153 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1154 | {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1155 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1156 | {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1157 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1158 | {0xde, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1159 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1160 | {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL, | |
1161 | NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, | |
1162 | ||
1163 | {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, | |
1164 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1165 | {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, | |
1166 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1167 | {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, | |
1168 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1169 | ||
1170 | {0xe3, X86_DECODE_CMD_JCXZ, 1, false, | |
1171 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1172 | ||
1173 | {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8, | |
1174 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1175 | {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8, | |
1176 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1177 | {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8, | |
1178 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1179 | {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8, | |
1180 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1181 | {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed, | |
1182 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1183 | {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed, | |
1184 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1185 | {0xea, X86_DECODE_CMD_JMP_FAR, 0, false, | |
1186 | NULL, NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE}, | |
1187 | {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed, | |
1188 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1189 | {0xec, X86_DECODE_CMD_IN, 1, false, | |
1190 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1191 | {0xed, X86_DECODE_CMD_IN, 0, false, | |
1192 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1193 | {0xee, X86_DECODE_CMD_OUT, 1, false, | |
1194 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1195 | {0xef, X86_DECODE_CMD_OUT, 0, false, | |
1196 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1197 | ||
1198 | {0xf4, X86_DECODE_CMD_HLT, 0, false, | |
1199 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1200 | ||
1201 | {0xf5, X86_DECODE_CMD_CMC, 0, false, | |
1202 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, | |
1203 | ||
1204 | {0xf6, X86_DECODE_CMD_INVL, 1, true, | |
1205 | NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC}, | |
1206 | {0xf7, X86_DECODE_CMD_INVL, 0, true, | |
1207 | NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC}, | |
1208 | ||
1209 | {0xf8, X86_DECODE_CMD_CLC, 0, false, | |
1210 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, | |
1211 | {0xf9, X86_DECODE_CMD_STC, 0, false, | |
1212 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, | |
1213 | ||
1214 | {0xfa, X86_DECODE_CMD_CLI, 0, false, | |
1215 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF}, | |
1216 | {0xfb, X86_DECODE_CMD_STI, 0, false, | |
1217 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF}, | |
1218 | {0xfc, X86_DECODE_CMD_CLD, 0, false, | |
1219 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF}, | |
1220 | {0xfd, X86_DECODE_CMD_STD, 0, false, | |
1221 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF}, | |
1222 | {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, | |
1223 | NULL, NULL, NULL, decode_incgroup2, RFLAGS_MASK_OSZAPC}, | |
1224 | {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, | |
1225 | NULL, NULL, NULL, decode_ffgroup, RFLAGS_MASK_OSZAPC}, | |
1226 | }; | |
1227 | ||
1228 | struct decode_tbl _2op_inst[] = { | |
1229 | {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, | |
1230 | NULL, NULL, NULL, decode_sldtgroup, RFLAGS_MASK_NONE}, | |
1231 | {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, | |
1232 | NULL, NULL, NULL, decode_lidtgroup, RFLAGS_MASK_NONE}, | |
1233 | {0x6, X86_DECODE_CMD_CLTS, 0, false, | |
1234 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_TF}, | |
1235 | {0x9, X86_DECODE_CMD_WBINVD, 0, false, | |
1236 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1237 | {0x18, X86_DECODE_CMD_PREFETCH, 0, true, | |
1238 | NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE}, | |
1239 | {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm, | |
1240 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1241 | {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm, | |
1242 | decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1243 | {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm, | |
1244 | decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1245 | {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg, | |
1246 | decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1247 | {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg, | |
1248 | decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1249 | {0x30, X86_DECODE_CMD_WRMSR, 0, false, | |
1250 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1251 | {0x31, X86_DECODE_CMD_RDTSC, 0, false, | |
1252 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1253 | {0x32, X86_DECODE_CMD_RDMSR, 0, false, | |
1254 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1255 | {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1256 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1257 | {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1258 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1259 | {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1260 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1261 | {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1262 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1263 | {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1264 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1265 | {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1266 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1267 | {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1268 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1269 | {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1270 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1271 | {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1272 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1273 | {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1274 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1275 | {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1276 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1277 | {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1278 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1279 | {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1280 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1281 | {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1282 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1283 | {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1284 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1285 | {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1286 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1287 | {0x77, X86_DECODE_CMD_EMMS, 0, false, | |
1288 | NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE}, | |
1289 | {0x82, X86_DECODE_CMD_JXX, 0, false, | |
1290 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1291 | {0x83, X86_DECODE_CMD_JXX, 0, false, | |
1292 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1293 | {0x84, X86_DECODE_CMD_JXX, 0, false, | |
1294 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1295 | {0x85, X86_DECODE_CMD_JXX, 0, false, | |
1296 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1297 | {0x86, X86_DECODE_CMD_JXX, 0, false, | |
1298 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1299 | {0x87, X86_DECODE_CMD_JXX, 0, false, | |
1300 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1301 | {0x88, X86_DECODE_CMD_JXX, 0, false, | |
1302 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1303 | {0x89, X86_DECODE_CMD_JXX, 0, false, | |
1304 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1305 | {0x8a, X86_DECODE_CMD_JXX, 0, false, | |
1306 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1307 | {0x8b, X86_DECODE_CMD_JXX, 0, false, | |
1308 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1309 | {0x8c, X86_DECODE_CMD_JXX, 0, false, | |
1310 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1311 | {0x8d, X86_DECODE_CMD_JXX, 0, false, | |
1312 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1313 | {0x8e, X86_DECODE_CMD_JXX, 0, false, | |
1314 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1315 | {0x8f, X86_DECODE_CMD_JXX, 0, false, | |
1316 | NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, | |
1317 | {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1318 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1319 | {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1320 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1321 | {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1322 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1323 | {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1324 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1325 | {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1326 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1327 | {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1328 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1329 | {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1330 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1331 | {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1332 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1333 | {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1334 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1335 | {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1336 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1337 | {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1338 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1339 | {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1340 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1341 | {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1342 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1343 | {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1344 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1345 | {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1346 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1347 | {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, | |
1348 | NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1349 | ||
1350 | {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg, | |
1351 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1352 | {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1353 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1354 | ||
1355 | {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1356 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1357 | {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1358 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1359 | {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1360 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1361 | {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1362 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1363 | {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1364 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1365 | {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false, | |
1366 | NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, | |
1367 | {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false, | |
1368 | NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, | |
1369 | {0xa2, X86_DECODE_CMD_CPUID, 0, false, | |
1370 | NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1371 | {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1372 | NULL, NULL, NULL, RFLAGS_MASK_CF}, | |
1373 | {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1374 | decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1375 | {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1376 | decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1377 | {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false, | |
1378 | NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, | |
1379 | {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false, | |
1380 | NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, | |
1381 | {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1382 | NULL, NULL, NULL, RFLAGS_MASK_CF}, | |
1383 | {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1384 | decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1385 | {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1386 | decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1387 | ||
1388 | {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, | |
1389 | NULL, NULL, NULL, decode_aegroup, RFLAGS_MASK_NONE}, | |
1390 | ||
1391 | {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1392 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1393 | {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1394 | NULL, NULL, NULL, RFLAGS_MASK_NONE}, | |
1395 | {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1396 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1397 | {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8, | |
1398 | NULL, NULL, decode_btgroup, RFLAGS_MASK_OSZAPC}, | |
1399 | {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1400 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1401 | {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1402 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1403 | {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm, | |
1404 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1405 | ||
1406 | {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg, | |
1407 | NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, | |
1408 | ||
1409 | {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm, | |
1410 | NULL, NULL, NULL, NULL, RFLAGS_MASK_ZF}, | |
1411 | ||
1412 | {0xc8, X86_DECODE_CMD_BSWAP, 0, false, | |
1413 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1414 | {0xc9, X86_DECODE_CMD_BSWAP, 0, false, | |
1415 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1416 | {0xca, X86_DECODE_CMD_BSWAP, 0, false, | |
1417 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1418 | {0xcb, X86_DECODE_CMD_BSWAP, 0, false, | |
1419 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1420 | {0xcc, X86_DECODE_CMD_BSWAP, 0, false, | |
1421 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1422 | {0xcd, X86_DECODE_CMD_BSWAP, 0, false, | |
1423 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1424 | {0xce, X86_DECODE_CMD_BSWAP, 0, false, | |
1425 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1426 | {0xcf, X86_DECODE_CMD_BSWAP, 0, false, | |
1427 | NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, | |
1428 | }; | |
1429 | ||
1430 | struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL, | |
1431 | NULL, decode_invalid, 0}; | |
1432 | ||
1433 | struct decode_x87_tbl _x87_inst[] = { | |
1434 | {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false, | |
1435 | decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1436 | {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, | |
1437 | decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1438 | {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0, | |
1439 | decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1440 | {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, | |
1441 | decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1442 | {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0, | |
1443 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1444 | {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0, | |
1445 | decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1446 | {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0, | |
1447 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1448 | {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, | |
1449 | decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1450 | {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0, | |
1451 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1452 | {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0, | |
1453 | decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1454 | {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0, | |
1455 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1456 | {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0, | |
1457 | decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1458 | ||
1459 | {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false, | |
1460 | decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, | |
1461 | {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, | |
1462 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1463 | {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0, | |
1464 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1465 | {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false, | |
1466 | decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, | |
1467 | {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false, | |
1468 | decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, | |
1469 | {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false, | |
1470 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1471 | {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false, | |
1472 | decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, | |
1473 | {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true, | |
1474 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1475 | {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, | |
1476 | decode_x87_modrm_st0, NULL, decode_d9_4, RFLAGS_MASK_NONE}, | |
1477 | {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false, | |
1478 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1479 | {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL, | |
1480 | RFLAGS_MASK_NONE}, | |
1481 | {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false, | |
1482 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1483 | ||
1484 | {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false, | |
1485 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1486 | {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false, | |
1487 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1488 | ||
1489 | {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, | |
1490 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1491 | {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, | |
1492 | decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1493 | {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, | |
1494 | decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1495 | {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, | |
1496 | decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1497 | {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, | |
1498 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1499 | {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, | |
1500 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1501 | {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, | |
1502 | RFLAGS_MASK_NONE}, | |
1503 | {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0, | |
1504 | decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1505 | {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0, | |
1506 | decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1507 | {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, | |
1508 | decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1509 | {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, | |
1510 | RFLAGS_MASK_NONE}, | |
1511 | {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0, | |
1512 | decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1513 | {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, | |
1514 | RFLAGS_MASK_NONE}, | |
1515 | {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0, | |
1516 | decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1517 | ||
1518 | {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, | |
1519 | decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1520 | {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, | |
1521 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1522 | {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, | |
1523 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1524 | {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, | |
1525 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1526 | {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false, | |
1527 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1528 | {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, | |
1529 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1530 | {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true, | |
1531 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1532 | {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, | |
1533 | decode_db_4, RFLAGS_MASK_NONE}, | |
1534 | {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, | |
1535 | RFLAGS_MASK_NONE}, | |
1536 | {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false, | |
1537 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1538 | {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false, | |
1539 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1540 | {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true, | |
1541 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1542 | ||
1543 | {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false, | |
1544 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1545 | {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false, | |
1546 | decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1547 | {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, | |
1548 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1549 | {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false, | |
1550 | decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1551 | {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false, | |
1552 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1553 | {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false, | |
1554 | decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1555 | {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false, | |
1556 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1557 | {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false, | |
1558 | decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1559 | {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false, | |
1560 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1561 | {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false, | |
1562 | decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1563 | {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false, | |
1564 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1565 | {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false, | |
1566 | decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, | |
1567 | ||
1568 | {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false, | |
1569 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1570 | {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, | |
1571 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1572 | {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false, | |
1573 | decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, | |
1574 | {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false, | |
1575 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1576 | {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true, | |
1577 | decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, | |
1578 | {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true, | |
1579 | decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1580 | {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false, | |
1581 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1582 | {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false, | |
1583 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1584 | {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, | |
1585 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1586 | {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false, | |
1587 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1588 | {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false, | |
1589 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1590 | ||
1591 | {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true, | |
1592 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1593 | {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false, | |
1594 | decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1595 | {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true, | |
1596 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1597 | {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false, | |
1598 | decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1599 | {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true, | |
1600 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1601 | {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false, | |
1602 | decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1603 | {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true, | |
1604 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1605 | {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false, | |
1606 | decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1607 | {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true, | |
1608 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1609 | {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false, | |
1610 | decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1611 | {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true, | |
1612 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1613 | {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false, | |
1614 | decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, | |
1615 | ||
1616 | {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false, | |
1617 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1618 | {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, | |
1619 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1620 | {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true, | |
1621 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1622 | {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false, | |
1623 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1624 | {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true, | |
1625 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1626 | {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true, | |
1627 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1628 | {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true, | |
1629 | decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, | |
1630 | {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true, | |
1631 | decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, | |
1632 | {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false, | |
1633 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1634 | {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true, | |
1635 | decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, | |
1636 | }; | |
1637 | ||
1638 | void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, | |
1639 | struct x86_decode_op *op) | |
1640 | { | |
ff2de166 | 1641 | target_ulong ptr = 0; |
6701d81d | 1642 | X86Seg seg = R_DS; |
c97d6d2c SAGDR |
1643 | |
1644 | if (!decode->modrm.mod && 6 == decode->modrm.rm) { | |
1edead0f | 1645 | ptr = decode->displacement; |
c97d6d2c SAGDR |
1646 | goto calc_addr; |
1647 | } | |
1648 | ||
1649 | if (decode->displacement_size) { | |
1650 | ptr = sign(decode->displacement, decode->displacement_size); | |
1651 | } | |
1652 | ||
1653 | switch (decode->modrm.rm) { | |
1654 | case 0: | |
1655 | ptr += BX(env) + SI(env); | |
1656 | break; | |
1657 | case 1: | |
1658 | ptr += BX(env) + DI(env); | |
1659 | break; | |
1660 | case 2: | |
1661 | ptr += BP(env) + SI(env); | |
6701d81d | 1662 | seg = R_SS; |
c97d6d2c SAGDR |
1663 | break; |
1664 | case 3: | |
1665 | ptr += BP(env) + DI(env); | |
6701d81d | 1666 | seg = R_SS; |
c97d6d2c SAGDR |
1667 | break; |
1668 | case 4: | |
1669 | ptr += SI(env); | |
1670 | break; | |
1671 | case 5: | |
1672 | ptr += DI(env); | |
1673 | break; | |
1674 | case 6: | |
1675 | ptr += BP(env); | |
6701d81d | 1676 | seg = R_SS; |
c97d6d2c SAGDR |
1677 | break; |
1678 | case 7: | |
1679 | ptr += BX(env); | |
1680 | break; | |
1681 | } | |
1682 | calc_addr: | |
1683 | if (X86_DECODE_CMD_LEA == decode->cmd) { | |
1684 | op->ptr = (uint16_t)ptr; | |
1685 | } else { | |
1686 | op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg); | |
1687 | } | |
1688 | } | |
1689 | ||
b4e1af89 RB |
1690 | target_ulong get_reg_ref(CPUX86State *env, int reg, int rex, int is_extended, |
1691 | int size) | |
c97d6d2c | 1692 | { |
ff2de166 | 1693 | target_ulong ptr = 0; |
c97d6d2c SAGDR |
1694 | int which = 0; |
1695 | ||
1696 | if (is_extended) { | |
6701d81d | 1697 | reg |= R_R8; |
c97d6d2c SAGDR |
1698 | } |
1699 | ||
1700 | ||
1701 | switch (size) { | |
1702 | case 1: | |
b4e1af89 | 1703 | if (is_extended || reg < 4 || rex) { |
c97d6d2c | 1704 | which = 1; |
ff2de166 | 1705 | ptr = (target_ulong)&RL(env, reg); |
c97d6d2c SAGDR |
1706 | } else { |
1707 | which = 2; | |
ff2de166 | 1708 | ptr = (target_ulong)&RH(env, reg - 4); |
c97d6d2c SAGDR |
1709 | } |
1710 | break; | |
1711 | default: | |
1712 | which = 3; | |
ff2de166 | 1713 | ptr = (target_ulong)&RRX(env, reg); |
c97d6d2c SAGDR |
1714 | break; |
1715 | } | |
1716 | return ptr; | |
1717 | } | |
1718 | ||
b4e1af89 RB |
1719 | target_ulong get_reg_val(CPUX86State *env, int reg, int rex, int is_extended, |
1720 | int size) | |
c97d6d2c | 1721 | { |
ff2de166 | 1722 | target_ulong val = 0; |
b4e1af89 | 1723 | memcpy(&val, (void *)get_reg_ref(env, reg, rex, is_extended, size), size); |
c97d6d2c SAGDR |
1724 | return val; |
1725 | } | |
1726 | ||
ff2de166 | 1727 | static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode, |
6701d81d | 1728 | X86Seg *sel) |
c97d6d2c | 1729 | { |
ff2de166 PB |
1730 | target_ulong base = 0; |
1731 | target_ulong scaled_index = 0; | |
c97d6d2c SAGDR |
1732 | int addr_size = decode->addressing_size; |
1733 | int base_reg = decode->sib.base; | |
1734 | int index_reg = decode->sib.index; | |
1735 | ||
6701d81d | 1736 | *sel = R_DS; |
c97d6d2c | 1737 | |
6701d81d | 1738 | if (decode->modrm.mod || base_reg != R_EBP) { |
c97d6d2c | 1739 | if (decode->rex.b) { |
6701d81d | 1740 | base_reg |= R_R8; |
c97d6d2c | 1741 | } |
6701d81d PB |
1742 | if (base_reg == R_ESP || base_reg == R_EBP) { |
1743 | *sel = R_SS; | |
c97d6d2c | 1744 | } |
b4e1af89 RB |
1745 | base = get_reg_val(env, decode->sib.base, decode->rex.rex, |
1746 | decode->rex.b, addr_size); | |
c97d6d2c SAGDR |
1747 | } |
1748 | ||
1749 | if (decode->rex.x) { | |
6701d81d | 1750 | index_reg |= R_R8; |
c97d6d2c SAGDR |
1751 | } |
1752 | ||
6701d81d | 1753 | if (index_reg != R_ESP) { |
b4e1af89 RB |
1754 | scaled_index = get_reg_val(env, index_reg, decode->rex.rex, |
1755 | decode->rex.x, addr_size) << | |
c97d6d2c SAGDR |
1756 | decode->sib.scale; |
1757 | } | |
1758 | return base + scaled_index; | |
1759 | } | |
1760 | ||
1761 | void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode, | |
1762 | struct x86_decode_op *op) | |
1763 | { | |
6701d81d | 1764 | X86Seg seg = R_DS; |
ff2de166 | 1765 | target_ulong ptr = 0; |
c97d6d2c SAGDR |
1766 | int addr_size = decode->addressing_size; |
1767 | ||
1768 | if (decode->displacement_size) { | |
1769 | ptr = sign(decode->displacement, decode->displacement_size); | |
1770 | } | |
1771 | ||
1772 | if (4 == decode->modrm.rm) { | |
1773 | ptr += get_sib_val(env, decode, &seg); | |
1774 | } else if (!decode->modrm.mod && 5 == decode->modrm.rm) { | |
1775 | if (x86_is_long_mode(ENV_GET_CPU(env))) { | |
1776 | ptr += RIP(env) + decode->len; | |
1777 | } else { | |
1778 | ptr = decode->displacement; | |
1779 | } | |
1780 | } else { | |
6701d81d PB |
1781 | if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) { |
1782 | seg = R_SS; | |
c97d6d2c | 1783 | } |
b4e1af89 RB |
1784 | ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex, |
1785 | decode->rex.b, addr_size); | |
c97d6d2c SAGDR |
1786 | } |
1787 | ||
1788 | if (X86_DECODE_CMD_LEA == decode->cmd) { | |
1789 | op->ptr = (uint32_t)ptr; | |
1790 | } else { | |
1791 | op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg); | |
1792 | } | |
1793 | } | |
1794 | ||
1795 | void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode, | |
1796 | struct x86_decode_op *op) | |
1797 | { | |
6701d81d | 1798 | X86Seg seg = R_DS; |
c97d6d2c SAGDR |
1799 | int32_t offset = 0; |
1800 | int mod = decode->modrm.mod; | |
1801 | int rm = decode->modrm.rm; | |
ff2de166 | 1802 | target_ulong ptr; |
c97d6d2c SAGDR |
1803 | int src = decode->modrm.rm; |
1804 | ||
1805 | if (decode->displacement_size) { | |
1806 | offset = sign(decode->displacement, decode->displacement_size); | |
1807 | } | |
1808 | ||
1809 | if (4 == rm) { | |
1810 | ptr = get_sib_val(env, decode, &seg) + offset; | |
1811 | } else if (0 == mod && 5 == rm) { | |
1812 | ptr = RIP(env) + decode->len + (int32_t) offset; | |
1813 | } else { | |
b4e1af89 RB |
1814 | ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) + |
1815 | (int64_t) offset; | |
c97d6d2c SAGDR |
1816 | } |
1817 | ||
1818 | if (X86_DECODE_CMD_LEA == decode->cmd) { | |
1819 | op->ptr = ptr; | |
1820 | } else { | |
1821 | op->ptr = decode_linear_addr(env, decode, ptr, seg); | |
1822 | } | |
1823 | } | |
1824 | ||
1825 | ||
1826 | void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode, | |
1827 | struct x86_decode_op *op) | |
1828 | { | |
1829 | if (3 == decode->modrm.mod) { | |
1830 | op->reg = decode->modrm.reg; | |
1831 | op->type = X86_VAR_REG; | |
b4e1af89 RB |
1832 | op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex, |
1833 | decode->rex.b, decode->operand_size); | |
c97d6d2c SAGDR |
1834 | return; |
1835 | } | |
1836 | ||
1837 | switch (decode->addressing_size) { | |
1838 | case 2: | |
1839 | calc_modrm_operand16(env, decode, op); | |
1840 | break; | |
1841 | case 4: | |
1842 | calc_modrm_operand32(env, decode, op); | |
1843 | break; | |
1844 | case 8: | |
1845 | calc_modrm_operand64(env, decode, op); | |
1846 | break; | |
1847 | default: | |
1848 | VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size); | |
1849 | break; | |
1850 | } | |
1851 | } | |
1852 | ||
1853 | static void decode_prefix(CPUX86State *env, struct x86_decode *decode) | |
1854 | { | |
1855 | while (1) { | |
1856 | uint8_t byte = decode_byte(env, decode); | |
1857 | switch (byte) { | |
1858 | case PREFIX_LOCK: | |
1859 | decode->lock = byte; | |
1860 | break; | |
1861 | case PREFIX_REPN: | |
1862 | case PREFIX_REP: | |
1863 | decode->rep = byte; | |
1864 | break; | |
1865 | case PREFIX_CS_SEG_OVEERIDE: | |
1866 | case PREFIX_SS_SEG_OVEERIDE: | |
1867 | case PREFIX_DS_SEG_OVEERIDE: | |
1868 | case PREFIX_ES_SEG_OVEERIDE: | |
1869 | case PREFIX_FS_SEG_OVEERIDE: | |
1870 | case PREFIX_GS_SEG_OVEERIDE: | |
1871 | decode->segment_override = byte; | |
1872 | break; | |
1873 | case PREFIX_OP_SIZE_OVERRIDE: | |
1874 | decode->op_size_override = byte; | |
1875 | break; | |
1876 | case PREFIX_ADDR_SIZE_OVERRIDE: | |
1877 | decode->addr_size_override = byte; | |
1878 | break; | |
1879 | case PREFIX_REX ... (PREFIX_REX + 0xf): | |
1880 | if (x86_is_long_mode(ENV_GET_CPU(env))) { | |
1881 | decode->rex.rex = byte; | |
1882 | break; | |
1883 | } | |
1884 | /* fall through when not in long mode */ | |
1885 | default: | |
1886 | decode->len--; | |
1887 | return; | |
1888 | } | |
1889 | } | |
1890 | } | |
1891 | ||
1892 | void set_addressing_size(CPUX86State *env, struct x86_decode *decode) | |
1893 | { | |
1894 | decode->addressing_size = -1; | |
1895 | if (x86_is_real(ENV_GET_CPU(env)) || x86_is_v8086(ENV_GET_CPU(env))) { | |
1896 | if (decode->addr_size_override) { | |
1897 | decode->addressing_size = 4; | |
1898 | } else { | |
1899 | decode->addressing_size = 2; | |
1900 | } | |
1901 | } else if (!x86_is_long_mode(ENV_GET_CPU(env))) { | |
1902 | /* protected */ | |
1903 | struct vmx_segment cs; | |
6701d81d | 1904 | vmx_read_segment_descriptor(ENV_GET_CPU(env), &cs, R_CS); |
c97d6d2c SAGDR |
1905 | /* check db */ |
1906 | if ((cs.ar >> 14) & 1) { | |
1907 | if (decode->addr_size_override) { | |
1908 | decode->addressing_size = 2; | |
1909 | } else { | |
1910 | decode->addressing_size = 4; | |
1911 | } | |
1912 | } else { | |
1913 | if (decode->addr_size_override) { | |
1914 | decode->addressing_size = 4; | |
1915 | } else { | |
1916 | decode->addressing_size = 2; | |
1917 | } | |
1918 | } | |
1919 | } else { | |
1920 | /* long */ | |
1921 | if (decode->addr_size_override) { | |
1922 | decode->addressing_size = 4; | |
1923 | } else { | |
1924 | decode->addressing_size = 8; | |
1925 | } | |
1926 | } | |
1927 | } | |
1928 | ||
1929 | void set_operand_size(CPUX86State *env, struct x86_decode *decode) | |
1930 | { | |
1931 | decode->operand_size = -1; | |
1932 | if (x86_is_real(ENV_GET_CPU(env)) || x86_is_v8086(ENV_GET_CPU(env))) { | |
1933 | if (decode->op_size_override) { | |
1934 | decode->operand_size = 4; | |
1935 | } else { | |
1936 | decode->operand_size = 2; | |
1937 | } | |
1938 | } else if (!x86_is_long_mode(ENV_GET_CPU(env))) { | |
1939 | /* protected */ | |
1940 | struct vmx_segment cs; | |
6701d81d | 1941 | vmx_read_segment_descriptor(ENV_GET_CPU(env), &cs, R_CS); |
c97d6d2c SAGDR |
1942 | /* check db */ |
1943 | if ((cs.ar >> 14) & 1) { | |
1944 | if (decode->op_size_override) { | |
1945 | decode->operand_size = 2; | |
1946 | } else{ | |
1947 | decode->operand_size = 4; | |
1948 | } | |
1949 | } else { | |
1950 | if (decode->op_size_override) { | |
1951 | decode->operand_size = 4; | |
1952 | } else { | |
1953 | decode->operand_size = 2; | |
1954 | } | |
1955 | } | |
1956 | } else { | |
1957 | /* long */ | |
1958 | if (decode->op_size_override) { | |
1959 | decode->operand_size = 2; | |
1960 | } else { | |
1961 | decode->operand_size = 4; | |
1962 | } | |
1963 | ||
1964 | if (decode->rex.w) { | |
1965 | decode->operand_size = 8; | |
1966 | } | |
1967 | } | |
1968 | } | |
1969 | ||
1970 | static void decode_sib(CPUX86State *env, struct x86_decode *decode) | |
1971 | { | |
1972 | if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) && | |
1973 | (decode->addressing_size != 2)) { | |
1974 | decode->sib.sib = decode_byte(env, decode); | |
1975 | decode->sib_present = true; | |
1976 | } | |
1977 | } | |
1978 | ||
1979 | /* 16 bit modrm */ | |
1980 | int disp16_tbl[4][8] = { | |
1981 | {0, 0, 0, 0, 0, 0, 2, 0}, | |
1982 | {1, 1, 1, 1, 1, 1, 1, 1}, | |
1983 | {2, 2, 2, 2, 2, 2, 2, 2}, | |
1984 | {0, 0, 0, 0, 0, 0, 0, 0} | |
1985 | }; | |
1986 | ||
1987 | /* 32/64-bit modrm */ | |
1988 | int disp32_tbl[4][8] = { | |
1989 | {0, 0, 0, 0, -1, 4, 0, 0}, | |
1990 | {1, 1, 1, 1, 1, 1, 1, 1}, | |
1991 | {4, 4, 4, 4, 4, 4, 4, 4}, | |
1992 | {0, 0, 0, 0, 0, 0, 0, 0} | |
1993 | }; | |
1994 | ||
1995 | static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode) | |
1996 | { | |
1997 | int addressing_size = decode->addressing_size; | |
1998 | int mod = decode->modrm.mod; | |
1999 | int rm = decode->modrm.rm; | |
2000 | ||
2001 | decode->displacement_size = 0; | |
2002 | switch (addressing_size) { | |
2003 | case 2: | |
2004 | decode->displacement_size = disp16_tbl[mod][rm]; | |
2005 | if (decode->displacement_size) { | |
2006 | decode->displacement = (uint16_t)decode_bytes(env, decode, | |
2007 | decode->displacement_size); | |
2008 | } | |
2009 | break; | |
2010 | case 4: | |
2011 | case 8: | |
2012 | if (-1 == disp32_tbl[mod][rm]) { | |
2013 | if (5 == decode->sib.base) { | |
2014 | decode->displacement_size = 4; | |
2015 | } | |
2016 | } else { | |
2017 | decode->displacement_size = disp32_tbl[mod][rm]; | |
2018 | } | |
2019 | ||
2020 | if (decode->displacement_size) { | |
2021 | decode->displacement = (uint32_t)decode_bytes(env, decode, | |
2022 | decode->displacement_size); | |
2023 | } | |
2024 | break; | |
2025 | } | |
2026 | } | |
2027 | ||
2028 | static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode) | |
2029 | { | |
2030 | decode->modrm.modrm = decode_byte(env, decode); | |
2031 | decode->is_modrm = true; | |
2032 | ||
2033 | decode_sib(env, decode); | |
2034 | decode_displacement(env, decode); | |
2035 | } | |
2036 | ||
2037 | static inline void decode_opcode_general(CPUX86State *env, | |
2038 | struct x86_decode *decode, | |
2039 | uint8_t opcode, | |
2040 | struct decode_tbl *inst_decoder) | |
2041 | { | |
2042 | decode->cmd = inst_decoder->cmd; | |
2043 | if (inst_decoder->operand_size) { | |
2044 | decode->operand_size = inst_decoder->operand_size; | |
2045 | } | |
2046 | decode->flags_mask = inst_decoder->flags_mask; | |
2047 | ||
2048 | if (inst_decoder->is_modrm) { | |
2049 | decode_modrm(env, decode); | |
2050 | } | |
2051 | if (inst_decoder->decode_op1) { | |
2052 | inst_decoder->decode_op1(env, decode, &decode->op[0]); | |
2053 | } | |
2054 | if (inst_decoder->decode_op2) { | |
2055 | inst_decoder->decode_op2(env, decode, &decode->op[1]); | |
2056 | } | |
2057 | if (inst_decoder->decode_op3) { | |
2058 | inst_decoder->decode_op3(env, decode, &decode->op[2]); | |
2059 | } | |
2060 | if (inst_decoder->decode_op4) { | |
2061 | inst_decoder->decode_op4(env, decode, &decode->op[3]); | |
2062 | } | |
2063 | if (inst_decoder->decode_postfix) { | |
2064 | inst_decoder->decode_postfix(env, decode); | |
2065 | } | |
2066 | } | |
2067 | ||
2068 | static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode, | |
2069 | uint8_t opcode) | |
2070 | { | |
2071 | struct decode_tbl *inst_decoder = &_decode_tbl1[opcode]; | |
2072 | decode_opcode_general(env, decode, opcode, inst_decoder); | |
2073 | } | |
2074 | ||
2075 | ||
2076 | static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode, | |
2077 | uint8_t opcode) | |
2078 | { | |
2079 | struct decode_tbl *inst_decoder = &_decode_tbl2[opcode]; | |
2080 | decode_opcode_general(env, decode, opcode, inst_decoder); | |
2081 | } | |
2082 | ||
2083 | static void decode_opcodes(CPUX86State *env, struct x86_decode *decode) | |
2084 | { | |
2085 | uint8_t opcode; | |
2086 | ||
2087 | opcode = decode_byte(env, decode); | |
2088 | decode->opcode[decode->opcode_len++] = opcode; | |
2089 | if (opcode != OPCODE_ESCAPE) { | |
2090 | decode_opcode_1(env, decode, opcode); | |
2091 | } else { | |
2092 | opcode = decode_byte(env, decode); | |
2093 | decode->opcode[decode->opcode_len++] = opcode; | |
2094 | decode_opcode_2(env, decode, opcode); | |
2095 | } | |
2096 | } | |
2097 | ||
2098 | uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode) | |
2099 | { | |
715f396d | 2100 | memset(decode, 0, sizeof(*decode)); |
c97d6d2c SAGDR |
2101 | decode_prefix(env, decode); |
2102 | set_addressing_size(env, decode); | |
2103 | set_operand_size(env, decode); | |
2104 | ||
2105 | decode_opcodes(env, decode); | |
2106 | ||
2107 | return decode->len; | |
2108 | } | |
2109 | ||
2110 | void init_decoder() | |
2111 | { | |
2112 | int i; | |
2113 | ||
2114 | for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) { | |
2115 | memcpy(_decode_tbl1, &invl_inst, sizeof(invl_inst)); | |
2116 | } | |
2117 | for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) { | |
2118 | memcpy(_decode_tbl2, &invl_inst, sizeof(invl_inst)); | |
2119 | } | |
2120 | for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) { | |
2121 | memcpy(_decode_tbl3, &invl_inst, sizeof(invl_inst_x87)); | |
2122 | ||
2123 | } | |
2124 | for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) { | |
2125 | _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i]; | |
2126 | } | |
2127 | for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) { | |
2128 | _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i]; | |
2129 | } | |
2130 | for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) { | |
2131 | int index = ((_x87_inst[i].opcode & 0xf) << 4) | | |
2132 | ((_x87_inst[i].modrm_mod & 1) << 3) | | |
2133 | _x87_inst[i].modrm_reg; | |
2134 | _decode_tbl3[index] = _x87_inst[i]; | |
2135 | } | |
2136 | } | |
2137 | ||
2138 | ||
2139 | const char *decode_cmd_to_string(enum x86_decode_cmd cmd) | |
2140 | { | |
2141 | static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG", | |
2142 | "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT", | |
2143 | "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD", | |
2144 | "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST", | |
2145 | "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR", | |
2146 | "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG", | |
2147 | "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN", | |
2148 | "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW", | |
2149 | "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR", | |
2150 | "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR", | |
2151 | "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL", | |
2152 | "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS", | |
2153 | "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT", | |
2154 | "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA", | |
2155 | "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT", | |
2156 | "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES", | |
2157 | "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT", | |
2158 | "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW", | |
2159 | "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV", | |
2160 | "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE", | |
2161 | "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW", | |
2162 | "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"}; | |
2163 | return cmds[cmd]; | |
2164 | } | |
2165 | ||
ff2de166 PB |
2166 | target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode, |
2167 | target_ulong addr, X86Seg seg) | |
c97d6d2c SAGDR |
2168 | { |
2169 | switch (decode->segment_override) { | |
2170 | case PREFIX_CS_SEG_OVEERIDE: | |
6701d81d | 2171 | seg = R_CS; |
c97d6d2c SAGDR |
2172 | break; |
2173 | case PREFIX_SS_SEG_OVEERIDE: | |
6701d81d | 2174 | seg = R_SS; |
c97d6d2c SAGDR |
2175 | break; |
2176 | case PREFIX_DS_SEG_OVEERIDE: | |
6701d81d | 2177 | seg = R_DS; |
c97d6d2c SAGDR |
2178 | break; |
2179 | case PREFIX_ES_SEG_OVEERIDE: | |
6701d81d | 2180 | seg = R_ES; |
c97d6d2c SAGDR |
2181 | break; |
2182 | case PREFIX_FS_SEG_OVEERIDE: | |
6701d81d | 2183 | seg = R_FS; |
c97d6d2c SAGDR |
2184 | break; |
2185 | case PREFIX_GS_SEG_OVEERIDE: | |
6701d81d | 2186 | seg = R_GS; |
c97d6d2c SAGDR |
2187 | break; |
2188 | default: | |
2189 | break; | |
2190 | } | |
2191 | return linear_addr_size(ENV_GET_CPU(env), addr, decode->addressing_size, seg); | |
2192 | } |