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.
---
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 d729b488397..f3387dd3177 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 af1e027f53d..400703208b1 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 4fab1e055a1..eea7323b326 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. */
--
2.39.5