Commit 430c1ad18e231727cbf00d1e8a2415ecba5128a2
1 parent
f5dc2e54
Convert CPSR pseudo-registers into TCG registers.
Signed-off-by: Filip Navara <filip.navara@gmail.com>
Showing
1 changed file
with
41 additions
and
66 deletions
target-arm/translate.c
| ... | ... | @@ -77,6 +77,8 @@ static TCGv_ptr cpu_env; |
| 77 | 77 | /* We reuse the same 64-bit temporaries for efficiency. */ |
| 78 | 78 | static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; |
| 79 | 79 | static TCGv_i32 cpu_R[16]; |
| 80 | +/* CPSR flags, used for efficiency */ | |
| 81 | +static TCGv_i32 cpu_CF, cpu_VF, cpu_NF, cpu_ZF; | |
| 80 | 82 | |
| 81 | 83 | /* FIXME: These should be removed. */ |
| 82 | 84 | static TCGv cpu_F0s, cpu_F1s; |
| ... | ... | @@ -101,6 +103,11 @@ void arm_translate_init(void) |
| 101 | 103 | regnames[i]); |
| 102 | 104 | } |
| 103 | 105 | |
| 106 | + cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, CF), "CF"); | |
| 107 | + cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, VF), "VF"); | |
| 108 | + cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, NF), "NF"); | |
| 109 | + cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, ZF), "ZF"); | |
| 110 | + | |
| 104 | 111 | #define GEN_HELPER 2 |
| 105 | 112 | #include "helpers.h" |
| 106 | 113 | } |
| ... | ... | @@ -362,43 +369,34 @@ static void gen_add16(TCGv t0, TCGv t1) |
| 362 | 369 | dead_tmp(t1); |
| 363 | 370 | } |
| 364 | 371 | |
| 365 | -#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF)) | |
| 372 | +#define gen_set_CF(var) tcg_gen_mov_i32(cpu_CF, var) | |
| 366 | 373 | |
| 367 | 374 | /* Set CF to the top bit of var. */ |
| 368 | 375 | static void gen_set_CF_bit31(TCGv var) |
| 369 | 376 | { |
| 370 | - TCGv tmp = new_tmp(); | |
| 371 | - tcg_gen_shri_i32(tmp, var, 31); | |
| 372 | - gen_set_CF(tmp); | |
| 373 | - dead_tmp(tmp); | |
| 377 | + tcg_gen_shri_i32(cpu_CF, var, 31); | |
| 374 | 378 | } |
| 375 | 379 | |
| 376 | 380 | /* Set N and Z flags from var. */ |
| 377 | 381 | static inline void gen_logic_CC(TCGv var) |
| 378 | 382 | { |
| 379 | - tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF)); | |
| 380 | - tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF)); | |
| 383 | + tcg_gen_mov_i32(cpu_NF, var); | |
| 384 | + tcg_gen_mov_i32(cpu_ZF, var); | |
| 381 | 385 | } |
| 382 | 386 | |
| 383 | 387 | /* dest = T0 + T1 + CF. */ |
| 384 | 388 | static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) |
| 385 | 389 | { |
| 386 | - TCGv tmp; | |
| 387 | 390 | tcg_gen_add_i32(dest, t0, t1); |
| 388 | - tmp = load_cpu_field(CF); | |
| 389 | - tcg_gen_add_i32(dest, dest, tmp); | |
| 390 | - dead_tmp(tmp); | |
| 391 | + tcg_gen_add_i32(dest, dest, cpu_CF); | |
| 391 | 392 | } |
| 392 | 393 | |
| 393 | 394 | /* dest = T0 - T1 + CF - 1. */ |
| 394 | 395 | static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) |
| 395 | 396 | { |
| 396 | - TCGv tmp; | |
| 397 | 397 | tcg_gen_sub_i32(dest, t0, t1); |
| 398 | - tmp = load_cpu_field(CF); | |
| 399 | - tcg_gen_add_i32(dest, dest, tmp); | |
| 398 | + tcg_gen_add_i32(dest, dest, cpu_CF); | |
| 400 | 399 | tcg_gen_subi_i32(dest, dest, 1); |
| 401 | - dead_tmp(tmp); | |
| 402 | 400 | } |
| 403 | 401 | |
| 404 | 402 | /* T0 &= ~T1. Clobbers T1. */ |
| ... | ... | @@ -467,7 +465,8 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) |
| 467 | 465 | shifter_out_im(var, shift - 1); |
| 468 | 466 | tcg_gen_rotri_i32(var, var, shift); break; |
| 469 | 467 | } else { |
| 470 | - TCGv tmp = load_cpu_field(CF); | |
| 468 | + TCGv tmp = new_tmp(); | |
| 469 | + tcg_gen_mov_i32(tmp, cpu_CF); | |
| 471 | 470 | if (flags) |
| 472 | 471 | shifter_out_im(var, 0); |
| 473 | 472 | tcg_gen_shri_i32(var, var, 1); |
| ... | ... | @@ -591,99 +590,75 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) |
| 591 | 590 | static void gen_test_cc(int cc, int label) |
| 592 | 591 | { |
| 593 | 592 | TCGv tmp; |
| 594 | - TCGv tmp2; | |
| 595 | 593 | int inv; |
| 596 | 594 | |
| 597 | 595 | switch (cc) { |
| 598 | 596 | case 0: /* eq: Z */ |
| 599 | - tmp = load_cpu_field(ZF); | |
| 600 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); | |
| 597 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label); | |
| 601 | 598 | break; |
| 602 | 599 | case 1: /* ne: !Z */ |
| 603 | - tmp = load_cpu_field(ZF); | |
| 604 | - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); | |
| 600 | + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label); | |
| 605 | 601 | break; |
| 606 | 602 | case 2: /* cs: C */ |
| 607 | - tmp = load_cpu_field(CF); | |
| 608 | - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); | |
| 603 | + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label); | |
| 609 | 604 | break; |
| 610 | 605 | case 3: /* cc: !C */ |
| 611 | - tmp = load_cpu_field(CF); | |
| 612 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); | |
| 606 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label); | |
| 613 | 607 | break; |
| 614 | 608 | case 4: /* mi: N */ |
| 615 | - tmp = load_cpu_field(NF); | |
| 616 | - tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); | |
| 609 | + tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label); | |
| 617 | 610 | break; |
| 618 | 611 | case 5: /* pl: !N */ |
| 619 | - tmp = load_cpu_field(NF); | |
| 620 | - tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); | |
| 612 | + tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label); | |
| 621 | 613 | break; |
| 622 | 614 | case 6: /* vs: V */ |
| 623 | - tmp = load_cpu_field(VF); | |
| 624 | - tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); | |
| 615 | + tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label); | |
| 625 | 616 | break; |
| 626 | 617 | case 7: /* vc: !V */ |
| 627 | - tmp = load_cpu_field(VF); | |
| 628 | - tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); | |
| 618 | + tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label); | |
| 629 | 619 | break; |
| 630 | 620 | case 8: /* hi: C && !Z */ |
| 631 | 621 | inv = gen_new_label(); |
| 632 | - tmp = load_cpu_field(CF); | |
| 633 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); | |
| 634 | - dead_tmp(tmp); | |
| 635 | - tmp = load_cpu_field(ZF); | |
| 636 | - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); | |
| 622 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv); | |
| 623 | + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label); | |
| 637 | 624 | gen_set_label(inv); |
| 638 | 625 | break; |
| 639 | 626 | case 9: /* ls: !C || Z */ |
| 640 | - tmp = load_cpu_field(CF); | |
| 641 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); | |
| 642 | - dead_tmp(tmp); | |
| 643 | - tmp = load_cpu_field(ZF); | |
| 644 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); | |
| 627 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label); | |
| 628 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label); | |
| 645 | 629 | break; |
| 646 | 630 | case 10: /* ge: N == V -> N ^ V == 0 */ |
| 647 | - tmp = load_cpu_field(VF); | |
| 648 | - tmp2 = load_cpu_field(NF); | |
| 649 | - tcg_gen_xor_i32(tmp, tmp, tmp2); | |
| 650 | - dead_tmp(tmp2); | |
| 631 | + tmp = new_tmp(); | |
| 632 | + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); | |
| 651 | 633 | tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); |
| 634 | + dead_tmp(tmp); | |
| 652 | 635 | break; |
| 653 | 636 | case 11: /* lt: N != V -> N ^ V != 0 */ |
| 654 | - tmp = load_cpu_field(VF); | |
| 655 | - tmp2 = load_cpu_field(NF); | |
| 656 | - tcg_gen_xor_i32(tmp, tmp, tmp2); | |
| 657 | - dead_tmp(tmp2); | |
| 637 | + tmp = new_tmp(); | |
| 638 | + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); | |
| 658 | 639 | tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); |
| 640 | + dead_tmp(tmp); | |
| 659 | 641 | break; |
| 660 | 642 | case 12: /* gt: !Z && N == V */ |
| 661 | 643 | inv = gen_new_label(); |
| 662 | - tmp = load_cpu_field(ZF); | |
| 663 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); | |
| 664 | - dead_tmp(tmp); | |
| 665 | - tmp = load_cpu_field(VF); | |
| 666 | - tmp2 = load_cpu_field(NF); | |
| 667 | - tcg_gen_xor_i32(tmp, tmp, tmp2); | |
| 668 | - dead_tmp(tmp2); | |
| 644 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv); | |
| 645 | + tmp = new_tmp(); | |
| 646 | + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); | |
| 669 | 647 | tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); |
| 648 | + dead_tmp(tmp); | |
| 670 | 649 | gen_set_label(inv); |
| 671 | 650 | break; |
| 672 | 651 | case 13: /* le: Z || N != V */ |
| 673 | - tmp = load_cpu_field(ZF); | |
| 674 | - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); | |
| 675 | - dead_tmp(tmp); | |
| 676 | - tmp = load_cpu_field(VF); | |
| 677 | - tmp2 = load_cpu_field(NF); | |
| 678 | - tcg_gen_xor_i32(tmp, tmp, tmp2); | |
| 679 | - dead_tmp(tmp2); | |
| 652 | + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label); | |
| 653 | + tmp = new_tmp(); | |
| 654 | + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); | |
| 680 | 655 | tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); |
| 656 | + dead_tmp(tmp); | |
| 681 | 657 | break; |
| 682 | 658 | default: |
| 683 | 659 | fprintf(stderr, "Bad condition code 0x%x\n", cc); |
| 684 | 660 | abort(); |
| 685 | 661 | } |
| 686 | - dead_tmp(tmp); | |
| 687 | 662 | } |
| 688 | 663 | |
| 689 | 664 | static const uint8_t table_logic_cc[16] = { | ... | ... |