Line 93... |
Line 93... |
int gpr_size;
|
int gpr_size;
|
int gpr_offset;
|
int gpr_offset;
|
int total_size;
|
int total_size;
|
int vars_size;
|
int vars_size;
|
int args_size;
|
int args_size;
|
|
int gpr_frame;
|
|
int late_frame;
|
HOST_WIDE_INT mask;
|
HOST_WIDE_INT mask;
|
} frame_info;
|
} frame_info;
|
|
|
|
|
/* ========================================================================== */
|
/* ========================================================================== */
|
Line 156... |
Line 158... |
or32_compute_frame_size (HOST_WIDE_INT size)
|
or32_compute_frame_size (HOST_WIDE_INT size)
|
{
|
{
|
HOST_WIDE_INT args_size;
|
HOST_WIDE_INT args_size;
|
HOST_WIDE_INT vars_size;
|
HOST_WIDE_INT vars_size;
|
HOST_WIDE_INT stack_offset;
|
HOST_WIDE_INT stack_offset;
|
|
HOST_WIDE_INT save_size;
|
bool interrupt_p = false;
|
bool interrupt_p = false;
|
|
|
int regno;
|
int regno;
|
|
|
args_size = crtl->outgoing_args_size;
|
args_size = crtl->outgoing_args_size;
|
vars_size = OR32_ALIGN (size, 4);
|
vars_size = OR32_ALIGN (size, 4);
|
|
|
frame_info.args_size = args_size;
|
frame_info.args_size = args_size;
|
frame_info.vars_size = vars_size;
|
frame_info.vars_size = vars_size;
|
|
frame_info.gpr_frame = interrupt_p ? or32_redzone : 0;
|
|
|
/* If the function has local variables, we're committed to
|
/* If the function has local variables, we're committed to
|
allocating it anyway. Otherwise reclaim it here. */
|
allocating it anyway. Otherwise reclaim it here. */
|
/* FIXME: Verify this. Got if from the MIPS port. */
|
/* FIXME: Verify this. Got if from the MIPS port. */
|
if (vars_size == 0 && current_function_is_leaf)
|
if (vars_size == 0 && current_function_is_leaf)
|
Line 211... |
Line 215... |
frame_info.gpr_size += UNITS_PER_WORD;
|
frame_info.gpr_size += UNITS_PER_WORD;
|
frame_info.mask |= ((HOST_WIDE_INT) 1 << regno);
|
frame_info.mask |= ((HOST_WIDE_INT) 1 << regno);
|
}
|
}
|
}
|
}
|
|
|
frame_info.total_size = ((frame_info.save_fp_p ? UNITS_PER_WORD : 0)
|
save_size = (frame_info.gpr_size
|
+ (frame_info.save_lr_p ? UNITS_PER_WORD : 0)
|
+ (frame_info.save_fp_p ? UNITS_PER_WORD : 0)
|
+ args_size + frame_info.gpr_size + vars_size);
|
+ (frame_info.save_lr_p ? UNITS_PER_WORD : 0));
|
|
frame_info.total_size = save_size + vars_size + args_size;
|
gcc_assert (PROLOGUE_TMP != STATIC_CHAIN_REGNUM);
|
gcc_assert (PROLOGUE_TMP != STATIC_CHAIN_REGNUM);
|
if (frame_info.total_size > 32767 && interrupt_p)
|
if (frame_info.total_size > 32767 && interrupt_p)
|
{
|
{
|
int n_extra
|
int n_extra
|
= (!!(~frame_info.mask && 1 << PROLOGUE_TMP)
|
= (!!(~frame_info.mask && 1 << PROLOGUE_TMP)
|
+ !!(~frame_info.mask & 1 << EPILOGUE_TMP)) * UNITS_PER_WORD;
|
+ !!(~frame_info.mask & 1 << EPILOGUE_TMP)) * UNITS_PER_WORD;
|
|
|
|
save_size += n_extra;
|
frame_info.gpr_size += n_extra;
|
frame_info.gpr_size += n_extra;
|
frame_info.total_size += n_extra;
|
frame_info.total_size += n_extra;
|
frame_info.mask |= (1 << PROLOGUE_TMP) | (1 << EPILOGUE_TMP);
|
frame_info.mask |= (1 << PROLOGUE_TMP) | (1 << EPILOGUE_TMP);
|
}
|
}
|
|
|
stack_offset -= frame_info.gpr_size;
|
stack_offset -= frame_info.gpr_size;
|
frame_info.gpr_offset = stack_offset;
|
frame_info.gpr_offset = stack_offset;
|
|
frame_info.late_frame = frame_info.total_size;
|
|
|
|
if (save_size > or32_redzone
|
|
|| (frame_info.gpr_frame
|
|
&& (frame_info.gpr_frame + frame_info.late_frame <= 32767)))
|
|
{
|
|
if (frame_info.gpr_frame + frame_info.late_frame <= 32767)
|
|
save_size = frame_info.total_size;
|
|
frame_info.gpr_frame += save_size;
|
|
frame_info.lr_save_offset += save_size;
|
|
frame_info.fp_save_offset += save_size;
|
|
frame_info.gpr_offset += save_size;
|
|
frame_info.late_frame -= save_size;
|
|
/* FIXME: check in TARGET_OVERRIDE_OPTIONS for invalid or32_redzone. */
|
|
gcc_assert (frame_info.gpr_frame <= 32767);
|
|
gcc_assert ((frame_info.gpr_frame & 3) == 0);
|
|
}
|
|
|
return frame_info.total_size;
|
return frame_info.total_size;
|
|
|
} /* or32_compute_frame_size () */
|
} /* or32_compute_frame_size () */
|
|
|
Line 618... |
Line 641... |
|
|
if (!total_size)
|
if (!total_size)
|
/* No frame needed. */
|
/* No frame needed. */
|
return;
|
return;
|
|
|
|
if (frame_info.gpr_frame)
|
|
emit_frame_insn (gen_add2_insn (stack_pointer_rtx,
|
|
GEN_INT (-frame_info.gpr_frame)));
|
if (frame_info.save_fp_p)
|
if (frame_info.save_fp_p)
|
{
|
{
|
emit_frame_insn (gen_rtx_SET (Pmode,
|
emit_frame_insn (gen_rtx_SET (Pmode,
|
stack_disp_mem (frame_info.fp_save_offset),
|
stack_disp_mem (frame_info.fp_save_offset),
|
hard_frame_pointer_rtx));
|
hard_frame_pointer_rtx));
|
Line 653... |
Line 679... |
offset = offset + UNITS_PER_WORD;
|
offset = offset + UNITS_PER_WORD;
|
}
|
}
|
}
|
}
|
|
|
/* Update the stack pointer to reflect frame size. */
|
/* Update the stack pointer to reflect frame size. */
|
|
total_size = frame_info.late_frame;
|
insn = gen_add2_insn (stack_pointer_rtx, GEN_INT (-total_size));
|
insn = gen_add2_insn (stack_pointer_rtx, GEN_INT (-total_size));
|
if (total_size > 32767)
|
if (total_size > 32768)
|
{
|
{
|
rtx note = insn;
|
rtx note = insn;
|
rtx value_rtx = gen_rtx_REG (Pmode, PROLOGUE_TMP);
|
rtx value_rtx = gen_rtx_REG (Pmode, PROLOGUE_TMP);
|
|
|
or32_emit_set_const32 (value_rtx, GEN_INT (-total_size));
|
or32_emit_set_const32 (value_rtx, GEN_INT (-total_size));
|
insn = emit_frame_insn (gen_add2_insn (stack_pointer_rtx, value_rtx));
|
insn = emit_frame_insn (gen_add2_insn (stack_pointer_rtx, value_rtx));
|
add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
|
add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
|
}
|
}
|
else
|
else if (total_size)
|
emit_frame_insn (insn);
|
emit_frame_insn (insn);
|
|
|
} /* or32_expand_prologue () */
|
} /* or32_expand_prologue () */
|
|
|
|
|
Line 709... |
Line 736... |
else
|
else
|
gcc_assert (CONSTANT_P (sibcall));
|
gcc_assert (CONSTANT_P (sibcall));
|
}
|
}
|
if (frame_info.save_fp_p)
|
if (frame_info.save_fp_p)
|
{
|
{
|
emit_insn
|
emit_insn (gen_frame_dealloc_fp ());
|
(gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, const0_rtx));
|
|
emit_insn
|
emit_insn
|
(gen_rtx_SET (Pmode, hard_frame_pointer_rtx,
|
(gen_rtx_SET (Pmode, hard_frame_pointer_rtx,
|
stack_disp_mem (frame_info.fp_save_offset)));
|
stack_disp_mem (frame_info.fp_save_offset)));
|
}
|
}
|
else
|
else
|
{
|
{
|
rtx value_rtx;
|
rtx value_rtx;
|
|
|
|
total_size = frame_info.late_frame;
|
if (total_size > 32767)
|
if (total_size > 32767)
|
{
|
{
|
value_rtx = gen_rtx_REG (Pmode, EPILOGUE_TMP);
|
value_rtx = gen_rtx_REG (Pmode, EPILOGUE_TMP);
|
or32_emit_set_const32 (value_rtx, GEN_INT (total_size));
|
or32_emit_set_const32 (value_rtx, GEN_INT (total_size));
|
}
|
}
|
else
|
else if (frame_info.late_frame)
|
value_rtx = GEN_INT (total_size);
|
value_rtx = GEN_INT (total_size);
|
if (total_size)
|
if (total_size)
|
emit_insn (gen_add2_insn (stack_pointer_rtx, value_rtx));
|
emit_insn (gen_frame_dealloc_sp (value_rtx));
|
}
|
}
|
|
|
if (frame_info.save_lr_p)
|
if (frame_info.save_lr_p)
|
{
|
{
|
emit_insn
|
emit_insn
|
Line 755... |
Line 782... |
stack_disp_mem (frame_info.gpr_offset + offset)));
|
stack_disp_mem (frame_info.gpr_offset + offset)));
|
offset = offset + UNITS_PER_WORD;
|
offset = offset + UNITS_PER_WORD;
|
}
|
}
|
}
|
}
|
|
|
|
if (frame_info.gpr_frame)
|
|
emit_insn (gen_add2_insn (stack_pointer_rtx,
|
|
GEN_INT (frame_info.gpr_frame)));
|
if (!sibcall)
|
if (!sibcall)
|
emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, 9)));
|
emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, 9)));
|
|
|
} /* or32_expand_epilogue () */
|
} /* or32_expand_epilogue () */
|
|
|
Line 1535... |
Line 1565... |
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
static bool
|
static bool
|
or32_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
|
or32_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
|
tree exp ATTRIBUTE_UNUSED)
|
tree exp ATTRIBUTE_UNUSED)
|
{
|
{
|
return true;
|
/* Assume up to 31 registers of 4 bytes might be saved. */
|
|
return or32_redzone >= 31 * 4;
|
} /* or32_function_ok_for_sibcall () */
|
} /* or32_function_ok_for_sibcall () */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
/*!Should an argument be passed by reference.
|
/*!Should an argument be passed by reference.
|
Line 1620... |
Line 1651... |
#endif
|
#endif
|
|
|
int
|
int
|
or32_initial_elimination_offset(int from, int to)
|
or32_initial_elimination_offset(int from, int to)
|
{
|
{
|
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
|
|
return 0;
|
|
or32_compute_frame_size (get_frame_size ());
|
or32_compute_frame_size (get_frame_size ());
|
return ((from == FRAME_POINTER_REGNUM ? frame_info.gpr_offset : 0)
|
return ((from == FRAME_POINTER_REGNUM
|
+ (to == STACK_POINTER_REGNUM ? frame_info.total_size : 0));
|
? frame_info.gpr_offset : frame_info.gpr_frame)
|
|
+ (to == STACK_POINTER_REGNUM ? frame_info.late_frame : 0));
|
}
|
}
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
/*!How many bytes at the beginning of an argument must be put into registers.
|
/*!How many bytes at the beginning of an argument must be put into registers.
|