(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:
parent
b6c9286a86
commit
956a5206b0
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue