summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-24 16:59:15 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-24 16:59:15 +0000
commitd9b5adbbb56c81595198b63ba78323eb7e554c63 (patch)
tree6e029f556f05d3720f8de25266b46432c5c916c5
parent18aeab2a8979a6018c1695ec24970f9725fc1f1e (diff)
downloadgcc-d9b5adbbb56c81595198b63ba78323eb7e554c63.tar.gz
rx: Uncomplicate fp comparisons.
It turns out that the middle-end will happily take care of doing the swapping and splitting of compound fp comparisons. No need for us to replicate that here. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169169 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rx/predicates.md4
-rw-r--r--gcc/config/rx/rx-protos.h1
-rw-r--r--gcc/config/rx/rx.c62
-rw-r--r--gcc/config/rx/rx.md169
5 files changed, 28 insertions, 221 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d13b6275975..26edfae1db0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2011-01-24 Richard Henderson <rth@redhat.com>
+
+ * config/rx/predicates.md (rx_fp_comparison_operator): Don't accept
+ compound unordered comparisons.
+ * config/rx/rx.c (rx_split_fp_compare): Remove.
+ * config/rx/rx-protos.h: Update.
+ * config/rx/rx.md (gcc_conds, rx_conds): Remove.
+ (cbranchsf4): Don't call rx_split_fp_compare.
+ (*cbranchsf4): Use rx_split_cbranch.
+ (*cmpsf): Don't accept "i" constraint.
+ (*conditional_branch): Only valid after reload.
+ (cstoresf4): Merge expander with insn. Don't call rx_split_fp_compare.
+
2011-01-24 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/47385
diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md
index 608fca5f925..77b3353ac3e 100644
--- a/gcc/config/rx/predicates.md
+++ b/gcc/config/rx/predicates.md
@@ -287,9 +287,9 @@
(match_code "eq,ne,lt,ge")
)
-;; GT, LE, UNLE, UNGT omitted due to operand swap required.
+;; GT and LE omitted due to operand swap required.
(define_predicate "rx_fp_comparison_operator"
- (match_code "eq,ne,lt,ge,ordered,unordered,uneq,unlt,unge,ltgt")
+ (match_code "eq,ne,lt,ge,ordered,unordered")
)
(define_predicate "rshift_operator"
diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h
index 3c3f2d47124..ad97c597675 100644
--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -39,7 +39,6 @@ extern bool rx_is_mode_dependent_addr (rtx);
extern bool rx_is_restricted_memory_address (rtx, Mmode);
extern void rx_notice_update_cc (rtx body, rtx insn);
extern void rx_split_cbranch (Mmode, Rcode, rtx, rtx, rtx);
-extern bool rx_split_fp_compare (Rcode, Rcode *, Rcode *);
extern Mmode rx_select_cc_mode (Rcode, rtx, rtx);
extern bool rx_match_ccmode (rtx, Mmode);
#endif
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 9855c625f4d..f2429b74d28 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2665,68 +2665,6 @@ rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y ATTRIBUTE_UNUSED)
return mode_from_flags (flags_from_code (cmp_code));
}
-/* Split the floating-point comparison IN into individual comparisons
- O1 and O2. O2 may be UNKNOWN if there is no second comparison.
- Return true iff the comparison operands must be swapped. */
-
-bool
-rx_split_fp_compare (enum rtx_code in, enum rtx_code *o1, enum rtx_code *o2)
-{
- enum rtx_code cmp1 = in, cmp2 = UNKNOWN;
- bool swap = false;
-
- switch (in)
- {
- case ORDERED:
- case UNORDERED:
- case LT:
- case GE:
- case EQ:
- case NE:
- break;
-
- case GT:
- case LE:
- cmp1 = swap_condition (cmp1);
- swap = true;
- break;
-
- case UNEQ:
- cmp1 = UNORDERED;
- cmp2 = EQ;
- break;
- case UNLT:
- cmp1 = UNORDERED;
- cmp2 = LT;
- break;
- case UNGE:
- cmp1 = UNORDERED;
- cmp2 = GE;
- break;
- case UNLE:
- cmp1 = UNORDERED;
- cmp2 = GT;
- swap = true;
- break;
- case UNGT:
- cmp1 = UNORDERED;
- cmp2 = LE;
- swap = true;
- break;
- case LTGT:
- cmp1 = ORDERED;
- cmp2 = NE;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- *o1 = cmp1;
- *o2 = cmp2;
- return swap;
-}
-
/* Split the conditional branch. Emit (COMPARE C1 C2) into CC_REG with
CC_MODE, and use that in branches based on that compare. */
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 11dc1f32ee8..9ab5f173bda 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -29,16 +29,6 @@
(define_mode_iterator register_modes
[(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
-
-;; Used to map RX condition names to GCC
-;; condition names for builtin instructions.
-(define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
- unge unlt uneq ltgt])
-(define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
- (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
- (leu "leu") (unge "pz") (unlt "n") (uneq "o")
- (ltgt "no")])
-
(define_constants
[
(SP_REG 0)
@@ -259,46 +249,20 @@
(define_expand "cbranchsf4"
[(set (pc)
(if_then_else
- (match_operator 0 "comparison_operator"
+ (match_operator 0 "rx_fp_comparison_operator"
[(match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "register_operand")])
- (label_ref (match_operand 3 ""))
+ (match_operand:SF 2 "rx_source_operand")])
+ (label_ref (match_operand 3 ""))
(pc)))]
"ALLOW_RX_FPU_INSNS"
-{
- enum rtx_code cmp1, cmp2;
-
- /* If the comparison needs swapping of operands, do that now.
- Do not split the comparison in two yet. */
- if (rx_split_fp_compare (GET_CODE (operands[0]), &cmp1, &cmp2))
- {
- rtx op1, op2;
-
- if (cmp2 != UNKNOWN)
- {
- gcc_assert (cmp1 == UNORDERED);
- if (cmp2 == GT)
- cmp1 = UNGT;
- else if (cmp2 == LE)
- cmp1 = UNLE;
- else
- gcc_unreachable ();
- }
-
- op1 = operands[2];
- op2 = operands[1];
- operands[0] = gen_rtx_fmt_ee (cmp1, VOIDmode, op1, op2);
- operands[1] = op1;
- operands[2] = op2;
- }
-})
+)
(define_insn_and_split "*cbranchsf4"
[(set (pc)
(if_then_else
(match_operator 3 "rx_fp_comparison_operator"
[(match_operand:SF 0 "register_operand" "r")
- (match_operand:SF 1 "rx_source_operand" "rFiQ")])
+ (match_operand:SF 1 "rx_source_operand" "rFQ")])
(match_operand 2 "label_ref_operand" "")
(pc)))]
"ALLOW_RX_FPU_INSNS"
@@ -306,46 +270,8 @@
"&& reload_completed"
[(const_int 0)]
{
- enum rtx_code cmp0, cmp1, cmp2;
- rtx flags, lab1, lab2, over, x;
- bool swap;
-
- cmp0 = GET_CODE (operands[3]);
- swap = rx_split_fp_compare (cmp0, &cmp1, &cmp2);
- gcc_assert (!swap);
-
- flags = gen_rtx_REG (CC_Fmode, CC_REG);
- x = gen_rtx_COMPARE (CC_Fmode, operands[0], operands[1]);
- x = gen_rtx_SET (VOIDmode, flags, x);
- emit_insn (x);
-
- over = NULL;
- lab1 = lab2 = operands[2];
-
- /* The one case of LTGT needs to be split into cmp1 && cmp2. */
- if (cmp0 == LTGT)
- {
- over = gen_label_rtx ();
- lab1 = gen_rtx_LABEL_REF (VOIDmode, over);
- cmp1 = reverse_condition_maybe_unordered (cmp1);
- }
-
- /* Otherwise we split into cmp1 || cmp2. */
- x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
- x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, lab1, pc_rtx);
- x = gen_rtx_SET (VOIDmode, pc_rtx, x);
- emit_jump_insn (x);
-
- if (cmp2 != UNKNOWN)
- {
- x = gen_rtx_fmt_ee (cmp2, VOIDmode, flags, const0_rtx);
- x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, lab2, pc_rtx);
- x = gen_rtx_SET (VOIDmode, pc_rtx, x);
- emit_jump_insn (x);
- }
-
- if (over)
- emit_label (over);
+ rx_split_cbranch (CC_Fmode, GET_CODE (operands[3]),
+ operands[0], operands[1], operands[2]);
DONE;
})
@@ -353,7 +279,7 @@
[(set (reg:CC_F CC_REG)
(compare:CC_F
(match_operand:SF 0 "register_operand" "r,r,r")
- (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
+ (match_operand:SF 1 "rx_source_operand" "r,F,Q")))]
"ALLOW_RX_FPU_INSNS && reload_completed"
"fcmp\t%1, %0"
[(set_attr "timings" "11,11,33")
@@ -369,7 +295,7 @@
[(reg CC_REG) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
- ""
+ "reload_completed"
"b%B1\t%0"
[(set_attr "length" "8") ;; This length is wrong, but it is
;; too hard to compute statically.
@@ -750,95 +676,26 @@
[(set_attr "length" "3")]
)
-(define_expand "cstoresf4"
- [(parallel [(set (match_operand:SI 0 "register_operand" "")
- (match_operator:SI 1 "comparison_operator"
- [(match_operand:SF 2 "register_operand" "")
- (match_operand:SF 3 "register_operand" "")]))
- (clobber (match_scratch:SI 4))])]
- "ALLOW_RX_FPU_INSNS"
-{
- enum rtx_code cmp1, cmp2;
-
- /* If the comparison needs swapping of operands, do that now.
- Do not split the comparison in two yet. */
- if (rx_split_fp_compare (GET_CODE (operands[1]), &cmp1, &cmp2))
- {
- rtx op2, op3;
-
- if (cmp2 != UNKNOWN)
- {
- gcc_assert (cmp1 == UNORDERED);
- if (cmp2 == GT)
- cmp1 = UNGT;
- else if (cmp2 == LE)
- cmp1 = UNLE;
- else
- gcc_unreachable ();
- }
-
- op2 = operands[3];
- op3 = operands[2];
- operands[0] = gen_rtx_fmt_ee (cmp1, VOIDmode, op2, op3);
- operands[2] = op2;
- operands[3] = op3;
- }
-})
-
-(define_insn_and_split "*cstoresf4"
+(define_insn_and_split "cstoresf4"
[(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 4 "rx_fp_comparison_operator"
+ (match_operator:SI 1 "rx_fp_comparison_operator"
[(match_operand:SF 2 "register_operand" "r")
- (match_operand:SF 3 "rx_source_operand" "rFiQ")]))
- (clobber (match_scratch:SI 1 "=r"))]
+ (match_operand:SF 3 "rx_source_operand" "rFQ")]))]
"ALLOW_RX_FPU_INSNS"
"#"
"reload_completed"
[(const_int 0)]
{
- enum rtx_code cmp0, cmp1, cmp2;
rtx flags, x;
- bool swap;
-
- cmp0 = GET_CODE (operands[4]);
- swap = rx_split_fp_compare (cmp0, &cmp1, &cmp2);
- gcc_assert (!swap);
flags = gen_rtx_REG (CC_Fmode, CC_REG);
x = gen_rtx_COMPARE (CC_Fmode, operands[2], operands[3]);
x = gen_rtx_SET (VOIDmode, flags, x);
emit_insn (x);
- x = gen_rtx_fmt_ee (cmp1, SImode, flags, const0_rtx);
+ x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx);
x = gen_rtx_SET (VOIDmode, operands[0], x);
emit_insn (x);
-
- if (cmp0 == LTGT)
- {
- /* The one case of LTGT needs to be split into ORDERED && NE. */
- x = gen_rtx_fmt_ee (EQ, VOIDmode, flags, const0_rtx);
- x = gen_rtx_IF_THEN_ELSE (SImode, x, const0_rtx, operands[0]);
- x = gen_rtx_SET (VOIDmode, operands[0], x);
- emit_insn (x);
- }
- else if (cmp2 == EQ || cmp2 == NE)
- {
- /* Oring the two flags can be performed with a movcc operation. */
- x = gen_rtx_fmt_ee (cmp2, VOIDmode, flags, const0_rtx);
- x = gen_rtx_IF_THEN_ELSE (SImode, x, const1_rtx, operands[0]);
- x = gen_rtx_SET (VOIDmode, operands[0], x);
- emit_insn (x);
- }
- else if (cmp2 != UNKNOWN)
- {
- /* We can't use movcc, but need to or in another compare.
- Do this by storing the second operation into the scratch. */
- x = gen_rtx_fmt_ee (cmp2, SImode, flags, const0_rtx);
- x = gen_rtx_SET (VOIDmode, operands[1], x);
- emit_insn (x);
-
- emit_insn (gen_iorsi3 (operands[0], operands[0], operands[1]));
- }
DONE;
})