From 19ec6a367c17e084d0a9165a1d2284eebb0fe311 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 4 Apr 2001 03:13:54 +0000 Subject: [PATCH] DWARF2 frame notes for hppa. * dwarf2out.c (dwarf2out_frame_debug_expr): Support adjusting stack pointer via a LO_SUM. Ditto for setting a temp register used to save to the stack. Set cfa_temp when setting fp, and allow matches to cfa_temp in addition to cfa_store when saving regs. Handle POST_INC and LO_SUM register stores. Document the changes and errors in rule 12 doco. * pa.c (set_reg_plus_d, store_reg, load_reg): Return last insn. (actual_fsize, local_fsize, save_fregs): Move for store_reg to see. (load_reg): Move closer to epilogue code. (DO_FRAME_NOTES): Define to control the following.. (FRP): Define to set RTX_FRAME_RELATED_P on insns. (hppa_expand_prologue): Use FRP and REG_FRAME_RELATED_EXPR notes as necessary. (hppa_expand_epilogue): Likewise. From-SVN: r41074 --- gcc/ChangeLog | 18 +++ gcc/config/pa/pa.c | 315 ++++++++++++++++++++++++++++----------------- gcc/dwarf2out.c | 117 ++++++++++------- 3 files changed, 284 insertions(+), 166 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 61eafd1693a..425e6ce2c78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2001-04-04 Alan Modra + + * dwarf2out.c (dwarf2out_frame_debug_expr): Support adjusting + stack pointer via a LO_SUM. Ditto for setting a temp register + used to save to the stack. Set cfa_temp when setting fp, and + allow matches to cfa_temp in addition to cfa_store when saving + regs. Handle POST_INC and LO_SUM register stores. Document the + changes and errors in rule 12 doco. + + * pa.c (set_reg_plus_d, store_reg, load_reg): Return last insn. + (actual_fsize, local_fsize, save_fregs): Move for store_reg to see. + (load_reg): Move closer to epilogue code. + (DO_FRAME_NOTES): Define to control the following.. + (FRP): Define to set RTX_FRAME_RELATED_P on insns. + (hppa_expand_prologue): Use FRP and REG_FRAME_RELATED_EXPR + notes as necessary. + (hppa_expand_epilogue): Likewise. + 2001-04-03 Richard Henderson * configure.in (gcc_cv_as_leb128): Reject gas before 2.11. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 502d204e74d..2f16c6f085f 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -42,21 +42,29 @@ Boston, MA 02111-1307, USA. */ #include "recog.h" #include "tm_p.h" +#ifndef DO_FRAME_NOTES +#ifdef INCOMING_RETURN_ADDR_RTX +#define DO_FRAME_NOTES 1 +#else +#define DO_FRAME_NOTES 0 +#endif +#endif + static void pa_init_machine_status PARAMS ((struct function *)); static void pa_mark_machine_status PARAMS ((struct function *)); static void pa_free_machine_status PARAMS ((struct function *)); -static void pa_combine_instructions PARAMS ((rtx)); -static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx)); -static int forward_branch_p PARAMS ((rtx)); -static int shadd_constant_p PARAMS ((int)); -static void pa_add_gc_roots PARAMS ((void)); -static void mark_deferred_plabels PARAMS ((void *)); -static void compute_zdepwi_operands PARAMS ((unsigned HOST_WIDE_INT, unsigned *)); -static int compute_movstrsi_length PARAMS ((rtx)); -static void remove_useless_addtr_insns PARAMS ((rtx, int)); -static void store_reg PARAMS ((int, int, int)); -static void load_reg PARAMS ((int, int, int)); -static void set_reg_plus_d PARAMS ((int, int, int)); +static void pa_combine_instructions PARAMS ((rtx)); +static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx)); +static int forward_branch_p PARAMS ((rtx)); +static int shadd_constant_p PARAMS ((int)); +static void pa_add_gc_roots PARAMS ((void)); +static void mark_deferred_plabels PARAMS ((void *)); +static void compute_zdepwi_operands PARAMS ((unsigned HOST_WIDE_INT, unsigned *)); +static int compute_movstrsi_length PARAMS ((rtx)); +static void remove_useless_addtr_insns PARAMS ((rtx, int)); +static rtx store_reg PARAMS ((int, int, int)); +static rtx load_reg PARAMS ((int, int, int)); +static rtx set_reg_plus_d PARAMS ((int, int, int)); /* Save the operands last given to a compare for use when we generate a scc or bcc insn. */ @@ -2003,7 +2011,6 @@ output_move_double (operands) xoperands); return "ldw 0(%R0),%0\n\tldw 4(%R0),%R0"; } - } } @@ -2743,60 +2750,41 @@ remove_useless_addtr_insns (insns, check_notes) */ +/* Global variables set by FUNCTION_PROLOGUE. */ +/* Size of frame. Need to know this to emit return insns from + leaf procedures. */ +static int actual_fsize; +static int local_fsize, save_fregs; + /* Emit RTL to store REG at the memory location specified by BASE+DISP. Handle case where DISP > 8k by using the add_high_const patterns. Note in DISP > 8k case, we will leave the high part of the address in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/ -static void +static rtx store_reg (reg, disp, base) int reg, disp, base; { + rtx i, dest, src, basereg; + + src = gen_rtx_REG (word_mode, reg); + basereg = gen_rtx_REG (Pmode, base); if (VAL_14_BITS_P (disp)) - emit_move_insn (gen_rtx_MEM (word_mode, - plus_constant (gen_rtx_REG (Pmode, base), - disp)), - gen_rtx_REG (word_mode, reg)); - else { - emit_move_insn (gen_rtx_REG (Pmode, 1), - gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base), - gen_rtx_HIGH (Pmode, GEN_INT (disp)))); - emit_move_insn (gen_rtx_MEM (word_mode, - gen_rtx_LO_SUM (Pmode, - gen_rtx_REG (Pmode, 1), - GEN_INT (disp))), - gen_rtx_REG (word_mode, reg)); + dest = gen_rtx_MEM (word_mode, plus_constant (basereg, disp)); + i = emit_move_insn (dest, src); } -} - -/* Emit RTL to load REG from the memory location specified by BASE+DISP. - Handle case where DISP > 8k by using the add_high_const patterns. - - Note in DISP > 8k case, we will leave the high part of the address - in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/ - -static void -load_reg (reg, disp, base) - int reg, disp, base; -{ - if (VAL_14_BITS_P (disp)) - emit_move_insn (gen_rtx_REG (word_mode, reg), - gen_rtx_MEM (word_mode, - plus_constant (gen_rtx_REG (Pmode, base), - disp))); else { - emit_move_insn (gen_rtx_REG (Pmode, 1), - gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base), - gen_rtx_HIGH (Pmode, GEN_INT (disp)))); - emit_move_insn (gen_rtx_REG (word_mode, reg), - gen_rtx_MEM (word_mode, - gen_rtx_LO_SUM (Pmode, - gen_rtx_REG (Pmode, 1), - GEN_INT (disp)))); + rtx delta = GEN_INT (disp); + rtx high = gen_rtx_PLUS (Pmode, basereg, gen_rtx_HIGH (Pmode, delta)); + rtx tmpreg = gen_rtx_REG (Pmode, 1); + emit_move_insn (tmpreg, high); + dest = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta)); + i = emit_move_insn (dest, src); } + return i; } /* Emit RTL to set REG to the value specified by BASE+DISP. @@ -2805,31 +2793,30 @@ load_reg (reg, disp, base) Note in DISP > 8k case, we will leave the high part of the address in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/ -static void +static rtx set_reg_plus_d (reg, base, disp) int reg, base, disp; { + rtx i; + if (VAL_14_BITS_P (disp)) - emit_move_insn (gen_rtx_REG (Pmode, reg), - plus_constant (gen_rtx_REG (Pmode, base), disp)); + { + i = emit_move_insn (gen_rtx_REG (Pmode, reg), + plus_constant (gen_rtx_REG (Pmode, base), disp)); + } else { + rtx delta = GEN_INT (disp); emit_move_insn (gen_rtx_REG (Pmode, 1), gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base), - gen_rtx_HIGH (Pmode, GEN_INT (disp)))); - emit_move_insn (gen_rtx_REG (Pmode, reg), - gen_rtx_LO_SUM (Pmode, - gen_rtx_REG (Pmode, 1), - GEN_INT (disp))); + gen_rtx_HIGH (Pmode, delta))); + i = emit_move_insn (gen_rtx_REG (Pmode, reg), + gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 1), + delta)); } + return i; } -/* Global variables set by FUNCTION_PROLOGUE. */ -/* Size of frame. Need to know this to emit return insns from - leaf procedures. */ -static int actual_fsize; -static int local_fsize, save_fregs; - int compute_frame_size (size, fregs_live) int size; @@ -2937,8 +2924,20 @@ output_function_prologue (file, size) remove_useless_addtr_insns (get_insns (), 0); } +#if DO_FRAME_NOTES +#define FRP(INSN) \ + do \ + { \ + rtx insn = INSN; \ + RTX_FRAME_RELATED_P (insn) = 1; \ + } \ + while (0) +#else +#define FRP (INSN) INSN +#endif + void -hppa_expand_prologue() +hppa_expand_prologue () { extern char call_used_regs[]; int size = get_frame_size (); @@ -2965,10 +2964,10 @@ hppa_expand_prologue() size_rtx = GEN_INT (actual_fsize); /* Save RP first. The calling conventions manual states RP will - always be stored into the caller's frame at sp-20 or sp - 16 + always be stored into the caller's frame at sp - 20 or sp - 16 depending on which ABI is in use. */ if (regs_ever_live[2]) - store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM); + FRP (store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM)); /* Allocate the local frame and set up the frame pointer if needed. */ if (actual_fsize != 0) @@ -2982,9 +2981,31 @@ hppa_expand_prologue() handles small (<8k) frames. The second handles large (>=8k) frames. */ emit_move_insn (tmpreg, frame_pointer_rtx); - emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); + FRP (emit_move_insn (frame_pointer_rtx, stack_pointer_rtx)); if (VAL_14_BITS_P (actual_fsize)) - emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, size_rtx)); + { + rtx insn = emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, + size_rtx)); + if (DO_FRAME_NOTES) + { + rtvec vec; + RTX_FRAME_RELATED_P (insn) = 1; + vec = gen_rtvec (2, + gen_rtx_SET (VOIDmode, + gen_rtx_MEM (word_mode, + stack_pointer_rtx), + frame_pointer_rtx), + gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + gen_rtx_PLUS (word_mode, + stack_pointer_rtx, + size_rtx))); + REG_NOTES (insn) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SEQUENCE (VOIDmode, vec), + REG_NOTES (insn)); + } + } else { /* It is incorrect to store the saved frame pointer at *sp, @@ -2996,10 +3017,31 @@ hppa_expand_prologue() int adjust1 = 8192 - 64; int adjust2 = actual_fsize - adjust1; rtx delta = GEN_INT (adjust1); - emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, delta)); - set_reg_plus_d (STACK_POINTER_REGNUM, - STACK_POINTER_REGNUM, - adjust2); + rtx insn = emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, + delta)); + if (DO_FRAME_NOTES) + { + rtvec vec; + RTX_FRAME_RELATED_P (insn) = 1; + vec = gen_rtvec (2, + gen_rtx_SET (VOIDmode, + gen_rtx_MEM (word_mode, + stack_pointer_rtx), + frame_pointer_rtx), + gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + gen_rtx_PLUS (word_mode, + stack_pointer_rtx, + delta))); + REG_NOTES (insn) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SEQUENCE (VOIDmode, vec), + REG_NOTES (insn)); + } + + FRP (set_reg_plus_d (STACK_POINTER_REGNUM, + STACK_POINTER_REGNUM, + adjust2)); } /* Prevent register spills from being scheduled before the stack pointer is raised. Necessary as we will be storing @@ -3019,9 +3061,9 @@ hppa_expand_prologue() /* Can not optimize. Adjust the stack frame by actual_fsize bytes. */ else - set_reg_plus_d (STACK_POINTER_REGNUM, - STACK_POINTER_REGNUM, - actual_fsize); + FRP (set_reg_plus_d (STACK_POINTER_REGNUM, + STACK_POINTER_REGNUM, + actual_fsize)); } } @@ -3034,7 +3076,7 @@ hppa_expand_prologue() for (i = 18, offset = local_fsize; i >= 4; i--) if (regs_ever_live[i] && ! call_used_regs[i]) { - store_reg (i, offset, FRAME_POINTER_REGNUM); + FRP (store_reg (i, offset, FRAME_POINTER_REGNUM)); offset += UNITS_PER_WORD; gr_saved++; } @@ -3051,13 +3093,14 @@ hppa_expand_prologue() optimize the first GR save. */ if (merge_sp_adjust_with_store) { + rtx delta = GEN_INT (-offset); merge_sp_adjust_with_store = 0; - emit_insn (gen_post_store (stack_pointer_rtx, - gen_rtx_REG (word_mode, i), - GEN_INT (-offset))); + FRP (emit_insn (gen_post_store (stack_pointer_rtx, + gen_rtx_REG (word_mode, i), + delta))); } else - store_reg (i, offset, STACK_POINTER_REGNUM); + FRP (store_reg (i, offset, STACK_POINTER_REGNUM)); offset += UNITS_PER_WORD; gr_saved++; } @@ -3065,9 +3108,9 @@ hppa_expand_prologue() /* If we wanted to merge the SP adjustment with a GR save, but we never did any GR saves, then just emit the adjustment here. */ if (merge_sp_adjust_with_store) - set_reg_plus_d (STACK_POINTER_REGNUM, - STACK_POINTER_REGNUM, - actual_fsize); + FRP (set_reg_plus_d (STACK_POINTER_REGNUM, + STACK_POINTER_REGNUM, + actual_fsize)); } /* The hppa calling conventions say that %r19, the pic offset @@ -3088,9 +3131,9 @@ hppa_expand_prologue() /* First get the frame or stack pointer to the start of the FP register save area. */ if (frame_pointer_needed) - set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset); + FRP (set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset)); else - set_reg_plus_d (1, STACK_POINTER_REGNUM, offset); + FRP (set_reg_plus_d (1, STACK_POINTER_REGNUM, offset)); /* Now actually save the FP registers. */ for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP) @@ -3098,15 +3141,49 @@ hppa_expand_prologue() if (regs_ever_live[i] || (! TARGET_64BIT && regs_ever_live[i + 1])) { - emit_move_insn (gen_rtx_MEM (DFmode, - gen_rtx_POST_INC (DFmode, tmpreg)), - gen_rtx_REG (DFmode, i)); + rtx addr, reg; + addr = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg)); + reg = gen_rtx_REG (DFmode, i); + FRP (emit_move_insn (addr, reg)); fr_saved++; } } } } +/* ?!? Do we want frame notes in the epilogue yet? */ +#undef DO_FRAME_NOTES +#define DO_FRAME_NOTES 0 +#undef FRP +#define FRP(INSN) INSN + +/* Emit RTL to load REG from the memory location specified by BASE+DISP. + Handle case where DISP > 8k by using the add_high_const patterns. */ + +static rtx +load_reg (reg, disp, base) + int reg, disp, base; +{ + rtx i, src, dest, basereg; + + dest = gen_rtx_REG (word_mode, reg); + basereg = gen_rtx_REG (Pmode, base); + if (VAL_14_BITS_P (disp)) + { + src = gen_rtx_MEM (word_mode, plus_constant (basereg, disp)); + i = emit_move_insn (dest, src); + } + else + { + rtx delta = GEN_INT (disp); + rtx high = gen_rtx_PLUS (Pmode, basereg, gen_rtx_HIGH (Pmode, delta)); + rtx tmpreg = gen_rtx_REG (Pmode, 1); + emit_move_insn (tmpreg, high); + src = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta)); + i = emit_move_insn (dest, src); + } + return i; +} void output_function_epilogue (file, size) @@ -3159,7 +3236,7 @@ hppa_expand_epilogue () ret_off = TARGET_64BIT ? -16 : -20; if (frame_pointer_needed) { - load_reg (2, ret_off, FRAME_POINTER_REGNUM); + FRP (load_reg (2, ret_off, FRAME_POINTER_REGNUM)); ret_off = 0; } else @@ -3167,7 +3244,7 @@ hppa_expand_epilogue () /* No frame pointer, and stack is smaller than 8k. */ if (VAL_14_BITS_P (ret_off - actual_fsize)) { - load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM); + FRP (load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM)); ret_off = 0; } } @@ -3179,7 +3256,7 @@ hppa_expand_epilogue () for (i = 18, offset = local_fsize; i >= 4; i--) if (regs_ever_live[i] && ! call_used_regs[i]) { - load_reg (i, offset, FRAME_POINTER_REGNUM); + FRP (load_reg (i, offset, FRAME_POINTER_REGNUM)); offset += UNITS_PER_WORD; } } @@ -3197,7 +3274,7 @@ hppa_expand_epilogue () && VAL_14_BITS_P (-actual_fsize)) merge_sp_adjust_with_load = i; else - load_reg (i, offset, STACK_POINTER_REGNUM); + FRP (load_reg (i, offset, STACK_POINTER_REGNUM)); offset += UNITS_PER_WORD; } } @@ -3211,21 +3288,19 @@ hppa_expand_epilogue () { /* Adjust the register to index off of. */ if (frame_pointer_needed) - set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset); + FRP (set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset)); else - set_reg_plus_d (1, STACK_POINTER_REGNUM, offset); + FRP (set_reg_plus_d (1, STACK_POINTER_REGNUM, offset)); /* Actually do the restores now. */ for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP) - { - if (regs_ever_live[i] - || (! TARGET_64BIT && regs_ever_live[i + 1])) - { - emit_move_insn (gen_rtx_REG (DFmode, i), - gen_rtx_MEM (DFmode, - gen_rtx_POST_INC (DFmode, tmpreg))); - } - } + if (regs_ever_live[i] + || (! TARGET_64BIT && regs_ever_live[i + 1])) + { + rtx src = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg)); + rtx dest = gen_rtx_REG (DFmode, i); + FRP (emit_move_insn (dest, src)); + } } /* Emit a blockage insn here to keep these insns from being moved to @@ -3239,35 +3314,33 @@ hppa_expand_epilogue () pointer is initially set to fp + 64 to avoid a race condition. */ if (frame_pointer_needed) { - set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64); - emit_insn (gen_pre_load (frame_pointer_rtx, - stack_pointer_rtx, - GEN_INT (-64))); + rtx delta = GEN_INT (-64); + FRP (set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64)); + FRP (emit_insn (gen_pre_load (frame_pointer_rtx, + stack_pointer_rtx, + delta))); } /* If we were deferring a callee register restore, do it now. */ else if (merge_sp_adjust_with_load) { rtx delta = GEN_INT (-actual_fsize); - emit_insn (gen_pre_load (gen_rtx_REG (word_mode, - merge_sp_adjust_with_load), - stack_pointer_rtx, - delta)); + rtx dest = gen_rtx_REG (word_mode, merge_sp_adjust_with_load); + FRP (emit_insn (gen_pre_load (dest, stack_pointer_rtx, delta))); } else if (actual_fsize != 0) - { - set_reg_plus_d (STACK_POINTER_REGNUM, - STACK_POINTER_REGNUM, - - actual_fsize); - } + FRP (set_reg_plus_d (STACK_POINTER_REGNUM, + STACK_POINTER_REGNUM, + - actual_fsize)); /* If we haven't restored %r2 yet (no frame pointer, and a stack frame greater than 8k), do so now. */ if (ret_off != 0) - load_reg (2, ret_off, STACK_POINTER_REGNUM); + FRP (load_reg (2, ret_off, STACK_POINTER_REGNUM)); } /* Set up a callee saved register for the pic offset table register. */ -void hppa_init_pic_save () +void +hppa_init_pic_save () { rtx insn, picreg; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 873d0b6d97e..f93e42d7a9d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1133,11 +1133,13 @@ static dw_cfa_location cfa_temp; cfa_store.reg to the actual CFA cfa_temp register holding an integral value. cfa_temp.offset stores the value, which will be used to adjust the - stack pointer. + stack pointer. cfa_temp is also used like cfa_store, + to track stores to the stack via fp or a temp reg. Rules 1- 4: Setting a register's value to cfa.reg or an expression with cfa.reg as the first operand changes the cfa.reg and its - cfa.offset. + cfa.offset. Rule 1 and 4 also set cfa_temp.reg and + cfa_temp.offset. Rules 6- 9: Set a non-cfa.reg register value to a constant or an expression yielding a constant. This sets cfa_temp.reg @@ -1146,9 +1148,9 @@ static dw_cfa_location cfa_temp; Rule 5: Create a new register cfa_store used to save items to the stack. - Rules 10-13: Save a register to the stack. Define offset as the + Rules 10-14: Save a register to the stack. Define offset as the difference of the original location and cfa_store's - location. + location (or cfa_temp's location if cfa_temp is used). The Rules @@ -1157,26 +1159,30 @@ static dw_cfa_location cfa_temp; Rule 1: (set :cfa.reg) - effects: cfa.reg = + effects: cfa.reg = cfa.offset unchanged + cfa_temp.reg = + cfa_temp.offset = cfa.offset Rule 2: - (set sp ({minus,plus} {sp,fp}:cfa.reg {,:cfa_temp.reg})) + (set sp ({minus,plus,losum} {sp,fp}:cfa.reg {,:cfa_temp.reg})) effects: cfa.reg = sp if fp used cfa.offset += {+/- , cfa_temp.offset} if cfa.reg==sp cfa_store.offset += {+/- , cfa_temp.offset} if cfa_store.reg==sp Rule 3: - (set fp ({minus,plus} :cfa.reg )) + (set fp ({minus,plus,losum} :cfa.reg )) effects: cfa.reg = fp cfa_offset += +/- Rule 4: - (set (plus :cfa.reg )) + (set ({plus,losum} :cfa.reg )) constraints: != fp != sp effects: cfa.reg = + cfa_temp.reg = + cfa_temp.offset = cfa.offset Rule 5: (set (plus :cfa_temp.reg sp:cfa.reg)) @@ -1208,30 +1214,31 @@ static dw_cfa_location cfa_temp; (set (mem (pre_modify sp:cfa_store (???? ))) ) effects: cfa_store.offset -= cfa.offset = cfa_store.offset if cfa.reg == sp - offset = -cfa_store.offset cfa.reg = sp - cfa.base_offset = offset + cfa.base_offset = -cfa_store.offset Rule 11: (set (mem ({pre_inc,pre_dec} sp:cfa_store.reg)) ) effects: cfa_store.offset += -/+ mode_size(mem) cfa.offset = cfa_store.offset if cfa.reg == sp - offset = -cfa_store.offset cfa.reg = sp - cfa.base_offset = offset + cfa.base_offset = -cfa_store.offset Rule 12: - (set (mem ({minus,plus} :cfa_store )) ) - effects: cfa_store.offset += -/+ - offset = -cfa_store.offset - cfa.reg = :{cfa_store,cfa_temp} )) ) + effects: cfa.reg = + cfa.base_offset = -/+ - {cfa_store,cfa_temp}.offset Rule 13: - (set (mem :cfa_store) ) - effects: offset = -cfa_store.offset - cfa.reg = - cfa.base_offset = offset */ + (set (mem :{cfa_store,cfa_temp}) ) + effects: cfa.reg = + cfa.base_offset = -{cfa_store,cfa_temp}.offset + + Rule 14: + (set (mem (postinc :cfa_temp )) ) + effects: cfa.reg = + cfa.base_offset = -cfa_temp.offset + cfa_temp.offset -= mode_size(mem) */ static void dwarf2out_frame_debug_expr (expr, label) @@ -1291,10 +1298,13 @@ dwarf2out_frame_debug_expr (expr, label) FP. So we just rely on the backends to only set RTX_FRAME_RELATED_P on appropriate insns. */ cfa.reg = REGNO (dest); + cfa_temp.reg = cfa.reg; + cfa_temp.offset = cfa.offset; break; case PLUS: case MINUS: + case LO_SUM: if (dest == stack_pointer_rtx) { /* Rule 2 */ @@ -1320,10 +1330,13 @@ dwarf2out_frame_debug_expr (expr, label) abort (); cfa.reg = STACK_POINTER_REGNUM; } + else if (GET_CODE (src) == LO_SUM) + /* Assume we've set the source reg of the LO_SUM from sp. */ + ; else if (XEXP (src, 0) != stack_pointer_rtx) abort (); - if (GET_CODE (src) == PLUS) + if (GET_CODE (src) != MINUS) offset = -offset; if (cfa.reg == STACK_POINTER_REGNUM) cfa.offset += offset; @@ -1343,7 +1356,7 @@ dwarf2out_frame_debug_expr (expr, label) && GET_CODE (XEXP (src, 1)) == CONST_INT) { offset = INTVAL (XEXP (src, 1)); - if (GET_CODE (src) == PLUS) + if (GET_CODE (src) != MINUS) offset = -offset; cfa.offset += offset; cfa.reg = HARD_FRAME_POINTER_REGNUM; @@ -1353,7 +1366,7 @@ dwarf2out_frame_debug_expr (expr, label) } else { - if (GET_CODE (src) != PLUS) + if (GET_CODE (src) == MINUS) abort (); /* Rule 4 */ @@ -1363,27 +1376,34 @@ dwarf2out_frame_debug_expr (expr, label) { /* Setting a temporary CFA register that will be copied into the FP later on. */ - offset = INTVAL (XEXP (src, 1)); - if (GET_CODE (src) == PLUS) - offset = -offset; + offset = - INTVAL (XEXP (src, 1)); cfa.offset += offset; cfa.reg = REGNO (dest); + /* Or used to save regs to the stack. */ + cfa_temp.reg = cfa.reg; + cfa_temp.offset = cfa.offset; } /* Rule 5 */ - else + else if (GET_CODE (XEXP (src, 0)) == REG + && REGNO (XEXP (src, 0)) == cfa_temp.reg + && XEXP (src, 1) == stack_pointer_rtx) { /* Setting a scratch register that we will use instead of SP for saving registers to the stack. */ - if (XEXP (src, 1) != stack_pointer_rtx) - abort (); - if (GET_CODE (XEXP (src, 0)) != REG - || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp.reg) - abort (); if (cfa.reg != STACK_POINTER_REGNUM) abort (); cfa_store.reg = REGNO (dest); cfa_store.offset = cfa.offset - cfa_temp.offset; } + /* Rule 9 */ + else if (GET_CODE (src) == LO_SUM + && GET_CODE (XEXP (src, 1)) == CONST_INT) + { + cfa_temp.reg = REGNO (dest); + cfa_temp.offset = INTVAL (XEXP (src, 1)); + } + else + abort (); } break; @@ -1410,14 +1430,6 @@ dwarf2out_frame_debug_expr (expr, label) case HIGH: break; - /* Rule 9 */ - case LO_SUM: - if (GET_CODE (XEXP (src, 1)) != CONST_INT) - abort (); - cfa_temp.reg = REGNO (dest); - cfa_temp.offset = INTVAL (XEXP (src, 1)); - break; - default: abort (); } @@ -1470,23 +1482,38 @@ dwarf2out_frame_debug_expr (expr, label) /* With an offset. */ case PLUS: case MINUS: + case LO_SUM: if (GET_CODE (XEXP (XEXP (dest, 0), 1)) != CONST_INT) abort (); offset = INTVAL (XEXP (XEXP (dest, 0), 1)); if (GET_CODE (XEXP (dest, 0)) == MINUS) offset = -offset; - if (cfa_store.reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) + if (cfa_store.reg == (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) + offset -= cfa_store.offset; + else if (cfa_temp.reg == (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) + offset -= cfa_temp.offset; + else abort (); - offset -= cfa_store.offset; break; /* Rule 13 */ /* Without an offset. */ case REG: - if (cfa_store.reg != (unsigned) REGNO (XEXP (dest, 0))) + if (cfa_store.reg == (unsigned) REGNO (XEXP (dest, 0))) + offset = -cfa_store.offset; + else if (cfa_temp.reg == (unsigned) REGNO (XEXP (dest, 0))) + offset = -cfa_temp.offset; + else abort (); - offset = -cfa_store.offset; + break; + + /* Rule 14 */ + case POST_INC: + if (cfa_temp.reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) + abort (); + offset = -cfa_temp.offset; + cfa_temp.offset -= GET_MODE_SIZE (GET_MODE (dest)); break; default: -- 2.30.2