PR target/21078, 21080
PR target/21078, 21080 * config/avr/avr.c (avr_return_addr_rtx): New function for builtin_return_address. (expand_prologue): Calculate stack usage. (avr_asm_function_end_prologue): Output stack size and offset label. * config/avr/avr.h (RETURN_ADDR_RTX): Replace. (machine_function): Add stack_usage. * config/avr/avr-protos.h (avr_return_addr_rtx): New function. From-SVN: r154188
This commit is contained in:
parent
de8caa8cf8
commit
a212a5d408
@ -1,3 +1,14 @@
|
|||||||
|
2009-11-14 Andy Hutchinson <hutchinsonandy@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR target/21078, 21080
|
||||||
|
* config/avr/avr.c (avr_return_addr_rtx): New function for
|
||||||
|
builtin_return_address.
|
||||||
|
(expand_prologue): Calculate stack usage.
|
||||||
|
(avr_asm_function_end_prologue): Output stack size and offset label.
|
||||||
|
* config/avr/avr.h (RETURN_ADDR_RTX): Replace.
|
||||||
|
(machine_function): Add stack_usage.
|
||||||
|
* config/avr/avr-protos.h (avr_return_addr_rtx): New function.
|
||||||
|
|
||||||
2009-11-14 Anatoly Sokolov <aesok@post.ru>
|
2009-11-14 Anatoly Sokolov <aesok@post.ru>
|
||||||
|
|
||||||
* config/iq2000/iq2000.c (iq2000_function_value): Make static, add
|
* config/iq2000/iq2000.c (iq2000_function_value): Make static, add
|
||||||
|
@ -39,6 +39,7 @@ extern int avr_simple_epilogue (void);
|
|||||||
extern void gas_output_limited_string (FILE *file, const char *str);
|
extern void gas_output_limited_string (FILE *file, const char *str);
|
||||||
extern void gas_output_ascii (FILE *file, const char *str, size_t length);
|
extern void gas_output_ascii (FILE *file, const char *str, size_t length);
|
||||||
extern int avr_hard_regno_rename_ok (unsigned int, unsigned int);
|
extern int avr_hard_regno_rename_ok (unsigned int, unsigned int);
|
||||||
|
extern rtx avr_return_addr_rtx (int count, const_rtx tem);
|
||||||
|
|
||||||
#ifdef TREE_CODE
|
#ifdef TREE_CODE
|
||||||
extern void asm_output_external (FILE *file, tree decl, char *name);
|
extern void asm_output_external (FILE *file, tree decl, char *name);
|
||||||
|
@ -461,6 +461,31 @@ rtx avr_builtin_setjmp_frame_value (void)
|
|||||||
gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
|
gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
|
||||||
|
This is return address of function. */
|
||||||
|
rtx
|
||||||
|
avr_return_addr_rtx (int count, const_rtx tem)
|
||||||
|
{
|
||||||
|
rtx r;
|
||||||
|
|
||||||
|
/* Can only return this functions return address. Others not supported. */
|
||||||
|
if (count)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (AVR_3_BYTE_PC)
|
||||||
|
{
|
||||||
|
r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
|
||||||
|
warning (0, "'builtin_return_address' contains only 2 bytes of address");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
|
||||||
|
|
||||||
|
r = gen_rtx_PLUS (Pmode, tem, r);
|
||||||
|
r = gen_frame_mem (Pmode, memory_address (Pmode, r));
|
||||||
|
r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return 1 if the function epilogue is just a single "ret". */
|
/* Return 1 if the function epilogue is just a single "ret". */
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -560,6 +585,7 @@ expand_prologue (void)
|
|||||||
cfun->machine->is_signal = signal_function_p (current_function_decl);
|
cfun->machine->is_signal = signal_function_p (current_function_decl);
|
||||||
cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
|
cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
|
||||||
cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
|
cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
|
||||||
|
cfun->machine->stack_usage = 0;
|
||||||
|
|
||||||
/* Prologue: naked. */
|
/* Prologue: naked. */
|
||||||
if (cfun->machine->is_naked)
|
if (cfun->machine->is_naked)
|
||||||
@ -588,10 +614,12 @@ expand_prologue (void)
|
|||||||
/* Push zero reg. */
|
/* Push zero reg. */
|
||||||
insn = emit_move_insn (pushbyte, zero_reg_rtx);
|
insn = emit_move_insn (pushbyte, zero_reg_rtx);
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage++;
|
||||||
|
|
||||||
/* Push tmp reg. */
|
/* Push tmp reg. */
|
||||||
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
|
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage++;
|
||||||
|
|
||||||
/* Push SREG. */
|
/* Push SREG. */
|
||||||
insn = emit_move_insn (tmp_reg_rtx,
|
insn = emit_move_insn (tmp_reg_rtx,
|
||||||
@ -599,6 +627,7 @@ expand_prologue (void)
|
|||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
|
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage++;
|
||||||
|
|
||||||
/* Push RAMPZ. */
|
/* Push RAMPZ. */
|
||||||
if(AVR_HAVE_RAMPZ
|
if(AVR_HAVE_RAMPZ
|
||||||
@ -609,6 +638,7 @@ expand_prologue (void)
|
|||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
|
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear zero reg. */
|
/* Clear zero reg. */
|
||||||
@ -630,6 +660,7 @@ expand_prologue (void)
|
|||||||
emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
|
emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
|
||||||
gen_int_mode (size + live_seq, HImode)));
|
gen_int_mode (size + live_seq, HImode)));
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage += size + live_seq;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -641,6 +672,7 @@ expand_prologue (void)
|
|||||||
/* Emit push of register to save. */
|
/* Emit push of register to save. */
|
||||||
insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
|
insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frame_pointer_needed)
|
if (frame_pointer_needed)
|
||||||
@ -650,6 +682,7 @@ expand_prologue (void)
|
|||||||
/* Push frame pointer. */
|
/* Push frame pointer. */
|
||||||
insn = emit_move_insn (pushword, frame_pointer_rtx);
|
insn = emit_move_insn (pushword, frame_pointer_rtx);
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
cfun->machine->stack_usage += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
@ -756,6 +789,7 @@ expand_prologue (void)
|
|||||||
emit_insn (sp_plus_insns);
|
emit_insn (sp_plus_insns);
|
||||||
else
|
else
|
||||||
emit_insn (fp_plus_insns);
|
emit_insn (fp_plus_insns);
|
||||||
|
cfun->machine->stack_usage += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -785,6 +819,11 @@ avr_asm_function_end_prologue (FILE *file)
|
|||||||
}
|
}
|
||||||
fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
|
fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
|
||||||
get_frame_size());
|
get_frame_size());
|
||||||
|
fprintf (file, "/* stack size = %d */\n",
|
||||||
|
cfun->machine->stack_usage);
|
||||||
|
/* Create symbol stack offset here so all functions have it. Add 1 to stack
|
||||||
|
usage for offset so that SP + .L__stack_offset = return address. */
|
||||||
|
fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -367,8 +367,7 @@ enum reg_class {
|
|||||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||||
OFFSET = avr_initial_elimination_offset (FROM, TO)
|
OFFSET = avr_initial_elimination_offset (FROM, TO)
|
||||||
|
|
||||||
#define RETURN_ADDR_RTX(count, x) \
|
#define RETURN_ADDR_RTX(count, tem) avr_return_addr_rtx (count, tem)
|
||||||
gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (tem, 1)))
|
|
||||||
|
|
||||||
/* Don't use Push rounding. expr.c: emit_single_push_insn is broken
|
/* Don't use Push rounding. expr.c: emit_single_push_insn is broken
|
||||||
for POST_DEC targets (PR27386). */
|
for POST_DEC targets (PR27386). */
|
||||||
@ -857,4 +856,7 @@ struct GTY(()) machine_function
|
|||||||
/* 'true' - if current function is a 'main' function
|
/* 'true' - if current function is a 'main' function
|
||||||
as specified by the "OS_main" attribute. */
|
as specified by the "OS_main" attribute. */
|
||||||
int is_OS_main;
|
int is_OS_main;
|
||||||
|
|
||||||
|
/* Current function stack size. */
|
||||||
|
int stack_usage;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user