From patchwork Fri Jan 21 17:30:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 79878 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E8BC2B70DA for ; Sat, 22 Jan 2011 05:09:52 +1100 (EST) Received: (qmail 14264 invoked by alias); 21 Jan 2011 18:09:50 -0000 Received: (qmail 14252 invoked by uid 22791); 21 Jan 2011 18:09:49 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 21 Jan 2011 18:09:34 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0LI9Vpn007459 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 21 Jan 2011 13:09:32 -0500 Received: from anchor.twiddle.home (ovpn-113-149.phx2.redhat.com [10.3.113.149]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0LHUaVO020621; Fri, 21 Jan 2011 12:30:36 -0500 Message-ID: <4D39C2BB.6000706@redhat.com> Date: Fri, 21 Jan 2011 09:30:35 -0800 From: Richard Henderson User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Thunderbird/3.1.7 MIME-Version: 1.0 To: nickc@redhat.com CC: Paolo Bonzini , gcc-patches@gcc.gnu.org Subject: Re: [PATCH 03/14] rx: Cleanup conditional branches. References: <1295021309-28608-1-git-send-email-rth@redhat.com> <1295021309-28608-4-git-send-email-rth@redhat.com> <4D355768.5090902@gnu.org> <4D36A540.2080602@gnu.org> <4D370FAC.2050802@redhat.com> <4D3714AD.3070108@gnu.org> In-Reply-To: <4D3714AD.3070108@gnu.org> X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On 01/19/2011 08:43 AM, Paolo Bonzini wrote: > On 01/19/2011 05:22 PM, Richard Henderson wrote: >> Consider all of this deleted, and rx_fp_compare_operator reduced to >> the bare essentials -- un/ordered + the non-swapping normal ops. > > I think you're getting everything else for free anyway (especially if you leave the non-swapping, native unordered ops in). > > Paolo This does in fact seem to work. Ok, Nick? r~ commit 9db9d735c88d95d5a414bfb382628cb7150e6cb2 Author: Richard Henderson Date: Thu Jan 20 07:24:13 2011 -0800 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. diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md index 608fca5..77b3353 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 3c3f2d4..ad97c59 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 c37ddcc..4474f70 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -2627,68 +2627,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 d8cd66d..0df92d6 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) @@ -258,46 +248,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" @@ -305,46 +269,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; }) @@ -352,7 +278,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") @@ -368,7 +294,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. @@ -739,95 +665,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[0]), &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; })