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