diff mbox series

[AArch64] Add a "y" constraint for V0-V7

Message ID mptd0hg6dpb.fsf@arm.com
State New
Headers show
Series [AArch64] Add a "y" constraint for V0-V7 | expand

Commit Message

Richard Sandiford Aug. 7, 2019, 6:19 p.m. UTC
Some indexed SVE FCMLA operations have a 3-bit register field that
requires one of Z0-Z7.  This patch adds a public "y" constraint for that.

The patch also documents "x", which is again intended to be a public
constraint.

Tested on aarch64-linux-gnu (with and without SVE) and aarch64_be-elf.
OK to install?

Richard


2019-08-07  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* doc/md.texi: Document the x and y constraints for AArch64.
	* config/aarch64/aarch64.h (FP_LO8_REGNUM_P): New macro.
	(FP_LO8_REGS): New reg_class.
	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add an entry for FP_LO8_REGS.
	* config/aarch64/aarch64.c (aarch64_hard_regno_nregs)
	(aarch64_regno_regclass, aarch64_class_max_nregs): Handle FP_LO8_REGS.
	* config/aarch64/predicates.md (aarch64_simd_register): Use
	FP_REGNUM_P instead of checking the classes manually.
	* config/aarch64/constraints.md (y): New constraint.

gcc/testsuite/
	* gcc.target/aarch64/asm-x-constraint-1.c: New test.
	* gcc.target/aarch64/asm-y-constraint-1.c: Likewise.

Comments

James Greenhalgh Aug. 12, 2019, 5:03 p.m. UTC | #1
On Wed, Aug 07, 2019 at 07:19:12PM +0100, Richard Sandiford wrote:
> Some indexed SVE FCMLA operations have a 3-bit register field that
> requires one of Z0-Z7.  This patch adds a public "y" constraint for that.
> 
> The patch also documents "x", which is again intended to be a public
> constraint.
> 
> Tested on aarch64-linux-gnu (with and without SVE) and aarch64_be-elf.
> OK to install?


I had the vague recollection that 'y' already meant something... I'm
guessing you already checked, but just in case, please check.

Otherwise, this is OK.

Thanks,
James


> 
> Richard
> 
> 
> 2019-08-07  Richard Sandiford  <richard.sandiford@arm.com>
> 
> gcc/
> 	* doc/md.texi: Document the x and y constraints for AArch64.
> 	* config/aarch64/aarch64.h (FP_LO8_REGNUM_P): New macro.
> 	(FP_LO8_REGS): New reg_class.
> 	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add an entry for FP_LO8_REGS.
> 	* config/aarch64/aarch64.c (aarch64_hard_regno_nregs)
> 	(aarch64_regno_regclass, aarch64_class_max_nregs): Handle FP_LO8_REGS.
> 	* config/aarch64/predicates.md (aarch64_simd_register): Use
> 	FP_REGNUM_P instead of checking the classes manually.
> 	* config/aarch64/constraints.md (y): New constraint.
> 
> gcc/testsuite/
> 	* gcc.target/aarch64/asm-x-constraint-1.c: New test.
> 	* gcc.target/aarch64/asm-y-constraint-1.c: Likewise.
>
Richard Sandiford Aug. 13, 2019, 9:48 a.m. UTC | #2
James Greenhalgh <james.greenhalgh@arm.com> writes:
> On Wed, Aug 07, 2019 at 07:19:12PM +0100, Richard Sandiford wrote:
>> Some indexed SVE FCMLA operations have a 3-bit register field that
>> requires one of Z0-Z7.  This patch adds a public "y" constraint for that.
>> 
>> The patch also documents "x", which is again intended to be a public
>> constraint.
>> 
>> Tested on aarch64-linux-gnu (with and without SVE) and aarch64_be-elf.
>> OK to install?
>
>
> I had the vague recollection that 'y' already meant something... I'm
> guessing you already checked, but just in case, please check.

Yeah, it's definitely unused at the moment.  It might be this usage that
you're remembering, since we unofficially "reserved" "y" for it a few
years back.  (It was a nice coincidence that the w/x/y sequence was still
free to mean 32/16/8 FP registers. :-))

Thanks,
Richard

> Otherwise, this is OK.
>
> Thanks,
> James
>
>
>> 
>> Richard
>> 
>> 
>> 2019-08-07  Richard Sandiford  <richard.sandiford@arm.com>
>> 
>> gcc/
>> 	* doc/md.texi: Document the x and y constraints for AArch64.
>> 	* config/aarch64/aarch64.h (FP_LO8_REGNUM_P): New macro.
>> 	(FP_LO8_REGS): New reg_class.
>> 	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add an entry for FP_LO8_REGS.
>> 	* config/aarch64/aarch64.c (aarch64_hard_regno_nregs)
>> 	(aarch64_regno_regclass, aarch64_class_max_nregs): Handle FP_LO8_REGS.
>> 	* config/aarch64/predicates.md (aarch64_simd_register): Use
>> 	FP_REGNUM_P instead of checking the classes manually.
>> 	* config/aarch64/constraints.md (y): New constraint.
>> 
>> gcc/testsuite/
>> 	* gcc.target/aarch64/asm-x-constraint-1.c: New test.
>> 	* gcc.target/aarch64/asm-y-constraint-1.c: Likewise.
>>
diff mbox series

Patch

Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	2019-07-12 08:54:11.881445730 +0100
+++ gcc/doc/md.texi	2019-08-07 19:17:05.935537080 +0100
@@ -1748,6 +1748,12 @@  The stack pointer register (@code{SP})
 @item w
 Floating point register, Advanced SIMD vector register or SVE vector register
 
+@item x
+Like @code{w}, but restricted to registers 0 to 15 inclusive.
+
+@item y
+Like @code{w}, but restricted to registers 0 to 7 inclusive.
+
 @item Upl
 One of the low eight SVE predicate registers (@code{P0} to @code{P7})
 
Index: gcc/config/aarch64/aarch64.h
===================================================================
--- gcc/config/aarch64/aarch64.h	2019-08-05 17:46:20.717723584 +0100
+++ gcc/config/aarch64/aarch64.h	2019-08-07 19:17:05.931537111 +0100
@@ -563,6 +563,9 @@  #define FP_REGNUM_P(REGNO)			\
 #define FP_LO_REGNUM_P(REGNO)            \
   (((unsigned) (REGNO - V0_REGNUM)) <= (V15_REGNUM - V0_REGNUM))
 
+#define FP_LO8_REGNUM_P(REGNO)            \
+  (((unsigned) (REGNO - V0_REGNUM)) <= (V7_REGNUM - V0_REGNUM))
+
 #define PR_REGNUM_P(REGNO)\
   (((unsigned) (REGNO - P0_REGNUM)) <= (P15_REGNUM - P0_REGNUM))
 
@@ -581,6 +584,7 @@  enum reg_class
   GENERAL_REGS,
   STACK_REG,
   POINTER_REGS,
+  FP_LO8_REGS,
   FP_LO_REGS,
   FP_REGS,
   POINTER_AND_FP_REGS,
@@ -600,6 +604,7 @@  #define REG_CLASS_NAMES				\
   "GENERAL_REGS",				\
   "STACK_REG",					\
   "POINTER_REGS",				\
+  "FP_LO8_REGS",				\
   "FP_LO_REGS",					\
   "FP_REGS",					\
   "POINTER_AND_FP_REGS",			\
@@ -616,6 +621,7 @@  #define REG_CLASS_CONTENTS						\
   { 0x7fffffff, 0x00000000, 0x00000003 },	/* GENERAL_REGS */	\
   { 0x80000000, 0x00000000, 0x00000000 },	/* STACK_REG */		\
   { 0xffffffff, 0x00000000, 0x00000003 },	/* POINTER_REGS */	\
+  { 0x00000000, 0x000000ff, 0x00000000 },       /* FP_LO8_REGS  */	\
   { 0x00000000, 0x0000ffff, 0x00000000 },       /* FP_LO_REGS  */	\
   { 0x00000000, 0xffffffff, 0x00000000 },       /* FP_REGS  */		\
   { 0xffffffff, 0xffffffff, 0x00000003 },	/* POINTER_AND_FP_REGS */\
Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	2019-08-07 19:07:38.203739735 +0100
+++ gcc/config/aarch64/aarch64.c	2019-08-07 19:17:05.931537111 +0100
@@ -1610,6 +1610,7 @@  aarch64_hard_regno_nregs (unsigned regno
     {
     case FP_REGS:
     case FP_LO_REGS:
+    case FP_LO8_REGS:
       if (aarch64_sve_data_mode_p (mode))
 	return exact_div (GET_MODE_SIZE (mode),
 			  BYTES_PER_SVE_VECTOR).to_constant ();
@@ -8295,7 +8296,8 @@  aarch64_regno_regclass (unsigned regno)
     return POINTER_REGS;
 
   if (FP_REGNUM_P (regno))
-    return FP_LO_REGNUM_P (regno) ?  FP_LO_REGS : FP_REGS;
+    return (FP_LO8_REGNUM_P (regno) ? FP_LO8_REGS
+	    : FP_LO_REGNUM_P (regno) ? FP_LO_REGS : FP_REGS);
 
   if (PR_REGNUM_P (regno))
     return PR_LO_REGNUM_P (regno) ? PR_LO_REGS : PR_HI_REGS;
@@ -8585,6 +8587,7 @@  aarch64_class_max_nregs (reg_class_t reg
     case POINTER_AND_FP_REGS:
     case FP_REGS:
     case FP_LO_REGS:
+    case FP_LO8_REGS:
       if (aarch64_sve_data_mode_p (mode)
 	  && constant_multiple_p (GET_MODE_SIZE (mode),
 				  BYTES_PER_SVE_VECTOR, &nregs))
Index: gcc/config/aarch64/predicates.md
===================================================================
--- gcc/config/aarch64/predicates.md	2019-05-12 12:27:15.753897237 +0100
+++ gcc/config/aarch64/predicates.md	2019-08-07 19:17:05.931537111 +0100
@@ -53,8 +53,7 @@  (define_predicate "aarch64_ccmp_operand"
 
 (define_predicate "aarch64_simd_register"
   (and (match_code "reg")
-       (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
-            (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS"))))
+       (match_test "FP_REGNUM_P (REGNO (op))")))
 
 (define_predicate "aarch64_reg_or_zero"
   (and (match_code "reg,subreg,const_int")
Index: gcc/config/aarch64/constraints.md
===================================================================
--- gcc/config/aarch64/constraints.md	2019-03-08 18:15:38.224734558 +0000
+++ gcc/config/aarch64/constraints.md	2019-08-07 19:17:05.931537111 +0100
@@ -36,6 +36,9 @@  (define_register_constraint "Upl" "PR_LO
 (define_register_constraint "x" "FP_LO_REGS"
   "Floating point and SIMD vector registers V0 - V15.")
 
+(define_register_constraint "y" "FP_LO8_REGS"
+  "Floating point and SIMD vector registers V0 - V7.")
+
 (define_constraint "I"
  "A constant that can be used with an ADD operation."
  (and (match_code "const_int")
Index: gcc/testsuite/gcc.target/aarch64/asm-x-constraint-1.c
===================================================================
--- /dev/null	2019-07-30 08:53:31.317691683 +0100
+++ gcc/testsuite/gcc.target/aarch64/asm-x-constraint-1.c	2019-08-07 19:17:05.935537080 +0100
@@ -0,0 +1,34 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void
+f (void)
+{
+  register float s0 asm ("s0");
+  register float s7 asm ("s7");
+  register float s8 asm ("s8");
+  register float s15 asm ("s15");
+  register float s16 asm ("s16");
+  register float s31 asm ("s31");
+  asm volatile ("// s0 out: %s0" : "=w" (s0));
+  asm volatile ("// s0 in: %s0" :: "x" (s0));
+  asm volatile ("// s7 out: %s0" : "=w" (s7));
+  asm volatile ("// s7 in: %s0" :: "x" (s7));
+  asm volatile ("// s8 out: %s0" : "=w" (s8));
+  asm volatile ("// s8 in: %s0" :: "x" (s8));
+  asm volatile ("// s15 out: %s0" : "=w" (s15));
+  asm volatile ("// s15 in: %s0" :: "x" (s15));
+  asm volatile ("// s16 out: %s0" : "=w" (s16));
+  asm volatile ("// s16 in: %s0" :: "x" (s16));
+  asm volatile ("// s31 out: %s0" : "=w" (s31));
+  asm volatile ("// s31 in: %s0" :: "x" (s31));
+}
+
+/* { dg-final { scan-assembler {\t// s0 out: s0\n.*[/]/ s0 in: s0\n} } } */
+/* { dg-final { scan-assembler {\t// s7 out: s7\n.*[/]/ s7 in: s7\n} } } */
+/* { dg-final { scan-assembler {\t// s8 out: s8\n.*[/]/ s8 in: s8\n} } } */
+/* { dg-final { scan-assembler {\t// s15 out: s15\n.*[/]/ s15 in: s15\n} } } */
+/* { dg-final { scan-assembler {\t// s16 out: s16\n.*\tfmov\t(s[0-7]), s16\n.*[/]/ s16 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s31 out: s31\n.*\tfmov\t(s[0-7]), s31\n.*[/]/ s31 in: \1\n} } } */
+/* { dg-final { scan-assembler-not {\t// s16 in: s16\n} } } */
+/* { dg-final { scan-assembler-not {\t// s31 in: s31\n} } } */
Index: gcc/testsuite/gcc.target/aarch64/asm-y-constraint-1.c
===================================================================
--- /dev/null	2019-07-30 08:53:31.317691683 +0100
+++ gcc/testsuite/gcc.target/aarch64/asm-y-constraint-1.c	2019-08-07 19:17:05.935537080 +0100
@@ -0,0 +1,36 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void
+f (void)
+{
+  register float s0 asm ("s0");
+  register float s7 asm ("s7");
+  register float s8 asm ("s8");
+  register float s15 asm ("s15");
+  register float s16 asm ("s16");
+  register float s31 asm ("s31");
+  asm volatile ("// s0 out: %s0" : "=w" (s0));
+  asm volatile ("// s0 in: %s0" :: "y" (s0));
+  asm volatile ("// s7 out: %s0" : "=w" (s7));
+  asm volatile ("// s7 in: %s0" :: "y" (s7));
+  asm volatile ("// s8 out: %s0" : "=w" (s8));
+  asm volatile ("// s8 in: %s0" :: "y" (s8));
+  asm volatile ("// s15 out: %s0" : "=w" (s15));
+  asm volatile ("// s15 in: %s0" :: "y" (s15));
+  asm volatile ("// s16 out: %s0" : "=w" (s16));
+  asm volatile ("// s16 in: %s0" :: "y" (s16));
+  asm volatile ("// s31 out: %s0" : "=w" (s31));
+  asm volatile ("// s31 in: %s0" :: "y" (s31));
+}
+
+/* { dg-final { scan-assembler {\t// s0 out: s0\n.*[/]/ s0 in: s0\n} } } */
+/* { dg-final { scan-assembler {\t// s7 out: s7\n.*[/]/ s7 in: s7\n} } } */
+/* { dg-final { scan-assembler {\t// s8 out: s8\n.*\tfmov\t(s[0-7]), s8\n.*[/]/ s8 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s15 out: s15\n.*\tfmov\t(s[0-7]), s15\n.*[/]/ s15 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s16 out: s16\n.*\tfmov\t(s[0-7]), s16\n.*[/]/ s16 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s31 out: s31\n.*\tfmov\t(s[0-7]), s31\n.*[/]/ s31 in: \1\n} } } */
+/* { dg-final { scan-assembler-not {\t// s8 in: s8\n} } } */
+/* { dg-final { scan-assembler-not {\t// s15 in: s15\n} } } */
+/* { dg-final { scan-assembler-not {\t// s16 in: s16\n} } } */
+/* { dg-final { scan-assembler-not {\t// s31 in: s31\n} } } */