Commit c596defdb9507d9f98269e760616773e2acde371

Authored by malc
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,9 +282,12 @@ static int tcg_target_const_match(tcg_target_long val,
282 282
283 #define RLWINM OPCD(21) 283 #define RLWINM OPCD(21)
284 284
285 -#define BCLR XO19(16) 285 +#define BCLR XO19( 16)
286 #define BCCTR XO19(528) 286 #define BCCTR XO19(528)
287 #define CRAND XO19(257) 287 #define CRAND XO19(257)
  288 +#define CRANDC XO19(129)
  289 +#define CRNAND XO19(225)
  290 +#define CROR XO19(449)
288 291
289 #define EXTSB XO31(954) 292 #define EXTSB XO31(954)
290 #define EXTSH XO31(922) 293 #define EXTSH XO31(922)
@@ -870,11 +873,9 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) @@ -870,11 +873,9 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
870 ppc_addi (s, reg, reg, val); 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 int imm; 879 int imm;
879 uint32_t op; 880 uint32_t op;
880 881
@@ -930,7 +931,7 @@ static void tcg_out_brcond(TCGContext *s, int cond, @@ -930,7 +931,7 @@ static void tcg_out_brcond(TCGContext *s, int cond,
930 default: 931 default:
931 tcg_abort (); 932 tcg_abort ();
932 } 933 }
933 - op |= BF (7); 934 + op |= BF (cr);
934 935
935 if (imm) 936 if (imm)
936 tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff)); 937 tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
@@ -943,79 +944,79 @@ static void tcg_out_brcond(TCGContext *s, int cond, @@ -943,79 +944,79 @@ static void tcg_out_brcond(TCGContext *s, int cond,
943 tcg_out32 (s, op | RA (arg1) | RB (arg2)); 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 if (l->has_value) 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 else { 955 else {
950 uint16_t val = *(uint16_t *) &s->code_ptr[2]; 956 uint16_t val = *(uint16_t *) &s->code_ptr[2];
951 957
952 /* Thanks to Andrzej Zaborowski */ 958 /* Thanks to Andrzej Zaborowski */
953 - tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc)); 959 + tcg_out32 (s, bc | (val & 0xfffc));
954 tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0); 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 /* XXX: we implement it at the target level to avoid having to 972 /* XXX: we implement it at the target level to avoid having to
960 handle cross basic blocks temporaries */ 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 case TCG_COND_EQ: 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 break; 994 break;
971 case TCG_COND_NE: 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 break; 999 break;
975 case TCG_COND_LT: 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 case TCG_COND_LE: 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 case TCG_COND_GT: 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 case TCG_COND_GE: 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 case TCG_COND_LTU: 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 case TCG_COND_LEU: 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 case TCG_COND_GTU: 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 case TCG_COND_GEU: 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 break; 1014 break;
1015 default: 1015 default:
1016 tcg_abort(); 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 static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, 1022 static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,