This patch adds a new constraint ('wD') that matches the accumulator registers
that overlap with VSX registers 0..31 on power10. Future patches will add the
support for a separate accumulator register class that will be used when the
support for dense math registes is added.
2025-11-07 Michael Meissner <[email protected]>
* config/rs6000/constraints.md (wD): New constraint.
* config/rs6000/mma.md (mma_<acc>): Prepare for alternate accumulator
registers. Use wD constraint instead of 'd' constraint. Use
accumulator_operand instead of fpr_reg_operand.
(mma_<vv>): Likewise.
(mma_<avv>): Likewise.
(mma_<pv>): Likewise.
(mma_<apv>): Likewise.
(mma_<vvi4i4i8>): Likewise.
(mma_<avvi4i4i8>): Likewise.
(mma_<vvi4i4i2>): Likewise.
(mma_<avvi4i4i2>): Likewise.
(mma_<vvi4i4>): Likewise.
(mma_<avvi4i4>): Likewise.
(mma_<pvi4i2): Likewise.
(mma_<apvi4i2>): Likewise.
(mma_<vvi4i4i4>): Likewise.
(mma_<avvi4i4i4): Likewise.
* config/rs6000/predicates.md (accumulator_operand): New predicate.
* config/rs6000/rs6000.cc (rs6000_debug_reg_global): Print the register
class for the 'wD' constraint.
(rs6000_init_hard_regno_mode_ok): Set up the 'wD' register constraint
class.
* config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add element for
the 'wD' constraint.
* doc/md.texi (PowerPC constraints): Document the 'wD' constraint.
---
gcc/config/rs6000/constraints.md | 3 +++
gcc/config/rs6000/mma.md | 46 ++++++++++++++++----------------
gcc/config/rs6000/predicates.md | 15 +++++++++++
gcc/config/rs6000/rs6000.cc | 7 ++++-
gcc/config/rs6000/rs6000.h | 1 +
gcc/doc/md.texi | 5 ++++
6 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 4875895e4f5..3da9ed08681 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -107,6 +107,9 @@ (define_constraint "wB"
(match_test "TARGET_P8_VECTOR")
(match_operand 0 "s5bit_cint_operand")))
+(define_register_constraint "wD" "rs6000_constraints[RS6000_CONSTRAINT_wD]"
+ "Accumulator register.")
+
(define_constraint "wE"
"@internal Vector constant that can be loaded with the XXSPLTIB instruction."
(match_test "xxspltib_constant_nosplit (op, mode)"))
diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index 85f3a926682..9f866361376 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -461,8 +461,8 @@ (define_expand "mma_disassemble_acc"
;; 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")]
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0")]
MMA_ACC))]
"TARGET_MMA"
"<acc> %A0"
@@ -480,7 +480,7 @@ (define_insn "mma_xxsetaccz"
[(set_attr "type" "mma")])
(define_insn "mma_<vv>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")]
MMA_VV))]
@@ -489,8 +489,8 @@ (define_insn "mma_<vv>"
[(set_attr "type" "mma")])
(define_insn "mma_<avv>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")]
MMA_AVV))]
@@ -499,7 +499,7 @@ (define_insn "mma_<avv>"
[(set_attr "type" "mma")])
(define_insn "mma_<pv>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:OO 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")]
MMA_PV))]
@@ -508,8 +508,8 @@ (define_insn "mma_<pv>"
[(set_attr "type" "mma")])
(define_insn "mma_<apv>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:OO 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")]
MMA_APV))]
@@ -518,7 +518,7 @@ (define_insn "mma_<apv>"
[(set_attr "type" "mma")])
(define_insn "mma_<vvi4i4i8>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:SI 3 "const_0_to_15_operand" "n,n")
@@ -531,8 +531,8 @@ (define_insn "mma_<vvi4i4i8>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<avvi4i4i8>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")
(match_operand:SI 4 "const_0_to_15_operand" "n,n")
@@ -545,7 +545,7 @@ (define_insn "mma_<avvi4i4i8>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<vvi4i4i2>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:SI 3 "const_0_to_15_operand" "n,n")
@@ -558,8 +558,8 @@ (define_insn "mma_<vvi4i4i2>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<avvi4i4i2>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")
(match_operand:SI 4 "const_0_to_15_operand" "n,n")
@@ -572,7 +572,7 @@ (define_insn "mma_<avvi4i4i2>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<vvi4i4>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:SI 3 "const_0_to_15_operand" "n,n")
@@ -584,8 +584,8 @@ (define_insn "mma_<vvi4i4>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<avvi4i4>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")
(match_operand:SI 4 "const_0_to_15_operand" "n,n")
@@ -597,7 +597,7 @@ (define_insn "mma_<avvi4i4>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<pvi4i2>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:OO 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:SI 3 "const_0_to_15_operand" "n,n")
@@ -609,8 +609,8 @@ (define_insn "mma_<pvi4i2>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<apvi4i2>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:OO 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")
(match_operand:SI 4 "const_0_to_15_operand" "n,n")
@@ -622,7 +622,7 @@ (define_insn "mma_<apvi4i2>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<vvi4i4i4>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:SI 3 "const_0_to_15_operand" "n,n")
@@ -635,8 +635,8 @@ (define_insn "mma_<vvi4i4i4>"
(set_attr "prefixed" "yes")])
(define_insn "mma_<avvi4i4i4>"
- [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d")
- (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0,0")
+ [(set (match_operand:XO 0 "accumulator_operand" "=&wD,&wD")
+ (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0,0")
(match_operand:V16QI 2 "vsx_register_operand" "v,?wa")
(match_operand:V16QI 3 "vsx_register_operand" "v,?wa")
(match_operand:SI 4 "const_0_to_15_operand" "n,n")
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 647e89afb6a..9f152037222 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -186,6 +186,21 @@ (define_predicate "vlogical_operand"
return VLOGICAL_REGNO_P (REGNO (op));
})
+;; Return 1 if op is an accumulator. On power10 systems, the accumulators
+;; overlap with the FPRs.
+(define_predicate "accumulator_operand"
+ (match_operand 0 "register_operand")
+{
+ if (!REG_P (op))
+ return 0;
+
+ if (!HARD_REGISTER_P (op))
+ return 1;
+
+ int r = REGNO (op);
+ return FP_REGNO_P (r) && (r & 3) == 0;
+})
+
;; Return 1 if op is the carry register.
(define_predicate "ca_operand"
(match_operand 0 "register_operand")
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 23d691d88e3..7be845b98fc 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)
@@ -2997,6 +2999,9 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
if (TARGET_DIRECT_MOVE_128)
rs6000_constraints[RS6000_CONSTRAINT_we] = VSX_REGS;
+ if (TARGET_MMA)
+ rs6000_constraints[RS6000_CONSTRAINT_wD] = FLOAT_REGS;
+
/* Set up the reload helper and direct move functions. */
if (TARGET_VSX || TARGET_ALTIVEC)
{
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 3a5695570bc..68cec5c1517 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1193,6 +1193,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 regs if MMA/Dense Math.
*/
RS6000_CONSTRAINT_MAX
};
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index ae5d709bd47..b7e61c5c3c1 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3415,6 +3415,11 @@ Like @code{d}, if @option{-mpowerpc-gfxopt} is used;
otherwise, @code{NO_REGS}.
@item wA
Like @code{b}, if @option{-mpowerpc64} is used; otherwise, @code{NO_REGS}.
+@item wD
+Accumulator register if @option{-mma} is used; otherwise,
+@code{NO_REGS}. For @option{-mcpu=power10} the accumulator registers
+overlap with VSX vector registers 0..31.
+
@item wB
Signed 5-bit constant integer that can be loaded into an Altivec register.
--
2.51.1
--
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]