+2005-10-19 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_hard_regno_rename_ok): Add prototype.
+ * config/s390/s390.c (s390_hard_regno_rename_ok): New function.
+ (s390_can_eliminate): Handle BASE_REGNUM elimination.
+ (s390_initial_elimination_offset): Likewise.
+ (s390_conditional_register_usage): BASE_REGNUM is no longer a fixed
+ register on TARGET_ZARCH targets.
+ * config/s390/s390.h (HARD_REGNO_RENAME_OK): Define
+ (INITIAL_FRAME_POINTER_OFFSET): Remove.
+ (REG_ALLOC_ORDER): Move BASE_REGNUM lower.
+ (ELIMINABLE_REGS): Add BASE_REGNUM elimination rule.
+
2005-10-19 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390.md: Comment describing output modifiers updated.
regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
}
+/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
+
+bool
+s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
+{
+ /* Once we've decided upon a register to use as base register, it must
+ no longer be used for any other purpose. */
+ if (cfun->machine->base_reg)
+ if (REGNO (cfun->machine->base_reg) == old_reg
+ || REGNO (cfun->machine->base_reg) == new_reg)
+ return false;
+
+ return true;
+}
+
/* Return true if register FROM can be eliminated via register TO. */
bool
s390_can_eliminate (int from, int to)
{
+ /* On zSeries machines, we have not marked the base register as fixed.
+ Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
+ If a function requires the base register, we say here that this
+ elimination cannot be performed. This will cause reload to free
+ up the base register (as if it were fixed). On the other hand,
+ if the current function does *not* require the base register, we
+ say here the elimination succeeds, which in turn allows reload
+ to allocate the base register for any other purpose. */
+ if (from == BASE_REGNUM && to == BASE_REGNUM)
+ {
+ if (TARGET_CPU_ZARCH)
+ {
+ s390_init_frame_layout ();
+ return cfun->machine->base_reg == NULL_RTX;
+ }
+
+ return false;
+ }
+
+ /* Everything else must point into the stack frame. */
gcc_assert (to == STACK_POINTER_REGNUM
|| to == HARD_FRAME_POINTER_REGNUM);
offset += index * UNITS_PER_WORD;
break;
+ case BASE_REGNUM:
+ offset = 0;
+ break;
+
default:
gcc_unreachable ();
}
}
if (TARGET_CPU_ZARCH)
{
+ fixed_regs[BASE_REGNUM] = 0;
+ call_used_regs[BASE_REGNUM] = 0;
fixed_regs[RETURN_REGNUM] = 0;
call_used_regs[RETURN_REGNUM] = 0;
}
/* Preferred register allocation order. */
#define REG_ALLOC_ORDER \
-{ 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \
+{ 1, 2, 3, 4, 5, 0, 12, 11, 10, 9, 8, 7, 6, 14, 13, \
16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31, \
15, 32, 33, 34, 35, 36, 37 }
&& (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) : \
0)
+#define HARD_REGNO_RENAME_OK(FROM, TO) \
+ s390_hard_regno_rename_ok (FROM, TO)
+
#define MODES_TIEABLE_P(MODE1, MODE2) \
(((MODE1) == SFmode || (MODE1) == DFmode) \
== ((MODE2) == SFmode || (MODE2) == DFmode))
#define FRAME_POINTER_REQUIRED 0
-#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0
-
-#define ELIMINABLE_REGS \
-{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
- { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+#define ELIMINABLE_REGS \
+{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
+ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
+ { BASE_REGNUM, BASE_REGNUM }}
#define CAN_ELIMINATE(FROM, TO) \
s390_can_eliminate ((FROM), (TO))