From 8f1594b2b805e9214594ad1f4552f629429fd07e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 2 Aug 2011 12:56:29 -0700 Subject: [PATCH] h8300: Generate correct unwind info around swap_into/out_of_er6. Minimal bug fix is to unset RTX_FRAME_RELATED_P on the PUSH insn generated in h8300_swap_into_er6. But with a tiny bit of effort we can generate real unwind info around the sequence. From-SVN: r177209 --- gcc/ChangeLog | 6 ++++++ gcc/config/h8300/h8300.c | 32 ++++++++++++++++++++++++++------ gcc/dwarf2cfi.c | 29 +++++++++++------------------ 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index caf57be4efc..6745886dc55 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-08-02 Richard Henderson + + * config/h8300/h8300.c (push, pop): Return the insn. + (h8300_swap_into_er6): Generate correct unwind info. + (h8300_swap_out_of_er6): Likewise. + 2011-08-02 H.J. Lu * config/i386/driver-i386.c (host_detect_local_cpu): Fix a typo. diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index ef483957366..a929a28663a 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -87,8 +87,6 @@ static int h8300_os_task_function_p (tree); static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT, bool); static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT); static unsigned int compute_saved_regs (void); -static void push (int); -static void pop (int); static const char *cond_string (enum rtx_code); static unsigned int h8300_asm_insn_count (const char *); static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *); @@ -556,7 +554,7 @@ compute_saved_regs (void) /* Emit an insn to push register RN. */ -static void +static rtx push (int rn) { rtx reg = gen_rtx_REG (word_mode, rn); @@ -570,11 +568,12 @@ push (int rn) x = gen_push_h8300hs_normal (reg); x = F (emit_insn (x), true); add_reg_note (x, REG_INC, stack_pointer_rtx); + return x; } /* Emit an insn to pop register RN. */ -static void +static rtx pop (int rn) { rtx reg = gen_rtx_REG (word_mode, rn); @@ -588,6 +587,7 @@ pop (int rn) x = gen_pop_h8300hs_normal (reg); x = emit_insn (x); add_reg_note (x, REG_INC, stack_pointer_rtx); + return x; } /* Emit an instruction to push or pop NREGS consecutive registers @@ -2678,7 +2678,16 @@ h8sx_emit_movmd (rtx dest, rtx src, rtx length, void h8300_swap_into_er6 (rtx addr) { - push (HARD_FRAME_POINTER_REGNUM); + rtx insn = push (HARD_FRAME_POINTER_REGNUM); + if (frame_pointer_needed) + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (gen_rtx_MEM (Pmode, stack_pointer_rtx), + 2 * UNITS_PER_WORD)); + else + add_reg_note (insn, REG_CFA_ADJUST_CFA, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + plus_constant (stack_pointer_rtx, 4))); + emit_move_insn (hard_frame_pointer_rtx, addr); if (REGNO (addr) == SP_REG) emit_move_insn (hard_frame_pointer_rtx, @@ -2692,9 +2701,20 @@ h8300_swap_into_er6 (rtx addr) void h8300_swap_out_of_er6 (rtx addr) { + rtx insn; + if (REGNO (addr) != SP_REG) emit_move_insn (addr, hard_frame_pointer_rtx); - pop (HARD_FRAME_POINTER_REGNUM); + + insn = pop (HARD_FRAME_POINTER_REGNUM); + RTX_FRAME_RELATED_P (insn) = 1; + if (frame_pointer_needed) + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (hard_frame_pointer_rtx, 2 * UNITS_PER_WORD)); + else + add_reg_note (insn, REG_CFA_ADJUST_CFA, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + plus_constant (stack_pointer_rtx, -4))); } /* Return the length of mov instruction. */ diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 99b37abbff7..69218cb2dfe 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -778,8 +778,8 @@ def_cfa_1 (dw_cfa_location *new_cfa) if (cfi) { cur_row->cfa = *new_cfa; - if (cfi->dw_cfi_opc == DW_CFA_def_cfa_expression) - cur_row->cfa_cfi = cfi; + cur_row->cfa_cfi = (cfi->dw_cfi_opc == DW_CFA_def_cfa_expression + ? cfi : NULL); add_cfi (cfi); } @@ -1205,18 +1205,13 @@ dwarf2out_frame_debug_def_cfa (rtx pat) memset (&loc, 0, sizeof (loc)); - switch (GET_CODE (pat)) + if (GET_CODE (pat) == PLUS) { - case PLUS: - loc.reg = dwf_regno (XEXP (pat, 0)); loc.offset = INTVAL (XEXP (pat, 1)); - break; - - case REG: - loc.reg = dwf_regno (pat); - break; - - case MEM: + pat = XEXP (pat, 0); + } + if (MEM_P (pat)) + { loc.indirect = 1; pat = XEXP (pat, 0); if (GET_CODE (pat) == PLUS) @@ -1224,13 +1219,11 @@ dwarf2out_frame_debug_def_cfa (rtx pat) loc.base_offset = INTVAL (XEXP (pat, 1)); pat = XEXP (pat, 0); } - loc.reg = dwf_regno (pat); - break; - - default: - /* Recurse and define an expression. */ - gcc_unreachable (); } + /* ??? If this fails, we could be calling into the _loc functions to + define a full expression. So far no port does that. */ + gcc_assert (REG_P (pat)); + loc.reg = dwf_regno (pat); def_cfa_1 (&loc); } -- 2.30.2