[gcc r17-2644] rs6000: Add Dense Math (DMF/MMA+) built-in/instruction support

kishan parmar via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:6d3f40485df12a961e36d337895b28af74ba181d

commit r17-2644-g6d3f40485df12a961e36d337895b28af74ba181d
Author: Kishan Parmar <[email protected]>
Date:   Thu Jul 23 11:43:29 2026 +0530

    rs6000: Add Dense Math (DMF/MMA+) built-in/instruction support
    
    Add support for the DMF (Dense Math Facility) and MMA+
    (Matrix-Multiply Assist Plus) builtins and instructions which may be
    available on a future Power processor.
    
    This patch extends the existing MMA infrastructure to support Dense
    Math Registers (DMRs).
    
    Key changes:
    
    1. Extended MMA operand support from 7 to 9 operands (MAX_MMA_OPERANDS)
    
    2. Added new DMF-specific unspecs:
    
       * UNSPEC_DMF_DMXOR for DMR XOR operations
       * UNSPEC_DMF_DMXVI8GERX4* for DMR GER (outer product) operations
       * UNSPEC_DMF_PMDMXVI8GERX4* for prefixed DMR GER operations
       * UNSPEC_DMF_DMSETDMRZ for zeroing a DMR register
    
    3. Implemented new instruction patterns in mma.md:
    
       * dmf_build_dmr: Build a DMR from eight vector operands
       * dmf_dmsetdmrz: Zero a DMR register
       * dmf_dmxor: XOR operation on DMR registers
       * dmf_dmxvi8gerx4/dmxvi8gerx4pp: DMR outer product operations
       * dmf_pmdmxvi8gerx4/pmdmxvi8gerx4pp: Prefixed DMR outer product
         operations
    
    4. Added new DMF builtins and updated GIMPLE folding:
    
       * Added DMF and MMA+ builtins
       * Updated GIMPLE folding to handle DMR pass-by-reference semantics
       * Extended builtin expansion to support up to 9 operand instructions
    
    5. Added documentation for the new DMF and MMA+ builtins.
    
    The implementation follows the existing MMA pattern where user-facing
    builtins use pass-by-reference for DMR arguments, while internal
    builtins use pass-by-value for optimization.
    
    2026-07-15  Peter Bergner  <[email protected]>
                Surya Kumari Jangala  <[email protected]>
                Kishan Parmar  <[email protected]>
    
    gcc/ChangeLog:
            * config/rs6000/mma.md (MAX_MMA_OPERANDS): Increase from 7 to 9.
            (UNSPEC_DMF_DMXOR): New unspec.
            (UNSPEC_DMF_DMXVI8GERX4): Likewise.
            (UNSPEC_DMF_DMXVI8GERX4PP): Likewise.
            (UNSPEC_DMF_PMDMXVI8GERX4): Likewise.
            (UNSPEC_DMF_PMDMXVI8GERX4PP): Likewise.
            (UNSPEC_DMF_DMSETDMRZ): Likewise.
            (DMF_PV): New iterator.
            (DMF_DPV): Likewise.
            (DMF_PVI8I4I4): Likewise.
            (DMF_DPVI8I4I4): Likewise.
            (pv): Add DMF mappings.
            (apv): Likewise.
            (pvi8i4i4): New attribute.
            (dpvi8i4i4): Likewise.
            (dmf_build_dmr): New define_expand.
            (dmf_dmsetdmrz): New insn.
            (dmf_dmxor): Likewise.
            (dmf_<pv>): New insn pattern.
            (dmf_<apv>): Likewise.
            (dmf_<pvi8i4i4>): Likewise.
            (dmf_<dpvi8i4i4>): Likewise.
            * config/rs6000/rs6000-builtin.cc (rs6000_gimple_fold_mma_builtin): Add
            DMF builtin support. Handle DMR pass-by-reference semantics.
            Support up to nine builtin operands.
            (mma_expand_builtin): Likewise.
            (rs6000_expand_builtin): Handle DMF builtins.
            * config/rs6000/rs6000-builtins.def: Add DMF and MMA+ builtin
            definitions.
            * doc/extend.texi
            (PowerPC Matrix-Multiply Assist Built-in Functions): Document
            MMA+ builtins.
            (PowerPC Dense Math Facility Built-in Functions): Document DMF builtins.
    
    gcc/testsuite/ChangeLog:
            * gcc.target/powerpc/dmf-build-dmr.c: New test.
            * gcc.target/powerpc/dmf-builtin.c: New test.

Diff:
---
 gcc/config/rs6000/mma.md                         | 126 ++++++++++++++++++++++-
 gcc/config/rs6000/rs6000-builtin.cc              |  84 ++++++++++-----
 gcc/config/rs6000/rs6000-builtins.def            |  55 ++++++++++
 gcc/doc/extend.texi                              |  38 +++++++
 gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c |  15 +++
 gcc/testsuite/gcc.target/powerpc/dmf-builtin.c   |  81 +++++++++++++++
 6 files changed, 372 insertions(+), 27 deletions(-)

diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index 85caa19ee10b..8d4a65a48b16 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -24,7 +24,7 @@
 ;; __vector_pair types that the MMA built-in functions reference.  We
 ;; use OPAQUE_MODE to prevent anything from trying to open them up.
 
-(define_constants [(MAX_MMA_OPERANDS 7)])
+(define_constants [(MAX_MMA_OPERANDS 9)])
 
 ;; Constants for creating unspecs
 
@@ -96,6 +96,12 @@
    UNSPEC_DMF_INSERT1024
    UNSPEC_DMF_RELOAD_FROM_MEMORY
    UNSPEC_DMF_RELOAD_TO_MEMORY
+   UNSPEC_DMF_DMXOR
+   UNSPEC_DMF_DMXVI8GERX4
+   UNSPEC_DMF_DMXVI8GERX4PP
+   UNSPEC_DMF_PMDMXVI8GERX4
+   UNSPEC_DMF_PMDMXVI8GERX4PP
+   UNSPEC_DMF_DMSETDMRZ
   ])
 
 (define_c_enum "unspecv"
@@ -138,12 +144,18 @@
 ;; MMA instructions with 1 vector pair and 1 vector arguments
 (define_int_iterator MMA_PV		[UNSPEC_MMA_XVF64GER])
 
+; DMF instructions with 1 vector pair and 1 vector arguments
+(define_int_iterator DMF_PV		[UNSPEC_DMF_DMXVI8GERX4])
+
 ;; MMA instructions with 1 accumulator, 1 vector pair and 1 vector arguments
 (define_int_iterator MMA_APV		[UNSPEC_MMA_XVF64GERPP
 					 UNSPEC_MMA_XVF64GERPN
 					 UNSPEC_MMA_XVF64GERNP
 					 UNSPEC_MMA_XVF64GERNN])
 
+;; DMF instructions with 1 dmr, 1 vector pair and 1 vector arguments
+(define_int_iterator DMF_DPV		[UNSPEC_DMF_DMXVI8GERX4PP])
+
 ;; MMA instructions with 2 vector, 2 4-bit and 1 8-bit arguments
 (define_int_iterator MMA_VVI4I4I8	[UNSPEC_MMA_PMXVI4GER8])
 
@@ -193,6 +205,14 @@
 (define_int_iterator MMA_AVVI4I4I4	[UNSPEC_MMA_PMXVI8GER4PP
 					 UNSPEC_MMA_PMXVI8GER4SPP])
 
+; DMF instructions with 1 vector pair, 1 vector and 1 8-bit and 2 4-bit
+;; arguments
+(define_int_iterator DMF_PVI8I4I4	[UNSPEC_DMF_PMDMXVI8GERX4])
+
+;; DMF instructions with 1 dmr, 1 vector pair, 1 vector and 1 8-bit and
+;; 2 4-bit arguments
+(define_int_iterator DMF_DPVI8I4I4	[UNSPEC_DMF_PMDMXVI8GERX4PP])
+
 (define_int_attr acc		[(UNSPEC_MMA_XXMFACC		"xxmfacc")
 				 (UNSPEC_MMA_XXMTACC		"xxmtacc")])
 
@@ -222,12 +242,14 @@
 				 (UNSPEC_MMA_XVF32GERNP		"xvf32gernp")
 				 (UNSPEC_MMA_XVF32GERNN		"xvf32gernn")])
 
-(define_int_attr pv		[(UNSPEC_MMA_XVF64GER		"xvf64ger")])
+(define_int_attr pv		[(UNSPEC_MMA_XVF64GER		"xvf64ger")
+				 (UNSPEC_DMF_DMXVI8GERX4        "dmxvi8gerx4")])
 
 (define_int_attr apv		[(UNSPEC_MMA_XVF64GERPP		"xvf64gerpp")
 				 (UNSPEC_MMA_XVF64GERPN		"xvf64gerpn")
 				 (UNSPEC_MMA_XVF64GERNP		"xvf64gernp")
-				 (UNSPEC_MMA_XVF64GERNN		"xvf64gernn")])
+				 (UNSPEC_MMA_XVF64GERNN		"xvf64gernn")
+				 (UNSPEC_DMF_DMXVI8GERX4PP      "dmxvi8gerx4pp")])
 
 (define_int_attr vvi4i4i8	[(UNSPEC_MMA_PMXVI4GER8		"pmxvi4ger8")])
 
@@ -268,6 +290,9 @@
 (define_int_attr avvi4i4i4	[(UNSPEC_MMA_PMXVI8GER4PP	"pmxvi8ger4pp")
 				 (UNSPEC_MMA_PMXVI8GER4SPP	"pmxvi8ger4spp")])
 
+(define_int_attr pvi8i4i4	[(UNSPEC_DMF_PMDMXVI8GERX4      "pmdmxvi8gerx4")])
+
+(define_int_attr dpvi8i4i4	[(UNSPEC_DMF_PMDMXVI8GERX4PP    "pmdmxvi8gerx4pp")])
 
 ;; Vector pair support.  OOmode can only live in VSRs.
 (define_expand "movoo"
@@ -682,6 +707,30 @@
   DONE;
 })
 
+(define_expand "dmf_build_dmr"
+  [(match_operand:TDO 0 "dmr_register_operand")
+   (match_operand:V16QI 1 "mma_assemble_input_operand")
+   (match_operand:V16QI 2 "mma_assemble_input_operand")
+   (match_operand:V16QI 3 "mma_assemble_input_operand")
+   (match_operand:V16QI 4 "mma_assemble_input_operand")
+   (match_operand:V16QI 5 "mma_assemble_input_operand")
+   (match_operand:V16QI 6 "mma_assemble_input_operand")
+   (match_operand:V16QI 7 "mma_assemble_input_operand")
+   (match_operand:V16QI 8 "mma_assemble_input_operand")]
+  "TARGET_DMF"
+{
+  rtx vp0 = gen_reg_rtx (OOmode);
+  rtx vp1 = gen_reg_rtx (OOmode);
+  rtx vp2 = gen_reg_rtx (OOmode);
+  rtx vp3 = gen_reg_rtx (OOmode);
+  emit_insn (gen_vsx_assemble_pair (vp0, operands[2], operands[1]));
+  emit_insn (gen_vsx_assemble_pair (vp1, operands[4], operands[3]));
+  emit_insn (gen_vsx_assemble_pair (vp2, operands[6], operands[5]));
+  emit_insn (gen_vsx_assemble_pair (vp3, operands[8], operands[7]));
+  emit_insn (gen_dm_insert1024 (operands[0], vp0, vp1, vp2, vp3));
+  DONE;
+})
+
 (define_expand "mma_disassemble_acc"
   [(match_operand:V16QI 0 "mma_disassemble_output_operand")
    (match_operand:XO 1 "accumulator_operand")
@@ -759,6 +808,13 @@
   "xxsetaccz %A0"
   [(set_attr "type" "mma")])
 
+(define_insn "dmf_dmsetdmrz"
+  [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
+	(unspec:TDO [(const_int 0)] UNSPEC_DMF_DMSETDMRZ))]
+  "TARGET_DMF"
+  "dmsetdmrz %0"
+  [(set_attr "type" "dmf")])
+
 (define_insn "mma_<vv>"
   [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
 	(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa")
@@ -927,3 +983,67 @@
   "<avvi4i4i4> %A0,%x2,%x3,%4,%5,%6"
   [(set_attr "type" "mma")
    (set_attr "prefixed" "yes")])
+
+(define_insn "dmf_dmxor"
+  [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
+	(unspec:TDO [(match_operand:TDO 1 "dmr_register_operand" "0")
+		     (match_operand:TDO 2 "dmr_register_operand" "wD")]
+		    UNSPEC_DMF_DMXOR))]
+  "TARGET_DMF"
+  "dmxor %0,%2"
+  [(set_attr "type" "dmf")])
+
+(define_insn "dmf_<pv>"
+  [(set (match_operand:TDO 0 "accumulator_operand" "=wD")
+	(unspec:TDO [(match_operand:OO 1 "vsx_register_operand" "wa")
+		     (match_operand:V16QI 2 "vsx_register_operand" "wa")]
+		    DMF_PV))]
+  "TARGET_DMF"
+{
+  return "<pv> %0,%x1,%x2";
+}
+  [(set_attr "type" "dmf")])
+
+(define_insn "dmf_<apv>"
+  [(set (match_operand:TDO 0 "accumulator_operand" "=wD")
+	(unspec:TDO [(match_operand:TDO 1 "accumulator_operand" "0")
+		     (match_operand:OO 2 "vsx_register_operand" "wa")
+		     (match_operand:V16QI 3 "vsx_register_operand" "wa")]
+		    DMF_DPV))]
+  "TARGET_DMF"
+{
+  return "<apv> %0,%x2,%x3";
+}
+  [(set_attr "type" "dmf")])
+
+(define_insn "dmf_<pvi8i4i4>"
+  [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
+	(unspec:TDO [(match_operand:OO 1 "vsx_register_operand" "wa")
+		     (match_operand:V16QI 2 "vsx_register_operand" "wa")
+		     (match_operand:SI 3 "u8bit_cint_operand" "n")
+		     (match_operand:SI 4 "const_0_to_15_operand" "n")
+		     (match_operand:SI 5 "const_0_to_15_operand" "n")]
+		    DMF_PVI8I4I4))]
+  "TARGET_DMF"
+{
+  return "<pvi8i4i4> %0,%x1,%x2,%3,%4,%5";
+}
+  [(set_attr "type" "dmf")
+   (set_attr "prefixed" "yes")])
+
+(define_insn "dmf_<dpvi8i4i4>"
+  [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
+	(unspec:TDO [(match_operand:TDO 1 "dmr_register_operand" "0")
+		     (match_operand:OO 2 "vsx_register_operand" "wa")
+		     (match_operand:V16QI 3 "vsx_register_operand" "wa")
+		     (match_operand:SI 4 "u8bit_cint_operand" "n")
+		     (match_operand:SI 5 "const_0_to_15_operand" "n")
+		     (match_operand:SI 6 "const_0_to_15_operand" "n")]
+		    DMF_DPVI8I4I4))]
+  "TARGET_DMF"
+{
+  return "<dpvi8i4i4> %0,%x2,%x3,%4,%5,%6";
+}
+  [(set_attr "type" "dmf")
+   (set_attr "prefixed" "yes")])
+
diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 4ecbbe43ba00..0c6d961d7a7d 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -1121,7 +1121,8 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
   gimple *stmt = gsi_stmt (*gsi);
   size_t fncode = (size_t) fn_code;
 
-  if (!bif_is_mma (rs6000_builtin_info[fncode]))
+  if (!bif_is_mma (rs6000_builtin_info[fncode])
+      && !bif_is_dm (rs6000_builtin_info[fncode]))
     return false;
 
   /* Each call that can be gimple-expanded has an associated built-in
@@ -1129,11 +1130,11 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
      already expanded it!  Exceptions: lxvp and stxvp.  */
   if (rs6000_builtin_info[fncode].assoc_bif == RS6000_BIF_NONE
       && fncode != RS6000_BIF_LXVP
-      && fncode != RS6000_BIF_STXVP)
+      && fncode != RS6000_BIF_STXVP
+      && fncode != RS6000_BIF_DMMR)
     return false;
 
   bifdata *bd = &rs6000_builtin_info[fncode];
-  unsigned nopnds = bd->nargs;
   gimple_seq new_seq = NULL;
   gimple *new_call;
   tree new_decl;
@@ -1249,27 +1250,49 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
 
   /* Convert this built-in into an internal version that uses pass-by-value
      arguments.  The internal built-in is found in the assoc_bif field.  */
-  new_decl = rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif];
+  size_t new_fncode = rs6000_builtin_info[fncode].assoc_bif;
+  new_decl = rs6000_builtin_decls[new_fncode];
   tree lhs, op[MAX_MMA_OPERANDS];
+  tree lhs_type = NULL_TREE;
   tree acc = gimple_call_arg (stmt, 0);
   push_gimplify_context (true);
 
-  if (bif_is_quad (*bd))
+  switch (insn_data[rs6000_builtin_info[new_fncode].icode].operand[0].mode)
     {
-      /* This built-in has a pass-by-reference accumulator input, so load it
-	 into a temporary accumulator for use as a pass-by-value input.  */
-      op[0] = make_ssa_name (vector_quad_type_node);
-      for (unsigned i = 1; i < nopnds; i++)
-	op[i] = gimple_call_arg (stmt, i);
-      gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq);
+    case TDOmode:
+      lhs_type = dmr1024_type_node;
+      break;
+    case XOmode:
+      lhs_type = vector_quad_type_node;
+      break;
+    case OOmode:
+      lhs_type = vector_pair_type_node;
+      break;
+    default:
+      gcc_unreachable ();
     }
-  else
-    {
-      /* This built-in does not use its pass-by-reference accumulator argument
-	 as an input argument, so remove it from the input list.  */
-      nopnds--;
-      for (unsigned i = 0; i < nopnds; i++)
-	op[i] = gimple_call_arg (stmt, i + 1);
+
+  unsigned nopnds = 0;
+  for (int i = 0; i < bd->nargs; i++)
+    {
+      tree arg = gimple_call_arg (stmt, i);
+      if (i == 0 && !bif_is_dmr (*bd) && !bif_is_quad (*bd))
+	continue;
+      /* If this is another DMR operand, it is passed in by reference.
+	 The internal built-ins use pass-by-value, so load this operand
+	 into a variable and pass that in as our operand.  */
+      if (POINTER_TYPE_P (TREE_TYPE (arg))
+	  && types_compatible_p (TREE_TYPE (TREE_TYPE (arg)), lhs_type))
+       {
+	 tree op_mem = build_simple_mem_ref (build1 (NOP_EXPR,
+					     TREE_TYPE (arg),
+					     arg));
+	 op[nopnds] = make_ssa_name (lhs_type);
+	 gimplify_assign (op[nopnds], op_mem, &new_seq);
+       }
+      else
+	op[nopnds] = arg;
+      nopnds++;
     }
 
   switch (nopnds)
@@ -1301,14 +1324,19 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
       new_call = gimple_build_call (new_decl, 7, op[0], op[1], op[2], op[3],
 				    op[4], op[5], op[6]);
       break;
+    case 8:
+      new_call = gimple_build_call (new_decl, 8, op[0], op[1], op[2], op[3],
+				    op[4], op[5], op[6], op[7]);
+      break;
+    case 9:
+      new_call = gimple_build_call (new_decl, 9, op[0], op[1], op[2], op[3],
+				    op[4], op[5], op[6], op[7], op[8]);
+      break;
     default:
       gcc_unreachable ();
     }
 
-  if (fncode == RS6000_BIF_BUILD_PAIR || fncode == RS6000_BIF_ASSEMBLE_PAIR_V)
-    lhs = make_ssa_name (vector_pair_type_node);
-  else
-    lhs = make_ssa_name (vector_quad_type_node);
+  lhs = make_ssa_name (lhs_type);
   gimple_call_set_lhs (new_call, lhs);
   gimple_seq_add_stmt (&new_seq, new_call);
   gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq);
@@ -3025,6 +3053,14 @@ mma_expand_builtin (tree exp, rtx target, insn_code icode,
     case 7:
       pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6]);
       break;
+    case 8:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6],
+			     op[7]);
+      break;
+    case 9:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6],
+			     op[7], op[8]);
+      break;
     default:
       gcc_unreachable ();
     }
@@ -3567,7 +3603,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
   /* Position of first argument (0 for void-returning functions, else 1).  */
   int k;
   /* Modes for the return value, if any, and arguments.  */
-  const int MAX_BUILTIN_ARGS = 6;
+  const int MAX_BUILTIN_ARGS = 8;
   machine_mode mode[MAX_BUILTIN_ARGS + 1];
 
   if (void_func)
@@ -3702,7 +3738,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
   if (bif_is_lxvrze (*bifaddr))
     return lxvrze_expand_builtin (target, icode, op, mode[0], mode[1]);
 
-  if (bif_is_mma (*bifaddr))
+  if (bif_is_mma (*bifaddr) || bif_is_dm (*bifaddr))
     return mma_expand_builtin (exp, target, icode, fcode);
 
   if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index 85486c70f0d7..2c0bc1d0119b 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -4095,3 +4095,58 @@
 
   const vf __builtin_altivec_unpack_int8_to_fp32 (vui, const int<2>);
     VUPKINT8TOFP32 altivec_vupkint8tofp32 {}
+
+[dm]
+  void __builtin_dmsetdmrz (dmr1024 *);
+    DMSETDMRZ nothing {dm,dmint}
+
+  dmr1024 __builtin_dmsetdmrz_internal ();
+    DMSETDMRZ_INTERNAL dmf_dmsetdmrz {dm}
+
+  void __builtin_dmmr (dmr1024 *, dmr1024 *);
+    DMMR nothing {dm,dmint}
+
+  dmr1024 __builtin_dmmr_internal (dmr1024);
+    DMMR_INTERNAL movtdo {dm}
+
+  void __builtin_dmxor (dmr1024 *, dmr1024 *);
+    DMXOR nothing {dm,dmint,dmr}
+
+  dmr1024 __builtin_dmxor_internal (dmr1024, dmr1024);
+    DMXOR_INTERNAL dmf_dmxor {dm}
+
+  void __builtin_build_dmr (dmr1024 *, vuc, vuc, vuc, vuc, vuc, vuc, vuc, vuc);
+    BUILD_DMR nothing {dm,dmint}
+
+  dmr1024 __builtin_build_dmr_internal (vuc, vuc, vuc, vuc, vuc, vuc, vuc, vuc);
+    BUILD_DMR_INTERNAL dmf_build_dmr {dm}
+
+  void __builtin_mma_dmxvi8gerx4 (dmr1024 *, v256, vuc);
+    DMXVI8GERX4 nothing {dm,dmint}
+
+  dmr1024 __builtin_mma_dmxvi8gerx4_internal (v256, vuc);
+    DMXVI8GERX4_INTERNAL dmf_dmxvi8gerx4 {dm}
+
+  void __builtin_mma_dmxvi8gerx4pp (dmr1024 *, v256, vuc);
+    DMXVI8GERX4PP nothing {dm,dmint,dmr}
+
+  dmr1024 __builtin_mma_dmxvi8gerx4pp_internal (dmr1024, v256, vuc);
+    DMXVI8GERX4PP_INTERNAL dmf_dmxvi8gerx4pp {dm}
+
+  void __builtin_mma_pmdmxvi8gerx4 (dmr1024 *, v256, vuc, const int<8>, \
+                                   const int<4>, const int<4>);
+    PMDMXVI8GERX4 nothing {dm,pair,dmint}
+
+  dmr1024 __builtin_mma_pmdmxvi8gerx4_internal (v256, vuc, const int<8>, \
+                                              const int<4>, const int<4>);
+    PMDMXVI8GERX4_INTERNAL dmf_pmdmxvi8gerx4 {dm,pair}
+
+  void __builtin_mma_pmdmxvi8gerx4pp (dmr1024 *, v256, vuc, const int<8>, \
+                                     const int<4>, const int<4>);
+    PMDMXVI8GERX4PP nothing {dm,pair,dmint,dmr}
+
+  dmr1024 __builtin_mma_pmdmxvi8gerx4pp_internal (dmr1024, v256, vuc, \
+                                                const int<8>, const int<4>, \
+                                                const int<4>);
+    PMDMXVI8GERX4PP_INTERNAL dmf_pmdmxvi8gerx4pp {dm,pair}
+
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a61138f5496d..cb956d005420 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -18715,6 +18715,7 @@ instructions, but allow the compiler to schedule those calls.
 * PowerPC Hardware Transactional Memory Built-in Functions::
 * PowerPC Atomic Memory Operation Functions::
 * PowerPC Matrix-Multiply Assist Built-in Functions::
+* PowerPC Dense Math Facility Built-in Functions::
 * PRU Built-in Functions::
 * RISC-V Built-in Functions::
 * RISC-V Vector Intrinsics::
@@ -27469,6 +27470,43 @@ __vector_pair __builtin_vsx_lxvp (size_t, __vector_pair *);
 void __builtin_vsx_stxvp (__vector_pair, size_t, __vector_pair *);
 @end smallexample
 
+Future ISA of PowerPC may add new Matrix-Multiply Assist Plus (MMA+)
+instructions.  GCC provides support for these instructions through the
+following built-in functions which are enabled with the @code{-mmma} option.
+The vec_t type below is defined to be a normal vector unsigned char type.
+The uint2, uint4 and uint8 parameters are 2-bit, 4-bit and 8-bit unsigned
+integer constants respectively.  The compiler will verify that they are
+constants and that their values are within range.  The __dmr1024 type is a
+1024-bit integer type.
+
+The built-in functions supported are:
+
+@smallexample
+void __builtin_mma_dmxvi8gerx4 (__dmr1024 *, __vector_pair, vec_t);
+void __builtin_mma_dmxvi8gerx4pp (__dmr1024 *, __vector_pair, vec_t);
+
+void __builtin_mma_pmdmxvi8gerx4 (__dmr1024 *, __vector_pair, vec_t, uint8, uint4, uint4);
+void __builtin_mma_pmdmxvi8gerx4pp (__dmr1024 *, __vector_pair, vec_t, uint8, uint4, uint4);
+@end smallexample
+
+@node PowerPC Dense Math Facility Built-in Functions
+@subsection PowerPC Dense Math Facility Built-in Functions
+
+A future PowerPC processor may provide Dense Math Facility (DMF)
+instructions.  GCC provides support for these instructions through the
+following built-in functions which are enabled with the @code{-mdense-math}
+option.  The vec_t type below is defined to be a normal vector unsigned char
+type.  The __dmr1024 type is a 1024 bit integer type.
+
+The built-in functions supported are:
+
+@smallexample
+void __builtin_dmsetdmrz (__dmr1024 *);
+void __builtin_dmmr (__dmr1024 *, __dmr1024 *);
+void __builtin_dmxor (__dmr1024 *, __dmr1024 *);
+void __builtin_build_dmr (__dmr1024 *, vec_t, vec_t, vec_t, vec_t, vec_t, vec_t, vec_t, vec_t);
+@end smallexample
+
 @node PRU Built-in Functions
 @subsection PRU Built-in Functions
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c b/gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c
new file mode 100644
index 000000000000..d5e85e64e27e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+
+typedef unsigned char vec_t __attribute__((vector_size(16)));
+
+void
+foo2 (__dmr1024 *dst, vec_t *src)
+{
+  __builtin_build_dmr (dst, src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7]);
+}
+
+/* { dg-final { scan-assembler-times {\mdmxxinstdmr512\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mlxv\M} 8 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-builtin.c b/gcc/testsuite/gcc.target/powerpc/dmf-builtin.c
new file mode 100644
index 000000000000..02bbebf69f82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmf-builtin.c
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+
+typedef unsigned char vec_t __attribute__((vector_size(16)));
+
+void
+foo (__dmr1024 *dst, __vector_pair *vpp, vec_t *src)
+{
+  __dmr1024 dmr;
+  __vector_pair vp = *vpp;
+  vec_t vec = *src;
+  __builtin_dmsetdmrz (&dmr);
+  __builtin_mma_dmxvi8gerx4 (&dmr, vp, vec);
+  *dst = dmr;
+}
+
+void
+bar (__dmr1024 *dst, __vector_pair *vpp, vec_t *src)
+{
+  __dmr1024 dmr = dst[0];
+  __vector_pair vp = *vpp;
+  vec_t vec = *src;
+  __builtin_mma_dmxvi8gerx4 (&dmr, vp, vec);
+  dst[1] = dmr;
+}
+
+/* { dg-final { scan-assembler-times {\mdmxvi8gerx4\M} 2 } } */
+
+void
+foo_1 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src)
+{
+  __dmr1024 dmr;
+  __vector_pair vp = *vpp;
+  vec_t vec = *src;
+  __builtin_dmsetdmrz (&dmr);
+  __builtin_mma_dmxvi8gerx4pp (&dmr, vp, vec);
+  *dst = dmr;
+}
+
+void
+bar_1 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src)
+{
+  __dmr1024 dmr = dst[0];;
+  __vector_pair vp = *vpp;
+  vec_t vec = *src;
+  __builtin_mma_dmxvi8gerx4pp (&dmr, vp, vec);
+  dst[1] = dmr;
+}
+
+/* { dg-final { scan-assembler-times {\mdmxvi8gerx4pp\M} 2 } } */
+
+void
+foo_2 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src)
+{
+  __vector_pair vp = *vpp;
+  vec_t vec = *src;
+  __builtin_mma_pmdmxvi8gerx4 (dst, vp, vec, 255, 15, 2);
+}
+
+/* { dg-final { scan-assembler-times {\mpmdmxvi8gerx4\M} 1 } } */
+
+void
+foo_3 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src)
+{
+  __vector_pair vp = *vpp;
+  vec_t vec = *src;
+  __builtin_mma_pmdmxvi8gerx4pp (dst, vp, vec, 255, 15, 2);
+}
+
+/* { dg-final { scan-assembler-times {\mpmdmxvi8gerx4pp\M} 1 } } */
+
+
+void
+foo_5 (__dmr1024 *dst, __dmr1024 *src)
+{
+  __builtin_dmxor (dst, src);
+}
+
+/* { dg-final { scan-assembler-times {\mdmxor\M} 1 } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.