diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-24 16:59:15 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-24 16:59:15 +0000 |
commit | d9b5adbbb56c81595198b63ba78323eb7e554c63 (patch) | |
tree | 6e029f556f05d3720f8de25266b46432c5c916c5 | |
parent | 18aeab2a8979a6018c1695ec24970f9725fc1f1e (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/rx/predicates.md | 4 | ||||
-rw-r--r-- | gcc/config/rx/rx-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/rx/rx.c | 62 | ||||
-rw-r--r-- | gcc/config/rx/rx.md | 169 |
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; }) |