From patchwork Sat Mar 21 17:25:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Hurley X-Patchwork-Id: 6064581 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 92FFF9F318 for ; Sat, 21 Mar 2015 17:28:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9DBA4202F0 for ; Sat, 21 Mar 2015 17:28:55 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 35F122025B for ; Sat, 21 Mar 2015 17:28:54 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YZNAT-0006N1-Gt; Sat, 21 Mar 2015 17:26:37 +0000 Received: from mail-qg0-f45.google.com ([209.85.192.45]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YZNAQ-0006Ju-9z for linux-arm-kernel@lists.infradead.org; Sat, 21 Mar 2015 17:26:35 +0000 Received: by qgew92 with SMTP id w92so41786908qge.2 for ; Sat, 21 Mar 2015 10:26:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=5VOXSQSuGRROHBE3Oc4opo1b0uilCZmeVlzZNyjJ7f0=; b=Er15ZWXfjXkarDkUbFc9fZwSNviqNyYSAfoy4EYFPkpkAIJc2lSZFtwdm2BTrTTm7D /xaTqYB1yQ1bKCuhCk6HgLEhwejYQ629i/nsay01VREdOtKxv/VZOCHcXhgctNKlrCOR AmCj34QpCveIswWyJebEX83UhfjZwv/t9AgEGOb7GJ+ecFRh7QkuP7AQ07WBBgVWj2xL SW8mQ4kHd8HTUhBMbB99B5rNjo4X+UvAzflcwENXbSeJVSXHtGG6nhTEtd9Dv+f9Dgka YkS14R+uB1ywU8iNYpyCF9LwptDji6g+RZYK3Ddw+4l3bY2Ev6q5wuaNPIq5Flh5CaNj eQsw== X-Gm-Message-State: ALoCoQm/DPwshBYc6c7ezMTT4v+uqA6VRffTcf4OinCTutQ8vaayj8Dp3k4M92sVzExL1nVcYa7l X-Received: by 10.140.36.239 with SMTP id p102mr105510530qgp.44.1426958772050; Sat, 21 Mar 2015 10:26:12 -0700 (PDT) Received: from thor.lan (h96-61-87-245.cntcnh.dsl.dynamic.tds.net. [96.61.87.245]) by mx.google.com with ESMTPSA id i48sm5503868qge.34.2015.03.21.10.26.11 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 21 Mar 2015 10:26:11 -0700 (PDT) From: Peter Hurley To: Russell King Subject: [PATCH] ARM: io: Unpessimize relaxed io accessors Date: Sat, 21 Mar 2015 13:25:53 -0400 Message-Id: <1426958753-26903-1-git-send-email-peter@hurleysoftware.com> X-Mailer: git-send-email 2.3.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150321_102634_428220_077C9662 X-CRM114-Status: GOOD ( 13.06 ) X-Spam-Score: -0.7 (/) Cc: Catalin Marinas , Will Deacon , Peter Hurley , linux-arm-kernel@lists.infradead.org, Nicolas Pitre X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP commit 195bbcac2e5c12f7fb ("ARM: 7500/1: io: avoid writeback addressing modes for __raw_ accessors") disables writeback addressing modes for raw i/o. However, the "+Q" assembler constraint forces the compiler to invalidate and reload the 'addr' input. The 'addr' parameter is an input, not an output, and the instructions do not change the value of 'addr', so the '+' constraint modifier is unnecessarily pessimistic and leads to poor code generation. This is especially noticeable with complex address inputs in loops; the compiler is forced to recompute 'addr' on each loop iteration. For example, the following code: #include #include static const int *remap; void wr_loop(void __iomem *base, int c, int val) { int i; for (i = 0; i < c; i++) writew_relaxed(val, base + remap[c >> 2]); } generates current master | this patch 0: e3510000 cmp r1, #0 | 0: e3510000 cmp r1, #0 4: d12fff1e bxle lr | 4: d12fff1e bxle lr 8: e3003000 movw r3, #0 | 8: e3c1c003 bic ip, r1, #3 c: e3403000 movt r3, #0 | c: e6ff2072 uxth r2, r2 10: e92d4010 push {r4, lr} | 10: e3a03000 mov r3, #0 14: e6ff2072 uxth r2, r2 | 14: e59cc000 ldr ip, [ip] 18: e3c14003 bic r4, r1, #3 | 18: e080000c add r0, r0, ip 1c: e593e000 ldr lr, [r3] | 20: e3a03000 mov r3, #0 | 1c: e1c020b0 strh r2, [r0] | 20: e2833001 add r3, r3, #1 24: e79ec004 ldr ip, [lr, r4] | 24: e1530001 cmp r3, r1 28: e080c00c add ip, r0, ip | 28: 1afffffb bne 1c 2c: e1cc20b0 strh r2, [ip] | 2c: e12fff1e bx lr 30: e2833001 add r3, r3, #1 | 34: e1530001 cmp r3, r1 | 38: 1afffff9 bne 24 | | 3c: e8bd8010 pop {r4, pc} | Signed-off-by: Peter Hurley --- arch/arm/include/asm/io.h | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index db58deb..7744e58 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -73,17 +73,16 @@ void __raw_readsl(const volatile void __iomem *addr, void *data, int longlen); static inline void __raw_writew(u16 val, volatile void __iomem *addr) { asm volatile("strh %1, %0" - : "+Q" (*(volatile u16 __force *)addr) - : "r" (val)); + : : "Q" (*(volatile u16 __force *)addr), "r" (val)); } #define __raw_readw __raw_readw static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; - asm volatile("ldrh %1, %0" - : "+Q" (*(volatile u16 __force *)addr), - "=r" (val)); + asm volatile("ldrh %0, %1" + : "=r" (val) + : "Q" (*(volatile u16 __force *)addr)); return val; } #endif @@ -92,25 +91,23 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) static inline void __raw_writeb(u8 val, volatile void __iomem *addr) { asm volatile("strb %1, %0" - : "+Qo" (*(volatile u8 __force *)addr) - : "r" (val)); + : : "Qo" (*(volatile u8 __force *)addr), "r" (val)); } #define __raw_writel __raw_writel static inline void __raw_writel(u32 val, volatile void __iomem *addr) { asm volatile("str %1, %0" - : "+Qo" (*(volatile u32 __force *)addr) - : "r" (val)); + : : "Qo" (*(volatile u32 __force *)addr), "r" (val)); } #define __raw_readb __raw_readb static inline u8 __raw_readb(const volatile void __iomem *addr) { u8 val; - asm volatile("ldrb %1, %0" - : "+Qo" (*(volatile u8 __force *)addr), - "=r" (val)); + asm volatile("ldrb %0, %1" + : "=r" (val) + : "Qo" (*(volatile u8 __force *)addr)); return val; } @@ -118,9 +115,9 @@ static inline u8 __raw_readb(const volatile void __iomem *addr) static inline u32 __raw_readl(const volatile void __iomem *addr) { u32 val; - asm volatile("ldr %1, %0" - : "+Qo" (*(volatile u32 __force *)addr), - "=r" (val)); + asm volatile("ldr %0, %1" + : "=r" (val) + : "Qo" (*(volatile u32 __force *)addr)); return val; }