From patchwork Tue Apr 24 16:31:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greta Yorsh X-Patchwork-Id: 154716 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 40F9CB6EF1 for ; Wed, 25 Apr 2012 02:30:59 +1000 (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=1335889860; 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=JGBpZzjU8c3QBm/EaJNZXX49PfU=; b=nxcrCb/D+VkrPSO y6bkG6OGBe2uq44SIk83W6c3lclrjxfckueTf+3fqB6W0btdPFDTKYYmU2B6tJ8t GKlBt+iqXDXQ+AhP1r2yU4/voxfMqsG5SFcJJzMmM5qMBqDCALjs+cuy9Z4uOn9B 2pZv3Cdu0vrKFZJKHQkrgidyAQbg= 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=Kq7PgKhBAuqqSGTdjR0Sq4Uip5TID3X+mEA4Wm26Lu/bbv3mmu/QI2LhFDehPc Po0BVJv3Gd180lo9hAbOoUl/n+pmF7BtMqPdbg/nhDilBuWLJhazsuJha2rNySIz vQ8c35wgca9uRbCjue0zMwWg7gmOfiuDT/ROBqNgvoQ+A=; Received: (qmail 4808 invoked by alias); 24 Apr 2012 16:30:54 -0000 Received: (qmail 4786 invoked by uid 22791); 24 Apr 2012 16:30:52 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, 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; Tue, 24 Apr 2012 16:30:37 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Tue, 24 Apr 2012 17:30:35 +0100 Received: from E103079 ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 24 Apr 2012 17:31:54 +0100 From: "Greta Yorsh" To: Cc: , "Ramana Radhakrishnan" , , "Richard Earnshaw" , References: In-Reply-To: Subject: [Patch, ARM][2/2] generalize ldm_stm_operation_p Date: Tue, 24 Apr 2012 17:31:51 +0100 Message-ID: <000501cd2237$c0df7cb0$429e7610$@Yorsh@arm.com> MIME-Version: 1.0 X-MC-Unique: 112042417303500801 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 Generalize ldm_stm_operation_p with additional parameters that will be used by epilogue patterns: * machine mode to support both SImode and DFmode registers * flag to request consecutive registers in the register list * flag to indicate whether PC in the register list gcc/ChangeLog 2012-04-24 Ian Bolton Sameera Deshpande Greta Yorsh * config/arm/arm-protos.h (ldm_stm_operation_p): New parameters. * config/arm/arm.c (ldm_stm_operation_p): New parameters. * config/arm/predicates.md (load_multiple_operation): Add arguments. (store_multiple_operation): Likewise. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 753e109..efb5b9f 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -62,7 +62,8 @@ extern bool arm_legitimize_reload_address (rtx *, enum machine_mode, int, int, extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int, int); extern int thumb1_legitimate_address_p (enum machine_mode, rtx, int); -extern bool ldm_stm_operation_p (rtx, bool); +extern bool ldm_stm_operation_p (rtx, bool, enum machine_mode mode, + bool, bool); extern int arm_const_double_rtx (rtx); extern int neg_const_double_rtx_ok_for_fpa (rtx); extern int vfp3_const_double_rtx (rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 4216d05..5477de2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -10139,7 +10139,9 @@ adjacent_mem_locations (rtx a, rtx b) } /* Return true if OP is a valid load or store multiple operation. LOAD is true - for load operations, false for store operations. + for load operations, false for store operations. CONSECUTIVE is true + if the register numbers in the operation must be consecutive in the register + bank. RETURN_PC is true if value is to be loaded in PC. The pattern we are trying to match for load is: [(SET (R_d0) (MEM (PLUS (addr) (offset)))) (SET (R_d1) (MEM (PLUS (addr) (offset + )))) @@ -10154,20 +10156,31 @@ adjacent_mem_locations (rtx a, rtx b) REGNO (R_dk) = REGNO (R_d0) + k. The pattern for store is similar. */ bool -ldm_stm_operation_p (rtx op, bool load) +ldm_stm_operation_p (rtx op, bool load, enum machine_mode mode, + bool consecutive, bool return_pc) { HOST_WIDE_INT count = XVECLEN (op, 0); rtx reg, mem, addr; unsigned regno; + unsigned first_regno; HOST_WIDE_INT i = 1, base = 0, offset = 0; rtx elt; bool addr_reg_in_reglist = false; bool update = false; int reg_increment; int offset_adj; + int regs_per_val; - reg_increment = 4; - offset_adj = 0; + /* If not in SImode, then registers must be consecutive + (e.g., VLDM instructions for DFmode). */ + gcc_assert ((mode == SImode) || consecutive); + /* Setting return_pc for stores is illegal. */ + gcc_assert (!return_pc || load); + + /* Set up the increments and the regs per val based on the mode. */ + reg_increment = GET_MODE_SIZE (mode); + regs_per_val = reg_increment / 4; + offset_adj = return_pc ? 1 : 0; if (count <= 1 || GET_CODE (XVECEXP (op, 0, offset_adj)) != SET @@ -10195,9 +10208,11 @@ ldm_stm_operation_p (rtx op, bool load) i = i + offset_adj; base = base + offset_adj; - /* Perform a quick check so we don't blow up below. */ - if (count <= i) - return false; + /* Perform a quick check so we don't blow up below. If only one reg is loaded, + success depends on the type: VLDM can do just one reg, + LDM must do at least two. */ + if ((count <= i) && (mode == SImode)) + return false; elt = XVECEXP (op, 0, i - 1); if (GET_CODE (elt) != SET) @@ -10218,6 +10233,7 @@ ldm_stm_operation_p (rtx op, bool load) return false; regno = REGNO (reg); + first_regno = regno; addr = XEXP (mem, 0); if (GET_CODE (addr) == PLUS) { @@ -10249,10 +10265,13 @@ ldm_stm_operation_p (rtx op, bool load) } if (!REG_P (reg) - || GET_MODE (reg) != SImode + || GET_MODE (reg) != mode || REGNO (reg) <= regno + || (consecutive + && (REGNO (reg) != + (unsigned int) (first_regno + regs_per_val * (i - base)))) || !MEM_P (mem) - || GET_MODE (mem) != SImode + || GET_MODE (mem) != mode || ((GET_CODE (XEXP (mem, 0)) != PLUS || !rtx_equal_p (XEXP (XEXP (mem, 0), 0), addr) || !CONST_INT_P (XEXP (XEXP (mem, 0), 1)) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 20a64ec..428f9e0 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -380,13 +380,17 @@ (define_special_predicate "load_multiple_operation" (match_code "parallel") { - return ldm_stm_operation_p (op, /*load=*/true); + return ldm_stm_operation_p (op, /*load=*/true, SImode, + /*consecutive=*/false, + /*return_pc=*/false); }) (define_special_predicate "store_multiple_operation" (match_code "parallel") { - return ldm_stm_operation_p (op, /*load=*/false); + return ldm_stm_operation_p (op, /*load=*/false, SImode, + /*consecutive=*/false, + /*return_pc=*/false); }) (define_special_predicate "multi_register_push"