https://gcc.gnu.org/g:0982dc7bf700e201c5ccea28d109c7ee0a39edf0

commit 0982dc7bf700e201c5ccea28d109c7ee0a39edf0
Author: Michael Meissner <[email protected]>
Date:   Sat Jul 18 02:51:38 2026 -0400

    DMF patch 10
    
    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/
    
            * 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/
    
            * 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 4761b07973a7..6bd1e8247add 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -18714,6 +18714,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::
@@ -27468,6 +27469,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 } } */

Reply via email to