From patchwork Thu Sep 27 14:02:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Malcomson X-Patchwork-Id: 975743 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-486562-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Ke4ccG4P"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.b="ikE3GuyV"; dkim-atps=neutral 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 42Lc4Y6Xngz9s3Z for ; Fri, 28 Sep 2018 00:04:29 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :content-type:mime-version:from:to:cc:date:subject:message-id; q=dns; s=default; b=wcuP54bHh1A4yCp3OtFfb3reGloEMsdKBu6MQcrIT3D cWwzRpPJYCjFyCBOIfHrOk/b5WXapGVn/gDfYN9PPH12g0wZSwccqZrJCELXU33V UCUk4Qairxgg+zGAi2dZ79PDTODRwtruiFhFe8bUl7q+RGuJLwGeiSUgkYIiTXQo = 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 :content-type:mime-version:from:to:cc:date:subject:message-id; s=default; bh=JLsN2L6b2Z6mvio2Hb2MROgTE0Y=; b=Ke4ccG4PRL/4pIcw7 mHXoXIeA5gh6Ro4rYbRXwkYYPXGaGevkwwAIOVRpjGSJJ1Ro1X4wwn+blXlPmoem FsyqMbwXgIrtrV05J+bhcyI+/ry+wtYwmqrDIHRxhbL3W+i7hRk4qwvstoRU7tbH LC2UyRSjoNsP5FfeHegacd/Xuo= Received: (qmail 39515 invoked by alias); 27 Sep 2018 14:04:22 -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 39490 invoked by uid 89); 27 Sep 2018 14:04:20 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=cf, 02, uev, REG_CLASS_NAMES X-HELO: EUR02-HE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr10069.outbound.protection.outlook.com (HELO EUR02-HE1-obe.outbound.protection.outlook.com) (40.107.1.69) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Sep 2018 14:04:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=L7p9ofFQR3AUyjHE+sflxtTOChh+B56dsHLDi38Rjps=; b=ikE3GuyVOkZkAJMWcNawssF3uuIE/kqlbSON7sY7BV30p8I0Il7rkmeGACb2EgCaisxhZWFw93tqJ5b3zqwpdmiYt+AANlyzQhPkNFAT5BJKIqFzdN7zlnWgfKCRNqA3bd2sn3qHTfYvYUwCluoLGZZ548D3lYHlN7/gvfVezJE= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Matthew.Malcomson@arm.com; Received: from e120487-lin.cambridge.arm.com (217.140.106.55) by DB6PR0801MB2006.eurprd08.prod.outlook.com (2603:10a6:4:76::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1164.25; Thu, 27 Sep 2018 14:04:12 +0000 MIME-Version: 1.0 From: Matthew Malcomson To: gcc-patches@gcc.gnu.org Cc: Richard Henderson , Richard.Earnshaw@arm.com, james.greenhalgh@arm.com, nd@arm.com, Marcus.Shawcroft@arm.com Date: Thu, 27 Sep 2018 15:02:16 +0100 Subject: [PATCH][GCC][AARCH64] Add even-pair register classes Message-ID: Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-IsSubscribed: yes Hello, LSE instructions like casp require even-odd pairs of registers. Other instructions that take a pair of registers don't have this restriction. As mentioned in the internals documentation, a limitation of forcing a register pair to start with an even register can't be enforced by defining an EVEN_REGS register class, as a pseudo register that spans multiple hard-registers is only counted as being in a register class if all registers it spans are in that class is only counted as being in a register class if all registers it spans are in that class. The canonical way to require even-odd pairs of registers to implement a TImode pseudo register as mentioned in the documentation is to limit *all* TImode registers to being even-odd by using the TARGET_HARD_REGNO_MODE_OK hook. We don't want to use this method as it would apply to all register pairs. (It is noteworthy that the current cost model in ira prefers to put values that span two registers in an even-odd pair anyway, so the use of TARGET_HARD_REGNO_MODE_OK would likely not cause much change in low register pressure situations) As a workaround we define two register classes that each define a set of non-consecutive even-odd register pairs. i.e. their bitfields are 11001100110011001100110011001100 00110011001100110011001100110000 c.f. the bitfield for GENERAL_REGS which is. 11111111111111111111111111111110 (note the last two registers are always masked out as we can't use the stack pointer). Requiring a TImode register to be allocated from one of these classes ensures the register will be allocated an even-odd pair. Using constraint letters Uep and Uex (for U and U). Full bootstrap and regtest done on aarch64-none-linux-gnu. Ok for trunk? gcc/ChangeLog: 2018-09-27 Matthew Malcomson * config/aarch64/aarch64.c (aarch64_class_max_nregs,aarch64_register_move_cost): Account for new register classes. * config/aarch64/aarch64.h (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add new register classes EVEN_PAIRS and EVEN_PAIRS_ALT. * config/aarch64/constraints.md (Uep, Uex): New register constraints corresponding to new register classes. * doc/md.texi: Document new register constraints. gcc/testsuite/ChangeLog: 2018-09-27 Matthew Malcomson * gcc.target/aarch64/even-pair-constraint.c: New test. ############### Attachment also inlined for ease of reply ############### diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 56e48b8a553f0b38a9c39b4defa094bccbebc2c4..4538023971142dcd6d76c05fc54d1ad4eddaca8b 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -513,6 +513,8 @@ extern unsigned aarch64_architecture_version; enum reg_class { NO_REGS, + EVEN_PAIRS, + EVEN_PAIRS_ALT, TAILCALL_ADDR_REGS, GENERAL_REGS, STACK_REG, @@ -532,6 +534,8 @@ enum reg_class #define REG_CLASS_NAMES \ { \ "NO_REGS", \ + "EVEN_PAIRS" \ + "EVEN_PAIRS_ALT" \ "TAILCALL_ADDR_REGS", \ "GENERAL_REGS", \ "STACK_REG", \ @@ -548,6 +552,8 @@ enum reg_class #define REG_CLASS_CONTENTS \ { \ { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ + { 0x33333333, 0x00000000, 0x00000000 }, /* EVEN_PAIRS */ \ + { 0x0ccccccc, 0x00000000, 0x00000000 }, /* EVEN_PAIRS_ALT */ \ { 0x0004ffff, 0x00000000, 0x00000000 }, /* TAILCALL_ADDR_REGS */\ { 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \ { 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 1e23b2336f6c3b895a20c6129a13e5606cf86f9f..356ced8583a5f543f4870caadcb6314123b9a4fe 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -7549,6 +7549,8 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode) switch (regclass) { case TAILCALL_ADDR_REGS: + case EVEN_PAIRS_ALT: + case EVEN_PAIRS: case POINTER_REGS: case GENERAL_REGS: case ALL_REGS: @@ -9709,11 +9711,14 @@ aarch64_register_move_cost (machine_mode mode, const struct cpu_regmove_cost *regmove_cost = aarch64_tune_params.regmove_cost; - /* Caller save and pointer regs are equivalent to GENERAL_REGS. */ - if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS) + /* Caller save, even pairs, and pointer regs are equivalent to GENERAL_REGS. + */ + if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS || to == EVEN_PAIRS + || to == EVEN_PAIRS_ALT) to = GENERAL_REGS; - if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS) + if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS || from == EVEN_PAIRS + || from == EVEN_PAIRS_ALT) from = GENERAL_REGS; /* Moving between GPR and stack cost is the same as GP2GP. */ diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 809b35e5fd377a8c6245138e0639c3afc41c7c13..1b10f7ea77a1e3407c18d3631396a63280805fe5 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -21,6 +21,16 @@ (define_register_constraint "k" "STACK_REG" "@internal The stack register.") +(define_register_constraint "Uex" "EVEN_PAIRS_ALT" + "@internal An even numbered register pair (e.g. for use with the CASP + instruction). This class contains the even register pairs not included in the + Uev class.") + +(define_register_constraint "Uep" "EVEN_PAIRS" + "An even numbered register pair (e.g. for use with the @code{CASP} + instruction). Note that for implementation reasons not all even pairs are + available in this register class. .") + (define_register_constraint "Ucs" "TAILCALL_ADDR_REGS" "@internal Registers suitable for an indirect tail call") diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 4801d68a2071a166ae6734c9010ca0fd41d65d71..53ee9dfdde7a5c61d801a3f326ef03caac09e5b4 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1797,6 +1797,16 @@ A memory address which uses a single base register with no offset A memory address suitable for a load/store pair instruction in SI, DI, SF and DF modes +@item Uep +An even numbered register pair (e.g. for use with the @code{CASP} +instruction). Note that for implementation reasons not all even +pairs are available in this register class. + +@item Uex +An even numbered register pair (e.g. for use with the @code{CASP} +instruction). This class contains the even register pairs not +included in the @samp{Uev} class. + @end table diff --git a/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c new file mode 100644 index 0000000000000000000000000000000000000000..eaedd88d893dccabcd09cc232776bf0126a28925 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +#include + +__int128 +foo () +{ + register __int128 a __asm ("x3") = 0; + // This statement to ensure "a" is indeed put into x3,x4 + asm ("" : "=r" (a) : "0" (a)); + // This statement to show that "Uep" moves the "a" into an even-odd pair. + asm ("" : "=Uep" (a) : "0" (a)); + return a+1; +} + +// Assert that variable "a" is moved into an even-odd register pair. +// Do this by checking the contents in the x3 register are moved to the +// contents in an even register. +/* { dg-final { scan-assembler "mov\tx\[0-2\]?\[02468\], x3" } } */ diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 56e48b8a553f0b38a9c39b4defa094bccbebc2c4..4538023971142dcd6d76c05fc54d1ad4eddaca8b 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -513,6 +513,8 @@ extern unsigned aarch64_architecture_version; enum reg_class { NO_REGS, + EVEN_PAIRS, + EVEN_PAIRS_ALT, TAILCALL_ADDR_REGS, GENERAL_REGS, STACK_REG, @@ -532,6 +534,8 @@ enum reg_class #define REG_CLASS_NAMES \ { \ "NO_REGS", \ + "EVEN_PAIRS" \ + "EVEN_PAIRS_ALT" \ "TAILCALL_ADDR_REGS", \ "GENERAL_REGS", \ "STACK_REG", \ @@ -548,6 +552,8 @@ enum reg_class #define REG_CLASS_CONTENTS \ { \ { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ + { 0x33333333, 0x00000000, 0x00000000 }, /* EVEN_PAIRS */ \ + { 0x0ccccccc, 0x00000000, 0x00000000 }, /* EVEN_PAIRS_ALT */ \ { 0x0004ffff, 0x00000000, 0x00000000 }, /* TAILCALL_ADDR_REGS */\ { 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \ { 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 1e23b2336f6c3b895a20c6129a13e5606cf86f9f..356ced8583a5f543f4870caadcb6314123b9a4fe 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -7549,6 +7549,8 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode) switch (regclass) { case TAILCALL_ADDR_REGS: + case EVEN_PAIRS_ALT: + case EVEN_PAIRS: case POINTER_REGS: case GENERAL_REGS: case ALL_REGS: @@ -9709,11 +9711,14 @@ aarch64_register_move_cost (machine_mode mode, const struct cpu_regmove_cost *regmove_cost = aarch64_tune_params.regmove_cost; - /* Caller save and pointer regs are equivalent to GENERAL_REGS. */ - if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS) + /* Caller save, even pairs, and pointer regs are equivalent to GENERAL_REGS. + */ + if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS || to == EVEN_PAIRS + || to == EVEN_PAIRS_ALT) to = GENERAL_REGS; - if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS) + if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS || from == EVEN_PAIRS + || from == EVEN_PAIRS_ALT) from = GENERAL_REGS; /* Moving between GPR and stack cost is the same as GP2GP. */ diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 809b35e5fd377a8c6245138e0639c3afc41c7c13..1b10f7ea77a1e3407c18d3631396a63280805fe5 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -21,6 +21,16 @@ (define_register_constraint "k" "STACK_REG" "@internal The stack register.") +(define_register_constraint "Uex" "EVEN_PAIRS_ALT" + "@internal An even numbered register pair (e.g. for use with the CASP + instruction). This class contains the even register pairs not included in the + Uev class.") + +(define_register_constraint "Uep" "EVEN_PAIRS" + "An even numbered register pair (e.g. for use with the @code{CASP} + instruction). Note that for implementation reasons not all even pairs are + available in this register class. .") + (define_register_constraint "Ucs" "TAILCALL_ADDR_REGS" "@internal Registers suitable for an indirect tail call") diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 4801d68a2071a166ae6734c9010ca0fd41d65d71..53ee9dfdde7a5c61d801a3f326ef03caac09e5b4 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1797,6 +1797,16 @@ A memory address which uses a single base register with no offset A memory address suitable for a load/store pair instruction in SI, DI, SF and DF modes +@item Uep +An even numbered register pair (e.g. for use with the @code{CASP} +instruction). Note that for implementation reasons not all even +pairs are available in this register class. + +@item Uex +An even numbered register pair (e.g. for use with the @code{CASP} +instruction). This class contains the even register pairs not +included in the @samp{Uev} class. + @end table diff --git a/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c new file mode 100644 index 0000000000000000000000000000000000000000..eaedd88d893dccabcd09cc232776bf0126a28925 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +#include + +__int128 +foo () +{ + register __int128 a __asm ("x3") = 0; + // This statement to ensure "a" is indeed put into x3,x4 + asm ("" : "=r" (a) : "0" (a)); + // This statement to show that "Uep" moves the "a" into an even-odd pair. + asm ("" : "=Uep" (a) : "0" (a)); + return a+1; +} + +// Assert that variable "a" is moved into an even-odd register pair. +// Do this by checking the contents in the x3 register are moved to the +// contents in an even register. +/* { dg-final { scan-assembler "mov\tx\[0-2\]?\[02468\], x3" } } */