(insn-attr.h): Include.

(pragma_nosave_low_regs): New global variable.
(calc_live_regs): If SH3 and pragma_nosave_low_regs, then don't
save registers r0 through r7 for interrupt functions.
(function_epilogue): Clear pragma_nosave_low_regs.
(handle_pragma): Set pragma_nosave_low_regs if see pragma for it.

From-SVN: r10649
This commit is contained in:
Jim Wilson 1995-11-30 12:31:06 -08:00
parent b6c9286a86
commit 956a5206b0
1 changed files with 19 additions and 3 deletions

View File

@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */
#include "regs.h"
#include "hard-reg-set.h"
#include "output.h"
#include "insn-attr.h"
#define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)
#define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)
@ -46,6 +47,13 @@ int pragma_interrupt;
the compiler doesn't emit code to preserve all registers. */
static int pragma_trapa;
/* This is set by #pragma nosave_low_regs. This is useful on the SH3,
which has a separate set of low regs for User and Supervisor modes.
This should only be used for the lowest level of interrupts. Higher levels
of interrupts must save the registers in case they themselves are
interrupted. */
int pragma_nosave_low_regs;
/* This is used for communication between SETUP_INCOMING_VARARGS and
sh_expand_prologue. */
int current_function_anonymous_args;
@ -1509,11 +1517,14 @@ calc_live_regs (count_ptr)
{
if (pragma_interrupt && ! pragma_trapa)
{
/* Need to save all the regs ever live. */
/* Normally, we must save all the regs ever live.
If pragma_nosave_low_regs, then don't save any of the
registers which are banked on the SH3. */
if ((regs_ever_live[reg]
|| (call_used_regs[reg] && regs_ever_live[PR_REG]))
&& reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM
&& reg != T_REG && reg != GBR_REG)
&& reg != T_REG && reg != GBR_REG
&& ! (sh_cpu == CPU_SH3 && pragma_nosave_low_regs && reg < 8))
{
live_regs_mask |= 1 << reg;
count++;
@ -1613,7 +1624,7 @@ function_epilogue (stream, size)
FILE *stream;
int size;
{
pragma_interrupt = pragma_trapa = 0;
pragma_interrupt = pragma_trapa = pragma_nosave_low_regs = 0;
}
/* Define the offset between two registers, one to be eliminated, and
@ -1675,6 +1686,11 @@ handle_pragma (file)
pragma_interrupt = pragma_trapa = 1;
return ' ';
}
if (psize == 15 && strncmp (pbuf, "nosave_low_regs", 15) == 0)
{
pragma_nosave_low_regs = 1;
return ' ';
}
c = getc (file);
}
return c;