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.  */

Reply via email to