Commit 4dd2ac2c by Jan Hubicka Committed by Jan Hubicka

i386.c (ix86_frame): New structure.

	* i386.c (ix86_frame): New structure.
	(ix86_compute_frame_size): Kill.
	(ix86_compute_frame_layout): New.
	(ix86_save_reg): New.
	(ix86_can_use_return_insn_p): Use frame layout stuff.
	(ix86_expand_prologue): Likewise.
	(ix86_expand_epilogue): Likewise.
	(ix86_initial_elimination_offset): Likewise.
	(ix86_nsaved_regs): Use ix86_save_reg.
	(ix86_emit_save_regs): Likewise.

From-SVN: r40022
parent a686dbf8
Sat Feb 24 03:32:50 CET 2001 Jan Hubicka <jh@suse.cz>
* i386.c (ix86_frame): New structure.
(ix86_compute_frame_size): Kill.
(ix86_compute_frame_layout): New.
(ix86_save_reg): New.
(ix86_can_use_return_insn_p): Use frame layout stuff.
(ix86_expand_prologue): Likewise.
(ix86_expand_epilogue): Likewise.
(ix86_initial_elimination_offset): Likewise.
(ix86_nsaved_regs): Use ix86_save_reg.
(ix86_emit_save_regs): Likewise.
Sat Feb 24 03:30:38 CET 2001 Jan Hubicka <jh@suse.cz> Sat Feb 24 03:30:38 CET 2001 Jan Hubicka <jh@suse.cz>
* flow.c (find_sub_basic_blocks): New function. * flow.c (find_sub_basic_blocks): New function.
......
...@@ -402,6 +402,40 @@ struct machine_function ...@@ -402,6 +402,40 @@ struct machine_function
#define ix86_stack_locals (cfun->machine->stack_locals) #define ix86_stack_locals (cfun->machine->stack_locals)
/* Structure describing stack frame layout.
Stack grows downward:
[arguments]
<- ARG_POINTER
saved pc
saved frame pointer if frame_pointer_needed
<- HARD_FRAME_POINTER
[saved regs]
[padding1] \
)
[va_arg registers] (
> to_allocate <- FRAME_POINTER
[frame] (
)
[padding2] /
*/
struct ix86_frame
{
int nregs;
int padding1;
HOST_WIDE_INT frame;
int padding2;
int outgoing_arguments_size;
HOST_WIDE_INT to_allocate;
/* The offsets relative to ARG_POINTER. */
HOST_WIDE_INT frame_pointer_offset;
HOST_WIDE_INT hard_frame_pointer_offset;
HOST_WIDE_INT stack_pointer_offset;
};
/* which cpu are we scheduling for */ /* which cpu are we scheduling for */
enum processor_type ix86_cpu; enum processor_type ix86_cpu;
...@@ -469,8 +503,6 @@ static void ix86_mark_machine_status PARAMS ((struct function *)); ...@@ -469,8 +503,6 @@ static void ix86_mark_machine_status PARAMS ((struct function *));
static void ix86_free_machine_status PARAMS ((struct function *)); static void ix86_free_machine_status PARAMS ((struct function *));
static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode)); static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
static int ix86_safe_length_prefix PARAMS ((rtx)); static int ix86_safe_length_prefix PARAMS ((rtx));
static HOST_WIDE_INT ix86_compute_frame_size PARAMS((HOST_WIDE_INT,
int *, int *, int *));
static int ix86_nsaved_regs PARAMS((void)); static int ix86_nsaved_regs PARAMS((void));
static void ix86_emit_save_regs PARAMS((void)); static void ix86_emit_save_regs PARAMS((void));
static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int)); static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int));
...@@ -508,6 +540,8 @@ static int ix86_fp_comparison_arithmetics_cost PARAMS ((enum rtx_code code)); ...@@ -508,6 +540,8 @@ static int ix86_fp_comparison_arithmetics_cost PARAMS ((enum rtx_code code));
static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code)); static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code)); static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code)); static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
static int ix86_save_reg PARAMS ((int));
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
/* Sometimes certain combinations of command options do not make /* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro sense on a particular target machine. You can define a macro
...@@ -1667,8 +1701,7 @@ symbolic_reference_mentioned_p (op) ...@@ -1667,8 +1701,7 @@ symbolic_reference_mentioned_p (op)
int int
ix86_can_use_return_insn_p () ix86_can_use_return_insn_p ()
{ {
HOST_WIDE_INT tsize; struct ix86_frame frame;
int nregs;
#ifdef NON_SAVING_SETJMP #ifdef NON_SAVING_SETJMP
if (NON_SAVING_SETJMP && current_function_calls_setjmp) if (NON_SAVING_SETJMP && current_function_calls_setjmp)
...@@ -1688,8 +1721,8 @@ ix86_can_use_return_insn_p () ...@@ -1688,8 +1721,8 @@ ix86_can_use_return_insn_p ()
&& current_function_args_size >= 32768) && current_function_args_size >= 32768)
return 0; return 0;
tsize = ix86_compute_frame_size (get_frame_size (), &nregs, NULL, NULL); ix86_compute_frame_layout (&frame);
return tsize == 0 && nregs == 0; return frame.to_allocate == 0 && frame.nregs == 0;
} }
/* Value should be nonzero if functions must have frame pointers. /* Value should be nonzero if functions must have frame pointers.
...@@ -1817,24 +1850,31 @@ gen_push (arg) ...@@ -1817,24 +1850,31 @@ gen_push (arg)
arg); arg);
} }
/* Return 1 if we need to save REGNO. */
static int
ix86_save_reg (regno)
int regno;
{
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
return ((regs_ever_live[regno] && !call_used_regs[regno]
&& !fixed_regs[regno]
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used));
}
/* Return number of registers to be saved on the stack. */ /* Return number of registers to be saved on the stack. */
static int static int
ix86_nsaved_regs () ix86_nsaved_regs ()
{ {
int nregs = 0; int nregs = 0;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
int limit = (frame_pointer_needed
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
int regno; int regno;
for (regno = limit - 1; regno >= 0; regno--) for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
if ((regs_ever_live[regno] && ! call_used_regs[regno]) if (ix86_save_reg (regno))
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) nregs++;
{
nregs ++;
}
return nregs; return nregs;
} }
...@@ -1846,82 +1886,46 @@ ix86_initial_elimination_offset (from, to) ...@@ -1846,82 +1886,46 @@ ix86_initial_elimination_offset (from, to)
int from; int from;
int to; int to;
{ {
int padding1; struct ix86_frame frame;
int nregs; ix86_compute_frame_layout (&frame);
/* Stack grows downward:
[arguments]
<- ARG_POINTER
saved pc
saved frame pointer if frame_pointer_needed
<- HARD_FRAME_POINTER
[saved regs]
[padding1] \
| <- FRAME_POINTER
[frame] > tsize
|
[padding2] /
*/
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
/* Skip saved PC and previous frame pointer. return frame.hard_frame_pointer_offset;
Executed only when frame_pointer_needed. */
return 8;
else if (from == FRAME_POINTER_REGNUM else if (from == FRAME_POINTER_REGNUM
&& to == HARD_FRAME_POINTER_REGNUM) && to == HARD_FRAME_POINTER_REGNUM)
{ return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
ix86_compute_frame_size (get_frame_size (), &nregs, &padding1, (int *) 0);
padding1 += nregs * UNITS_PER_WORD;
return -padding1;
}
else else
{ {
/* ARG_POINTER or FRAME_POINTER to STACK_POINTER elimination. */
int frame_size = frame_pointer_needed ? 8 : 4;
HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (),
&nregs, &padding1, (int *) 0);
if (to != STACK_POINTER_REGNUM) if (to != STACK_POINTER_REGNUM)
abort (); abort ();
else if (from == ARG_POINTER_REGNUM) else if (from == ARG_POINTER_REGNUM)
return tsize + nregs * UNITS_PER_WORD + frame_size; return frame.stack_pointer_offset;
else if (from != FRAME_POINTER_REGNUM) else if (from != FRAME_POINTER_REGNUM)
abort (); abort ();
else else
return tsize - padding1; return frame.stack_pointer_offset - frame.frame_pointer_offset;
} }
} }
/* Compute the size of local storage taking into consideration the /* Fill structure ix86_frame about frame of currently computed function. */
desired stack alignment which is to be maintained. Also determine
the number of registers saved below the local storage.
PADDING1 returns padding before stack frame and PADDING2 returns static void
padding after stack frame; ix86_compute_frame_layout (frame)
*/ struct ix86_frame *frame;
static HOST_WIDE_INT
ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2)
HOST_WIDE_INT size;
int *nregs_on_stack;
int *rpadding1;
int *rpadding2;
{ {
int nregs;
int padding1 = 0;
int padding2 = 0;
HOST_WIDE_INT total_size; HOST_WIDE_INT total_size;
int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT; int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
int offset; int offset;
int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT; int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
HOST_WIDE_INT size = get_frame_size ();
nregs = ix86_nsaved_regs (); frame->nregs = ix86_nsaved_regs ();
total_size = size; total_size = size;
offset = frame_pointer_needed ? 8 : 4; /* Skip return value and save base pointer. */
offset = frame_pointer_needed ? UNITS_PER_WORD * 2 : UNITS_PER_WORD;
frame->hard_frame_pointer_offset = offset;
/* Do some sanity checking of stack_alignment_needed and /* Do some sanity checking of stack_alignment_needed and
preferred_alignment, since i386 port is the only using those features preferred_alignment, since i386 port is the only using those features
...@@ -1936,36 +1940,58 @@ ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2) ...@@ -1936,36 +1940,58 @@ ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2)
if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
abort (); abort ();
if (stack_alignment_needed < 4) if (stack_alignment_needed < STACK_BOUNDARY / BITS_PER_UNIT)
stack_alignment_needed = 4; stack_alignment_needed = STACK_BOUNDARY / BITS_PER_UNIT;
offset += nregs * UNITS_PER_WORD; /* Register save area */
offset += frame->nregs * UNITS_PER_WORD;
if (ACCUMULATE_OUTGOING_ARGS) /* Align start of frame for local function. */
total_size += current_function_outgoing_args_size; frame->padding1 = ((offset + stack_alignment_needed - 1)
& -stack_alignment_needed) - offset;
total_size += offset; offset += frame->padding1;
/* Align start of frame for local function. */ /* Frame pointer points here. */
padding1 = ((offset + stack_alignment_needed - 1) frame->frame_pointer_offset = offset;
& -stack_alignment_needed) - offset;
total_size += padding1;
/* Align stack boundary. */ offset += size;
padding2 = ((total_size + preferred_alignment - 1)
& -preferred_alignment) - total_size;
/* Add outgoing arguments area. */
if (ACCUMULATE_OUTGOING_ARGS) if (ACCUMULATE_OUTGOING_ARGS)
padding2 += current_function_outgoing_args_size; {
offset += current_function_outgoing_args_size;
if (nregs_on_stack) frame->outgoing_arguments_size = current_function_outgoing_args_size;
*nregs_on_stack = nregs; }
if (rpadding1) else
*rpadding1 = padding1; frame->outgoing_arguments_size = 0;
if (rpadding2)
*rpadding2 = padding2;
return size + padding1 + padding2; /* Align stack boundary. */
frame->padding2 = ((offset + preferred_alignment - 1)
& -preferred_alignment) - offset;
offset += frame->padding2;
/* We've reached end of stack frame. */
frame->stack_pointer_offset = offset;
/* Size prologue needs to allocate. */
frame->to_allocate =
(size + frame->padding1 + frame->padding2
+ frame->outgoing_arguments_size);
#if 0
fprintf (stderr, "nregs: %i\n", frame->nregs);
fprintf (stderr, "size: %i\n", size);
fprintf (stderr, "alignment1: %i\n", stack_alignment_needed);
fprintf (stderr, "padding1: %i\n", frame->padding1);
fprintf (stderr, "padding2: %i\n", frame->padding2);
fprintf (stderr, "to_allocate: %i\n", frame->to_allocate);
fprintf (stderr, "frame_pointer_offset: %i\n", frame->frame_pointer_offset);
fprintf (stderr, "hard_frame_pointer_offset: %i\n",
frame->hard_frame_pointer_offset);
fprintf (stderr, "stack_pointer_offset: %i\n", frame->stack_pointer_offset);
#endif
} }
/* Emit code to save registers in the prologue. */ /* Emit code to save registers in the prologue. */
...@@ -1974,16 +2000,10 @@ static void ...@@ -1974,16 +2000,10 @@ static void
ix86_emit_save_regs () ix86_emit_save_regs ()
{ {
register int regno; register int regno;
int limit;
rtx insn; rtx insn;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
limit = (frame_pointer_needed
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
for (regno = limit - 1; regno >= 0; regno--) for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
if ((regs_ever_live[regno] && !call_used_regs[regno]) if (ix86_save_reg (regno))
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
{ {
insn = emit_insn (gen_push (gen_rtx_REG (SImode, regno))); insn = emit_insn (gen_push (gen_rtx_REG (SImode, regno)));
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
...@@ -1995,11 +2015,12 @@ ix86_emit_save_regs () ...@@ -1995,11 +2015,12 @@ ix86_emit_save_regs ()
void void
ix86_expand_prologue () ix86_expand_prologue ()
{ {
HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *) 0,
(int *) 0, (int *) 0);
rtx insn; rtx insn;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool); || current_function_uses_const_pool);
struct ix86_frame frame;
ix86_compute_frame_layout (&frame);
/* Note: AT&T enter does NOT have reversed args. Enter is probably /* Note: AT&T enter does NOT have reversed args. Enter is probably
slower on all targets. Also sdb doesn't like it. */ slower on all targets. Also sdb doesn't like it. */
...@@ -2015,17 +2036,17 @@ ix86_expand_prologue () ...@@ -2015,17 +2036,17 @@ ix86_expand_prologue ()
ix86_emit_save_regs (); ix86_emit_save_regs ();
if (tsize == 0) if (frame.to_allocate == 0)
; ;
else if (! TARGET_STACK_PROBE || tsize < CHECK_STACK_LIMIT) else if (! TARGET_STACK_PROBE || frame.to_allocate < CHECK_STACK_LIMIT)
{ {
if (frame_pointer_needed) if (frame_pointer_needed)
insn = emit_insn (gen_pro_epilogue_adjust_stack insn = emit_insn (gen_pro_epilogue_adjust_stack
(stack_pointer_rtx, stack_pointer_rtx, (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-tsize), hard_frame_pointer_rtx)); GEN_INT (-frame.to_allocate), hard_frame_pointer_rtx));
else else
insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-tsize))); GEN_INT (-frame.to_allocate)));
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
else else
...@@ -2035,7 +2056,7 @@ ix86_expand_prologue () ...@@ -2035,7 +2056,7 @@ ix86_expand_prologue ()
rtx arg0, sym; rtx arg0, sym;
arg0 = gen_rtx_REG (SImode, 0); arg0 = gen_rtx_REG (SImode, 0);
emit_move_insn (arg0, GEN_INT (tsize)); emit_move_insn (arg0, GEN_INT (frame.to_allocate));
sym = gen_rtx_MEM (FUNCTION_MODE, sym = gen_rtx_MEM (FUNCTION_MODE,
gen_rtx_SYMBOL_REF (Pmode, "_alloca")); gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
...@@ -2087,20 +2108,15 @@ ix86_emit_restore_regs_using_mov (pointer, offset) ...@@ -2087,20 +2108,15 @@ ix86_emit_restore_regs_using_mov (pointer, offset)
int offset; int offset;
{ {
int regno; int regno;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
int limit = (frame_pointer_needed
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
for (regno = 0; regno < limit; regno++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if ((regs_ever_live[regno] && !call_used_regs[regno]) if (ix86_save_reg (regno))
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
{ {
emit_move_insn (gen_rtx_REG (SImode, regno), emit_move_insn (gen_rtx_REG (Pmode, regno),
adj_offsettable_operand (gen_rtx_MEM (SImode, adj_offsettable_operand (gen_rtx_MEM (Pmode,
pointer), pointer),
offset)); offset));
offset += 4; offset += UNITS_PER_WORD;
} }
} }
...@@ -2110,18 +2126,15 @@ void ...@@ -2110,18 +2126,15 @@ void
ix86_expand_epilogue (emit_return) ix86_expand_epilogue (emit_return)
int emit_return; int emit_return;
{ {
int nregs;
int regno; int regno;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging; int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
struct ix86_frame frame;
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), &nregs,
(int *) 0, (int *) 0); ix86_compute_frame_layout (&frame);
/* Calculate start of saved registers relative to ebp. */ /* Calculate start of saved registers relative to ebp. */
offset = -nregs * UNITS_PER_WORD; offset = -frame.nregs * UNITS_PER_WORD;
#ifdef FUNCTION_BLOCK_PROFILER_EXIT #ifdef FUNCTION_BLOCK_PROFILER_EXIT
if (profile_block_flag == 2) if (profile_block_flag == 2)
...@@ -2140,10 +2153,10 @@ ix86_expand_epilogue (emit_return) ...@@ -2140,10 +2153,10 @@ ix86_expand_epilogue (emit_return)
are no registers to restore. We also use this code when TARGET_USE_LEAVE are no registers to restore. We also use this code when TARGET_USE_LEAVE
and there is exactly one register to pop. This heruistic may need some and there is exactly one register to pop. This heruistic may need some
tuning in future. */ tuning in future. */
if ((!sp_valid && nregs <= 1) if ((!sp_valid && frame.nregs <= 1)
|| (frame_pointer_needed && !nregs && tsize) || (frame_pointer_needed && !frame.nregs && frame.to_allocate)
|| (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size || (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size
&& nregs == 1)) && frame.nregs == 1))
{ {
/* Restore registers. We can use ebp or esp to address the memory /* Restore registers. We can use ebp or esp to address the memory
locations. If both are available, default to ebp, since offsets locations. If both are available, default to ebp, since offsets
...@@ -2151,13 +2164,14 @@ ix86_expand_epilogue (emit_return) ...@@ -2151,13 +2164,14 @@ ix86_expand_epilogue (emit_return)
end of block of saved registers, where we may simplify addressing end of block of saved registers, where we may simplify addressing
mode. */ mode. */
if (!frame_pointer_needed || (sp_valid && !tsize)) if (!frame_pointer_needed || (sp_valid && !frame.to_allocate))
ix86_emit_restore_regs_using_mov (stack_pointer_rtx, tsize); ix86_emit_restore_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
else else
ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx, offset); ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx, offset);
if (!frame_pointer_needed) if (!frame_pointer_needed)
ix86_emit_epilogue_esp_adjustment (tsize + nregs * UNITS_PER_WORD); ix86_emit_epilogue_esp_adjustment (frame.to_allocate
+ frame.nregs * UNITS_PER_WORD);
/* If not an i386, mov & pop is faster than "leave". */ /* If not an i386, mov & pop is faster than "leave". */
else if (TARGET_USE_LEAVE || optimize_size) else if (TARGET_USE_LEAVE || optimize_size)
emit_insn (gen_leave ()); emit_insn (gen_leave ());
...@@ -2183,13 +2197,14 @@ ix86_expand_epilogue (emit_return) ...@@ -2183,13 +2197,14 @@ ix86_expand_epilogue (emit_return)
GEN_INT (offset), GEN_INT (offset),
hard_frame_pointer_rtx)); hard_frame_pointer_rtx));
} }
else if (tsize) else if (frame.to_allocate)
ix86_emit_epilogue_esp_adjustment (tsize); ix86_emit_epilogue_esp_adjustment (frame.to_allocate);
for (regno = 0; regno < STACK_POINTER_REGNUM; regno++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if ((regs_ever_live[regno] && !call_used_regs[regno]) if (ix86_save_reg (regno))
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
emit_insn (gen_popsi1 (gen_rtx_REG (SImode, regno))); emit_insn (gen_popsi1 (gen_rtx_REG (SImode, regno)));
if (frame_pointer_needed)
emit_insn (gen_popsi1 (hard_frame_pointer_rtx));
} }
/* Sibcall epilogues don't want a return instruction. */ /* Sibcall epilogues don't want a return instruction. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment