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] = { |