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,6 +77,8 @@ static TCGv_ptr cpu_env; | ||
| 77 | /* We reuse the same 64-bit temporaries for efficiency. */ | 77 | /* We reuse the same 64-bit temporaries for efficiency. */ |
| 78 | static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; | 78 | static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; |
| 79 | static TCGv_i32 cpu_R[16]; | 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 | /* FIXME: These should be removed. */ | 83 | /* FIXME: These should be removed. */ |
| 82 | static TCGv cpu_F0s, cpu_F1s; | 84 | static TCGv cpu_F0s, cpu_F1s; |
| @@ -101,6 +103,11 @@ void arm_translate_init(void) | @@ -101,6 +103,11 @@ void arm_translate_init(void) | ||
| 101 | regnames[i]); | 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 | #define GEN_HELPER 2 | 111 | #define GEN_HELPER 2 |
| 105 | #include "helpers.h" | 112 | #include "helpers.h" |
| 106 | } | 113 | } |
| @@ -362,43 +369,34 @@ static void gen_add16(TCGv t0, TCGv t1) | @@ -362,43 +369,34 @@ static void gen_add16(TCGv t0, TCGv t1) | ||
| 362 | dead_tmp(t1); | 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 | /* Set CF to the top bit of var. */ | 374 | /* Set CF to the top bit of var. */ |
| 368 | static void gen_set_CF_bit31(TCGv var) | 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 | /* Set N and Z flags from var. */ | 380 | /* Set N and Z flags from var. */ |
| 377 | static inline void gen_logic_CC(TCGv var) | 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 | /* dest = T0 + T1 + CF. */ | 387 | /* dest = T0 + T1 + CF. */ |
| 384 | static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) | 388 | static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) |
| 385 | { | 389 | { |
| 386 | - TCGv tmp; | ||
| 387 | tcg_gen_add_i32(dest, t0, t1); | 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 | /* dest = T0 - T1 + CF - 1. */ | 394 | /* dest = T0 - T1 + CF - 1. */ |
| 394 | static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) | 395 | static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) |
| 395 | { | 396 | { |
| 396 | - TCGv tmp; | ||
| 397 | tcg_gen_sub_i32(dest, t0, t1); | 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 | tcg_gen_subi_i32(dest, dest, 1); | 399 | tcg_gen_subi_i32(dest, dest, 1); |
| 401 | - dead_tmp(tmp); | ||
| 402 | } | 400 | } |
| 403 | 401 | ||
| 404 | /* T0 &= ~T1. Clobbers T1. */ | 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,7 +465,8 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) | ||
| 467 | shifter_out_im(var, shift - 1); | 465 | shifter_out_im(var, shift - 1); |
| 468 | tcg_gen_rotri_i32(var, var, shift); break; | 466 | tcg_gen_rotri_i32(var, var, shift); break; |
| 469 | } else { | 467 | } else { |
| 470 | - TCGv tmp = load_cpu_field(CF); | 468 | + TCGv tmp = new_tmp(); |
| 469 | + tcg_gen_mov_i32(tmp, cpu_CF); | ||
| 471 | if (flags) | 470 | if (flags) |
| 472 | shifter_out_im(var, 0); | 471 | shifter_out_im(var, 0); |
| 473 | tcg_gen_shri_i32(var, var, 1); | 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,99 +590,75 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) | ||
| 591 | static void gen_test_cc(int cc, int label) | 590 | static void gen_test_cc(int cc, int label) |
| 592 | { | 591 | { |
| 593 | TCGv tmp; | 592 | TCGv tmp; |
| 594 | - TCGv tmp2; | ||
| 595 | int inv; | 593 | int inv; |
| 596 | 594 | ||
| 597 | switch (cc) { | 595 | switch (cc) { |
| 598 | case 0: /* eq: Z */ | 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 | break; | 598 | break; |
| 602 | case 1: /* ne: !Z */ | 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 | break; | 601 | break; |
| 606 | case 2: /* cs: C */ | 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 | break; | 604 | break; |
| 610 | case 3: /* cc: !C */ | 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 | break; | 607 | break; |
| 614 | case 4: /* mi: N */ | 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 | break; | 610 | break; |
| 618 | case 5: /* pl: !N */ | 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 | break; | 613 | break; |
| 622 | case 6: /* vs: V */ | 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 | break; | 616 | break; |
| 626 | case 7: /* vc: !V */ | 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 | break; | 619 | break; |
| 630 | case 8: /* hi: C && !Z */ | 620 | case 8: /* hi: C && !Z */ |
| 631 | inv = gen_new_label(); | 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 | gen_set_label(inv); | 624 | gen_set_label(inv); |
| 638 | break; | 625 | break; |
| 639 | case 9: /* ls: !C || Z */ | 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 | break; | 629 | break; |
| 646 | case 10: /* ge: N == V -> N ^ V == 0 */ | 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 | tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); | 633 | tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); |
| 634 | + dead_tmp(tmp); | ||
| 652 | break; | 635 | break; |
| 653 | case 11: /* lt: N != V -> N ^ V != 0 */ | 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 | tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); | 639 | tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); |
| 640 | + dead_tmp(tmp); | ||
| 659 | break; | 641 | break; |
| 660 | case 12: /* gt: !Z && N == V */ | 642 | case 12: /* gt: !Z && N == V */ |
| 661 | inv = gen_new_label(); | 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 | tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); | 647 | tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); |
| 648 | + dead_tmp(tmp); | ||
| 670 | gen_set_label(inv); | 649 | gen_set_label(inv); |
| 671 | break; | 650 | break; |
| 672 | case 13: /* le: Z || N != V */ | 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 | tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); | 655 | tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); |
| 656 | + dead_tmp(tmp); | ||
| 681 | break; | 657 | break; |
| 682 | default: | 658 | default: |
| 683 | fprintf(stderr, "Bad condition code 0x%x\n", cc); | 659 | fprintf(stderr, "Bad condition code 0x%x\n", cc); |
| 684 | abort(); | 660 | abort(); |
| 685 | } | 661 | } |
| 686 | - dead_tmp(tmp); | ||
| 687 | } | 662 | } |
| 688 | 663 | ||
| 689 | static const uint8_t table_logic_cc[16] = { | 664 | static const uint8_t table_logic_cc[16] = { |