===================================================================
@@ -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)
===================================================================
@@ -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)
===================================================================
@@ -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. */
===================================================================
@@ -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
===================================================================
@@ -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));
+}
===================================================================
@@ -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));
+}
===================================================================
@@ -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));
+}
===================================================================
@@ -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));
+}
===================================================================
@@ -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));
+}