aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKelvin Nilsen <kelvin@gcc.gnu.org>2017-05-11 14:13:31 +0000
committerKelvin Nilsen <kelvin@gcc.gnu.org>2017-05-11 14:13:31 +0000
commit4fd18c782de4833736d9b3604a3b031f74429f5c (patch)
tree650ce85d5076fced2e6e671c2ff13a4c72a6ea00 /gcc
parent43b883a99006138770d42067d385347fbae21334 (diff)
downloadgcc-4fd18c782de4833736d9b3604a3b031f74429f5c.zip
gcc-4fd18c782de4833736d9b3604a3b031f74429f5c.tar.gz
gcc-4fd18c782de4833736d9b3604a3b031f74429f5c.tar.bz2
cmpb-1.c: New test.
gcc/testsuite/ChangeLog: 2017-05-11 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. gcc/ChangeLog: 2017-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org> * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add array entries to represent two legal parameterizations of the overloaded __builtin_cmpb function, as represented by the P6_OV_BUILTIN_CMPB constant. (altivec_resolve_overloaded_builtin): Add special case handling for the __builtin_cmpb function, as represented by the P6_OV_BUILTIN_CMPB constant. * config/rs6000/rs6000-builtin.def (BU_P6_2): New macro. (BU_P6_64BIT_2): New macro. (BU_P6_OVERLOAD_2): New macro (CMPB_32): Add 32-bit compare-bytes support for 32-bit only targets. (CMPB): Add 64-bit compare-bytes support for 32-bit and 64-bit targets. (CMPB): Add overload support to represent both 32-bit and 64-bit compare-bytes function. * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add support for TARGET_CMPB. * config/rs6000/rs6000.h: Add support for RS6000_BTM_CMPB. * doc/extend.texi (PowerPC AltiVec Built-in Functions): Add documentation of the __builtin_cmpb overloaded built-in function. From-SVN: r247907
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def35
-rw-r--r--gcc/config/rs6000/rs6000-c.c78
-rw-r--r--gcc/config/rs6000/rs6000.c1
-rw-r--r--gcc/config/rs6000/rs6000.h1
-rw-r--r--gcc/doc/extend.texi18
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-1.c31
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-2.c31
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-3.c30
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb32-1.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb32-2.c27
12 files changed, 298 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a317c21..447f72f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2017-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org>
+
+ * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
+ array entries to represent two legal parameterizations of the
+ overloaded __builtin_cmpb function, as represented by the
+ P6_OV_BUILTIN_CMPB constant.
+ (altivec_resolve_overloaded_builtin): Add special case handling
+ for the __builtin_cmpb function, as represented by the
+ P6_OV_BUILTIN_CMPB constant.
+ * config/rs6000/rs6000-builtin.def (BU_P6_2): New macro.
+ (BU_P6_64BIT_2): New macro.
+ (BU_P6_OVERLOAD_2): New macro
+ (CMPB_32): Add 32-bit compare-bytes support for 32-bit only targets.
+ (CMPB): Add 64-bit compare-bytes support for 32-bit and 64-bit targets.
+ (CMPB): Add overload support to represent both 32-bit and 64-bit
+ compare-bytes function.
+ * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
+ support for TARGET_CMPB.
+ * config/rs6000/rs6000.h: Add support for RS6000_BTM_CMPB.
+ * doc/extend.texi (PowerPC AltiVec Built-in Functions): Add
+ documentation of the __builtin_cmpb overloaded built-in function.
+
2017-05-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/80705
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 50b1588..e5ab9d3 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -339,6 +339,34 @@
| RS6000_BTC_SPECIAL), \
CODE_FOR_nothing) /* ICODE */
+/* ISA 2.05 (power6) convenience macros. */
+/* For functions that depend on the CMPB instruction */
+#define BU_P6_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (P6_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_p6_" 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_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (P6_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_p6_" NAME, /* NAME */ \
+ RS6000_BTM_CMPB \
+ | RS6000_BTM_64BIT, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_P6_OVERLOAD_2(ENUM, NAME) \
+ RS6000_BUILTIN_2 (P6_OV_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_CMPB, /* MASK */ \
+ (RS6000_BTC_OVERLOADED /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_nothing) /* ICODE */
+
/* ISA 2.07 (power8) vector convenience macros. */
/* For the instructions that are encoded as altivec instructions use
__builtin_altivec_ as the builtin name. */
@@ -1787,6 +1815,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_2 (CMPB_32, "cmpb_32", CONST, cmpbsi3)
+BU_P6_64BIT_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)
@@ -1873,6 +1905,9 @@ BU_P8V_AV_P (VCMPEQUD_P, "vcmpequd_p", CONST, vector_eq_v2di_p)
BU_P8V_AV_P (VCMPGTSD_P, "vcmpgtsd_p", CONST, vector_gt_v2di_p)
BU_P8V_AV_P (VCMPGTUD_P, "vcmpgtud_p", CONST, vector_gtu_v2di_p)
+/* ISA 2.05 overloaded 2 argument functions. */
+BU_P6_OVERLOAD_2 (CMPB, "cmpb")
+
/* ISA 2.07 vector overloaded 1 argument functions. */
BU_P8V_OVERLOAD_1 (VUPKHSW, "vupkhsw")
BU_P8V_OVERLOAD_1 (VUPKLSW, "vupklsw")
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 3309f8d..ccf9cac 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -5362,6 +5362,11 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI,
RS6000_BTI_unsigned_V1TI, 0 },
+ { P6_OV_BUILTIN_CMPB, P6_BUILTIN_CMPB_32,
+ RS6000_BTI_UINTSI, RS6000_BTI_UINTSI, RS6000_BTI_UINTSI, 0 },
+ { P6_OV_BUILTIN_CMPB, P6_BUILTIN_CMPB,
+ RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, 0 },
+
{ P8V_BUILTIN_VEC_VUPKHSW, P8V_BUILTIN_VUPKHSW,
RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
{ P8V_BUILTIN_VEC_VUPKHSW, P8V_BUILTIN_VUPKHSW,
@@ -6424,17 +6429,48 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
for (desc = altivec_overloaded_builtins;
desc->code && desc->code != fcode; desc++)
continue;
-
- /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in
- the opX fields. */
- for (; desc->code == fcode; desc++)
+
+ /* Need to special case __builtin_cmp because the overloaded forms
+ of this function take (unsigned int, unsigned int) or (unsigned
+ long long int, unsigned long long int). Since C conventions
+ allow the respective argument types to be implicitly coerced into
+ each other, the default handling does not provide adequate
+ discrimination between the desired forms of the function. */
+ if (fcode == P6_OV_BUILTIN_CMPB)
{
- if ((desc->op1 == RS6000_BTI_NOT_OPAQUE
- || rs6000_builtin_type_compatible (types[0], desc->op1))
- && (desc->op2 == RS6000_BTI_NOT_OPAQUE
- || rs6000_builtin_type_compatible (types[1], desc->op2))
- && (desc->op3 == RS6000_BTI_NOT_OPAQUE
- || rs6000_builtin_type_compatible (types[2], desc->op3)))
+ int overloaded_code;
+ int arg1_mode = TYPE_MODE (types[0]);
+ int arg2_mode = TYPE_MODE (types[1]);
+
+ if (nargs != 2)
+ {
+ error ("__builtin_cmpb only accepts 2 arguments");
+ return error_mark_node;
+ }
+
+ /* If any supplied arguments are wider than 32 bits, resolve to
+ 64-bit variant of built-in function. */
+ if ((GET_MODE_PRECISION (arg1_mode) > 32)
+ || (GET_MODE_PRECISION (arg2_mode) > 32))
+ {
+ /* Assure all argument and result types are compatible with
+ the built-in function represented by P6_BUILTIN_CMPB. */
+ overloaded_code = P6_BUILTIN_CMPB;
+ }
+ else
+ {
+ /* Assure all argument and result types are compatible with
+ the built-in function represented by P6_BUILTIN_CMPB_32. */
+ overloaded_code = P6_BUILTIN_CMPB_32;
+ }
+
+ while (desc->code && desc->code == fcode &&
+ desc->overloaded_code != overloaded_code)
+ desc++;
+
+ if (desc->code && (desc->code == fcode)
+ && rs6000_builtin_type_compatible (types[0], desc->op1)
+ && rs6000_builtin_type_compatible (types[1], desc->op2))
{
if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
return altivec_build_resolved_builtin (args, n, desc);
@@ -6442,7 +6478,27 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
unsupported_builtin = true;
}
}
-
+ else
+ {
+ /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in
+ the opX fields. */
+ for (; desc->code == fcode; desc++)
+ {
+ if ((desc->op1 == RS6000_BTI_NOT_OPAQUE
+ || rs6000_builtin_type_compatible (types[0], desc->op1))
+ && (desc->op2 == RS6000_BTI_NOT_OPAQUE
+ || rs6000_builtin_type_compatible (types[1], desc->op2))
+ && (desc->op3 == RS6000_BTI_NOT_OPAQUE
+ || rs6000_builtin_type_compatible (types[2], desc->op3)))
+ {
+ if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
+ return altivec_build_resolved_builtin (args, n, desc);
+ else
+ unsupported_builtin = true;
+ }
+ }
+ }
+
if (unsupported_builtin)
{
const char *name = rs6000_overloaded_builtin_name (fcode);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e77026a..d55e552 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3873,6 +3873,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)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 3780a49..c4e98dd 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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: compare 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. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f2b3042..a163961 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -15107,6 +15107,24 @@ Similar to @code{__builtin_nans}, except the return type is @code{__float128}.
@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
+unsigned long long __builtin_cmpb (unsigned long long int, unsigned long long int);
+unsigned int __builtin_cmpb (unsigned int, unsigned int);
+@end smallexample
+
+The @code{__builtin_cmpb} function
+performs a byte-wise compare on the contents of its 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 the input bytes are equal and 0 if the input bytes
+are not equal. If either of the arguments to this built-in function
+is wider than 32 bits, the function call expands into the form that
+expects @code{unsigned long long int} arguments
+which is only available on 64-bit targets.
+
+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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1af2958..411996f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2017-05-11 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.
+
2017-05-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/80705
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-1.c b/gcc/testsuite/gcc.target/powerpc/cmpb-1.c
new file mode 100644
index 0000000..1f04a76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-1.c
@@ -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 ();
+
+unsigned long long int
+do_compare (unsigned long long int a, unsigned long long int b)
+{
+ return __builtin_cmpb (a, b);
+}
+
+void
+expect (unsigned long long int pattern, unsigned long long int value)
+{
+ if (pattern != value)
+ abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ expect (0xff00000000000000LL,
+ do_compare (0x0123456789abcdefLL, 0x0100000000000000LL));
+ expect (0x00ffffffffffffff,
+ do_compare (0x0123456789abcdefLL, 0x0023456789abcdefLL));
+ expect (0x00000000000000ff,
+ do_compare (0x00000000000000efLL, 0x0123456789abcdefLL));
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-2.c b/gcc/testsuite/gcc.target/powerpc/cmpb-2.c
new file mode 100644
index 0000000..4dde174
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-2.c
@@ -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 ();
+
+unsigned long long int
+do_compare (unsigned long long int a, unsigned long long int b)
+{
+ return __builtin_cmpb (a, b); /* { dg-warning "implicit declaration of function '__builtin_cmpb'" } */
+}
+
+void
+expect (unsigned long long int pattern, unsigned long long int value)
+{
+ if (pattern != value)
+ abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ expect (0xff00000000000000LL,
+ do_compare (0x0123456789abcdefLL, 0x0100000000000000LL));
+ expect (0x00ffffffffffffff,
+ do_compare (0x0123456789abcdefLL, 0x0023456789abcdefLL));
+ expect (0x00000000000000ff,
+ do_compare (0x00000000000000efLL, 0x0123456789abcdefLL));
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-3.c b/gcc/testsuite/gcc.target/powerpc/cmpb-3.c
new file mode 100644
index 0000000..edb62f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-3.c
@@ -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-error "Builtin function __builtin_cmpb not supported in this compiler configuration" } */
+}
+
+void expect (long long int pattern, long long int value)
+{
+ if (pattern != value)
+ abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ expect (0xff00000000000000LL,
+ do_compare (0x0123456789abcdefLL, 0x0100000000000000LL));
+ expect (0x00ffffffffffffff,
+ do_compare (0x0123456789abcdefLL, 0x0023456789abcdefLL));
+ expect (0x00000000000000ff,
+ do_compare (0x00000000000000efLL, 0x0123456789abcdefLL));
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb32-1.c b/gcc/testsuite/gcc.target/powerpc/cmpb32-1.c
new file mode 100644
index 0000000..6338ccf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb32-1.c
@@ -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 ();
+
+unsigned int
+do_compare (unsigned int a, unsigned int b)
+{
+ return __builtin_cmpb (a, b);
+}
+
+void
+expect (unsigned int pattern, unsigned 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));
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb32-2.c b/gcc/testsuite/gcc.target/powerpc/cmpb32-2.c
new file mode 100644
index 0000000..30403a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb32-2.c
@@ -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 ();
+
+unsigned int
+do_compare (unsigned int a, unsigned int b)
+{
+ return __builtin_cmpb (a, b); /* { dg-warning "implicit declaration of function '__builtin_cmpb'" } */
+}
+
+void
+expect (unsigned int pattern, unsigned 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));
+}