X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=6b603efcd7aec84477dfab593f725b342d4408e3;hb=a1a465eb2b3f54027b29f829423fffd0396937f4;hp=972b0c326f6d2566b5099591df374b160a1c1720;hpb=d5e0ce712c31d7e24e07684e5d90492863ee79a0;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 972b0c326..6b603efcd 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -421,7 +421,7 @@ static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *op1, ir_node tv = get_ia32_Immop_tarval(imm_op); if (tv) { - tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu)); + tv = tarval_mod(tv, new_tarval_from_long(32, get_tarval_mode(tv))); set_ia32_Immop_tarval(imm_op, tv); } else { @@ -515,7 +515,7 @@ static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;) /* try to optimize to inc/dec */ - if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) { + if ((env->cg->opt & IA32_OPT_INCDEC) && tv && (get_ia32_op_type(const_op) == ia32_Const)) { /* optimize tarvals */ class_tv = classify_tarval(tv); class_negtv = classify_tarval(tarval_neg(tv)); @@ -839,7 +839,7 @@ static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;) /* try to optimize to inc/dec */ - if ((env->cg->opt & IA32_OPT_INCDEC) && tv) { + if ((env->cg->opt & IA32_OPT_INCDEC) && tv && (get_ia32_op_type(const_op) == ia32_Const)) { /* optimize tarvals */ class_tv = classify_tarval(tv); class_negtv = classify_tarval(tarval_neg(tv)); @@ -1016,7 +1016,8 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EDX); } else { - edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu); + edx_node = new_rd_ia32_Const(dbg, irg, block, mode_Iu); + add_irn_dep(edx_node, be_abi_get_start_barrier(env->cg->birg->abi)); set_ia32_Const_type(edx_node, ia32_Const); set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu)); } @@ -1427,6 +1428,16 @@ static ir_node *gen_Load(ia32_transform_env_t *env) { ia32_collect_Projs(env->irn, projs, pn_Load_max); + /* + check for special case: the loaded value might not be used (optimized, volatile, ...) + we add a Proj + Keep for volatile loads and ignore all other cases + */ + if (! get_proj_for_pn(node, pn_Load_res) && get_Load_volatility(node) == volatility_is_volatile) { + /* add a result proj and a Keep to produce a pseudo use */ + ir_node *proj = new_r_Proj(env->irg, env->block, node, mode, pn_ia32_Load_res); + be_new_Keep(arch_get_irn_reg_class(env->cg->arch_env, proj, -1), env->irg, env->block, 1, &proj); + } + /* address might be a constant (symconst or absolute address) */ if (is_ia32_Const(ptr)) { lptr = noreg; @@ -1462,6 +1473,9 @@ static ir_node *gen_Load(ia32_transform_env_t *env) { add_ia32_am_offs(new_op, get_ia32_cnst(ptr)); am_flav = ia32_am_O; } + /* add dependency to barrier, if we are in start block */ + if (get_irg_start_block(env->irg) == env->block) + add_irn_dep(new_op, be_abi_get_start_barrier(env->cg->birg->abi)); } set_ia32_am_support(new_op, ia32_am_Source); @@ -1469,16 +1483,6 @@ static ir_node *gen_Load(ia32_transform_env_t *env) { set_ia32_am_flavour(new_op, am_flav); set_ia32_ls_mode(new_op, mode); - /* - check for special case: the loaded value might not be used (optimized, volatile, ...) - we add a Proj + Keep for volatile loads and ignore all other cases - */ - if (! get_proj_for_pn(node, pn_Load_res) && get_Load_volatility(node) == volatility_is_volatile) { - /* add a result proj and a Keep to produce a pseudo use */ - ir_node *proj = new_r_Proj(env->irg, env->block, new_op, mode, pn_ia32_Load_res); - be_new_Keep(arch_get_irn_reg_class(env->cg->arch_env, proj, -1), env->irg, env->block, 1, &proj); - } - SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); return new_op; @@ -1749,7 +1753,8 @@ static ir_node *gen_CopyB(ia32_transform_env_t *env) { rem = size & 0x3; /* size % 4 */ size >>= 2; - res = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Is); + res = new_rd_ia32_Const(dbg, irg, block, mode_Is); + add_irn_dep(res, be_abi_get_start_barrier(env->cg->birg->abi)); set_ia32_op_type(res, ia32_Const); set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is)); @@ -2221,7 +2226,8 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { set_ia32_tgt_mode(new_op, tgt_mode); set_ia32_src_mode(new_op, src_mode); - set_ia32_am_support(new_op, ia32_am_Source); + if(tgt_bits >= src_bits) + set_ia32_am_support(new_op, ia32_am_Source); new_op = new_rd_Proj(dbg, irg, block, new_op, tgt_mode, pn); @@ -2846,11 +2852,24 @@ static ir_node *gen_ia32_l_MulS(ia32_transform_env_t *env) { ir_node *new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_MulS); ir_node *muls = get_Proj_pred(new_op); + ir_node *proj; /* MulS cannot have AM for destination */ if (get_ia32_am_support(muls) != ia32_am_None) set_ia32_am_support(muls, ia32_am_Source); + /* check if EAX and EDX proj exist, add missing one */ + proj = get_proj_for_pn(env->irn, pn_ia32_MulS_EAX); + if (! proj) { + proj = new_r_Proj(env->irg, env->block, muls, get_ia32_res_mode(env->irn), pn_ia32_MulS_EAX); + be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, &proj); + } + proj = get_proj_for_pn(env->irn, pn_ia32_MulS_EDX); + if (! proj) { + proj = new_r_Proj(env->irg, env->block, muls, get_ia32_res_mode(env->irn), pn_ia32_MulS_EDX); + be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, &proj); + } + return muls; }