diff mbox series

rs6000: Add scalar cfuged instruction

Message ID 20200508130533.115062-1-wschmidt@linux.ibm.com
State New
Headers show
Series rs6000: Add scalar cfuged instruction | expand

Commit Message

Bill Schmidt May 8, 2020, 1:05 p.m. UTC
From: Kelvin Nilsen <kelvin@gcc.gnu.org>

Add the centrifuge-doubleword instruction and built-in access.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions.  Is this okay for master?

Thanks,
Bill

[gcc]

2020-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* config/rs6000/rs6000-builtin.def (BU_FUTURE_MISC_0): New
	#define.
	(BU_FUTURE_MISC_1): Likewise.
	(BU_FUTURE_MISC_2): Likewise.
	(BU_FUTURE_MISC_3): Likewise.
	(__builtin_cfuged): New built-in function definition.
	* config/rs6000/rs6000.md (UNSPEC_CFUGED): New constant.
	(cfuged): New insn.
	* doc/extend.texi (Basic PowerPC Built-in Functions Available for
	a Future Architecture): New subsubsection.

[gcc/testsuite]

2020-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* gcc.target.powerpc/cfuged-0.c: New test.
	* gcc.target.powerpc/cfuged-1.c: New test.
---
 gcc/config/rs6000/rs6000-builtin.def        | 37 +++++++++++++++
 gcc/config/rs6000/rs6000.md                 | 10 ++++
 gcc/doc/extend.texi                         | 22 +++++++++
 gcc/testsuite/gcc.target/powerpc/cfuged-0.c | 51 +++++++++++++++++++++
 gcc/testsuite/gcc.target/powerpc/cfuged-1.c | 50 ++++++++++++++++++++
 5 files changed, 170 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/cfuged-0.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/cfuged-1.c

Comments

Segher Boessenkool May 8, 2020, 11:43 p.m. UTC | #1
On Fri, May 08, 2020 at 08:05:33AM -0500, Bill Schmidt wrote:
> From: Kelvin Nilsen <kelvin@gcc.gnu.org>
> 
> Add the centrifuge-doubleword instruction and built-in access.
> 
> Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> regressions.  Is this okay for master?

This looks fine to me as well.  We could drop the "D" from the unspec
name, the size is in the mode already, but let's leave that to a future
cleanup :-)


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index e25249b5418..afc8487515f 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -993,6 +993,40 @@ 
 		     | RS6000_BTC_TERNARY),				\
 		    CODE_FOR_nothing)			/* ICODE */
 
+/* Miscellaneous (non-vector) builtins for instructions which may be
+   added at some point in the future.  */
+
+#define BU_FUTURE_MISC_0(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_0 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_FUTURE,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_SPECIAL),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+#define BU_FUTURE_MISC_1(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_1 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_FUTURE,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_UNARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+#define BU_FUTURE_MISC_2(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_2 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_FUTURE,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_BINARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+#define BU_FUTURE_MISC_3(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_3 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_FUTURE,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_TERNARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
 #endif
 
 
@@ -2539,6 +2573,9 @@  BU_P9_OVERLOAD_2 (CMPRB,	"byte_in_range")
 BU_P9_OVERLOAD_2 (CMPRB2,	"byte_in_either_range")
 BU_P9_OVERLOAD_2 (CMPEQB,	"byte_in_set")
 
+/* Future architecture scalar built-ins.  */
+BU_FUTURE_MISC_2 (CFUGED, "cfuged", CONST, cfuged)
+
 /* Future architecture vector built-ins.  */
 BU_FUTURE_V_2 (VCLZDM, "vclzdm", CONST, vclzdm)
 BU_FUTURE_V_2 (VCTZDM, "vctzdm", CONST, vctzdm)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index c02c2e1de72..001ec27f403 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -148,6 +148,7 @@  (define_c_enum "unspec"
    UNSPEC_SI_FROM_SF
    UNSPEC_PLTSEQ
    UNSPEC_PLT16_HA
+   UNSPEC_CFUGED
   ])
 
 ;;
@@ -2453,6 +2454,15 @@  (define_insn "parity<mode>2_cmpb"
   "prty<wd> %0,%1"
   [(set_attr "type" "popcnt")])
 
+(define_insn "cfuged"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
+		    (match_operand:DI 2 "gpc_reg_operand" "r")]
+	 UNSPEC_CFUGED))]
+   "TARGET_FUTURE && TARGET_64BIT"
+   "cfuged %0,%1,%2"
+   [(set_attr "type" "integer")])
+
 (define_insn "cmpb<mode>3"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
 	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 4a4d3bd0918..8b5a51a6973 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -16980,6 +16980,7 @@  implementing assertions.
 * Basic PowerPC Built-in Functions Available on ISA 2.06::
 * Basic PowerPC Built-in Functions Available on ISA 2.07::
 * Basic PowerPC Built-in Functions Available on ISA 3.0::
+* Basic PowerPC Built-in Functions Available for a Future Architecture::
 @end menu
 
 This section describes PowerPC built-in functions that do not require
@@ -17533,6 +17534,27 @@  the FPSCR.  The instruction is a lower latency version of the @code{mffs}
 instruction.  If the @code{mffsl} instruction is not available, then the
 builtin uses the older @code{mffs} instruction to read the FPSCR.
 
+@node Basic PowerPC Built-in Functions Available for a Future Architecture
+@subsubsection Basic PowerPC Built-in Functions Available for a Future Architecture
+
+The basic built-in functions described in this section are
+available on the PowerPC family of processors starting with a
+hypothetical CPU which may or may not be available in the future, as
+requested by specifying @option{-mcpu=future} on the command line.
+Unless explicitly disabled on the command line,
+specifying @option{-mcpu=future} has the effect of enabling all the
+same options as for @option{-mcpu=power9}.
+
+The following built-in functions are available on Linux 64-bit systems
+that use a future architecture instruction set (@option{-mcpu=future}):
+
+@smallexample
+@exdent unsigned long long int
+@exdent __builtin_cfuged (unsigned long long int, unsigned long long int)
+@end smallexample
+Perform a 64-bit centrifuge operation, as if implemented by the Future
+@code{cfuged} instruction.
+@findex __builtin_cfuged
 
 @node PowerPC AltiVec/VSX Built-in Functions
 @subsection PowerPC AltiVec/VSX Built-in Functions
diff --git a/gcc/testsuite/gcc.target/powerpc/cfuged-0.c b/gcc/testsuite/gcc.target/powerpc/cfuged-0.c
new file mode 100644
index 00000000000..da780eae5ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cfuged-0.c
@@ -0,0 +1,51 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+extern void abort (void);
+
+unsigned long long int
+do_cfuged (unsigned long long int source, unsigned long long int mask)
+{
+  return __builtin_cfuged (source, mask);
+}
+
+int main (int argc, char *argv [])
+{
+  unsigned long long int sources [4], masks [4];
+  unsigned long long int results [4][4] = {
+    /* sources[0] with each of masks [0 .. 3] */
+    {0x7e3ca5f0ll, 0xa5f07e3cll, 0xaf7350ecll, 0x50ecaf73ll },
+    /* sources[1] with each of masks [0 .. 3] */
+    { 0xa5f07e3cll,  0x7e3ca5f0ll, 0x73afec50ll, 0xec5073afll },
+    /* sources[2] with each of masks [0 .. 3] */
+    { 0xf07e3ca5ll, 0x3ca5f07ell, 0x3af7c50ell, 0xc50e3af7ll },
+    /* sources[3] with each of masks [0 .. 3] */
+    { 0xe7c35a0fll, 0x5a0fe7c3ll, 0x50ecaf73ll, 0xaf7350ecll },
+  };
+
+  sources[0] = 0xa5f07e3cll;
+  sources[1] = 0x7e3ca5f0ll;
+  sources[2] = 0x3ca5f07ell;
+  sources[3] = 0x5a0fe7c3ll;
+
+  masks[0] = 0xffff0000ll;
+  masks[1] = 0x0000ffffll;
+  masks[2] = 0x0f0f0f0fll;
+  masks[3] = 0xf0f0f0f0ll;
+
+  unsigned long long int result;
+
+  for (int i = 0; i < 4; i++)
+    {
+      for (int j = 0; j < 4; j++)
+	{
+	  if (do_cfuged (sources[i], masks[j]) != results [i][j])
+	    abort ();
+	}
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\mcfuged\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/cfuged-1.c b/gcc/testsuite/gcc.target/powerpc/cfuged-1.c
new file mode 100644
index 00000000000..83bf2ae1499
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cfuged-1.c
@@ -0,0 +1,50 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+extern void abort (void);
+
+unsigned long long int
+do_cfuged (unsigned long long int source, unsigned long long int mask)
+{
+  return __builtin_cfuged (source, mask);
+}
+
+int main (int argc, char *argv [])
+{
+  unsigned long long int sources [4], masks [4];
+  unsigned long long int results [4][4] = {
+    /* sources[0] with each of masks [0 .. 3] */
+    {0x7e3ca5f0ll, 0xa5f07e3cll, 0xaf7350ecll, 0x50ecaf73ll },
+    /* sources[1] with each of masks [0 .. 3] */
+    { 0xa5f07e3cll,  0x7e3ca5f0ll, 0x73afec50ll, 0xec5073afll },
+    /* sources[2] with each of masks [0 .. 3] */
+    { 0xf07e3ca5ll, 0x3ca5f07ell, 0x3af7c50ell, 0xc50e3af7ll },
+    /* sources[3] with each of masks [0 .. 3] */
+    { 0xe7c35a0fll, 0x5a0fe7c3ll, 0x50ecaf73ll, 0xaf7350ecll },
+  };
+
+  sources[0] = 0xa5f07e3cll;
+  sources[1] = 0x7e3ca5f0ll;
+  sources[2] = 0x3ca5f07ell;
+  sources[3] = 0x5a0fe7c3ll;
+
+  masks[0] = 0xffff0000ll;
+  masks[1] = 0x0000ffffll;
+  masks[2] = 0x0f0f0f0fll;
+  masks[3] = 0xf0f0f0f0ll;
+
+  unsigned long long int result;
+
+  for (int i = 0; i < 4; i++)
+    {
+      for (int j = 0; j < 4; j++)
+	{
+	  if (do_cfuged (sources[i], masks[j]) != results [i][j])
+	    abort ();
+	}
+    }
+
+  return 0;
+}