diff mbox

[rs600] Add built-in function support for compare bytes instruction

Message ID 6e6d1f80-448e-dab4-6086-f55ccda38885@linux.vnet.ibm.com
State New
Headers show

Commit Message

Kelvin Nilsen April 28, 2017, 5:48 p.m. UTC
This patch adds support for the compare bytes instruction, which has
been available in the rs6000 architecture since Power6.

The patch has been bootstrapped and tested on powerpc64le-unknown-linux
and powerpc-unknown-linux (big-endian, with both -m32 and -m64 target
options) with no regressions.

Is this ok for the trunk?

gcc/ChangeLog:

2017-04-28  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
	support for TARGET_CMPB.
	* config/rs6000/rs6000.h: Add support for RS6000_BTM_CMPB.
	* config/rs6000/rs6000-builtin.def (BU_P6_CMPB_2): New macro.
	(BU_P6_64BIT_CMPB_2): New macro.
	(CMPB_32): Add compare-bytes support for 32-bit only targets.
	(CMPB): Add compare-bytes support for 32-bit and 64-bit targets.
	* doc/extend.texi (PowerPC AltiVec Built-in Functions): Add
	documentation of __builtin_cmpb and __builtin_cmpb_32 built-in
	functions.

gcc/testsuite/ChangeLog:

2017-04-28  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* gcc.target/powerpc/cmpb-1.c: New test.
	* gcc.target/powerpc/cmpb-2.c: New test.
	* gcc.target/powerpc/cmpb-3.c: New test.
	* gcc.target/powerpc/cmpb32-1.c: New test.
	* gcc.target/powerpc/cmpb32-2.c: New test.

Comments

Segher Boessenkool April 28, 2017, 8:45 p.m. UTC | #1
Hi Kelvin,

On Fri, Apr 28, 2017 at 11:48:03AM -0600, Kelvin Nilsen wrote:
> --- gcc/config/rs6000/rs6000.h	(revision 247069)
> +++ gcc/config/rs6000/rs6000.h	(working copy)
> @@ -2717,6 +2717,7 @@ extern int frame_pointer_needed;
>     aren't in target_flags.  */
>  #define RS6000_BTM_ALWAYS	0		/* Always enabled.  */
>  #define RS6000_BTM_ALTIVEC	MASK_ALTIVEC	/* VMX/altivec vectors.  */
> +#define RS6000_BTM_CMPB		MASK_CMPB	/* ISA 2.05: cmopare bytes.  */

Typo ("compare").  And line too long?

> --- gcc/doc/extend.texi	(revision 247069)
> +++ gcc/doc/extend.texi	(working copy)
> @@ -15107,6 +15107,22 @@ Similar to @code{__builtin_nans}, except the retur
>  @end table
>  
>  The following built-in functions are available for the PowerPC family
> +of processors, starting with ISA 2.05 or later (@option{-mcpu=power6}
> +or @option{-mcmpb}):
> +@smallexample
> +long long __builtin_cmpb (long long, long long);
> +int __builtin_cmpb_32 (int, int);
> +@end smallexample

Is __builtin_cmpb_32 required by the ABI?  If not, why do we need it,
can't __builtin_cmpb simply do the SI version if its arguments do not
need bigger?

[ We talked about this elsewhere, but for the record :-) ].


Segher
diff mbox

Patch

Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 247069)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -339,6 +339,26 @@ 
 		     | RS6000_BTC_SPECIAL),				\
 		    CODE_FOR_nothing)			/* ICODE */
 
+/* ISA 2.05 (power6) convenience macros. */
+/* For functions that depend on the CMPB instruction */
+#define BU_P6_CMPB_2(ENUM, NAME, ATTR, ICODE)				\
+  RS6000_BUILTIN_2 (P6_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_CMPB,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_BINARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+/* For functions that depend on 64-BIT support and on the CMPB instruction */
+#define BU_P6_64BIT_CMPB_2(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_2 (P6_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_CMPB			   		\
+		      | RS6000_BTM_64BIT,		/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_BINARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
 /* ISA 2.07 (power8) vector convenience macros.  */
 /* For the instructions that are encoded as altivec instructions use
    __builtin_altivec_ as the builtin name.  */
@@ -1778,6 +1798,10 @@  BU_VSX_OVERLOAD_X (ST,	     "st")
 BU_VSX_OVERLOAD_X (XL,	     "xl")
 BU_VSX_OVERLOAD_X (XST,	     "xst")
 
+/* 2 argument CMPB instructions added in ISA 2.05. */
+BU_P6_CMPB_2 (CMPB_32,        "cmpb_32",	CONST,	cmpbsi3)
+BU_P6_64BIT_CMPB_2 (CMPB,     "cmpb",		CONST,	cmpbdi3)
+
 /* 1 argument VSX instructions added in ISA 2.07.  */
 BU_P8V_VSX_1 (XSCVSPDPN,      "xscvspdpn",	CONST,	vsx_xscvspdpn)
 BU_P8V_VSX_1 (XSCVDPSPN,      "xscvdpspn",	CONST,	vsx_xscvdpspn)
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 247069)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3788,6 +3788,7 @@  HOST_WIDE_INT
 rs6000_builtin_mask_calculate (void)
 {
   return (((TARGET_ALTIVEC)		    ? RS6000_BTM_ALTIVEC   : 0)
+	  | ((TARGET_CMPB)		    ? RS6000_BTM_CMPB	   : 0)
 	  | ((TARGET_VSX)		    ? RS6000_BTM_VSX	   : 0)
 	  | ((TARGET_SPE)		    ? RS6000_BTM_SPE	   : 0)
 	  | ((TARGET_PAIRED_FLOAT)	    ? RS6000_BTM_PAIRED	   : 0)
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 247069)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -2717,6 +2717,7 @@  extern int frame_pointer_needed;
    aren't in target_flags.  */
 #define RS6000_BTM_ALWAYS	0		/* Always enabled.  */
 #define RS6000_BTM_ALTIVEC	MASK_ALTIVEC	/* VMX/altivec vectors.  */
+#define RS6000_BTM_CMPB		MASK_CMPB	/* ISA 2.05: cmopare bytes.  */
 #define RS6000_BTM_VSX		MASK_VSX	/* VSX (vector/scalar).  */
 #define RS6000_BTM_P8_VECTOR	MASK_P8_VECTOR	/* ISA 2.07 vector.  */
 #define RS6000_BTM_P9_VECTOR	MASK_P9_VECTOR	/* ISA 3.0 vector.  */
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 247069)
+++ gcc/doc/extend.texi	(working copy)
@@ -15107,6 +15107,22 @@  Similar to @code{__builtin_nans}, except the retur
 @end table
 
 The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 2.05 or later (@option{-mcpu=power6}
+or @option{-mcmpb}):
+@smallexample
+long long __builtin_cmpb (long long, long long);
+int __builtin_cmpb_32 (int, int);
+@end smallexample
+
+The @code{__builtin_cmpb} and @code{__builtin_cmpb_32} functions
+perform a byte-wise compare on the contents of their two arguments,
+returning the result of the byte-wise comparison as the returned
+value.  For each byte comparison, the corresponding byte of the return
+value holds 0xff if input bytes are equal, and 0 if the input bytes
+are not equal.  The @code{__builtin_cmpb} function requires a
+64-bit environment.
+
+The following built-in functions are available for the PowerPC family
 of processors, starting with ISA 2.06 or later (@option{-mcpu=power7}
 or @option{-mpopcntd}):
 @smallexample
Index: gcc/testsuite/gcc.target/powerpc/cmpb-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cmpb-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/cmpb-1.c	(revision 247279)
@@ -0,0 +1,31 @@ 
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target dfp_hw } */
+/* { dg-options "-mcpu=power6" } */
+
+void abort ();
+
+long long int
+do_compare (long long int a, long long int b)
+{
+  return __builtin_cmpb (a, b);
+}
+
+void
+expect (long long int pattern, long long int value)
+{
+  if (pattern != value)
+    abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  expect (0xff00000000000000,
+	  do_compare (0x0123456789abcdef, 0x0100000000000000));
+  expect (0x00ffffffffffffff,
+	  do_compare (0x0123456789abcdef, 0x0023456789abcdef));
+  expect (0x00000000000000ff,
+	  do_compare (0x00000000000000ef, 0x0123456789abcdef));
+}
Index: gcc/testsuite/gcc.target/powerpc/cmpb-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cmpb-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/cmpb-2.c	(revision 247393)
@@ -0,0 +1,31 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power5" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_popcntb_ok } */
+/* { dg-options "-mcpu=power5" } */
+
+void abort ();
+
+long long int
+do_compare (long long int a, long long int b)
+{
+  return __builtin_cmpb (a, b);	/* { dg-warning "implicit declaration of function '__builtin_cmpb'" } */
+}
+
+void
+expect (long long int pattern, long long int value)
+{
+  if (pattern != value)
+    abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  expect (0xff00000000000000,
+	  do_compare (0x0123456789abcdef, 0x0100000000000000));
+  expect (0x00ffffffffffffff,
+	  do_compare (0x0123456789abcdef, 0x0023456789abcdef));
+  expect (0x00000000000000ff,
+	  do_compare (0x00000000000000ef, 0x0123456789abcdef));
+}
Index: gcc/testsuite/gcc.target/powerpc/cmpb-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cmpb-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/cmpb-3.c	(revision 247393)
@@ -0,0 +1,30 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target powerpc_popcntb_ok } */
+/* { dg-options "-mcpu=power6" } */
+
+void abort ();
+
+long long int
+do_compare (long long int a, long long int b)
+{
+  return __builtin_cmpb (a, b);	/* { dg-warning "implicit declaration of function '__builtin_cmpb'" } */
+}
+
+void expect (long long int pattern, long long int value)
+{
+  if (pattern != value)
+    abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  expect (0xff00000000000000,
+	  do_compare (0x0123456789abcdef, 0x0100000000000000));
+  expect (0x00ffffffffffffff,
+	  do_compare (0x0123456789abcdef, 0x0023456789abcdef));
+  expect (0x00000000000000ff,
+	  do_compare (0x00000000000000ef, 0x0123456789abcdef));
+}
Index: gcc/testsuite/gcc.target/powerpc/cmpb32-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cmpb32-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/cmpb32-1.c	(revision 247279)
@@ -0,0 +1,27 @@ 
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-require-effective-target dfp_hw } */
+/* { dg-options "-mcpu=power6" } */
+
+void abort ();
+
+int
+do_compare (int a, int b)
+{
+  return __builtin_cmpb_32 (a, b);
+}
+
+void
+expect (int pattern, int value)
+{
+  if (pattern != value)
+    abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  expect (0xff000000, do_compare (0x12345678, 0x12000000));
+  expect (0x00ffffff, do_compare (0x12345678, 0x00345678));
+  expect (0x000000ff, do_compare (0x00000078, 0x12345678));
+}
Index: gcc/testsuite/gcc.target/powerpc/cmpb32-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cmpb32-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/cmpb32-2.c	(revision 247393)
@@ -0,0 +1,27 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power5" } } */
+/* { dg-require-effective-target powerpc_popcntb_ok } */
+/* { dg-options "-mcpu=power5" } */
+
+void abort ();
+
+int
+do_compare (int a, int b)
+{
+  return __builtin_cmpb_32 (a, b);  /* { dg-warning "implicit declaration of function '__builtin_cmpb_32'" } */
+}
+
+void
+expect (int pattern, int value)
+{
+  if (pattern != value)
+    abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  expect (0xff000000, do_compare (0x12345678, 0x12000000));
+  expect (0x00ffffff, do_compare (0x12345678, 0x00345678));
+  expect (0x000000ff, do_compare (0x00000078, 0x12345678));
+}