-/**
- * 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);
-}
-