summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/global.c5
-rw-r--r--gcc/local-alloc.c5
-rw-r--r--gcc/regs.h6
-rw-r--r--gcc/tm.texi11
5 files changed, 30 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4075787acd7..be78bfb1448 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -24,6 +24,11 @@ Wed Sep 30 18:29:26 1998 Jeffrey A Law (law@cygnus.com)
Wed Sep 30 18:19:27 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+ * regs.h (HARD_REGNO_CALL_PART_CLOBBERED): New macro.
+ * local-alloc.c (find_free_reg): Use it.
+ * global.c (find_reg): Likewise.
+ * tm.texi: Document HARD_REGNO_CALL_PART_CLOBBERED.
+
* regs.h (HARD_REGNO_CALLER_SAVE_MODE): New macro.
* caller-save.c (init_caller_save): Use it.
* tm.texi: Document HARD_REGNO_CALLER_SAVE_MODE.
diff --git a/gcc/global.c b/gcc/global.c
index a3d7e023283..3b0c0ec7a4c 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -976,7 +976,10 @@ find_reg (allocno, losers, alt_regs_p, accept_call_clobbered, retrying)
int regno = i;
#endif
if (! TEST_HARD_REG_BIT (used, regno)
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (allocno_calls_crossed[allocno] == 0
+ || accept_call_clobbered
+ || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
{
register int j;
register int lim = regno + HARD_REGNO_NREGS (regno, mode);
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index 5dbde5218f8..3049a988007 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -2043,7 +2043,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
int regno = i;
#endif
if (! TEST_HARD_REG_BIT (first_used, regno)
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (qty_n_calls_crossed[qty] == 0
+ || accept_call_clobbered
+ || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
{
register int j;
register int size1 = HARD_REGNO_NREGS (regno, mode);
diff --git a/gcc/regs.h b/gcc/regs.h
index 02bdf92c1f5..a4065e6e371 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -217,6 +217,12 @@ extern int caller_save_needed;
choose_hard_reg_mode (REGNO, NREGS)
#endif
+/* Registers that get partially clobbered by a call in a given mode.
+ These must not be call used registers. */
+#ifndef HARD_REGNO_CALL_PART_CLOBBERED
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0
+#endif
+
/* Allocated in local_alloc. */
/* A list of SCRATCH rtl allocated by local-alloc. */
diff --git a/gcc/tm.texi b/gcc/tm.texi
index a42eb67a619..463ae8ef6c0 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -1333,6 +1333,17 @@ If a register has 0 in @code{CALL_USED_REGISTERS}, the compiler
automatically saves it on function entry and restores it on function
exit, if the register is used within the function.
+@findex HARD_REGNO_CALL_PART_CLOBBERED
+@item HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode})
+@cindex call-used register
+@cindex call-clobbered register
+@cindex call-saved register
+A C expression that is non-zero if it is not permissible to store a
+value of mode @var{mode} in hard register number @var{regno} across a
+call without some part of it being clobbered. For most machines this
+macro need not be defined. It is only required for machines that do not
+preserve the entire contents of a register across a call.
+
@findex CONDITIONAL_REGISTER_USAGE
@findex fixed_regs
@findex call_used_regs