Skip to content
This repository was archived by the owner on Feb 3, 2020. It is now read-only.

Commit 1235ebb

Browse files
target-arm/translate.c: update gen_test_cc from 1.0 to 3.0
Signed-off-by: chaojixx <wpz5080@psu.edu>
1 parent a0c0b9a commit 1235ebb

File tree

1 file changed

+47
-56
lines changed

1 file changed

+47
-56
lines changed

src/target-arm/translate.c

Lines changed: 47 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -728,98 +728,89 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) {
728728
static void gen_test_cc(int cc, TCGLabel *label) {
729729
TCGv tmp;
730730
TCGv tmp2;
731-
TCGLabel *inv;
731+
732+
TCGv_i32 value;
733+
TCGCond cond;
732734

733735
switch (cc) {
734736
case 0: /* eq: Z */
735-
tmp = load_cpu_field(ZF);
736-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
737-
break;
738737
case 1: /* ne: !Z */
739-
tmp = load_cpu_field(ZF);
740-
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
738+
cond = TCG_COND_EQ;
739+
value = load_cpu_field(ZF);
741740
break;
742741
case 2: /* cs: C */
743-
tmp = load_cpu_field(CF);
744-
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
745-
break;
746742
case 3: /* cc: !C */
747-
tmp = load_cpu_field(CF);
748-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
743+
cond = TCG_COND_NE;
744+
value = load_cpu_field(CF);
749745
break;
750746
case 4: /* mi: N */
751-
tmp = load_cpu_field(NF);
752-
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
753-
break;
754747
case 5: /* pl: !N */
755-
tmp = load_cpu_field(NF);
756-
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
748+
cond = TCG_COND_LT;
749+
value = load_cpu_field(NF);
757750
break;
758751
case 6: /* vs: V */
759-
tmp = load_cpu_field(VF);
760-
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
761-
break;
762752
case 7: /* vc: !V */
763-
tmp = load_cpu_field(VF);
764-
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
753+
cond = TCG_COND_LT;
754+
value = load_cpu_field(VF);
765755
break;
766756
case 8: /* hi: C && !Z */
767-
inv = gen_new_label();
768-
tmp = load_cpu_field(CF);
769-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
770-
tcg_temp_free_i32(tmp);
771-
tmp = load_cpu_field(ZF);
772-
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
773-
gen_set_label(inv);
774-
break;
775757
case 9: /* ls: !C || Z */
758+
cond = TCG_COND_NE;
759+
value = tcg_temp_new_i32();
776760
tmp = load_cpu_field(CF);
777-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
761+
tmp2 = load_cpu_field(ZF);
762+
/* CF is 1 for C, so -CF is an all-bits-set mask for C;
763+
ZF is non-zero for !Z; so AND the two subexpressions. */
764+
tcg_gen_neg_i32(value, tmp);
765+
tcg_gen_and_i32(value, value, tmp2);
778766
tcg_temp_free_i32(tmp);
779-
tmp = load_cpu_field(ZF);
780-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
781-
break;
782-
case 10: /* ge: N == V -> N ^ V == 0 */
783-
tmp = load_cpu_field(VF);
784-
tmp2 = load_cpu_field(NF);
785-
tcg_gen_xor_i32(tmp, tmp, tmp2);
786767
tcg_temp_free_i32(tmp2);
787-
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
788768
break;
769+
case 10: /* ge: N == V -> N ^ V == 0 */
789770
case 11: /* lt: N != V -> N ^ V != 0 */
771+
cond = TCG_COND_GE;
772+
value = tcg_temp_new_i32();
790773
tmp = load_cpu_field(VF);
791774
tmp2 = load_cpu_field(NF);
792-
tcg_gen_xor_i32(tmp, tmp, tmp2);
775+
tcg_gen_xor_i32(value, tmp, tmp2);
776+
tcg_temp_free_i32(tmp);
793777
tcg_temp_free_i32(tmp2);
794-
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
795778
break;
796779
case 12: /* gt: !Z && N == V */
797-
inv = gen_new_label();
798-
tmp = load_cpu_field(ZF);
799-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
800-
tcg_temp_free_i32(tmp);
780+
case 13: /* le: Z || N != V */
781+
cond = TCG_COND_NE;
782+
value = tcg_temp_new_i32();
801783
tmp = load_cpu_field(VF);
802784
tmp2 = load_cpu_field(NF);
803-
tcg_gen_xor_i32(tmp, tmp, tmp2);
785+
/* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
786+
* the sign bit then AND with ZF to yield the result. */
787+
tcg_gen_xor_i32(value, tmp, tmp2);
788+
tcg_gen_sari_i32(value, value, 31);
789+
tcg_temp_free_i32(tmp);
804790
tcg_temp_free_i32(tmp2);
805-
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
806-
gen_set_label(inv);
807-
break;
808-
case 13: /* le: Z || N != V */
809791
tmp = load_cpu_field(ZF);
810-
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
792+
tcg_gen_andc_i32(value, tmp, value);
811793
tcg_temp_free_i32(tmp);
812-
tmp = load_cpu_field(VF);
813-
tmp2 = load_cpu_field(NF);
814-
tcg_gen_xor_i32(tmp, tmp, tmp2);
815-
tcg_temp_free_i32(tmp2);
816-
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
817794
break;
795+
case 14: /* always */
796+
case 15: /* always */
797+
/* Use the ALWAYS condition, which will fold early.
798+
* It doesn't matter what we use for the value. */
799+
cond = TCG_COND_ALWAYS;
800+
value = load_cpu_field(ZF);
801+
goto no_invert;
818802
default:
819803
fprintf(stderr, "Bad condition code 0x%x\n", cc);
820804
abort();
821805
}
822-
tcg_temp_free_i32(tmp);
806+
807+
if (cc & 1) {
808+
cond = tcg_invert_cond(cond);
809+
}
810+
811+
no_invert:
812+
tcg_gen_brcondi_i32(cond, value, 0, label);
813+
tcg_temp_free_i32(value);
823814
}
824815

825816
static const uint8_t table_logic_cc[16] = {

0 commit comments

Comments
 (0)