X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=d22a8c6bc56200348345fceb1d56d142945a254e;hb=0b8982204ab5a697035d387517d406bd7c096c38;hp=403b615d8ed77c92e91e520d1af0db0d9b551189;hpb=2ec2984b80f97ad455add5278f1d3129ced02b3d;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 403b615d8..d22a8c6bc 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -324,8 +324,6 @@ static ir_node *gen_Const(ir_node *node) end: #endif /* CONSTRUCT_SSE_CONST */ SET_IA32_ORIG_NODE(load, node); - - be_dep_on_frame(load); return res; } else { /* non-float mode */ ir_node *cnst; @@ -343,7 +341,6 @@ end: cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val); SET_IA32_ORIG_NODE(cnst, node); - be_dep_on_frame(cnst); return cnst; } } @@ -378,7 +375,6 @@ static ir_node *gen_SymConst(ir_node *node) SET_IA32_ORIG_NODE(cnst, node); - be_dep_on_frame(cnst); return cnst; } @@ -1267,7 +1263,6 @@ static ir_node *gen_Add(ir_node *node) if (addr.base == NULL && addr.index == NULL) { new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent, addr.symconst_sign, 0, addr.offset); - be_dep_on_frame(new_node); SET_IA32_ORIG_NODE(new_node, node); return new_node; } @@ -1535,7 +1530,6 @@ static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block, (void)orig; if (ia32_cg_config.use_short_sex_eax) { ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block); - be_dep_on_frame(pval); res = new_bd_ia32_Cltd(dbgi, block, val, pval); } else { ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31); @@ -1595,7 +1589,6 @@ static ir_node *create_Div(ir_node *node) addr->index, new_mem, am.new_op2, am.new_op1, sign_extension); } else { sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0); - be_dep_on_frame(sign_extension); new_node = new_bd_ia32_Div(dbgi, new_block, addr->base, addr->index, new_mem, am.new_op2, @@ -1916,73 +1909,75 @@ static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) return new_bd_ia32_Bt(dbgi, new_block, op1, op2); } -static ia32_condition_code_t pnc_to_condition_code(pn_Cmp pnc, ir_mode *mode) +static ia32_condition_code_t relation_to_condition_code(ir_relation relation, + ir_mode *mode) { if (mode_is_float(mode)) { - switch (pnc) { - case pn_Cmp_Eq: return ia32_cc_float_equal; - case pn_Cmp_Lt: return ia32_cc_float_below; - case pn_Cmp_Le: return ia32_cc_float_below_equal; - case pn_Cmp_Gt: return ia32_cc_float_above; - case pn_Cmp_Ge: return ia32_cc_float_above_equal; - case pn_Cmp_Lg: return ia32_cc_not_equal; - case pn_Cmp_Leg: return ia32_cc_not_parity; - case pn_Cmp_Uo: return ia32_cc_parity; - case pn_Cmp_Ue: return ia32_cc_equal; - case pn_Cmp_Ul: return ia32_cc_float_unordered_below; - case pn_Cmp_Ule: return ia32_cc_float_unordered_below_equal; - case pn_Cmp_Ug: return ia32_cc_float_unordered_above; - case pn_Cmp_Uge: return ia32_cc_float_unordered_above_equal; - case pn_Cmp_Ne: return ia32_cc_float_not_equal; - case pn_Cmp_False: - case pn_Cmp_True: - case pn_Cmp_max: + switch (relation) { + case ir_relation_equal: return ia32_cc_float_equal; + case ir_relation_less: return ia32_cc_float_below; + case ir_relation_less_equal: return ia32_cc_float_below_equal; + case ir_relation_greater: return ia32_cc_float_above; + case ir_relation_greater_equal: return ia32_cc_float_above_equal; + case ir_relation_less_greater: return ia32_cc_not_equal; + case ir_relation_less_equal_greater: return ia32_cc_not_parity; + case ir_relation_unordered: return ia32_cc_parity; + case ir_relation_unordered_equal: return ia32_cc_equal; + case ir_relation_unordered_less: return ia32_cc_float_unordered_below; + case ir_relation_unordered_less_equal: + return ia32_cc_float_unordered_below_equal; + case ir_relation_unordered_greater: + return ia32_cc_float_unordered_above; + case ir_relation_unordered_greater_equal: + return ia32_cc_float_unordered_above_equal; + case ir_relation_unordered_less_greater: + return ia32_cc_float_not_equal; + case ir_relation_false: + case ir_relation_true: /* should we introduce a jump always/jump never? */ break; } panic("Unexpected float pnc"); } else if (mode_is_signed(mode)) { - switch (pnc) { - case pn_Cmp_Ue: - case pn_Cmp_Eq: return ia32_cc_equal; - case pn_Cmp_Ul: - case pn_Cmp_Lt: return ia32_cc_less; - case pn_Cmp_Ule: - case pn_Cmp_Le: return ia32_cc_less_equal; - case pn_Cmp_Ug: - case pn_Cmp_Gt: return ia32_cc_greater; - case pn_Cmp_Uge: - case pn_Cmp_Ge: return ia32_cc_greater_equal; - case pn_Cmp_Lg: - case pn_Cmp_Ne: return ia32_cc_not_equal; - case pn_Cmp_Leg: - case pn_Cmp_Uo: - case pn_Cmp_False: - case pn_Cmp_True: - case pn_Cmp_max: + switch (relation) { + case ir_relation_unordered_equal: + case ir_relation_equal: return ia32_cc_equal; + case ir_relation_unordered_less: + case ir_relation_less: return ia32_cc_less; + case ir_relation_unordered_less_equal: + case ir_relation_less_equal: return ia32_cc_less_equal; + case ir_relation_unordered_greater: + case ir_relation_greater: return ia32_cc_greater; + case ir_relation_unordered_greater_equal: + case ir_relation_greater_equal: return ia32_cc_greater_equal; + case ir_relation_unordered_less_greater: + case ir_relation_less_greater: return ia32_cc_not_equal; + case ir_relation_less_equal_greater: + case ir_relation_unordered: + case ir_relation_false: + case ir_relation_true: /* introduce jump always/jump never? */ break; } panic("Unexpected pnc"); } else { - switch (pnc) { - case pn_Cmp_Ue: - case pn_Cmp_Eq: return ia32_cc_equal; - case pn_Cmp_Ul: - case pn_Cmp_Lt: return ia32_cc_below; - case pn_Cmp_Ule: - case pn_Cmp_Le: return ia32_cc_below_equal; - case pn_Cmp_Ug: - case pn_Cmp_Gt: return ia32_cc_above; - case pn_Cmp_Uge: - case pn_Cmp_Ge: return ia32_cc_above_equal; - case pn_Cmp_Lg: - case pn_Cmp_Ne: return ia32_cc_not_equal; - case pn_Cmp_Leg: - case pn_Cmp_Uo: - case pn_Cmp_False: - case pn_Cmp_True: - case pn_Cmp_max: + switch (relation) { + case ir_relation_unordered_equal: + case ir_relation_equal: return ia32_cc_equal; + case ir_relation_unordered_less: + case ir_relation_less: return ia32_cc_below; + case ir_relation_unordered_less_equal: + case ir_relation_less_equal: return ia32_cc_below_equal; + case ir_relation_unordered_greater: + case ir_relation_greater: return ia32_cc_above; + case ir_relation_unordered_greater_equal: + case ir_relation_greater_equal: return ia32_cc_above_equal; + case ir_relation_unordered_less_greater: + case ir_relation_less_greater: return ia32_cc_not_equal; + case ir_relation_less_equal_greater: + case ir_relation_unordered: + case ir_relation_false: + case ir_relation_true: /* introduce jump always/jump never? */ break; } @@ -2001,48 +1996,55 @@ static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out) return flags; } -static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out) +static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out) { - /* must have a Proj(Cmp) as input */ - ir_node *cmp = get_Proj_pred(node); - int pnc = get_Proj_pn_cmp(node); - ir_node *l = get_Cmp_left(cmp); - ir_mode *mode = get_irn_mode(l); - ir_node *flags; + /* must have a Cmp as input */ + ir_relation relation = get_Cmp_relation(cmp); + ir_relation possible; + ir_node *l = get_Cmp_left(cmp); + ir_node *r = get_Cmp_right(cmp); + ir_mode *mode = get_irn_mode(l); + ir_node *flags; /* check for bit-test */ - if (ia32_cg_config.use_bt - && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq || pnc == pn_Cmp_Ne - || pnc == pn_Cmp_Ue)) { - ir_node *l = get_Cmp_left(cmp); - ir_node *r = get_Cmp_right(cmp); - if (is_And(l)) { - ir_node *la = get_And_left(l); - ir_node *ra = get_And_right(l); - if (is_Shl(ra)) { - ir_node *tmp = la; - la = ra; - ra = tmp; - } - if (is_Shl(la)) { - ir_node *c = get_Shl_left(la); - if (is_Const_1(c) && is_Const_0(r)) { - /* (1 << n) & ra) */ - ir_node *n = get_Shl_right(la); - flags = gen_bt(cmp, ra, n); - /* the bit is copied into the CF flag */ - if (pnc & pn_Cmp_Eq) - *cc_out = ia32_cc_below; /* ==0, so we test for CF=1 */ - else - *cc_out = ia32_cc_above_equal; /* test for CF=0 */ - return flags; - } + if (ia32_cg_config.use_bt && (relation == ir_relation_equal + || (mode_is_signed(mode) && relation == ir_relation_less_greater) + || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater))) + && is_And(l)) { + ir_node *la = get_And_left(l); + ir_node *ra = get_And_right(l); + if (is_Shl(ra)) { + ir_node *tmp = la; + la = ra; + ra = tmp; + } + if (is_Shl(la)) { + ir_node *c = get_Shl_left(la); + if (is_Const_1(c) && is_Const_0(r)) { + /* (1 << n) & ra) */ + ir_node *n = get_Shl_right(la); + flags = gen_bt(cmp, ra, n); + /* the bit is copied into the CF flag */ + if (relation & ir_relation_equal) + *cc_out = ia32_cc_above_equal; /* test for CF=0 */ + else + *cc_out = ia32_cc_below; /* test for CF=1 */ + return flags; } } } + /* the middle-end tries to eliminate impossible relations, so a ptr != 0 + * test becomes ptr > 0. But for x86 an equal comparison is preferable to + * a >0 (we can sometimes eliminate the cmp in favor of flags produced by + * a predecessor node). So add the < bit */ + possible = ir_get_possible_cmp_relations(l, r); + if (((relation & ir_relation_less) && !(possible & ir_relation_greater)) + || ((relation & ir_relation_greater) && !(possible & ir_relation_less))) + relation |= ir_relation_less_greater; + /* just do a normal transformation of the Cmp */ - *cc_out = pnc_to_condition_code(pnc, mode); + *cc_out = relation_to_condition_code(relation, mode); flags = be_transform_node(cmp); return flags; } @@ -2055,7 +2057,7 @@ static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out) */ static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out) { - if (is_Proj(node) && is_Cmp(get_Proj_pred(node))) + if (is_Cmp(node)) return get_flags_node_cmp(node, cc_out); assert(get_irn_mode(node) == mode_b); return get_flags_mode_b(node, cc_out); @@ -2069,14 +2071,14 @@ static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out) static ir_node *gen_Load(ir_node *node) { ir_node *old_block = get_nodes_block(node); - ir_node *block = be_transform_node(old_block); - ir_node *ptr = get_Load_ptr(node); - ir_node *mem = get_Load_mem(node); - ir_node *new_mem = be_transform_node(mem); + ir_node *block = be_transform_node(old_block); + ir_node *ptr = get_Load_ptr(node); + ir_node *mem = get_Load_mem(node); + ir_node *new_mem = be_transform_node(mem); + dbg_info *dbgi = get_irn_dbg_info(node); + ir_mode *mode = get_Load_mode(node); ir_node *base; ir_node *index; - dbg_info *dbgi = get_irn_dbg_info(node); - ir_mode *mode = get_Load_mode(node); ir_node *new_node; ia32_address_t addr; @@ -2132,7 +2134,6 @@ static ir_node *gen_Load(ir_node *node) SET_IA32_ORIG_NODE(new_node, node); - be_dep_on_frame(new_node); return new_node; } @@ -2846,25 +2847,6 @@ static ir_node *create_Ucomi(ir_node *node) return new_node; } -/** - * helper function: checks whether all Cmp projs are Lg or Eq which is needed - * to fold an and into a test node - */ -static bool can_fold_test_and(ir_node *node) -{ - const ir_edge_t *edge; - - /** we can only have eq and lg projs */ - foreach_out_edge(node, edge) { - ir_node *proj = get_edge_src_irn(edge); - pn_Cmp pnc = get_Proj_pn_cmp(proj); - if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg) - return false; - } - - return true; -} - /** * returns true if it is assured, that the upper bits of a node are "clean" * which means for a 16 or 8 bit value, that the upper bits in the register @@ -2973,8 +2955,7 @@ static ir_node *gen_Cmp(ir_node *node) /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */ if (is_Const_0(right) && is_And(left) && - get_irn_n_edges(left) == 1 && - can_fold_test_and(node)) { + get_irn_n_edges(left) == 1) { /* Test(and_left, and_right) */ ir_node *and_left = get_And_left(left); ir_node *and_right = get_And_right(left); @@ -3114,12 +3095,12 @@ static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b) if (is_Proj(new_node)) { sub = get_Proj_pred(new_node); - assert(is_ia32_Sub(sub)); } else { sub = new_node; set_irn_mode(sub, mode_T); new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res); } + assert(is_ia32_Sub(sub)); eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags); dbgi = get_irn_dbg_info(psi); @@ -3234,7 +3215,7 @@ static void find_const_transform(ia32_condition_code_t cc, t = f; f = tmp; cc = ia32_negate_condition_code(cc); - } else if (tarval_cmp(t, f) == pn_Cmp_Lt) { + } else if (tarval_cmp(t, f) == ir_relation_less) { // now, t is the bigger one ir_tarval *tmp = t; t = f; @@ -3351,29 +3332,28 @@ static ir_node *gen_Mux(ir_node *node) ir_node *new_block = be_transform_node(block); ir_node *mux_true = get_Mux_true(node); ir_node *mux_false = get_Mux_false(node); - ir_node *cond = get_Mux_sel(node); + ir_node *sel = get_Mux_sel(node); ir_mode *mode = get_irn_mode(node); ir_node *flags; ir_node *new_node; int is_abs; ia32_condition_code_t cc; - assert(get_irn_mode(cond) == mode_b); + assert(get_irn_mode(sel) == mode_b); - is_abs = be_mux_is_abs(cond, mux_true, mux_false); + is_abs = be_mux_is_abs(sel, mux_true, mux_false); if (is_abs != 0) { - return create_abs(dbgi, block, be_get_abs_op(cond), is_abs < 0, node); + return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node); } /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */ if (mode_is_float(mode)) { - ir_node *cmp = get_Proj_pred(cond); - ir_node *cmp_left = get_Cmp_left(cmp); - ir_node *cmp_right = get_Cmp_right(cmp); - int pnc = get_Proj_proj(cond); + ir_node *cmp_left = get_Cmp_left(sel); + ir_node *cmp_right = get_Cmp_right(sel); + ir_relation relation = get_Cmp_relation(sel); if (ia32_cg_config.use_sse2) { - if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) { + if (relation == ir_relation_less || relation == ir_relation_less_equal) { if (cmp_left == mux_true && cmp_right == mux_false) { /* Mux(a <= b, a, b) => MIN */ return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin, @@ -3383,7 +3363,7 @@ static ir_node *gen_Mux(ir_node *node) return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax, match_commutative | match_am | match_two_users); } - } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) { + } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) { if (cmp_left == mux_true && cmp_right == mux_false) { /* Mux(a >= b, a, b) => MAX */ return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax, @@ -3402,7 +3382,7 @@ static ir_node *gen_Mux(ir_node *node) ir_mode *new_mode; unsigned scale; - flags = get_flags_node(cond, &cc); + flags = get_flags_node(sel, &cc); new_node = create_set_32bit(dbgi, new_block, flags, cc, node); if (ia32_cg_config.use_sse2) { @@ -3437,7 +3417,7 @@ static ir_node *gen_Mux(ir_node *node) case 16: /* arg, shift 16 NOT supported */ scale = 3; - new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node); + new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node); break; default: panic("Unsupported constant size"); @@ -3473,37 +3453,34 @@ static ir_node *gen_Mux(ir_node *node) } else { assert(ia32_mode_needs_gp_reg(mode)); - if (is_Proj(cond)) { - ir_node *cmp = get_Proj_pred(cond); - if (is_Cmp(cmp)) { - ir_node *cmp_left = get_Cmp_left(cmp); - ir_node *cmp_right = get_Cmp_right(cmp); - ir_node *val_true = mux_true; - ir_node *val_false = mux_false; - int pnc = get_Proj_proj(cond); - - if (is_Const(val_true) && is_Const_null(val_true)) { - ir_node *tmp = val_false; - val_false = val_true; - val_true = tmp; - pnc = get_negated_pnc(pnc, get_irn_mode(cmp_left)); + if (is_Cmp(sel)) { + ir_node *cmp_left = get_Cmp_left(sel); + ir_node *cmp_right = get_Cmp_right(sel); + ir_relation relation = get_Cmp_relation(sel); + ir_node *val_true = mux_true; + ir_node *val_false = mux_false; + + if (is_Const(val_true) && is_Const_null(val_true)) { + ir_node *tmp = val_false; + val_false = val_true; + val_true = tmp; + relation = get_negated_relation(relation); + } + if (is_Const_0(val_false) && is_Sub(val_true)) { + if ((relation & ir_relation_greater) + && get_Sub_left(val_true) == cmp_left + && get_Sub_right(val_true) == cmp_right) { + return create_doz(node, cmp_left, cmp_right); } - if (is_Const_0(val_false) && is_Sub(val_true)) { - if ((pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) - && get_Sub_left(val_true) == cmp_left - && get_Sub_right(val_true) == cmp_right) { - return create_doz(node, cmp_left, cmp_right); - } - if ((pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) - && get_Sub_left(val_true) == cmp_right - && get_Sub_right(val_true) == cmp_left) { - return create_doz(node, cmp_right, cmp_left); - } + if ((relation & ir_relation_less) + && get_Sub_left(val_true) == cmp_right + && get_Sub_right(val_true) == cmp_left) { + return create_doz(node, cmp_right, cmp_left); } } } - flags = get_flags_node(cond, &cc); + flags = get_flags_node(sel, &cc); if (is_Const(mux_true) && is_Const(mux_false)) { /* both are const, good */ @@ -3519,8 +3496,8 @@ static ir_node *gen_Mux(ir_node *node) switch (res.steps[step].transform) { case SETCC_TR_ADD: - imm = ia32_immediate_from_long(res.steps[step].val); - new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm); + new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP); + add_ia32_am_offs_int(new_node, res.steps[step].val); break; case SETCC_TR_ADDxx: new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node); @@ -3560,7 +3537,7 @@ static ir_node *gen_Mux(ir_node *node) } } } else { - new_node = create_CMov(node, cond, flags, cc); + new_node = create_CMov(node, sel, flags, cc); } return new_node; } @@ -3953,19 +3930,23 @@ static ir_node *gen_be_FrameAddr(ir_node *node) */ static ir_node *gen_be_Return(ir_node *node) { - ir_graph *irg = current_ir_graph; - ir_node *ret_val = get_irn_n(node, be_pos_Return_val); - ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem); - ir_entity *ent = get_irg_entity(irg); - ir_type *tp = get_entity_type(ent); - dbg_info *dbgi; - ir_node *block; + ir_graph *irg = current_ir_graph; + ir_node *ret_val = get_irn_n(node, be_pos_Return_val); + ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem); + ir_node *new_ret_val = be_transform_node(ret_val); + ir_node *new_ret_mem = be_transform_node(ret_mem); + ir_entity *ent = get_irg_entity(irg); + ir_type *tp = get_entity_type(ent); + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *block = be_transform_node(get_nodes_block(node)); ir_type *res_type; ir_mode *mode; - ir_node *frame, *sse_store, *fld, *mproj, *barrier; - ir_node *new_barrier, *new_ret_val, *new_ret_mem; - ir_node **in; - int pn_ret_val, pn_ret_mem, arity, i; + ir_node *frame, *sse_store, *fld, *mproj; + int i; + int arity; + unsigned pop; + ir_node **in; + ir_node *new_node; assert(ret_val != NULL); if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) { @@ -3985,25 +3966,8 @@ static ir_node *gen_be_Return(ir_node *node) assert(get_method_n_ress(tp) == 1); - pn_ret_val = get_Proj_proj(ret_val); - pn_ret_mem = get_Proj_proj(ret_mem); - - /* get the Barrier */ - barrier = get_Proj_pred(ret_val); - - /* get result input of the Barrier */ - ret_val = get_irn_n(barrier, pn_ret_val); - new_ret_val = be_transform_node(ret_val); - - /* get memory input of the Barrier */ - ret_mem = get_irn_n(barrier, pn_ret_mem); - new_ret_mem = be_transform_node(ret_mem); - frame = get_irg_frame(irg); - dbgi = get_irn_dbg_info(barrier); - block = be_transform_node(get_nodes_block(barrier)); - /* store xmm0 onto stack */ sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP, new_ret_mem, new_ret_val); @@ -4019,32 +3983,24 @@ static ir_node *gen_be_Return(ir_node *node) mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M); fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res); - /* create a new barrier */ - arity = get_irn_arity(barrier); + /* create a new return */ + arity = get_irn_arity(node); in = ALLOCAN(ir_node*, arity); + pop = be_Return_get_pop(node); for (i = 0; i < arity; ++i) { - ir_node *new_in; - - if (i == pn_ret_val) { - new_in = fld; - } else if (i == pn_ret_mem) { - new_in = mproj; + ir_node *op = get_irn_n(node, i); + if (op == ret_val) { + in[i] = fld; + } else if (op == ret_mem) { + in[i] = mproj; } else { - ir_node *in = get_irn_n(barrier, i); - new_in = be_transform_node(in); + in[i] = be_transform_node(op); } - in[i] = new_in; } + new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in); + copy_node_attr(irg, node, new_node); - new_barrier = new_ir_node(dbgi, irg, block, - get_irn_op(barrier), get_irn_mode(barrier), - arity, in); - copy_node_attr(irg, barrier, new_barrier); - be_duplicate_deps(barrier, new_barrier); - be_set_transformed_node(barrier, new_barrier); - - /* transform normally */ - return be_duplicate_node(node); + return new_node; } /** @@ -4052,11 +4008,15 @@ static ir_node *gen_be_Return(ir_node *node) */ static ir_node *gen_be_AddSP(ir_node *node) { - ir_node *sz = get_irn_n(node, be_pos_AddSP_size); - ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp); + ir_node *sz = get_irn_n(node, be_pos_AddSP_size); + ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp); - return gen_binop(node, sp, sz, new_bd_ia32_SubSP, - match_am | match_immediate); + ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP, + match_am | match_immediate); + assert(is_ia32_SubSP(new_node)); + arch_irn_set_register(new_node, pn_ia32_SubSP_stack, + &ia32_registers[REG_ESP]); + return new_node; } /** @@ -4064,11 +4024,15 @@ static ir_node *gen_be_AddSP(ir_node *node) */ static ir_node *gen_be_SubSP(ir_node *node) { - ir_node *sz = get_irn_n(node, be_pos_SubSP_size); - ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp); + ir_node *sz = get_irn_n(node, be_pos_SubSP_size); + ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp); - return gen_binop(node, sp, sz, new_bd_ia32_AddSP, - match_am | match_immediate); + ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP, + match_am | match_immediate); + assert(is_ia32_AddSP(new_node)); + arch_irn_set_register(new_node, pn_ia32_AddSP_stack, + &ia32_registers[REG_ESP]); + return new_node; } /** @@ -4976,7 +4940,6 @@ static ir_node *gen_prefetch(ir_node *node) SET_IA32_ORIG_NODE(new_node, node); - be_dep_on_frame(new_node); return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M); } @@ -5014,7 +4977,7 @@ static ir_node *gen_ffs(ir_node *node) ir_node *real = skip_Proj(bsf); dbg_info *dbgi = get_irn_dbg_info(real); ir_node *block = get_nodes_block(real); - ir_node *flag, *set, *conv, *neg, *orn; + ir_node *flag, *set, *conv, *neg, *orn, *add; /* bsf x */ if (get_irn_mode(real) != mode_T) { @@ -5040,7 +5003,9 @@ static ir_node *gen_ffs(ir_node *node) set_ia32_commutative(orn); /* add 1 */ - return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, orn, ia32_create_Immediate(NULL, 0, 1)); + add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP); + add_ia32_am_offs_int(add, 1); + return add; } /** @@ -5367,7 +5332,8 @@ static ir_node *gen_inner_trampoline(ir_node *node) if (is_SymConst(callee)) { rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10); } else { - rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), ia32_create_Immediate(NULL, 0, -10)); + rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP); + add_ia32_am_offs_int(rel, -10); } rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline); @@ -5726,6 +5692,8 @@ static void ia32_pretransform_node(void) irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp); irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp); irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm); + assert(irg_data->fpu_trunc_mode == NULL); + assert(irg_data->get_eip == NULL); nomem = get_irg_no_mem(irg); noreg_GP = ia32_new_NoReg_gp(irg);