Commit c596defdb9507d9f98269e760616773e2acde371
1 parent
200ae688
Reimplement brcond2 and refactor brcond
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4738 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
52 additions
and
51 deletions
tcg/ppc/tcg-target.c
... | ... | @@ -282,9 +282,12 @@ static int tcg_target_const_match(tcg_target_long val, |
282 | 282 | |
283 | 283 | #define RLWINM OPCD(21) |
284 | 284 | |
285 | -#define BCLR XO19(16) | |
285 | +#define BCLR XO19( 16) | |
286 | 286 | #define BCCTR XO19(528) |
287 | 287 | #define CRAND XO19(257) |
288 | +#define CRANDC XO19(129) | |
289 | +#define CRNAND XO19(225) | |
290 | +#define CROR XO19(449) | |
288 | 291 | |
289 | 292 | #define EXTSB XO31(954) |
290 | 293 | #define EXTSH XO31(922) |
... | ... | @@ -870,11 +873,9 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) |
870 | 873 | ppc_addi (s, reg, reg, val); |
871 | 874 | } |
872 | 875 | |
873 | -static void tcg_out_brcond(TCGContext *s, int cond, | |
874 | - TCGArg arg1, TCGArg arg2, int const_arg2, | |
875 | - int label_index) | |
876 | +static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, | |
877 | + int const_arg2, int cr) | |
876 | 878 | { |
877 | - TCGLabel *l = &s->labels[label_index]; | |
878 | 879 | int imm; |
879 | 880 | uint32_t op; |
880 | 881 | |
... | ... | @@ -930,7 +931,7 @@ static void tcg_out_brcond(TCGContext *s, int cond, |
930 | 931 | default: |
931 | 932 | tcg_abort (); |
932 | 933 | } |
933 | - op |= BF (7); | |
934 | + op |= BF (cr); | |
934 | 935 | |
935 | 936 | if (imm) |
936 | 937 | tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff)); |
... | ... | @@ -943,79 +944,79 @@ static void tcg_out_brcond(TCGContext *s, int cond, |
943 | 944 | tcg_out32 (s, op | RA (arg1) | RB (arg2)); |
944 | 945 | } |
945 | 946 | |
947 | +} | |
948 | + | |
949 | +static void tcg_out_bc (TCGContext *s, int bc, int label_index) | |
950 | +{ | |
951 | + TCGLabel *l = &s->labels[label_index]; | |
952 | + | |
946 | 953 | if (l->has_value) |
947 | - tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr, | |
948 | - l->u.value)); | |
954 | + tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value)); | |
949 | 955 | else { |
950 | 956 | uint16_t val = *(uint16_t *) &s->code_ptr[2]; |
951 | 957 | |
952 | 958 | /* Thanks to Andrzej Zaborowski */ |
953 | - tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc)); | |
959 | + tcg_out32 (s, bc | (val & 0xfffc)); | |
954 | 960 | tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0); |
955 | 961 | } |
956 | 962 | } |
957 | 963 | |
958 | -/* brcond2 is taken verbatim from i386 tcg-target */ | |
964 | +static void tcg_out_brcond (TCGContext *s, int cond, | |
965 | + TCGArg arg1, TCGArg arg2, int const_arg2, | |
966 | + int label_index) | |
967 | +{ | |
968 | + tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7); | |
969 | + tcg_out_bc (s, tcg_to_bc[cond], label_index); | |
970 | +} | |
971 | + | |
959 | 972 | /* XXX: we implement it at the target level to avoid having to |
960 | 973 | handle cross basic blocks temporaries */ |
961 | -static void tcg_out_brcond2(TCGContext *s, | |
962 | - const TCGArg *args, const int *const_args) | |
974 | +static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args, | |
975 | + const int *const_args) | |
963 | 976 | { |
964 | - int label_next; | |
965 | - label_next = gen_new_label(); | |
966 | - switch(args[4]) { | |
977 | + int cond = args[4], label_index = args[5], op; | |
978 | + struct { int bit1; int bit2; int cond2; } bits[] = { | |
979 | + [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT }, | |
980 | + [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT }, | |
981 | + [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT }, | |
982 | + [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT }, | |
983 | + [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU }, | |
984 | + [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU }, | |
985 | + [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU }, | |
986 | + [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU }, | |
987 | + }, *b = &bits[cond]; | |
988 | + | |
989 | + switch (cond) { | |
967 | 990 | case TCG_COND_EQ: |
968 | - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next); | |
969 | - tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]); | |
991 | + tcg_out_cmp (s, TCG_COND_EQ, args[0], args[2], const_args[2], 6); | |
992 | + tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 7); | |
993 | + tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); | |
970 | 994 | break; |
971 | 995 | case TCG_COND_NE: |
972 | - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]); | |
973 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]); | |
996 | + tcg_out_cmp (s, TCG_COND_NE, args[0], args[2], const_args[2], 6); | |
997 | + tcg_out_cmp (s, TCG_COND_NE, args[1], args[3], const_args[3], 7); | |
998 | + tcg_out32 (s, CRNAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); | |
974 | 999 | break; |
975 | 1000 | case TCG_COND_LT: |
976 | - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]); | |
977 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
978 | - tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2], args[5]); | |
979 | - break; | |
980 | 1001 | case TCG_COND_LE: |
981 | - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]); | |
982 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
983 | - tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2], args[5]); | |
984 | - break; | |
985 | 1002 | case TCG_COND_GT: |
986 | - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]); | |
987 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
988 | - tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2], args[5]); | |
989 | - break; | |
990 | 1003 | case TCG_COND_GE: |
991 | - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]); | |
992 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
993 | - tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2], args[5]); | |
994 | - break; | |
995 | 1004 | case TCG_COND_LTU: |
996 | - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); | |
997 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
998 | - tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]); | |
999 | - break; | |
1000 | 1005 | case TCG_COND_LEU: |
1001 | - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); | |
1002 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
1003 | - tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]); | |
1004 | - break; | |
1005 | 1006 | case TCG_COND_GTU: |
1006 | - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); | |
1007 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
1008 | - tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]); | |
1009 | - break; | |
1010 | 1007 | case TCG_COND_GEU: |
1011 | - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); | |
1012 | - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); | |
1013 | - tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]); | |
1008 | + op = (b->bit1 != b->bit2) ? CRANDC : CRAND; | |
1009 | + tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5); | |
1010 | + tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6); | |
1011 | + tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 7); | |
1012 | + tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2)); | |
1013 | + tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ)); | |
1014 | 1014 | break; |
1015 | 1015 | default: |
1016 | 1016 | tcg_abort(); |
1017 | 1017 | } |
1018 | - tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); | |
1018 | + | |
1019 | + tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), label_index); | |
1019 | 1020 | } |
1020 | 1021 | |
1021 | 1022 | static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, | ... | ... |