From patchwork Mon Feb 18 18:38:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greta Yorsh X-Patchwork-Id: 221441 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 4B8732C008C for ; Tue, 19 Feb 2013 05:39:27 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1361817567; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: From:To:Cc:References:In-Reply-To:Subject:Date:Message-ID: MIME-Version:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=bQ7WhOSuf3gsbxW7HuBblQR7y90=; b=psAjS3vpHYEp/NK tlBSNcZlStopM00PK2ji17daudptimCy9qeylOdqTTfpoYqBsX8Ou56VldZaqjBS Wpqvd1QSrblvYfUODfVpTv+V0FTvYgW3avO53+PdJ9h1iPWCTVy/3te/PXaL0szA BlwQIgAi2ZOHsxMMxKt2XWFsKZiI= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:From:To:Cc:References:In-Reply-To:Subject:Date:Message-ID:MIME-Version:X-MC-Unique:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=nr13QjPMBsAaW0CsXpP/ITp8Q/JFyejLQ+8WVjhPlNIrNOCmSaqcjhK14N1LT8 u3sXWNgdcXBavQKk5BfFVzyQJGKxhyK5fZ8//udD+2s0G0hqAdJelQU+SLrjmWsK q2+cToDgvkhsz71b8CceeM7ll1eoZdyx/WAhlo4ne487w=; Received: (qmail 28899 invoked by alias); 18 Feb 2013 18:39:16 -0000 Received: (qmail 28669 invoked by uid 22791); 18 Feb 2013 18:39:14 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_SPAMHAUS_DROP, KHOP_THREADED, MSGID_MULTIPLE_AT, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 18 Feb 2013 18:39:05 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Mon, 18 Feb 2013 18:39:03 +0000 Received: from e103227vm ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Mon, 18 Feb 2013 18:39:03 +0000 From: "Greta Yorsh" To: "Greta Yorsh" , "GCC Patches" Cc: "Richard Earnshaw" , "Ramana Radhakrishnan" , , References: <001101ce0e05$f5928a50$e0b79ef0$@yorsh@arm.com> In-Reply-To: <001101ce0e05$f5928a50$e0b79ef0$@yorsh@arm.com> Subject: [PATCH,ARM][3/n] Split various patterns Date: Mon, 18 Feb 2013 18:38:59 -0000 Message-ID: <001b01ce0e07$37a73cf0$a6f5b6d0$@yorsh@arm.com> MIME-Version: 1.0 X-MC-Unique: 113021818390303501 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 Convert define_insn into define_insn_and_split for various patterns that output multiple assembly instructions. It appears that preparation statements in define_insn_and_split sometimes are called with which_alternative set to -1 even after reload. Therefore, preparation statements use conditions on the operands instead of which_alternative. gcc/ 2013-02-14 Greta Yorsh * config/arm/arm.md (andsi_iorsi3_notsi): Convert define_insn into define_insn_and_split. (arm_negdi2,arm_abssi2,arm_neg_abssi2): Likewise. (arm_cmpdi_insn,arm_cmpdi_unsigned): Likewise. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 282d460f928f9f1a58230a4f3f3e8960e3357c1a..0000000000000000000000000000000000000000 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3276,13 +3276,17 @@ (define_split "" ) -(define_insn "*andsi_iorsi3_notsi" +(define_insn_and_split "*andsi_iorsi3_notsi" [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r") (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")) (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))] "TARGET_32BIT" - "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3" + "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3" + "&& reload_completed" + [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))] + "" [(set_attr "length" "8") (set_attr "ce_count" "2") (set_attr "predicable" "yes")] @@ -4350,12 +4354,24 @@ (define_expand "negdi2" ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). ;; The first alternative allows the common case of a *full* overlap. -(define_insn "*arm_negdi2" +(define_insn_and_split "*arm_negdi2" [(set (match_operand:DI 0 "s_register_operand" "=r,&r") (neg:DI (match_operand:DI 1 "s_register_operand" "0,r"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" - "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0" + "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0" + "&& reload_completed" + [(parallel [(set (reg:CC CC_REGNUM) + (compare:CC (const_int 0) (match_dup 1))) + (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) + (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] + { + operands[2] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[1]); + operands[1] = gen_lowpart (SImode, operands[1]); + } [(set_attr "conds" "clob") (set_attr "length" "8")] ) @@ -4425,14 +4441,67 @@ (define_expand "abssi2" operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); ") -(define_insn "*arm_abssi2" +(define_insn_and_split "*arm_abssi2" [(set (match_operand:SI 0 "s_register_operand" "=r,&r") (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" - "@ - cmp\\t%0, #0\;rsblt\\t%0, %0, #0 - eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31" + "#" + "&& reload_completed" + [(const_int 0)] + { + /* if (which_alternative == 0) */ + if (REGNO(operands[0]) == REGNO(operands[1])) + { + /* Emit the pattern: + cmp\\t%0, #0\;rsblt\\t%0, %0, #0 + [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 0) (const_int 0))) + (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0)) + (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))] + */ + emit_insn (gen_rtx_SET (VOIDmode, + gen_rtx_REG (CCmode, CC_REGNUM), + gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); + emit_insn (gen_rtx_COND_EXEC (VOIDmode, + (gen_rtx_LT (SImode, + gen_rtx_REG (CCmode, CC_REGNUM), + const0_rtx)), + (gen_rtx_SET (VOIDmode, + operands[0], + (gen_rtx_MINUS (SImode, + const0_rtx, + operands[1])))))); + DONE; + } + else + { + /* Emit the pattern: + alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31 + [(set (match_dup 0) + (xor:SI (match_dup 1) + (ashiftrt:SI (match_dup 1) (const_int 31)))) + (set (match_dup 0) + (minus:SI (match_dup 0) + (ashiftrt:SI (match_dup 1) (const_int 31))))] + */ + emit_insn (gen_rtx_SET (VOIDmode, + operands[0], + gen_rtx_XOR (SImode, + gen_rtx_ASHIFTRT (SImode, + operands[1], + GEN_INT (31)), + operands[1]))); + emit_insn (gen_rtx_SET (VOIDmode, + operands[0], + gen_rtx_MINUS (SImode, + operands[0], + gen_rtx_ASHIFTRT (SImode, + operands[1], + GEN_INT (31))))); + DONE; + } + } [(set_attr "conds" "clob,*") (set_attr "shift" "1") (set_attr "predicable" "no, yes") @@ -4453,14 +4522,57 @@ (define_insn_and_split "*thumb1_abssi2" [(set_attr "length" "6")] ) -(define_insn "*arm_neg_abssi2" +(define_insn_and_split "*arm_neg_abssi2" [(set (match_operand:SI 0 "s_register_operand" "=r,&r") (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" - "@ - cmp\\t%0, #0\;rsbgt\\t%0, %0, #0 - eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31" + "#" + "&& reload_completed" + [(const_int 0)] + { + /* if (which_alternative == 0) */ + if (REGNO (operands[0]) == REGNO (operands[1])) + { + /* Emit the pattern: + cmp\\t%0, #0\;rsbgt\\t%0, %0, #0 + */ + emit_insn (gen_rtx_SET (VOIDmode, + gen_rtx_REG (CCmode, CC_REGNUM), + gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); + emit_insn (gen_rtx_COND_EXEC (VOIDmode, + gen_rtx_GT (SImode, + gen_rtx_REG (CCmode, CC_REGNUM), + const0_rtx), + gen_rtx_SET (VOIDmode, + operands[0], + (gen_rtx_MINUS (SImode, + const0_rtx, + operands[1]))))); + DONE; + } + else + { + /* Emit the pattern: + eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31 + */ + emit_insn (gen_rtx_SET (VOIDmode, + operands[0], + gen_rtx_XOR (SImode, + gen_rtx_ASHIFTRT (SImode, + operands[1], + GEN_INT (31)), + operands[1]))); + emit_insn (gen_rtx_SET (VOIDmode, + operands[0], + gen_rtx_MINUS (SImode, + gen_rtx_ASHIFTRT (SImode, + operands[1], + GEN_INT (31)), + operands[0]))); + DONE; + } + } [(set_attr "conds" "clob,*") (set_attr "shift" "1") (set_attr "predicable" "no, yes") @@ -7828,23 +7940,64 @@ (define_insn "*arm_cmpsi_negshiftsi_si" ;; if-conversion can not reduce to a conditional compare, so we do ;; that directly. -(define_insn "*arm_cmpdi_insn" +(define_insn_and_split "*arm_cmpdi_insn" [(set (reg:CC_NCV CC_REGNUM) (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r") (match_operand:DI 1 "arm_di_operand" "rDi"))) (clobber (match_scratch:SI 2 "=r"))] "TARGET_32BIT" - "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" + "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" + "&& reload_completed" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 0) (match_dup 1))) + (parallel [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 3) (match_dup 4))) + (set (match_dup 2) + (minus:SI (match_dup 5) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] + { + operands[3] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + if (CONST_INT_P (operands[1])) + { + operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode, + DImode, + operands[1]))); + operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]); + } + else + { + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]); + } + operands[1] = gen_lowpart (SImode, operands[1]); + operands[2] = gen_lowpart (SImode, operands[2]); + } [(set_attr "conds" "set") (set_attr "length" "8")] ) -(define_insn "*arm_cmpdi_unsigned" +(define_insn_and_split "*arm_cmpdi_unsigned" [(set (reg:CC_CZ CC_REGNUM) (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r,r,l") (match_operand:DI 1 "arm_di_operand" "rDi,l,Py")))] "TARGET_32BIT" - "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" + "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" + "&& reload_completed" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 2) (match_dup 3))) + (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0)) + (set (reg:CC CC_REGNUM) + (compare:CC (match_dup 0) (match_dup 1))))] + { + operands[2] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + if (CONST_INT_P (operands[1])) + operands[3] = gen_highpart_mode (SImode, DImode, operands[1]); + else + operands[3] = gen_highpart (SImode, operands[1]); + operands[1] = gen_lowpart (SImode, operands[1]); + } [(set_attr "conds" "set") (set_attr "enabled_for_depr_it" "no,yes,yes") (set_attr "length" "8,6,6")]