diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 4569359..06c9254 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -109,6 +109,7 @@ extern RTX_CODE avr_normalize_condition (RTX_CODE condition); extern int compare_eq_p (rtx insn); extern void out_shift_with_cnt (const char *templ, rtx insn, rtx operands[], int *len, int t_len); +extern rtx avr_incoming_return_addr_rtx (void); #endif /* RTX_CODE */ #ifdef HAVE_MACHINE_MODES diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 30e4626..761eea3 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -534,6 +534,16 @@ get_sequence_length (rtx insns) return length; } +/* Implement INCOMING_RETURN_ADDR_RTX. */ + +rtx +avr_incoming_return_addr_rtx (void) +{ + /* The return address is at the top of the stack. Note that the push + was via post-decrement, which means the actual address is off by one. */ + return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1)); +} + /* Output function prologue. */ void diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 9a71078..385b4e6 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -809,6 +809,9 @@ mmcu=*:-mmcu=%*}" #define OBJECT_FORMAT_ELF +#define INCOMING_RETURN_ADDR_RTX avr_incoming_return_addr_rtx () +#define INCOMING_FRAME_SP_OFFSET (AVR_3_BYTE_PC ? 3 : 2) + #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \ avr_hard_regno_rename_ok (OLD_REG, NEW_REG) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index fea8209..b5e660c 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -2240,7 +2240,7 @@ dwarf2out_frame_debug_cfa_restore (rtx reg, const char *label) cfa.base_offset = -cfa_store.offset Rule 11: - (set (mem ({pre_inc,pre_dec} sp:cfa_store.reg)) ) + (set (mem ({pre_inc,pre_dec,post_dec} sp:cfa_store.reg)) ) effects: cfa_store.offset += -/+ mode_size(mem) cfa.offset = cfa_store.offset if cfa.reg == sp cfa.reg = sp @@ -2259,7 +2259,7 @@ dwarf2out_frame_debug_cfa_restore (rtx reg, const char *label) cfa.base_offset = -{cfa_store,cfa_temp}.offset Rule 14: - (set (mem (postinc :cfa_temp )) ) + (set (mem (post_inc :cfa_temp )) ) effects: cfa.reg = cfa.base_offset = -cfa_temp.offset cfa_temp.offset -= mode_size(mem) @@ -2592,6 +2592,7 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) /* Rule 11 */ case PRE_INC: case PRE_DEC: + case POST_DEC: offset = GET_MODE_SIZE (GET_MODE (dest)); if (GET_CODE (XEXP (dest, 0)) == PRE_INC) offset = -offset; @@ -2616,7 +2617,10 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) if (cfa.reg == STACK_POINTER_REGNUM) cfa.offset = cfa_store.offset; - offset = -cfa_store.offset; + if (GET_CODE (XEXP (dest, 0)) == POST_DEC) + offset += -cfa_store.offset; + else + offset = -cfa_store.offset; break; /* Rule 12 */