From patchwork Fri Oct 19 16:51:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greta Yorsh X-Patchwork-Id: 192774 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 096A02C0092 for ; Sat, 20 Oct 2012 03:52:54 +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=1351270375; 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=gIPc88z+E+yMG4Zz6KvhX0tKAC0=; b=kt2i9R7OLYeNL1b DTVER1S8uJTpJiQSTTA5CueJUke1Vjj8/1WZwuuftpgvkPgm/gMVwbZh2Fr442G5 qLeDs9wMH7IyE5fiu4KzJo7zGvvYyE9gV9c05MpcQTnGpXeDUsVL/JZA3eDtwHEm qDtuH3UuzATOt2IYosjMrM1wfa+E= 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=JRjzh4sdQUOJYmdNLkt7ZvVGxpmu8x+wFWYvWPBycDcJDV2QnTGo3jdZFVeqbL fDCRzP54ctdXuVpCTh9hQT/QsMiJBwm+eO6eIE0Cc/NBzxloyHcHPdj4OJAyvats en48L5EqPTPp9Gu+zgOsPsW9fk4TifJVwDr5dfySMPRkw=; Received: (qmail 1625 invoked by alias); 19 Oct 2012 16:52:32 -0000 Received: (qmail 1503 invoked by uid 22791); 19 Oct 2012 16:52:29 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, MSGID_MULTIPLE_AT, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE 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; Fri, 19 Oct 2012 16:52:10 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Fri, 19 Oct 2012 17:52:06 +0100 Received: from e103227vm ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Fri, 19 Oct 2012 17:52:03 +0100 From: "Greta Yorsh" To: "Richard Earnshaw" Cc: "GCC Patches" , "Ramana Radhakrishnan" , , References: <001601cda6f6$2b3fcea0$81bf6be0$@yorsh@arm.com> <001701cda6f8$5f19a9b0$1d4cfd10$@yorsh@arm.com> <508006D6.4090806@arm.com> <000001cdae0d$421f2e40$c65d8ac0$@yorsh@arm.com> <5081754C.3090504@arm.com> In-Reply-To: <5081754C.3090504@arm.com> Subject: RE: [PATCH, ARM][1/4] New RTL patterns for LDRD/STRD in Thumb mode Date: Fri, 19 Oct 2012 17:51:50 +0100 Message-ID: <000401cdae1a$09231810$1b694830$@yorsh@arm.com> MIME-Version: 1.0 X-MC-Unique: 112101917520601801 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 > -----Original Message----- > From: Richard Earnshaw > Sent: 19 October 2012 16:44 > To: Greta Yorsh > Cc: GCC Patches; Ramana Radhakrishnan; nickc@redhat.com; > paul@codesourcery.com > Subject: Re: [PATCH, ARM][1/4] New RTL patterns for LDRD/STRD in Thumb > mode > > On 19/10/12 16:20, Greta Yorsh wrote: > > > Removed the condition "!optimize_function_for_size_p (cfun))". > > > > The condition "current_tune->prefer_ldrd_strd" is needed because the > > patterns > > for LDRD/STRD appear before the patterns for LDM/STM that can match > the same > > RTL > > (two register in the list). Condition "reload_completed" does not > help with > > it > > because peephole optimizations in ldmstm.md may (after reload) create > new > > RTL insn > > that match this pattern. > > > > The point of the reload_completed is that these patterns have the > potential to cause some problems if they somehow matched during earlier > passes and the address base was an eliminable register. > Thank you for the explanation. Here is an updated patch. Regression tests and bootstrap in progress for the entire sequence, after addressing all other comments as well. OK for trunk, if bootstrap successful? Thanks, Greta ChangeLog gcc/ 2012-10-19 Sameera Deshpande Greta Yorsh * config/arm/arm-protos.h (offset_ok_for_ldrd_strd): New declaration. (operands_ok_ldrd_strd): Likewise. * config/arm/arm.c (offset_ok_for_ldrd_strd): New function. (operands_ok_ldrd_strd): Likewise. * config/arm/arm.md (thumb2_ldrd, thumb2_ldrd_base): New patterns. (thumb2_ldrd_base_neg): Likewise. (thumb2_strd, thumb2_strd_base, thumb_strd_base_neg): Likewise. * predicates.md (ldrd_strd_offset_operand): New predicate. * config/arm/constraints.md (Do): New constraint. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 010e7fc..bfe96ea 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -116,6 +116,8 @@ extern bool gen_stm_seq (rtx *, int); extern bool gen_const_stm_seq (rtx *, int); extern rtx arm_gen_load_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *); extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *); +extern bool offset_ok_for_ldrd_strd (HOST_WIDE_INT); +extern bool operands_ok_ldrd_strd (rtx, rtx, rtx, HOST_WIDE_INT, bool, bool); extern int arm_gen_movmemqi (rtx *); extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx); extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx, diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index fc3a508..c60e62f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -12185,6 +12185,75 @@ arm_pad_reg_upward (enum machine_mode mode, return !BYTES_BIG_ENDIAN; } +/* Returns true iff OFFSET is valid for use in an LDRD/STRD instruction, + assuming that the address in the base register is word aligned. */ +bool +offset_ok_for_ldrd_strd (HOST_WIDE_INT offset) +{ + HOST_WIDE_INT max_offset; + + /* Offset must be a multiple of 4 in Thumb mode. */ + if (TARGET_THUMB2 && ((offset & 3) != 0)) + return false; + + if (TARGET_THUMB2) + max_offset = 1020; + else if (TARGET_ARM) + max_offset = 255; + else + gcc_unreachable (); + + return ((offset <= max_offset) && (offset >= -max_offset)); +} + +/* Checks whether the operands are valid for use in an LDRD/STRD instruction. + Assumes that RT, RT2, and RN are REG. This is guaranteed by the patterns. + Assumes that the address in the base register RN is word aligned. Pattern + guarantees that both memory accesses use the same base register, + the offsets are constants within the range, and the gap between the offsets is 4. + If preload complete then check that registers are legal. WBACK indicates whether + address is updated. LOAD indicates whether memory access is load or store. */ +bool +operands_ok_ldrd_strd (rtx rt, rtx rt2, rtx rn, HOST_WIDE_INT offset, + bool wback, bool load) +{ + unsigned int t, t2, n; + + if (!reload_completed) + return true; + + if (!offset_ok_for_ldrd_strd (offset)) + return false; + + t = REGNO (rt); + t2 = REGNO (rt2); + n = REGNO (rn); + + if ((TARGET_THUMB2) + && ((wback && (n == t || n == t2)) + || (t == SP_REGNUM) + || (t == PC_REGNUM) + || (t2 == SP_REGNUM) + || (t2 == PC_REGNUM) + || (!load && (n == PC_REGNUM)) + || (load && (t == t2)) + /* Triggers Cortex-M3 LDRD errata. */ + || (!wback && load && fix_cm3_ldrd && (n == t)))) + return false; + + if ((TARGET_ARM) + && ((wback && (n == t || n == t2)) + || (t2 == PC_REGNUM) + || (t % 2 != 0) /* First destination register is not even. */ + || (t2 != t + 1) + /* PC can be used as base register (for offset addressing only), + but it is depricated. */ + || (n == PC_REGNUM))) + return false; + + return true; +} + /* Print a symbolic form of X to the debug file, F. */ static void diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 7c80f91..3277561 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -11511,6 +11511,99 @@ "" ) +;; Patterns for LDRD/STRD in Thumb2 mode + +(define_insn "*thumb2_ldrd" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") + (match_operand:SI 2 "ldrd_strd_offset_operand" "Do")))) + (set (match_operand:SI 3 "s_register_operand" "=r") + (mem:SI (plus:SI (match_dup 1) + (match_operand:SI 4 "const_int_operand" ""))))] + "TARGET_LDRD && TARGET_THUMB2 && reload_completed + && current_tune->prefer_ldrd_strd + && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4])) + && (operands_ok_ldrd_strd (operands[0], operands[3], + operands[1], INTVAL (operands[2]), + false, true))" + "ldrd%?\t%0, %3, [%1, %2]" + [(set_attr "type" "load2") + (set_attr "predicable" "yes")]) + +(define_insn "*thumb2_ldrd_base" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) + (set (match_operand:SI 2 "s_register_operand" "=r") + (mem:SI (plus:SI (match_dup 1) + (const_int 4))))] + "TARGET_LDRD && TARGET_THUMB2 && reload_completed + && current_tune->prefer_ldrd_strd + && (operands_ok_ldrd_strd (operands[0], operands[2], + operands[1], 0, false, true))" + "ldrd%?\t%0, %2, [%1]" + [(set_attr "type" "load2") + (set_attr "predicable" "yes")]) + +(define_insn "*thumb2_ldrd_base_neg" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") + (const_int -4)))) + (set (match_operand:SI 2 "s_register_operand" "=r") + (mem:SI (match_dup 1)))] + "TARGET_LDRD && TARGET_THUMB2 && reload_completed + && current_tune->prefer_ldrd_strd + && (operands_ok_ldrd_strd (operands[0], operands[2], + operands[1], -4, false, true))" + "ldrd%?\t%0, %2, [%1, #-4]" + [(set_attr "type" "load2") + (set_attr "predicable" "yes")]) + +(define_insn "*thumb2_strd" + [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") + (match_operand:SI 1 "ldrd_strd_offset_operand" "Do"))) + (match_operand:SI 2 "s_register_operand" "r")) + (set (mem:SI (plus:SI (match_dup 0) + (match_operand:SI 3 "const_int_operand" ""))) + (match_operand:SI 4 "s_register_operand" "r"))] + "TARGET_LDRD && TARGET_THUMB2 && reload_completed + && current_tune->prefer_ldrd_strd + && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3])) + && (operands_ok_ldrd_strd (operands[2], operands[4], + operands[0], INTVAL (operands[1]), + false, false))" + "strd%?\t%2, %4, [%0, %1]" + [(set_attr "type" "store2") + (set_attr "predicable" "yes")]) + +(define_insn "*thumb2_strd_base" + [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk")) + (match_operand:SI 1 "s_register_operand" "r")) + (set (mem:SI (plus:SI (match_dup 0) + (const_int 4))) + (match_operand:SI 2 "s_register_operand" "r"))] + "TARGET_LDRD && TARGET_THUMB2 && reload_completed + && current_tune->prefer_ldrd_strd + && (operands_ok_ldrd_strd (operands[1], operands[2], + operands[0], 0, false, false))" + "strd%?\t%1, %2, [%0]" + [(set_attr "type" "store2") + (set_attr "predicable" "yes")]) + +(define_insn "*thumb2_strd_base_neg" + [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") + (const_int -4))) + (match_operand:SI 1 "s_register_operand" "r")) + (set (mem:SI (match_dup 0)) + (match_operand:SI 2 "s_register_operand" "r"))] + "TARGET_LDRD && TARGET_THUMB2 && reload_completed + && current_tune->prefer_ldrd_strd + && (operands_ok_ldrd_strd (operands[1], operands[2], + operands[0], -4, false, false))" + "strd%?\t%1, %2, [%0, #-4]" + [(set_attr "type" "store2") + (set_attr "predicable" "yes")]) + + ;; Load the load/store multiple patterns (include "ldmstm.md") diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index b67df55..1b4167e 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -31,7 +31,7 @@ ;; 'H' was previously used for FPA. ;; The following multi-letter normal constraints have been used: -;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Dv, Dy, Di, Dt, Dz +;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Do, Dv, Dy, Di, Dt, Dz ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe ;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py @@ -279,6 +279,12 @@ (match_test "TARGET_32BIT && imm_for_neon_inv_logic_operand (op, GET_MODE (op))"))) +(define_constraint "Do" + "@internal + In ARM/Thumb2 state valid offset for an ldrd/strd instruction." + (and (match_code "const_int") + (match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (ival)"))) + (define_constraint "Dv" "@internal In ARM/Thumb-2 state a const_double which can be used with a VFP fconsts diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index f55acbf..8f49450 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -137,6 +137,10 @@ (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) <= GET_MODE_BITSIZE (mode) && ((unsigned HOST_WIDE_INT) INTVAL (op)) > 0"))) +(define_predicate "ldrd_strd_offset_operand" + (and (match_operand 0 "const_int_operand") + (match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (INTVAL (op))"))) + (define_predicate "arm_add_operand" (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "arm_neg_immediate_operand")))