X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=7e571d189409613a9d35fb51aafe9a9073b5964f;hb=06588d996f1597c6098b9715ba7fc81afd975e9b;hp=c3b6984ed43fdae7b5d40b4981b8f90a98f81549;hpb=ec4ce0e79bd13da8b3b0f068e78c64b21a35ffba;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index c3b6984ed..7e571d189 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -36,6 +36,7 @@ #include "ia32_transform.h" #include "ia32_new_nodes.h" #include "ia32_map_regs.h" +#include "ia32_dbg_stat.h" #include "gen_ia32_regalloc_if.h" @@ -57,10 +58,10 @@ extern ir_op *get_op_Mulh(void); typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \ - ir_node *op1, ir_node *op2, ir_node *mem, ir_mode *mode); + ir_node *op1, ir_node *op2, ir_node *mem); typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \ - ir_node *op, ir_node *mem, ir_mode *mode); + ir_node *op, ir_node *mem); typedef enum { ia32_SSIGN, ia32_DSIGN, ia32_SABS, ia32_DABS, ia32_known_const_max @@ -219,13 +220,13 @@ static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, /* floating point operations */ if (imm_op) { DB((mod, LEVEL_1, "FP with immediate ...")); - new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem, mode_T); + new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem); set_ia32_Immop_attr(new_op, imm_op); set_ia32_am_support(new_op, ia32_am_None); } else { DB((mod, LEVEL_1, "FP binop ...")); - new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem, mode_T); + new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem); set_ia32_am_support(new_op, ia32_am_Source); } } @@ -234,7 +235,7 @@ static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, if (imm_op) { /* This is expr + const */ DB((mod, LEVEL_1, "INT with immediate ...")); - new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem, mode_T); + new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem); set_ia32_Immop_attr(new_op, imm_op); /* set AM support */ @@ -243,7 +244,7 @@ static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, else { DB((mod, LEVEL_1, "INT binop ...")); /* This is a normal operation */ - new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem, mode_T); + new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem); /* set AM support */ set_ia32_am_support(new_op, ia32_am_Full); @@ -315,13 +316,13 @@ static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *op1, ir_node /* This is shift/rot with const */ DB((mod, LEVEL_1, "Shift/Rot with immediate ...")); - new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T); + new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem); set_ia32_Immop_attr(new_op, imm_op); } else { /* This is a normal shift/rot */ DB((mod, LEVEL_1, "Shift/Rot binop ...")); - new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T); + new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem); } /* set AM support */ @@ -354,7 +355,7 @@ static ir_node *gen_unop(ia32_transform_env_t *env, ir_node *op, construct_unop_ ir_node *nomem = new_NoMem(); DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;) - new_op = func(dbg, irg, block, noreg, noreg, op, nomem, mode_T); + new_op = func(dbg, irg, block, noreg, noreg, op, nomem); if (mode_is_float(mode)) { DB((mod, LEVEL_1, "FP unop ...")); @@ -396,26 +397,27 @@ 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) && tv) { + if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) { /* optimize tarvals */ class_tv = classify_tarval(tv); class_negtv = classify_tarval(tarval_neg(tv)); if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */ DB((env->mod, LEVEL_2, "Add(1) to Inc ... ")); - new_op = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T); + new_op = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem); normal_add = 0; } else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */ DB((mod, LEVEL_2, "Add(-1) to Dec ... ")); - new_op = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T); + new_op = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem); normal_add = 0; } } if (normal_add) { - new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T); + new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem); set_ia32_Immop_attr(new_op, const_op); + set_ia32_commutative(new_op); } return new_op; @@ -449,7 +451,7 @@ static ir_node *gen_Add(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - return gen_binop(env, op1, op2, new_rd_ia32_fAdd); + return gen_binop(env, op1, op2, new_rd_ia32_xAdd); else return gen_binop(env, op1, op2, new_rd_ia32_vfadd); } @@ -501,7 +503,7 @@ static ir_node *gen_Add(ia32_transform_env_t *env) { } else { /* This is a normal add */ - new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T); + new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem); /* set AM support */ set_ia32_am_support(new_op, ia32_am_Full); @@ -532,7 +534,7 @@ static ir_node *gen_Mul(ia32_transform_env_t *env) { if (mode_is_float(env->mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = gen_binop(env, op1, op2, new_rd_ia32_fMul); + new_op = gen_binop(env, op1, op2, new_rd_ia32_xMul); else new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul); } @@ -648,7 +650,7 @@ static ir_node *gen_Max(ia32_transform_env_t *env) { if (mode_is_float(env->mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = gen_binop(env, op1, op2, new_rd_ia32_fMax); + new_op = gen_binop(env, op1, op2, new_rd_ia32_xMax); else { assert(0); } @@ -678,7 +680,7 @@ static ir_node *gen_Min(ia32_transform_env_t *env) { if (mode_is_float(env->mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = gen_binop(env, op1, op2, new_rd_ia32_fMin); + new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin); else { assert(0); } @@ -722,18 +724,18 @@ static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */ DB((mod, LEVEL_2, "Sub(1) to Dec ... ")); - new_op = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T); + new_op = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem); normal_sub = 0; } else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */ DB((mod, LEVEL_2, "Sub(-1) to Inc ... ")); - new_op = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T); + new_op = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem); normal_sub = 0; } } if (normal_sub) { - new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T); + new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem); set_ia32_Immop_attr(new_op, const_op); } @@ -768,7 +770,7 @@ static ir_node *gen_Sub(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - return gen_binop(env, op1, op2, new_rd_ia32_fSub); + return gen_binop(env, op1, op2, new_rd_ia32_xSub); else return gen_binop(env, op1, op2, new_rd_ia32_vfsub); } @@ -822,7 +824,7 @@ static ir_node *gen_Sub(ia32_transform_env_t *env) { } else { /* This is a normal sub */ - new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T); + new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem); /* set AM support */ set_ia32_am_support(new_op, ia32_am_Full); @@ -878,17 +880,17 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir if (mode_is_signed(mode)) { /* in signed mode, we need to sign extend the dividend */ - cltd = new_rd_ia32_Cdq(dbg, irg, block, dividend, mode_T); - dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EAX); - edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EDX); + cltd = new_rd_ia32_Cdq(dbg, irg, block, dividend); + dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EAX); + 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, mode_Iu); + edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu); set_ia32_Const_type(edx_node, ia32_Const); set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu)); } - res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, mode_T, dm_flav); + res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, dm_flav); set_ia32_n_res(res, 2); @@ -899,10 +901,12 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir proj = get_edge_src_irn(get_irn_out_edge_first(irn)); assert(is_Proj(proj) && "non-Proj to Div/Mod node"); - if (get_Proj_proj(proj) == pn_DivMod_res_div) { + if (get_irn_op(irn) == op_Div) { + set_Proj_proj(proj, pn_DivMod_res_div); in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_mod); } else { + set_Proj_proj(proj, pn_DivMod_res_mod); in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_div); } @@ -948,7 +952,7 @@ static ir_node *gen_DivMod(ia32_transform_env_t *env) { * Creates an ia32 floating Div. * * @param env The transformation environment - * @return The created ia32 fDiv node + * @return The created ia32 xDiv node */ static ir_node *gen_Quot(ia32_transform_env_t *env) { ir_node *noreg = ia32_new_NoReg_gp(env->cg); @@ -959,18 +963,18 @@ static ir_node *gen_Quot(ia32_transform_env_t *env) { FP_USED(env->cg); if (USE_SSE2(env->cg)) { - if (is_ia32_fConst(op2)) { - new_op = new_rd_ia32_fDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, noreg, nomem, mode_T); + if (is_ia32_xConst(op2)) { + new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, noreg, nomem); set_ia32_am_support(new_op, ia32_am_None); set_ia32_Immop_attr(new_op, op2); } else { - new_op = new_rd_ia32_fDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem, mode_T); + new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem); set_ia32_am_support(new_op, ia32_am_Source); } } else { - new_op = new_rd_ia32_vfdiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem, mode_T); + new_op = new_rd_ia32_vfdiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem); set_ia32_am_support(new_op, ia32_am_Source); } set_ia32_res_mode(new_op, get_irn_mode(get_proj_for_pn(env->irn, pn_Quot_res))); @@ -1113,7 +1117,7 @@ static ir_node *gen_Minus_ex(ia32_transform_env_t *env, ir_node *op) { ir_node *noreg_fp = ia32_new_NoReg_fp(env->cg); ir_node *nomem = new_rd_NoMem(env->irg); - new_op = new_rd_ia32_fEor(env->dbg, env->irg, env->block, noreg_gp, noreg_gp, op, noreg_fp, nomem, mode_T); + new_op = new_rd_ia32_xEor(env->dbg, env->irg, env->block, noreg_gp, noreg_gp, op, noreg_fp, nomem); size = get_mode_size_bits(env->mode); name = gen_fp_known_const(env->mode, size == 32 ? ia32_SSIGN : ia32_DSIGN); @@ -1125,7 +1129,7 @@ static ir_node *gen_Minus_ex(ia32_transform_env_t *env, ir_node *op) { set_ia32_res_mode(new_op, env->mode); set_ia32_immop_type(new_op, ia32_ImmSymConst); - new_op = new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, 0); + new_op = new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_xEor_res); } else { new_op = new_rd_ia32_vfchs(env->dbg, env->irg, env->block, op, env->mode); @@ -1185,7 +1189,7 @@ static ir_node *gen_Abs(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) { - res = new_rd_ia32_fAnd(dbg,irg, block, noreg_gp, noreg_gp, op, noreg_fp, nomem, mode_T); + res = new_rd_ia32_xAnd(dbg,irg, block, noreg_gp, noreg_gp, op, noreg_fp, nomem); size = get_mode_size_bits(mode); name = gen_fp_known_const(mode, size == 32 ? ia32_SABS : ia32_DABS); @@ -1197,7 +1201,7 @@ static ir_node *gen_Abs(ia32_transform_env_t *env) { set_ia32_res_mode(res, mode); set_ia32_immop_type(res, ia32_ImmSymConst); - res = new_rd_Proj(dbg, irg, block, res, mode, 0); + res = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_xAnd_res); } else { res = new_rd_ia32_vfabs(dbg, irg, block, op, mode); @@ -1205,24 +1209,24 @@ static ir_node *gen_Abs(ia32_transform_env_t *env) { } } else { - res = new_rd_ia32_Cdq(dbg, irg, block, op, mode_T); + res = new_rd_ia32_Cdq(dbg, irg, block, op); SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn)); set_ia32_res_mode(res, mode); - p_eax = new_rd_Proj(dbg, irg, block, res, mode, pn_EAX); - p_edx = new_rd_Proj(dbg, irg, block, res, mode, pn_EDX); + p_eax = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Cdq_EAX); + p_edx = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Cdq_EDX); - res = new_rd_ia32_Eor(dbg, irg, block, noreg_gp, noreg_gp, p_eax, p_edx, nomem, mode_T); + res = new_rd_ia32_Eor(dbg, irg, block, noreg_gp, noreg_gp, p_eax, p_edx, nomem); SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn)); set_ia32_res_mode(res, mode); - res = new_rd_Proj(dbg, irg, block, res, mode, 0); + res = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Eor_res); - res = new_rd_ia32_Sub(dbg, irg, block, noreg_gp, noreg_gp, res, p_edx, nomem, mode_T); + res = new_rd_ia32_Sub(dbg, irg, block, noreg_gp, noreg_gp, res, p_edx, nomem); SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn)); set_ia32_res_mode(res, mode); - res = new_rd_Proj(dbg, irg, block, res, mode, 0); + res = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Sub_res); } return res; @@ -1255,12 +1259,12 @@ static ir_node *gen_Load(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node), env->mode); + new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node)); else - new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node), env->mode); + new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node)); } else { - new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node), env->mode); + new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node)); } /* base is an constant address */ @@ -1327,21 +1331,21 @@ static ir_node *gen_Store(ia32_transform_env_t *env) { /* address might be a constant (symconst or absolute address) */ if (is_ia32_Const(ptr)) { sptr = noreg; - is_imm = 0; + is_imm = 1; } if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, sptr, noreg, sval, mem, mode_T); + new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, sptr, noreg, sval, mem); else - new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, sptr, noreg, sval, mem, mode_T); + new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, sptr, noreg, sval, mem); } else if (get_mode_size_bits(mode) == 8) { - new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, sptr, noreg, sval, mem, mode_T); + new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, sptr, noreg, sval, mem); } else { - new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T); + new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, sptr, noreg, sval, mem); } /* stored const is an attribute (saves a register) */ @@ -1423,7 +1427,7 @@ static ir_node *gen_Cond(ia32_transform_env_t *env) { cnst = (is_ia32_ImmConst(and) || is_ia32_ImmSymConst(and)) ? get_ia32_cnst(and) : NULL; } - res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2, mode_T); + res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2); set_ia32_pncode(res, get_Proj_proj(sel)); set_ia32_res_mode(res, get_irn_mode(op1)); @@ -1439,13 +1443,13 @@ static ir_node *gen_Cond(ia32_transform_env_t *env) { if (mode_is_float(get_irn_mode(expr))) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - res = new_rd_ia32_fCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T); + res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem); else { assert(0); } } else { - res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T); + res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem); } set_ia32_Immop_attr(res, cnst); set_ia32_res_mode(res, get_irn_mode(expr)); @@ -1454,19 +1458,23 @@ static ir_node *gen_Cond(ia32_transform_env_t *env) { if (mode_is_float(get_irn_mode(cmp_a))) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - res = new_rd_ia32_fCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T); + res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem); else { - assert(0); + ir_node *proj_eax; + res = new_rd_ia32_vfCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem); + proj_eax = new_r_Proj(irg, block, res, mode_Is, pn_ia32_vfCondJmp_temp_reg_eax); + be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, &proj_eax); } } else { - res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T); + res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem); + set_ia32_commutative(res); } set_ia32_res_mode(res, get_irn_mode(cmp_a)); } set_ia32_pncode(res, get_Proj_proj(sel)); - set_ia32_am_support(res, ia32_am_Source); + //set_ia32_am_support(res, ia32_am_Source); } else { /* determine the smallest switch case value */ @@ -1526,7 +1534,7 @@ 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, mode_Is); + res = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Is); set_ia32_op_type(res, ia32_Const); set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is)); @@ -1612,7 +1620,7 @@ static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_mode *tgt_mode) { } /* do a fist */ - fist = new_rd_ia32_vfist(env->dbg, irg, block, get_irg_frame(irg), noreg, op, get_irg_no_mem(irg), mode_T); + fist = new_rd_ia32_vfist(env->dbg, irg, block, get_irg_frame(irg), noreg, op, get_irg_no_mem(irg)); set_ia32_frame_ent(fist, ent); set_ia32_use_frame(fist); @@ -1621,10 +1629,10 @@ static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_mode *tgt_mode) { set_ia32_am_flavour(fist, ia32_B); set_ia32_ls_mode(fist, mode_E); - mem = new_r_Proj(irg, block, fist, mode_M, 0); + mem = new_r_Proj(irg, block, fist, mode_M, pn_ia32_vfist_M); /* do a Load */ - load = new_rd_ia32_Load(env->dbg, irg, block, get_irg_frame(irg), noreg, mem, mode_T); + load = new_rd_ia32_Load(env->dbg, irg, block, get_irg_frame(irg), noreg, mem); set_ia32_frame_ent(load, ent); set_ia32_use_frame(load); @@ -1633,7 +1641,7 @@ static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_mode *tgt_mode) { set_ia32_am_flavour(load, ia32_B); set_ia32_ls_mode(load, tgt_mode); - return new_r_Proj(irg, block, load, tgt_mode, 0); + return new_r_Proj(irg, block, load, tgt_mode, pn_ia32_Load_res); } /** @@ -1659,16 +1667,16 @@ static ir_node *gen_x87_gp_to_fp(ia32_transform_env_t *env, ir_mode *src_mode) { /* first convert to 32 bit */ src_bits = get_mode_size_bits(src_mode); if (src_bits == 8) { - op = new_rd_ia32_Conv_I2I8Bit(env->dbg, irg, block, noreg, noreg, op, nomem, mode_T); + op = new_rd_ia32_Conv_I2I8Bit(env->dbg, irg, block, noreg, noreg, op, nomem); op = new_r_Proj(irg, block, op, mode_Is, 0); } else if (src_bits < 32) { - op = new_rd_ia32_Conv_I2I(env->dbg, irg, block, noreg, noreg, op, nomem, mode_T); + op = new_rd_ia32_Conv_I2I(env->dbg, irg, block, noreg, noreg, op, nomem); op = new_r_Proj(irg, block, op, mode_Is, 0); } /* do a store */ - store = new_rd_ia32_Store(env->dbg, irg, block, get_irg_frame(irg), noreg, op, nomem, mode_T); + store = new_rd_ia32_Store(env->dbg, irg, block, get_irg_frame(irg), noreg, op, nomem); set_ia32_frame_ent(store, ent); set_ia32_use_frame(store); @@ -1681,7 +1689,7 @@ static ir_node *gen_x87_gp_to_fp(ia32_transform_env_t *env, ir_mode *src_mode) { mem = new_r_Proj(irg, block, store, mode_M, 0); /* do a fild */ - fild = new_rd_ia32_vfild(env->dbg, irg, block, get_irg_frame(irg), noreg, mem, mode_T); + fild = new_rd_ia32_vfild(env->dbg, irg, block, get_irg_frame(irg), noreg, mem); set_ia32_frame_ent(fild, ent); set_ia32_use_frame(fild); @@ -1725,7 +1733,7 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { /* ... to float */ if (USE_SSE2(env->cg)) { DB((mod, LEVEL_1, "create Conv(float, float) ...")); - new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T); + new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem); } else { DB((mod, LEVEL_1, "killed Conv(float, float) ...")); @@ -1736,7 +1744,7 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { /* ... to int */ DB((mod, LEVEL_1, "create Conv(float, int) ...")); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T); + new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem); else return gen_x87_fp_to_gp(env, tgt_mode); @@ -1750,10 +1758,10 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { proj = new_rd_Proj(dbg, irg, block, new_op, mode_Is, 0); if (tgt_bits == 8 || src_bits == 8) { - new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem, mode_T); + new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem); } else { - new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem, mode_T); + new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem); } } } @@ -1765,7 +1773,7 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { /* ... to float */ DB((mod, LEVEL_1, "create Conv(int, float) ...")); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T); + new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem); else return gen_x87_gp_to_fp(env, src_mode); } @@ -1778,10 +1786,10 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { else { DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode)); if (tgt_bits == 8 || src_bits == 8) { - new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem, mode_T); + new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem); } else { - new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T); + new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem); } } } @@ -1830,12 +1838,12 @@ static ir_node *gen_be_StackParam(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T); + new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem); else - new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T); + new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem); } else { - new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T); + new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem); } set_ia32_frame_ent(new_op, ent); @@ -1848,7 +1856,7 @@ static ir_node *gen_be_StackParam(ia32_transform_env_t *env) { SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); - return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, 0); + return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_ia32_Load_res); } /** @@ -1861,7 +1869,7 @@ static ir_node *gen_be_FrameAddr(ia32_transform_env_t *env) { ir_node *noreg = ia32_new_NoReg_gp(env->cg); ir_node *nomem = new_rd_NoMem(env->irg); - new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem, mode_T); + new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem); set_ia32_frame_ent(new_op, be_get_frame_entity(node)); set_ia32_am_support(new_op, ia32_am_Full); set_ia32_use_frame(new_op); @@ -1870,7 +1878,7 @@ static ir_node *gen_be_FrameAddr(ia32_transform_env_t *env) { SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); - return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, 0); + return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_Add_res); } /** @@ -1888,12 +1896,12 @@ static ir_node *gen_be_FrameLoad(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T); + new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem); else - new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T); + new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem); } else - new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T); + new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem); set_ia32_frame_ent(new_op, ent); set_ia32_use_frame(new_op); @@ -1925,15 +1933,15 @@ static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T); + new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem); else - new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T); + new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem); } else if (get_mode_size_bits(mode) == 8) { - new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T); + new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem); } else { - new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T); + new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem); } set_ia32_frame_ent(new_op, ent); @@ -1949,6 +1957,30 @@ static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) { return new_op; } +/** + * This function just sets the register for the Unknown node + * as this is not done during register allocation because Unknown + * is an "ignore" node. + */ +static ir_node *gen_Unknown(ia32_transform_env_t *env) { + ir_mode *mode = env->mode; + ir_node *irn = env->irn; + + if (mode_is_float(mode)) { + if (USE_SSE2(env->cg)) + arch_set_irn_register(env->cg->arch_env, irn, &ia32_xmm_regs[REG_XMM_UKNWN]); + else + arch_set_irn_register(env->cg->arch_env, irn, &ia32_vfp_regs[REG_VFP_UKNWN]); + } + else if (mode_is_int(mode) || mode_is_reference(mode)) { + arch_set_irn_register(env->cg->arch_env, irn, &ia32_gp_regs[REG_GP_UKNWN]); + } + else { + assert(0 && "unsupported Unknown-Mode"); + } + + return NULL; +} /********************************************************* @@ -1962,7 +1994,7 @@ static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) { *********************************************************/ /** - * Transforms a Sub or fSub into Neg--Add iff OUT_REG == SRC2_REG. + * Transforms a Sub or xSub into Neg--Add iff OUT_REG == SRC2_REG. * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION. */ void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) { @@ -1970,8 +2002,8 @@ void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) { ir_node *in1, *in2, *noreg, *nomem, *res; const arch_register_t *in1_reg, *in2_reg, *out_reg, **slots; - /* Return if AM node or not a Sub or fSub */ - if (get_ia32_op_type(irn) != ia32_Normal || !(is_ia32_Sub(irn) || is_ia32_fSub(irn))) + /* Return if AM node or not a Sub or xSub */ + if (get_ia32_op_type(irn) != ia32_Normal || !(is_ia32_Sub(irn) || is_ia32_xSub(irn))) return; noreg = ia32_new_NoReg_gp(cg); @@ -2001,14 +2033,15 @@ void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) { /* generate the add */ if (mode_is_float(tenv.mode)) { - res = new_rd_ia32_fAdd(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem, mode_T); + res = new_rd_ia32_xAdd(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem); set_ia32_am_support(res, ia32_am_Source); } else { - res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem, mode_T); + res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem); set_ia32_am_support(res, ia32_am_Full); set_ia32_commutative(res); } + set_ia32_res_mode(res, tenv.mode); SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(tenv.cg, irn)); /* copy register */ @@ -2021,6 +2054,8 @@ void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) { /* remove the old sub */ sched_remove(irn); + DBG_OPT_SUB2NEGADD(irn, res); + /* exchange the add and the sub */ exchange(irn, res); } @@ -2116,10 +2151,11 @@ void ia32_transform_lea_to_add(ir_node *irn, ia32_code_gen_t *cg) { break; } - res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, op1, op2, nomem, mode_T); + res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, op1, op2, nomem); arch_set_irn_register(cg->arch_env, res, out_reg); set_ia32_op_type(res, ia32_Normal); set_ia32_commutative(res); + set_ia32_res_mode(res, tenv.mode); if (imm) { set_ia32_cnst(res, offs); @@ -2131,6 +2167,8 @@ void ia32_transform_lea_to_add(ir_node *irn, ia32_code_gen_t *cg) { /* add Add to schedule */ sched_add_before(irn, res); + DBG_OPT_LEA2ADD(irn, res); + res = new_rd_Proj(tenv.dbg, tenv.irg, tenv.block, res, tenv.mode, 0); /* add result Proj to schedule */ @@ -2207,7 +2245,6 @@ void ia32_register_transformers(void) { IGN(IJmp); IGN(Break); IGN(Cmp); - IGN(Unknown); /* constant transformation happens earlier */ IGN(Const); @@ -2233,6 +2270,9 @@ void ia32_register_transformers(void) { GEN(be_FrameStore); GEN(be_StackParam); + /* set the register for all Unknown nodes */ + GEN(Unknown); + op_Max = get_op_Max(); if (op_Max) GEN(Max);