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
