Commit 4f31916ffbb196ac1a68ecd53703167a70880022
1 parent
943144d9
added raw/user/kernel memory accesses for shifts/adc/sbb/cmpxchg/push/pop (faste…
…r emulation) - make 'call Ev' exception safe - in/out dx fix - PE flag is static git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@511 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
295 additions
and
319 deletions
target-i386/translate.c
| @@ -380,34 +380,30 @@ static GenOpFunc *gen_op_arith_T0_T1_cc[8] = { | @@ -380,34 +380,30 @@ static GenOpFunc *gen_op_arith_T0_T1_cc[8] = { | ||
| 380 | NULL, | 380 | NULL, |
| 381 | }; | 381 | }; |
| 382 | 382 | ||
| 383 | -static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = { | ||
| 384 | - [OT_BYTE] = { | ||
| 385 | - gen_op_adcb_T0_T1_cc, | ||
| 386 | - gen_op_sbbb_T0_T1_cc, | ||
| 387 | - }, | ||
| 388 | - [OT_WORD] = { | ||
| 389 | - gen_op_adcw_T0_T1_cc, | ||
| 390 | - gen_op_sbbw_T0_T1_cc, | ||
| 391 | - }, | ||
| 392 | - [OT_LONG] = { | ||
| 393 | - gen_op_adcl_T0_T1_cc, | ||
| 394 | - gen_op_sbbl_T0_T1_cc, | 383 | +#define DEF_ARITHC(SUFFIX)\ |
| 384 | + {\ | ||
| 385 | + gen_op_adcb ## SUFFIX ## _T0_T1_cc,\ | ||
| 386 | + gen_op_sbbb ## SUFFIX ## _T0_T1_cc,\ | ||
| 387 | + },\ | ||
| 388 | + {\ | ||
| 389 | + gen_op_adcw ## SUFFIX ## _T0_T1_cc,\ | ||
| 390 | + gen_op_sbbw ## SUFFIX ## _T0_T1_cc,\ | ||
| 391 | + },\ | ||
| 392 | + {\ | ||
| 393 | + gen_op_adcl ## SUFFIX ## _T0_T1_cc,\ | ||
| 394 | + gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\ | ||
| 395 | }, | 395 | }, |
| 396 | + | ||
| 397 | +static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = { | ||
| 398 | + DEF_ARITHC() | ||
| 396 | }; | 399 | }; |
| 397 | 400 | ||
| 398 | -static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3][2] = { | ||
| 399 | - [OT_BYTE] = { | ||
| 400 | - gen_op_adcb_mem_T0_T1_cc, | ||
| 401 | - gen_op_sbbb_mem_T0_T1_cc, | ||
| 402 | - }, | ||
| 403 | - [OT_WORD] = { | ||
| 404 | - gen_op_adcw_mem_T0_T1_cc, | ||
| 405 | - gen_op_sbbw_mem_T0_T1_cc, | ||
| 406 | - }, | ||
| 407 | - [OT_LONG] = { | ||
| 408 | - gen_op_adcl_mem_T0_T1_cc, | ||
| 409 | - gen_op_sbbl_mem_T0_T1_cc, | ||
| 410 | - }, | 401 | +static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[9][2] = { |
| 402 | + DEF_ARITHC(_raw) | ||
| 403 | +#ifndef CONFIG_USER_ONLY | ||
| 404 | + DEF_ARITHC(_kernel) | ||
| 405 | + DEF_ARITHC(_user) | ||
| 406 | +#endif | ||
| 411 | }; | 407 | }; |
| 412 | 408 | ||
| 413 | static const int cc_op_arithb[8] = { | 409 | static const int cc_op_arithb[8] = { |
| @@ -421,126 +417,105 @@ static const int cc_op_arithb[8] = { | @@ -421,126 +417,105 @@ static const int cc_op_arithb[8] = { | ||
| 421 | CC_OP_SUBB, | 417 | CC_OP_SUBB, |
| 422 | }; | 418 | }; |
| 423 | 419 | ||
| 420 | +#define DEF_CMPXCHG(SUFFIX)\ | ||
| 421 | + gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\ | ||
| 422 | + gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\ | ||
| 423 | + gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc, | ||
| 424 | + | ||
| 425 | + | ||
| 424 | static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = { | 426 | static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = { |
| 425 | - gen_op_cmpxchgb_T0_T1_EAX_cc, | ||
| 426 | - gen_op_cmpxchgw_T0_T1_EAX_cc, | ||
| 427 | - gen_op_cmpxchgl_T0_T1_EAX_cc, | 427 | + DEF_CMPXCHG() |
| 428 | }; | 428 | }; |
| 429 | 429 | ||
| 430 | -static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3] = { | ||
| 431 | - gen_op_cmpxchgb_mem_T0_T1_EAX_cc, | ||
| 432 | - gen_op_cmpxchgw_mem_T0_T1_EAX_cc, | ||
| 433 | - gen_op_cmpxchgl_mem_T0_T1_EAX_cc, | 430 | +static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[9] = { |
| 431 | + DEF_CMPXCHG(_raw) | ||
| 432 | +#ifndef CONFIG_USER_ONLY | ||
| 433 | + DEF_CMPXCHG(_kernel) | ||
| 434 | + DEF_CMPXCHG(_user) | ||
| 435 | +#endif | ||
| 434 | }; | 436 | }; |
| 435 | 437 | ||
| 436 | -static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = { | ||
| 437 | - [OT_BYTE] = { | ||
| 438 | - gen_op_rolb_T0_T1_cc, | ||
| 439 | - gen_op_rorb_T0_T1_cc, | ||
| 440 | - gen_op_rclb_T0_T1_cc, | ||
| 441 | - gen_op_rcrb_T0_T1_cc, | ||
| 442 | - gen_op_shlb_T0_T1_cc, | ||
| 443 | - gen_op_shrb_T0_T1_cc, | ||
| 444 | - gen_op_shlb_T0_T1_cc, | ||
| 445 | - gen_op_sarb_T0_T1_cc, | ||
| 446 | - }, | ||
| 447 | - [OT_WORD] = { | ||
| 448 | - gen_op_rolw_T0_T1_cc, | ||
| 449 | - gen_op_rorw_T0_T1_cc, | ||
| 450 | - gen_op_rclw_T0_T1_cc, | ||
| 451 | - gen_op_rcrw_T0_T1_cc, | ||
| 452 | - gen_op_shlw_T0_T1_cc, | ||
| 453 | - gen_op_shrw_T0_T1_cc, | ||
| 454 | - gen_op_shlw_T0_T1_cc, | ||
| 455 | - gen_op_sarw_T0_T1_cc, | ||
| 456 | - }, | ||
| 457 | - [OT_LONG] = { | ||
| 458 | - gen_op_roll_T0_T1_cc, | ||
| 459 | - gen_op_rorl_T0_T1_cc, | ||
| 460 | - gen_op_rcll_T0_T1_cc, | ||
| 461 | - gen_op_rcrl_T0_T1_cc, | ||
| 462 | - gen_op_shll_T0_T1_cc, | ||
| 463 | - gen_op_shrl_T0_T1_cc, | ||
| 464 | - gen_op_shll_T0_T1_cc, | ||
| 465 | - gen_op_sarl_T0_T1_cc, | 438 | +#define DEF_SHIFT(SUFFIX)\ |
| 439 | + {\ | ||
| 440 | + gen_op_rolb ## SUFFIX ## _T0_T1_cc,\ | ||
| 441 | + gen_op_rorb ## SUFFIX ## _T0_T1_cc,\ | ||
| 442 | + gen_op_rclb ## SUFFIX ## _T0_T1_cc,\ | ||
| 443 | + gen_op_rcrb ## SUFFIX ## _T0_T1_cc,\ | ||
| 444 | + gen_op_shlb ## SUFFIX ## _T0_T1_cc,\ | ||
| 445 | + gen_op_shrb ## SUFFIX ## _T0_T1_cc,\ | ||
| 446 | + gen_op_shlb ## SUFFIX ## _T0_T1_cc,\ | ||
| 447 | + gen_op_sarb ## SUFFIX ## _T0_T1_cc,\ | ||
| 448 | + },\ | ||
| 449 | + {\ | ||
| 450 | + gen_op_rolw ## SUFFIX ## _T0_T1_cc,\ | ||
| 451 | + gen_op_rorw ## SUFFIX ## _T0_T1_cc,\ | ||
| 452 | + gen_op_rclw ## SUFFIX ## _T0_T1_cc,\ | ||
| 453 | + gen_op_rcrw ## SUFFIX ## _T0_T1_cc,\ | ||
| 454 | + gen_op_shlw ## SUFFIX ## _T0_T1_cc,\ | ||
| 455 | + gen_op_shrw ## SUFFIX ## _T0_T1_cc,\ | ||
| 456 | + gen_op_shlw ## SUFFIX ## _T0_T1_cc,\ | ||
| 457 | + gen_op_sarw ## SUFFIX ## _T0_T1_cc,\ | ||
| 458 | + },\ | ||
| 459 | + {\ | ||
| 460 | + gen_op_roll ## SUFFIX ## _T0_T1_cc,\ | ||
| 461 | + gen_op_rorl ## SUFFIX ## _T0_T1_cc,\ | ||
| 462 | + gen_op_rcll ## SUFFIX ## _T0_T1_cc,\ | ||
| 463 | + gen_op_rcrl ## SUFFIX ## _T0_T1_cc,\ | ||
| 464 | + gen_op_shll ## SUFFIX ## _T0_T1_cc,\ | ||
| 465 | + gen_op_shrl ## SUFFIX ## _T0_T1_cc,\ | ||
| 466 | + gen_op_shll ## SUFFIX ## _T0_T1_cc,\ | ||
| 467 | + gen_op_sarl ## SUFFIX ## _T0_T1_cc,\ | ||
| 466 | }, | 468 | }, |
| 469 | + | ||
| 470 | +static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = { | ||
| 471 | + DEF_SHIFT() | ||
| 467 | }; | 472 | }; |
| 468 | 473 | ||
| 469 | -static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3][8] = { | ||
| 470 | - [OT_BYTE] = { | ||
| 471 | - gen_op_rolb_mem_T0_T1_cc, | ||
| 472 | - gen_op_rorb_mem_T0_T1_cc, | ||
| 473 | - gen_op_rclb_mem_T0_T1_cc, | ||
| 474 | - gen_op_rcrb_mem_T0_T1_cc, | ||
| 475 | - gen_op_shlb_mem_T0_T1_cc, | ||
| 476 | - gen_op_shrb_mem_T0_T1_cc, | ||
| 477 | - gen_op_shlb_mem_T0_T1_cc, | ||
| 478 | - gen_op_sarb_mem_T0_T1_cc, | ||
| 479 | - }, | ||
| 480 | - [OT_WORD] = { | ||
| 481 | - gen_op_rolw_mem_T0_T1_cc, | ||
| 482 | - gen_op_rorw_mem_T0_T1_cc, | ||
| 483 | - gen_op_rclw_mem_T0_T1_cc, | ||
| 484 | - gen_op_rcrw_mem_T0_T1_cc, | ||
| 485 | - gen_op_shlw_mem_T0_T1_cc, | ||
| 486 | - gen_op_shrw_mem_T0_T1_cc, | ||
| 487 | - gen_op_shlw_mem_T0_T1_cc, | ||
| 488 | - gen_op_sarw_mem_T0_T1_cc, | ||
| 489 | - }, | ||
| 490 | - [OT_LONG] = { | ||
| 491 | - gen_op_roll_mem_T0_T1_cc, | ||
| 492 | - gen_op_rorl_mem_T0_T1_cc, | ||
| 493 | - gen_op_rcll_mem_T0_T1_cc, | ||
| 494 | - gen_op_rcrl_mem_T0_T1_cc, | ||
| 495 | - gen_op_shll_mem_T0_T1_cc, | ||
| 496 | - gen_op_shrl_mem_T0_T1_cc, | ||
| 497 | - gen_op_shll_mem_T0_T1_cc, | ||
| 498 | - gen_op_sarl_mem_T0_T1_cc, | ||
| 499 | - }, | 474 | +static GenOpFunc *gen_op_shift_mem_T0_T1_cc[9][8] = { |
| 475 | + DEF_SHIFT(_raw) | ||
| 476 | +#ifndef CONFIG_USER_ONLY | ||
| 477 | + DEF_SHIFT(_kernel) | ||
| 478 | + DEF_SHIFT(_user) | ||
| 479 | +#endif | ||
| 500 | }; | 480 | }; |
| 501 | 481 | ||
| 502 | -static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = { | ||
| 503 | - [0] = { | ||
| 504 | - gen_op_shldw_T0_T1_im_cc, | ||
| 505 | - gen_op_shrdw_T0_T1_im_cc, | ||
| 506 | - }, | ||
| 507 | - [1] = { | ||
| 508 | - gen_op_shldl_T0_T1_im_cc, | ||
| 509 | - gen_op_shrdl_T0_T1_im_cc, | 482 | +#define DEF_SHIFTD(SUFFIX, op)\ |
| 483 | + {\ | ||
| 484 | + NULL,\ | ||
| 485 | + NULL,\ | ||
| 486 | + },\ | ||
| 487 | + {\ | ||
| 488 | + gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | ||
| 489 | + gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | ||
| 490 | + },\ | ||
| 491 | + {\ | ||
| 492 | + gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | ||
| 493 | + gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\ | ||
| 510 | }, | 494 | }, |
| 495 | + | ||
| 496 | + | ||
| 497 | +static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[3][2] = { | ||
| 498 | + DEF_SHIFTD(, im) | ||
| 511 | }; | 499 | }; |
| 512 | 500 | ||
| 513 | -static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = { | ||
| 514 | - [0] = { | ||
| 515 | - gen_op_shldw_T0_T1_ECX_cc, | ||
| 516 | - gen_op_shrdw_T0_T1_ECX_cc, | ||
| 517 | - }, | ||
| 518 | - [1] = { | ||
| 519 | - gen_op_shldl_T0_T1_ECX_cc, | ||
| 520 | - gen_op_shrdl_T0_T1_ECX_cc, | ||
| 521 | - }, | 501 | +static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[3][2] = { |
| 502 | + DEF_SHIFTD(, ECX) | ||
| 522 | }; | 503 | }; |
| 523 | 504 | ||
| 524 | -static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[2][2] = { | ||
| 525 | - [0] = { | ||
| 526 | - gen_op_shldw_mem_T0_T1_im_cc, | ||
| 527 | - gen_op_shrdw_mem_T0_T1_im_cc, | ||
| 528 | - }, | ||
| 529 | - [1] = { | ||
| 530 | - gen_op_shldl_mem_T0_T1_im_cc, | ||
| 531 | - gen_op_shrdl_mem_T0_T1_im_cc, | ||
| 532 | - }, | 505 | +static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[9][2] = { |
| 506 | + DEF_SHIFTD(_raw, im) | ||
| 507 | +#ifndef CONFIG_USER_ONLY | ||
| 508 | + DEF_SHIFTD(_kernel, im) | ||
| 509 | + DEF_SHIFTD(_user, im) | ||
| 510 | +#endif | ||
| 533 | }; | 511 | }; |
| 534 | 512 | ||
| 535 | -static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[2][2] = { | ||
| 536 | - [0] = { | ||
| 537 | - gen_op_shldw_mem_T0_T1_ECX_cc, | ||
| 538 | - gen_op_shrdw_mem_T0_T1_ECX_cc, | ||
| 539 | - }, | ||
| 540 | - [1] = { | ||
| 541 | - gen_op_shldl_mem_T0_T1_ECX_cc, | ||
| 542 | - gen_op_shrdl_mem_T0_T1_ECX_cc, | ||
| 543 | - }, | 513 | +static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[9][2] = { |
| 514 | + DEF_SHIFTD(_raw, ECX) | ||
| 515 | +#ifndef CONFIG_USER_ONLY | ||
| 516 | + DEF_SHIFTD(_kernel, ECX) | ||
| 517 | + DEF_SHIFTD(_user, ECX) | ||
| 518 | +#endif | ||
| 544 | }; | 519 | }; |
| 545 | 520 | ||
| 546 | static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = { | 521 | static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = { |
| @@ -649,6 +624,22 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { | @@ -649,6 +624,22 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { | ||
| 649 | #endif | 624 | #endif |
| 650 | }; | 625 | }; |
| 651 | 626 | ||
| 627 | +static GenOpFunc *gen_op_st_T1_A0[3 * 3] = { | ||
| 628 | + NULL, | ||
| 629 | + gen_op_stw_raw_T1_A0, | ||
| 630 | + gen_op_stl_raw_T1_A0, | ||
| 631 | + | ||
| 632 | +#ifndef CONFIG_USER_ONLY | ||
| 633 | + NULL, | ||
| 634 | + gen_op_stw_kernel_T1_A0, | ||
| 635 | + gen_op_stl_kernel_T1_A0, | ||
| 636 | + | ||
| 637 | + NULL, | ||
| 638 | + gen_op_stw_user_T1_A0, | ||
| 639 | + gen_op_stl_user_T1_A0, | ||
| 640 | +#endif | ||
| 641 | +}; | ||
| 642 | + | ||
| 652 | static inline void gen_string_movl_A0_ESI(DisasContext *s) | 643 | static inline void gen_string_movl_A0_ESI(DisasContext *s) |
| 653 | { | 644 | { |
| 654 | int override; | 645 | int override; |
| @@ -1093,7 +1084,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) | @@ -1093,7 +1084,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) | ||
| 1093 | gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); | 1084 | gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); |
| 1094 | gen_op_mov_reg_T0[ot][d](); | 1085 | gen_op_mov_reg_T0[ot][d](); |
| 1095 | } else { | 1086 | } else { |
| 1096 | - gen_op_arithc_mem_T0_T1_cc[ot][op - OP_ADCL](); | 1087 | + gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL](); |
| 1097 | } | 1088 | } |
| 1098 | s1->cc_op = CC_OP_DYNAMIC; | 1089 | s1->cc_op = CC_OP_DYNAMIC; |
| 1099 | goto the_end; | 1090 | goto the_end; |
| @@ -1172,7 +1163,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) | @@ -1172,7 +1163,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) | ||
| 1172 | if (d != OR_TMP0) | 1163 | if (d != OR_TMP0) |
| 1173 | gen_op_shift_T0_T1_cc[ot][op](); | 1164 | gen_op_shift_T0_T1_cc[ot][op](); |
| 1174 | else | 1165 | else |
| 1175 | - gen_op_shift_mem_T0_T1_cc[ot][op](); | 1166 | + gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op](); |
| 1176 | if (d != OR_TMP0) | 1167 | if (d != OR_TMP0) |
| 1177 | gen_op_mov_reg_T0[ot][d](); | 1168 | gen_op_mov_reg_T0[ot][d](); |
| 1178 | s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ | 1169 | s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ |
| @@ -1555,69 +1546,87 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip) | @@ -1555,69 +1546,87 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip) | ||
| 1555 | s->is_jmp = 3; | 1546 | s->is_jmp = 3; |
| 1556 | } | 1547 | } |
| 1557 | 1548 | ||
| 1549 | +static inline void gen_stack_update(DisasContext *s, int addend) | ||
| 1550 | +{ | ||
| 1551 | + if (s->ss32) { | ||
| 1552 | + if (addend == 2) | ||
| 1553 | + gen_op_addl_ESP_2(); | ||
| 1554 | + else if (addend == 4) | ||
| 1555 | + gen_op_addl_ESP_4(); | ||
| 1556 | + else | ||
| 1557 | + gen_op_addl_ESP_im(addend); | ||
| 1558 | + } else { | ||
| 1559 | + if (addend == 2) | ||
| 1560 | + gen_op_addw_ESP_2(); | ||
| 1561 | + else if (addend == 4) | ||
| 1562 | + gen_op_addw_ESP_4(); | ||
| 1563 | + else | ||
| 1564 | + gen_op_addw_ESP_im(addend); | ||
| 1565 | + } | ||
| 1566 | +} | ||
| 1567 | + | ||
| 1558 | /* generate a push. It depends on ss32, addseg and dflag */ | 1568 | /* generate a push. It depends on ss32, addseg and dflag */ |
| 1559 | static void gen_push_T0(DisasContext *s) | 1569 | static void gen_push_T0(DisasContext *s) |
| 1560 | { | 1570 | { |
| 1571 | + gen_op_movl_A0_reg[R_ESP](); | ||
| 1572 | + if (!s->dflag) | ||
| 1573 | + gen_op_subl_A0_2(); | ||
| 1574 | + else | ||
| 1575 | + gen_op_subl_A0_4(); | ||
| 1561 | if (s->ss32) { | 1576 | if (s->ss32) { |
| 1562 | - if (!s->addseg) { | ||
| 1563 | - if (s->dflag) | ||
| 1564 | - gen_op_pushl_T0(); | ||
| 1565 | - else | ||
| 1566 | - gen_op_pushw_T0(); | ||
| 1567 | - } else { | ||
| 1568 | - if (s->dflag) | ||
| 1569 | - gen_op_pushl_ss32_T0(); | ||
| 1570 | - else | ||
| 1571 | - gen_op_pushw_ss32_T0(); | 1577 | + if (s->addseg) { |
| 1578 | + gen_op_movl_T1_A0(); | ||
| 1579 | + gen_op_addl_A0_SS(); | ||
| 1572 | } | 1580 | } |
| 1573 | } else { | 1581 | } else { |
| 1574 | - if (s->dflag) | ||
| 1575 | - gen_op_pushl_ss16_T0(); | ||
| 1576 | - else | ||
| 1577 | - gen_op_pushw_ss16_T0(); | 1582 | + gen_op_andl_A0_ffff(); |
| 1583 | + gen_op_movl_T1_A0(); | ||
| 1584 | + gen_op_addl_A0_SS(); | ||
| 1578 | } | 1585 | } |
| 1586 | + gen_op_st_T0_A0[s->dflag + 1 + s->mem_index](); | ||
| 1587 | + if (s->ss32 && !s->addseg) | ||
| 1588 | + gen_op_movl_ESP_A0(); | ||
| 1589 | + else | ||
| 1590 | + gen_op_mov_reg_T1[s->ss32 + 1][R_ESP](); | ||
| 1579 | } | 1591 | } |
| 1580 | 1592 | ||
| 1581 | -/* two step pop is necessary for precise exceptions */ | ||
| 1582 | -static void gen_pop_T0(DisasContext *s) | 1593 | +/* generate a push. It depends on ss32, addseg and dflag */ |
| 1594 | +/* slower version for T1, only used for call Ev */ | ||
| 1595 | +static void gen_push_T1(DisasContext *s) | ||
| 1583 | { | 1596 | { |
| 1597 | + gen_op_movl_A0_reg[R_ESP](); | ||
| 1598 | + if (!s->dflag) | ||
| 1599 | + gen_op_subl_A0_2(); | ||
| 1600 | + else | ||
| 1601 | + gen_op_subl_A0_4(); | ||
| 1584 | if (s->ss32) { | 1602 | if (s->ss32) { |
| 1585 | - if (!s->addseg) { | ||
| 1586 | - if (s->dflag) | ||
| 1587 | - gen_op_popl_T0(); | ||
| 1588 | - else | ||
| 1589 | - gen_op_popw_T0(); | ||
| 1590 | - } else { | ||
| 1591 | - if (s->dflag) | ||
| 1592 | - gen_op_popl_ss32_T0(); | ||
| 1593 | - else | ||
| 1594 | - gen_op_popw_ss32_T0(); | 1603 | + if (s->addseg) { |
| 1604 | + gen_op_addl_A0_SS(); | ||
| 1595 | } | 1605 | } |
| 1596 | } else { | 1606 | } else { |
| 1597 | - if (s->dflag) | ||
| 1598 | - gen_op_popl_ss16_T0(); | ||
| 1599 | - else | ||
| 1600 | - gen_op_popw_ss16_T0(); | 1607 | + gen_op_andl_A0_ffff(); |
| 1608 | + gen_op_addl_A0_SS(); | ||
| 1601 | } | 1609 | } |
| 1610 | + gen_op_st_T1_A0[s->dflag + 1 + s->mem_index](); | ||
| 1611 | + | ||
| 1612 | + if (s->ss32 && !s->addseg) | ||
| 1613 | + gen_op_movl_ESP_A0(); | ||
| 1614 | + else | ||
| 1615 | + gen_stack_update(s, (-2) << s->dflag); | ||
| 1602 | } | 1616 | } |
| 1603 | 1617 | ||
| 1604 | -static inline void gen_stack_update(DisasContext *s, int addend) | 1618 | +/* two step pop is necessary for precise exceptions */ |
| 1619 | +static void gen_pop_T0(DisasContext *s) | ||
| 1605 | { | 1620 | { |
| 1621 | + gen_op_movl_A0_reg[R_ESP](); | ||
| 1606 | if (s->ss32) { | 1622 | if (s->ss32) { |
| 1607 | - if (addend == 2) | ||
| 1608 | - gen_op_addl_ESP_2(); | ||
| 1609 | - else if (addend == 4) | ||
| 1610 | - gen_op_addl_ESP_4(); | ||
| 1611 | - else | ||
| 1612 | - gen_op_addl_ESP_im(addend); | 1623 | + if (s->addseg) |
| 1624 | + gen_op_addl_A0_SS(); | ||
| 1613 | } else { | 1625 | } else { |
| 1614 | - if (addend == 2) | ||
| 1615 | - gen_op_addw_ESP_2(); | ||
| 1616 | - else if (addend == 4) | ||
| 1617 | - gen_op_addw_ESP_4(); | ||
| 1618 | - else | ||
| 1619 | - gen_op_addw_ESP_im(addend); | 1626 | + gen_op_andl_A0_ffff(); |
| 1627 | + gen_op_addl_A0_SS(); | ||
| 1620 | } | 1628 | } |
| 1629 | + gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index](); | ||
| 1621 | } | 1630 | } |
| 1622 | 1631 | ||
| 1623 | static void gen_pop_update(DisasContext *s) | 1632 | static void gen_pop_update(DisasContext *s) |
| @@ -1704,9 +1713,7 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) | @@ -1704,9 +1713,7 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) | ||
| 1704 | gen_op_st_T0_A0[ot + s->mem_index](); | 1713 | gen_op_st_T0_A0[ot + s->mem_index](); |
| 1705 | } | 1714 | } |
| 1706 | gen_op_addl_A0_im(-opsize); | 1715 | gen_op_addl_A0_im(-opsize); |
| 1707 | - /* XXX: add st_T1_A0 ? */ | ||
| 1708 | - gen_op_movl_T0_T1(); | ||
| 1709 | - gen_op_st_T0_A0[ot + s->mem_index](); | 1716 | + gen_op_st_T1_A0[ot + s->mem_index](); |
| 1710 | } | 1717 | } |
| 1711 | gen_op_mov_reg_T1[ot][R_EBP](); | 1718 | gen_op_mov_reg_T1[ot][R_EBP](); |
| 1712 | addend = -esp_addend; | 1719 | addend = -esp_addend; |
| @@ -2122,13 +2129,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2122,13 +2129,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2122 | gen_inc(s, ot, opreg, -1); | 2129 | gen_inc(s, ot, opreg, -1); |
| 2123 | break; | 2130 | break; |
| 2124 | case 2: /* call Ev */ | 2131 | case 2: /* call Ev */ |
| 2125 | - /* XXX: optimize if memory (no and is necessary) */ | 2132 | + /* XXX: optimize if memory (no 'and' is necessary) */ |
| 2126 | if (s->dflag == 0) | 2133 | if (s->dflag == 0) |
| 2127 | gen_op_andl_T0_ffff(); | 2134 | gen_op_andl_T0_ffff(); |
| 2128 | - gen_op_jmp_T0(); | ||
| 2129 | next_eip = s->pc - s->cs_base; | 2135 | next_eip = s->pc - s->cs_base; |
| 2130 | - gen_op_movl_T0_im(next_eip); | ||
| 2131 | - gen_push_T0(s); | 2136 | + gen_op_movl_T1_im(next_eip); |
| 2137 | + gen_push_T1(s); | ||
| 2138 | + gen_op_jmp_T0(); | ||
| 2132 | gen_eob(s); | 2139 | gen_eob(s); |
| 2133 | break; | 2140 | break; |
| 2134 | case 3: /* lcall Ev */ | 2141 | case 3: /* lcall Ev */ |
| @@ -2291,7 +2298,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2291,7 +2298,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2291 | } else { | 2298 | } else { |
| 2292 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | 2299 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
| 2293 | gen_op_ld_T0_A0[ot + s->mem_index](); | 2300 | gen_op_ld_T0_A0[ot + s->mem_index](); |
| 2294 | - gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot](); | 2301 | + gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index](); |
| 2295 | } | 2302 | } |
| 2296 | s->cc_op = CC_OP_SUBB + ot; | 2303 | s->cc_op = CC_OP_SUBB + ot; |
| 2297 | break; | 2304 | break; |
| @@ -2776,9 +2783,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2776,9 +2783,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2776 | val &= 0x1f; | 2783 | val &= 0x1f; |
| 2777 | if (val) { | 2784 | if (val) { |
| 2778 | if (mod == 3) | 2785 | if (mod == 3) |
| 2779 | - gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val); | 2786 | + gen_op_shiftd_T0_T1_im_cc[ot][op](val); |
| 2780 | else | 2787 | else |
| 2781 | - gen_op_shiftd_mem_T0_T1_im_cc[ot - OT_WORD][op](val); | 2788 | + gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val); |
| 2782 | if (op == 0 && ot != OT_WORD) | 2789 | if (op == 0 && ot != OT_WORD) |
| 2783 | s->cc_op = CC_OP_SHLB + ot; | 2790 | s->cc_op = CC_OP_SHLB + ot; |
| 2784 | else | 2791 | else |
| @@ -2788,9 +2795,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2788,9 +2795,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2788 | if (s->cc_op != CC_OP_DYNAMIC) | 2795 | if (s->cc_op != CC_OP_DYNAMIC) |
| 2789 | gen_op_set_cc_op(s->cc_op); | 2796 | gen_op_set_cc_op(s->cc_op); |
| 2790 | if (mod == 3) | 2797 | if (mod == 3) |
| 2791 | - gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op](); | 2798 | + gen_op_shiftd_T0_T1_ECX_cc[ot][op](); |
| 2792 | else | 2799 | else |
| 2793 | - gen_op_shiftd_mem_T0_T1_ECX_cc[ot - OT_WORD][op](); | 2800 | + gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op](); |
| 2794 | s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ | 2801 | s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ |
| 2795 | } | 2802 | } |
| 2796 | if (mod == 3) { | 2803 | if (mod == 3) { |
| @@ -3347,6 +3354,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3347,6 +3354,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 3347 | else | 3354 | else |
| 3348 | ot = dflag ? OT_LONG : OT_WORD; | 3355 | ot = dflag ? OT_LONG : OT_WORD; |
| 3349 | gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); | 3356 | gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); |
| 3357 | + gen_op_andl_T0_ffff(); | ||
| 3350 | gen_check_io(s, ot, 0, pc_start - s->cs_base); | 3358 | gen_check_io(s, ot, 0, pc_start - s->cs_base); |
| 3351 | gen_op_in[ot](); | 3359 | gen_op_in[ot](); |
| 3352 | gen_op_mov_reg_T1[ot][R_EAX](); | 3360 | gen_op_mov_reg_T1[ot][R_EAX](); |
| @@ -3358,6 +3366,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3358,6 +3366,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 3358 | else | 3366 | else |
| 3359 | ot = dflag ? OT_LONG : OT_WORD; | 3367 | ot = dflag ? OT_LONG : OT_WORD; |
| 3360 | gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); | 3368 | gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); |
| 3369 | + gen_op_andl_T0_ffff(); | ||
| 3361 | gen_check_io(s, ot, 0, pc_start - s->cs_base); | 3370 | gen_check_io(s, ot, 0, pc_start - s->cs_base); |
| 3362 | gen_op_mov_TN_reg[ot][1][R_EAX](); | 3371 | gen_op_mov_TN_reg[ot][1][R_EAX](); |
| 3363 | gen_op_out[ot](); | 3372 | gen_op_out[ot](); |
| @@ -4148,20 +4157,6 @@ static uint16_t opc_read_flags[NB_OPS] = { | @@ -4148,20 +4157,6 @@ static uint16_t opc_read_flags[NB_OPS] = { | ||
| 4148 | [INDEX_op_das] = CC_A | CC_C, | 4157 | [INDEX_op_das] = CC_A | CC_C, |
| 4149 | [INDEX_op_daa] = CC_A | CC_C, | 4158 | [INDEX_op_daa] = CC_A | CC_C, |
| 4150 | 4159 | ||
| 4151 | - [INDEX_op_adcb_T0_T1_cc] = CC_C, | ||
| 4152 | - [INDEX_op_adcw_T0_T1_cc] = CC_C, | ||
| 4153 | - [INDEX_op_adcl_T0_T1_cc] = CC_C, | ||
| 4154 | - [INDEX_op_sbbb_T0_T1_cc] = CC_C, | ||
| 4155 | - [INDEX_op_sbbw_T0_T1_cc] = CC_C, | ||
| 4156 | - [INDEX_op_sbbl_T0_T1_cc] = CC_C, | ||
| 4157 | - | ||
| 4158 | - [INDEX_op_adcb_mem_T0_T1_cc] = CC_C, | ||
| 4159 | - [INDEX_op_adcw_mem_T0_T1_cc] = CC_C, | ||
| 4160 | - [INDEX_op_adcl_mem_T0_T1_cc] = CC_C, | ||
| 4161 | - [INDEX_op_sbbb_mem_T0_T1_cc] = CC_C, | ||
| 4162 | - [INDEX_op_sbbw_mem_T0_T1_cc] = CC_C, | ||
| 4163 | - [INDEX_op_sbbl_mem_T0_T1_cc] = CC_C, | ||
| 4164 | - | ||
| 4165 | /* subtle: due to the incl/decl implementation, C is used */ | 4160 | /* subtle: due to the incl/decl implementation, C is used */ |
| 4166 | [INDEX_op_update_inc_cc] = CC_C, | 4161 | [INDEX_op_update_inc_cc] = CC_C, |
| 4167 | 4162 | ||
| @@ -4233,19 +4228,28 @@ static uint16_t opc_read_flags[NB_OPS] = { | @@ -4233,19 +4228,28 @@ static uint16_t opc_read_flags[NB_OPS] = { | ||
| 4233 | [INDEX_op_cmc] = CC_C, | 4228 | [INDEX_op_cmc] = CC_C, |
| 4234 | [INDEX_op_salc] = CC_C, | 4229 | [INDEX_op_salc] = CC_C, |
| 4235 | 4230 | ||
| 4236 | - [INDEX_op_rclb_T0_T1_cc] = CC_C, | ||
| 4237 | - [INDEX_op_rclw_T0_T1_cc] = CC_C, | ||
| 4238 | - [INDEX_op_rcll_T0_T1_cc] = CC_C, | ||
| 4239 | - [INDEX_op_rcrb_T0_T1_cc] = CC_C, | ||
| 4240 | - [INDEX_op_rcrw_T0_T1_cc] = CC_C, | ||
| 4241 | - [INDEX_op_rcrl_T0_T1_cc] = CC_C, | ||
| 4242 | - | ||
| 4243 | - [INDEX_op_rclb_mem_T0_T1_cc] = CC_C, | ||
| 4244 | - [INDEX_op_rclw_mem_T0_T1_cc] = CC_C, | ||
| 4245 | - [INDEX_op_rcll_mem_T0_T1_cc] = CC_C, | ||
| 4246 | - [INDEX_op_rcrb_mem_T0_T1_cc] = CC_C, | ||
| 4247 | - [INDEX_op_rcrw_mem_T0_T1_cc] = CC_C, | ||
| 4248 | - [INDEX_op_rcrl_mem_T0_T1_cc] = CC_C, | 4231 | +#define DEF_READF(SUFFIX)\ |
| 4232 | + [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4233 | + [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4234 | + [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4235 | + [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4236 | + [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4237 | + [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4238 | +\ | ||
| 4239 | + [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4240 | + [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4241 | + [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4242 | + [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4243 | + [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\ | ||
| 4244 | + [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C, | ||
| 4245 | + | ||
| 4246 | + | ||
| 4247 | + DEF_READF() | ||
| 4248 | + DEF_READF(_raw) | ||
| 4249 | +#ifndef CONFIG_USER_ONLY | ||
| 4250 | + DEF_READF(_kernel) | ||
| 4251 | + DEF_READF(_user) | ||
| 4252 | +#endif | ||
| 4249 | }; | 4253 | }; |
| 4250 | 4254 | ||
| 4251 | /* flags written by an operation */ | 4255 | /* flags written by an operation */ |
| @@ -4258,20 +4262,6 @@ static uint16_t opc_write_flags[NB_OPS] = { | @@ -4258,20 +4262,6 @@ static uint16_t opc_write_flags[NB_OPS] = { | ||
| 4258 | [INDEX_op_update_inc_cc] = CC_OSZAPC, | 4262 | [INDEX_op_update_inc_cc] = CC_OSZAPC, |
| 4259 | [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC, | 4263 | [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC, |
| 4260 | 4264 | ||
| 4261 | - [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC, | ||
| 4262 | - [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC, | ||
| 4263 | - [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC, | ||
| 4264 | - [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC, | ||
| 4265 | - [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC, | ||
| 4266 | - [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC, | ||
| 4267 | - | ||
| 4268 | - [INDEX_op_adcb_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4269 | - [INDEX_op_adcw_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4270 | - [INDEX_op_adcl_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4271 | - [INDEX_op_sbbb_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4272 | - [INDEX_op_sbbw_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4273 | - [INDEX_op_sbbl_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4274 | - | ||
| 4275 | [INDEX_op_mulb_AL_T0] = CC_OSZAPC, | 4265 | [INDEX_op_mulb_AL_T0] = CC_OSZAPC, |
| 4276 | [INDEX_op_imulb_AL_T0] = CC_OSZAPC, | 4266 | [INDEX_op_imulb_AL_T0] = CC_OSZAPC, |
| 4277 | [INDEX_op_mulw_AX_T0] = CC_OSZAPC, | 4267 | [INDEX_op_mulw_AX_T0] = CC_OSZAPC, |
| @@ -4300,78 +4290,6 @@ static uint16_t opc_write_flags[NB_OPS] = { | @@ -4300,78 +4290,6 @@ static uint16_t opc_write_flags[NB_OPS] = { | ||
| 4300 | [INDEX_op_stc] = CC_C, | 4290 | [INDEX_op_stc] = CC_C, |
| 4301 | [INDEX_op_cmc] = CC_C, | 4291 | [INDEX_op_cmc] = CC_C, |
| 4302 | 4292 | ||
| 4303 | - [INDEX_op_rolb_T0_T1_cc] = CC_O | CC_C, | ||
| 4304 | - [INDEX_op_rolw_T0_T1_cc] = CC_O | CC_C, | ||
| 4305 | - [INDEX_op_roll_T0_T1_cc] = CC_O | CC_C, | ||
| 4306 | - [INDEX_op_rorb_T0_T1_cc] = CC_O | CC_C, | ||
| 4307 | - [INDEX_op_rorw_T0_T1_cc] = CC_O | CC_C, | ||
| 4308 | - [INDEX_op_rorl_T0_T1_cc] = CC_O | CC_C, | ||
| 4309 | - | ||
| 4310 | - [INDEX_op_rclb_T0_T1_cc] = CC_O | CC_C, | ||
| 4311 | - [INDEX_op_rclw_T0_T1_cc] = CC_O | CC_C, | ||
| 4312 | - [INDEX_op_rcll_T0_T1_cc] = CC_O | CC_C, | ||
| 4313 | - [INDEX_op_rcrb_T0_T1_cc] = CC_O | CC_C, | ||
| 4314 | - [INDEX_op_rcrw_T0_T1_cc] = CC_O | CC_C, | ||
| 4315 | - [INDEX_op_rcrl_T0_T1_cc] = CC_O | CC_C, | ||
| 4316 | - | ||
| 4317 | - [INDEX_op_shlb_T0_T1_cc] = CC_OSZAPC, | ||
| 4318 | - [INDEX_op_shlw_T0_T1_cc] = CC_OSZAPC, | ||
| 4319 | - [INDEX_op_shll_T0_T1_cc] = CC_OSZAPC, | ||
| 4320 | - | ||
| 4321 | - [INDEX_op_shrb_T0_T1_cc] = CC_OSZAPC, | ||
| 4322 | - [INDEX_op_shrw_T0_T1_cc] = CC_OSZAPC, | ||
| 4323 | - [INDEX_op_shrl_T0_T1_cc] = CC_OSZAPC, | ||
| 4324 | - | ||
| 4325 | - [INDEX_op_sarb_T0_T1_cc] = CC_OSZAPC, | ||
| 4326 | - [INDEX_op_sarw_T0_T1_cc] = CC_OSZAPC, | ||
| 4327 | - [INDEX_op_sarl_T0_T1_cc] = CC_OSZAPC, | ||
| 4328 | - | ||
| 4329 | - [INDEX_op_shldw_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4330 | - [INDEX_op_shldl_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4331 | - [INDEX_op_shldw_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4332 | - [INDEX_op_shldl_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4333 | - | ||
| 4334 | - [INDEX_op_shrdw_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4335 | - [INDEX_op_shrdl_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4336 | - [INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4337 | - [INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4338 | - | ||
| 4339 | - [INDEX_op_rolb_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4340 | - [INDEX_op_rolw_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4341 | - [INDEX_op_roll_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4342 | - [INDEX_op_rorb_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4343 | - [INDEX_op_rorw_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4344 | - [INDEX_op_rorl_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4345 | - | ||
| 4346 | - [INDEX_op_rclb_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4347 | - [INDEX_op_rclw_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4348 | - [INDEX_op_rcll_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4349 | - [INDEX_op_rcrb_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4350 | - [INDEX_op_rcrw_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4351 | - [INDEX_op_rcrl_mem_T0_T1_cc] = CC_O | CC_C, | ||
| 4352 | - | ||
| 4353 | - [INDEX_op_shlb_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4354 | - [INDEX_op_shlw_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4355 | - [INDEX_op_shll_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4356 | - | ||
| 4357 | - [INDEX_op_shrb_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4358 | - [INDEX_op_shrw_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4359 | - [INDEX_op_shrl_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4360 | - | ||
| 4361 | - [INDEX_op_sarb_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4362 | - [INDEX_op_sarw_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4363 | - [INDEX_op_sarl_mem_T0_T1_cc] = CC_OSZAPC, | ||
| 4364 | - | ||
| 4365 | - [INDEX_op_shldw_mem_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4366 | - [INDEX_op_shldl_mem_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4367 | - [INDEX_op_shldw_mem_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4368 | - [INDEX_op_shldl_mem_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4369 | - | ||
| 4370 | - [INDEX_op_shrdw_mem_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4371 | - [INDEX_op_shrdl_mem_T0_T1_ECX_cc] = CC_OSZAPC, | ||
| 4372 | - [INDEX_op_shrdw_mem_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4373 | - [INDEX_op_shrdl_mem_T0_T1_im_cc] = CC_OSZAPC, | ||
| 4374 | - | ||
| 4375 | [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC, | 4293 | [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC, |
| 4376 | [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC, | 4294 | [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC, |
| 4377 | [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC, | 4295 | [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC, |
| @@ -4390,15 +4308,67 @@ static uint16_t opc_write_flags[NB_OPS] = { | @@ -4390,15 +4308,67 @@ static uint16_t opc_write_flags[NB_OPS] = { | ||
| 4390 | [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC, | 4308 | [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC, |
| 4391 | [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC, | 4309 | [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC, |
| 4392 | 4310 | ||
| 4393 | - [INDEX_op_cmpxchgb_mem_T0_T1_EAX_cc] = CC_OSZAPC, | ||
| 4394 | - [INDEX_op_cmpxchgw_mem_T0_T1_EAX_cc] = CC_OSZAPC, | ||
| 4395 | - [INDEX_op_cmpxchgl_mem_T0_T1_EAX_cc] = CC_OSZAPC, | ||
| 4396 | - | ||
| 4397 | [INDEX_op_cmpxchg8b] = CC_Z, | 4311 | [INDEX_op_cmpxchg8b] = CC_Z, |
| 4398 | [INDEX_op_lar] = CC_Z, | 4312 | [INDEX_op_lar] = CC_Z, |
| 4399 | [INDEX_op_lsl] = CC_Z, | 4313 | [INDEX_op_lsl] = CC_Z, |
| 4400 | [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C, | 4314 | [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C, |
| 4401 | [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C, | 4315 | [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C, |
| 4316 | + | ||
| 4317 | +#define DEF_WRITEF(SUFFIX)\ | ||
| 4318 | + [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4319 | + [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4320 | + [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4321 | + [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4322 | + [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4323 | + [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4324 | +\ | ||
| 4325 | + [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4326 | + [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4327 | + [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4328 | + [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4329 | + [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4330 | + [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4331 | +\ | ||
| 4332 | + [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4333 | + [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4334 | + [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4335 | + [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4336 | + [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4337 | + [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\ | ||
| 4338 | +\ | ||
| 4339 | + [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4340 | + [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4341 | + [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4342 | +\ | ||
| 4343 | + [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4344 | + [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4345 | + [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4346 | +\ | ||
| 4347 | + [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4348 | + [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4349 | + [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ||
| 4350 | +\ | ||
| 4351 | + [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\ | ||
| 4352 | + [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\ | ||
| 4353 | + [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\ | ||
| 4354 | + [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\ | ||
| 4355 | +\ | ||
| 4356 | + [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\ | ||
| 4357 | + [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\ | ||
| 4358 | + [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\ | ||
| 4359 | + [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\ | ||
| 4360 | +\ | ||
| 4361 | + [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\ | ||
| 4362 | + [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\ | ||
| 4363 | + [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC, | ||
| 4364 | + | ||
| 4365 | + | ||
| 4366 | + DEF_WRITEF() | ||
| 4367 | + DEF_WRITEF(_raw) | ||
| 4368 | +#ifndef CONFIG_USER_ONLY | ||
| 4369 | + DEF_WRITEF(_kernel) | ||
| 4370 | + DEF_WRITEF(_user) | ||
| 4371 | +#endif | ||
| 4402 | }; | 4372 | }; |
| 4403 | 4373 | ||
| 4404 | /* simpler form of an operation if no flags need to be generated */ | 4374 | /* simpler form of an operation if no flags need to be generated */ |
| @@ -4410,21 +4380,6 @@ static uint16_t opc_simpler[NB_OPS] = { | @@ -4410,21 +4380,6 @@ static uint16_t opc_simpler[NB_OPS] = { | ||
| 4410 | /* broken: CC_OP logic must be rewritten */ | 4380 | /* broken: CC_OP logic must be rewritten */ |
| 4411 | [INDEX_op_update_inc_cc] = INDEX_op_nop, | 4381 | [INDEX_op_update_inc_cc] = INDEX_op_nop, |
| 4412 | #endif | 4382 | #endif |
| 4413 | - [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1, | ||
| 4414 | - [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1, | ||
| 4415 | - [INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1, | ||
| 4416 | - | ||
| 4417 | - [INDEX_op_rorb_T0_T1_cc] = INDEX_op_rorb_T0_T1, | ||
| 4418 | - [INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1, | ||
| 4419 | - [INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1, | ||
| 4420 | - | ||
| 4421 | - [INDEX_op_rolb_mem_T0_T1_cc] = INDEX_op_rolb_mem_T0_T1, | ||
| 4422 | - [INDEX_op_rolw_mem_T0_T1_cc] = INDEX_op_rolw_mem_T0_T1, | ||
| 4423 | - [INDEX_op_roll_mem_T0_T1_cc] = INDEX_op_roll_mem_T0_T1, | ||
| 4424 | - | ||
| 4425 | - [INDEX_op_rorb_mem_T0_T1_cc] = INDEX_op_rorb_mem_T0_T1, | ||
| 4426 | - [INDEX_op_rorw_mem_T0_T1_cc] = INDEX_op_rorw_mem_T0_T1, | ||
| 4427 | - [INDEX_op_rorl_mem_T0_T1_cc] = INDEX_op_rorl_mem_T0_T1, | ||
| 4428 | 4383 | ||
| 4429 | [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1, | 4384 | [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1, |
| 4430 | [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1, | 4385 | [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1, |
| @@ -4437,6 +4392,22 @@ static uint16_t opc_simpler[NB_OPS] = { | @@ -4437,6 +4392,22 @@ static uint16_t opc_simpler[NB_OPS] = { | ||
| 4437 | [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1, | 4392 | [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1, |
| 4438 | [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1, | 4393 | [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1, |
| 4439 | [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1, | 4394 | [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1, |
| 4395 | + | ||
| 4396 | +#define DEF_SIMPLER(SUFFIX)\ | ||
| 4397 | + [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\ | ||
| 4398 | + [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\ | ||
| 4399 | + [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\ | ||
| 4400 | +\ | ||
| 4401 | + [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\ | ||
| 4402 | + [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\ | ||
| 4403 | + [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1, | ||
| 4404 | + | ||
| 4405 | + DEF_SIMPLER() | ||
| 4406 | + DEF_SIMPLER(_raw) | ||
| 4407 | +#ifndef CONFIG_USER_ONLY | ||
| 4408 | + DEF_SIMPLER(_kernel) | ||
| 4409 | + DEF_SIMPLER(_user) | ||
| 4410 | +#endif | ||
| 4440 | }; | 4411 | }; |
| 4441 | 4412 | ||
| 4442 | void optimize_flags_init(void) | 4413 | void optimize_flags_init(void) |
| @@ -4495,7 +4466,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | @@ -4495,7 +4466,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
| 4495 | cs_base = (uint8_t *)tb->cs_base; | 4466 | cs_base = (uint8_t *)tb->cs_base; |
| 4496 | flags = tb->flags; | 4467 | flags = tb->flags; |
| 4497 | 4468 | ||
| 4498 | - dc->pe = env->cr[0] & CR0_PE_MASK; | 4469 | + dc->pe = (flags >> HF_PE_SHIFT) & 1; |
| 4499 | dc->code32 = (flags >> HF_CS32_SHIFT) & 1; | 4470 | dc->code32 = (flags >> HF_CS32_SHIFT) & 1; |
| 4500 | dc->ss32 = (flags >> HF_SS32_SHIFT) & 1; | 4471 | dc->ss32 = (flags >> HF_SS32_SHIFT) & 1; |
| 4501 | dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1; | 4472 | dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1; |
| @@ -4523,6 +4494,12 @@ static inline int gen_intermediate_code_internal(CPUState *env, | @@ -4523,6 +4494,12 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
| 4523 | || (flags & HF_SOFTMMU_MASK) | 4494 | || (flags & HF_SOFTMMU_MASK) |
| 4524 | #endif | 4495 | #endif |
| 4525 | ); | 4496 | ); |
| 4497 | +#if 0 | ||
| 4498 | + /* check addseg logic */ | ||
| 4499 | + if (!dc->addseg && (dc->vm86 || !dc->pe)) | ||
| 4500 | + printf("ERROR addseg\n"); | ||
| 4501 | +#endif | ||
| 4502 | + | ||
| 4526 | gen_opc_ptr = gen_opc_buf; | 4503 | gen_opc_ptr = gen_opc_buf; |
| 4527 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; | 4504 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
| 4528 | gen_opparam_ptr = gen_opparam_buf; | 4505 | gen_opparam_ptr = gen_opparam_buf; |
| @@ -4589,7 +4566,6 @@ static inline int gen_intermediate_code_internal(CPUState *env, | @@ -4589,7 +4566,6 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
| 4589 | fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); | 4566 | fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); |
| 4590 | disas(logfile, pc_start, pc_ptr - pc_start, 0, !dc->code32); | 4567 | disas(logfile, pc_start, pc_ptr - pc_start, 0, !dc->code32); |
| 4591 | fprintf(logfile, "\n"); | 4568 | fprintf(logfile, "\n"); |
| 4592 | - | ||
| 4593 | fprintf(logfile, "OP:\n"); | 4569 | fprintf(logfile, "OP:\n"); |
| 4594 | dump_ops(gen_opc_buf, gen_opparam_buf); | 4570 | dump_ops(gen_opc_buf, gen_opparam_buf); |
| 4595 | fprintf(logfile, "\n"); | 4571 | fprintf(logfile, "\n"); |