public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] rs6000, vector integer multiply/divide/modulo instructions
@ 2020-10-30 20:07 Carl Love
  2020-10-30 21:05 ` David Edelsohn
  2020-10-31 13:28 ` David Edelsohn
  0 siblings, 2 replies; 22+ messages in thread
From: Carl Love @ 2020-10-30 20:07 UTC (permalink / raw)
  To: dje.gcc, gcc-patches, Will Schmidt, Segher Boessenkool

GCC maintainers:

The following patch adds new builtins for the vector integer multiply,
divide and modulo operations.  The builtins are:  
vec_mulh(), vec_div(), vec_dive(), vec_mod() for signed and unsigned
integers and long long integers.  Support for signed and unsigned long
long integers the exiting vec_mul() is added.  Note that the existing
support for the vec_div()and vec_mul() builtins emulate the vector
operations with multiple scalar instructions.  This patch adds support
for these builtins to use the new vector instructions.

The patch was compiled and tested on:

  powerpc64le-unknown-linux-gnu (Power 9 LE)

with no regressions. Additionally the new test case was compiled and
executed by hand on Mambo to verify the test case passes.

Please let me know if this patch is acceptable for mainline.  Thanks.

                Carl Love

-------------------------------------------------------------

2020-10-30  Carl Love  <cel@us.ibm.com>

gcc/
	* config/rs6000/altivec.h (vec_mulh, vec_div, vec_dive, vec_mod): New
	defines.
	* config/rs6000/altivec.md (VIlong): Move define to file vector.md.
	* config/rs6000/rs6000-builtin.def (VDIVES_V4SI, VDIVES_V2DI,
	VDIVEU_V4SI, VDIVEU_V2DI, VDIVS_V4SI, VDIVS_V2DI, VDIVU_V4SI,
	VDIVU_V2DI, VMODS_V2DI, VMODS_V4SI, VMODU_V2DI, VMODU_V4SI, VMULHS_V2DI,
	VMULHS_V4SI, VMULHU_V2DI, VMULHU_V4SI, VMULLD_V2DI): Add builtin define.
	(VMUL, VMULH, VDIVE, VMOD):  Add new BU_P10_OVERLOAD_2 definitions.
	* config/rs6000/rs6000-call.c (VSX_BUILTIN_VEC_DIV, P10_BUILTIN_VEC_VDIVE,
	P10_BUILTIN_VEC_VMOD, P10_BUILTIN_VEC_VMULH): New overloaded definitions.
	(builtin_function_type)
	[P10V_BUILTIN_VDIVEU_V4SI, P10V_BUILTIN_VDIVEU_V2DI,
	P10V_BUILTIN_VDIVU_V4SI, P10V_BUILTIN_VDIVU_V2DI,
	P10V_BUILTIN_VMODU_V2DI, P10V_BUILTIN_VMODU_V4SI, P10V_BUILTIN_VMULHU_V2DI,
	P10V_BUILTIN_VMULHU_V4SI, P10V_BUILTIN_VMULLD_V2DI]: Add case statement
	for builtins.
	* config/rs6000/vector.md (UNSPEC_VDIVES, UNSPEC_VDIVEU, UNSPEC_VMULHS,
	UNSPEC_VMULHU, UNSPEC_VMULLD): Add enum for UNSPECs.
	(VIlong_char): Add define_mod_attribute.
	(vdives_<mode>, vdiveu_<mode>, vdiv<mode>3, uuvdiv<mode>3, vdivs_<mode>,
	vdivu_<mode>, vmods_<mode>, vmodu_<mode>, vmulhs_<mode>, vmulhu_<mode>,
	mulv2di3): Add define_insn, mode is VIlong.
	config/rs6000/vsx.md (vsx_mul_v2di, vsx_udiv_v2di): Add if (TARGET_POWER10)
	statement.
	* doc/extend.texi (vec_mulh, vec_mul, vec_div, vec_dive, vec_mod): Add
	builtin descriptions.

gcc/testsuite/
	* gcc.target/powerpc/builtins-1-p10-runnable.c: New test file.
---
 gcc/config/rs6000/altivec.h                   |   5 +
 gcc/config/rs6000/altivec.md                  |   2 -
 gcc/config/rs6000/rs6000-builtin.def          |  23 ++
 gcc/config/rs6000/rs6000-call.c               |  49 +++
 gcc/config/rs6000/vector.md                   | 104 +++++
 gcc/config/rs6000/vsx.md                      | 118 +++---
 gcc/doc/extend.texi                           | 120 ++++++
 .../powerpc/builtins-1-p10-runnable.c         | 378 ++++++++++++++++++
 8 files changed, 747 insertions(+), 52 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-1-p10-runnable.c

diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index df10a8c498d..b2803e52d93 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -725,6 +725,11 @@ __altivec_scalar_pred(vec_any_nle,
 #define vec_strir_p(a)	__builtin_vec_strir_p (a)
 #define vec_stril_p(a)	__builtin_vec_stril_p (a)
 
+#define vec_mulh(a, b) __builtin_vec_mulh (a, b)
+#define vec_div(a, b) __builtin_vec_div (a, b)
+#define vec_dive(a, b) __builtin_vec_dive (a, b)
+#define vec_mod(a, b) __builtin_vec_mod (a, b)
+
 /* VSX Mask Manipulation builtin. */
 #define vec_genbm __builtin_vec_mtvsrbm
 #define vec_genhm __builtin_vec_mtvsrhm
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 0a2e634d6b0..8e80c681b11 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -192,8 +192,6 @@
 
 ;; Short vec int modes
 (define_mode_iterator VIshort [V8HI V16QI])
-;; Longer vec int modes for rotate/mask ops
-(define_mode_iterator VIlong [V2DI V4SI])
 ;; Vec float modes
 (define_mode_iterator VF [V4SF])
 ;; Vec modes, pity mode iterators are not composable
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 5b05da87f4b..706527dcd3a 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2830,6 +2830,24 @@ BU_P10V_AV_3 (VSRDB_V8HI, "vsrdb_v8hi", CONST, vsrdb_v8hi)
 BU_P10V_AV_3 (VSRDB_V4SI, "vsrdb_v4si", CONST, vsrdb_v4si)
 BU_P10V_AV_3 (VSRDB_V2DI, "vsrdb_v2di", CONST, vsrdb_v2di)
 
+BU_P10V_AV_2 (VDIVES_V4SI, "vdivesw", CONST, vdives_v4si)
+BU_P10V_AV_2 (VDIVES_V2DI, "vdivesd", CONST, vdives_v2di)
+BU_P10V_AV_2 (VDIVEU_V4SI, "vdiveuw", CONST, vdiveu_v4si)
+BU_P10V_AV_2 (VDIVEU_V2DI, "vdiveud", CONST, vdiveu_v2di)
+BU_P10V_AV_2 (VDIVS_V4SI, "vdivsw", CONST, vdivs_v4si)
+BU_P10V_AV_2 (VDIVS_V2DI, "vdivsd", CONST, vdivs_v2di)
+BU_P10V_AV_2 (VDIVU_V4SI, "vdivuw", CONST, vdivu_v4si)
+BU_P10V_AV_2 (VDIVU_V2DI, "vdivud", CONST, vdivu_v2di)
+BU_P10V_AV_2 (VMODS_V2DI, "vmodsd", CONST, vmods_v2di)
+BU_P10V_AV_2 (VMODS_V4SI, "vmodsw", CONST, vmods_v4si)
+BU_P10V_AV_2 (VMODU_V2DI, "vmodud", CONST, vmodu_v2di)
+BU_P10V_AV_2 (VMODU_V4SI, "vmoduw", CONST, vmodu_v4si)
+BU_P10V_AV_2 (VMULHS_V2DI, "vmulhsd", CONST, vmulhs_v2di)
+BU_P10V_AV_2 (VMULHS_V4SI, "vmulhsw", CONST, vmulhs_v4si)
+BU_P10V_AV_2 (VMULHU_V2DI, "vmulhud", CONST, vmulhu_v2di)
+BU_P10V_AV_2 (VMULHU_V4SI, "vmulhuw", CONST, vmulhu_v4si)
+BU_P10V_AV_2 (VMULLD_V2DI, "vmulld", CONST, mulv2di3)
+
 BU_P10V_VSX_1 (VXXSPLTIW_V4SI, "vxxspltiw_v4si", CONST, xxspltiw_v4si)
 BU_P10V_VSX_1 (VXXSPLTIW_V4SF, "vxxspltiw_v4sf", CONST, xxspltiw_v4sf)
 
@@ -2905,6 +2923,11 @@ BU_P10_OVERLOAD_1 (VSTRIL_P, "stril_p")
 BU_P10_OVERLOAD_1 (XVTLSBB_ZEROS, "xvtlsbb_all_zeros")
 BU_P10_OVERLOAD_1 (XVTLSBB_ONES, "xvtlsbb_all_ones")
 
+BU_P10_OVERLOAD_2 (VMUL, "mul")
+BU_P10_OVERLOAD_2 (VMULH, "mulh")
+BU_P10_OVERLOAD_2 (VDIVE, "dive")
+BU_P10_OVERLOAD_2 (VMOD, "mod")
+
 \f
 BU_P10_OVERLOAD_1 (MTVSRBM, "mtvsrbm")
 BU_P10_OVERLOAD_1 (MTVSRHM, "mtvsrhm")
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b044778a7ae..be2e6c56632 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -993,6 +993,35 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
   { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_UDIV_V2DI,
     RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+
+  { VSX_BUILTIN_VEC_DIV, P10V_BUILTIN_VDIVS_V4SI,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { VSX_BUILTIN_VEC_DIV, P10V_BUILTIN_VDIVU_V4SI,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_unsigned_V4SI, 0 },
+
+  { P10_BUILTIN_VEC_VDIVE, P10V_BUILTIN_VDIVES_V4SI,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P10_BUILTIN_VEC_VDIVE, P10V_BUILTIN_VDIVEU_V4SI,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_unsigned_V4SI, 0 },
+  { P10_BUILTIN_VEC_VDIVE, P10V_BUILTIN_VDIVES_V2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+  { P10_BUILTIN_VEC_VDIVE, P10V_BUILTIN_VDIVEU_V2DI,
+    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+    RS6000_BTI_unsigned_V2DI, 0 },
+
+  { P10_BUILTIN_VEC_VMOD, P10V_BUILTIN_VMODS_V4SI,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P10_BUILTIN_VEC_VMOD, P10V_BUILTIN_VMODU_V4SI,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_unsigned_V4SI, 0 },
+  { P10_BUILTIN_VEC_VMOD, P10V_BUILTIN_VMODS_V2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+  { P10_BUILTIN_VEC_VMOD, P10V_BUILTIN_VMODU_V2DI,
+    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+    RS6000_BTI_unsigned_V2DI, 0 },
+
   { VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVSXDDP,
     RS6000_BTI_V2DF, RS6000_BTI_V2DI, 0, 0 },
   { VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVUXDDP,
@@ -1833,6 +1862,17 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
   { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB,
     RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 },
+  { P10_BUILTIN_VEC_VMULH, P10V_BUILTIN_VMULHS_V4SI,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P10_BUILTIN_VEC_VMULH, P10V_BUILTIN_VMULHU_V4SI,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_unsigned_V4SI, 0 },
+  { P10_BUILTIN_VEC_VMULH, P10V_BUILTIN_VMULHS_V2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
+  { P10_BUILTIN_VEC_VMULH, P10V_BUILTIN_VMULHU_V2DI,
+    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+    RS6000_BTI_unsigned_V2DI, 0 },
+
   { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB,
     RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
   { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB,
@@ -14325,6 +14365,15 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
     case P10V_BUILTIN_XXGENPCVM_V8HI:
     case P10V_BUILTIN_XXGENPCVM_V4SI:
     case P10V_BUILTIN_XXGENPCVM_V2DI:
+    case P10V_BUILTIN_VDIVEU_V4SI:
+    case P10V_BUILTIN_VDIVEU_V2DI:
+    case P10V_BUILTIN_VDIVU_V4SI:
+    case P10V_BUILTIN_VDIVU_V2DI:
+    case P10V_BUILTIN_VMODU_V2DI:
+    case P10V_BUILTIN_VMODU_V4SI:
+    case P10V_BUILTIN_VMULHU_V2DI:
+    case P10V_BUILTIN_VMULHU_V4SI:
+    case P10V_BUILTIN_VMULLD_V2DI:
       h.uns_p[0] = 1;
       h.uns_p[1] = 1;
       h.uns_p[2] = 1;
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index 796345c80d3..670feb4e04e 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -22,6 +22,12 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+(define_c_enum "unspec"
+  [UNSPEC_VDIVES
+   UNSPEC_VDIVEU
+   UNSPEC_VMULHS
+   UNSPEC_VMULHU
+])
 
 ;; Vector int modes
 (define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI])
@@ -64,6 +70,11 @@
 ;; Vector integer modes
 (define_mode_iterator VI [V4SI V8HI V16QI])
 
+;; Longer vec int moeds for Vector Integer Multiply/Divide/Modulo Instructions
+(define_mode_iterator VIlong [V2DI V4SI])
+(define_mode_attr VIlong_char [(V2DI "d")
+			       (V4SI "w")])
+
 ;; Base type from vector mode
 (define_mode_attr VEC_base [(V16QI "QI")
 			    (V8HI  "HI")
@@ -1521,3 +1532,96 @@
     emit_insn (gen_vsx_extract_<VEC_F:mode> (operand0, vec, elt));
     DONE;
   })
+
+(define_insn "vdives_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+        (unspec:VIlong [(match_operand:VIlong 1 "vsx_register_operand" "v")
+		        (match_operand:VIlong 2 "vsx_register_operand" "v")]
+		       UNSPEC_VDIVES))]
+  "TARGET_POWER10"
+  "vdives<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vdiveu_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+        (unspec: VIlong [(match_operand:VIlong 1 "vsx_register_operand" "v")
+			 (match_operand:VIlong 2 "vsx_register_operand" "v")]
+			UNSPEC_VDIVEU))]
+  "TARGET_POWER10"
+  "vdiveu<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "div<mode>3"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(div:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
+		    (match_operand:VIlong 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vdivs<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "udiv<mode>3"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(udiv:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
+		    (match_operand:VIlong 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vdivu<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vdivs_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(div:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
+		    (match_operand:VIlong 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vdivs<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vdivu_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(udiv:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
+		     (match_operand:VIlong 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vdivu<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vmods_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(mod:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
+		    (match_operand:VIlong 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vmods<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vmodu_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(umod:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
+		     (match_operand:VIlong 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vmodu<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vmulhs_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(unspec:VIlong [(match_operand:VIlong 1 "vsx_register_operand" "v")
+		        (match_operand:VIlong 2 "vsx_register_operand" "v")]
+		       UNSPEC_VMULHS))]
+  "TARGET_POWER10"
+  "vmulhs<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "vmulhu_<mode>"
+  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
+	(unspec:VIlong [(match_operand:VIlong 1 "vsx_register_operand" "v")
+		        (match_operand:VIlong 2 "vsx_register_operand" "v")]
+		       UNSPEC_VMULHU))]
+  "TARGET_POWER10"
+  "vmulhu<VIlong_char> %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
+
+;; Vector multiply low double word
+(define_insn "mulv2di3"
+  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v")
+	(mult:V2DI (match_operand:V2DI 1 "vsx_register_operand" "v")
+		   (match_operand:V2DI 2 "vsx_register_operand" "v")))]
+  "TARGET_POWER10"
+  "vmulld %0,%1,%2"
+  [(set_attr "type" "vecsimple")])
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index d6347dba149..2b04f19842d 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -1623,28 +1623,35 @@
   rtx op0 = operands[0];
   rtx op1 = operands[1];
   rtx op2 = operands[2];
-  rtx op3 = gen_reg_rtx (DImode);
-  rtx op4 = gen_reg_rtx (DImode);
-  rtx op5 = gen_reg_rtx (DImode);
-  emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
-  emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
-  if (TARGET_POWERPC64)
-    emit_insn (gen_muldi3 (op5, op3, op4));
-  else
-    {
-      rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
-      emit_move_insn (op5, ret);
-    }
-  emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
-  emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
-  if (TARGET_POWERPC64)
-    emit_insn (gen_muldi3 (op3, op3, op4));
+
+  if (TARGET_POWER10)
+    emit_insn (gen_mulv2di3 (op0, op1, op2) );
+
   else
     {
-      rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
-      emit_move_insn (op3, ret);
+      rtx op3 = gen_reg_rtx (DImode);
+      rtx op4 = gen_reg_rtx (DImode);
+      rtx op5 = gen_reg_rtx (DImode);
+      emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
+      emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
+      if (TARGET_POWERPC64)
+	emit_insn (gen_muldi3 (op5, op3, op4));
+      else
+	{
+	  rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
+	  emit_move_insn (op5, ret);
+	}
+      emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
+      emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
+      if (TARGET_POWERPC64)
+	emit_insn (gen_muldi3 (op3, op3, op4));
+      else
+	{
+	  rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
+	  emit_move_insn (op3, ret);
+	}
+      emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
     }
-  emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
   DONE;
 }
   [(set_attr "type" "mul")])
@@ -1674,6 +1681,7 @@
   rtx op3 = gen_reg_rtx (DImode);
   rtx op4 = gen_reg_rtx (DImode);
   rtx op5 = gen_reg_rtx (DImode);
+
   emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
   emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
   if (TARGET_POWERPC64)
@@ -1718,37 +1726,47 @@
   rtx op0 = operands[0];
   rtx op1 = operands[1];
   rtx op2 = operands[2];
-  rtx op3 = gen_reg_rtx (DImode);
-  rtx op4 = gen_reg_rtx (DImode);
-  rtx op5 = gen_reg_rtx (DImode);
-  emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
-  emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
-  if (TARGET_POWERPC64)
-    emit_insn (gen_udivdi3 (op5, op3, op4));
-  else
-    {
-      rtx libfunc = optab_libfunc (udiv_optab, DImode);
-      rtx target = emit_library_call_value (libfunc,
-					    op5, LCT_NORMAL, DImode,
-					    op3, DImode,
-					    op4, DImode);
-      emit_move_insn (op5, target);
-    }
-  emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
-  emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
-  if (TARGET_POWERPC64)
-    emit_insn (gen_udivdi3 (op3, op3, op4));
-  else
-    {
-      rtx libfunc = optab_libfunc (udiv_optab, DImode);
-      rtx target = emit_library_call_value (libfunc,
-					    op3, LCT_NORMAL, DImode,
-					    op3, DImode,
-					    op4, DImode);
-      emit_move_insn (op3, target);
-    }
-  emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
-  DONE;
+
+    if (TARGET_POWER10)
+      emit_insn (gen_udivv2di3 (op0, op1, op2) );
+
+    else
+      {
+	rtx op3 = gen_reg_rtx (DImode);
+	rtx op4 = gen_reg_rtx (DImode);
+	rtx op5 = gen_reg_rtx (DImode);
+
+	emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
+	emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
+
+	if (TARGET_POWERPC64)
+	  emit_insn (gen_udivdi3 (op5, op3, op4));
+	else
+	  {
+	    rtx libfunc = optab_libfunc (udiv_optab, DImode);
+	    rtx target = emit_library_call_value (libfunc,
+						  op5, LCT_NORMAL, DImode,
+						  op3, DImode,
+						  op4, DImode);
+	    emit_move_insn (op5, target);
+	  }
+	emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
+	emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
+
+	if (TARGET_POWERPC64)
+	  emit_insn (gen_udivdi3 (op3, op3, op4));
+	else
+	  {
+	    rtx libfunc = optab_libfunc (udiv_optab, DImode);
+	    rtx target = emit_library_call_value (libfunc,
+						  op3, LCT_NORMAL, DImode,
+						  op3, DImode,
+						  op4, DImode);
+	    emit_move_insn (op3, target);
+	  }
+	emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
+      }
+    DONE;
 }
   [(set_attr "type" "div")])
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5be1cbecf60..7b4293c3db7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21356,6 +21356,126 @@ integer value between 0 and 255 inclusive.
 @exdent vector unsigned int vec_genpcvm (vector unsigned long long int,
                                          const int)
 @end smallexample
+
+Vector Integer Multiply-Divide-Modulo
+
+@smallexample
+@exdent vector signed int
+@exdent vec_mulh (vector signed int a, vector signed int b)
+@exdent vector unsigned int
+@exdent vec_mulh (vector unsigned int a, vector unsigned int b)
+@end smallexample
+
+For each integer value i from 0 to 3, do the following. The integer value in
+word element i of a is multiplied by the integer value in word
+element i of b. The high-order 32 bits of the 64-bit product are placed into
+word element i of the vector returned.
+
+@smallexample
+@exdent vector signed long long
+@exdent vec_mulh (vector signed long long a, vector signed long long b)
+@exdent vector unsigned long long
+@exdent vec_mulh (vector unsigned long long a, vector unsigned long long b)
+@end smallexample
+
+For each integer value i from 0 to 1, do the following. The integer value in
+doubleword element i of a is multiplied by the integer value in doubleword
+element i of b. The high-order 64 bits of the 128-bit product are placed into
+doubleword element i of the vector returned.
+
+@smallexample
+@exdent vector unsigned long long
+@exdent vec_mul (vector unsigned long long a, vector unsigned long long b)
+@exdent vector signed long long
+@exdent vec_mul (vector signed long long a, vector signed long long b)
+@end smallexample
+
+For each integer value i from 0 to 1, do the following. The integer value in
+doubleword element i of a is multiplied by the integer value in
+doubleword element i of b. The low-order 64 bits of the 128-bit product
+are placed into doubleword element i of the vector returned.
+
+@smallexample
+@exdent vector signed int
+@exdent vec_div (vector signed int a, vector signed int b)
+@exdent vector unsigned int
+@exdent vec_div (vector unsigned int a, vector unsigned int b)
+@end smallexample
+
+For each integer value i from 0 to 3, do the following. The integer in word
+element i of a is divided by the integer in word element i of b. The unique
+integer quotient is placed into the word element i of the vector returned. If
+an attempt is made to perform any of the divisions <anything> ÷ 0 then the
+quotient is undefined.
+
+@smallexample
+@exdent vector signed long long
+@exdent vec_div (vector signed long long a, vector signed long long b)
+@exdent vector unsigned long long
+@exdent vec_div (vector unsigned long long a, vector unsigned long long b)
+@end smallexample
+
+For each integer value i from 0 to 1, do the following. The integer in
+doubleword element i of a is divided by the integer in doubleword
+element i of b. The unique integer quotient is placed into the
+doubleword element i of the vector returned. If an attempt is made to perform
+any of the divisions 0x8000_0000_0000_0000 ÷ -1 or <anything> ÷ 0 then the
+quotient is undefined.
+
+@smallexample
+@exdent vector signed int
+@exdent vec_dive (vector signed int a, vector signed int b)
+@exdent vector unsigned int
+@exdent vec_dive (vector unsigned int a, vector unsigned int b)
+@end smallexample
+
+For each integer value i from 0 to 3, do the following. The integer in word
+element i of a is shifted left by 32 bits, then divided by the integer
+in word element i of b. The unique integer quotient is placed into the
+word element i of the vector returned. If the quotient cannot be represented
+in 32 bits, or if an attempt is made to perform any of the divisions
+<anything> ÷ 0 then the quotient is undefined.
+
+@smallexample
+@exdent vector signed long long
+@exdent vec_dive (vector signed long long a, vector signed long long b)
+@exdent vector unsigned long long
+@exdent vec_dive (vector unsigned long long a, vector unsigned long long b)
+@end smallexample
+
+For each integer value i from 0 to 1, do the following. The integer in
+doubleword element i of a is shifted left by 64 bits, then divided by the
+integer in doubleword element i of b. The unique integer quotient is placed
+into the doubleword element i of the vector returned. If the quotient cannot
+be represented in 64 bits, or if an attempt is made to perform <anything> ÷ 0
+then the quotient is undefined.
+
+@smallexample
+@exdent vector signed int
+@exdent vec_mod (vector signed int a, vector signed int b)
+@exdent vector unsigned int
+@exdent vec_mod (vector unsigned int a, vector unsigned int b)
+@end smallexample
+
+For each integer value i from 0 to 3, do the following. The integer in word
+element i of a is divided by the integer in word element i of b. The unique
+integer remainder is placed into the word element i of the vector returned.
+If an attempt is made to perform any of the divisions 0x8000_0000 ÷ -1 or
+<anything> ÷ 0 then the remainder is undefined.
+
+@smallexample
+@exdent vector signed long long
+@exdent vec_mod (vector signed long long a, vector signed long long b)
+@exdent vector unsigned long long
+@exdent vec_mod (vector unsigned long long a, vector unsigned long long b)
+@end smallexample
+
+For each integer value i from 0 to 1, do the following. The integer in
+doubleword element i of a is divided by the integer in doubleword element i of
+b. The unique integer remainder is placed into the doubleword
+element i of the vector returned. If an attempt is made to perform
+<anything> ÷ 0 then the remainder is undefined.
+
 Generate PCV from specified Mask size, as if implemented by the
 @code{xxgenpcvbm}, @code{xxgenpcvhm}, @code{xxgenpcvwm} instructions, where
 immediate value is either 0, 1, 2 or 3.
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1-p10-runnable.c b/gcc/testsuite/gcc.target/powerpc/builtins-1-p10-runnable.c
new file mode 100644
index 00000000000..549bc742d12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-1-p10-runnable.c
@@ -0,0 +1,378 @@
+/* { dg-do run } */
+/* { dg-require-effective-target power10_hw } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+/* { dg-final { scan-assembler-times "\mvdivsw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdivuw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdivsd\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdivud\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdivesw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdiveuw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdivesd\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvdiveud\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmodsw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmoduw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmodsd\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmodud\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmulhsw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmulhuw\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmulhsd\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmulhud\M" 1 } } */
+/* { dg-final { scan-assembler-times "\mvmulld\M" 2 } } */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <math.h>
+#include <altivec.h>
+
+#define DEBUG 0
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+int main()
+  {
+    int i;
+    vector int i_arg1, i_arg2;
+    vector unsigned int u_arg1, u_arg2;
+    vector long long int d_arg1, d_arg2;
+    vector long long unsigned int ud_arg1, ud_arg2;
+   
+    vector int vec_i_expected, vec_i_result;
+    vector unsigned int vec_u_expected, vec_u_result;
+    vector long long int vec_d_expected, vec_d_result;
+    vector long long unsigned int vec_ud_expected, vec_ud_result;
+  
+    /* Signed word divide */
+    i_arg1 = (vector int){ 20, 40, 60, 80};
+    i_arg2 = (vector int){ 2, 2, 2, 2};
+    vec_i_expected = (vector int){10, 20, 30, 40};
+
+    vec_i_result = vec_div (i_arg1, i_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_i_expected[i] != vec_i_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_div result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_i_result[i],  i, vec_i_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned word divide */
+    u_arg1 = (vector unsigned int){ 20, 40, 60, 80};
+    u_arg2 = (vector unsigned int){ 2, 2, 2, 2};
+    vec_u_expected = (vector unsigned int){10, 20, 30, 40};
+
+    vec_u_result = vec_div (u_arg1, u_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_u_expected[i] != vec_u_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_div result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_u_result[i],  i, vec_u_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Signed double word divide */
+    d_arg1 = (vector long long){ 24, 68};
+    d_arg2 = (vector long long){ 2, 2};
+    vec_d_expected = (vector long long){12, 34};
+
+    vec_d_result = vec_div (d_arg1, d_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_d_expected[i] != vec_d_result[i])
+#ifdef DEBUG
+	  printf("ERROR vec_div result[%d] = %d != expected[%d] = %d\n",
+		 i, vec_d_result[i],  i, vec_d_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned double word divide */
+    ud_arg1 = (vector unsigned long long){ 24, 68};
+    ud_arg2 = (vector unsigned long long){ 2, 2};
+    vec_ud_expected = (vector unsigned long long){12, 34};
+
+    vec_ud_result = vec_div (ud_arg1, ud_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_ud_expected[i] != vec_ud_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_div result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_ud_result[i],  i, vec_ud_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Divide Extended signed word  result = (arg1 << 32)/arg2 */
+    i_arg1 = (vector int){ 2, 4, 6, 8};
+    i_arg2 = (vector int){ 2048, 2048, 2048, 2048};
+    vec_i_expected = (vector int){4194304, 8388608, 12582912, 16777216};
+
+    vec_i_result = vec_dive (i_arg1, i_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_i_expected[i] != vec_i_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_dive result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_i_result[i],  i, vec_i_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Divide Extended unsigned word  result = (arg1 << 32)/arg2 */
+    u_arg1 = (vector unsigned int){ 2, 4, 6, 8};
+    u_arg2 = (vector unsigned int){ 2048, 2048, 2048, 2048};
+    vec_u_expected = (vector unsigned int){4194304, 8388608,
+					   12582912, 16777216};
+
+    vec_u_result = vec_dive (u_arg1, u_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_u_expected[i] != vec_u_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_dive result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_u_result[i],  i, vec_u_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Divide Extended double signed  esult = (arg1 << 64)/arg2 */
+    d_arg1 = (vector long long int){ 2, 4};
+    d_arg2 = (vector long long int){ 4294967296, 4294967296};
+
+    vec_d_expected = (vector long long int){8589934592, 17179869184};
+
+    vec_d_result = vec_dive (d_arg1, d_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_d_expected[i] != vec_d_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_dive result[%d] = %lld != expected[%d] = %lld\n",
+		  i, vec_d_result[i],  i, vec_d_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Divide Extended double unsigned result = (arg1 << 64)/arg2 */
+    ud_arg1 = (vector long long unsigned int){ 2, 4};
+    ud_arg2 = (vector long long unsigned int){ 4294967296, 4294967296};
+
+    vec_ud_expected = (vector long long unsigned int){8589934592,
+						      17179869184};
+
+    vec_ud_result = vec_dive (ud_arg1, ud_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_ud_expected[i] != vec_ud_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_dive result[%d] = %lld != expected[%d] = %lld\n",
+		  i, vec_ud_result[i],  i, vec_ud_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Signed word modulo */
+    i_arg1 = (vector int){ 23, 45, 61, 89};
+    i_arg2 = (vector int){ 2, 2, 2, 2};
+    vec_i_expected = (vector int){1, 1, 1, 1};
+
+    vec_i_result = vec_mod (i_arg1, i_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_i_expected[i] != vec_i_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mod result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_i_result[i],  i, vec_i_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned word modulo */
+    u_arg1 = (vector unsigned int){ 25, 41, 67, 86};
+    u_arg2 = (vector unsigned int){ 3, 3, 3, 3};
+    vec_u_expected = (vector unsigned int){1, 2, 1, 2};
+
+    vec_u_result = vec_mod (u_arg1, u_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_u_expected[i] != vec_u_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mod result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_u_result[i],  i, vec_u_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Signed double word modulo */
+    d_arg1 = (vector long long){ 24, 68};
+    d_arg2 = (vector long long){ 7, 7};
+    vec_d_expected = (vector long long){3, 5};
+
+    vec_d_result = vec_mod (d_arg1, d_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_d_expected[i] != vec_d_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mod result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_d_result[i],  i, vec_d_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned double word modulo */
+    ud_arg1 = (vector unsigned long long){ 24, 68};
+    ud_arg2 = (vector unsigned long long){ 8, 8};
+    vec_ud_expected = (vector unsigned long long){0, 4};
+
+    vec_ud_result = vec_mod (ud_arg1, ud_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_ud_expected[i] != vec_ud_result[i])
+#ifdef DEBUG
+           printf("ERROR vecmod result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_ud_result[i],  i, vec_ud_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Signed word multiply high */
+    i_arg1 = (vector int){ 2147483648, 2147483648, 2147483648, 2147483648 };
+    i_arg2 = (vector int){ 2, 3, 4, 5};
+    vec_i_expected = (vector int){-1, -2, -2, -3};
+
+    vec_i_result = vec_mulh (i_arg1, i_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_i_expected[i] != vec_i_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mulh result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_i_result[i],  i, vec_i_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned word multiply high */
+    u_arg1 = (vector unsigned int){ 2147483648, 2147483648,
+				    2147483648, 2147483648 };
+    u_arg2 = (vector unsigned int){ 4, 5, 6, 7 };
+    vec_u_expected = (vector unsigned int){2, 2, 3, 3 };
+
+    vec_u_result = vec_mulh (u_arg1, u_arg2);
+
+    for (i = 0; i < 4; i++)
+      {
+        if (vec_u_expected[i] != vec_u_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mulh result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_u_result[i],  i, vec_u_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Signed double word multiply high */
+    d_arg1 = (vector long long int){  2305843009213693951,
+				      4611686018427387903 };
+    d_arg2 = (vector long long int){ 12, 20 };
+    vec_d_expected = (vector long long int){ 1, 4 };
+
+    vec_d_result = vec_mulh (d_arg1, d_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_d_expected[i] != vec_d_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mulh result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_d_result[i],  i, vec_d_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned double word multiply high */
+    ud_arg1 = (vector unsigned long long int){ 2305843009213693951,
+					       4611686018427387903 };
+    ud_arg2 = (vector unsigned long long int){ 32, 10 };
+    vec_ud_expected = (vector unsigned long long int){ 3, 2 };
+
+    vec_ud_result = vec_mulh (ud_arg1, ud_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_ud_expected[i] != vec_ud_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mulh result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_ud_result[i],  i, vec_ud_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Unsigned double word multiply low */
+    ud_arg1 = (vector unsigned long long int){ 2048, 4096 };
+    ud_arg2 = (vector unsigned long long int){ 2, 4 };
+    vec_ud_expected = (vector unsigned long long int){ 4096, 16384 };
+
+    vec_ud_result = vec_mul (ud_arg1, ud_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_ud_expected[i] != vec_ud_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mul result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_ud_result[i],  i, vec_ud_expected[i]);
+#else
+        abort();
+#endif
+      }
+
+    /* Signed double word multiply low */
+    d_arg1 = (vector signed long long int){ 2048, 4096 };
+    d_arg2 = (vector signed long long int){ 2, 4 };
+    vec_d_expected = (vector signed long long int){ 4096, 16384 };
+
+    vec_d_result = vec_mul (d_arg1, d_arg2);
+
+    for (i = 0; i < 2; i++)
+      {
+        if (vec_d_expected[i] != vec_d_result[i])
+#ifdef DEBUG
+           printf("ERROR vec_mul result[%d] = %d != expected[%d] = %d\n",
+		  i, vec_d_result[i],  i, vec_d_expected[i]);
+#else
+        abort();
+#endif
+      }
+  }
-- 
2.17.1



^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2021-01-15 18:52 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-30 20:07 [PATCH] rs6000, vector integer multiply/divide/modulo instructions Carl Love
2020-10-30 21:05 ` David Edelsohn
2020-10-30 21:33   ` Carl Love
2020-10-31 13:28 ` David Edelsohn
2020-11-02 21:06   ` Carl Love
2020-11-04 16:44   ` Carl Love
2020-11-19  0:42     ` David Edelsohn
2020-11-19 17:25     ` Pat Haugen
2020-11-19 20:40       ` Segher Boessenkool
2020-11-19 23:26     ` Segher Boessenkool
2020-11-24 18:59       ` [PATCH v2] " Carl Love
2020-11-25  2:17         ` Pat Haugen
2020-11-25  2:34           ` Pat Haugen
2020-11-26  2:30             ` Segher Boessenkool
2020-12-01 23:48               ` Carl Love
2020-12-02 23:14                 ` will schmidt
2020-12-03 19:55                 ` will schmidt
2020-12-08  0:31                   ` [PATCH v4] " Carl Love
2021-01-04 16:45                     ` Carl Love
2021-01-11 21:18                     ` will schmidt
2021-01-13 22:15                     ` [PATCH v5] " Carl Love
2021-01-15 18:51                       ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).