This patch adds built-in function support for the ISA 3.0 vabsub, 
vabsduh, and vabsduw instructions.

I have bootstrapped and tested on powerpc64le-unkonwn-linux-gnu with no 
regressions.  Is this ok for the trunk?

I have also tested against the gcc-6 branch without regressions.  Is 
this ok for backporting to gcc6 after a few days of burn-in time on the 
trunk?

gcc/testsuite/ChangeLog:

2016-06-06  Kelvin Nilsen  <kel...@gcc.gnu.org>

        * gcc.target/powerpc/vadsdu-0.c: New test.
        * gcc.target/powerpc/vadsdu-1.c: New test.
        * gcc.target/powerpc/vadsdu-2.c: New test.
        * gcc.target/powerpc/vadsdu-3.c: New test.
        * gcc.target/powerpc/vadsdu-4.c: New test.
        * gcc.target/powerpc/vadsdu-5.c: New test.
        * gcc.target/powerpc/vadsdub-1.c: New test.
        * gcc.target/powerpc/vadsdub-2.c: New test.
        * gcc.target/powerpc/vadsduh-1.c: New test.
        * gcc.target/powerpc/vadsduh-2.c: New test.
        * gcc.target/powerpc/vadsduw-1.c: New test.
        * gcc.target/powerpc/vadsduw-2.c: New test.


gcc/ChangeLog:

2016-06-06  Kelvin Nilsen  <kel...@gcc.gnu.org>

        * config/rs6000/altivec.h (vec_adu): New macro for vector absolute
        difference unsigned.
        (vec_adub): New macro for vector absolute difference unsigned
        byte.
        (vec_aduh): New macro for vector absolute difference unsigned
        half-word. 
        (vec_aduw): New macro for vector absolute difference unsigned word.
        * config/rs6000/altivec.md (UNSPEC_VADU): New value.
        (vadu<mode>3): New insn.
        (*p9_vadu<mode>3): New insn.
        * config/rs6000/rs6000-builtin.def (vadub): New built-in
        definition.
        (vaduh): New built-in definition.
        (vaduw): New built-in definition.
        (vadu): New overloaded built-in definition.
        (vadub): New overloaded built-in definition.
        (vaduh): New overloaded built-in definition.
        (vaduw): New overloaded built-in definition.
        * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
        overloaded vector absolute difference unsigned functions.
        * doc/extend.texi (PowerPC AltiVec Built-in Functions): Document
        the ISA 3.0 vector absolute difference unsigned built-in functions.

Index: gcc/config/rs6000/altivec.h
===================================================================
--- gcc/config/rs6000/altivec.h (revision 237045)
+++ gcc/config/rs6000/altivec.h (working copy)
@@ -401,6 +401,11 @@
 #define vec_vprtybq __builtin_vec_vprtybq
 #endif
 
+#define vec_adu __builtin_vec_vadu
+#define vec_adub __builtin_vec_vadub
+#define vec_aduh __builtin_vec_vaduh
+#define vec_aduw __builtin_vec_vaduw
+
 #define vec_slv __builtin_vec_vslv
 #define vec_srv __builtin_vec_vsrv
 #endif
Index: gcc/config/rs6000/altivec.md
===================================================================
--- gcc/config/rs6000/altivec.md        (revision 237045)
+++ gcc/config/rs6000/altivec.md        (working copy)
@@ -114,6 +114,7 @@
    UNSPEC_STVLXL
    UNSPEC_STVRX
    UNSPEC_STVRXL
+   UNSPEC_VADU
    UNSPEC_VSLV
    UNSPEC_VSRV
    UNSPEC_VMULWHUB
@@ -3464,6 +3465,25 @@
   [(set_attr "length" "4")
    (set_attr "type" "vecsimple")])
 
+;; Vector absolute difference unsigned
+(define_expand "vadu<mode>3"
+  [(set (match_operand:VI 0 "register_operand" "")
+        (unspec:VI [(match_operand:VI 1 "register_operand" "")
+                   (match_operand:VI 2 "register_operand" "")]
+         UNSPEC_VADU))]
+  "TARGET_P9_VECTOR")
+
+;; Vector absolute difference unsigned
+(define_insn "*p9_vadu<mode>3"
+  [(set (match_operand:VI 0 "register_operand" "=v")
+        (unspec:VI [(match_operand:VI 1 "register_operand" "v")
+                   (match_operand:VI 2 "register_operand" "v")]
+         UNSPEC_VADU))]
+  "TARGET_P9_VECTOR"
+  "vabsdu<wd> %0, %1, %2"
+  [(set_attr "type" "add")
+   (set_attr "length" "4")])
+
 ;; Vector count trailing zeros
 (define_insn "*p9v_ctz<mode>2"
   [(set (match_operand:VI2 0 "register_operand" "=v")
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def        (revision 237045)
+++ gcc/config/rs6000/rs6000-builtin.def        (working copy)
@@ -1757,6 +1757,17 @@ BU_P9V_AV_2 (VSRV,               "vsrv",                 
CONST, vsrv)
 BU_P9V_OVERLOAD_2 (VSLV,       "vslv")
 BU_P9V_OVERLOAD_2 (VSRV,       "vsrv")
 
+/* 2 argument vector functions added in ISA 3.0 (power9). */
+BU_P9V_AV_2 (VADUB,            "vadub",                CONST,  vaduv16qi3)
+BU_P9V_AV_2 (VADUH,            "vaduh",                CONST,  vaduv8hi3)
+BU_P9V_AV_2 (VADUW,            "vaduw",                CONST,  vaduv4si3)
+
+/* ISA 3.0 vector overloaded 2 argument functions. */
+BU_P9V_OVERLOAD_2 (VADU,       "vadu")
+BU_P9V_OVERLOAD_2 (VADUB,      "vadub")
+BU_P9V_OVERLOAD_2 (VADUH,      "vaduh")
+BU_P9V_OVERLOAD_2 (VADUW,      "vaduw")
+
 
 /* 2 argument extended divide functions added in ISA 2.06.  */
 BU_P7_MISC_2 (DIVWE,           "divwe",        CONST,  dive_si)
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c        (revision 237045)
+++ gcc/config/rs6000/rs6000-c.c        (working copy)
@@ -4247,6 +4247,28 @@ const struct altivec_builtin_types altivec_overloa
   { P9V_BUILTIN_VEC_VCTZD, P9V_BUILTIN_VCTZD,
     RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 },
 
+  { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUB,
+    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
+    RS6000_BTI_unsigned_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUH,
+    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
+    RS6000_BTI_unsigned_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUW,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_unsigned_V4SI, 0 },
+
+  { P9V_BUILTIN_VEC_VADUB, P9V_BUILTIN_VADUB,
+    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
+    RS6000_BTI_unsigned_V16QI, 0 },
+
+  { P9V_BUILTIN_VEC_VADUH, P9V_BUILTIN_VADUH,
+    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
+    RS6000_BTI_unsigned_V8HI, 0 },
+
+  { P9V_BUILTIN_VEC_VADUW, P9V_BUILTIN_VADUW,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_unsigned_V4SI, 0 },
+
   { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
     RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
   { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 237045)
+++ gcc/doc/extend.texi (working copy)
@@ -17375,6 +17375,31 @@ result returned from the @code{vec_srv} function i
 (0x07 & shift_distance[i]))},
 with this resulting value coerced to the @code{unsigned char} type.
 
+The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 3.0 or later (@option{-mcpu=power9})
+or with @option{-mpower9-vector}:
+@smallexample
+__vector unsigned char
+vec_adu (__vector unsigned char arg1, __vector unsigned char arg2);
+__vector unsighed short
+vec_adu (__vector unsigned short arg1, __vector unsigned short arg2);
+__vector unsigned int
+vec_adu (__vector unsigned int arg1, __vector unsigned int arg2);
+
+__vector unsigned char
+vec_adub (__vector unsigned char arg1, __vector unsigned char arg2);
+__vector unsighed short
+vec_aduh (__vector unsigned short arg1, __vector unsigned short arg2);
+__vector unsigned int
+vec_aduw (__vector unsigned int arg1, __vector unsigned int arg2);
+@end smallexample
+
+The @code{vec_adu}, @code{vec_adub}, @code{vec_aduh}, and
+@code{vec_aduw} built-in functions each computes the absolute
+differences of the pairs of vector elements supplied in its two vector
+arguments, placing the absolute differences into the corresponding
+elements of the vector result.
+
 If the cryptographic instructions are enabled (@option{-mcrypto} or
 @option{-mcpu=power8}), the following builtins are enabled.
 
Index: gcc/testsuite/gcc.target/powerpc/vadsdu-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdu-0.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdu-0.c (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned int
+doAbsoluteDifferenceUnsignedInt (__vector unsigned int *p,
+                                __vector unsigned int *q)
+{
+  __vector unsigned int source_1, source_2;
+  __vector unsigned int result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = __builtin_vec_vadu (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsduw" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdu-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdu-1.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdu-1.c (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned int
+doAbsoluteDifferenceUnsignedIntMacro (__vector unsigned int *p,
+                                     __vector unsigned int *q)
+{
+  __vector unsigned int result, source_1, source_2;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = vec_adu (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsduw" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdu-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdu-2.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdu-2.c (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned short
+doAbsoluteDifferenceUnsignedShort (__vector unsigned short *p,
+                                  __vector unsigned short *q)
+{
+  __vector unsigned short source_1, source_2;
+  __vector unsigned short result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = __builtin_vec_vadu (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsduh" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdu-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdu-3.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdu-3.c (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned short
+doAbsoluteDifferenceUnsignedShortMacro (__vector unsigned short *p,
+                                     __vector unsigned short *q)
+{
+  __vector unsigned short result, source_1, source_2;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = vec_adu (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsduh" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdu-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdu-4.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdu-4.c (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned char
+doAbsoluteDifferenceUnsignedChar (__vector unsigned char *p,
+                                 __vector unsigned char *q)
+{
+  __vector unsigned char source_1, source_2;
+  __vector unsigned char result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = __builtin_vec_vadu (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsdub" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdu-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdu-5.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdu-5.c (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned char
+doAbsoluteDifferenceUnsignedCharMacro (__vector unsigned char *p,
+                                      __vector unsigned char *q)
+{
+  __vector unsigned char result, source_1, source_2;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = vec_adu (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsdub" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdub-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdub-1.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdub-1.c        (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned char
+doAbsoluteDifferenceUnsigned (__vector unsigned char *p,
+                             __vector unsigned char *q)
+{
+  __vector unsigned char source_1, source_2;
+  __vector unsigned char uc_result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  uc_result = __builtin_vec_vadub (source_1, source_2);
+  return uc_result;
+}
+
+/* { dg-final { scan-assembler "vabsdub" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsdub-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsdub-2.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsdub-2.c        (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned char
+doAbsoluteDifferenceUnsigned (__vector unsigned char *p,
+                             __vector unsigned char *q)
+{
+  __vector unsigned char source_1, source_2;
+  __vector unsigned char uc_result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  uc_result = __builtin_vec_vadub (source_1, source_2);
+  return uc_result;
+}
+
+/* { dg-final { scan-assembler "vabsdub" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsduh-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsduh-1.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsduh-1.c        (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned short
+doAbsoluteDifferenceUnsigned (__vector unsigned short *p,
+                             __vector unsigned short *q)
+{
+  __vector unsigned short source_1, source_2;
+  __vector unsigned short us_result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  us_result = __builtin_vec_vaduh (source_1, source_2);
+  return us_result;
+}
+
+/* { dg-final { scan-assembler "vabsduh" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsduh-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsduh-2.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsduh-2.c        (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned short
+doAbsoluteDifferenceUnsignedMacro (__vector unsigned short *p,
+                                  __vector unsigned short *q)
+{
+  __vector unsigned short result, source_1, source_2;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = vec_aduh (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsduh" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsduw-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsduw-1.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsduw-1.c        (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned int
+doAbsoluteDifferenceUnsigned (__vector unsigned int *p,
+                             __vector unsigned int *q)
+{
+  __vector unsigned int source_1, source_2;
+  __vector unsigned int ui_result;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  ui_result = __builtin_vec_vaduw (source_1, source_2);
+  return ui_result;
+}
+
+/* { dg-final { scan-assembler "vabsduw" } } */
Index: gcc/testsuite/gcc.target/powerpc/vadsduw-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vadsduw-2.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vadsduw-2.c        (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+__vector unsigned int
+doAbsoluteDifferenceUnsignedMacro (__vector unsigned int *p,
+                                  __vector unsigned int *q)
+{
+  __vector unsigned int result, source_1, source_2;
+
+  source_1 = *p;
+  source_2 = *q;
+
+  result = vec_aduw (source_1, source_2);
+  return result;
+}
+
+/* { dg-final { scan-assembler "vabsduw" } } */

Reply via email to