aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-05-12 09:43:48 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-05-12 09:43:48 +0000
commitf90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch)
tree06c940a96a184a178bfadd53e04213225655a68d /gcc/config/rs6000/rs6000.md
parentb7a0af68063c79655c561750e9863799bf846cae (diff)
downloadgcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.zip
gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.gz
gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.bz2
Merge cond-optab branch.
From-SVN: r147425
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md307
1 files changed, 67 insertions, 240 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index cc37d91..9d4a960 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -11897,262 +11897,90 @@
;; 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:GPR 0 "gpc_reg_operand" "")
- (match_operand:GPR 1 "reg_or_short_operand" "")))]
+;; insns, and branches.
+
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "rs6000_cbranch_operator"
+ [(match_operand:GPR 1 "gpc_reg_operand" "")
+ (match_operand:GPR 2 "reg_or_short_operand" "")]))
+ (use (match_operand 3 ""))]
""
"
{
- /* Take care of the possibility that operands[1] might be negative but
+ /* Take care of the possibility that operands[2] might be negative but
this might be a logical operation. That insn doesn't exist. */
- if (GET_CODE (operands[1]) == CONST_INT
- && INTVAL (operands[1]) < 0)
- operands[1] = force_reg (<MODE>mode, operands[1]);
-
- rs6000_compare_op0 = operands[0];
- rs6000_compare_op1 = operands[1];
- rs6000_compare_fp_p = 0;
- DONE;
-}")
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) < 0)
+ {
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
+ GET_MODE (operands[0]),
+ operands[1], operands[2]);
+ }
-(define_expand "cmp<mode>"
- [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "")
- (match_operand:FP 1 "gpc_reg_operand" "")))]
- ""
- "
-{
- rs6000_compare_op0 = operands[0];
- rs6000_compare_op1 = operands[1];
- rs6000_compare_fp_p = 1;
+ rs6000_emit_cbranch (<MODE>mode, operands);
DONE;
}")
-(define_expand "beq"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }")
-
-(define_expand "bne"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }")
-
-(define_expand "bge"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }")
-
-(define_expand "bgt"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }")
-
-(define_expand "ble"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }")
-
-(define_expand "blt"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }")
-
-(define_expand "bgeu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }")
-
-(define_expand "bgtu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }")
-
-(define_expand "bleu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }")
-
-(define_expand "bltu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }")
-
-(define_expand "bunordered"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "bordered"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
-
-(define_expand "buneq"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
-
-(define_expand "bunge"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
-
-(define_expand "bungt"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
-
-(define_expand "bunle"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
-
-(define_expand "bunlt"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
-
-(define_expand "bltgt"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
-
-;; For SNE, we would prefer that the xor/abs sequence be used for integers.
-;; For SEQ, likewise, except that comparisons with zero should be done
-;; with an scc insns. However, due to the order that combine see the
-;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
-;; the cases we don't want to handle.
-(define_expand "seq"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }")
-
-(define_expand "sne"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "rs6000_cbranch_operator"
+ [(match_operand:FP 1 "gpc_reg_operand" "")
+ (match_operand:FP 2 "gpc_reg_operand" "")]))
+ (use (match_operand 3 ""))]
""
"
{
- if (! rs6000_compare_fp_p)
- FAIL;
-
- rs6000_emit_sCOND (NE, operands[0]);
+ rs6000_emit_cbranch (<MODE>mode, operands);
DONE;
}")
-;; A >= 0 is best done the portable way for A an integer.
-(define_expand "sge"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "rs6000_cbranch_operator"
+ [(match_operand:GPR 2 "gpc_reg_operand" "")
+ (match_operand:GPR 3 "reg_or_short_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
""
"
{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
- FAIL;
-
- rs6000_emit_sCOND (GE, operands[0]);
- DONE;
-}")
+ /* Take care of the possibility that operands[3] might be negative but
+ this might be a logical operation. That insn doesn't exist. */
+ if (GET_CODE (operands[3]) == CONST_INT
+ && INTVAL (operands[3]) < 0)
+ {
+ operands[3] = force_reg (<MODE>mode, operands[3]);
+ operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
+ GET_MODE (operands[1]),
+ operands[2], operands[3]);
+ }
-;; A > 0 is best done using the portable sequence, so fail in that case.
-(define_expand "sgt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "
-{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
+ /* For SNE, we would prefer that the xor/abs sequence be used for integers.
+ For SEQ, likewise, except that comparisons with zero should be done
+ with an scc insns. However, due to the order that combine see the
+ resulting insns, we must, in fact, allow SEQ for integers. Fail in
+ the cases we don't want to handle or are best handled by portable
+ code. */
+ if (GET_CODE (operands[1]) == NE)
FAIL;
-
- rs6000_emit_sCOND (GT, operands[0]);
- DONE;
-}")
-
-;; A <= 0 is best done the portable way for A an integer.
-(define_expand "sle"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "
-{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
+ if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
+ && operands[3] == const0_rtx)
FAIL;
-
- rs6000_emit_sCOND (LE, operands[0]);
+ rs6000_emit_sCOND (<MODE>mode, operands);
DONE;
}")
-;; A < 0 is best done in the portable way for A an integer.
-(define_expand "slt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "rs6000_cbranch_operator"
+ [(match_operand:FP 2 "gpc_reg_operand" "")
+ (match_operand:FP 3 "gpc_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
""
"
{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
- FAIL;
-
- rs6000_emit_sCOND (LT, operands[0]);
+ rs6000_emit_sCOND (<MODE>mode, operands);
DONE;
}")
-(define_expand "sgeu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
-
-(define_expand "sgtu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
-
-(define_expand "sleu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
-
-(define_expand "sltu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
-
-(define_expand "sunordered"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "sordered"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
-
-(define_expand "suneq"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
-
-(define_expand "sunge"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
-
-(define_expand "sungt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
-
-(define_expand "sunle"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
-
-(define_expand "sunlt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
-
-(define_expand "sltgt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
(define_expand "stack_protect_set"
[(match_operand 0 "memory_operand" "")
@@ -12195,16 +12023,16 @@
(match_operand 2 "" "")]
""
{
+ rtx test, op0, op1;
#ifdef TARGET_THREAD_SSP_OFFSET
rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
operands[1] = gen_rtx_MEM (Pmode, addr);
#endif
- rs6000_compare_op0 = operands[0];
- rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
- UNSPEC_SP_TEST);
- rs6000_compare_fp_p = 0;
- emit_jump_insn (gen_beq (operands[2]));
+ op0 = operands[0];
+ op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
+ test = gen_rtx_EQ (VOIDmode, op0, op1);
+ emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
DONE;
})
@@ -14775,17 +14603,16 @@
"{t 31,0,0|trap}"
[(set_attr "type" "trap")])
-(define_expand "conditional_trap"
- [(trap_if (match_operator 0 "trap_comparison_operator"
- [(match_dup 2) (match_dup 3)])
- (match_operand 1 "const_int_operand" ""))]
+(define_expand "ctrap<mode>4"
+ [(trap_if (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:GPR 1 "register_operand")
+ (match_operand:GPR 2 "reg_or_short_operand")])
+ (match_operand 3 "zero_constant" ""))]
""
- "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
- operands[2] = rs6000_compare_op0;
- operands[3] = rs6000_compare_op1;")
+ "")
(define_insn ""
- [(trap_if (match_operator 0 "trap_comparison_operator"
+ [(trap_if (match_operator 0 "ordered_comparison_operator"
[(match_operand:GPR 1 "register_operand" "r")
(match_operand:GPR 2 "reg_or_short_operand" "rI")])
(const_int 0))]