[gcc(refs/vendors/ibm/heads/dmr-support)] rs6000: Add Dense Math (DMF/MMA+) instruction support

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

commit ca15033303848bc675557995bbd586f73804452e
Author: Kishan Parmar <[email protected]>
Date:   Wed Jul 8 13:23:59 2026 +0530

    rs6000: Add Dense Math (DMF/MMA+) instruction support
    
    This patch adds support for Dense Math Facility (DMF) instructions and
    MMA+ (Matrix-Multiply Assist Plus) instructions which may be available in
    a future Power processor.
    The changes extend the existing MMA infrastructure to support the new DMR
    (Dense Math Register) operations.
    
    Key changes:
    
    1. Extended MMA operand support from 7 to 9 operands (MAX_MMA_OPERANDS)
    
    2. Added new DMF-specific unspecs for DMR operations:
       - UNSPEC_DM_INSERT1024 for 1024-bit DMR insertions
       - UNSPEC_DMF_DMXOR for DMR XOR operations
       - UNSPEC_DMF_DMXVI8GERX4* for DMR GER (outer product) operations
       - UNSPEC_DMF_PMDMXVI8GERX4* for prefixed DMR GER operations
    
    3. Implemented new instruction patterns in mma.md:
       - dm_insert1024: Insert 1024-bit data into DMR
       - 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 predicate for DMR register handling:
       - dmr_register_operand: Validates DMR register operands
    
    5. Extended builtin infrastructure:
       - Added 8 new DMF builtins (DMSETDMRZ, DMXOR, BUILD_DMR, etc.)
       - Added dm, dmint, and dmr attributes for builtin classification
       - Updated gimple folding to handle DMR pass-by-reference semantics
       - Extended builtin expansion to support 8 and 9 operand instructions
    
    6. Added ISA support:
       - New "dmf" ISA attribute for Dense Math instructions
       - New "dmf" instruction type for scheduling
       - TARGET_DENSE_MATH feature flag support
    
    The implementation follows the existing MMA pattern where user-facing
    builtins use pass-by-reference for accumulator/DMR arguments, while
    internal builtins use pass-by-value for optimization.
    
    2026-04-11  Peter Bergner  <[email protected]>
                Surya Kumari Jangala <[email protected]>

Diff:
---
 gcc/config/rs6000/mma.md                         | 183 ++++++++++++++++++++++-
 gcc/config/rs6000/rs6000-builtin.cc              |  81 +++++++---
 gcc/config/rs6000/rs6000-builtins.def            |  49 ++++++
 gcc/config/rs6000/rs6000.md                      |  12 +-
 gcc/doc/extend.texi                              |  38 +++++
 gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c |  15 ++
 gcc/testsuite/gcc.target/powerpc/dmf-builtin.c   |  81 ++++++++++
 7 files changed, 430 insertions(+), 29 deletions(-)

diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index a31ac8b3bac3..41dd32ca4edd 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
 
@@ -92,6 +92,14 @@
    UNSPEC_MMA_XXMFACC
    UNSPEC_MMA_XXMTACC
    UNSPEC_DM_INSERT512
+   UNSPEC_DMF_INSERT1024
+   UNSPEC_DMF_DMXOR
+   UNSPEC_DMF_DMXVI8GERX4
+   UNSPEC_DMF_DMXVI8GERX4PP
+   UNSPEC_DMF_PMDMXVI8GERX4
+   UNSPEC_DMF_PMDMXVI8GERX4PP
+   UNSPEC_MMA_DMSETDMRZ
+   UNSPEC_DM_RELOAD_FROM_MEMORY
   ])
 
 (define_c_enum "unspecv"
@@ -134,12 +142,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])
 
@@ -189,6 +203,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 1dmr, 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")])
 
@@ -218,12 +240,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")])
 
@@ -264,6 +288,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"
@@ -436,7 +463,18 @@
 		  UNSPEC_DM_INSERT512))]
   "TARGET_DMF"
   "dmxxinstdmr512 %0,%x1,%x2,%3"
-  [(set_attr "type" "mma")])
+  [(set_attr "type" "dmf")])
+
+(define_insn "dm_insert1024"
+  [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
+       (unspec:TDO [(match_operand:OO 1 "vsx_register_operand" "wa")
+                    (match_operand:OO 2 "vsx_register_operand" "wa")
+                    (match_operand:OO 3 "vsx_register_operand" "wa")
+                    (match_operand:OO 4 "vsx_register_operand" "wa")]
+                   UNSPEC_DMF_INSERT1024))]
+  "TARGET_DMF"
+  "dmxxinstdmr512 %0,%x1,%x2,0\n\tdmxxinstdmr512 %0,%x3,%x4,1"
+  [(set_attr "type" "dmf")])
 
 (define_expand "mma_assemble_acc"
   [(match_operand:XO 0 "accumulator_operand")
@@ -490,6 +528,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[1], operands[2]));
+  emit_insn (gen_vsx_assemble_pair (vp1, operands[3], operands[4]));
+  emit_insn (gen_vsx_assemble_pair (vp2, operands[5], operands[6]));
+  emit_insn (gen_vsx_assemble_pair (vp3, operands[7], operands[8]));
+  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")
@@ -566,6 +628,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_MMA_DMSETDMRZ))]
+  "TARGET_DMF"
+  "dmsetdmrz %A0"
+  [(set_attr "type" "mma")])
+
 (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")
@@ -734,3 +803,109 @@
   "<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")])
+
+;; Reload dense math registers from memory.
+(define_insn_and_split "reload_tdo_from_memory"
+  [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
+        (unspec:TDO [(match_operand:TDO 1 "memory_operand" "m")]
+                    UNSPEC_DM_RELOAD_FROM_MEMORY))
+   (clobber (match_operand:XO 2 "vsx_register_operand" "=wa"))]
+  "TARGET_DMF"
+
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  rtx dest = operands[0];
+  rtx src = operands[1];
+  rtx pair0 = operands[2];
+  rtx pair1 = operands[3];
+  rtx pair2 = operands[4];
+  rtx pair3 = operands[5];
+
+  if (BYTES_BIG_ENDIAN)
+    {
+      emit_move_insn (pair0, adjust_address (src, OOmode, 0));
+      emit_move_insn (pair1, adjust_address (src, OOmode, 32));
+      emit_move_insn (pair2, adjust_address (src, OOmode, 64));
+      emit_move_insn (pair3, adjust_address (src, OOmode, 96));
+    }
+  else
+    {
+      emit_move_insn (pair3, adjust_address (src, OOmode, 0));
+      emit_move_insn (pair2, adjust_address (src, OOmode, 32));
+      emit_move_insn (pair1, adjust_address (src, OOmode, 64));
+      emit_move_insn (pair0, adjust_address (src, OOmode, 96));
+    }
+
+  emit_insn (gen_dm_insert1024 (dest, pair0, pair1, pair2, pair3));
+  DONE;
+}
+  [(set_attr "length" "20")
+   (set_attr "max_prefixed_insns" "2")
+   (set_attr "type" "vecload")])
+
+
+(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 "accumulator_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 3fa61cde28a4..db5e3df57ca9 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
@@ -1133,7 +1134,6 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
     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 +1249,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 +1323,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 +3052,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 ();
     }
@@ -3461,7 +3496,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)
@@ -3596,7 +3631,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 172a97adaa88..e4183d847508 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -4042,3 +4042,52 @@
 
   const vuq __builtin_vsx_xsrebase3t3uqm (vuq, vuq, vuq);
     XSREBASE3T3UQM vsx_xsrebase3t3uqm {}
+
+[dm]
+  void __builtin_dmsetdmrz (dmr1024 *);
+    DMSETDMRZ nothing {dm,dmint}
+
+  dmr1024 __builtin_dmsetdmrz_internal ();
+    DMSETDMRZ_INTERNAL dmf_dmsetdmrz {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/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 86d79d922586..e7ad644cdf2e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -223,7 +223,7 @@
    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
    vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
    veclogical,veccmpfx,vecexts,vecmove,
-   htm,htmsimple,dfp,mma,
+   htm,htmsimple,dfp,mma,dmf,
    fused_arith_logical,
    fused_cmp_isel,
    fused_carry,
@@ -371,7 +371,7 @@
   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
 
 ;; The ISA we implement.
-(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,future"
+(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,future,mma,dmf"
   (const_string "any"))
 
 ;; Is this alternative enabled for the current CPU/ISA/etc.?
@@ -427,6 +427,14 @@
      (and (eq_attr "isa" "future")
           (match_test "TARGET_FUTURE"))
      (const_int 1)
+
+     (and (eq_attr "isa" "mma")
+         (match_test "TARGET_MMA"))
+     (const_int 1)
+
+     (and (eq_attr "isa" "dmf")
+         (match_test "TARGET_DMF"))
+     (const_int 1)
     ] (const_int 0)))
 
 ;; If this instruction is microcoded on the CELL processor
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7bd84e6d8cc3..ca32be3b4258 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -18713,6 +18713,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::
@@ -27442,6 +27443,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 __dm1024 type is a
+1024 bit integer type.
+
+The built-in functions supported are:
+
+@smallexample
+void __builtin_mma_dmxvi8gerx4 (__dm1024 *, __vector_pair, vec_t);
+void __builtin_mma_dmxvi8gerx4pp (__dm1024 *, __vector_pair, vec_t);
+
+void __builtin_mma_pmdmxvi8gerx4 (__dm1024 *, __vector_pair, vec_t, uint8, uint4, uint4);
+void __builtin_mma_pmdmxvi8gerx4pp (__dm1024 *, __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 __dm1024 type is a 1024 bit integer type.
+
+The built-in functions supported are:
+
+@smallexample
+void __builtin_dmsetdmrz (__dm1024 *);
+void __builtin_dmmr (__dm1024 *, __dm1024 *);
+void __builtin_dmxor (__dm1024 *, __dm1024 *);
+void __builtin_build_dmr (__dm1024 *, 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..625b311acb9d
--- /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 {\mdmxxextfdmr512\M} 2 } } */
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..434cf2ac2d3d
--- /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.