diff options
author | H.J. Lu <hjl@gcc.gnu.org> | 2008-07-30 12:20:43 -0700 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2008-07-30 12:20:43 -0700 |
commit | 2e3f842fe69ce4e74cfe18493429b807af271083 (patch) | |
tree | 9703441244044dbd6ab33443385887297f540e4f /gcc/dwarf2out.c | |
parent | 22129589211764a55ee21f9202ab80b3772817b6 (diff) | |
download | gcc-2e3f842fe69ce4e74cfe18493429b807af271083.zip gcc-2e3f842fe69ce4e74cfe18493429b807af271083.tar.gz gcc-2e3f842fe69ce4e74cfe18493429b807af271083.tar.bz2 |
[multiple changes]
2008-07-30 Joey Ye <joey.ye@intel.com>
H.J. Lu <hongjiu.lu@intel.com>
* builtins.c (expand_builtin_setjmp_receiver): Replace
virtual_incoming_args_rtx with crtl->args.internal_arg_pointer.
(expand_builtin_apply_args_1): Likewise.
(expand_builtin_longjmp): Need DRAP for stack alignment.
(expand_builtin_apply): Likewise.
* caller-save.c (setup_save_areas): Call assign_stack_local_1
instead of assign_stack_local to allow alignment reduction.
* calls.c (emit_call_1): Need DRAP for stack alignment if
return pops.
(expand_call): Replace virtual_incoming_args_rtx with
crtl->args.internal_arg_pointer.
* stmt.c (expand_nl_goto_receiver): Likewise.
* cfgexpand.c (get_decl_align_unit): Estimate stack variable
alignment and store to stack_alignment_estimated and
max_used_stack_slot_alignment.
(expand_one_var): Likewise.
(expand_stack_alignment): New function.
(tree_expand_cfg): Initialize max_used_stack_slot_alignment
and stack_alignment_estimated fields in rtl_data. Call
expand_stack_alignment at end.
* defaults.h (INCOMING_STACK_BOUNDARY): New.
(MAX_STACK_ALIGNMENT): Likewise.
(MAX_SUPPORTED_STACK_ALIGNMENT): Likewise.
(SUPPORTS_STACK_ALIGNMENT): Likewise.
* emit-rtl.c (gen_reg_rtx): Estimate stack alignment for
stack alignment when generating virtual registers.
* function.c (assign_stack_local): Renamed to ...
(assign_stack_local_1): This. Add a parameter to indicate
if it is OK to reduce alignment.
(assign_stack_local): Use it.
(instantiate_new_reg): Instantiate virtual incoming args rtx
to vDRAP if stack realignment and DRAP is needed.
(assign_parms): Collect parameter/return type alignment and
contribute to stack_alignment_estimated.
(locate_and_pad_parm): Likewise.
(get_arg_pointer_save_area): Replace virtual_incoming_args_rtx
with crtl->args.internal_arg_pointer.
* function.h (rtl_data): Add new field drap_reg,
max_used_stack_slot_alignment, stack_alignment_estimated,
stack_realign_needed, need_drap, stack_realign_processed and
stack_realign_finalized.
(stack_realign_fp): New macro.
(stack_realign_drap): Likewise.
* global.c (compute_regsets): Frame pointer is needed when
stack is realigned. Can eliminate frame pointer when stack is
realigned and dynamic realigned argument pointer isn't used.
* reload1.c (update_eliminables): Frame pointer is needed
when stack is realigned.
(init_elim_table): Can eliminate frame pointer when stack is
realigned and dynamic realigned argument pointer isn't used.
* rtl.h (assign_stack_local_1): Declare new funtion.
* target-def.h (TARGET_UPDATE_STACK_BOUNDARY): New.
(TARGET_GET_DRAP_RTX): Likewise.
(TARGET_CALLS): Add TARGET_UPDATE_STACK_BOUNDARY and
TARGET_GET_DRAP_RTX.
* target.h (gcc_target): Add update_stack_boundary and
get_drap_rtx.
* tree-vectorizer.c (vect_can_force_dr_alignment_p): Replace
STACK_BOUNDARY with MAX_STACK_ALIGNMENT.
2008-07-30 Xuepeng Guo <xuepeng.guo@intel.com>
H.J. Lu <hongjiu.lu@intel.com>
* dwarf2out.c (dw_fde_struct): Add stack_realignment, drap_reg,
vdrap_reg, stack_realign and drap_reg_saved.
(add_cfi): Don't allow redefining CFA when DRAP is used.
(reg_save): Handle stack alignment.
(dwarf2out_frame_debug_expr): Add rules 16-20 to handle stack
alignment. Don't generate DWARF information for (set fp sp)
when DRAP is used.
(dwarf2out_begin_prologue): Initialize drap_reg and vdrap_reg
to INVALID_REGNUM.
(int_loc_descriptor): Move prototype forward. Also define if
DWARF2_UNWIND_INFO is true.
(output_cfa_loc): Handle DW_CFA_expression.
(build_cfa_aligned_loc): New.
(based_loc_descr): Update assert for stack realign. For local
variables, use sp+offset when stack is aligned without drap and
fp+offset when stack is aligned with drap. For arguments, use
cfa+offset when drap is used to align stack.
2008-07-30 Joey Ye <joey.ye@intel.com>
H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_force_align_arg_pointer_string):
Break long line.
(ix86_gen_andsp): New.
(ix86_user_incoming_stack_boundary): Likewise.
(ix86_default_incoming_stack_boundary): Likewise.
(ix86_incoming_stack_boundary): Likewise.
(ix86_can_eliminate): Likewise.
(find_drap_reg): Likewise.
(ix86_update_stack_boundary): Likewise.
(ix86_get_drap_rtx): Likewise.
(ix86_finalize_stack_realign_flags): Likewise.
(TARGET_UPDATE_STACK_BOUNDARY): Likewise.
(TARGET_GET_DRAP_RTX): Likewise.
(override_options): Overide option value for new options.
(ix86_function_ok_for_sibcall): Remove check for
force_align_arg_pointer.
(ix86_handle_cconv_attribute): Likewise.
(ix86_function_regparm): Likewise.
(setup_incoming_varargs_64): Don't set stack_alignment_needed
here.
(ix86_va_start): Replace virtual_incoming_args_rtx with
crtl->args.internal_arg_pointer.
(ix86_select_alt_pic_regnum): Check DRAP register.
(ix86_save_reg): Replace force_align_arg_pointer with drap_reg.
(ix86_compute_frame_layout): Compute frame layout wrt stack
realignment.
(ix86_internal_arg_pointer): Just return
virtual_incoming_args_rtx.
(ix86_expand_prologue): Decide if stack realignment is needed
and generate prologue code accordingly.
(ix86_expand_epilogue): Generate epilogue code wrt stack
realignment is really needed or not.
* config/i386/i386.h (MAIN_STACK_BOUNDARY): New.
(ABI_STACK_BOUNDARY): Likewise.
(PREFERRED_STACK_BOUNDARY_DEFAULT): Likewise.
(STACK_REALIGN_DEFAULT): Likewise.
(INCOMING_STACK_BOUNDARY): Likewise.
(MAX_STACK_ALIGNMENT): Likewise.
(ix86_incoming_stack_boundary): Likewise.
(FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Removed.
(REAL_PIC_OFFSET_TABLE_REGNUM): Updated to use BX_REG.
(CAN_ELIMINATE): Defined with ix86_can_eliminate.
(machine_function): Remove force_align_arg_pointer.
* config/i386/i386.md (BX_REG): New.
(R13_REG): Likewise.
* config/i386/i386.opt (mforce_drap): New.
(mincoming-stack-boundary): Likewise.
(mstackrealign): Add Init(-1).
* config/i386/i386-protos.h (ix86_can_eliminate): New
2008-07-30 H.J. Lu <hongjiu.lu@intel.com>
* doc/extend.texi: Update force_align_arg_pointer.
* doc/invoke.texi: Document -mincoming-stack-boundary. Update
-mstackrealign.
* doc/tm.texi (MAX_STACK_ALIGNMENT): Add macro.
(INCOMING_STACK_BOUNDARY): Likewise.
(TARGET_UPDATE_STACK_BOUNDARY): New target hook.
(TARGET_GET_DRAP_RTX): Likewise.
From-SVN: r138335
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 278 |
1 files changed, 267 insertions, 11 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index a8e06ef..72514a6 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -239,9 +239,18 @@ typedef struct dw_fde_struct GTY(()) bool dw_fde_switched_sections; dw_cfi_ref dw_fde_cfi; unsigned funcdef_number; + HOST_WIDE_INT stack_realignment; + /* Dynamic realign argument pointer register. */ + unsigned int drap_reg; + /* Virtual dynamic realign argument pointer register. */ + unsigned int vdrap_reg; unsigned all_throwers_are_sibcalls : 1; unsigned nothrow : 1; unsigned uses_eh_lsda : 1; + /* Whether we did stack realign in this call frame. */ + unsigned stack_realign : 1; + /* Whether dynamic realign argument pointer register has been saved. */ + unsigned drap_reg_saved: 1; } dw_fde_node; @@ -388,6 +397,8 @@ static void get_cfa_from_loc_descr (dw_cfa_location *, struct dw_loc_descr_struct *); static struct dw_loc_descr_struct *build_cfa_loc (dw_cfa_location *, HOST_WIDE_INT); +static struct dw_loc_descr_struct *build_cfa_aligned_loc + (HOST_WIDE_INT, HOST_WIDE_INT); static void def_cfa_1 (const char *, dw_cfa_location *); /* How to start an assembler comment. */ @@ -621,6 +632,23 @@ static inline void add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi) { dw_cfi_ref *p; + dw_fde_ref fde = current_fde (); + + /* When DRAP is used, CFA is defined with an expression. Redefine + CFA may lead to a different CFA value. */ + if (fde && fde->drap_reg != INVALID_REGNUM) + switch (cfi->dw_cfi_opc) + { + case DW_CFA_def_cfa_register: + case DW_CFA_def_cfa_offset: + case DW_CFA_def_cfa_offset_sf: + case DW_CFA_def_cfa: + case DW_CFA_def_cfa_sf: + gcc_unreachable (); + + default: + break; + } /* Find the end of the chain. */ for (p = list_head; (*p) != NULL; p = &(*p)->dw_cfi_next) @@ -880,10 +908,22 @@ static void reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset) { dw_cfi_ref cfi = new_cfi (); + dw_fde_ref fde = current_fde (); cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg; - if (sreg == INVALID_REGNUM) + /* When stack is aligned, store REG using DW_CFA_expression with + FP. */ + if (fde + && fde->stack_realign + && sreg == INVALID_REGNUM) + { + cfi->dw_cfi_opc = DW_CFA_expression; + cfi->dw_cfi_oprnd2.dw_cfi_reg_num = reg; + cfi->dw_cfi_oprnd1.dw_cfi_loc + = build_cfa_aligned_loc (offset, fde->stack_realignment); + } + else if (sreg == INVALID_REGNUM) { if (reg & ~0x3f) /* The register number won't fit in 6 bits, so we have to use @@ -1445,6 +1485,11 @@ static dw_cfa_location cfa_temp; difference of the original location and cfa_store's location (or cfa_temp's location if cfa_temp is used). + Rules 16-20: If AND operation happens on sp in prologue, we assume + stack is realigned. We will use a group of DW_OP_XXX + expressions to represent the location of the stored + register instead of CFA+offset. + The Rules "{a,b}" indicates a choice of a xor b. @@ -1538,13 +1583,48 @@ static dw_cfa_location cfa_temp; Rule 15: (set <reg> {unspec, unspec_volatile}) - effects: target-dependent */ + effects: target-dependent + + Rule 16: + (set sp (and: sp <const_int>)) + constraints: cfa_store.reg == sp + effects: current_fde.stack_realign = 1 + cfa_store.offset = 0 + fde->drap_reg = cfa.reg if cfa.reg != sp and cfa.reg != fp + + Rule 17: + (set (mem ({pre_inc, pre_dec} sp)) (mem (plus (cfa.reg) (const_int)))) + effects: cfa_store.offset += -/+ mode_size(mem) + + Rule 18: + (set (mem ({pre_inc, pre_dec} sp)) fp) + constraints: fde->stack_realign == 1 + effects: cfa_store.offset = 0 + cfa.reg != HARD_FRAME_POINTER_REGNUM + + Rule 19: + (set (mem ({pre_inc, pre_dec} sp)) cfa.reg) + constraints: fde->stack_realign == 1 + && cfa.offset == 0 + && cfa.indirect == 0 + && cfa.reg != HARD_FRAME_POINTER_REGNUM + effects: Use DW_CFA_def_cfa_expression to define cfa + cfa.reg == fde->drap_reg + + Rule 20: + (set reg fde->drap_reg) + constraints: fde->vdrap_reg == INVALID_REGNUM + effects: fde->vdrap_reg = reg. + (set mem fde->drap_reg) + constraints: fde->drap_reg_saved == 1 + effects: none. */ static void dwarf2out_frame_debug_expr (rtx expr, const char *label) { rtx src, dest, span; HOST_WIDE_INT offset; + dw_fde_ref fde; /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of the PARALLEL independently. The first element is always processed if @@ -1621,6 +1701,26 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) src = rsi; } + fde = current_fde (); + + if (GET_CODE (src) == REG + && fde + && fde->drap_reg == REGNO (src) + && (fde->drap_reg_saved + || GET_CODE (dest) == REG)) + { + /* Rule 20 */ + /* If we are saving dynamic realign argument pointer to a + register, the destination is virtual dynamic realign + argument pointer. It may be used to access argument. */ + if (GET_CODE (dest) == REG) + { + gcc_assert (fde->vdrap_reg == INVALID_REGNUM); + fde->vdrap_reg = REGNO (dest); + } + return; + } + switch (GET_CODE (dest)) { case REG: @@ -1649,7 +1749,19 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) /* For the SPARC and its register window. */ || (DWARF_FRAME_REGNUM (REGNO (src)) == DWARF_FRAME_RETURN_COLUMN)); - queue_reg_save (label, src, dest, 0); + + /* After stack is aligned, we can only save SP in FP + if drap register is used. In this case, we have + to restore stack pointer with the CFA value and we + don't generate this DWARF information. */ + if (fde + && fde->stack_realign + && REGNO (src) == STACK_POINTER_REGNUM) + gcc_assert (REGNO (dest) == HARD_FRAME_POINTER_REGNUM + && fde->drap_reg != INVALID_REGNUM + && cfa.reg != REGNO (src)); + else + queue_reg_save (label, src, dest, 0); } break; @@ -1782,6 +1894,24 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) targetm.dwarf_handle_frame_unspec (label, expr, XINT (src, 1)); return; + /* Rule 16 */ + case AND: + /* If this AND operation happens on stack pointer in prologue, + we assume the stack is realigned and we extract the + alignment. */ + if (fde && XEXP (src, 0) == stack_pointer_rtx) + { + gcc_assert (cfa_store.reg == REGNO (XEXP (src, 0))); + fde->stack_realign = 1; + fde->stack_realignment = INTVAL (XEXP (src, 1)); + cfa_store.offset = 0; + + if (cfa.reg != STACK_POINTER_REGNUM + && cfa.reg != HARD_FRAME_POINTER_REGNUM) + fde->drap_reg = cfa.reg; + } + return; + default: gcc_unreachable (); } @@ -1790,7 +1920,6 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) break; case MEM: - gcc_assert (REG_P (src)); /* Saving a register to the stack. Make sure dest is relative to the CFA register. */ @@ -1821,10 +1950,23 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) if (GET_CODE (XEXP (dest, 0)) == PRE_INC) offset = -offset; - gcc_assert (REGNO (XEXP (XEXP (dest, 0), 0)) == STACK_POINTER_REGNUM + gcc_assert ((REGNO (XEXP (XEXP (dest, 0), 0)) + == STACK_POINTER_REGNUM) && cfa_store.reg == STACK_POINTER_REGNUM); cfa_store.offset += offset; + + /* Rule 18: If stack is aligned, we will use FP as a + reference to represent the address of the stored + regiser. */ + if (fde + && fde->stack_realign + && src == hard_frame_pointer_rtx) + { + gcc_assert (cfa.reg != HARD_FRAME_POINTER_REGNUM); + cfa_store.offset = 0; + } + if (cfa.reg == STACK_POINTER_REGNUM) cfa.offset = cfa_store.offset; @@ -1893,6 +2035,32 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) if (cfa.offset == 0) { + /* Rule 19 */ + /* If stack is aligned, putting CFA reg into stack means + we can no longer use reg + offset to represent CFA. + Here we use DW_CFA_def_cfa_expression instead. The + result of this expression equals to the original CFA + value. */ + if (fde + && fde->stack_realign + && cfa.indirect == 0 + && cfa.reg != HARD_FRAME_POINTER_REGNUM) + { + dw_cfa_location cfa_exp; + + gcc_assert (fde->drap_reg == cfa.reg); + + cfa_exp.indirect = 1; + cfa_exp.reg = HARD_FRAME_POINTER_REGNUM; + cfa_exp.base_offset = offset; + cfa_exp.offset = 0; + + fde->drap_reg_saved = 1; + + def_cfa_1 (label, &cfa_exp); + break; + } + /* If the source register is exactly the CFA, assume we're saving SP like any other register; this happens on the ARM. */ @@ -1917,6 +2085,12 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) break; } } + /* Rule 17 */ + /* If the source operand of this MEM operation is not a + register, basically the source is return address. Here + we only care how much stack grew and we don't save it. */ + if (!REG_P (src)) + break; def_cfa_1 (label, &cfa); { @@ -2693,6 +2867,8 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, fde->nothrow = TREE_NOTHROW (current_function_decl); fde->uses_eh_lsda = crtl->uses_eh_lsda; fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls; + fde->drap_reg = INVALID_REGNUM; + fde->vdrap_reg = INVALID_REGNUM; args_size = old_args_size = 0; @@ -2924,6 +3100,7 @@ typedef struct dw_loc_list_struct GTY(()) static const char *dwarf_stack_op_name (unsigned); static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT); +static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT); static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref); static unsigned long size_of_loc_descr (dw_loc_descr_ref); static unsigned long size_of_locs (dw_loc_descr_ref); @@ -3583,6 +3760,9 @@ output_cfa_loc (dw_cfi_ref cfi) dw_loc_descr_ref loc; unsigned long size; + if (cfi->dw_cfi_opc == DW_CFA_expression) + dw2_asm_output_data (1, cfi->dw_cfi_oprnd2.dw_cfi_reg_num, NULL); + /* Output the size of the block. */ loc = cfi->dw_cfi_oprnd1.dw_cfi_loc; size = size_of_locs (loc); @@ -3642,6 +3822,38 @@ build_cfa_loc (dw_cfa_location *cfa, HOST_WIDE_INT offset) return head; } +/* This function builds a dwarf location descriptor sequence for + the address at OFFSET from the CFA when stack is aligned to + ALIGNMENT byte. */ + +static struct dw_loc_descr_struct * +build_cfa_aligned_loc (HOST_WIDE_INT offset, HOST_WIDE_INT alignment) +{ + struct dw_loc_descr_struct *head; + unsigned int dwarf_fp + = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM); + + /* When CFA is defined as FP+OFFSET, emulate stack alignment. */ + if (cfa.reg == HARD_FRAME_POINTER_REGNUM && cfa.indirect == 0) + { + if (dwarf_fp <= 31) + head = new_loc_descr (DW_OP_breg0 + dwarf_fp, 0, 0); + else + head = new_loc_descr (DW_OP_bregx, dwarf_fp, 0); + + add_loc_descr (&head, int_loc_descriptor (alignment)); + add_loc_descr (&head, new_loc_descr (DW_OP_and, 0, 0)); + + add_loc_descr (&head, int_loc_descriptor (offset)); + add_loc_descr (&head, new_loc_descr (DW_OP_plus, 0, 0)); + } + else if (dwarf_fp <= 31) + head = new_loc_descr (DW_OP_breg0 + dwarf_fp, offset, 0); + else + head = new_loc_descr (DW_OP_bregx, dwarf_fp, offset); + return head; +} + /* This function fills in aa dw_cfa_location structure from a dwarf location descriptor sequence. */ @@ -4310,7 +4522,6 @@ static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int, enum var_init_status); static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx, enum var_init_status); -static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT); static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT, enum var_init_status); static int is_based_loc (const_rtx); @@ -8997,6 +9208,10 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs, return loc_result; } +#endif /* DWARF2_DEBUGGING_INFO */ + +#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) + /* Return a location descriptor that designates a constant. */ static dw_loc_descr_ref @@ -9035,6 +9250,9 @@ int_loc_descriptor (HOST_WIDE_INT i) return new_loc_descr (op, i, 0); } +#endif + +#ifdef DWARF2_DEBUGGING_INFO /* Return a location descriptor that designates a base+offset location. */ @@ -9044,6 +9262,7 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset, { unsigned int regno; dw_loc_descr_ref result; + dw_fde_ref fde = current_fde (); /* We only use "frame base" when we're sure we're talking about the post-prologue local stack frame. We do this by *not* running @@ -9060,13 +9279,45 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset, offset += INTVAL (XEXP (elim, 1)); elim = XEXP (elim, 0); } - gcc_assert (elim == (frame_pointer_needed ? hard_frame_pointer_rtx - : stack_pointer_rtx)); - offset += frame_pointer_fb_offset; + gcc_assert ((SUPPORTS_STACK_ALIGNMENT + && (elim == hard_frame_pointer_rtx + || elim == stack_pointer_rtx)) + || elim == (frame_pointer_needed + ? hard_frame_pointer_rtx + : stack_pointer_rtx)); + + /* If drap register is used to align stack, use frame + pointer + offset to access stack variables. If stack + is aligned without drap, use stack pointer + offset to + access stack variables. */ + if (fde + && fde->stack_realign + && cfa.reg == HARD_FRAME_POINTER_REGNUM + && reg == frame_pointer_rtx) + { + int base_reg + = DWARF_FRAME_REGNUM (cfa.indirect + ? HARD_FRAME_POINTER_REGNUM + : STACK_POINTER_REGNUM); + if (base_reg <= 31) + return new_loc_descr (DW_OP_breg0 + base_reg, offset, 0); + else + return new_loc_descr (DW_OP_bregx, base_reg, offset); + } + offset += frame_pointer_fb_offset; return new_loc_descr (DW_OP_fbreg, offset, 0); } } + else if (fde + && fde->drap_reg != INVALID_REGNUM + && (fde->drap_reg == REGNO (reg) + || fde->vdrap_reg == REGNO (reg))) + { + /* Use cfa+offset to represent the location of arguments passed + on stack when drap is used to align stack. */ + return new_loc_descr (DW_OP_fbreg, offset, 0); + } regno = dbx_reg_number (reg); if (regno <= 31) @@ -11111,8 +11362,13 @@ compute_frame_pointer_to_fb_displacement (HOST_WIDE_INT offset) offset += INTVAL (XEXP (elim, 1)); elim = XEXP (elim, 0); } - gcc_assert (elim == (frame_pointer_needed ? hard_frame_pointer_rtx - : stack_pointer_rtx)); + + gcc_assert ((SUPPORTS_STACK_ALIGNMENT + && (elim == hard_frame_pointer_rtx + || elim == stack_pointer_rtx)) + || elim == (frame_pointer_needed + ? hard_frame_pointer_rtx + : stack_pointer_rtx)); frame_pointer_fb_offset = -offset; } |