This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[cond-optab] Convert spu
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 26 Mar 2009 04:35:51 -0400
- Subject: [cond-optab] Convert spu
The spu port is quite easy too, though long because there are quite a few
variations of cmp (now cbranch/cstore) patterns.
Paolo
2009-03-24 Paolo Bonzini <bonzini@gnu.org>
* config/spu/spu-protos.h (spu_emit_branch_or_set): Change second
argument to rtx.
* config/spu/spu.c (spu_compare_op0, spu_compare_op1): Remove.
(spu_emit_branch_or_set): Get code/op0/op1 from second argument.
Change spu_compare_op0/op1 to op0/op1 throughout. Get target
from operands[0] or operands[3] depending on is_set.
* config/spu/spu.h (spu_compare_op0, spu_compare_op1): Remove.
* config/spu/spu.md (cmp<mode:VQHSI>, cmp<mode:DTI>, cmp<mode:VSF>,
cmpdf, bCC), sCC: Remove.
(cbranch<mode:VQHSI>4, cbranch<mode:DTI>, cbranch<mode:VSF>4,
cbranchdf4, cstore<mode:VQHSI>4, cstore<mode:DTI>, cstore<mode:VSF>4,
cstoredf4): New.
(mov<mode>cc): Accept ordered_comparison_operator, adjust call to
spu_emit_branch_or_set.
Index: gcc/config/spu/spu-protos.h
===================================================================
--- gcc/config/spu/spu-protos.h (branch cond-optab)
+++ gcc/config/spu/spu-protos.h (working copy)
@@ -28,8 +28,7 @@ extern int valid_subreg (rtx op);
extern void spu_expand_extv (rtx * ops, int unsignedp);
extern void spu_expand_insv (rtx * ops);
extern int spu_expand_block_move (rtx * ops);
-extern void spu_emit_branch_or_set (int is_set, enum rtx_code code,
- rtx * operands);
+extern void spu_emit_branch_or_set (int is_set, rtx cmp, rtx * operands);
extern int spu_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx);
extern HOST_WIDE_INT const_double_to_hwint (rtx x);
extern rtx hwint_to_const_double (enum machine_mode mode, HOST_WIDE_INT v);
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c (branch cond-optab)
+++ gcc/config/spu/spu.c (working copy)
@@ -146,7 +146,6 @@ static void asm_file_start (void);
static unsigned int spu_section_type_flags (tree, const char *, int);
extern const char *reg_names[];
-rtx spu_compare_op0, spu_compare_op1;
/* Which instruction set architecture to use. */
int spu_arch;
@@ -777,41 +776,43 @@ int spu_comp_icode[12][3] = {
WORD_MODE, we can generate better code in most cases if we do it
ourselves. */
void
-spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
+spu_emit_branch_or_set (int is_set, rtx cmp, rtx operands[])
{
int reverse_compare = 0;
int reverse_test = 0;
rtx compare_result, eq_result;
rtx comp_rtx, eq_rtx;
- rtx target = operands[0];
enum machine_mode comp_mode;
enum machine_mode op_mode;
enum spu_comp_code scode, eq_code, ior_code;
+ enum rtx_code code = GET_CODE (cmp);
+ rtx op0 = XEXP (cmp, 0);
+ rtx op1 = XEXP (cmp, 1);
int index;
int eq_test = 0;
- /* When spu_compare_op1 is a CONST_INT change (X >= C) to (X > C-1),
+ /* When op1 is a CONST_INT change (X >= C) to (X > C-1),
and so on, to keep the constant in operand 1. */
- if (GET_CODE (spu_compare_op1) == CONST_INT)
+ if (GET_CODE (op1) == CONST_INT)
{
- HOST_WIDE_INT val = INTVAL (spu_compare_op1) - 1;
- if (trunc_int_for_mode (val, GET_MODE (spu_compare_op0)) == val)
+ HOST_WIDE_INT val = INTVAL (op1) - 1;
+ if (trunc_int_for_mode (val, GET_MODE (op0)) == val)
switch (code)
{
case GE:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = GT;
break;
case LT:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = LE;
break;
case GEU:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = GTU;
break;
case LTU:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = LEU;
break;
default:
@@ -820,7 +821,7 @@ spu_emit_branch_or_set (int is_set, enum
}
comp_mode = SImode;
- op_mode = GET_MODE (spu_compare_op0);
+ op_mode = GET_MODE (op0);
switch (code)
{
@@ -944,18 +945,18 @@ spu_emit_branch_or_set (int is_set, enum
abort ();
}
- if (GET_MODE (spu_compare_op1) == DFmode
+ if (GET_MODE (op1) == DFmode
&& (scode != SPU_GT && scode != SPU_EQ))
abort ();
- if (is_set == 0 && spu_compare_op1 == const0_rtx
- && (GET_MODE (spu_compare_op0) == SImode
- || GET_MODE (spu_compare_op0) == HImode) && scode == SPU_EQ)
+ if (is_set == 0 && op1 == const0_rtx
+ && (GET_MODE (op0) == SImode
+ || GET_MODE (op0) == HImode) && scode == SPU_EQ)
{
/* Don't need to set a register with the result when we are
comparing against zero and branching. */
reverse_test = !reverse_test;
- compare_result = spu_compare_op0;
+ compare_result = op0;
}
else
{
@@ -963,23 +964,22 @@ spu_emit_branch_or_set (int is_set, enum
if (reverse_compare)
{
- rtx t = spu_compare_op1;
- spu_compare_op1 = spu_compare_op0;
- spu_compare_op0 = t;
+ rtx t = op1;
+ op1 = op0;
+ op0 = t;
}
if (spu_comp_icode[index][scode] == 0)
abort ();
if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate)
- (spu_compare_op0, op_mode))
- spu_compare_op0 = force_reg (op_mode, spu_compare_op0);
+ (op0, op_mode))
+ op0 = force_reg (op_mode, op0);
if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate)
- (spu_compare_op1, op_mode))
- spu_compare_op1 = force_reg (op_mode, spu_compare_op1);
+ (op1, op_mode))
+ op1 = force_reg (op_mode, op1);
comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result,
- spu_compare_op0,
- spu_compare_op1);
+ op0, op1);
if (comp_rtx == 0)
abort ();
emit_insn (comp_rtx);
@@ -988,8 +988,7 @@ spu_emit_branch_or_set (int is_set, enum
{
eq_result = gen_reg_rtx (comp_mode);
eq_rtx = GEN_FCN (spu_comp_icode[index][eq_code]) (eq_result,
- spu_compare_op0,
- spu_compare_op1);
+ op0, op1);
if (eq_rtx == 0)
abort ();
emit_insn (eq_rtx);
@@ -1020,13 +1019,14 @@ spu_emit_branch_or_set (int is_set, enum
else
bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx);
- loc_ref = gen_rtx_LABEL_REF (VOIDmode, target);
+ loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
loc_ref, pc_rtx)));
}
else if (is_set == 2)
{
+ rtx target = operands[0];
int compare_size = GET_MODE_BITSIZE (comp_mode);
int target_size = GET_MODE_BITSIZE (GET_MODE (target));
enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0);
@@ -1061,6 +1061,7 @@ spu_emit_branch_or_set (int is_set, enum
}
else
{
+ rtx target = operands[0];
if (reverse_test)
emit_insn (gen_rtx_SET (VOIDmode, compare_result,
gen_rtx_NOT (comp_mode, compare_result)));
Index: gcc/config/spu/spu.h
===================================================================
--- gcc/config/spu/spu.h (branch cond-optab)
+++ gcc/config/spu/spu.h (working copy)
@@ -617,8 +617,3 @@ targetm.resolve_overloaded_builtin = spu
} \
} while (0)
-/* These are set by the cmp patterns and used while expanding
- conditional branches. */
-extern GTY(()) rtx spu_compare_op0;
-extern GTY(()) rtx spu_compare_op1;
-
Index: gcc/config/spu/spu.md
===================================================================
--- gcc/config/spu/spu.md (branch cond-optab)
+++ gcc/config/spu/spu.md (working copy)
@@ -3636,57 +3636,6 @@ selb\t%0,%4,%0,%3"
[(set_attr "type" "br")])
-;; Compare insns are next. Note that the spu has two types of compares,
-;; signed & unsigned, and one type of branch.
-;;
-;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
-;; insns, and branches. We store the operands of compares until we see
-;; how it is used.
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:VQHSI 0 "spu_reg_operand" "")
- (match_operand:VQHSI 1 "spu_nonmem_operand" "")))]
- ""
- {
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:DTI 0 "spu_reg_operand" "")
- (match_operand:DTI 1 "spu_reg_operand" "")))]
- ""
- {
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:VSF 0 "spu_reg_operand" "")
- (match_operand:VSF 1 "spu_reg_operand" "")))]
- ""
- {
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" "")))]
- ""
- "{
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
-}")
-
;; vector conditional compare patterns
(define_expand "vcond<mode>"
[(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
@@ -3725,108 +3674,72 @@ selb\t%0,%4,%0,%3"
;; branch on condition
-(define_expand "beq"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, EQ, operands); DONE; })
-
-(define_expand "bne"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:VQHSI 1 "spu_reg_operand" "")
+ (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
+ (use (match_operand 3 ""))]
+ ""
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
+
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DTI 1 "spu_reg_operand" "")
+ (match_operand:DTI 2 "spu_reg_operand" "")]))
+ (use (match_operand 3 ""))]
+ ""
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
+
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:VSF 1 "spu_reg_operand" "")
+ (match_operand:VSF 2 "spu_reg_operand" "")]))
+ (use (match_operand 3 ""))]
+ ""
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
+
+(define_expand "cbranchdf4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DF 1 "spu_reg_operand" "")
+ (match_operand:DF 2 "spu_reg_operand" "")]))
+ (use (match_operand 3 ""))]
""
- { spu_emit_branch_or_set (0, NE, operands); DONE; })
-
-(define_expand "bge"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, GE, operands); DONE; })
-
-(define_expand "bgt"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, GT, operands); DONE; })
-
-(define_expand "ble"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LE, operands); DONE; })
-
-(define_expand "blt"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LT, operands); DONE; })
-
-(define_expand "bgeu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, GEU, operands); DONE; })
-
-(define_expand "bgtu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, GTU, operands); DONE; })
-
-(define_expand "bleu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LEU, operands); DONE; })
-
-(define_expand "bltu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LTU, operands); DONE; })
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
;; set on condition
-(define_expand "seq"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, EQ, operands); DONE; })
-
-(define_expand "sne"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, NE, operands); DONE; })
-
-(define_expand "sgt"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, GT, operands); DONE; })
-
-(define_expand "slt"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, LT, operands); DONE; })
-
-(define_expand "sge"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, GE, operands); DONE; })
-
-(define_expand "sle"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, LE, operands); DONE; })
-
-(define_expand "sgtu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, GTU, operands); DONE; })
-
-(define_expand "sltu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, LTU, operands); DONE; })
-
-(define_expand "sgeu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, GEU, operands); DONE; })
-
-(define_expand "sleu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:VQHSI 2 "spu_reg_operand" "")
+ (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
+ ""
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
+
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:DTI 2 "spu_reg_operand" "")
+ (match_operand:DTI 3 "spu_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
+ ""
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
+
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:VSF 2 "spu_reg_operand" "")
+ (match_operand:VSF 3 "spu_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
+ ""
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
+
+(define_expand "cstoredf4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:DF 2 "spu_reg_operand" "")
+ (match_operand:DF 3 "spu_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
""
- { spu_emit_branch_or_set (1, LEU, operands); DONE; })
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
;; conditional move
@@ -3842,12 +3755,12 @@ selb\t%0,%4,%0,%3"
(define_expand "mov<mode>cc"
[(set (match_operand:ALL 0 "spu_reg_operand" "")
- (if_then_else:ALL (match_operand 1 "comparison_operator" "")
+ (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
(match_operand:ALL 2 "spu_reg_operand" "")
(match_operand:ALL 3 "spu_reg_operand" "")))]
""
{
- spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
+ spu_emit_branch_or_set(2, operands[1], operands);
DONE;
})