aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-01-17 09:57:15 -0800
committerRichard Henderson <rth@gcc.gnu.org>2011-01-17 09:57:15 -0800
commit2882702b64846a135c57cad5ca83dc781d19aad8 (patch)
treeb26e850edd0abaaf97ada13ad508b9fd2a8d820d
parent6f7310f2b450fa98642b4a8e76a52ea3837ee66c (diff)
downloadgcc-2882702b64846a135c57cad5ca83dc781d19aad8.zip
gcc-2882702b64846a135c57cad5ca83dc781d19aad8.tar.gz
gcc-2882702b64846a135c57cad5ca83dc781d19aad8.tar.bz2
rx: Split movsicc post-reload.
This will allow elimination of the compare. From-SVN: r168921
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/rx/rx.md107
2 files changed, 73 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a3d7e92..d32b89a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2011-01-17 Richard Henderson <rth@redhat.com>
+ * config/rx/rx.md (movsicc): Split after reload.
+ (*movsicc): Merge *movsieq and *movsine via match_operator.
+ (*stcc): New pattern.
+
* config/rx/rx.c (rx_float_compare_mode): Remove.
* config/rx/rx.h (rx_float_compare_mode): Remove.
* config/rx/rx.md (cstoresi4): Split after reload.
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index f9a7c02..4ffbfec 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -744,47 +744,78 @@
[(set (match_operand:SI 0 "register_operand")
(if_then_else:SI (match_operand:SI 1 "comparison_operator")
(match_operand:SI 2 "nonmemory_operand")
- (match_operand:SI 3 "immediate_operand")))
- (clobber (reg:CC CC_REG))])] ;; See cstoresi4
+ (match_operand:SI 3 "nonmemory_operand")))
+ (clobber (reg:CC CC_REG))])]
""
- {
- if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
- FAIL;
- if (! CONST_INT_P (operands[3]))
- FAIL;
- }
-)
+{
+ /* ??? Support other conditions via cstore into a temporary? */
+ if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
+ FAIL;
+ /* One operand must be a constant. */
+ if (!CONSTANT_P (operands[2]) && !CONSTANT_P (operands[3]))
+ FAIL;
+})
-(define_insn "*movsieq"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (if_then_else:SI (eq (match_operand:SI 3 "register_operand" "r,r,r")
- (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
- (match_operand:SI 1 "nonmemory_operand" "0,i,r")
- (match_operand:SI 2 "immediate_operand" "i,i,i")))
- (clobber (reg:CC CC_REG))] ;; See cstoresi4
- ""
- "@
- cmp\t%Q4, %Q3\n\tstnz\t%2, %0
- cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
- cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
- [(set_attr "length" "13,19,15")
- (set_attr "timings" "22,33,33")]
-)
+(define_insn_and_split "*movsicc"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (if_then_else:SI
+ (match_operator 5 "rx_z_comparison_operator"
+ [(match_operand:SI 3 "register_operand" "r,r")
+ (match_operand:SI 4 "rx_source_operand" "riQ,riQ")])
+ (match_operand:SI 1 "nonmemory_operand" "i,ri")
+ (match_operand:SI 2 "nonmemory_operand" "ri,i")))
+ (clobber (reg:CC CC_REG))]
+ "CONSTANT_P (operands[1]) || CONSTANT_P (operands[2])"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx x, flags, op0, op1, op2;
+ enum rtx_code cmp_code;
-(define_insn "*movsine"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r")
- (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
- (match_operand:SI 1 "nonmemory_operand" "0,i,r")
- (match_operand:SI 2 "immediate_operand" "i,i,i")))
- (clobber (reg:CC CC_REG))] ;; See cstoresi4
- ""
- "@
- cmp\t%Q4, %Q3\n\tstz\t%2, %0
- cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
- cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
- [(set_attr "length" "13,19,15")
- (set_attr "timings" "22,33,33")]
+ flags = gen_rtx_REG (CCmode, CC_REG);
+ x = gen_rtx_COMPARE (CCmode, operands[3], operands[4]);
+ emit_insn (gen_rtx_SET (VOIDmode, flags, x));
+
+ cmp_code = GET_CODE (operands[5]);
+ op0 = operands[0];
+ op1 = operands[1];
+ op2 = operands[2];
+
+ /* If OP2 is the constant, reverse the sense of the move. */
+ if (!CONSTANT_P (operands[1]))
+ {
+ x = op1, op1 = op2, op2 = x;
+ cmp_code = reverse_condition (cmp_code);
+ }
+
+ /* If OP2 does not match the output, copy it into place. We have allowed
+ these alternatives so that the destination can legitimately be one of
+ the comparison operands without increasing register pressure. */
+ if (!rtx_equal_p (op0, op2))
+ emit_move_insn (op0, op2);
+
+ x = gen_rtx_fmt_ee (cmp_code, VOIDmode, flags, const0_rtx);
+ x = gen_rtx_IF_THEN_ELSE (SImode, x, op1, op0);
+ emit_insn (gen_rtx_SET (VOIDmode, op0, x));
+ DONE;
+})
+
+(define_insn "*stcc"
+ [(set (match_operand:SI 0 "register_operand" "+r,r,r,r")
+ (if_then_else:SI
+ (match_operator 2 "rx_z_comparison_operator"
+ [(reg CC_REG) (const_int 0)])
+ (match_operand:SI 1 "immediate_operand" "Sint08,Sint16,Sint24,i")
+ (match_dup 0)))]
+ "reload_completed"
+{
+ if (GET_CODE (operands[2]) == EQ)
+ return "stz\t%1, %0";
+ else
+ return "stnz\t%1, %0";
+}
+ [(set_attr "length" "4,5,6,7")]
)
;; Arithmetic Instructions