Commit 14dd44af authored by Matthias Braun's avatar Matthias Braun
Browse files

fix allocas, fix Tls transform

[r15173]
parent 84725b31
......@@ -1444,8 +1444,9 @@ static ir_node *gen_Proj_be_SubSP(ir_node *node) {
dbg_info *dbgi = get_irn_dbg_info(node);
long proj = get_Proj_proj(node);
if (proj == pn_be_SubSP_res) {
ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_arm_SubSP_stack);
if (proj == pn_be_SubSP_sp) {
ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
pn_arm_SubSP_stack);
arch_set_irn_register(env_cg->arch_env, res, &arm_gp_regs[REG_SP]);
return res;
} else if (proj == pn_be_SubSP_M) {
......
......@@ -881,10 +881,11 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp
/* we might need to multiply the size with the element size */
if(type != get_unknown_type() && get_type_size_bytes(type) != 1) {
tarval *tv = new_tarval_from_long(get_type_size_bytes(type), mode_Iu);
tarval *tv = new_tarval_from_long(get_type_size_bytes(type),
mode_Iu);
ir_node *cnst = new_rd_Const(dbg, irg, block, mode_Iu, tv);
ir_node *mul = new_rd_Mul(dbg, irg, block, get_Alloc_size(alloc),
cnst, mode_Iu);
ir_node *mul = new_rd_Mul(dbg, irg, block, get_Alloc_size(alloc),
cnst, mode_Iu);
size = mul;
} else {
size = get_Alloc_size(alloc);
......@@ -921,20 +922,25 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp
/* fix projnum of alloca res */
set_Proj_proj(alloc_res, pn_be_AddSP_res);
addr = env->isa->stack_dir < 0 ? alloc_res : curr_sp;
addr = alloc_res;
curr_sp = new_r_Proj(irg, block, new_alloc, get_irn_mode(curr_sp),
pn_be_AddSP_sp);
#if 0
/* copy the address away, since it could be used after further stack pointer modifications. */
/* Let it point curr_sp just for the moment, I'll reroute it in a second. */
*result_copy = copy = be_new_Copy(env->isa->sp->reg_class, irg, block, curr_sp);
set_irn_mode(copy, mode_P);
/* Let all users of the Alloc() result now point to the copy. */
edges_reroute(alloc_res, copy, irg);
edges_reroute(alloc_res, addr, irg);
/* Rewire the copy appropriately. */
set_irn_n(copy, be_pos_Copy_op, addr);
curr_sp = alloc_res;
#endif
return curr_sp;
} /* adjust_alloc */
......@@ -988,7 +994,7 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
set_irn_dbg_info(subsp, dbg);
mem = new_r_Proj(irg, block, subsp, mode_M, pn_be_SubSP_M);
res = new_r_Proj(irg, block, subsp, sp_mode, pn_be_SubSP_res);
res = new_r_Proj(irg, block, subsp, sp_mode, pn_be_SubSP_sp);
/* we need to sync the memory */
in[0] = get_Free_mem(free);
......
......@@ -56,6 +56,7 @@ static INLINE int is_liveness_node(const ir_node *irn)
case iro_Block:
case iro_Bad:
case iro_End:
case iro_Anchor:
return 0;
default:;
}
......
......@@ -720,6 +720,7 @@ ir_node *be_new_AddSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
be_node_attr_t *a;
ir_node *irn;
ir_node *in[be_pos_AddSP_last];
const arch_register_class_t *class;
in[be_pos_AddSP_old_sp] = old_sp;
in[be_pos_AddSP_size] = sz;
......@@ -727,13 +728,17 @@ ir_node *be_new_AddSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
irn = new_ir_node(NULL, irg, bl, op_be_AddSP, mode_T, be_pos_AddSP_last, in);
a = init_node_attr(irn, be_pos_AddSP_last);
be_node_set_flags(irn, OUT_POS(pn_be_AddSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
be_node_set_flags(irn, OUT_POS(pn_be_AddSP_sp),
arch_irn_flags_ignore | arch_irn_flags_modify_sp);
/* Set output constraint to stack register. */
be_set_constr_single_reg(irn, be_pos_AddSP_old_sp, sp);
be_node_set_reg_class(irn, be_pos_AddSP_size, arch_register_get_class(sp));
be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
a->reg_data[pn_be_AddSP_res].reg = sp;
be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_sp), sp);
a->reg_data[pn_be_AddSP_sp].reg = sp;
class = arch_register_get_class(sp);
be_node_set_reg_class(irn, OUT_POS(pn_be_AddSP_res), class);
return irn;
}
......@@ -750,28 +755,30 @@ ir_node *be_new_SubSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
irn = new_ir_node(NULL, irg, bl, op_be_SubSP, mode_T, be_pos_SubSP_last, in);
a = init_node_attr(irn, be_pos_SubSP_last);
be_node_set_flags(irn, OUT_POS(pn_be_SubSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
be_node_set_flags(irn, OUT_POS(pn_be_SubSP_sp),
arch_irn_flags_ignore | arch_irn_flags_modify_sp);
/* Set output constraint to stack register. */
be_set_constr_single_reg(irn, be_pos_SubSP_old_sp, sp);
be_node_set_reg_class(irn, be_pos_SubSP_size, arch_register_get_class(sp));
be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_res), sp);
a->reg_data[pn_be_SubSP_res].reg = sp;
be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_sp), sp);
a->reg_data[pn_be_SubSP_sp].reg = sp;
return irn;
}
ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *op, ir_node *mem)
ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl,
ir_node *old_sp, ir_node *op, ir_node *mem)
{
be_node_attr_t *a;
ir_node *irn;
ir_node *in[3];
in[0] = mem;
in[1] = old_sp;
in[2] = op;
irn = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
a = init_node_attr(irn, 3);
in[0] = mem;
in[1] = old_sp;
in[2] = op;
irn = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
a = init_node_attr(irn, 3);
be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
......
......@@ -225,9 +225,10 @@ enum {
};
enum {
pn_be_AddSP_res = 0,
pn_be_AddSP_M = 1,
pn_be_AddSP_last = 2
pn_be_AddSP_sp = 0,
pn_be_AddSP_res = 1,
pn_be_AddSP_M = 2,
pn_be_AddSP_last = 3
};
/**
......@@ -254,7 +255,7 @@ enum {
};
enum {
pn_be_SubSP_res = 0,
pn_be_SubSP_sp = 0,
pn_be_SubSP_M = 1,
pn_be_SubSP_last = 2
};
......
......@@ -219,6 +219,11 @@ ir_node *be_pre_transform_node(ir_node *place) {
return be_transform_node(place);
}
ir_node *be_get_old_anchor(int anchor)
{
return get_irn_n(env.old_anchor, anchor);
}
static void pre_transform_anchor(int anchor)
{
ir_node *old_anchor_node = get_irn_n(env.old_anchor, anchor);
......
......@@ -48,6 +48,11 @@ ir_node *be_pre_transform_node(ir_node *place);
*/
ir_node *be_transform_node(ir_node *node);
/**
* returns an anchor from the graph before the transformation
*/
ir_node *be_get_old_anchor(int anchor);
/**
* Duplicate all dependency edges of a node.
*/
......
......@@ -171,7 +171,7 @@ static be_next_use_t get_next_use(be_uses_t *env, ir_node *from,
unsigned from_step, const ir_node *def,
int skip_from_uses)
{
unsigned step = from_step;
unsigned step = from_step;
ir_node *block = get_nodes_block(from);
ir_node *next_use;
ir_node *node;
......@@ -192,6 +192,8 @@ static be_next_use_t get_next_use(be_uses_t *env, ir_node *from,
ir_node *node = get_edge_src_irn(edge);
unsigned node_step;
if(is_Anchor(node))
continue;
if(get_nodes_block(node) != block)
continue;
if(is_Phi(node))
......
......@@ -1023,10 +1023,11 @@ AddSP => {
},
SubSP => {
irn_flags => "I",
reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
emit => '. subl %binop',
outs => [ "stack:S", "M" ],
#irn_flags => "I",
reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "gp", "none" ] },
emit => ". subl %binop\n".
". movl %%esp, %D1",
outs => [ "stack:I|S", "addr", "M" ],
units => [ "GP" ],
modified_flags => $status_flags
},
......
......@@ -1158,7 +1158,7 @@ static ir_node *gen_Quot(ir_node *node) {
} else {
new_op = new_rd_ia32_xDiv(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
// Matze: disabled for now, spillslot coalescer fails
//set_ia32_am_support(new_op, ia32_am_Source | ia32_am_binary);
set_ia32_am_support(new_op, ia32_am_Source, ia32_am_binary);
}
set_ia32_ls_mode(new_op, mode);
} else {
......@@ -1167,7 +1167,7 @@ static ir_node *gen_Quot(ir_node *node) {
new_op = new_rd_ia32_vfdiv(dbgi, irg, block, noreg, noreg, new_op1,
new_op2, nomem, fpcw);
// Matze: disabled for now (spillslot coalescer fails)
//set_ia32_am_support(new_op, ia32_am_Source | ia32_am_binary);
set_ia32_am_support(new_op, ia32_am_Source, ia32_am_binary);
}
SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
return new_op;
......@@ -2022,6 +2022,44 @@ static ir_node *gen_x87_fp_to_gp(ir_node *node) {
return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
}
static ir_node *create_strict_conv(ir_mode *src_mode, ir_mode *tgt_mode,
ir_node *node)
{
ir_node *block = get_nodes_block(node);
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *noreg = ia32_new_NoReg_gp(env_cg);
ir_node *nomem = new_NoMem();
int src_bits = get_mode_size_bits(src_mode);
int tgt_bits = get_mode_size_bits(tgt_mode);
ir_node *frame = get_irg_frame(irg);
ir_mode *smaller_mode;
ir_node *store, *load;
ir_node *res;
if(src_bits <= tgt_bits)
smaller_mode = src_mode;
else
smaller_mode = tgt_mode;
store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, node, nomem,
smaller_mode);
set_ia32_use_frame(store);
set_ia32_op_type(store, ia32_AddrModeD);
set_ia32_am_flavour(store, ia32_am_OB);
SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
smaller_mode);
set_ia32_use_frame(load);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_flavour(load, ia32_am_OB);
SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
res = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
return res;
}
/**
* Create a conversion from general purpose to x87 register
*/
......@@ -2034,7 +2072,8 @@ static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
ir_node *noreg = ia32_new_NoReg_gp(env_cg);
ir_node *nomem = new_NoMem();
ir_node *fild, *store;
int src_bits;
ir_node *res;
int src_bits;
/* first convert to 32 bit if necessary */
src_bits = get_mode_size_bits(src_mode);
......@@ -2066,42 +2105,12 @@ static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
set_ia32_am_flavour(fild, ia32_am_OB);
set_ia32_ls_mode(fild, mode_Iu);
return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
}
static ir_node *create_strict_conv(ir_mode *src_mode, ir_mode *tgt_mode,
ir_node *node)
{
ir_node *block = get_nodes_block(node);
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *noreg = ia32_new_NoReg_gp(env_cg);
ir_node *nomem = new_NoMem();
int src_bits = get_mode_size_bits(src_mode);
int tgt_bits = get_mode_size_bits(tgt_mode);
ir_node *frame = get_irg_frame(irg);
ir_mode *smaller_mode;
ir_node *store, *load;
ir_node *res;
if(src_bits <= tgt_bits)
smaller_mode = src_mode;
else
smaller_mode = tgt_mode;
res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, node, nomem,
smaller_mode);
set_ia32_use_frame(store);
set_ia32_op_type(store, ia32_AddrModeD);
set_ia32_am_flavour(store, ia32_am_OB);
load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
smaller_mode);
set_ia32_use_frame(load);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_flavour(load, ia32_am_OB);
if(get_irg_fp_model(irg) & fp_explicit_rounding) {
res = create_strict_conv(mode_E, get_irn_mode(node), res);
}
res = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
return res;
}
......@@ -3068,10 +3077,18 @@ static ir_node *gen_Unknown(ir_node *node) {
ir_mode *mode = get_irn_mode(node);
if (mode_is_float(mode)) {
#if 0
/* Unknown nodes are buggy in x87 sim, use zero for now... */
if (USE_SSE2(env_cg))
return ia32_new_Unknown_xmm(env_cg);
else
return ia32_new_Unknown_vfp(env_cg);
#else
ir_graph *irg = current_ir_graph;
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = get_irg_start_block(irg);
return new_rd_ia32_vfldz(dbgi, irg, block);
#endif
} else if (mode_needs_gp_reg(mode)) {
return ia32_new_Unknown_gp(env_cg);
} else {
......@@ -3540,12 +3557,16 @@ static ir_node *gen_Proj_be_AddSP(ir_node *node) {
dbg_info *dbgi = get_irn_dbg_info(node);
long proj = get_Proj_proj(node);
if (proj == pn_be_AddSP_res) {
ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_AddSP_stack);
if (proj == pn_be_AddSP_sp) {
ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
pn_ia32_SubSP_stack);
arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
return res;
} else if(proj == pn_be_AddSP_res) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
pn_ia32_SubSP_addr);
} else if (proj == pn_be_AddSP_M) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
}
assert(0);
......@@ -3563,12 +3584,13 @@ static ir_node *gen_Proj_be_SubSP(ir_node *node) {
dbg_info *dbgi = get_irn_dbg_info(node);
long proj = get_Proj_proj(node);
if (proj == pn_be_SubSP_res) {
ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_SubSP_stack);
if (proj == pn_be_SubSP_sp) {
ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
pn_ia32_AddSP_stack);
arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
return res;
} else if (proj == pn_be_SubSP_M) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
}
assert(0);
......@@ -3925,7 +3947,7 @@ static ir_node *gen_Proj(ir_node *node) {
jump = new_rd_Jmp(dbgi, irg, block);
return jump;
}
if (node == get_irg_anchor(irg, anchor_tls)) {
if (node == be_get_old_anchor(anchor_tls)) {
return gen_Proj_tls(node);
}
} else {
......
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