https://gcc.gnu.org/g:df7a9c7cfc4fd6d74577b01b4be6e25d6e5ba0b3

commit df7a9c7cfc4fd6d74577b01b4be6e25d6e5ba0b3
Author: Kishan Parmar <[email protected]>
Date:   Tue Jul 7 02:01:01 2026 +0530

    rs6000: Treat xxmtacc/xxmfacc as no-ops and build accumulators via DMR for 
DMF
    
    When the Dense Math Facility (DMF) is enabled, accumulators are backed
    by dedicated Dense Math Registers (DMRs) instead of aliased VSX/FPR
    registers. In this mode, xxmtacc/xxmfacc do not require explicit
    prime/deprime operations, so treat them as no-ops.
    
    Update accumulator assembly to construct accumulators in DMRs using
    DMR insert operations rather than relying on aliased VSX/FPR registers.
    Also switch the relevant patterns to use accumulator_operand/"wD" so
    they correctly support both conventional and DMF-backed accumulators,
    and avoid emitting xxmtacc/xxmfacc during internal accumulator
    moves when DMF is enabled.

Diff:
---
 gcc/config/rs6000/mma.md    | 70 ++++++++++++++++++++++++++++++++++++---------
 gcc/config/rs6000/rs6000.cc | 35 ++++++++++++++---------
 2 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index 1103f1fc0375..a31ac8b3bac3 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -91,6 +91,7 @@
    UNSPEC_MMA_XVI8GER4SPP
    UNSPEC_MMA_XXMFACC
    UNSPEC_MMA_XXMTACC
+   UNSPEC_DM_INSERT512
   ])
 
 (define_c_enum "unspecv"
@@ -425,19 +426,42 @@
   DONE;
 })
 
+;; Move from VSX registers to DMR registers via two insert 512 bit
+;; instructions.
+(define_insn "dm_insert512"
+  [(set (match_operand:XO 0 "dmr_register_operand" "=wD")
+       (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa")
+                  (match_operand:OO 2 "vsx_register_operand" "wa")
+                 (match_operand 3 "const_0_to_1_operand")]
+                 UNSPEC_DM_INSERT512))]
+  "TARGET_DMF"
+  "dmxxinstdmr512 %0,%x1,%x2,%3"
+  [(set_attr "type" "mma")])
+
 (define_expand "mma_assemble_acc"
-  [(match_operand:XO 0 "fpr_reg_operand")
+  [(match_operand:XO 0 "accumulator_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")]
   "TARGET_MMA"
 {
-  rtx src = gen_rtx_UNSPEC_VOLATILE (XOmode,
-                                    gen_rtvec (4, operands[1], operands[2],
-                                               operands[3], operands[4]),
-                                    UNSPECV_MMA_ASSEMBLE);
-  emit_move_insn (operands[0], src);
+  if (TARGET_DMF)
+    {
+      rtx vp0 = gen_reg_rtx (OOmode);
+      rtx vp1 = 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_dm_insert512 (operands[0], vp0, vp1, const0_rtx));
+    }
+  else
+    {
+      rtx src = gen_rtx_UNSPEC_VOLATILE (XOmode,
+                                        gen_rtvec (4, operands[1], operands[2],
+                                                   operands[3], operands[4]),
+                                        UNSPECV_MMA_ASSEMBLE);
+      emit_move_insn (operands[0], src);
+    }
   DONE;
 })
 
@@ -445,7 +469,7 @@
 ;; as an early clobber so we don't accidentally clobber the input operands.  */
 
 (define_insn_and_split "*mma_assemble_acc"
-  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+  [(set (match_operand:XO 0 "accumulator_operand" "=&wD")
        (unspec_volatile:XO
          [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
           (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")
@@ -453,7 +477,7 @@
           (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")]
          UNSPECV_MMA_ASSEMBLE))]
   "TARGET_MMA
-   && fpr_reg_operand (operands[0], XOmode)"
+   && accumulator_operand (operands[0], XOmode)"
   "#"
   "&& reload_completed"
   [(const_int 0)]
@@ -468,7 +492,7 @@
 
 (define_expand "mma_disassemble_acc"
   [(match_operand:V16QI 0 "mma_disassemble_output_operand")
-   (match_operand:XO 1 "fpr_reg_operand")
+   (match_operand:XO 1 "accumulator_operand")
    (match_operand 2 "const_0_to_3_operand")]
   "TARGET_MMA"
 {
@@ -499,15 +523,35 @@
   DONE;
 })
 
+;; xxmtacc/xxmfacc prime/deprime an accumulator that lives in 4 adjacent
+;; FPRs -- they reformat that shared FPR/accumulator storage in place.  On
+;; TARGET_DMF, DMRs are a register file entirely separate from the FPRs,
+;; so there is no such format to convert and these are a nop.  This expand
+;; only exists so __builtin_mma_xxmfacc/xxmtacc (which always resolve to
+;; this icode, regardless of register class) correctly do nothing on
+;; TARGET_DMF instead of failing to match any insn.
+(define_expand "mma_<acc>"
+  [(set (match_operand:XO 0 "accumulator_operand")
+       (unspec:XO [(match_operand:XO 1 "accumulator_operand")]
+                   MMA_ACC))]
+  "TARGET_MMA"
+{
+  if (TARGET_DMF)
+    {
+      emit_move_insn (operands[0], operands[1]);
+      DONE;
+    }
+})
+
 ;; MMA instructions that do not use their accumulators as an input, still
 ;; must not allow their vector operands to overlap the registers used by
 ;; the accumulator.  We enforce this by marking the output as early clobber.
 
-(define_insn "mma_<acc>"
-  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
-       (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")]
+(define_insn "*mma_<acc>"
+  [(set (match_operand:XO 0 "accumulator_operand" "=&wD")
+       (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0")]
                    MMA_ACC))]
-  "TARGET_MMA"
+  "TARGET_MMA && !TARGET_DMF"
   "<acc> %A0"
   [(set_attr "type" "mma")])
 
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index c2302a253379..49695dfbc163 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -27587,8 +27587,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
          unsigned size = GET_MODE_SIZE (reg_mode);
 
          /* If we are reading an accumulator register, we have to
-            deprime it before we can access it.  */
-         if (TARGET_MMA
+            deprime it before we can access it, unless we have dense math
+            registers, which do not need priming/depriming.  */
+         if (TARGET_MMA && !TARGET_DMF
              && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src)))
            emit_insn (gen_mma_xxmfacc (src, src));
 
@@ -27621,8 +27622,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
            }
 
          /* If we are writing an accumulator register, we have to
-            prime it after we've written it.  */
-         if (TARGET_MMA
+            prime it after we've written it, unless we have dense math
+            registers, which do not need priming/depriming.  */
+         if (TARGET_MMA && !TARGET_DMF
              && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst)))
            emit_insn (gen_mma_xxmtacc (dst, dst));
 
@@ -27690,8 +27692,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
            }
 
          /* We are writing an accumulator register, so we have to
-            prime it after we've written it.  */
-         if (GET_MODE (src) == XOmode)
+            prime it after we've written it, unless we have dense math
+            registers, which do not need priming/depriming.  */
+         if (GET_MODE (src) == XOmode && !TARGET_DMF)
            emit_insn (gen_mma_xxmtacc (dst, dst));
 
          return;
@@ -27703,8 +27706,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
   if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
     {
       /* If we are reading an accumulator register, we have to
-        deprime it before we can access it.  */
-      if (TARGET_MMA
+        deprime it before we can access it, unless we have dense math
+        registers, which do not need priming/depriming.  */
+      if (TARGET_MMA && !TARGET_DMF
          && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src)))
        emit_insn (gen_mma_xxmfacc (src, src));
 
@@ -27731,8 +27735,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
        }
 
       /* If we are writing an accumulator register, we have to
-        prime it after we've written it.  */
-      if (TARGET_MMA
+        prime it after we've written it, unless we have dense math
+        registers, which do not need priming/depriming.  */
+      if (TARGET_MMA && !TARGET_DMF
          && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst)))
        emit_insn (gen_mma_xxmtacc (dst, dst));
     }
@@ -27868,8 +27873,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
        }
 
       /* If we are reading an accumulator register, we have to
-        deprime it before we can access it.  */
-      if (TARGET_MMA && REG_P (src)
+        deprime it before we can access it, unless we have dense math
+        registers, which do not need priming/depriming.  */
+      if (TARGET_MMA && !TARGET_DMF && REG_P (src)
          && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src)))
        emit_insn (gen_mma_xxmfacc (src, src));
 
@@ -27900,8 +27906,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
        }
 
       /* If we are writing an accumulator register, we have to
-        prime it after we've written it.  */
-      if (TARGET_MMA && REG_P (dst)
+        prime it after we've written it, unless we have dense math
+        registers, which do not need priming/depriming.  */
+      if (TARGET_MMA && !TARGET_DMF && REG_P (dst)
          && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst)))
        emit_insn (gen_mma_xxmtacc (dst, dst));

Reply via email to