Commit aa373839 authored by Matthias Braun's avatar Matthias Braun
Browse files

sparc: Fix omit-fp mode

parent aff3fec9
...@@ -903,31 +903,25 @@ static void memperm_emit_restore_registers(const ir_node *node, int n_spilled) ...@@ -903,31 +903,25 @@ static void memperm_emit_restore_registers(const ir_node *node, int n_spilled)
sparc_emitf(node, "add %%sp, %u, %%sp", sp_change); sparc_emitf(node, "add %%sp, %u, %%sp", sp_change);
} }
static int get_real_entity_offset(const ir_node *node, ir_entity *ent)
{
int offset = be_get_MemPerm_offset(node);
return get_entity_offset(ent) + offset;
}
static void memperm_emit_copy(const ir_node *node, ir_entity *in_ent, static void memperm_emit_copy(const ir_node *node, ir_entity *in_ent,
ir_entity *out_ent) ir_entity *out_ent, int ent_offset)
{ {
ir_graph *irg = get_irn_irg(node); ir_graph *irg = get_irn_irg(node);
const char *reg = sparc_get_irg_data(irg)->omit_fp ? "sp" : "fp"; const char *reg = sparc_get_irg_data(irg)->omit_fp ? "sp" : "fp";
const int off_in = get_real_entity_offset(node, in_ent); const int off_in = get_entity_offset(in_ent) + ent_offset;
const int off_out = get_real_entity_offset(node, out_ent); const int off_out = get_entity_offset(out_ent) + ent_offset;
sparc_emitf(node, "ld [%%%s%+d], %%l0", reg, off_in); sparc_emitf(node, "ld [%%%s%+d], %%l0", reg, off_in);
sparc_emitf(node, "st %%l0, [%%%s%+d]", reg, off_out); sparc_emitf(node, "st %%l0, [%%%s%+d]", reg, off_out);
} }
static void memperm_emit_swap(const ir_node *node, ir_entity *ent1, static void memperm_emit_swap(const ir_node *node, ir_entity *ent1,
ir_entity *ent2) ir_entity *ent2, int ent_offset)
{ {
ir_graph *irg = get_irn_irg(node); ir_graph *irg = get_irn_irg(node);
const char *reg = sparc_get_irg_data(irg)->omit_fp ? "sp" : "fp"; const char *reg = sparc_get_irg_data(irg)->omit_fp ? "sp" : "fp";
const int off1 = get_real_entity_offset(node, ent1); const int off1 = get_entity_offset(ent1) + ent_offset;
const int off2 = get_real_entity_offset(node, ent2); const int off2 = get_entity_offset(ent2) + ent_offset;
sparc_emitf(node, "ld [%%%s%+d], %%l0", reg, off1); sparc_emitf(node, "ld [%%%s%+d], %%l0", reg, off1);
sparc_emitf(node, "ld [%%%s%+d], %%l1", reg, off2); sparc_emitf(node, "ld [%%%s%+d], %%l1", reg, off2);
...@@ -967,6 +961,10 @@ static void emit_be_MemPerm(const ir_node *node) ...@@ -967,6 +961,10 @@ static void emit_be_MemPerm(const ir_node *node)
int *n_users = ALLOCANZ(int, max_size); int *n_users = ALLOCANZ(int, max_size);
/* n_spilled records the number of spilled registers, either 1 or 2. */ /* n_spilled records the number of spilled registers, either 1 or 2. */
int n_spilled = 0; int n_spilled = 0;
ir_graph *irg = get_irn_irg(node);
bool omit_fp = sparc_get_irg_data(irg)->omit_fp;
int ent_offset = be_get_MemPerm_offset(node);
for (int i = 0; i < max_size; ++i) { for (int i = 0; i < max_size; ++i) {
sourceof[i] = i; sourceof[i] = i;
...@@ -1006,8 +1004,10 @@ static void emit_be_MemPerm(const ir_node *node) ...@@ -1006,8 +1004,10 @@ static void emit_be_MemPerm(const ir_node *node)
if (n_spilled == 0) { if (n_spilled == 0) {
memperm_emit_spill_registers(node, n_spilled, /*n_to_spill=*/1); memperm_emit_spill_registers(node, n_spilled, /*n_to_spill=*/1);
n_spilled = 1; n_spilled = 1;
if (omit_fp)
ent_offset += 8;
} }
memperm_emit_copy(node, entities[iidx], entities[oidx]); memperm_emit_copy(node, entities[iidx], entities[oidx], ent_offset);
/* Mark as done. */ /* Mark as done. */
sourceof[oidx] = oidx; sourceof[oidx] = oidx;
...@@ -1037,7 +1037,7 @@ static void emit_be_MemPerm(const ir_node *node) ...@@ -1037,7 +1037,7 @@ static void emit_be_MemPerm(const ir_node *node)
memperm_emit_spill_registers(node, n_spilled, /*n_to_spill=*/2); memperm_emit_spill_registers(node, n_spilled, /*n_to_spill=*/2);
n_spilled = 2; n_spilled = 2;
} }
memperm_emit_swap(node, entities[iidx], entities[oidx]); memperm_emit_swap(node, entities[iidx], entities[oidx], ent_offset);
int tidx = sourceof[iidx]; int tidx = sourceof[iidx];
sourceof[iidx] = iidx; /* Mark as done. */ sourceof[iidx] = iidx; /* Mark as done. */
......
...@@ -85,8 +85,7 @@ static void introduce_epilog(ir_node *ret, bool omit_fp) ...@@ -85,8 +85,7 @@ static void introduce_epilog(ir_node *ret, bool omit_fp)
kill_unused_stacknodes(sp); kill_unused_stacknodes(sp);
} else { } else {
ir_type *const frame_type = get_irg_frame_type(irg); ir_type *const frame_type = get_irg_frame_type(irg);
unsigned const frame_size = get_type_size(frame_type) unsigned const frame_size = get_type_size(frame_type);
+ SPARC_MIN_STACKSIZE;
ir_node *const incsp = be_new_IncSP(sp_reg, block, sp, -frame_size, ir_node *const incsp = be_new_IncSP(sp_reg, block, sp, -frame_size,
true); true);
set_irn_n(ret, n_sparc_Return_sp, incsp); set_irn_n(ret, n_sparc_Return_sp, incsp);
...@@ -101,8 +100,7 @@ static void sparc_introduce_prolog_epilog(ir_graph *irg, bool omit_fp) ...@@ -101,8 +100,7 @@ static void sparc_introduce_prolog_epilog(ir_graph *irg, bool omit_fp)
ir_node *block = get_nodes_block(start); ir_node *block = get_nodes_block(start);
ir_node *initial_sp = be_get_Start_proj(irg, sp_reg); ir_node *initial_sp = be_get_Start_proj(irg, sp_reg);
ir_type *frame_type = get_irg_frame_type(irg); ir_type *frame_type = get_irg_frame_type(irg);
unsigned frame_size = get_type_size(frame_type) unsigned frame_size = get_type_size(frame_type);
+ SPARC_MIN_STACKSIZE;
/* introduce epilog for every return node */ /* introduce epilog for every return node */
foreach_irn_in(get_irg_end_block(irg), i, ret) { foreach_irn_in(get_irg_end_block(irg), i, ret) {
...@@ -111,7 +109,8 @@ static void sparc_introduce_prolog_epilog(ir_graph *irg, bool omit_fp) ...@@ -111,7 +109,8 @@ static void sparc_introduce_prolog_epilog(ir_graph *irg, bool omit_fp)
} }
if (!omit_fp) { if (!omit_fp) {
ir_node *const save = new_bd_sparc_Save_imm(NULL, block, initial_sp, NULL, -frame_size); ir_node *const save = new_bd_sparc_Save_imm(NULL, block, initial_sp,
NULL, -frame_size-SPARC_MIN_STACKSIZE);
arch_set_irn_register(save, sp_reg); arch_set_irn_register(save, sp_reg);
sched_add_after(start, save); sched_add_after(start, save);
......
...@@ -83,7 +83,7 @@ static void sparc_determine_frameoffset(ir_node *const node, ...@@ -83,7 +83,7 @@ static void sparc_determine_frameoffset(ir_node *const node,
if (entity != NULL) { if (entity != NULL) {
attr->immediate_value += get_entity_offset(entity); attr->immediate_value += get_entity_offset(entity);
if (node_has_sp_base(node)) if (node_has_sp_base(node))
attr->immediate_value += sp_offset; attr->immediate_value += sp_offset + SPARC_MIN_STACKSIZE;
} }
} else if (sparc_has_load_store_attr(node)) { } else if (sparc_has_load_store_attr(node)) {
sparc_load_store_attr_t *const attr = get_sparc_load_store_attr(node); sparc_load_store_attr_t *const attr = get_sparc_load_store_attr(node);
...@@ -94,12 +94,12 @@ static void sparc_determine_frameoffset(ir_node *const node, ...@@ -94,12 +94,12 @@ static void sparc_determine_frameoffset(ir_node *const node,
if (entity != NULL) { if (entity != NULL) {
attr->base.immediate_value += get_entity_offset(entity); attr->base.immediate_value += get_entity_offset(entity);
if (node_has_sp_base(node)) if (node_has_sp_base(node))
attr->base.immediate_value += sp_offset; attr->base.immediate_value += sp_offset + SPARC_MIN_STACKSIZE;
} }
} else if (be_is_MemPerm(node)) { } else if (be_is_MemPerm(node)) {
ir_graph *irg = get_irn_irg(node); ir_graph *irg = get_irn_irg(node);
if (sparc_get_irg_data(irg)->omit_fp) if (sparc_get_irg_data(irg)->omit_fp)
be_set_MemPerm_offset(node, sp_offset); be_set_MemPerm_offset(node, sp_offset + SPARC_MIN_STACKSIZE);
} }
} }
......
Supports Markdown
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