Commit df80dbec authored by Tobias Rapp's avatar Tobias Rapp
Browse files

amd64: Explicitly create function prologue/epilogue

parent 0c00302a
......@@ -684,27 +684,8 @@ static void emit_be_IncSP(const ir_node *node)
}
}
static void emit_amd64_Start(const ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
ir_type *frame_type = get_irg_frame_type(irg);
unsigned size = get_type_size_bytes(frame_type);
if (size > 0) {
amd64_emitf(node, "subq $%u, %%rsp", size);
}
}
static void emit_amd64_Return(const ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
ir_type *frame_type = get_irg_frame_type(irg);
unsigned size = get_type_size_bytes(frame_type);
if (size > 0) {
amd64_emitf(node, "addq $%u, %%rsp", size);
}
be_emit_cstring("\tret");
be_emit_finish_line_gas(node);
}
......@@ -725,7 +706,7 @@ static void amd64_register_emitters(void)
be_set_emitter(op_amd64_Jmp, emit_amd64_Jmp);
be_set_emitter(op_amd64_Mov, emit_amd64_Mov);
be_set_emitter(op_amd64_Return, emit_amd64_Return);
be_set_emitter(op_amd64_Start, emit_amd64_Start);
be_set_emitter(op_amd64_Start, be_emit_nothing);
be_set_emitter(op_amd64_SwitchJmp, emit_amd64_SwitchJmp);
be_set_emitter(op_be_Copy, emit_be_Copy);
be_set_emitter(op_be_CopyKeep, emit_be_Copy);
......
......@@ -326,6 +326,58 @@ static void amd64_collect_frame_entity_nodes(ir_node *node, void *data)
}
}
static void introduce_epilogue(ir_node *ret)
{
const arch_register_t *sp = &amd64_registers[REG_RSP];
ir_graph *irg = get_irn_irg(ret);
ir_node *start = get_irg_start(irg);
ir_node *block = get_nodes_block(start);
ir_type *frame_type = get_irg_frame_type(irg);
unsigned frame_size = get_type_size_bytes(frame_type);
be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
ir_node *first_sp = get_irn_n(ret, n_be_Return_sp);
ir_node *curr_sp = first_sp;
if(!layout->sp_relative) {
assert(false);
} else {
if (frame_size > 0) {
ir_node *incsp = be_new_IncSP(sp, block, curr_sp,
- (int) frame_size, 0);
sched_add_before(ret, incsp);
curr_sp = incsp;
}
}
set_irn_n(ret, n_be_Return_sp, curr_sp);
}
static void introduce_prologue_epilogue(ir_graph *irg)
{
const arch_register_t *sp = &amd64_registers[REG_RSP];
ir_node *start = get_irg_start(irg);
ir_node *block = get_nodes_block(start);
ir_type *frame_type = get_irg_frame_type(irg);
unsigned frame_size = get_type_size_bytes(frame_type);
be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
ir_node *initial_sp = be_get_initial_reg_value(irg, sp);
if (!layout->sp_relative) {
assert(false);
} else {
if (frame_size > 0) {
ir_node *const incsp = be_new_IncSP(sp, block, initial_sp,
frame_size, 0);
sched_add_after(start, incsp);
}
}
/* introduce epilogue for every return node */
foreach_irn_in(get_irg_end_block(irg), i, ret) {
assert(be_is_Return(ret) || is_amd64_Return(ret));
introduce_epilogue(ret);
}
}
/**
* Called immediatly before emit phase.
*/
......@@ -346,6 +398,8 @@ static void amd64_finish_graph(ir_graph *irg)
be_abi_fix_stack_nodes(irg);
be_abi_fix_stack_bias(irg);
introduce_prologue_epilogue(irg);
/* Fix 2-address code constraints. */
amd64_finish_irg(irg);
......
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