Commit 1bf29643 by Andy Hutchinson Committed by Andy Hutchinson

re PR target/34879 (__builtin_setjmp / __builtin_longjmp fails stack frame…

re PR target/34879 (__builtin_setjmp / __builtin_longjmp fails stack frame address with O2, O3 and Os)

PR target/34879
* config/avr/avr.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Redefine.
(avr_builtin_setjmp_frame_value): New function.
* config/avr/avr.md (nonlocal_goto_receiver): Define.
(nonlocal_goto): Define.

From-SVN: r136297
parent e62532af
2008-06-02 Andy Hutchinson <hutchinsonandy@aim.com>
PR target/34879
* config/avr/avr.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Redefine.
(avr_builtin_setjmp_frame_value): New function.
* config/avr/avr.md (nonlocal_goto_receiver): Define.
(nonlocal_goto): Define.
2008-06-02 Richard Sandiford <rdsandiford@googlemail.com> 2008-06-02 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (mips_emit_loadgp): Return early if * config/mips/mips.c (mips_emit_loadgp): Return early if
......
...@@ -83,6 +83,8 @@ static bool avr_rtx_costs (rtx, int, int, int *); ...@@ -83,6 +83,8 @@ static bool avr_rtx_costs (rtx, int, int, int *);
static int avr_address_cost (rtx); static int avr_address_cost (rtx);
static bool avr_return_in_memory (const_tree, const_tree); static bool avr_return_in_memory (const_tree, const_tree);
static struct machine_function * avr_init_machine_status (void); static struct machine_function * avr_init_machine_status (void);
static rtx avr_builtin_setjmp_frame_value (void);
/* Allocate registers from r25 to r8 for parameters for function calls. */ /* Allocate registers from r25 to r8 for parameters for function calls. */
#define FIRST_CUM_REG 26 #define FIRST_CUM_REG 26
...@@ -323,6 +325,9 @@ int avr_case_values_threshold = 30000; ...@@ -323,6 +325,9 @@ int avr_case_values_threshold = 30000;
#undef TARGET_STRICT_ARGUMENT_NAMING #undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
#define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
void void
...@@ -523,6 +528,17 @@ initial_elimination_offset (int from, int to) ...@@ -523,6 +528,17 @@ initial_elimination_offset (int from, int to)
} }
} }
/* Actual start of frame is virtual_stack_vars_rtx this is offset from
frame pointer by +STARTING_FRAME_OFFSET.
Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
avoids creating add/sub of offset in nonlocal goto and setjmp. */
rtx avr_builtin_setjmp_frame_value (void)
{
return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx,
gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
}
/* Return 1 if the function epilogue is just a single "ret". */ /* Return 1 if the function epilogue is just a single "ret". */
int int
......
...@@ -58,7 +58,8 @@ ...@@ -58,7 +58,8 @@
(UNSPECV_PROLOGUE_SAVES 0) (UNSPECV_PROLOGUE_SAVES 0)
(UNSPECV_EPILOGUE_RESTORES 1) (UNSPECV_EPILOGUE_RESTORES 1)
(UNSPECV_WRITE_SP_IRQ_ON 2) (UNSPECV_WRITE_SP_IRQ_ON 2)
(UNSPECV_WRITE_SP_IRQ_OFF 3)]) (UNSPECV_WRITE_SP_IRQ_OFF 3)
(UNSPECV_GOTO_RECEIVER 4)])
(include "predicates.md") (include "predicates.md")
(include "constraints.md") (include "constraints.md")
...@@ -115,6 +116,63 @@ ...@@ -115,6 +116,63 @@
(const_int 2))] (const_int 2))]
(const_int 2))) (const_int 2)))
;;========================================================================
;; The following is used by nonlocal_goto and setjmp.
;; The receiver pattern will create no instructions since internally
;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
;; This avoids creating add/sub offsets in frame_pointer save/resore.
;; The 'null' receiver also avoids problems with optimisation
;; not recognising incoming jmp and removing code that resets frame_pointer.
;; The code derived from builtins.c.
(define_expand "nonlocal_goto_receiver"
[(set (reg:HI REG_Y)
(unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
""
{
emit_move_insn (virtual_stack_vars_rtx,
gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
gen_int_mode (STARTING_FRAME_OFFSET,
Pmode)));
/* This might change the hard frame pointer in ways that aren't
apparent to early optimization passes, so force a clobber. */
emit_clobber (hard_frame_pointer_rtx);
DONE;
})
;; Defining nonlocal_goto_receiver means we must also define this.
;; even though its function is identical to that in builtins.c
(define_expand "nonlocal_goto"
[
(use (match_operand 0 "general_operand"))
(use (match_operand 1 "general_operand"))
(use (match_operand 2 "general_operand"))
(use (match_operand 3 "general_operand"))
]
""
{
rtx r_label = copy_to_reg (operands[1]);
rtx r_fp = operands[3];
rtx r_sp = operands[2];
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
emit_move_insn (hard_frame_pointer_rtx, r_fp);
emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);
emit_indirect_jump (r_label);
DONE;
})
(define_insn "*pushqi" (define_insn "*pushqi"
[(set (mem:QI (post_dec (reg:HI REG_SP))) [(set (mem:QI (post_dec (reg:HI REG_SP)))
(match_operand:QI 0 "reg_or_0_operand" "r,L"))] (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
......
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