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