From patchwork Mon Dec 8 14:18:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Segher Boessenkool X-Patchwork-Id: 418713 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 73A811400DD for ; Tue, 9 Dec 2014 01:48:51 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; q=dns; s=default; b=ikrXeGaXR+lOXyFASYz hqbjvEAPUxkZx7FdvkqjPuuGx2IS4a8C1vCpaeExCjreXMcrzr8fp+zKiYa4q66v ntNBQfjLZNgoAR27mBGggF6WjCOReTR5MRBfqji8J3kNWsYsjuzIwZITCQHMYEXF 6g0rxnYubkNVICsQZS6Jx73o= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; s=default; bh=tpvLUZC3++ZO8hEsorHfQtjjw 9g=; b=NuldaNQIWaYVjkLN3ilD+j/TF4V/VcCpEaK+pec4lAzTzVhsll9eNfMUa MBkWHNoM47AQMDVop6DF/1YIBLFiETdVhw5P+UEKACVDJIya164l5++6H7Yvq+g+ GNev+PcnksEjUFLwU58deR/0AzSbnqJkwn9yy2dh1H9UMMNSv0= Received: (qmail 26618 invoked by alias); 8 Dec 2014 14:47:35 -0000 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 Received: (qmail 26511 invoked by uid 89); 8 Dec 2014 14:47:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: gcc1-power7.osuosl.org Received: from gcc1-power7.osuosl.org (HELO gcc1-power7.osuosl.org) (140.211.15.137) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 08 Dec 2014 14:47:26 +0000 Received: from gcc1-power7.osuosl.org (localhost [127.0.0.1]) by gcc1-power7.osuosl.org (8.14.6/8.14.6) with ESMTP id sB8EIMLJ033093; Mon, 8 Dec 2014 06:18:22 -0800 Received: (from segher@localhost) by gcc1-power7.osuosl.org (8.14.6/8.14.6/Submit) id sB8EIM55033061; Mon, 8 Dec 2014 06:18:22 -0800 From: Segher Boessenkool To: gcc-patches@gcc.gnu.org Cc: dje.gcc@gmail.com, Segher Boessenkool Subject: [PATCH 07/10] rs6000: The big carry insns addition Date: Mon, 8 Dec 2014 06:18:08 -0800 Message-Id: <55e7b78d51351112a42280ce15596cf9b743e2e2.1418024189.git.segher@kernel.crashing.org> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes Now that everything is in place for letting GCC use the carry-using and carry-producing machine insns as separate RTL insns, switch over all remaining patterns that clobber CA without telling the compiler. This are the multiple-precision add/sub/neg patterns, and the various eq/ne/ ltu/gtu/leu/geu patterns. The eq/ne patterns are special. The optimal machine code for those isn't regular (like e.g. the ltu patterns are), and we want to implement a plain eq as "cntlz[wd];sr[wd]i"; but that means that if we split those patterns at expand time, combine will happily put them back together again. So expand them as eq/ne, and split later. 2014-12-08 Segher Boessenkool gcc/ PR target/64180 * config/rs6000/predicates.md (unsigned_comparison_operator): New. (signed_comparison_operator): New. * config/rs6000/rs6000-protos.h (rs6000_emit_eqne): Declare. * config/rs6000/rs6000.c (rs6000_emit_eqne): New function. (rs6000_emit_sCOND): Remove ISEL test (move it to the expander). * config/rs6000/rs6000.md (add3 for SDI): Expand DImode add to addc,adde directly, if !TARGET_POWERPC64. (sub3 for SDI): Expand DImode sub to subfc,subfe directly, if !TARGET_POWERPC64. (neg2): Delete expander. (*neg2): Rename to "neg2". (addti3, subti3): Delete. (addti3, subti3): New expanders. (*adddi3_noppc64, *subdi3_noppc64, *negdi2_noppc64): Delete. (cstore4_unsigned): New expander. (cstore4): Allow GPR as output (not just SI). Rewrite. (cstore4 for FP): Remove superfluous quotes. (*eq, *eq_compare, *plus_eqsi and splitter, *compare_plus_eqsi and splitter, *plus_eqsi_compare and splitter, *neg_eq0, *neg_eq, *ne0_, plus_ne0_, compare_plus_ne0_ and splitter, *compare_plus_ne0__1 and splitter, *plus_ne0__compare and splitter, *leu, *leu_compare and splitter, *plus_leu, *neg_leu, *and_neg_leu, *ltu, *ltu_compare, *plus_ltu, *plus_ltu_1, *plus_ltucompare, *neg_ltu, *geu, *geu_compare and splitter, *plus_geu, *neg_geu, *and_neg_geu, *plus_gt0, *gtu, *gtu_compare, *plus_gtu, *plus_gtu_1, *plus_gtu_compare, *neg_gtu, 12 anonymous insns, and 12 anonymous splitters): Delete. (eq3, ne3): New. (*neg_eq_, *neg_ne_): New. (*plus_eq_, *plus_ne_): New. (*minus_eq_, *minus_ne_): New. --- gcc/config/rs6000/predicates.md | 8 + gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 27 +- gcc/config/rs6000/rs6000.md | 1559 +++++++++---------------------------- 4 files changed, 400 insertions(+), 1195 deletions(-) diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index a19cb2f..8b68f9c 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1240,6 +1240,14 @@ (define_predicate "rs6000_cbranch_operator" (match_code ("unlt,unle,ungt,unge")))) (match_operand 0 "comparison_operator"))) +;; Return 1 if OP is an unsigned comparison operator. +(define_predicate "unsigned_comparison_operator" + (match_code "ltu,gtu,leu,geu")) + +;; Return 1 if OP is a signed comparison operator. +(define_predicate "signed_comparison_operator" + (match_code "lt,gt,le,ge")) + ;; Return 1 if OP is a comparison operation that is valid for an SCC insn -- ;; it must be a positive comparison. (define_predicate "scc_comparison_operator" diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 8d27a69..eb64598 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -109,6 +109,7 @@ extern void print_operand (FILE *, rtx, int); extern void print_operand_address (FILE *, rtx); extern enum rtx_code rs6000_reverse_condition (machine_mode, enum rtx_code); +extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); extern void rs6000_emit_sISEL (machine_mode, rtx[]); extern void rs6000_emit_sCOND (machine_mode, rtx[]); extern void rs6000_emit_cbranch (machine_mode, rtx[]); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index e58fc81..f60f4d7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -19421,6 +19421,27 @@ rs6000_emit_sISEL (machine_mode mode ATTRIBUTE_UNUSED, rtx operands[]) rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); } +/* Emit RTL that sets a register to zero if OP1 and OP2 are equal. SCRATCH + can be used as that dest register. Return the dest register. */ + +rtx +rs6000_emit_eqne (machine_mode mode, rtx op1, rtx op2, rtx scratch) +{ + if (op2 == const0_rtx) + return op1; + + if (GET_CODE (scratch) == SCRATCH) + scratch = gen_reg_rtx (mode); + + if (logical_operand (op2, mode)) + emit_insn (gen_rtx_SET (VOIDmode, scratch, gen_rtx_XOR (mode, op1, op2))); + else + emit_insn (gen_rtx_SET (VOIDmode, scratch, + gen_rtx_PLUS (mode, op1, negate_rtx (mode, op2)))); + + return scratch; +} + void rs6000_emit_sCOND (machine_mode mode, rtx operands[]) { @@ -19429,12 +19450,6 @@ rs6000_emit_sCOND (machine_mode mode, rtx operands[]) enum rtx_code cond_code; rtx result = operands[0]; - if (TARGET_ISEL && (mode == SImode || mode == DImode)) - { - rs6000_emit_sISEL (mode, operands); - return; - } - condition_rtx = rs6000_generate_compare (operands[1], mode); cond_code = GET_CODE (condition_rtx); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index e23fadb..eb15fff 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1463,13 +1463,26 @@ (define_expand "add3" (match_operand:SDI 2 "reg_or_add_cint_operand" "")))] "" { - if (mode == DImode && ! TARGET_POWERPC64) + if (mode == DImode && !TARGET_POWERPC64) { - if (non_short_cint_operand (operands[2], DImode)) - FAIL; + rtx lo0 = gen_lowpart (SImode, operands[0]); + rtx lo1 = gen_lowpart (SImode, operands[1]); + rtx lo2 = gen_lowpart (SImode, operands[2]); + rtx hi0 = gen_highpart (SImode, operands[0]); + rtx hi1 = gen_highpart (SImode, operands[1]); + rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]); + + if (!reg_or_short_operand (lo2, SImode)) + lo2 = force_reg (SImode, lo2); + if (!adde_operand (hi2, SImode)) + hi2 = force_reg (SImode, hi2); + + emit_insn (gen_addsi3_carry (lo0, lo1, lo2)); + emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2)); + DONE; } - else if (GET_CODE (operands[2]) == CONST_INT - && ! add_operand (operands[2], mode)) + + if (CONST_INT_P (operands[2]) && !add_operand (operands[2], mode)) { rtx tmp = ((!can_create_pseudo_p () || rtx_equal_p (operands[0], operands[1])) @@ -1790,8 +1803,26 @@ (define_expand "sub3" (match_operand:SDI 2 "gpc_reg_operand" "")))] "" { - if (short_cint_operand (operands[1], mode) - && !(mode == DImode && !TARGET_POWERPC64)) + if (mode == DImode && !TARGET_POWERPC64) + { + rtx lo0 = gen_lowpart (SImode, operands[0]); + rtx lo1 = gen_lowpart (SImode, operands[1]); + rtx lo2 = gen_lowpart (SImode, operands[2]); + rtx hi0 = gen_highpart (SImode, operands[0]); + rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]); + rtx hi2 = gen_highpart (SImode, operands[2]); + + if (!reg_or_short_operand (lo1, SImode)) + lo1 = force_reg (SImode, lo1); + if (!adde_operand (hi1, SImode)) + hi1 = force_reg (SImode, hi1); + + emit_insn (gen_subfsi3_carry (lo0, lo2, lo1)); + emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1)); + DONE; + } + + if (short_cint_operand (operands[1], mode)) { emit_insn (gen_subf3_imm (operands[0], operands[2], operands[1])); DONE; @@ -1934,13 +1965,7 @@ (define_insn "subf3_carry_in_xx" [(set_attr "type" "add")]) -(define_expand "neg2" - [(set (match_operand:SDI 0 "gpc_reg_operand" "") - (neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "*neg2" +(define_insn "neg2" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] "" @@ -6455,99 +6480,51 @@ (define_insn_and_split "*floatunsdisf2_mem" ;; (for example, having an input in 7,8 and an output in 6,7). We ;; also allow for the output being the same as one of the inputs. -(define_insn "addti3" - [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r") - (plus:TI (match_operand:TI 1 "gpc_reg_operand" "%r,r,0,0") - (match_operand:TI 2 "reg_or_short_operand" "r,I,r,I")))] - "TARGET_64BIT" -{ - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[2])) != CONST_INT - ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\" - : \"addic %L0,%L1,%2\;add%G2e %0,%1\"; - else - return (GET_CODE (operands[2])) != CONST_INT - ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\" - : \"addic %0,%1,%2\;add%G2e %L0,%L1\"; -} - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "subti3" - [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r,r") - (minus:TI (match_operand:TI 1 "reg_or_short_operand" "r,I,0,r,I") - (match_operand:TI 2 "gpc_reg_operand" "r,r,r,0,0")))] +(define_expand "addti3" + [(set (match_operand:TI 0 "gpc_reg_operand" "") + (plus:TI (match_operand:TI 1 "gpc_reg_operand" "") + (match_operand:TI 2 "reg_or_short_operand" "")))] "TARGET_64BIT" { - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[1]) != CONST_INT) - ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\" - : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\"; - else - return (GET_CODE (operands[1]) != CONST_INT) - ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\" - : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\"; -} - [(set_attr "type" "two") - (set_attr "length" "8")]) + rtx lo0 = gen_lowpart (DImode, operands[0]); + rtx lo1 = gen_lowpart (DImode, operands[1]); + rtx lo2 = gen_lowpart (DImode, operands[2]); + rtx hi0 = gen_highpart (DImode, operands[0]); + rtx hi1 = gen_highpart (DImode, operands[1]); + rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); + if (!reg_or_short_operand (lo2, DImode)) + lo2 = force_reg (DImode, lo2); + if (!adde_operand (hi2, DImode)) + hi2 = force_reg (DImode, hi2); -;; Define the DImode operations that can be done in a small number -;; of instructions. The & constraints are to prevent the register -;; allocator from allocating registers that overlap with the inputs -;; (for example, having an input in 7,8 and an output in 6,7). We -;; also allow for the output being the same as one of the inputs. + emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); + emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); + DONE; +}) -(define_insn "*adddi3_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))] - "! TARGET_POWERPC64" - "* +(define_expand "subti3" + [(set (match_operand:TI 0 "gpc_reg_operand" "") + (minus:TI (match_operand:TI 1 "reg_or_short_operand" "") + (match_operand:TI 2 "gpc_reg_operand" "")))] + "TARGET_64BIT" { - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[2])) != CONST_INT - ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\" - : \"addic %L0,%L1,%2\;add%G2e %0,%1\"; - else - return (GET_CODE (operands[2])) != CONST_INT - ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\" - : \"addic %0,%1,%2\;add%G2e %L0,%L1\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) + rtx lo0 = gen_lowpart (DImode, operands[0]); + rtx lo1 = gen_lowpart (DImode, operands[1]); + rtx lo2 = gen_lowpart (DImode, operands[2]); + rtx hi0 = gen_highpart (DImode, operands[0]); + rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); + rtx hi2 = gen_highpart (DImode, operands[2]); -(define_insn "*subdi3_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I") - (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))] - "! TARGET_POWERPC64" - "* -{ - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[1]) != CONST_INT) - ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\" - : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\"; - else - return (GET_CODE (operands[1]) != CONST_INT) - ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\" - : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) + if (!reg_or_short_operand (lo1, DImode)) + lo1 = force_reg (DImode, lo1); + if (!adde_operand (hi1, DImode)) + hi1 = force_reg (DImode, hi1); -(define_insn "*negdi2_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"subfic %L0,%L1,0\;subfze %0,%1\" - : \"subfic %0,%1,0\;subfze %L0,%L1\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) + emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); + emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); + DONE; +}) ;; Shift by a variable amount is too complex to be worth open-coding. We @@ -11745,40 +11722,89 @@ (define_expand "cbranch4" DONE; }") +(define_expand "cstore4_unsigned" + [(use (match_operator 1 "unsigned_comparison_operator" + [(match_operand:P 2 "gpc_reg_operand" "") + (match_operand:P 3 "reg_or_short_operand" "")])) + (clobber (match_operand:P 0 "register_operand"))] + "" +{ + enum rtx_code cond_code = GET_CODE (operands[1]); + + rtx op0 = operands[0]; + rtx op1 = operands[2]; + rtx op2 = operands[3]; + + if (cond_code == GEU || cond_code == LTU) + { + cond_code = swap_condition (cond_code); + op1 = operands[3]; + op2 = operands[2]; + } + + if (!gpc_reg_operand (op1, mode)) + op1 = force_reg (mode, op1); + if (!reg_or_short_operand (op2, mode)) + op2 = force_reg (mode, op2); + + rtx tmp = gen_reg_rtx (mode); + rtx tmp2 = gen_reg_rtx (mode); + + emit_insn (gen_subf3_carry (tmp, op1, op2)); + emit_insn (gen_subf3_carry_in_xx (tmp2)); + + if (cond_code == LEU) + emit_insn (gen_add3 (op0, tmp2, const1_rtx)); + else + emit_insn (gen_neg2 (op0, tmp2)); + + DONE; +}) + (define_expand "cstore4" [(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"))] + (clobber (match_operand:GPR 0 "register_operand"))] "" - " { - /* 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) + /* Use ISEL if the user asked for it. */ + if (TARGET_ISEL) + rs6000_emit_sISEL (mode, operands); + + /* Expanding EQ and NE directly to some machine instructions does not help + but does hurt combine. So don't. */ + else if (GET_CODE (operands[1]) == EQ) + emit_insn (gen_eq3 (operands[0], operands[2], operands[3])); + else if (mode == Pmode + && GET_CODE (operands[1]) == NE) + emit_insn (gen_ne3 (operands[0], operands[2], operands[3])); + else if (GET_CODE (operands[1]) == NE) { - operands[3] = force_reg (mode, operands[3]); - operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), - GET_MODE (operands[1]), - operands[2], operands[3]); + rtx tmp = gen_reg_rtx (mode); + emit_insn (gen_eq3 (tmp, operands[2], operands[3])); + emit_insn (gen_xor3 (operands[0], tmp, const1_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) + /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu + etc. combinations magically work out just right. */ + else if (mode == Pmode + && unsigned_comparison_operator (operands[1], VOIDmode)) + emit_insn (gen_cstore4_unsigned (operands[0], operands[1], + operands[2], operands[3])); + + /* The generic code knows tricks to compute signed comparisons against + zero. Let it do its thing. */ + else if (operands[3] == const0_rtx + && signed_comparison_operator (operands[1], VOIDmode)) FAIL; - 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 (mode, operands); + + /* Everything else, use the mfcr brute force. */ + else + rs6000_emit_sCOND (mode, operands); + DONE; -}") +}) (define_expand "cstore4" [(use (match_operator 1 "rs6000_cbranch_operator" @@ -11786,11 +11812,10 @@ (define_expand "cstore4" (match_operand:FP 3 "gpc_reg_operand" "")])) (clobber (match_operand:SI 0 "register_operand"))] "" - " { rs6000_emit_sCOND (mode, operands); DONE; -}") +}) (define_expand "stack_protect_set" @@ -12262,1109 +12287,265 @@ (define_peephole [(set_attr "type" "mfcr") (set_attr "length" "12")]) -;; There are some scc insns that can be done directly, without a compare. -;; These are faster because they don't involve the communications between -;; the FXU and branch units. In fact, we will be replacing all of the -;; integer scc insns here or in the portable methods in emit_store_flag. -;; -;; Also support (neg (scc ..)) since that construct is used to replace -;; branches, (plus (scc ..) ..) since that construct is common and -;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the -;; cases where it is no more expensive than (neg (scc ..)). - -;; Have reload force a constant into a register for the simple insns that -;; otherwise won't accept constants. We do this because it is faster than -;; the cmp/mfcr sequence we would otherwise generate. (define_mode_attr scc_eq_op2 [(SI "rKLI") (DI "rKJI")]) -(define_insn_and_split "*eq" +(define_insn_and_split "eq3" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "scc_eq_operand" "")))] + (match_operand:GPR 2 "scc_eq_operand" ""))) + (clobber (match_scratch:GPR 3 "=r")) + (clobber (match_scratch:GPR 4 "=r"))] "" "#" "" - [(set (match_dup 0) + [(set (match_dup 4) (clz:GPR (match_dup 3))) (set (match_dup 0) - (lshiftrt:GPR (match_dup 0) (match_dup 4)))] - { - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) - { - /* Use output operand as intermediate. */ - operands[3] = operands[0]; - - if (logical_operand (operands[2], mode)) - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_XOR (mode, - operands[1], operands[2]))); - else - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_PLUS (mode, operands[1], - negate_rtx (mode, - operands[2])))); - } - else - operands[3] = operands[1]; - - operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (mode))); - }) - -(define_insn_and_split "*eq_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=y") - (compare:CC - (eq:P (match_operand:P 1 "gpc_reg_operand" "=r") - (match_operand:P 2 "scc_eq_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r") - (eq:P (match_dup 1) (match_dup 2)))] - "optimize_size" - "#" - "optimize_size" - [(set (match_dup 0) - (clz:P (match_dup 4))) - (parallel [(set (match_dup 3) - (compare:CC (lshiftrt:P (match_dup 0) (match_dup 5)) - (const_int 0))) - (set (match_dup 0) - (lshiftrt:P (match_dup 0) (match_dup 5)))])] - { - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) - { - /* Use output operand as intermediate. */ - operands[4] = operands[0]; - - if (logical_operand (operands[2], mode)) - emit_insn (gen_rtx_SET (VOIDmode, operands[4], - gen_rtx_XOR (mode, - operands[1], operands[2]))); - else - emit_insn (gen_rtx_SET (VOIDmode, operands[4], - gen_rtx_PLUS (mode, operands[1], - negate_rtx (mode, - operands[2])))); - } - else - operands[4] = operands[1]; - - operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (mode))); - }) - -;; We have insns of the form shown by the first define_insn below. If -;; there is something inside the comparison operation, we must split it. -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operator 1 "comparison_operator" - [(match_operand:SI 2 "" "") - (match_operand:SI 3 - "reg_or_cint_operand" "")]) - (match_operand:SI 4 "gpc_reg_operand" ""))) - (clobber (match_operand:SI 5 "register_operand" ""))] - "! gpc_reg_operand (operands[2], SImode)" - [(set (match_dup 5) (match_dup 2)) - (set (match_dup 0) (plus:SI (match_op_dup 1 [(match_dup 5) (match_dup 3)]) - (match_dup 4)))]) - -(define_insn "*plus_eqsi" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r") - (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))] - "TARGET_32BIT" - "@ - xor %0,%1,%2\;subfic %0,%0,0\;addze %0,%3 - subfic %0,%1,0\;addze %0,%3 - xori %0,%1,%b2\;subfic %0,%0,0\;addze %0,%3 - xoris %0,%1,%u2\;subfic %0,%0,0\;addze %0,%3 - subfic %0,%1,%2\;subfic %0,%0,0\;addze %0,%3" - [(set_attr "type" "three,two,three,three,three") - (set_attr "length" "12,8,12,12,12")]) + (lshiftrt:GPR (match_dup 4) + (match_dup 5)))] +{ + operands[3] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[3]); -(define_insn "*compare_plus_eqsi" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))] - "TARGET_32BIT && optimize_size" - "@ - xor %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3 - subfic %4,%1,0\;addze. %4,%3 - xori %4,%1,%b2\;subfic %4,%4,0\;addze. %4,%3 - xoris %4,%1,%u2\;subfic %4,%4,0\;addze. %4,%3 - subfic %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3 - # - # - # - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) + if (GET_CODE (operands[4]) == SCRATCH) + operands[4] = gen_reg_rtx (mode); -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "scc_eq_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && optimize_size && reload_completed" - [(set (match_dup 4) - (plus:SI (eq:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") + operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (mode))); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) -(define_insn "*plus_eqsi_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r") - (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_32BIT && optimize_size" - "@ - xor %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3 - subfic %0,%1,0\;addze. %0,%3 - xori %0,%1,%b2\;subfic %0,%0,0\;addze. %0,%3 - xoris %0,%1,%u2\;subfic %0,%0,0\;addze. %0,%3 - subfic %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3 - # - # - # - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) +(define_insn_and_split "ne3" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (ne:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "scc_eq_operand" ""))) + (clobber (match_scratch:P 3 "=r")) + (clobber (match_scratch:P 4 "=r")) + (clobber (reg:P CA_REGNO))] + "!TARGET_ISEL" + "#" + "" + [(parallel [(set (match_dup 4) + (plus:P (match_dup 3) + (const_int -1))) + (set (reg:P CA_REGNO) + (ne:P (match_dup 3) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (plus:P (not:P (match_dup 4)) + (reg:P CA_REGNO)) + (match_dup 3))) + (clobber (reg:P CA_REGNO))])] +{ + operands[3] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[3]); -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "scc_eq_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_32BIT && optimize_size && reload_completed" - [(set (match_dup 0) - (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") + if (GET_CODE (operands[4]) == SCRATCH) + operands[4] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) -(define_insn "*neg_eq0" +(define_insn_and_split "*neg_eq_" [(set (match_operand:P 0 "gpc_reg_operand" "=r") (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0))))] + (match_operand:P 2 "scc_eq_operand" "")))) + (clobber (match_scratch:P 3 "=r")) + (clobber (match_scratch:P 4 "=r")) + (clobber (reg:P CA_REGNO))] "" - "addic %0,%1,-1\;subfe %0,%0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) + "#" + "" + [(parallel [(set (match_dup 4) + (plus:P (match_dup 3) + (const_int -1))) + (set (reg:P CA_REGNO) + (ne:P (match_dup 3) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (reg:P CA_REGNO) + (const_int -1))) + (clobber (reg:P CA_REGNO))])] +{ + operands[3] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[3]); -(define_insn_and_split "*neg_eq" + if (GET_CODE (operands[4]) == SCRATCH) + operands[4] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) + +(define_insn_and_split "*neg_ne_" [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "%r") - (match_operand:P 2 "scc_eq_operand" ""))))] + (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "scc_eq_operand" "")))) + (clobber (match_scratch:P 3 "=r")) + (clobber (match_scratch:P 4 "=r")) + (clobber (reg:P CA_REGNO))] "" "#" "" - [(set (match_dup 0) (neg:P (eq:P (match_dup 3) (const_int 0))))] - { - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) - { - /* Use output operand as intermediate. */ - operands[3] = operands[0]; - - if (logical_operand (operands[2], mode)) - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_XOR (mode, - operands[1], operands[2]))); - else - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_PLUS (mode, operands[1], - negate_rtx (mode, - operands[2])))); - } - else - operands[3] = operands[1]; - }) + [(parallel [(set (match_dup 4) + (neg:P (match_dup 3))) + (set (reg:P CA_REGNO) + (eq:P (match_dup 3) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (reg:P CA_REGNO) + (const_int -1))) + (clobber (reg:P CA_REGNO))])] +{ + operands[3] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[3]); + + if (GET_CODE (operands[4]) == SCRATCH) + operands[4] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) -(define_insn "*ne0_" +(define_insn_and_split "*plus_eq_" [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (ne:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0))) - (clobber (match_scratch:P 2 "=&r"))] - "!(TARGET_32BIT && TARGET_ISEL)" - "addic %2,%1,-1\;subfe %0,%2,%1" - [(set_attr "type" "two") - (set_attr "length" "8")]) + (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "scc_eq_operand" "")) + (match_operand:P 3 "gpc_reg_operand" "r"))) + (clobber (match_scratch:P 4 "=r")) + (clobber (match_scratch:P 5 "=r")) + (clobber (reg:P CA_REGNO))] + "" + "#" + "" + [(parallel [(set (match_dup 5) + (neg:P (match_dup 4))) + (set (reg:P CA_REGNO) + (eq:P (match_dup 4) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (match_dup 3) + (reg:P CA_REGNO))) + (clobber (reg:P CA_REGNO))])] +{ + operands[4] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[4]); + + if (GET_CODE (operands[5]) == SCRATCH) + operands[5] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) -(define_insn "*plus_ne0_" +(define_insn_and_split "*plus_ne_" [(set (match_operand:P 0 "gpc_reg_operand" "=r") (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:P 3 "=&r"))] + (match_operand:P 2 "scc_eq_operand" "")) + (match_operand:P 3 "gpc_reg_operand" "r"))) + (clobber (match_scratch:P 4 "=r")) + (clobber (match_scratch:P 5 "=r")) + (clobber (reg:P CA_REGNO))] "" - "addic %3,%1,-1\;addze %0,%2" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*compare_plus_ne0_" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:P 3 "=&r,&r")) - (clobber (match_scratch:P 4 "=X,&r"))] + "#" "" - "@ - addic %3,%1,-1\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + [(parallel [(set (match_dup 5) + (plus:P (match_dup 4) + (const_int -1))) + (set (reg:P CA_REGNO) + (ne:P (match_dup 4) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (match_dup 3) + (reg:P CA_REGNO))) + (clobber (reg:P CA_REGNO))])] +{ + operands[4] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[4]); -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (ne:P (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (neg:P (match_operand:P 2 "gpc_reg_operand" "")))) - (clobber (match_scratch:P 3 "")) - (clobber (match_scratch:P 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") + if (GET_CODE (operands[5]) == SCRATCH) + operands[5] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) -; For combine. -(define_insn "*compare_plus_ne0__1" - [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") - (compare:CCEQ (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (neg:P (match_operand:P 2 "gpc_reg_operand" "r,r")))) - (clobber (match_scratch:P 3 "=&r,&r")) - (clobber (match_scratch:P 4 "=X,&r"))] +(define_insn_and_split "*minus_eq_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (minus:P (match_operand:P 3 "gpc_reg_operand" "r") + (eq:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "scc_eq_operand" "")))) + (clobber (match_scratch:P 4 "=r")) + (clobber (match_scratch:P 5 "=r")) + (clobber (reg:P CA_REGNO))] "" - "@ - addic %3,%1,-1\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + "#" + "" + [(parallel [(set (match_dup 5) + (plus:P (match_dup 4) + (const_int -1))) + (set (reg:P CA_REGNO) + (ne:P (match_dup 4) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (plus:P (match_dup 3) + (reg:P CA_REGNO)) + (const_int -1))) + (clobber (reg:P CA_REGNO))])] +{ + operands[4] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[4]); -(define_split - [(set (match_operand:CCEQ 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CCEQ (ne:P (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (neg:P (match_operand:P 2 "gpc_reg_operand" "")))) - (clobber (match_scratch:P 3 "")) - (clobber (match_scratch:P 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") + if (GET_CODE (operands[5]) == SCRATCH) + operands[5] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) -(define_insn "*plus_ne0__compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_scratch:P 3 "=&r,&r"))] +(define_insn_and_split "*minus_ne_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (minus:P (match_operand:P 3 "gpc_reg_operand" "r") + (ne:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "scc_eq_operand" "")))) + (clobber (match_scratch:P 4 "=r")) + (clobber (match_scratch:P 5 "=r")) + (clobber (reg:P CA_REGNO))] "" - "@ - addic %3,%1,-1\;addze. %0,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_scratch:P 3 ""))] - "reload_completed" - [(parallel [(set (match_dup 0) - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_dup 3))]) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*leu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")))] - "" - "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*leu_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (leu:P (match_dup 1) (match_dup 2)))] - "" - "@ - subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (leu:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (leu:P (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (leu:P (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*plus_leu" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")) - (match_operand:P 3 "gpc_reg_operand" "r")))] - "" - "subf%I2c %0,%1,%2\;addze %0,%3" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_32BIT" - "@ - subf%I2c %4,%1,%2\;addze. %4,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_32BIT" - "@ - subf%I2c %0,%1,%2\;addze. %0,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*neg_leu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI"))))] - "" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;nand %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*and_neg_leu" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (and:P (neg:P - (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI"))) - (match_operand:P 3 "gpc_reg_operand" "r")))] - "" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc %0,%3,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_32BIT" - "@ - subf%I2c %4,%1,%2\;subfe %4,%4,%4\;andc. %4,%3,%4 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "TARGET_32BIT" - "@ - subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc. %0,%3,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn_and_split "*ltu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (neg:P (match_dup 0)))] - "") - -(define_insn_and_split "*ltu_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") - (ltu:P (match_dup 1) (match_dup 2)))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 3) - (compare:CC (neg:P (match_dup 0)) (const_int 0))) - (set (match_dup 0) (neg:P (match_dup 0)))])] - "") - -(define_insn_and_split "*plus_ltu" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r") - (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:P 3 "gpc_reg_operand" "r,r")))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))] - "") - -(define_insn_and_split "*plus_ltu_1" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r") - (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:P 3 "short_cint_operand" "I,I")))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 0) (minus:P (match_dup 3) (match_dup 0))) - (clobber (reg:P CA_REGNO))])] - "") - -(define_insn_and_split "*plus_ltu_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:P 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:P (ltu:P (match_dup 1) (match_dup 2)) (match_dup 3)))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 4) - (compare:CC (minus:P (match_dup 3) (match_dup 0)) - (const_int 0))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])] - "") - -(define_insn "*neg_ltu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))] - "" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0 - addic %0,%1,%n2\;subfe %0,%0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*geu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))] - "" - "@ - subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*geu_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") - (geu:P (match_dup 1) (match_dup 2)))] - "" - "@ - subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (geu:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "reg_or_neg_short_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (geu:P (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (geu:P (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*plus_geu" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r") - (plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:P 3 "gpc_reg_operand" "r,r")))] - "" - "@ - subfc %0,%2,%1\;addze %0,%3 - addic %0,%1,%n2\;addze %0,%3" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "TARGET_32BIT" - "@ - subfc %4,%2,%1\;addze. %4,%3 - addic %4,%1,%n2\;addze. %4,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,8,12,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_32BIT" - "@ - subfc %0,%2,%1\;addze. %0,%3 - addic %0,%1,%n2\;addze. %0,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,8,12,12")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*neg_geu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_short_operand" "r,I"))))] - "" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0\;nand %0,%0,%0 - subfic %0,%1,-1\;add%I2c %0,%0,%2\;subfe %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*and_neg_geu" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r") - (and:P (neg:P - (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))) - (match_operand:P 3 "gpc_reg_operand" "r,r")))] - "" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0\;andc %0,%3,%0 - addic %0,%1,%n2\;subfe %0,%0,%0\;andc %0,%3,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "TARGET_32BIT" - "@ - subfc %4,%2,%1\;subfe %4,%4,%4\;andc. %4,%3,%4 - addic %4,%1,%n2\;subfe %4,%4,%4\;andc. %4,%3,%4 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "TARGET_32BIT" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0\;andc. %0,%3,%0 - addic %0,%1,%n2\;subfe %0,%0,%0\;andc. %0,%3,%0 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*plus_gt0" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (gt:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r")))] - "" - "addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "TARGET_32BIT" - "@ - addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) - (plus:SI (gt:SI (match_dup 1) (const_int 0)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_64BIT" - "@ - addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_64BIT && reload_completed" - [(set (match_dup 3) - (plus:DI (gt:DI (match_dup 1) (const_int 0)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))] - "TARGET_32BIT" - "@ - addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") - (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))] - "TARGET_64BIT" - "@ - addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))] - "TARGET_64BIT && reload_completed" - [(set (match_dup 0) - (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn_and_split "*gtu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (neg:P (match_dup 0)))] - "") - -(define_insn_and_split "*gtu_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (gtu:P (match_dup 1) (match_dup 2)))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 3) - (compare:CC (neg:P (match_dup 0)) (const_int 0))) - (set (match_dup 0) (neg:P (match_dup 0)))])] - "") - -(define_insn_and_split "*plus_gtu" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")) - (match_operand:P 3 "gpc_reg_operand" "r")))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))] - "") - -(define_insn_and_split "*plus_gtu_1" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")) - (match_operand:P 3 "short_cint_operand" "I")))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 0) (minus:P (match_dup 3) (match_dup 0))) - (clobber (reg:P CA_REGNO))])] - "") - -(define_insn_and_split "*plus_gtu_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:P 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:P (gtu:P (match_dup 1) (match_dup 2)) (match_dup 3)))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 4) - (compare:CC (minus:P (match_dup 3) (match_dup 0)) - (const_int 0))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])] - "") - -(define_insn "*neg_gtu" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI"))))] - "" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) + "#" + "" + [(parallel [(set (match_dup 5) + (neg:P (match_dup 4))) + (set (reg:P CA_REGNO) + (eq:P (match_dup 4) + (const_int 0)))]) + (parallel [(set (match_dup 0) + (plus:P (plus:P (match_dup 3) + (reg:P CA_REGNO)) + (const_int -1))) + (clobber (reg:P CA_REGNO))])] +{ + operands[4] = rs6000_emit_eqne (mode, + operands[1], operands[2], operands[4]); + if (GET_CODE (operands[5]) == SCRATCH) + operands[5] = gen_reg_rtx (mode); +} + [(set (attr "length") + (if_then_else (match_test "operands[2] == const0_rtx") + (const_string "8") + (const_string "12")))]) ;; Define both directions of branch and return. If we need a reload ;; register, we'd rather use CR0 since it is much easier to copy a