diff mbox

RX: don't renumber interrupt registers

Message ID 201107261932.p6QJWqIf005879@greed.delorie.com
State New
Headers show

Commit Message

DJ Delorie July 26, 2011, 7:32 p.m. UTC
If a function is both a leaf function and an interrupt function, leaf
register renumbering causes the wrong set of registers to be saved.
This patch disables renumbering for interrupt functions.

	* config/rx/rx.c (rx_leaf_registers): New.
	(rx_set_leaf_registers): New.
	(rx_expand_prologue): Call it.
	* config/rx/rx.h (LEAF_REGISTERS): Define.
	(LEAF_REG_REMAP): Define.
diff mbox

Patch

Index: gcc/config/rx/rx.c
===================================================================
--- gcc/config/rx/rx.c	(revision 176766)
+++ gcc/config/rx/rx.c	(working copy)
@@ -985,12 +985,24 @@  is_naked_func (const_tree decl)
 {
   return has_func_attr (decl, "naked");
 }
 
 static bool use_fixed_regs = false;
 
+char rx_leaf_registers [FIRST_PSEUDO_REGISTER];
+
+static void
+rx_set_leaf_registers (int enable)
+{
+  int i;
+
+  if (rx_leaf_registers[0] != enable)
+    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+      rx_leaf_registers[i] = enable;
+}
+
 static void
 rx_conditional_register_usage (void)
 {
   static bool using_fixed_regs = false;
 
   if (rx_small_data_limit > 0)
@@ -1380,12 +1392,17 @@  rx_expand_prologue (void)
   rtx insn;
 
   /* Naked functions use their own, programmer provided prologues.  */
   if (is_naked_func (NULL_TREE))
     return;
 
+  /* We must not allow register renaming in interrupt functions,
+     because that invalidates the correctness of the set of call-used
+     registers we're going to save/restore.  */
+  rx_set_leaf_registers (is_interrupt_func (NULL_TREE) ? 0 : 1);
+
   rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
 
   /* If we use any of the callee-saved registers, save them now.  */
   if (mask)
     {
       /* Push registers in reverse order.  */
Index: gcc/config/rx/rx.h
===================================================================
--- gcc/config/rx/rx.h	(revision 176766)
+++ gcc/config/rx/rx.h	(working copy)
@@ -260,12 +260,17 @@  enum reg_class
 /* Order of allocation of registers.  */
 
 #define REG_ALLOC_ORDER						\
 {  7,  10,  11,  12,  13,  14,  4,  3,  2,  1, 9, 8, 6, 5, 15	\
 }
 
+/* We must somehow disable register remapping for interrupt functions.  */
+extern char rx_leaf_registers[];
+#define LEAF_REGISTERS rx_leaf_registers
+#define LEAF_REG_REMAP(REG) (REG)
+
 #define REGNO_IN_RANGE(REGNO, MIN, MAX)		\
   (IN_RANGE ((REGNO), (MIN), (MAX)) 		\
    || (reg_renumber != NULL			\
        && reg_renumber[(REGNO)] >= (MIN)	\
        && reg_renumber[(REGNO)] <= (MAX)))