Commit 430c1ad18e231727cbf00d1e8a2415ecba5128a2

Authored by Filip Navara
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] = {