X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=0f0d3e5f50a0d2fd3a7ef0ecaf48647ed3158aca;hb=d9ba33a4b9e7b4ee41bae2d4697c217cb4ad9b53;hp=ae3ccf2f5d650ca1f64e979a9c44981e0de61b9b;hpb=eb798733d50fbfb32b12ae9cb2f989d8b86f0d12;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index ae3ccf2f5..0f0d3e5f5 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -271,7 +271,7 @@ static ir_node *gen_Const(ia32_transform_env_t *env, ir_node *node) { set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_flavour(load, ia32_am_N); set_ia32_am_sc(load, ia32_get_ent_ident(floatent)); - res = new_r_Proj(irg, block, load, mode_D, pn_ia32_vfld_res); + res = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res); } } else { floatent = get_entity_for_tv(env->cg, node); @@ -281,7 +281,7 @@ static ir_node *gen_Const(ia32_transform_env_t *env, ir_node *node) { set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_flavour(load, ia32_am_N); set_ia32_am_sc(load, ia32_get_ent_ident(floatent)); - res = new_r_Proj(irg, block, load, mode_D, pn_ia32_xLoad_res); + res = new_r_Proj(irg, block, load, mode_E, pn_ia32_xLoad_res); } set_ia32_ls_mode(load, mode); @@ -388,7 +388,7 @@ static ir_node *gen_sse_conv_f2d(ia32_code_gen_t *cg, dbg_info *dbg, ir_node *conv = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, in, nomem); set_ia32_am_support(conv, ia32_am_Source); - set_ia32_ls_mode(conv, mode_D); + set_ia32_ls_mode(conv, mode_E); SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node)); return conv; @@ -421,7 +421,8 @@ ident *ia32_gen_fp_known_const(ia32_known_const_t kct) { tp_name = names[kct].tp_name; cnst_str = names[kct].cnst_str; - mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu; + //mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu; + mode = mode_LLu; tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode); tp = new_type_primitive(new_id_from_str(tp_name), mode); ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp); @@ -521,7 +522,7 @@ static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *node, ir_node *new_op2 = transform_node(env, op2); new_node = func(dbg, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem); - if(func == new_rd_ia32_Mul) { + if(func == new_rd_ia32_IMul) { set_ia32_am_support(new_node, ia32_am_Source); } else { set_ia32_am_support(new_node, ia32_am_Full); @@ -884,18 +885,24 @@ static ir_node *gen_Mulh(ia32_transform_env_t *env, ir_node *node) { ir_node *new_op1 = transform_node(env, op1); ir_node *new_op2 = transform_node(env, op2); ir_node *noreg = ia32_new_NoReg_gp(env->cg); - ir_node *proj_EAX, *proj_EDX, *mulh; + ir_node *proj_EAX, *proj_EDX, *res; ir_mode *mode = get_irn_mode(node); ir_node *in[1]; assert(!mode_is_float(mode) && "Mulh with float not supported"); - mulh = new_rd_ia32_Mulh(dbg, irg, block, noreg, noreg, new_op1, new_op2, new_NoMem()); - set_ia32_commutative(mulh); - set_ia32_am_support(mulh, ia32_am_Source); + if(mode_is_signed(mode)) { + res = new_rd_ia32_IMul1OP(dbg, irg, block, noreg, noreg, new_op1, new_op2, new_NoMem()); + } else { + res = new_rd_ia32_Mul(dbg, irg, block, noreg, noreg, new_op1, new_op2, new_NoMem()); + } - /* imediates are not supported, so no fold_immediate */ - proj_EAX = new_rd_Proj(dbg, irg, block, mulh, mode_Iu, pn_EAX); - proj_EDX = new_rd_Proj(dbg, irg, block, mulh, mode_Iu, pn_EDX); + set_ia32_commutative(res); + set_ia32_am_support(res, ia32_am_Source); + + set_ia32_am_support(res, ia32_am_Source); + + proj_EAX = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_EAX); + proj_EDX = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_EDX); /* keep EAX */ in[0] = proj_EAX; @@ -1196,6 +1203,7 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *node, ir_node *in_keep[1]; ir_node *mem, *new_mem; ir_node *projs[pn_DivMod_max]; + ir_node *noreg = ia32_new_NoReg_gp(env->cg); ir_node *new_dividend = transform_node(env, dividend); ir_node *new_divisor = transform_node(env, divisor); @@ -1233,10 +1241,17 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *node, } if(mode_is_signed(mode)) { - res = new_rd_ia32_IDiv(dbg, irg, block, new_dividend, new_divisor, edx_node, new_mem, dm_flav); + res = new_rd_ia32_IDiv(dbg, irg, block, noreg, noreg, new_dividend, edx_node, new_divisor, new_mem, dm_flav); } else { - res = new_rd_ia32_Div(dbg, irg, block, new_dividend, new_divisor, edx_node, new_mem, dm_flav); + res = new_rd_ia32_Div(dbg, irg, block, noreg, noreg, new_dividend, edx_node, new_divisor, new_mem, dm_flav); } + + /* Matze: code can't handle this at the moment... */ +#if 0 + /* set AM support */ + set_ia32_am_support(res, ia32_am_Source); +#endif + set_ia32_n_res(res, 2); /* Only one proj is used -> We must add a second proj and */ @@ -2039,8 +2054,8 @@ static ir_node *gen_Psi(ia32_transform_env_t *env, ir_node *node) { /* in case the compare operands are int, we move them into xmm register */ if (! mode_is_float(get_irn_mode(cmp_a))) { - new_cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, new_cmp_a, node, mode_D); - new_cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, new_cmp_b, node, mode_D); + new_cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, new_cmp_a, node, mode_E); + new_cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, new_cmp_b, node, mode_E); pnc |= 8; /* transform integer compare to fp compare */ } @@ -2416,7 +2431,7 @@ static ir_node *gen_be_StackParam(ia32_transform_env_t *env, ir_node *node) { pn_res = pn_ia32_vfld_res; } - proj_mode = mode_D; + proj_mode = mode_E; } else { new_op = new_rd_ia32_Load(dbg, irg, block, new_ptr, noreg, nomem); proj_mode = mode_Iu; @@ -2553,105 +2568,6 @@ static ir_node *gen_be_FrameStore(ia32_transform_env_t *env, ir_node *node) { return new_op; } -/** - * In case SSE is used we need to copy the result from FPU TOS. - */ -static ir_node *gen_be_Call(ia32_transform_env_t *env, ir_node *node) { - ir_graph *irg = env->irg; - dbg_info *dbg = get_irn_dbg_info(node); - ir_node *block = transform_node(env, get_nodes_block(node)); - ir_node *call_res = be_get_Proj_for_pn(node, pn_be_Call_first_res); - ir_node *call_mem = be_get_Proj_for_pn(node, pn_be_Call_M_regular); - ir_mode *mode; - ir_node *nomem = new_NoMem(); - ir_node *noreg = ia32_new_NoReg_gp(env->cg); - - if (! call_res || ! USE_SSE2(env->cg)) { - return duplicate_node(env, node); - } - - mode = get_irn_mode(call_res); - - /* in case there is no memory output: create one to serialize the copy FPU -> SSE */ - if (call_mem == NULL) - call_mem = new_rd_Proj(dbg, irg, block, node, mode_M, pn_be_Call_M_regular); - - if (mode_is_float(mode)) { - /* store st(0) onto stack */ - ir_node *frame = get_irg_frame(irg); - ir_node *fstp = new_rd_ia32_GetST0(dbg, irg, block, frame, noreg, nomem); - ir_entity *ent = frame_alloc_area(get_irg_frame_type(irg), get_mode_size_bytes(mode), 16, 0); - ir_node *sse_load, *p, *bad, *keep; - ir_node *mproj; - ir_node **in_keep; - int keep_arity, i; - - // Matze: TODO, fix this for new transform code... - assert(0); - - set_ia32_ls_mode(fstp, mode); - set_ia32_op_type(fstp, ia32_AddrModeD); - set_ia32_use_frame(fstp); - set_ia32_frame_ent(fstp, ent); - set_ia32_am_flavour(fstp, ia32_am_B); - set_ia32_am_support(fstp, ia32_am_Dest); - - /* load into SSE register */ - sse_load = new_rd_ia32_xLoad(dbg, irg, block, frame, ia32_new_NoReg_gp(env->cg), fstp); - set_ia32_ls_mode(sse_load, mode); - set_ia32_op_type(sse_load, ia32_AddrModeS); - set_ia32_use_frame(sse_load); - set_ia32_frame_ent(sse_load, ent); - set_ia32_am_flavour(sse_load, ia32_am_B); - set_ia32_am_support(sse_load, ia32_am_Source); - mproj = new_rd_Proj(dbg, irg, block, sse_load, mode_M, pn_ia32_xLoad_M); - sse_load = new_rd_Proj(dbg, irg, block, sse_load, mode, pn_ia32_xLoad_res); - - /* reroute all users of the result proj to the sse load */ - edges_reroute(call_res, sse_load, irg); - edges_reroute_kind(call_res, sse_load, EDGE_KIND_DEP, irg); - - /* reroute all users of the old call memory to the sse load memory */ - edges_reroute(call_mem, mproj, irg); - edges_reroute_kind(call_mem, mproj, EDGE_KIND_DEP, irg); - - /* now, we can set the old call mem as input of GetST0 */ - set_irn_n(fstp, 1, call_mem); - - /* now: create new Keep whith all former ins and one additional in - the result Proj */ - - /* get a Proj representing a caller save register */ - p = be_get_Proj_for_pn(node, pn_be_Call_first_res + 1); - assert(is_Proj(p) && "Proj expected."); - - /* user of the the proj is the Keep */ - p = get_edge_src_irn(get_irn_out_edge_first(p)); - assert(be_is_Keep(p) && "Keep expected."); - - /* copy in array of the old keep and set the result proj as additional in */ - keep_arity = get_irn_arity(p) + 1; - NEW_ARR_A(ir_node *, in_keep, keep_arity); - in_keep[keep_arity - 1] = call_res; - for (i = 0; i < keep_arity - 1; ++i) - in_keep[i] = get_irn_n(p, i); - - /* create new keep and set the in class requirements properly */ - keep = be_new_Keep(NULL, irg, block, keep_arity, in_keep); - for(i = 0; i < keep_arity; ++i) { - const arch_register_class_t *cls = arch_get_irn_reg_class(env->cg->arch_env, in_keep[i], -1); - be_node_set_reg_class(keep, i, cls); - } - - /* kill the old keep */ - bad = get_irg_bad(irg); - for (i = 0; i < keep_arity - 1; i++) - set_irn_n(p, i, bad); - remove_End_keepalive(get_irg_end(irg), p); - } - - return duplicate_node(env, node); -} - /** * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return. */ @@ -2666,7 +2582,7 @@ static ir_node *gen_be_Return(ia32_transform_env_t *env, ir_node *node) { ir_type *res_type; ir_mode *mode; ir_node *frame, *sse_store, *fld, *mproj, *barrier; - ir_node *new_barrier, *new_frame, *new_ret_val, *new_ret_mem; + ir_node *new_barrier, *new_ret_val, *new_ret_mem; ir_node **in; int pn_ret_val, pn_ret_mem, arity, i; @@ -2687,7 +2603,6 @@ static ir_node *gen_be_Return(ia32_transform_env_t *env, ir_node *node) { } assert(get_method_n_ress(tp) == 1); - mode = mode_D; pn_ret_val = get_Proj_proj(ret_val); pn_ret_mem = get_Proj_proj(ret_mem); @@ -2704,13 +2619,12 @@ static ir_node *gen_be_Return(ia32_transform_env_t *env, ir_node *node) { new_ret_mem = transform_node(env, ret_mem); frame = get_irg_frame(irg); - new_frame = transform_node(env, frame); dbg = get_irn_dbg_info(barrier); block = transform_node(env, get_nodes_block(barrier)); /* store xmm0 onto stack */ - sse_store = new_rd_ia32_xStoreSimple(dbg, irg, block, new_frame, new_ret_val, new_ret_mem); + sse_store = new_rd_ia32_xStoreSimple(dbg, irg, block, frame, new_ret_val, new_ret_mem); set_ia32_ls_mode(sse_store, mode); set_ia32_op_type(sse_store, ia32_AddrModeD); set_ia32_use_frame(sse_store); @@ -2718,7 +2632,7 @@ static ir_node *gen_be_Return(ia32_transform_env_t *env, ir_node *node) { set_ia32_am_support(sse_store, ia32_am_Dest); /* load into st0 */ - fld = new_rd_ia32_SetST0(dbg, irg, block, new_frame, sse_store); + fld = new_rd_ia32_SetST0(dbg, irg, block, frame, sse_store); set_ia32_ls_mode(fld, mode); set_ia32_op_type(fld, ia32_AddrModeS); set_ia32_use_frame(fld); @@ -2726,7 +2640,7 @@ static ir_node *gen_be_Return(ia32_transform_env_t *env, ir_node *node) { set_ia32_am_support(fld, ia32_am_Source); mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_SetST0_M); - fld = new_r_Proj(irg, block, fld, mode_D, pn_ia32_SetST0_res); + fld = new_r_Proj(irg, block, fld, mode_E, pn_ia32_SetST0_res); arch_set_irn_register(env->cg->arch_env, fld, &ia32_vfp_regs[REG_VF0]); /* create a new barrier */ @@ -2847,8 +2761,8 @@ static ir_node *gen_Phi(ia32_transform_env_t *env, ir_node *node) { mode = mode_Iu; } else if(mode_is_float(mode)) { assert(mode == mode_D || mode == mode_F); - // all float operations are on mode_D registers - mode = mode_D; + // all float operations are on mode_E registers + mode = mode_E; } /* phi nodes allow loops, so we use the old arguments for now @@ -3234,7 +3148,7 @@ static ir_node *gen_ia32_l_X87toSSE(ia32_transform_env_t *env, ir_node *node) { set_ia32_am_support(res, ia32_am_Source); set_ia32_am_flavour(res, ia32_B); set_ia32_op_type(res, ia32_AddrModeS); - res = new_rd_Proj(dbg, irg, block, res, mode_D, pn_ia32_xLoad_res); + res = new_rd_Proj(dbg, irg, block, res, mode_E, pn_ia32_xLoad_res); return res; } @@ -3387,7 +3301,7 @@ static ir_node *gen_Proj_be_AddSP(ia32_transform_env_t *env, ir_node *node) { dbg_info *dbg = get_irn_dbg_info(node); ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); if(proj == pn_be_AddSP_res) { ir_node *res = new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_AddSP_stack); @@ -3407,7 +3321,7 @@ static ir_node *gen_Proj_be_SubSP(ia32_transform_env_t *env, ir_node *node) { dbg_info *dbg = get_irn_dbg_info(node); ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); if(proj == pn_be_SubSP_res) { ir_node *res = new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_AddSP_stack); @@ -3427,7 +3341,7 @@ static ir_node *gen_Proj_Load(ia32_transform_env_t *env, ir_node *node) { dbg_info *dbg = get_irn_dbg_info(node); ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); /* renumber the proj */ if(is_ia32_Load(new_pred)) { @@ -3438,13 +3352,13 @@ static ir_node *gen_Proj_Load(ia32_transform_env_t *env, ir_node *node) { } } else if(is_ia32_xLoad(new_pred)) { if(proj == pn_Load_res) { - return new_rd_Proj(dbg, irg, block, new_pred, mode_D, pn_ia32_xLoad_res); + return new_rd_Proj(dbg, irg, block, new_pred, mode_E, pn_ia32_xLoad_res); } else if(proj == pn_Load_M) { return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_xLoad_M); } } else if(is_ia32_vfld(new_pred)) { if(proj == pn_Load_res) { - return new_rd_Proj(dbg, irg, block, new_pred, mode_D, pn_ia32_vfld_res); + return new_rd_Proj(dbg, irg, block, new_pred, mode_E, pn_ia32_vfld_res); } else if(proj == pn_Load_M) { return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_vfld_M); } @@ -3462,7 +3376,7 @@ static ir_node *gen_Proj_DivMod(ia32_transform_env_t *env, ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)); @@ -3516,7 +3430,7 @@ static ir_node *gen_Proj_CopyB(ia32_transform_env_t *env, ir_node *node) ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); switch(proj) { case pn_CopyB_M_regular: @@ -3545,13 +3459,13 @@ static ir_node *gen_Proj_l_vfdiv(ia32_transform_env_t *env, ir_node *node) ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); switch(proj) { case pn_ia32_l_vfdiv_M: return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M); case pn_ia32_l_vfdiv_res: - return new_rd_Proj(dbg, irg, block, new_pred, mode_D, pn_ia32_vfdiv_res); + return new_rd_Proj(dbg, irg, block, new_pred, mode_E, pn_ia32_vfdiv_res); default: assert(0); } @@ -3568,7 +3482,7 @@ static ir_node *gen_Proj_Quot(ia32_transform_env_t *env, ir_node *node) ir_node *pred = get_Proj_pred(node); ir_node *new_pred = transform_node(env, pred); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); switch(proj) { case pn_Quot_M: @@ -3582,10 +3496,10 @@ static ir_node *gen_Proj_Quot(ia32_transform_env_t *env, ir_node *node) break; case pn_Quot_res: if(is_ia32_xDiv(new_pred)) { - return new_rd_Proj(dbg, irg, block, new_pred, mode, + return new_rd_Proj(dbg, irg, block, new_pred, mode_E, pn_ia32_xDiv_res); } else if(is_ia32_vfdiv(new_pred)) { - return new_rd_Proj(dbg, irg, block, new_pred, mode, + return new_rd_Proj(dbg, irg, block, new_pred, mode_E, pn_ia32_vfdiv_res); } break; @@ -3599,7 +3513,8 @@ static ir_node *gen_Proj_Quot(ia32_transform_env_t *env, ir_node *node) static ir_node *gen_Proj_tls(ia32_transform_env_t *env, ir_node *node) { ir_graph *irg = env->irg; - dbg_info *dbg = get_irn_dbg_info(node); + //dbg_info *dbg = get_irn_dbg_info(node); + dbg_info *dbg = NULL; ir_node *block = transform_node(env, get_nodes_block(node)); ir_node *res = new_rd_ia32_LdTls(dbg, irg, block, mode_Iu); @@ -3607,11 +3522,106 @@ static ir_node *gen_Proj_tls(ia32_transform_env_t *env, ir_node *node) { return res; } +static ir_node *gen_Proj_be_Call(ia32_transform_env_t *env, ir_node *node) { + ir_graph *irg = env->irg; + dbg_info *dbg = get_irn_dbg_info(node); + long proj = get_Proj_proj(node); + ir_mode *mode = get_irn_mode(node); + ir_node *block = transform_node(env, get_nodes_block(node)); + ir_node *sse_load; + ir_node *call = get_Proj_pred(node); + ir_node *new_call = transform_node(env, call); + + /* The following is kinda tricky: If we're using SSE, then we have to + * move the result value of the call in floating point registers to an + * xmm register, we therefore construct a GetST0 -> xLoad sequence + * after the call, we have to make sure to correctly make the + * MemProj and the result Proj use these 2 nodes + */ + if(proj == pn_be_Call_M_regular) { + // get new node for result, are we doing the sse load/store hack? + ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res); + ir_node *call_res_new; + ir_node *call_res_pred = NULL; + + if(call_res != NULL) { + call_res_new = transform_node(env, call_res); + call_res_pred = get_Proj_pred(call_res_new); + } + + if(call_res_pred == NULL || be_is_Call(call_res_pred)) { + return new_rd_Proj(dbg, irg, block, new_call, mode_M, pn_be_Call_M_regular); + } else { + assert(is_ia32_xLoad(call_res_pred)); + return new_rd_Proj(dbg, irg, block, call_res_pred, mode_M, pn_ia32_xLoad_M); + } + } + if(proj == pn_be_Call_first_res && mode_is_float(mode) + && USE_SSE2(env->cg)) { + ir_node *fstp; + ir_node *frame = get_irg_frame(irg); + ir_node *noreg = ia32_new_NoReg_gp(env->cg); + ir_node *p; + ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular); + ir_node *keepin[1]; + const arch_register_class_t *cls; + + /* in case there is no memory output: create one to serialize the copy FPU -> SSE */ + call_mem = new_rd_Proj(dbg, irg, block, new_call, mode_M, pn_be_Call_M_regular); + + /* store st(0) onto stack */ + fstp = new_rd_ia32_GetST0(dbg, irg, block, frame, noreg, call_mem); + + set_ia32_ls_mode(fstp, mode); + set_ia32_op_type(fstp, ia32_AddrModeD); + set_ia32_use_frame(fstp); + set_ia32_am_flavour(fstp, ia32_am_B); + set_ia32_am_support(fstp, ia32_am_Dest); + + /* load into SSE register */ + sse_load = new_rd_ia32_xLoad(dbg, irg, block, frame, noreg, fstp); + set_ia32_ls_mode(sse_load, mode); + set_ia32_op_type(sse_load, ia32_AddrModeS); + set_ia32_use_frame(sse_load); + set_ia32_am_flavour(sse_load, ia32_am_B); + set_ia32_am_support(sse_load, ia32_am_Source); + + //mproj = new_rd_Proj(dbg, irg, block, sse_load, mode_M, pn_ia32_xLoad_M); + sse_load = new_rd_Proj(dbg, irg, block, sse_load, mode_E, pn_ia32_xLoad_res); + + /* now: create new Keep whith all former ins and one additional in - the result Proj */ + + /* get a Proj representing a caller save register */ + p = be_get_Proj_for_pn(call, pn_be_Call_first_res + 1); + assert(is_Proj(p) && "Proj expected."); + + /* user of the the proj is the Keep */ + p = get_edge_src_irn(get_irn_out_edge_first(p)); + assert(be_is_Keep(p) && "Keep expected."); + + /* keep the result */ + cls = arch_get_irn_reg_class(env->cg->arch_env, sse_load, -1); + keepin[0] = sse_load; + be_new_Keep(cls, irg, block, 1, keepin); + + return sse_load; + } + + /* transform call modes to the mode_Iu or mode_E */ + if(mode_is_float(mode)) { + mode = mode_E; + } else if(mode != mode_M) { + mode = mode_Iu; + } + + return new_rd_Proj(dbg, irg, block, new_call, mode, proj); +} + static ir_node *gen_Proj(ia32_transform_env_t *env, ir_node *node) { ir_graph *irg = env->irg; dbg_info *dbg = get_irn_dbg_info(node); ir_node *pred = get_Proj_pred(node); - int proj = get_Proj_proj(node); + long proj = get_Proj_proj(node); if(is_Store(pred) || be_is_FrameStore(pred)) { if(proj == pn_Store_M) { @@ -3634,6 +3644,8 @@ static ir_node *gen_Proj(ia32_transform_env_t *env, ir_node *node) { return gen_Proj_be_SubSP(env, node); } else if(be_is_AddSP(pred)) { return gen_Proj_be_AddSP(env, node); + } else if(be_is_Call(pred)) { + return gen_Proj_be_Call(env, node); } else if(get_irn_op(pred) == op_Start) { if(proj == pn_Start_X_initial_exec) { ir_node *block = get_nodes_block(pred); @@ -3747,7 +3759,7 @@ static void register_transformers(void) { /* handle generic backend nodes */ GEN(be_FrameAddr); - GEN(be_Call); + //GEN(be_Call); GEN(be_Return); GEN(be_FrameLoad); GEN(be_FrameStore); @@ -3795,19 +3807,27 @@ static ir_node *duplicate_node(ia32_transform_env_t *env, ir_node *node) ir_node *block; ir_node *new_node; int i, arity; - ir_node **ins; block = transform_node(env, get_nodes_block(node)); arity = get_irn_arity(node); - ins = alloca(arity * sizeof(ins[0])); - for(i = 0; i < arity; ++i) { - ir_node *in = get_irn_n(node, i); - ins[i] = transform_node(env, in); + if(op->opar == oparity_dynamic) { + new_node = new_ir_node(dbg, irg, block, op, mode, -1, NULL); + for(i = 0; i < arity; ++i) { + ir_node *in = get_irn_n(node, i); + in = transform_node(env, in); + add_irn_n(new_node, in); + } + } else { + ir_node **ins = alloca(arity * sizeof(ins[0])); + for(i = 0; i < arity; ++i) { + ir_node *in = get_irn_n(node, i); + ins[i] = transform_node(env, in); + } + + new_node = new_ir_node(dbg, irg, block, op, mode, arity, ins); } - new_node = new_ir_node(dbg, irg, block, - op, mode, arity, ins); copy_node_attr(node, new_node); duplicate_deps(env, node, new_node);