https://gcc.gnu.org/g:f408d09eedfad5c9b470750c85444faea7f7ccc7
commit r17-4269-gf408d09eedfad5c9b470750c85444faea7f7ccc7 Author: Takayuki 'January June' Suwa <[email protected]> Date: Sun Sep 13 05:08:17 2026 +0900 xtensa: Revise REGNO_REG_CLASS() macro definition In the "Register Classes" chapter, gccint states the following regarding REGNO_REG_CLASS: " REGNO_REG_CLASS (regno) [Macro] A C expression whose value is a register class containing hard register regno. In general there is more than one such class; choose a class which is minimal, meaning that no smaller class also contains the register. " -- 19.8 Register Classes, gccint (the latest) This patch adds code to the end of the function specified by the TARGET_CONDITIONAL_REGISTER_USAGE macro to generate a regno-to-"minimal" regclass mapping, and ensures that this mapping is subsequently referenced via REGNO_REG_CLASS(). gcc/ChangeLog: * config/xtensa/xtensa-protos.h (xtensa_regno_to_class): Remove. * config/xtensa/xtensa.h (xtensa_regno_to_class): Declaration of a new global array. (REGNO_REG_CLASS): Change to reference the xtensa_regno_to_class array. * config/xtensa/xtensa.cc (xtensa_regno_to_class): Remove the original function definition and define it as a new global array. (xtensa_conditional_register_usage): Append code to the end that records a map in xtensa_regno_to_class showing which of the current regclass definitions each hardware register belongs to. Diff: --- gcc/config/xtensa/xtensa-protos.h | 1 - gcc/config/xtensa/xtensa.cc | 39 ++++++++++++++++----------------------- gcc/config/xtensa/xtensa.h | 3 ++- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index d729b488397b..f3387dd3177d 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -81,7 +81,6 @@ extern long compute_frame_size (poly_int64); extern void xtensa_expand_prologue (void); extern void xtensa_expand_epilogue (void); extern void xtensa_adjust_reg_alloc_order (void); -extern enum reg_class xtensa_regno_to_class (int regno); extern HOST_WIDE_INT xtensa_initial_elimination_offset (int from, int to); extern const char **xtensa_get_config_strings (void); extern rtl_opt_pass *make_pass_xtensa_largeconst1 (gcc::context *); diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index 9f9d1b8ef49a..ae0cde876a26 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -112,6 +112,9 @@ struct GTY(()) machine_function bool postreload_completed; }; +/* Referenced by the REGNO_REG_CLASS() macro. */ +enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; + static void xtensa_option_override (void); static void xtensa_option_override_after_change (void); static enum internal_test map_test_to_internal_test (enum rtx_code); @@ -5365,7 +5368,7 @@ xtensa_reorg (void) static void xtensa_conditional_register_usage (void) { - unsigned i, c_mask; + unsigned int i, c_mask, cl; c_mask = TARGET_WINDOWED_ABI ? (1 << 1) : (1 << 2); @@ -5391,30 +5394,20 @@ xtensa_conditional_register_usage (void) fixed_regs[A0_REG] = 0; else CLEAR_HARD_REG_BIT (reg_class_contents[RL_REGS], A0_REG); -} - -/* Map hard register number to register class */ -enum reg_class xtensa_regno_to_class (int regno) -{ - static const enum reg_class regno_to_class[FIRST_PSEUDO_REGISTER] = - { - RL_REGS, SP_REG, RL_REGS, RL_REGS, - RL_REGS, RL_REGS, RL_REGS, RL_REGS, - RL_REGS, RL_REGS, RL_REGS, RL_REGS, - RL_REGS, RL_REGS, RL_REGS, RL_REGS, - AR_REGS, AR_REGS, BR_REGS, - FP_REGS, FP_REGS, FP_REGS, FP_REGS, - FP_REGS, FP_REGS, FP_REGS, FP_REGS, - FP_REGS, FP_REGS, FP_REGS, FP_REGS, - FP_REGS, FP_REGS, FP_REGS, FP_REGS, - ACC_REG, - }; + /* Generate the contents of the reverse-lookup array from the currently + active register class definitions. */ + for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) + for (cl = NO_REGS + 1; cl < ALL_REGS; ++cl) + if (TEST_HARD_REG_BIT (reg_class_contents[cl], i)) + { + xtensa_regno_to_class[i] = (enum reg_class)cl; + break; + } - if (regno == HARD_FRAME_POINTER_REGNUM) - return GR_REGS; - else - return regno_to_class[regno]; + /* Verify the generated mapping for any omissions. */ + for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) + gcc_assert (xtensa_regno_to_class[i] != NO_REGS); } /* Implement TARGET_CONSTANT_ALIGNMENT. Align string constants and diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 4fab1e055a18..eea7323b326a 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -408,7 +408,8 @@ enum reg_class register REGNO. In general there is more that one such class; choose a class which is "minimal", meaning that no smaller class also contains the register. */ -#define REGNO_REG_CLASS(REGNO) xtensa_regno_to_class (REGNO) +extern enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; +#define REGNO_REG_CLASS(REGNO) xtensa_regno_to_class[REGNO] /* Use the Xtensa AR register file for base registers. No index registers. */
