rs6000: Add vcfuged instruction
authorKelvin Nilsen <kelvin@gcc.gnu.org>
Mon, 11 May 2020 16:41:23 +0000 (11:41 -0500)
committerBill Schmidt <wschmidt@linux.ibm.com>
Mon, 11 May 2020 16:41:23 +0000 (11:41 -0500)
Add the new vector centrifuge-doubleword instruction and built-in
function access.

[gcc]

2020-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>

* config/rs6000/altivec.h (vec_cfuge): New #define.
* config/rs6000/altivec.md (UNSPEC_VCFUGED): New constant.
(vcfuged): New insn.
* config/rs6000/rs6000-builtin.def (__builtin_altivec_vcfuged):
New built-in function.
* config/rs6000/rs6000-call.c (builtin_function_type): Add
handling for FUTURE_BUILTIN_VCFUGED case.
* doc/extend.texi (PowerPC AltiVec Built-in Functions Available
for a Future Architecture): Add description of vec_cfuge built-in
function.

[gcc/testsuite]

2020-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>

* gcc.target/powerpc/vec-cfuged-0.c: New test.
* gcc.target/powerpc/vec-cfuged-1.c: New test.

gcc/ChangeLog
gcc/config/rs6000/altivec.h
gcc/config/rs6000/altivec.md
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000-call.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/vec-cfuged-0.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-cfuged-1.c [new file with mode: 0644]

index 1440b2f13619204b736ab711c2706be453a73428..7933c2c3a6f8c5ad319189c60601c01cb0f19ecf 100644 (file)
@@ -1,3 +1,16 @@
+2020-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>
+
+       * config/rs6000/altivec.h (vec_cfuge): New #define.
+       * config/rs6000/altivec.md (UNSPEC_VCFUGED): New constant.
+       (vcfuged): New insn.
+       * config/rs6000/rs6000-builtin.def (__builtin_altivec_vcfuged):
+       New built-in function.
+       * config/rs6000/rs6000-call.c (builtin_function_type): Add
+       handling for FUTURE_BUILTIN_VCFUGED case.
+       * doc/extend.texi (PowerPC AltiVec Built-in Functions Available
+       for a Future Architecture): Add description of vec_cfuge built-in
+       function.
+
 2020-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * config/rs6000/rs6000-builtin.def (BU_FUTURE_MISC_0): New
index b6ecad6911d885b46d5ad40e2a3af6ef3c7f7ae5..0ecd961485baa85577c1f55c886d5c5dcf75630a 100644 (file)
@@ -693,6 +693,7 @@ __altivec_scalar_pred(vec_any_nle,
 #define vec_ctzm(a, b) __builtin_altivec_vctzdm (a, b)
 #define vec_pdep(a, b) __builtin_altivec_vpdepd (a, b)
 #define vec_pext(a, b) __builtin_altivec_vpextd (a, b)
+#define vec_cfuge(a, b)        __builtin_altivec_vcfuged (a, b)
 
 /* Overloaded built-in functions for future architecture.  */
 #define vec_gnb(a, b)  __builtin_vec_gnb (a, b)
index 7cebb58331e306e037ce0772e9fdbf795fb5fdb9..1400724fb582929017ef99789700198bb8b9761d 100644 (file)
    UNSPEC_BCD_OVERFLOW
    UNSPEC_VRLMI
    UNSPEC_VRLNM
+   UNSPEC_VCFUGED
    UNSPEC_VCLZDM
    UNSPEC_VCTZDM
    UNSPEC_VGNB
   "bcd<bcd_add_sub>. %0,%1,%2,%3"
   [(set_attr "type" "vecsimple")])
 
+(define_insn "vcfuged"
+  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+       (unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "v")
+                     (match_operand:V2DI 2 "altivec_register_operand" "v")]
+        UNSPEC_VCFUGED))]
+   "TARGET_FUTURE"
+   "vcfuged %0,%1,%2"
+   [(set_attr "type" "vecsimple")])
+
 (define_insn "vclzdm"
   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
        (unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "v")
index afc8487515f431a7b590fc68b030e58610e31ef9..9d80d03fe5047ae5eb30b068a670afcb857fa28b 100644 (file)
@@ -2577,6 +2577,7 @@ BU_P9_OVERLOAD_2 (CMPEQB, "byte_in_set")
 BU_FUTURE_MISC_2 (CFUGED, "cfuged", CONST, cfuged)
 
 /* Future architecture vector built-ins.  */
+BU_FUTURE_V_2 (VCFUGED, "vcfuged", CONST, vcfuged)
 BU_FUTURE_V_2 (VCLZDM, "vclzdm", CONST, vclzdm)
 BU_FUTURE_V_2 (VCTZDM, "vctzdm", CONST, vctzdm)
 BU_FUTURE_V_2 (VPDEPD, "vpdepd", CONST, vpdepd)
index 952f17c6854bacf515aece9b6214bd4028a7a3e9..c3ba6b93c46af800fe27f45f38054681be46b898 100644 (file)
@@ -12951,6 +12951,7 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
     case P8V_BUILTIN_ORC_V4SI_UNS:
     case P8V_BUILTIN_ORC_V2DI_UNS:
     case P8V_BUILTIN_ORC_V1TI_UNS:
+    case FUTURE_BUILTIN_VCFUGED:
     case FUTURE_BUILTIN_VCLZDM:
     case FUTURE_BUILTIN_VCTZDM:
     case FUTURE_BUILTIN_VGNB:
index 8b5a51a6973a024ca8f9d74703673b47b792bd1a..f7b30c7ead744469b425f2e5960c46fdc2ecd782 100644 (file)
@@ -20719,6 +20719,15 @@ PowerPC family of processors, starting with a hypothetical CPU
 which may or may not be available in the future
 (@option{-mcpu=future}) or later:
 
+
+@smallexample
+@exdent vector unsigned long long int
+@exdent vec_cfuge (vector unsigned long long int, vector unsigned long long int)
+@end smallexample
+Perform a vector centrifuge operation, as if implemented by the Future
+@code{vcfuged} instruction.
+@findex vec_cfuge
+
 @smallexample
 @exdent vector unsigned long long int
 @exdent vec_clzm (vector unsigned long long int, vector unsigned long long int)
index ed9b0d5505246c4cb2f3e6714e5de0b3d0933221..8bd3ef092afc3da04aff3a5ae2cb03683511fc4b 100644 (file)
@@ -1,3 +1,8 @@
+2020-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>
+
+       * gcc.target/powerpc/vec-cfuged-0.c: New test.
+       * gcc.target/powerpc/vec-cfuged-1.c: New test.
+
 2020-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * gcc.target.powerpc/cfuged-0.c: New test.
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-cfuged-0.c b/gcc/testsuite/gcc.target/powerpc/vec-cfuged-0.c
new file mode 100644 (file)
index 0000000..74528a4
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned long long int
+do_vec_cfuge (vector unsigned long long int source,
+             vector unsigned long long int mask)
+{
+  return vec_cfuge (source, mask);
+}
+
+int
+vectors_equal (vector unsigned long long int a,
+              vector unsigned long long int b)
+{
+  return (a[0] == b[0]) && (a[1] == b[1]);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned long long int source_a = { 0xa5f07e3cull, 0x7e3ca5f0ull };
+  vector unsigned long long int source_b = { 0x3ca5f07eull, 0x5a0fe7c3ull };
+
+  vector unsigned long long int mask_a = { 0xffff0000ull, 0x0000ffffull };
+  vector unsigned long long int mask_b = { 0x0f0f0f0full, 0xf0f0f0f0ull };
+
+  /* See cfuged-0.c for derivation of expected results.
+
+     result_aa [0] is compute (source [0], mask [0];
+     result_aa [1] is compute (source [1], mask [1].
+
+     result_ab [0] is compute (source [0], mask [2];
+     result_ab [1] is compute (source [1], mask [3].
+
+     result_ba [0] is compute (source [2], mask [0];
+     result_ba [1] is compute (source [3], mask [1].
+
+     result_bb [0] is compute (source [2], mask [2];
+     result_bb [1] is compute (source [3], mask [3].  */
+
+  vector unsigned long long int result_aa = { 0x7e3ca5f0ull, 0x7e3ca5f0ull };
+  vector unsigned long long int result_ab = { 0xaf7350ecull, 0xec5073afull };
+  vector unsigned long long int result_ba = { 0xf07e3ca5ull, 0x5a0fe7c3ull };
+  vector unsigned long long int result_bb = { 0x3af7c50eull, 0xaf7350ecull };
+
+  if (!vectors_equal (do_vec_cfuge (source_a, mask_a), result_aa))
+    abort ();
+  if (!vectors_equal (do_vec_cfuge (source_a, mask_b), result_ab))
+    abort ();
+  if (!vectors_equal (do_vec_cfuge (source_b, mask_a), result_ba))
+    abort ();
+  if (!vectors_equal (do_vec_cfuge (source_b, mask_b), result_bb))
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\mvcfuged\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-cfuged-1.c b/gcc/testsuite/gcc.target/powerpc/vec-cfuged-1.c
new file mode 100644 (file)
index 0000000..2c80135
--- /dev/null
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned long long int
+do_vec_cfuge (vector unsigned long long int source,
+             vector unsigned long long int mask)
+{
+  return vec_cfuge (source, mask);
+}
+
+int
+vectors_equal (vector unsigned long long int a,
+              vector unsigned long long int b)
+{
+  return (a[0] == b[0]) && (a[1] == b[1]);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned long long int source_a = { 0xa5f07e3cull, 0x7e3ca5f0ull };
+  vector unsigned long long int source_b = { 0x3ca5f07eull, 0x5a0fe7c3ull };
+
+  vector unsigned long long int mask_a = { 0xffff0000ull, 0x0000ffffull };
+  vector unsigned long long int mask_b = { 0x0f0f0f0full, 0xf0f0f0f0ull };
+
+  /* See cfuged-0.c for derivation of expected results.
+
+     result_aa [0] is compute (source [0], mask [0];
+     result_aa [1] is compute (source [1], mask [1].
+
+     result_ab [0] is compute (source [0], mask [2];
+     result_ab [1] is compute (source [1], mask [3].
+
+     result_ba [0] is compute (source [2], mask [0];
+     result_ba [1] is compute (source [3], mask [1].
+
+     result_bb [0] is compute (source [2], mask [2];
+     result_bb [1] is compute (source [3], mask [3].  */
+
+  vector unsigned long long int result_aa = { 0x7e3ca5f0ull, 0x7e3ca5f0ull };
+  vector unsigned long long int result_ab = { 0xaf7350ecull, 0xec5073afull };
+  vector unsigned long long int result_ba = { 0xf07e3ca5ull, 0x5a0fe7c3ull };
+  vector unsigned long long int result_bb = { 0x3af7c50eull, 0xaf7350ecull };
+
+  if (!vectors_equal (do_vec_cfuge (source_a, mask_a), result_aa))
+    abort ();
+  if (!vectors_equal (do_vec_cfuge (source_a, mask_b), result_ab))
+    abort ();
+  if (!vectors_equal (do_vec_cfuge (source_b, mask_a), result_ba))
+    abort ();
+  if (!vectors_equal (do_vec_cfuge (source_b, mask_b), result_bb))
+    abort ();
+
+  return 0;
+}