aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def25
-rw-r--r--gcc/config/rs6000/rs6000.c1
-rw-r--r--gcc/config/rs6000/rs6000.h1
-rw-r--r--gcc/config/rs6000/rs6000.md20
-rw-r--r--gcc/doc/extend.texi15
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-0.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-1.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-2.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-3.c14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-4.c14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-5.c26
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-6.c25
12 files changed, 184 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 399d9f69514..3d4c61c43f6 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -311,6 +311,27 @@
| 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. */
@@ -1510,6 +1531,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, cmpb_32)
+BU_P6_64BIT_CMPB_2 (CMPB, "cmpb", CONST, cmpb)
+
/* 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)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 0488db563e6..c1fdcd753c1 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3657,6 +3657,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 a438bfb1b23..caf44ce6a43 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2663,6 +2663,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 /* VMX/altivec vectors. */
#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/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 349bcca62e4..bdb3f2af831 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -147,6 +147,8 @@
UNSPEC_ROUND_TO_ODD
UNSPEC_IEEE128_MOVE
UNSPEC_IEEE128_CONVERT
+ UNSPEC_CMPB
+ UNSPEC_CMPB_32
])
;;
@@ -1554,6 +1556,24 @@
emit_insn (gen_addsi3 (result, result, constm1_rtx));
DONE;
})
+
+(define_insn "cmpb_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_CMPB_32))]
+ "TARGET_CMPB"
+ "cmpb %0,%1,%2"
+ [(set_attr "type" "integer")])
+
+(define_insn "cmpb"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "register_operand" "r")]
+ UNSPEC_CMPB))]
+ "TARGET_CMPB && TARGET_64BIT"
+ "cmpb %0,%1,%2"
+ [(set_attr "type" "integer")])
;; Fixed-point arithmetic insns.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5199134ca3c..dbd7dd9e6bc 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -14664,6 +14664,21 @@ returns the Time Base Register value as an unsigned long, throwing away
the most significant word on 32-bit environments.
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 in 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 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/gcc.target/powerpc/cmpb-0.c b/gcc/testsuite/gcc.target/powerpc/cmpb-0.c
new file mode 100644
index 00000000000..13eb0db9ff8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-0.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power6" } */
+
+/* This test should succeed on both 32- and 64-bit configurations. */
+#include <altivec.h>
+
+int int cmpb_32 (int arg1, int arg2)
+{
+ return __builtin_cmpb_32 (arg1, arg2);
+}
+
+/* { dg-final { scan-assembler "cmpb" } } */
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 00000000000..76a83f63fbd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power6" } */
+/* { dg-require-effective-target lp64 } */
+
+/* This test should succeed on only 64-bit configurations. */
+#include <altivec.h>
+
+int int cmpb (int arg1, int arg2)
+{
+ return __builtin_cmpb (arg1, arg2);
+}
+
+/* { dg-final { scan-assembler "cmpb" } } */
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 00000000000..2b146bf3da5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-2.c
@@ -0,0 +1,18 @@
+/* Only run this test on big-endian powerpc, because only big-endian
+ * supports a -m32 command-line option */
+/* { dg-do compile { target { powerpc-*-* } } } */
+/* { dg-options "-mcpu=power6 -m32" } */
+
+/* This test should result in a compile-time error because the
+ * __builtin_cmpb () function is not supported in 32-bit mode.
+ */
+#include <altivec.h>
+
+int int cmpb (int arg1, int arg2)
+{
+
+ /* { dg-error "replace this string with regexp that matches error message" } */
+ return __builtin_cmpb (arg1, arg2);
+}
+
+/* { dg-final { scan-assembler "cmpb" } } */
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 00000000000..b33621f7a9a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power5" } */
+
+/* This test should result in a compile-time warning because the
+ * __builtin_cmpb () function is not supported when -mcpu=power5
+ */
+#include <altivec.h>
+
+int int cmpb (int arg1, int arg2)
+{
+ /* { dg-warning "implicit declaration of function" } */
+ return __builtin_cmpb (arg1, arg2);
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-4.c b/gcc/testsuite/gcc.target/powerpc/cmpb-4.c
new file mode 100644
index 00000000000..a030094b975
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power5" } */
+
+/* This test should result in a compile-time warning because the
+ * __builtin_cmpb () function is not supported when -mcpu=power5
+ */
+#include <altivec.h>
+
+int int cmpb (int arg1, int arg2)
+{
+ /* { dg-warning "implicit declaration of function" } */
+ return __builtin_cmpb_32 (arg1, arg2);
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-5.c b/gcc/testsuite/gcc.target/powerpc/cmpb-5.c
new file mode 100644
index 00000000000..071e305ca08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-5.c
@@ -0,0 +1,26 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power6" } */
+
+/* This test should succeed on both 32- and 64-bit configurations. */
+#include <altivec.h>
+
+int int cmpb_32 (int arg1, int arg2)
+{
+ return __builtin_cmpb_32 (arg1, arg2);
+}
+
+int main (int argc, char *argv[])
+{
+ int i, j;
+
+ i = 0x01020304;
+ j = 0x01050304;
+
+ if (cmpb_32 (i, j) != 0xff00ffff)
+ return -2;
+ else
+ return 0;
+}
+
+
+
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-6.c b/gcc/testsuite/gcc.target/powerpc/cmpb-6.c
new file mode 100644
index 00000000000..bb7acd7c73e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-6.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-do run "-mcpu=power6" } */
+/* { dg-require-effective-target lp64 } */
+
+/* This test should succeed on only 64-bit configurations. */
+#include <altivec.h>
+
+int int cmpb (int arg1, int arg2)
+{
+ return __builtin_cmpb (arg1, arg2);
+}
+
+int main (int argc, char *argv[])
+{
+ long long a, b;
+
+ a = 0x0102030405060708L;
+ b = 0x0102030405060503L;
+
+ if (cmpb (a, b) != 0xffffffffffff0000)
+ return -1;
+ else
+ return 0;
+}
+