Commit 93febe68 by Marek Michalkiewicz Committed by Marek Michalkiewicz

avr.c (avr_regs_to_save): New function.


	* config/avr/avr.c (avr_regs_to_save): New function.  Also check
	for fixed registers, possibly used for global register variables.
	(initial_elimination_offset, avr_output_function_prologue,
	avr_output_function_epilogue):  Move common code to avr_regs_to_save.

From-SVN: r53569
parent 004cb263
2002-05-17 Marek Michalkiewicz <marekm@amelek.gda.pl>
* config/avr/avr.c (avr_regs_to_save): New function. Also check
for fixed registers, possibly used for global register variables.
(initial_elimination_offset, avr_output_function_prologue,
avr_output_function_epilogue): Move common code to avr_regs_to_save.
2002-05-17 Neil Booth <neil@daikokuya.demon.co.uk> 2002-05-17 Neil Booth <neil@daikokuya.demon.co.uk>
* Makefile.in: Update for cpptrad.c. * Makefile.in: Update for cpptrad.c.
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
static int avr_naked_function_p PARAMS ((tree)); static int avr_naked_function_p PARAMS ((tree));
static int interrupt_function_p PARAMS ((tree)); static int interrupt_function_p PARAMS ((tree));
static int signal_function_p PARAMS ((tree)); static int signal_function_p PARAMS ((tree));
static int avr_regs_to_save PARAMS ((HARD_REG_SET *));
static int sequent_regs_live PARAMS ((void)); static int sequent_regs_live PARAMS ((void));
static const char * ptrreg_to_str PARAMS ((int)); static const char * ptrreg_to_str PARAMS ((int));
static const char * cond_string PARAMS ((enum rtx_code)); static const char * cond_string PARAMS ((enum rtx_code));
...@@ -363,6 +364,42 @@ signal_function_p (func) ...@@ -363,6 +364,42 @@ signal_function_p (func)
return a != NULL_TREE; return a != NULL_TREE;
} }
/* Return the number of hard registers to push/pop in the prologue/epilogue
of the current function, and optionally store these registers in SET. */
static int
avr_regs_to_save (set)
HARD_REG_SET *set;
{
int reg, count;
int int_or_sig_p = (interrupt_function_p (current_function_decl)
|| signal_function_p (current_function_decl));
int leaf_func_p = leaf_function_p ();
if (set)
CLEAR_HARD_REG_SET (*set);
count = 0;
for (reg = 0; reg < 32; reg++)
{
/* Do not push/pop __tmp_reg__, __zero_reg__, as well as
any global register variables. */
if (fixed_regs[reg])
continue;
if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
|| (regs_ever_live[reg]
&& (int_or_sig_p || !call_used_regs[reg])
&& !(frame_pointer_needed
&& (reg == REG_Y || reg == (REG_Y+1)))))
{
if (set)
SET_HARD_REG_BIT (*set, reg);
count++;
}
}
return count;
}
/* Compute offset between arg_pointer and frame_pointer */ /* Compute offset between arg_pointer and frame_pointer */
int int
...@@ -370,31 +407,15 @@ initial_elimination_offset (from, to) ...@@ -370,31 +407,15 @@ initial_elimination_offset (from, to)
int from; int from;
int to; int to;
{ {
int reg;
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
return 0; return 0;
else else
{ {
int interrupt_func_p = interrupt_function_p (current_function_decl); int offset = frame_pointer_needed ? 2 : 0;
int signal_func_p = signal_function_p (current_function_decl);
int leaf_func_p = leaf_function_p ();
int offset= frame_pointer_needed ? 2 : 0;
for (reg = 0; reg < 32; ++reg) offset += avr_regs_to_save (NULL);
{
if ((!leaf_func_p && (call_used_regs[reg]
&& (interrupt_func_p || signal_func_p)))
|| (regs_ever_live[reg]
&& (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
&& ! (frame_pointer_needed
&& (reg == REG_Y || reg == (REG_Y+1)))))
{
++offset;
}
}
return get_frame_size () + 2 + 1 + offset; return get_frame_size () + 2 + 1 + offset;
} }
return 0;
} }
/* This function checks sequence of live registers */ /* This function checks sequence of live registers */
...@@ -569,7 +590,6 @@ avr_output_function_prologue (file, size) ...@@ -569,7 +590,6 @@ avr_output_function_prologue (file, size)
int reg; int reg;
int interrupt_func_p; int interrupt_func_p;
int signal_func_p; int signal_func_p;
int leaf_func_p;
int main_p; int main_p;
int live_seq; int live_seq;
int minimize; int minimize;
...@@ -582,7 +602,6 @@ avr_output_function_prologue (file, size) ...@@ -582,7 +602,6 @@ avr_output_function_prologue (file, size)
interrupt_func_p = interrupt_function_p (current_function_decl); interrupt_func_p = interrupt_function_p (current_function_decl);
signal_func_p = signal_function_p (current_function_decl); signal_func_p = signal_function_p (current_function_decl);
leaf_func_p = leaf_function_p ();
main_p = MAIN_NAME_P (DECL_NAME (current_function_decl)); main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
live_seq = sequent_regs_live (); live_seq = sequent_regs_live ();
minimize = (TARGET_CALL_PROLOGUES minimize = (TARGET_CALL_PROLOGUES
...@@ -598,7 +617,7 @@ avr_output_function_prologue (file, size) ...@@ -598,7 +617,7 @@ avr_output_function_prologue (file, size)
fprintf (file,"\tsei\n"); fprintf (file,"\tsei\n");
++prologue_size; ++prologue_size;
} }
if (interrupt_func_p | signal_func_p) if (interrupt_func_p || signal_func_p)
{ {
fprintf (file, "\t" fprintf (file, "\t"
AS1 (push,__zero_reg__) CR_TAB AS1 (push,__zero_reg__) CR_TAB
...@@ -647,20 +666,14 @@ avr_output_function_prologue (file, size) ...@@ -647,20 +666,14 @@ avr_output_function_prologue (file, size)
} }
else else
{ {
HARD_REG_SET set;
prologue_size += avr_regs_to_save (&set);
for (reg = 0; reg < 32; ++reg) for (reg = 0; reg < 32; ++reg)
{ {
if ((!leaf_func_p if (TEST_HARD_REG_BIT (set, reg))
&& (call_used_regs[reg]
&& (interrupt_func_p || signal_func_p)
&& !(reg == TMP_REGNO || reg == ZERO_REGNO)))
|| (regs_ever_live[reg]
&& (!call_used_regs[reg]
|| interrupt_func_p || signal_func_p)
&& ! (frame_pointer_needed
&& (reg == REG_Y || reg == (REG_Y+1)))))
{ {
fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]); fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
++prologue_size;
} }
} }
if (frame_pointer_needed) if (frame_pointer_needed)
...@@ -706,7 +719,6 @@ avr_output_function_epilogue (file, size) ...@@ -706,7 +719,6 @@ avr_output_function_epilogue (file, size)
int reg; int reg;
int interrupt_func_p; int interrupt_func_p;
int signal_func_p; int signal_func_p;
int leaf_func_p;
int main_p; int main_p;
int function_size; int function_size;
int live_seq; int live_seq;
...@@ -720,7 +732,6 @@ avr_output_function_epilogue (file, size) ...@@ -720,7 +732,6 @@ avr_output_function_epilogue (file, size)
interrupt_func_p = interrupt_function_p (current_function_decl); interrupt_func_p = interrupt_function_p (current_function_decl);
signal_func_p = signal_function_p (current_function_decl); signal_func_p = signal_function_p (current_function_decl);
leaf_func_p = leaf_function_p ();
main_p = MAIN_NAME_P (DECL_NAME (current_function_decl)); main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ())) function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
- INSN_ADDRESSES (INSN_UID (get_insns ()))); - INSN_ADDRESSES (INSN_UID (get_insns ())));
...@@ -766,6 +777,8 @@ avr_output_function_epilogue (file, size) ...@@ -766,6 +777,8 @@ avr_output_function_epilogue (file, size)
} }
else else
{ {
HARD_REG_SET set;
if (frame_pointer_needed) if (frame_pointer_needed)
{ {
if (size) if (size)
...@@ -773,7 +786,7 @@ avr_output_function_epilogue (file, size) ...@@ -773,7 +786,7 @@ avr_output_function_epilogue (file, size)
fputs ("\t", file); fputs ("\t", file);
epilogue_size += out_adj_frame_ptr (file, -size); epilogue_size += out_adj_frame_ptr (file, -size);
if (interrupt_func_p | signal_func_p) if (interrupt_func_p || signal_func_p)
{ {
epilogue_size += out_set_stack_ptr (file, -1, 0); epilogue_size += out_set_stack_ptr (file, -1, 0);
} }
...@@ -788,24 +801,16 @@ avr_output_function_epilogue (file, size) ...@@ -788,24 +801,16 @@ avr_output_function_epilogue (file, size)
epilogue_size += 2; epilogue_size += 2;
} }
epilogue_size += avr_regs_to_save (&set);
for (reg = 31; reg >= 0; --reg) for (reg = 31; reg >= 0; --reg)
{ {
if ((!leaf_func_p if (TEST_HARD_REG_BIT (set, reg))
&& (call_used_regs[reg]
&& (interrupt_func_p || signal_func_p)
&& !(reg == TMP_REGNO || reg == ZERO_REGNO)))
|| (regs_ever_live[reg]
&& (!call_used_regs[reg]
|| interrupt_func_p || signal_func_p)
&& ! (frame_pointer_needed
&& (reg == REG_Y || reg == (REG_Y+1)))))
{ {
fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]); fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
++epilogue_size;
} }
} }
if (interrupt_func_p | signal_func_p) if (interrupt_func_p || signal_func_p)
{ {
fprintf (file, "\t" fprintf (file, "\t"
AS1 (pop,__tmp_reg__) CR_TAB AS1 (pop,__tmp_reg__) CR_TAB
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment