From patchwork Fri Apr 11 07:36:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Terry Guo X-Patchwork-Id: 338413 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 A106214008F for ; Fri, 11 Apr 2014 17:36:07 +1000 (EST) 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:mime-version:content-type; q=dns; s=default; b=m19DC0UTMtm06ezsJSw2BfY2MJEKVdvu1SvlQIkS/e/AIi9nSX 4vdsrJmsVuj6CO5V1z1SBLAN3w8SrOeIHBXZ4ISLqijdc7TTL2IOO0wahNJEOR0Q Nbip0TeHchpFY7AoZi5Wfws93peoUzp8TJoTDxzR1Z8mYE1DHwj8T7nTU= 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:mime-version:content-type; s= default; bh=BQ6C9nLv2nB03sZKSj7ZkS9whN4=; b=QEF5/MIXJDaEyq/Npgjx 4knaRxyWBUGkXFqS+hU54FYm7fwn/HM5gp886/VFDHPxSgDgU0DKDgF9/Z10Ql4/ KVj9zeS7+5F5LNIIUbe9u7T1aEBYZwIwGxxqdmGrxMQTtmDrW0WDkO0xshZV8w9g dzzKVM6/ZpBDZZuv6paYM1g= Received: (qmail 6907 invoked by alias); 11 Apr 2014 07:36:01 -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 6894 invoked by uid 89); 11 Apr 2014 07:35:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: service87.mimecast.com Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Apr 2014 07:35:57 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Fri, 11 Apr 2014 08:35:54 +0100 Received: from shawin053 ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 11 Apr 2014 08:36:08 +0100 From: "Terry Guo" To: Cc: "Richard Earnshaw" , "Ramana Radhakrishnan" Subject: [Patch, GCC/Thumb1] Improve 64bit constant load for Thumb1 Date: Fri, 11 Apr 2014 15:36:04 +0800 Message-ID: <000001cf5558$b40149a0$1c03dce0$@arm.com> MIME-Version: 1.0 X-MC-Unique: 114041108355406101 X-IsSubscribed: yes Hi there, Current gcc prefers to using two LDR instructions to load 64bit constants. This could miss some chances that 64bit load can be done in fewer instructions or fewer cycles. For example, below code to load 0x100000001 mov r0, #1 mov r1, #1 is better than current solution: ldr r1, .L2+4 ldr r0, .L2 .L2: .word 1 .word 1 The attached patch intends to split 64bit load to take advantage of such chances. Tested with gcc regression test on cortex-m0. No new regressions. Is it ok to stage 1? BR, Terry gcc/ 2014-04-11 Terry Guo * config/arm/arm.md (split 64-bit constant for Thumb1): New split pattern. gcc/testsuite/ 2014-04-11 Terry Guo * gcc.target/arm/thumb1-load-64bit-constant-1.c: New test. * gcc.target/arm/thumb1-load-64bit-constant-2.c: Ditto. * gcc.target/arm/thumb1-load-64bit-constant-3.c: Ditto. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 2ddda02..b339e83 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -6422,7 +6422,26 @@ (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*") (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")]) -(define_split +; Split the load of 64-bit constant into two loads for high and low 32-bit parts respectively +; to see if we can load them in fewer instructions or fewer cycles. +; For the small 64-bit integer constants that satisfy constraint J, the instruction pattern +; thumb1_movdi_insn has a better way to handle them. +(define_split + [(set (match_operand:ANY64 0 "arm_general_register_operand" "") + (match_operand:ANY64 1 "const_double_operand" ""))] + "TARGET_THUMB1 && reload_completed && !satisfies_constraint_J (operands[1])" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + " + operands[2] = gen_highpart (SImode, operands[0]); + operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]), + operands[1]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + " +) + +(define_split [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "const_int_operand" ""))] "TARGET_THUMB1 && satisfies_constraint_J (operands[1])" diff --git a/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c new file mode 100644 index 0000000..9537aaf --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c @@ -0,0 +1,14 @@ +/* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-skip-if "" { ! { arm_thumb1 } } } */ + +extern long long madd (long long a, long long b); + +long long +foo () +{ + return madd (0x0000000100000001LL, 0x0000011100000001LL); +} + +/* { dg-final { scan-assembler-not "ldr" } } */ diff --git a/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c new file mode 100644 index 0000000..836682b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c @@ -0,0 +1,14 @@ +/* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { ! { arm_thumb1 } } } */ + +extern long long madd (long long a); + +long long +foo () +{ + return madd (0x0000000100000001LL); +} + +/* { dg-final { scan-assembler-not "ldr" } } */ diff --git a/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c new file mode 100644 index 0000000..cf4d0be --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c @@ -0,0 +1,14 @@ +/* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-skip-if "" { ! { arm_thumb1 } } } */ + +long long +foo (int len) +{ + return (long long) (((long long) 1 << len) - 1); +} + +/* { dg-final { scan-assembler-not "ldr" } } */ +/* { dg-final { scan-assembler-times "neg" 1 } } */ +