diff options
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r-- | gcc/config/i386/i386.c | 404 |
1 files changed, 79 insertions, 325 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index dbaccb308f9..2d2cc87e13c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -7686,9 +7686,6 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED) static rtx gen_push (rtx arg) { - if (ix86_cfa_state->reg == stack_pointer_rtx) - ix86_cfa_state->offset += UNITS_PER_WORD; - return gen_rtx_SET (VOIDmode, gen_rtx_MEM (Pmode, gen_rtx_PRE_DEC (Pmode, @@ -7748,7 +7745,8 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return) } } - if (crtl->drap_reg && regno == REGNO (crtl->drap_reg)) + if (crtl->drap_reg + && regno == REGNO (crtl->drap_reg)) return 1; return (df_regs_ever_live_p (regno) @@ -8078,49 +8076,6 @@ ix86_emit_save_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset) } } -static GTY(()) rtx queued_cfa_restores; - -/* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack - manipulation insn. Don't add it if the previously - saved value will be left untouched within stack red-zone till return, - as unwinders can find the same value in the register and - on the stack. */ - -static void -ix86_add_cfa_restore_note (rtx insn, rtx reg, HOST_WIDE_INT red_offset) -{ - if (TARGET_RED_ZONE - && !TARGET_64BIT_MS_ABI - && red_offset + RED_ZONE_SIZE >= 0 - && crtl->args.pops_args < 65536) - return; - - if (insn) - { - add_reg_note (insn, REG_CFA_RESTORE, reg); - RTX_FRAME_RELATED_P (insn) = 1; - } - else - queued_cfa_restores - = alloc_EXPR_LIST (REG_CFA_RESTORE, reg, queued_cfa_restores); -} - -/* Add queued REG_CFA_RESTORE notes if any to INSN. */ - -static void -ix86_add_queued_cfa_restore_notes (rtx insn) -{ - rtx last; - if (!queued_cfa_restores) - return; - for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1)) - ; - XEXP (last, 1) = REG_NOTES (insn); - REG_NOTES (insn) = queued_cfa_restores; - queued_cfa_restores = NULL_RTX; - RTX_FRAME_RELATED_P (insn) = 1; -} - /* Expand prologue or epilogue stack adjustment. The pattern exist to put a dependency on all ebp-based memory accesses. STYLE should be negative if instructions should be marked as frame related, @@ -8128,8 +8083,7 @@ ix86_add_queued_cfa_restore_notes (rtx insn) otherwise. */ static void -pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, - int style, bool set_cfa) +pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style) { rtx insn; @@ -8152,24 +8106,7 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64_2 (dest, src, r11, offset)); } - - if (style >= 0) - ix86_add_queued_cfa_restore_notes (insn); - - if (set_cfa) - { - rtx r; - - gcc_assert (ix86_cfa_state->reg == src); - ix86_cfa_state->offset += INTVAL (offset); - ix86_cfa_state->reg = dest; - - r = gen_rtx_PLUS (Pmode, src, offset); - r = gen_rtx_SET (VOIDmode, dest, r); - add_reg_note (insn, REG_CFA_ADJUST_CFA, r); - RTX_FRAME_RELATED_P (insn) = 1; - } - else if (style < 0) + if (style < 0) RTX_FRAME_RELATED_P (insn) = 1; } @@ -8305,6 +8242,30 @@ ix86_internal_arg_pointer (void) return virtual_incoming_args_rtx; } +/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook. + This is called from dwarf2out.c to emit call frame instructions + for frame-related insns containing UNSPECs and UNSPEC_VOLATILEs. */ +static void +ix86_dwarf_handle_frame_unspec (const char *label, rtx pattern, int index) +{ + rtx unspec = SET_SRC (pattern); + gcc_assert (GET_CODE (unspec) == UNSPEC); + + switch (index) + { + case UNSPEC_REG_SAVE: + dwarf2out_reg_save_reg (label, XVECEXP (unspec, 0, 0), + SET_DEST (pattern)); + break; + case UNSPEC_DEF_CFA: + dwarf2out_def_cfa (label, REGNO (SET_DEST (pattern)), + INTVAL (XVECEXP (unspec, 0, 0))); + break; + default: + gcc_unreachable (); + } +} + /* Finalize stack_realign_needed flag, which will guide prologue/epilogue to be generated in correct form. */ static void @@ -8348,10 +8309,6 @@ ix86_expand_prologue (void) /* DRAP should not coexist with stack_realign_fp */ gcc_assert (!(crtl->drap_reg && stack_realign_fp)); - /* Initialize CFA state for before the prologue. */ - ix86_cfa_state->reg = stack_pointer_rtx; - ix86_cfa_state->offset = INCOMING_FRAME_SP_OFFSET; - ix86_compute_frame_layout (&frame); /* Emit prologue code to adjust stack alignment and setup DRAP, in case @@ -8381,7 +8338,6 @@ ix86_expand_prologue (void) insn = emit_insn (gen_rtx_SET (VOIDmode, y, x)); RTX_FRAME_RELATED_P (insn) = 1; - ix86_cfa_state->reg = crtl->drap_reg; /* Align the stack. */ insn = emit_insn ((*ix86_gen_andsp) (stack_pointer_rtx, @@ -8410,9 +8366,6 @@ ix86_expand_prologue (void) insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; - - if (ix86_cfa_state->reg == stack_pointer_rtx) - ix86_cfa_state->reg = hard_frame_pointer_rtx; } if (stack_realign_fp) @@ -8451,8 +8404,7 @@ ix86_expand_prologue (void) ; else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT) pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-allocate), -1, - ix86_cfa_state->reg == stack_pointer_rtx); + GEN_INT (-allocate), -1); else { /* Only valid for Win32. */ @@ -8480,15 +8432,11 @@ ix86_expand_prologue (void) else insn = gen_allocate_stack_worker_32 (eax, eax); insn = emit_insn (insn); - - if (ix86_cfa_state->reg == stack_pointer_rtx) - { - ix86_cfa_state->offset += allocate; - t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate)); - t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t); - add_reg_note (insn, REG_CFA_ADJUST_CFA, t); - RTX_FRAME_RELATED_P (insn) = 1; - } + RTX_FRAME_RELATED_P (insn) = 1; + t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate)); + t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t); + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + t, REG_NOTES (insn)); if (eax_live) { @@ -8595,104 +8543,18 @@ ix86_expand_prologue (void) emit_insn (gen_cld ()); } -/* Emit code to restore REG using a POP insn. */ - -static void -ix86_emit_restore_reg_using_pop (rtx reg, HOST_WIDE_INT red_offset) -{ - rtx insn = emit_insn (ix86_gen_pop1 (reg)); - - if (ix86_cfa_state->reg == crtl->drap_reg - && REGNO (reg) == REGNO (crtl->drap_reg)) - { - /* Previously we'd represented the CFA as an expression - like *(%ebp - 8). We've just popped that value from - the stack, which means we need to reset the CFA to - the drap register. This will remain until we restore - the stack pointer. */ - add_reg_note (insn, REG_CFA_DEF_CFA, reg); - RTX_FRAME_RELATED_P (insn) = 1; - return; - } - - if (ix86_cfa_state->reg == stack_pointer_rtx) - { - ix86_cfa_state->offset -= UNITS_PER_WORD; - add_reg_note (insn, REG_CFA_ADJUST_CFA, - copy_rtx (XVECEXP (PATTERN (insn), 0, 1))); - RTX_FRAME_RELATED_P (insn) = 1; - } - - /* When the frame pointer is the CFA, and we pop it, we are - swapping back to the stack pointer as the CFA. This happens - for stack frames that don't allocate other data, so we assume - the stack pointer is now pointing at the return address, i.e. - the function entry state, which makes the offset be 1 word. */ - else if (ix86_cfa_state->reg == hard_frame_pointer_rtx - && reg == hard_frame_pointer_rtx) - { - ix86_cfa_state->reg = stack_pointer_rtx; - ix86_cfa_state->offset = UNITS_PER_WORD; - - add_reg_note (insn, REG_CFA_DEF_CFA, - gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (UNITS_PER_WORD))); - RTX_FRAME_RELATED_P (insn) = 1; - } - - ix86_add_cfa_restore_note (insn, reg, red_offset); -} - -/* Emit code to restore saved registers using POP insns. */ - -static void -ix86_emit_restore_regs_using_pop (HOST_WIDE_INT red_offset) -{ - int regno; - - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false)) - { - ix86_emit_restore_reg_using_pop (gen_rtx_REG (Pmode, regno), - red_offset); - red_offset += UNITS_PER_WORD; - } -} - -/* Emit code and notes for the LEAVE instruction. */ - -static void -ix86_emit_leave (HOST_WIDE_INT red_offset) -{ - rtx insn = emit_insn (ix86_gen_leave ()); - - ix86_add_queued_cfa_restore_notes (insn); - - if (ix86_cfa_state->reg == hard_frame_pointer_rtx) - { - add_reg_note (insn, REG_CFA_ADJUST_CFA, - copy_rtx (XVECEXP (PATTERN (insn), 0, 0))); - RTX_FRAME_RELATED_P (insn) = 1; - ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx, red_offset); - } -} - /* Emit code to restore saved registers using MOV insns. First register is restored from POINTER + OFFSET. */ static void ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset, - HOST_WIDE_INT red_offset, int maybe_eh_return) { - unsigned int regno; + int regno; rtx base_address = gen_rtx_MEM (Pmode, pointer); - rtx insn; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return)) { - rtx reg = gen_rtx_REG (Pmode, regno); - /* Ensure that adjust_address won't be forced to produce pointer out of range allowed by x86-64 instruction set. */ if (TARGET_64BIT && offset != trunc_int_for_mode (offset, SImode)) @@ -8705,25 +8567,9 @@ ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset, base_address = gen_rtx_MEM (Pmode, r11); offset = 0; } - insn = emit_move_insn (reg, - adjust_address (base_address, Pmode, offset)); + emit_move_insn (gen_rtx_REG (Pmode, regno), + adjust_address (base_address, Pmode, offset)); offset += UNITS_PER_WORD; - - if (ix86_cfa_state->reg == crtl->drap_reg - && regno == REGNO (crtl->drap_reg)) - { - /* Previously we'd represented the CFA as an expression - like *(%ebp - 8). We've just popped that value from - the stack, which means we need to reset the CFA to - the drap register. This will remain until we restore - the stack pointer. */ - add_reg_note (insn, REG_CFA_DEF_CFA, reg); - RTX_FRAME_RELATED_P (insn) = 1; - } - else - ix86_add_cfa_restore_note (NULL_RTX, reg, red_offset); - - red_offset += UNITS_PER_WORD; } } @@ -8731,18 +8577,15 @@ ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset, is restored from POINTER + OFFSET. */ static void ix86_emit_restore_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset, - HOST_WIDE_INT red_offset, int maybe_eh_return) { int regno; rtx base_address = gen_rtx_MEM (TImode, pointer); - rtx mem, insn; + rtx mem; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return)) { - rtx reg = gen_rtx_REG (TImode, regno); - /* Ensure that adjust_address won't be forced to produce pointer out of range allowed by x86-64 instruction set. */ if (TARGET_64BIT && offset != trunc_int_for_mode (offset, SImode)) @@ -8757,12 +8600,8 @@ ix86_emit_restore_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset, } mem = adjust_address (base_address, TImode, offset); set_mem_align (mem, 128); - insn = emit_move_insn (reg, mem); + emit_move_insn (gen_rtx_REG (TImode, regno), mem); offset += 16; - - ix86_add_cfa_restore_note (NULL_RTX, reg, red_offset); - - red_offset += 16; } } @@ -8771,11 +8610,10 @@ ix86_emit_restore_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset, void ix86_expand_epilogue (int style) { + int regno; int sp_valid; struct ix86_frame frame; - HOST_WIDE_INT offset, red_offset; - struct machine_cfa_state cfa_state_save = *ix86_cfa_state; - bool using_drap; + HOST_WIDE_INT offset; ix86_finalize_stack_realign_flags (); @@ -8791,9 +8629,6 @@ ix86_expand_epilogue (int style) if (frame_pointer_needed && frame.red_zone_size) emit_insn (gen_memory_blockage ()); - using_drap = crtl->drap_reg && crtl->stack_realign_needed; - gcc_assert (!using_drap || ix86_cfa_state->reg == crtl->drap_reg); - /* Calculate start of saved registers relative to ebp. Special care must be taken for the normal return case of a function using eh_return: the eax and edx registers are marked as saved, but not @@ -8804,19 +8639,6 @@ ix86_expand_epilogue (int style) offset *= -UNITS_PER_WORD; offset -= frame.nsseregs * 16 + frame.padding0; - /* Calculate start of saved registers relative to esp on entry of the - function. When realigning stack, this needs to be the most negative - value possible at runtime. */ - red_offset = offset; - if (using_drap) - red_offset -= crtl->stack_alignment_needed / BITS_PER_UNIT - + UNITS_PER_WORD; - else if (stack_realign_fp) - red_offset -= crtl->stack_alignment_needed / BITS_PER_UNIT - - UNITS_PER_WORD; - if (frame_pointer_needed) - red_offset -= UNITS_PER_WORD; - /* If we're only restoring one register and sp is not valid then using a move instruction to restore the register since it's less work than reloading sp and popping the register. @@ -8831,8 +8653,7 @@ ix86_expand_epilogue (int style) || (TARGET_EPILOGUE_USING_MOVE && cfun->machine->use_fast_prologue_epilogue && ((frame.nregs + frame.nsseregs) > 1 || frame.to_allocate)) - || (frame_pointer_needed && !(frame.nregs + frame.nsseregs) - && frame.to_allocate) + || (frame_pointer_needed && !(frame.nregs + frame.nsseregs) && frame.to_allocate) || (frame_pointer_needed && TARGET_USE_LEAVE && cfun->machine->use_fast_prologue_epilogue && (frame.nregs + frame.nsseregs) == 1) @@ -8852,32 +8673,22 @@ ix86_expand_epilogue (int style) || stack_realign_fp) { ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx, - frame.to_allocate, red_offset, - style == 2); + frame.to_allocate, style == 2); ix86_emit_restore_regs_using_mov (stack_pointer_rtx, frame.to_allocate + frame.nsseregs * 16 - + frame.padding0, - red_offset - + frame.nsseregs * 16 + frame.padding0, style == 2); } else { ix86_emit_restore_sse_regs_using_mov (hard_frame_pointer_rtx, - offset, red_offset, - style == 2); + offset, style == 2); ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx, offset + frame.nsseregs * 16 - + frame.padding0, - red_offset - + frame.nsseregs * 16 + frame.padding0, style == 2); } - red_offset -= offset; - /* eh_return epilogues need %ecx added to the stack pointer. */ if (style == 2) { @@ -8890,29 +8701,13 @@ ix86_expand_epilogue (int style) { tmp = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa); tmp = plus_constant (tmp, UNITS_PER_WORD); - tmp = emit_insn (gen_rtx_SET (VOIDmode, sa, tmp)); + emit_insn (gen_rtx_SET (VOIDmode, sa, tmp)); tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx); - tmp = emit_move_insn (hard_frame_pointer_rtx, tmp); - - /* Note that we use SA as a temporary CFA, as the return - address is at the proper place relative to it. We - pretend this happens at the FP restore insn because - prior to this insn the FP would be stored at the wrong - offset relative to SA, and after this insn we have no - other reasonable register to use for the CFA. We don't - bother resetting the CFA to the SP for the duration of - the return insn. */ - add_reg_note (tmp, REG_CFA_DEF_CFA, - plus_constant (sa, UNITS_PER_WORD)); - ix86_add_queued_cfa_restore_notes (tmp); - add_reg_note (tmp, REG_CFA_RESTORE, hard_frame_pointer_rtx); - RTX_FRAME_RELATED_P (tmp) = 1; - ix86_cfa_state->reg = sa; - ix86_cfa_state->offset = UNITS_PER_WORD; + emit_move_insn (hard_frame_pointer_rtx, tmp); pro_epilogue_adjust_stack (stack_pointer_rtx, sa, - const0_rtx, style, false); + const0_rtx, style); } else { @@ -8921,18 +8716,7 @@ ix86_expand_epilogue (int style) + frame.nregs * UNITS_PER_WORD + frame.nsseregs * 16 + frame.padding0)); - tmp = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp)); - ix86_add_queued_cfa_restore_notes (tmp); - - gcc_assert (ix86_cfa_state->reg == stack_pointer_rtx); - if (ix86_cfa_state->offset != UNITS_PER_WORD) - { - ix86_cfa_state->offset = UNITS_PER_WORD; - add_reg_note (tmp, REG_CFA_DEF_CFA, - plus_constant (stack_pointer_rtx, - UNITS_PER_WORD)); - RTX_FRAME_RELATED_P (tmp) = 1; - } + emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp)); } } else if (!frame_pointer_needed) @@ -8941,18 +8725,18 @@ ix86_expand_epilogue (int style) + frame.nregs * UNITS_PER_WORD + frame.nsseregs * 16 + frame.padding0), - style, !using_drap); + style); /* If not an i386, mov & pop is faster than "leave". */ else if (TARGET_USE_LEAVE || optimize_function_for_size_p (cfun) || !cfun->machine->use_fast_prologue_epilogue) - ix86_emit_leave (red_offset); + emit_insn ((*ix86_gen_leave) ()); else { pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, - const0_rtx, style, !using_drap); + const0_rtx, style); - ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx, red_offset); + emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx)); } } else @@ -8970,36 +8754,32 @@ ix86_expand_epilogue (int style) gcc_assert (!stack_realign_fp); pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, - GEN_INT (offset), style, false); + GEN_INT (offset), style); ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx, - frame.to_allocate, red_offset, - style == 2); + frame.to_allocate, style == 2); pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (frame.nsseregs * 16), - style, false); + GEN_INT (frame.nsseregs * 16), style); } else if (frame.to_allocate || frame.nsseregs) { ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx, - frame.to_allocate, red_offset, + frame.to_allocate, style == 2); pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (frame.to_allocate + frame.nsseregs * 16 - + frame.padding0), style, - !using_drap && !frame_pointer_needed); + + frame.padding0), style); } - ix86_emit_restore_regs_using_pop (red_offset + frame.nsseregs * 16 - + frame.padding0); - red_offset -= offset; - + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false)) + emit_insn ((*ix86_gen_pop1) (gen_rtx_REG (Pmode, regno))); if (frame_pointer_needed) { /* Leave results in shorter dependency chains on CPUs that are able to grok it fast. */ if (TARGET_USE_LEAVE) - ix86_emit_leave (red_offset); + emit_insn ((*ix86_gen_leave) ()); else { /* For stack realigned really happens, recover stack @@ -9008,71 +8788,47 @@ ix86_expand_epilogue (int style) if (stack_realign_fp) pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, - const0_rtx, style, !using_drap); - ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx, - red_offset); + const0_rtx, style); + emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx)); } } } - if (using_drap) + if (crtl->drap_reg && crtl->stack_realign_needed) { int param_ptr_offset = (call_used_regs[REGNO (crtl->drap_reg)] ? 0 : UNITS_PER_WORD); - rtx insn; - gcc_assert (stack_realign_drap); - - insn = emit_insn ((*ix86_gen_add3) (stack_pointer_rtx, - crtl->drap_reg, - GEN_INT (-(UNITS_PER_WORD - + param_ptr_offset)))); - - ix86_cfa_state->reg = stack_pointer_rtx; - ix86_cfa_state->offset = UNITS_PER_WORD + param_ptr_offset; - - add_reg_note (insn, REG_CFA_DEF_CFA, - gen_rtx_PLUS (Pmode, ix86_cfa_state->reg, - GEN_INT (ix86_cfa_state->offset))); - RTX_FRAME_RELATED_P (insn) = 1; - - if (param_ptr_offset) - ix86_emit_restore_reg_using_pop (crtl->drap_reg, -UNITS_PER_WORD); + emit_insn ((*ix86_gen_add3) (stack_pointer_rtx, + crtl->drap_reg, + GEN_INT (-(UNITS_PER_WORD + + param_ptr_offset)))); + if (!call_used_regs[REGNO (crtl->drap_reg)]) + emit_insn ((*ix86_gen_pop1) (crtl->drap_reg)); + } /* Sibcall epilogues don't want a return instruction. */ if (style == 0) - { - *ix86_cfa_state = cfa_state_save; - return; - } + return; if (crtl->args.pops_args && crtl->args.size) { rtx popc = GEN_INT (crtl->args.pops_args); - /* i386 can only pop 64K bytes. If asked to pop more, pop return - address, do explicit add, and jump indirectly to the caller. */ + /* i386 can only pop 64K bytes. If asked to pop more, pop + return address, do explicit add, and jump indirectly to the + caller. */ if (crtl->args.pops_args >= 65536) { rtx ecx = gen_rtx_REG (SImode, CX_REG); - rtx insn; /* There is no "pascal" calling convention in any 64bit ABI. */ gcc_assert (!TARGET_64BIT); - insn = emit_insn (gen_popsi1 (ecx)); - ix86_cfa_state->offset -= UNITS_PER_WORD; - - add_reg_note (insn, REG_CFA_ADJUST_CFA, - copy_rtx (XVECEXP (PATTERN (insn), 0, 1))); - add_reg_note (insn, REG_CFA_REGISTER, - gen_rtx_SET (VOIDmode, ecx, pc_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - - pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, - popc, -1, true); + emit_insn (gen_popsi1 (ecx)); + emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, popc)); emit_jump_insn (gen_return_indirect_internal (ecx)); } else @@ -9080,10 +8836,6 @@ ix86_expand_epilogue (int style) } else emit_jump_insn (gen_return_internal ()); - - /* Restore the state back to the state from the prologue, - so that it's correct for the next epilogue. */ - *ix86_cfa_state = cfa_state_save; } /* Reset from the function's potential modifications. */ @@ -30658,6 +30410,8 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary #undef TARGET_GET_DRAP_RTX #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx +#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC +#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec #undef TARGET_STRICT_ARGUMENT_NAMING #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true |