master
c 1,420 lines 38.8 KB
Raw
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
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.1 of the License, or (at your option) any later version.
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
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
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/>.
17 */
18
19 /////////////////////////////////////////////////////////////////////////
20 //
21 // Copyright (C) 2001-2012 The Bochs Project
22 //
23 // This library is free software; you can redistribute it and/or
24 // modify it under the terms of the GNU Lesser General Public
25 // License as published by the Free Software Foundation; either
26 // version 2.1 of the License, or (at your option) any later version.
27 //
28 // This library is distributed in the hope that it will be useful,
29 // but WITHOUT ANY WARRANTY; without even the implied warranty of
30 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31 // Lesser General Public License for more details.
32 //
33 // You should have received a copy of the GNU Lesser General Public
34 // License along with this library; if not, see
35 // <https://www.gnu.org/licenses/>.
36 /////////////////////////////////////////////////////////////////////////
37
38 #include "qemu/osdep.h"
39 #include "qemu/error-report.h"
40 #include "panic.h"
41 #include "x86_decode.h"
42 #include "x86.h"
43 #include "x86_emu.h"
44 #include "x86_flags.h"
45 #include "x86_mmu.h"
46
47
48 #ifdef TARGET_X86_64
49 #define EXEC_2OP_FLAGS_CMD_64(env, decode, cmd, FLAGS_FUNC, save_res) \
50 case 8: \
51 { \
52 uint64_t v1 = (uint64_t)decode->op[0].val; \
53 uint64_t v2 = (uint64_t)decode->op[1].val; \
54 uint64_t diff = v1 cmd v2; \
55 if (save_res) { \
56 if (write_val_ext(env, &decode->op[0], diff, 8)) { return 1; } \
57 } \
58 FLAGS_FUNC##64(env, v1, v2, diff); \
59 break; \
60 }
61 #else
62 #define EXEC_2OP_FLAGS_CMD_64(env, decode, cmd, FLAGS_FUNC, save_res)
63 #endif
64 #define EXEC_2OP_FLAGS_CMD(env, decode, cmd, FLAGS_FUNC, save_res) \
65 { \
66 if (fetch_operands(env, decode, 2, true, true, false)) {\
67 return 1; \
68 }\
69 switch (decode->operand_size) { \
70 case 1: \
71 { \
72 uint8_t v1 = (uint8_t)decode->op[0].val; \
73 uint8_t v2 = (uint8_t)decode->op[1].val; \
74 uint8_t diff = v1 cmd v2; \
75 if (save_res) { \
76 if (write_val_ext(env, &decode->op[0], diff, 1)) { return 1; } \
77 } \
78 FLAGS_FUNC##8(env, v1, v2, diff); \
79 break; \
80 } \
81 case 2: \
82 { \
83 uint16_t v1 = (uint16_t)decode->op[0].val; \
84 uint16_t v2 = (uint16_t)decode->op[1].val; \
85 uint16_t diff = v1 cmd v2; \
86 if (save_res) { \
87 if (write_val_ext(env, &decode->op[0], diff, 2)) { return 1; } \
88 } \
89 FLAGS_FUNC##16(env, v1, v2, diff); \
90 break; \
91 } \
92 case 4: \
93 { \
94 uint32_t v1 = (uint32_t)decode->op[0].val; \
95 uint32_t v2 = (uint32_t)decode->op[1].val; \
96 uint32_t diff = v1 cmd v2; \
97 if (save_res) { \
98 if (write_val_ext(env, &decode->op[0], diff, 4)) { return 1; } \
99 } \
100 FLAGS_FUNC##32(env, v1, v2, diff); \
101 break; \
102 } \
103 EXEC_2OP_FLAGS_CMD_64(env, decode, cmd, FLAGS_FUNC, save_res) \
104 default: \
105 VM_PANIC("bad size\n"); \
106 } \
107 } \
108
109 target_ulong read_reg(CPUX86State *env, int reg, int size)
110 {
111 switch (size) {
112 case 1:
113 return x86_reg(env, reg)->lx;
114 case 2:
115 return x86_reg(env, reg)->rx;
116 case 4:
117 return x86_reg(env, reg)->erx;
118 case 8:
119 return x86_reg(env, reg)->rrx;
120 default:
121 abort();
122 }
123 return 0;
124 }
125
126 void write_reg(CPUX86State *env, int reg, target_ulong val, int size)
127 {
128 switch (size) {
129 case 1:
130 x86_reg(env, reg)->lx = val;
131 break;
132 case 2:
133 x86_reg(env, reg)->rx = val;
134 break;
135 case 4:
136 x86_reg(env, reg)->rrx = (uint32_t)val;
137 break;
138 case 8:
139 x86_reg(env, reg)->rrx = val;
140 break;
141 default:
142 abort();
143 }
144 }
145
146 target_ulong read_val_from_reg(void *reg_ptr, int size)
147 {
148 target_ulong val;
149
150 switch (size) {
151 case 1:
152 val = *(uint8_t *)reg_ptr;
153 break;
154 case 2:
155 val = *(uint16_t *)reg_ptr;
156 break;
157 case 4:
158 val = *(uint32_t *)reg_ptr;
159 break;
160 case 8:
161 val = *(uint64_t *)reg_ptr;
162 break;
163 default:
164 abort();
165 }
166 return val;
167 }
168
169 void write_val_to_reg(void *reg_ptr, target_ulong val, int size)
170 {
171 switch (size) {
172 case 1:
173 *(uint8_t *)reg_ptr = val;
174 break;
175 case 2:
176 *(uint16_t *)reg_ptr = val;
177 break;
178 case 4:
179 *(uint64_t *)reg_ptr = (uint32_t)val;
180 break;
181 case 8:
182 *(uint64_t *)reg_ptr = val;
183 break;
184 default:
185 abort();
186 }
187 }
188
189 bool write_val_ext(CPUX86State *env, struct x86_decode_op *decode, target_ulong val, int size)
190 {
191 if (decode->type == X86_VAR_REG) {
192 write_val_to_reg(decode->regptr, val, size);
193 } else {
194 MMUTranslateResult res = x86_write_mem(env_cpu(env), &val, decode->addr, size);
195 if (res) {
196 if (res == MMU_TRANSLATE_GPA_UNMAPPED) {
197 return 0;
198 }
199 return 1;
200 }
201 }
202 return 0;
203 }
204
205 uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes)
206 {
207 MMUTranslateResult res = x86_read_mem(env_cpu(env), env->emu_mmio_buf, ptr, bytes);
208 if (res) {
209 if (res == MMU_TRANSLATE_GPA_UNMAPPED) {
210 memset(env->emu_mmio_buf, 0xFF, bytes);
211 return env->emu_mmio_buf;
212 }
213 return NULL;
214 }
215 return env->emu_mmio_buf;
216 }
217
218
219 static bool read_val_from_mem(CPUX86State *env, target_long ptr, int size, target_ulong* val)
220 {
221 uint8_t *mmio_ptr;
222
223 mmio_ptr = read_mmio(env, ptr, size);
224 if (mmio_ptr == NULL) {
225 return 1;
226 }
227 switch (size) {
228 case 1:
229 *val = *(uint8_t *)mmio_ptr;
230 break;
231 case 2:
232 *val = *(uint16_t *)mmio_ptr;
233 break;
234 case 4:
235 *val = *(uint32_t *)mmio_ptr;
236 break;
237 case 8:
238 *val = *(uint64_t *)mmio_ptr;
239 break;
240 default:
241 VM_PANIC("bad size\n");
242 break;
243 }
244 return 0;
245 }
246
247 bool read_val_ext(CPUX86State *env, struct x86_decode_op *decode, int size, target_ulong* val)
248 {
249 if (decode->type == X86_VAR_REG) {
250 *val = read_val_from_reg(decode->regptr, size);
251 } else {
252 if (read_val_from_mem(env, decode->addr, size, val)) {
253 return 1;
254 }
255 }
256 return 0;
257 }
258
259 static bool fetch_operands(CPUX86State *env, struct x86_decode *decode,
260 int n, bool val_op0, bool val_op1, bool val_op2)
261 {
262 int i;
263 bool calc_val[3] = {val_op0, val_op1, val_op2};
264
265 for (i = 0; i < n; i++) {
266 switch (decode->op[i].type) {
267 case X86_VAR_IMMEDIATE:
268 break;
269 case X86_VAR_REG:
270 VM_PANIC_ON(!decode->op[i].regptr);
271 if (calc_val[i]) {
272 decode->op[i].val = read_val_from_reg(decode->op[i].regptr,
273 decode->operand_size);
274 }
275 break;
276 case X86_VAR_RM:
277 calc_modrm_operand(env, decode, &decode->op[i]);
278 if (calc_val[i]) {
279 if (read_val_ext(env, &decode->op[i],decode->operand_size,
280 &decode->op[i].val)) {
281 return 1;
282 }
283 }
284 break;
285 case X86_VAR_OFFSET:
286 decode->op[i].addr = decode_linear_addr(env, decode,
287 decode->op[i].addr,
288 R_DS);
289 if (calc_val[i]) {
290 if (read_val_ext(env, &decode->op[i], decode->operand_size,
291 &decode->op[i].val)) {
292 return 1;
293 }
294 }
295 break;
296 default:
297 break;
298 }
299 }
300 return 0;
301 }
302
303 static bool exec_mov(CPUX86State *env, struct x86_decode *decode)
304 {
305 fetch_operands(env, decode, 2, false, true, false);
306 if (write_val_ext(env, &decode->op[0], decode->op[1].val,
307 decode->operand_size)) {
308 return 1;
309 }
310
311 env->eip += decode->len;
312 return 0;
313 }
314
315 static bool exec_add(CPUX86State *env, struct x86_decode *decode)
316 {
317 EXEC_2OP_FLAGS_CMD(env, decode, +, SET_FLAGS_OSZAPC_ADD, true);
318 env->eip += decode->len;
319 return 0;
320 }
321
322 static bool exec_or(CPUX86State *env, struct x86_decode *decode)
323 {
324 EXEC_2OP_FLAGS_CMD(env, decode, |, SET_FLAGS_OSZAPC_LOGIC, true);
325 env->eip += decode->len;
326 return 0;
327 }
328
329 static bool exec_adc(CPUX86State *env, struct x86_decode *decode)
330 {
331 EXEC_2OP_FLAGS_CMD(env, decode, +get_CF(env)+, SET_FLAGS_OSZAPC_ADD, true);
332 env->eip += decode->len;
333 return 0;
334 }
335
336 static bool exec_sbb(CPUX86State *env, struct x86_decode *decode)
337 {
338 EXEC_2OP_FLAGS_CMD(env, decode, -get_CF(env)-, SET_FLAGS_OSZAPC_SUB, true);
339 env->eip += decode->len;
340 return 0;
341 }
342
343 static bool exec_and(CPUX86State *env, struct x86_decode *decode)
344 {
345 EXEC_2OP_FLAGS_CMD(env, decode, &, SET_FLAGS_OSZAPC_LOGIC, true);
346 env->eip += decode->len;
347 return 0;
348 }
349
350 static bool exec_sub(CPUX86State *env, struct x86_decode *decode)
351 {
352 EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, true);
353 env->eip += decode->len;
354 return 0;
355 }
356
357 static bool exec_xor(CPUX86State *env, struct x86_decode *decode)
358 {
359 EXEC_2OP_FLAGS_CMD(env, decode, ^, SET_FLAGS_OSZAPC_LOGIC, true);
360 env->eip += decode->len;
361 return 0;
362 }
363
364 static bool exec_neg(CPUX86State *env, struct x86_decode *decode)
365 {
366 /*EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false);*/
367 int32_t val;
368 fetch_operands(env, decode, 2, true, true, false);
369
370 val = 0 - sign(decode->op[1].val, decode->operand_size);
371 write_val_ext(env, &decode->op[1], val, decode->operand_size);
372
373 if (4 == decode->operand_size) {
374 SET_FLAGS_OSZAPC_SUB32(env, 0, 0 - val, val);
375 } else if (2 == decode->operand_size) {
376 SET_FLAGS_OSZAPC_SUB16(env, 0, 0 - val, val);
377 } else if (1 == decode->operand_size) {
378 SET_FLAGS_OSZAPC_SUB8(env, 0, 0 - val, val);
379 } else {
380 VM_PANIC("bad op size\n");
381 }
382
383 /*lflags_to_rflags(env);*/
384 env->eip += decode->len;
385 return 0;
386 }
387
388 static bool exec_cmp(CPUX86State *env, struct x86_decode *decode)
389 {
390 EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false);
391 env->eip += decode->len;
392 return 0;
393 }
394
395 static bool exec_inc(CPUX86State *env, struct x86_decode *decode)
396 {
397 decode->op[1].type = X86_VAR_IMMEDIATE;
398 decode->op[1].val = 0;
399
400 EXEC_2OP_FLAGS_CMD(env, decode, +1+, SET_FLAGS_OSZAP_ADD, true);
401
402 env->eip += decode->len;
403 return 0;
404 }
405
406 static bool exec_dec(CPUX86State *env, struct x86_decode *decode)
407 {
408 decode->op[1].type = X86_VAR_IMMEDIATE;
409 decode->op[1].val = 0;
410
411 EXEC_2OP_FLAGS_CMD(env, decode, -1-, SET_FLAGS_OSZAP_SUB, true);
412 env->eip += decode->len;
413 return 0;
414 }
415
416 static bool exec_tst(CPUX86State *env, struct x86_decode *decode)
417 {
418 EXEC_2OP_FLAGS_CMD(env, decode, &, SET_FLAGS_OSZAPC_LOGIC, false);
419 env->eip += decode->len;
420 return 0;
421 }
422
423 static bool exec_not(CPUX86State *env, struct x86_decode *decode)
424 {
425 fetch_operands(env, decode, 1, true, false, false);
426
427 write_val_ext(env, &decode->op[0], ~decode->op[0].val,
428 decode->operand_size);
429 env->eip += decode->len;
430 return 0;
431 }
432
433 bool exec_movzx(CPUX86State *env, struct x86_decode *decode)
434 {
435 int src_op_size;
436 int op_size = decode->operand_size;
437
438 fetch_operands(env, decode, 1, false, false, false);
439
440 if (0xb6 == decode->opcode[1]) {
441 src_op_size = 1;
442 } else {
443 src_op_size = 2;
444 }
445 decode->operand_size = src_op_size;
446 calc_modrm_operand(env, decode, &decode->op[1]);
447 if (read_val_ext(env, &decode->op[1], src_op_size, &decode->op[1].val)) {
448 return 1;
449 }
450 write_val_ext(env, &decode->op[0], decode->op[1].val, op_size);
451
452 env->eip += decode->len;
453 return 0;
454 }
455
456 static bool exec_out(CPUX86State *env, struct x86_decode *decode)
457 {
458 switch (decode->opcode[0]) {
459 case 0xe6:
460 emul_ops->handle_io(env_cpu(env), decode->op[0].val, &AL(env), 1, 1, 1);
461 break;
462 case 0xe7:
463 emul_ops->handle_io(env_cpu(env), decode->op[0].val, &RAX(env), 1,
464 decode->operand_size, 1);
465 break;
466 case 0xee:
467 emul_ops->handle_io(env_cpu(env), DX(env), &AL(env), 1, 1, 1);
468 break;
469 case 0xef:
470 emul_ops->handle_io(env_cpu(env), DX(env), &RAX(env), 1,
471 decode->operand_size, 1);
472 break;
473 default:
474 VM_PANIC("Bad out opcode\n");
475 break;
476 }
477 env->eip += decode->len;
478 return 0;
479 }
480
481 static bool exec_in(CPUX86State *env, struct x86_decode *decode)
482 {
483 target_ulong val = 0;
484 switch (decode->opcode[0]) {
485 case 0xe4:
486 emul_ops->handle_io(env_cpu(env), decode->op[0].val, &AL(env), 0, 1, 1);
487 break;
488 case 0xe5:
489 emul_ops->handle_io(env_cpu(env), decode->op[0].val, &val, 0,
490 decode->operand_size, 1);
491 if (decode->operand_size == 2) {
492 AX(env) = val;
493 } else {
494 RAX(env) = (uint32_t)val;
495 }
496 break;
497 case 0xec:
498 emul_ops->handle_io(env_cpu(env), DX(env), &AL(env), 0, 1, 1);
499 break;
500 case 0xed:
501 emul_ops->handle_io(env_cpu(env), DX(env), &val, 0,
502 decode->operand_size, 1);
503 if (decode->operand_size == 2) {
504 AX(env) = val;
505 } else {
506 RAX(env) = (uint32_t)val;
507 }
508
509 break;
510 default:
511 VM_PANIC("Bad in opcode\n");
512 break;
513 }
514
515 env->eip += decode->len;
516 return 0;
517 }
518
519 static inline void string_increment_reg(CPUX86State *env, int reg,
520 struct x86_decode *decode)
521 {
522 target_ulong val = read_reg(env, reg, decode->addressing_size);
523 if (env->eflags & DF_MASK) {
524 val -= decode->operand_size;
525 } else {
526 val += decode->operand_size;
527 }
528 write_reg(env, reg, val, decode->addressing_size);
529 }
530
531 static inline int get_ZF(CPUX86State *env) {
532 return env->cc_dst ? 0 : CC_Z;
533 }
534
535 static inline bool string_rep(CPUX86State *env, struct x86_decode *decode,
536 bool (*func)(CPUX86State *env,
537 struct x86_decode *ins), int rep)
538 {
539 target_ulong rcx = read_reg(env, R_ECX, decode->addressing_size);
540
541 while (rcx != 0) {
542 bool is_cmps_or_scas = decode->cmd == X86_DECODE_CMD_CMPS || decode->cmd == X86_DECODE_CMD_SCAS;
543 if (func(env, decode)) {
544 return 1;
545 }
546 rcx--;
547 write_reg(env, R_ECX, rcx, decode->addressing_size);
548 if ((PREFIX_REP == rep) && !get_ZF(env) && is_cmps_or_scas) {
549 break;
550 }
551 if ((PREFIX_REPN == rep) && get_ZF(env)&& is_cmps_or_scas) {
552 break;
553 }
554 }
555 return 0;
556 }
557
558 static bool exec_ins_single(CPUX86State *env, struct x86_decode *decode)
559 {
560 MMUTranslateResult res;
561
562 target_ulong addr = linear_addr_size(env_cpu(env), RDI(env),
563 decode->addressing_size, R_ES);
564
565 emul_ops->handle_io(env_cpu(env), DX(env), env->emu_mmio_buf, 0,
566 decode->operand_size, 1);
567 res = x86_write_mem(env_cpu(env), env->emu_mmio_buf, addr,
568 decode->operand_size);
569 if (res) {
570 return 1;
571 }
572
573 string_increment_reg(env, R_EDI, decode);
574 return 0;
575 }
576
577 static bool exec_ins(CPUX86State *env, struct x86_decode *decode)
578 {
579 bool res;
580 if (decode->rep) {
581 res = string_rep(env, decode, exec_ins_single, 0);
582 } else {
583 res = exec_ins_single(env, decode);
584 }
585
586 if (res) {
587 return 1;
588 }
589 env->eip += decode->len;
590 return 0;
591 }
592
593 static bool exec_outs_single(CPUX86State *env, struct x86_decode *decode)
594 {
595 target_ulong addr = decode_linear_addr(env, decode, RSI(env), R_DS);
596
597 x86_read_mem(env_cpu(env), env->emu_mmio_buf, addr,
598 decode->operand_size);
599 emul_ops->handle_io(env_cpu(env), DX(env), env->emu_mmio_buf, 1,
600 decode->operand_size, 1);
601
602 string_increment_reg(env, R_ESI, decode);
603 return 0;
604 }
605
606 static bool exec_outs(CPUX86State *env, struct x86_decode *decode)
607 {
608 bool res;
609 if (decode->rep) {
610 res = string_rep(env, decode, exec_outs_single, 0);
611 } else {
612 res = exec_outs_single(env, decode);
613 }
614
615 if (res) {
616 return 1;
617 }
618 env->eip += decode->len;
619 return 0;
620 }
621
622 static bool exec_movs_single(CPUX86State *env, struct x86_decode *decode)
623 {
624 target_ulong src_addr;
625 target_ulong dst_addr;
626 target_ulong val;
627 MMUTranslateResult res;
628
629 src_addr = decode_linear_addr(env, decode, RSI(env), R_DS);
630 dst_addr = linear_addr_size(env_cpu(env), RDI(env),
631 decode->addressing_size, R_ES);
632
633 if (read_val_from_mem(env, src_addr, decode->operand_size, &val)) {
634 return 1;
635 }
636 res = x86_write_mem(env_cpu(env), &val, dst_addr, decode->operand_size);
637 if (res) {
638 return 1;
639 }
640
641 string_increment_reg(env, R_ESI, decode);
642 string_increment_reg(env, R_EDI, decode);
643 return 0;
644 }
645
646 static bool exec_movs(CPUX86State *env, struct x86_decode *decode)
647 {
648 bool res;
649 if (decode->rep) {
650 res = string_rep(env, decode, exec_movs_single, 0);
651 } else {
652 res = exec_movs_single(env, decode);
653 }
654
655 if (res) {
656 return 1;
657 }
658 env->eip += decode->len;
659 return 0;
660 }
661
662 static bool exec_cmps_single(CPUX86State *env, struct x86_decode *decode)
663 {
664 target_ulong src_addr;
665 target_ulong dst_addr;
666
667 src_addr = decode_linear_addr(env, decode, RSI(env), R_DS);
668 dst_addr = linear_addr_size(env_cpu(env), RDI(env),
669 decode->addressing_size, R_ES);
670
671 decode->op[0].type = X86_VAR_IMMEDIATE;
672 if (read_val_from_mem(env, src_addr, decode->operand_size, &decode->op[0].val)) {
673 return 1;
674 }
675 decode->op[1].type = X86_VAR_IMMEDIATE;
676 if (read_val_from_mem(env, dst_addr, decode->operand_size, &decode->op[1].val)) {
677 return 1;
678 }
679
680 EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false);
681
682 string_increment_reg(env, R_ESI, decode);
683 string_increment_reg(env, R_EDI, decode);
684 return 0;
685 }
686
687 static bool exec_cmps(CPUX86State *env, struct x86_decode *decode)
688 {
689 if (decode->rep) {
690 string_rep(env, decode, exec_cmps_single, decode->rep);
691 } else {
692 exec_cmps_single(env, decode);
693 }
694 env->eip += decode->len;
695 return 0;
696 }
697
698
699 static bool exec_stos_single(CPUX86State *env, struct x86_decode *decode)
700 {
701 target_ulong addr;
702 target_ulong val;
703 MMUTranslateResult res;
704
705 addr = linear_addr_size(env_cpu(env), RDI(env),
706 decode->addressing_size, R_ES);
707 val = read_reg(env, R_EAX, decode->operand_size);
708 res = x86_write_mem(env_cpu(env), &val, addr, decode->operand_size);
709 if (res) {
710 return 1;
711 }
712
713 string_increment_reg(env, R_EDI, decode);
714 return 0;
715 }
716
717
718 static bool exec_stos(CPUX86State *env, struct x86_decode *decode)
719 {
720 if (decode->rep) {
721 string_rep(env, decode, exec_stos_single, 0);
722 } else {
723 exec_stos_single(env, decode);
724 }
725
726 env->eip += decode->len;
727 return 0;
728 }
729
730 static bool exec_scas_single(CPUX86State *env, struct x86_decode *decode)
731 {
732 target_ulong addr;
733
734 addr = linear_addr_size(env_cpu(env), RDI(env),
735 decode->addressing_size, R_ES);
736 decode->op[1].type = X86_VAR_IMMEDIATE;
737 x86_read_mem(env_cpu(env), &decode->op[1].val, addr, decode->operand_size);
738
739 EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false);
740 string_increment_reg(env, R_EDI, decode);
741 return 0;
742 }
743
744 static bool exec_scas(CPUX86State *env, struct x86_decode *decode)
745 {
746 decode->op[0].type = X86_VAR_REG;
747 decode->op[0].reg = R_EAX;
748 decode->op[0].regptr = x86_reg(env, R_EAX);
749
750 if (decode->rep) {
751 string_rep(env, decode, exec_scas_single, decode->rep);
752 } else {
753 exec_scas_single(env, decode);
754 }
755
756 env->eip += decode->len;
757 return 0;
758 }
759
760 static bool exec_lods_single(CPUX86State *env, struct x86_decode *decode)
761 {
762 target_ulong addr;
763 target_ulong val = 0;
764
765 addr = decode_linear_addr(env, decode, RSI(env), R_DS);
766 x86_read_mem(env_cpu(env), &val, addr, decode->operand_size);
767 write_reg(env, R_EAX, val, decode->operand_size);
768
769 string_increment_reg(env, R_ESI, decode);
770 return 0;
771 }
772
773 static bool exec_lods(CPUX86State *env, struct x86_decode *decode)
774 {
775 if (decode->rep) {
776 string_rep(env, decode, exec_lods_single, 0);
777 } else {
778 exec_lods_single(env, decode);
779 }
780
781 env->eip += decode->len;
782 return 0;
783 }
784
785 void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_code)
786 {
787 env->exception_nr = exception_index;
788 env->error_code = error_code;
789 env->has_error_code = true;
790 env->exception_injected = 1;
791 }
792
793 static bool exec_rdmsr(CPUX86State *env, struct x86_decode *decode)
794 {
795 if (!emul_ops->simulate_rdmsr(env_cpu(env))) {
796 env->eip += decode->len;
797 }
798 return 0;
799 }
800
801 static bool exec_wrmsr(CPUX86State *env, struct x86_decode *decode)
802 {
803 if (!emul_ops->simulate_wrmsr(env_cpu(env))) {
804 env->eip += decode->len;
805 }
806 return 0;
807 }
808
809 /*
810 * flag:
811 * 0 - bt, 1 - btc, 2 - bts, 3 - btr
812 */
813 static bool do_bt(CPUX86State *env, struct x86_decode *decode, int flag)
814 {
815 int32_t displacement;
816 uint8_t index;
817 bool cf;
818 int mask = (4 == decode->operand_size) ? 0x1f : 0xf;
819
820 VM_PANIC_ON(decode->rex.rex);
821
822 if (fetch_operands(env, decode, 2, false, true, false)) {
823 return 1;
824 }
825 index = decode->op[1].val & mask;
826
827 if (decode->op[0].type != X86_VAR_REG) {
828 if (4 == decode->operand_size) {
829 displacement = ((int32_t) (decode->op[1].val & 0xffffffe0)) / 32;
830 decode->op[0].addr += 4 * displacement;
831 } else if (2 == decode->operand_size) {
832 displacement = ((int16_t) (decode->op[1].val & 0xfff0)) / 16;
833 decode->op[0].addr += 2 * displacement;
834 } else {
835 VM_PANIC("bt 64bit\n");
836 }
837 }
838 if (read_val_ext(env, &decode->op[0],
839 decode->operand_size, &decode->op[0].val)) {
840 return 1;
841 }
842 cf = (decode->op[0].val >> index) & 0x01;
843
844 switch (flag) {
845 case 0:
846 set_CF(env, cf);
847 return 0;
848 case 1:
849 decode->op[0].val ^= (1u << index);
850 break;
851 case 2:
852 decode->op[0].val |= (1u << index);
853 break;
854 case 3:
855 decode->op[0].val &= ~(1u << index);
856 break;
857 }
858 if (write_val_ext(env, &decode->op[0], decode->op[0].val,
859 decode->operand_size)) {
860 return 1;
861 }
862 set_CF(env, cf);
863 return 0;
864 }
865
866 static bool exec_bt(CPUX86State *env, struct x86_decode *decode)
867 {
868 if (do_bt(env, decode, 0)) {
869 return 1;
870 }
871 env->eip += decode->len;
872 return 0;
873 }
874
875 static bool exec_btc(CPUX86State *env, struct x86_decode *decode)
876 {
877 if (do_bt(env, decode, 1)) {
878 return 1;
879 }
880 env->eip += decode->len;
881 return 0;
882 }
883
884 static bool exec_btr(CPUX86State *env, struct x86_decode *decode)
885 {
886 if (do_bt(env, decode, 3)) {
887 return 1;
888 }
889 env->eip += decode->len;
890 return 0;
891 }
892
893 static bool exec_bts(CPUX86State *env, struct x86_decode *decode)
894 {
895 if (do_bt(env, decode, 2)) {
896 return 1;
897 }
898 env->eip += decode->len;
899 return 0;
900 }
901
902 bool exec_shl(CPUX86State *env, struct x86_decode *decode)
903 {
904 uint8_t count;
905 int of = 0, cf = 0;
906
907 if (fetch_operands(env, decode, 2, true, true, false)) {
908 return 1;
909 }
910
911 count = decode->op[1].val;
912 count &= 0x1f; /* count is masked to 5 bits*/
913 if (!count) {
914 goto exit;
915 }
916
917 switch (decode->operand_size) {
918 case 1:
919 {
920 uint8_t res = 0;
921 if (count <= 8) {
922 res = (decode->op[0].val << count);
923 cf = (decode->op[0].val >> (8 - count)) & 0x1;
924 of = cf ^ (res >> 7);
925 }
926
927 write_val_ext(env, &decode->op[0], res, 1);
928 SET_FLAGS_OSZAPC_LOGIC8(env, 0, 0, res);
929 SET_FLAGS_OxxxxC(env, of, cf);
930 break;
931 }
932 case 2:
933 {
934 uint16_t res = 0;
935
936 /* from bochs */
937 if (count <= 16) {
938 res = (decode->op[0].val << count);
939 cf = (decode->op[0].val >> (16 - count)) & 0x1;
940 of = cf ^ (res >> 15); /* of = cf ^ result15 */
941 }
942
943 write_val_ext(env, &decode->op[0], res, 2);
944 SET_FLAGS_OSZAPC_LOGIC16(env, 0, 0, res);
945 SET_FLAGS_OxxxxC(env, of, cf);
946 break;
947 }
948 case 4:
949 {
950 uint32_t res = decode->op[0].val << count;
951
952 write_val_ext(env, &decode->op[0], res, 4);
953 SET_FLAGS_OSZAPC_LOGIC32(env, 0, 0, res);
954 cf = (decode->op[0].val >> (32 - count)) & 0x1;
955 of = cf ^ (res >> 31); /* of = cf ^ result31 */
956 SET_FLAGS_OxxxxC(env, of, cf);
957 break;
958 }
959 default:
960 abort();
961 }
962
963 exit:
964 /* lflags_to_rflags(env); */
965 env->eip += decode->len;
966 return 0;
967 }
968
969 bool exec_movsx(CPUX86State *env, struct x86_decode *decode)
970 {
971 int src_op_size;
972 int op_size = decode->operand_size;
973 target_ulong val;
974
975 fetch_operands(env, decode, 2, false, false, false);
976
977 if (0xbe == decode->opcode[1]) {
978 src_op_size = 1;
979 } else {
980 src_op_size = 2;
981 }
982
983 decode->operand_size = src_op_size;
984 calc_modrm_operand(env, decode, &decode->op[1]);
985 if (read_val_ext(env, &decode->op[1], src_op_size, &val)) {
986 return 1;
987 }
988 decode->op[1].val = sign(val, src_op_size);
989
990 write_val_ext(env, &decode->op[0], decode->op[1].val, op_size);
991
992 env->eip += decode->len;
993 return 0;
994 }
995
996 bool exec_ror(CPUX86State *env, struct x86_decode *decode)
997 {
998 uint8_t count;
999
1000 fetch_operands(env, decode, 2, true, true, false);
1001 count = decode->op[1].val;
1002
1003 switch (decode->operand_size) {
1004 case 1:
1005 {
1006 uint32_t bit6, bit7;
1007 uint8_t res;
1008
1009 if ((count & 0x07) == 0) {
1010 if (count & 0x18) {
1011 bit6 = ((uint8_t)decode->op[0].val >> 6) & 1;
1012 bit7 = ((uint8_t)decode->op[0].val >> 7) & 1;
1013 SET_FLAGS_OxxxxC(env, bit6 ^ bit7, bit7);
1014 }
1015 } else {
1016 count &= 0x7; /* use only bottom 3 bits */
1017 res = ((uint8_t)decode->op[0].val >> count) |
1018 ((uint8_t)decode->op[0].val << (8 - count));
1019 write_val_ext(env, &decode->op[0], res, 1);
1020 bit6 = (res >> 6) & 1;
1021 bit7 = (res >> 7) & 1;
1022 /* set eflags: ROR count affects the following flags: C, O */
1023 SET_FLAGS_OxxxxC(env, bit6 ^ bit7, bit7);
1024 }
1025 break;
1026 }
1027 case 2:
1028 {
1029 uint32_t bit14, bit15;
1030 uint16_t res;
1031
1032 if ((count & 0x0f) == 0) {
1033 if (count & 0x10) {
1034 bit14 = ((uint16_t)decode->op[0].val >> 14) & 1;
1035 bit15 = ((uint16_t)decode->op[0].val >> 15) & 1;
1036 /* of = result14 ^ result15 */
1037 SET_FLAGS_OxxxxC(env, bit14 ^ bit15, bit15);
1038 }
1039 } else {
1040 count &= 0x0f; /* use only 4 LSB's */
1041 res = ((uint16_t)decode->op[0].val >> count) |
1042 ((uint16_t)decode->op[0].val << (16 - count));
1043 write_val_ext(env, &decode->op[0], res, 2);
1044
1045 bit14 = (res >> 14) & 1;
1046 bit15 = (res >> 15) & 1;
1047 /* of = result14 ^ result15 */
1048 SET_FLAGS_OxxxxC(env, bit14 ^ bit15, bit15);
1049 }
1050 break;
1051 }
1052 case 4:
1053 {
1054 uint32_t bit31, bit30;
1055 uint32_t res;
1056
1057 count &= 0x1f;
1058 if (count) {
1059 res = ((uint32_t)decode->op[0].val >> count) |
1060 ((uint32_t)decode->op[0].val << (32 - count));
1061 write_val_ext(env, &decode->op[0], res, 4);
1062
1063 bit31 = (res >> 31) & 1;
1064 bit30 = (res >> 30) & 1;
1065 /* of = result30 ^ result31 */
1066 SET_FLAGS_OxxxxC(env, bit30 ^ bit31, bit31);
1067 }
1068 break;
1069 }
1070 }
1071 env->eip += decode->len;
1072 return 0;
1073 }
1074
1075 bool exec_rol(CPUX86State *env, struct x86_decode *decode)
1076 {
1077 uint8_t count;
1078
1079 fetch_operands(env, decode, 2, true, true, false);
1080 count = decode->op[1].val;
1081
1082 switch (decode->operand_size) {
1083 case 1:
1084 {
1085 uint32_t bit0, bit7;
1086 uint8_t res;
1087
1088 if ((count & 0x07) == 0) {
1089 if (count & 0x18) {
1090 bit0 = ((uint8_t)decode->op[0].val & 1);
1091 bit7 = ((uint8_t)decode->op[0].val >> 7);
1092 SET_FLAGS_OxxxxC(env, bit0 ^ bit7, bit0);
1093 }
1094 } else {
1095 count &= 0x7; /* use only lowest 3 bits */
1096 res = ((uint8_t)decode->op[0].val << count) |
1097 ((uint8_t)decode->op[0].val >> (8 - count));
1098
1099 write_val_ext(env, &decode->op[0], res, 1);
1100 /* set eflags:
1101 * ROL count affects the following flags: C, O
1102 */
1103 bit0 = (res & 1);
1104 bit7 = (res >> 7);
1105 SET_FLAGS_OxxxxC(env, bit0 ^ bit7, bit0);
1106 }
1107 break;
1108 }
1109 case 2:
1110 {
1111 uint32_t bit0, bit15;
1112 uint16_t res;
1113
1114 if ((count & 0x0f) == 0) {
1115 if (count & 0x10) {
1116 bit0 = ((uint16_t)decode->op[0].val & 0x1);
1117 bit15 = ((uint16_t)decode->op[0].val >> 15);
1118 /* of = cf ^ result15 */
1119 SET_FLAGS_OxxxxC(env, bit0 ^ bit15, bit0);
1120 }
1121 } else {
1122 count &= 0x0f; /* only use bottom 4 bits */
1123 res = ((uint16_t)decode->op[0].val << count) |
1124 ((uint16_t)decode->op[0].val >> (16 - count));
1125
1126 write_val_ext(env, &decode->op[0], res, 2);
1127 bit0 = (res & 0x1);
1128 bit15 = (res >> 15);
1129 /* of = cf ^ result15 */
1130 SET_FLAGS_OxxxxC(env, bit0 ^ bit15, bit0);
1131 }
1132 break;
1133 }
1134 case 4:
1135 {
1136 uint32_t bit0, bit31;
1137 uint32_t res;
1138
1139 count &= 0x1f;
1140 if (count) {
1141 res = ((uint32_t)decode->op[0].val << count) |
1142 ((uint32_t)decode->op[0].val >> (32 - count));
1143
1144 write_val_ext(env, &decode->op[0], res, 4);
1145 bit0 = (res & 0x1);
1146 bit31 = (res >> 31);
1147 /* of = cf ^ result31 */
1148 SET_FLAGS_OxxxxC(env, bit0 ^ bit31, bit0);
1149 }
1150 break;
1151 }
1152 }
1153 env->eip += decode->len;
1154 return 0;
1155 }
1156
1157
1158 bool exec_rcl(CPUX86State *env, struct x86_decode *decode)
1159 {
1160 uint8_t count;
1161 int of = 0, cf = 0;
1162
1163 fetch_operands(env, decode, 2, true, true, false);
1164 count = decode->op[1].val & 0x1f;
1165
1166 switch (decode->operand_size) {
1167 case 1:
1168 {
1169 uint8_t op1_8 = decode->op[0].val;
1170 uint8_t res;
1171 count %= 9;
1172 if (!count) {
1173 break;
1174 }
1175
1176 if (1 == count) {
1177 res = (op1_8 << 1) | get_CF(env);
1178 } else {
1179 res = (op1_8 << count) | (get_CF(env) << (count - 1)) |
1180 (op1_8 >> (9 - count));
1181 }
1182
1183 write_val_ext(env, &decode->op[0], res, 1);
1184
1185 cf = (op1_8 >> (8 - count)) & 0x01;
1186 of = cf ^ (res >> 7); /* of = cf ^ result7 */
1187 SET_FLAGS_OxxxxC(env, of, cf);
1188 break;
1189 }
1190 case 2:
1191 {
1192 uint16_t res;
1193 uint16_t op1_16 = decode->op[0].val;
1194
1195 count %= 17;
1196 if (!count) {
1197 break;
1198 }
1199
1200 if (1 == count) {
1201 res = (op1_16 << 1) | get_CF(env);
1202 } else if (count == 16) {
1203 res = (get_CF(env) << 15) | (op1_16 >> 1);
1204 } else { /* 2..15 */
1205 res = (op1_16 << count) | (get_CF(env) << (count - 1)) |
1206 (op1_16 >> (17 - count));
1207 }
1208
1209 write_val_ext(env, &decode->op[0], res, 2);
1210
1211 cf = (op1_16 >> (16 - count)) & 0x1;
1212 of = cf ^ (res >> 15); /* of = cf ^ result15 */
1213 SET_FLAGS_OxxxxC(env, of, cf);
1214 break;
1215 }
1216 case 4:
1217 {
1218 uint32_t res;
1219 uint32_t op1_32 = decode->op[0].val;
1220
1221 if (!count) {
1222 break;
1223 }
1224
1225 if (1 == count) {
1226 res = (op1_32 << 1) | get_CF(env);
1227 } else {
1228 res = (op1_32 << count) | (get_CF(env) << (count - 1)) |
1229 (op1_32 >> (33 - count));
1230 }
1231
1232 write_val_ext(env, &decode->op[0], res, 4);
1233
1234 cf = (op1_32 >> (32 - count)) & 0x1;
1235 of = cf ^ (res >> 31); /* of = cf ^ result31 */
1236 SET_FLAGS_OxxxxC(env, of, cf);
1237 break;
1238 }
1239 }
1240 env->eip += decode->len;
1241 return 0;
1242 }
1243
1244 bool exec_rcr(CPUX86State *env, struct x86_decode *decode)
1245 {
1246 uint8_t count;
1247 int of = 0, cf = 0;
1248
1249 fetch_operands(env, decode, 2, true, true, false);
1250 count = decode->op[1].val & 0x1f;
1251
1252 switch (decode->operand_size) {
1253 case 1:
1254 {
1255 uint8_t op1_8 = decode->op[0].val;
1256 uint8_t res;
1257
1258 count %= 9;
1259 if (!count) {
1260 break;
1261 }
1262 res = (op1_8 >> count) | (get_CF(env) << (8 - count)) |
1263 (op1_8 << (9 - count));
1264
1265 write_val_ext(env, &decode->op[0], res, 1);
1266
1267 cf = (op1_8 >> (count - 1)) & 0x1;
1268 of = (((res << 1) ^ res) >> 7) & 0x1; /* of = result6 ^ result7 */
1269 SET_FLAGS_OxxxxC(env, of, cf);
1270 break;
1271 }
1272 case 2:
1273 {
1274 uint16_t op1_16 = decode->op[0].val;
1275 uint16_t res;
1276
1277 count %= 17;
1278 if (!count) {
1279 break;
1280 }
1281 res = (op1_16 >> count) | (get_CF(env) << (16 - count)) |
1282 (op1_16 << (17 - count));
1283
1284 write_val_ext(env, &decode->op[0], res, 2);
1285
1286 cf = (op1_16 >> (count - 1)) & 0x1;
1287 of = ((uint16_t)((res << 1) ^ res) >> 15) & 0x1; /* of = result15 ^
1288 result14 */
1289 SET_FLAGS_OxxxxC(env, of, cf);
1290 break;
1291 }
1292 case 4:
1293 {
1294 uint32_t res;
1295 uint32_t op1_32 = decode->op[0].val;
1296
1297 if (!count) {
1298 break;
1299 }
1300
1301 if (1 == count) {
1302 res = (op1_32 >> 1) | (get_CF(env) << 31);
1303 } else {
1304 res = (op1_32 >> count) | (get_CF(env) << (32 - count)) |
1305 (op1_32 << (33 - count));
1306 }
1307
1308 write_val_ext(env, &decode->op[0], res, 4);
1309
1310 cf = (op1_32 >> (count - 1)) & 0x1;
1311 of = ((res << 1) ^ res) >> 31; /* of = result30 ^ result31 */
1312 SET_FLAGS_OxxxxC(env, of, cf);
1313 break;
1314 }
1315 }
1316 env->eip += decode->len;
1317 return 0;
1318 }
1319
1320 static bool exec_xchg(CPUX86State *env, struct x86_decode *decode)
1321 {
1322 fetch_operands(env, decode, 2, true, true, false);
1323
1324 write_val_ext(env, &decode->op[0], decode->op[1].val,
1325 decode->operand_size);
1326 write_val_ext(env, &decode->op[1], decode->op[0].val,
1327 decode->operand_size);
1328
1329 env->eip += decode->len;
1330 return 0;
1331 }
1332
1333 static bool exec_xadd(CPUX86State *env, struct x86_decode *decode)
1334 {
1335 EXEC_2OP_FLAGS_CMD(env, decode, +, SET_FLAGS_OSZAPC_ADD, true);
1336 write_val_ext(env, &decode->op[1], decode->op[0].val,
1337 decode->operand_size);
1338
1339 env->eip += decode->len;
1340 return 0;
1341 }
1342
1343 static struct cmd_handler {
1344 enum x86_decode_cmd cmd;
1345 bool (*handler)(CPUX86State *env, struct x86_decode *ins);
1346 } handlers[] = {
1347 {X86_DECODE_CMD_INVL, NULL,},
1348 {X86_DECODE_CMD_MOV, exec_mov},
1349 {X86_DECODE_CMD_ADD, exec_add},
1350 {X86_DECODE_CMD_OR, exec_or},
1351 {X86_DECODE_CMD_ADC, exec_adc},
1352 {X86_DECODE_CMD_SBB, exec_sbb},
1353 {X86_DECODE_CMD_AND, exec_and},
1354 {X86_DECODE_CMD_SUB, exec_sub},
1355 {X86_DECODE_CMD_NEG, exec_neg},
1356 {X86_DECODE_CMD_XOR, exec_xor},
1357 {X86_DECODE_CMD_CMP, exec_cmp},
1358 {X86_DECODE_CMD_INC, exec_inc},
1359 {X86_DECODE_CMD_DEC, exec_dec},
1360 {X86_DECODE_CMD_TST, exec_tst},
1361 {X86_DECODE_CMD_NOT, exec_not},
1362 {X86_DECODE_CMD_MOVZX, exec_movzx},
1363 {X86_DECODE_CMD_OUT, exec_out},
1364 {X86_DECODE_CMD_IN, exec_in},
1365 {X86_DECODE_CMD_INS, exec_ins},
1366 {X86_DECODE_CMD_OUTS, exec_outs},
1367 {X86_DECODE_CMD_RDMSR, exec_rdmsr},
1368 {X86_DECODE_CMD_WRMSR, exec_wrmsr},
1369 {X86_DECODE_CMD_BT, exec_bt},
1370 {X86_DECODE_CMD_BTR, exec_btr},
1371 {X86_DECODE_CMD_BTC, exec_btc},
1372 {X86_DECODE_CMD_BTS, exec_bts},
1373 {X86_DECODE_CMD_SHL, exec_shl},
1374 {X86_DECODE_CMD_ROL, exec_rol},
1375 {X86_DECODE_CMD_ROR, exec_ror},
1376 {X86_DECODE_CMD_RCR, exec_rcr},
1377 {X86_DECODE_CMD_RCL, exec_rcl},
1378 /*{X86_DECODE_CMD_CPUID, exec_cpuid},*/
1379 {X86_DECODE_CMD_MOVS, exec_movs},
1380 {X86_DECODE_CMD_CMPS, exec_cmps},
1381 {X86_DECODE_CMD_STOS, exec_stos},
1382 {X86_DECODE_CMD_SCAS, exec_scas},
1383 {X86_DECODE_CMD_LODS, exec_lods},
1384 {X86_DECODE_CMD_MOVSX, exec_movsx},
1385 {X86_DECODE_CMD_XCHG, exec_xchg},
1386 {X86_DECODE_CMD_XADD, exec_xadd},
1387 };
1388
1389 static struct cmd_handler _cmd_handler[X86_DECODE_CMD_LAST];
1390
1391 const struct x86_emul_ops *emul_ops;
1392
1393 static void init_cmd_handler(void)
1394 {
1395 int i;
1396 for (i = 0; i < ARRAY_SIZE(handlers); i++) {
1397 _cmd_handler[handlers[i].cmd] = handlers[i];
1398 }
1399 }
1400
1401 bool exec_instruction(CPUX86State *env, struct x86_decode *ins)
1402 {
1403 if (!_cmd_handler[ins->cmd].handler) {
1404 printf("Unimplemented handler (" TARGET_FMT_lx ") for %s - %d (%x %x)\n",
1405 env->eip, decode_cmd_to_string(ins->cmd),
1406 ins->cmd, ins->opcode[0],
1407 ins->opcode_len > 1 ? ins->opcode[1] : 0);
1408 env->eip += ins->len;
1409 return true;
1410 }
1411
1412 _cmd_handler[ins->cmd].handler(env, ins);
1413 return true;
1414 }
1415
1416 void init_emu(const struct x86_emul_ops *o)
1417 {
1418 emul_ops = o;
1419 init_cmd_handler();
1420 }