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