lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
obstack_1grow(isa->name_obst, 0);
- isa->name_obst_size += obstack_object_size(isa->name_obst);
return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
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 {
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));
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));
*/
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);
+ 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);
}
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);
if (mode_is_float(mode)) {
/* store st(0) onto stack */
ir_node *frame = get_irg_frame(env->irg);
- ir_node *fstp = new_rd_ia32_GetST0(env->dbg, env->irg, env->block, frame, call_mem);
+ ir_node *fstp = new_rd_ia32_GetST0(env->dbg, env->irg, env->block, frame, get_irg_no_mem(env->irg));
ir_node *mproj = new_r_Proj(env->irg, env->block, fstp, mode_M, pn_ia32_GetST0_M);
entity *ent = frame_alloc_area(get_irg_frame_type(env->irg), get_mode_size_bytes(mode), 16, 0);
ir_node *sse_load, *p, *bad, *keep;
set_ia32_frame_ent(sse_load, ent);
set_ia32_am_flavour(sse_load, ia32_B);
set_ia32_am_support(sse_load, ia32_am_Source);
+ mproj = new_r_Proj(env->irg, env->block, sse_load, mode_M, pn_ia32_xLoad_M);
sse_load = new_r_Proj(env->irg, env->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, env->irg);
+ edges_reroute_kind(call_res, sse_load, EDGE_KIND_DEP, env->irg);
+
+ /* reroute all users of the old call memory to the sse load memory */
+ edges_reroute(call_mem, mproj, env->irg);
+ edges_reroute_kind(call_mem, mproj, EDGE_KIND_DEP, env->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 */
static ir_node *gen_be_Return(ia32_transform_env_t *env) {
ir_node *ret_val = get_irn_n(env->irn, be_pos_Return_val);
ir_node *ret_mem = get_irn_n(env->irn, be_pos_Return_mem);
- entity *ent = get_irg_entity(get_irn_irg(ret_val));
+ entity *ent = get_irg_entity(get_irn_irg(ret_val));
ir_type *tp = get_entity_type(ent);
if (be_Return_get_n_rets(env->irn) < 1 || ! ret_val || ! USE_SSE2(env->cg))
GEN_LOWERED_OP(Mul)
GEN_LOWERED_OP(Eor)
GEN_LOWERED_x87_OP(vfdiv)
+GEN_LOWERED_x87_OP(vfprem)
GEN_LOWERED_x87_OP(vfmul)
GEN_LOWERED_x87_OP(vfsub)
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;
}
set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
set_ia32_am_support(res, ia32_am_Dest);
set_ia32_am_flavour(res, ia32_B);
+ set_ia32_op_type(res, ia32_AddrModeD);
res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_vfst_M);
/* Load MEM -> SSE */
set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
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(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_xLoad_res);
}
else {
* In case SSE Unit is used, the node is transformed into a xStore + vfld.
*/
static ir_node *gen_ia32_l_SSEtoX87(ia32_transform_env_t *env) {
- ia32_code_gen_t *cg = env->cg;
- ir_node *res = NULL;
- ir_node *ptr = get_irn_n(env->irn, 0);
- ir_node *val = get_irn_n(env->irn, 1);
- ir_node *mem = get_irn_n(env->irn, 2);
+ ia32_code_gen_t *cg = env->cg;
+ ir_node *res = NULL;
+ ir_node *ptr = get_irn_n(env->irn, 0);
+ ir_node *val = get_irn_n(env->irn, 1);
+ ir_node *mem = get_irn_n(env->irn, 2);
+ entity *fent = get_ia32_frame_ent(env->irn);
+ ir_mode *lsmode = get_ia32_ls_mode(env->irn);
+ int offs = 0;
if (USE_SSE2(cg)) {
ir_node *noreg = ia32_new_NoReg_gp(cg);
/* Store SSE -> MEM */
- res = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
- set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
- set_ia32_use_frame(res);
- set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
- set_ia32_am_support(res, ia32_am_Dest);
- set_ia32_am_flavour(res, ia32_B);
- res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_xStore_M);
+ if (is_ia32_xLoad(skip_Proj(val))) {
+ ir_node *ld = skip_Proj(val);
+
+ /* we can vfld the value directly into the fpu */
+ fent = get_ia32_frame_ent(ld);
+ ptr = get_irn_n(ld, 0);
+ offs = get_ia32_am_offs_int(ld);
+ }
+ else {
+ res = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
+ set_ia32_frame_ent(res, fent);
+ set_ia32_use_frame(res);
+ set_ia32_ls_mode(res, lsmode);
+ set_ia32_am_support(res, ia32_am_Dest);
+ set_ia32_am_flavour(res, ia32_B);
+ set_ia32_op_type(res, ia32_AddrModeD);
+ mem = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_xStore_M);
+ }
/* Load MEM -> x87 */
res = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
- set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
+ set_ia32_frame_ent(res, fent);
set_ia32_use_frame(res);
- set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
+ set_ia32_ls_mode(res, lsmode);
+ add_ia32_am_offs_int(res, offs);
set_ia32_am_support(res, ia32_am_Source);
set_ia32_am_flavour(res, ia32_B);
- res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_vfld_res);
+ set_ia32_op_type(res, ia32_AddrModeS);
+ res = new_rd_Proj(env->dbg, env->irg, env->block, res, lsmode, pn_ia32_vfld_res);
}
else {
/* SSE unit is not used -> skip this node. */
GEN(ia32_l_ShlD);
GEN(ia32_l_ShrD);
GEN(ia32_l_vfdiv);
+ GEN(ia32_l_vfprem);
GEN(ia32_l_vfmul);
GEN(ia32_l_vfsub);
GEN(ia32_l_vfild);