The future processor may introduce new set of registers for
accumulators. This patch adds a constraint and predicate for the
accumulator registers which can be used by the dense math and mma
patterns.

2026-07-11  Avinash Jayakar  <[email protected]>

gcc/ChangeLog:
        * config/rs6000/constraints.md
        (rs6000_constraints[RS6000_CONSTRAINT_wD]): New wD constraint.
        * config/rs6000/predicates.md (accumulator_operand): New predicate.
        * config/rs6000/rs6000.cc (rs6000_debug_reg_global): Support wD
        register class.
        (rs6000_init_hard_regno_mode_ok): Map wD to FLOAT_REGS.
        * config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add wD constraint.
        * doc/md.texi: Document the new constraint.
---
 gcc/config/rs6000/constraints.md |  4 ++++
 gcc/config/rs6000/predicates.md  | 18 ++++++++++++++++++
 gcc/config/rs6000/rs6000.cc      | 11 +++++++++--
 gcc/config/rs6000/rs6000.h       |  1 +
 gcc/doc/md.texi                  |  4 ++++
 5 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index d0ed47faab8..4b2e703f049 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -99,6 +99,10 @@ (define_register_constraint "wA" 
"rs6000_constraints[RS6000_CONSTRAINT_wA]"
   "@internal Like @code{b}, if @option{-mpowerpc64} is used; otherwise,
    @code{NO_REGS}.")
 
+(define_register_constraint "wD" "rs6000_constraints[RS6000_CONSTRAINT_wD]"
+  "@internal Floating point register @code{FPR} if TARGET_MMA is enabled.
+  1024 bit Dense math register @code{DMR} if TARGET_DMF is enabled.")
+
 ;; wB needs ISA 2.07 VUPKHSW
 (define_constraint "wB"
   "@internal Signed 5-bit constant integer that can be loaded into an
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 4162c22f8f6..9d4928b0464 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -163,6 +163,24 @@ (define_predicate "vint_operand"
   return VINT_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if op is an accumulator.  On power10/11 systems, the accumulators
+;; overlap with the FPRs. If TARGET_DMF is true, it will be Dense math 
register.
+(define_predicate "accumulator_operand"
+  (match_operand 0 "register_operand")
+{
+  if (SUBREG_P (op))
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (!HARD_REGISTER_P (op))
+    return 1;
+
+  int r = REGNO (op);
+  return TARGET_DMF ? DMR_REGNO_P (r) : (FP_REGNO_P (r) && (r & 3) == 0);
+})
+
 ;; Return 1 if op is a vector register to do logical operations on (and, or,
 ;; xor, etc.)
 (define_predicate "vlogical_operand"
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index d8669d9ffce..28381ab3227 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -2328,6 +2328,7 @@ rs6000_debug_reg_global (void)
           "wr reg_class = %s\n"
           "wx reg_class = %s\n"
           "wA reg_class = %s\n"
+          "wD reg_class = %s\n"
           "\n",
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
@@ -2335,7 +2336,8 @@ rs6000_debug_reg_global (void)
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_we]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]]);
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]],
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wD]]);
 
   nl = "\n";
   for (m = 0; m < NUM_MACHINE_MODES; ++m)
@@ -2970,7 +2972,8 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
        wc - Reserved to represent individual CR bits (used in LLVM).
        wn - always NO_REGS.
        wr - GPR if 64-bit mode is permitted.
-       wx - Float register if we can do 32-bit int stores.  */
+       wx - Float register if we can do 32-bit int stores.
+       wD - Dense math register if TARGET_DMF is enabled, else float register. 
 */
 
   if (TARGET_HARD_FLOAT)
     rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
@@ -2978,6 +2981,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
     rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
   if (TARGET_VSX)
     rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
+  if (TARGET_DMF)
+    rs6000_constraints[RS6000_CONSTRAINT_wD] = DMR_REGS;
+  else if (TARGET_MMA)
+    rs6000_constraints[RS6000_CONSTRAINT_wD] = FLOAT_REGS;
 
   if (TARGET_POWERPC64)
     {
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 8235e095bcc..a46ed39a3e9 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1184,6 +1184,7 @@ enum r6000_reg_class_enum {
   RS6000_CONSTRAINT_wr,                /* GPR register if 64-bit  */
   RS6000_CONSTRAINT_wx,                /* FPR register for STFIWX */
   RS6000_CONSTRAINT_wA,                /* BASE_REGS if 64-bit.  */
+  RS6000_CONSTRAINT_wD,                /* Accumulator registers.  */
   RS6000_CONSTRAINT_MAX
 };
 
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index a98a572cc01..4253dc831e8 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3297,6 +3297,10 @@ Like @code{b}, if @option{-mpowerpc64} is used; 
otherwise, @code{NO_REGS}.
 @item wB
 Signed 5-bit constant integer that can be loaded into an Altivec register.
 
+@item wD
+Dense math register if @option{-mdense-math} is used; floating point register 
if
+@option{-mmma} with @option{-mno-dense-math}; otherwise, @code{NO_REGS}.
+
 @item wE
 Vector constant that can be loaded with the XXSPLTIB instruction.
 
-- 
2.54.0

Reply via email to