if(get_mode_size_bits(conv_mode) < get_mode_size_bits(load_mode))
return;
+ if(get_mode_sign(conv_mode) != get_mode_sign(load_mode)) {
+ /* change the load if it has only 1 user */
+ if(get_irn_n_edges(pred) == 1) {
+ ir_mode *newmode;
+ if(get_mode_sign(conv_mode)) {
+ newmode = find_signed_mode(load_mode);
+ } else {
+ newmode = find_unsigned_mode(load_mode);
+ }
+ assert(newmode != NULL);
+ set_ia32_ls_mode(predpred, newmode);
+ } else {
+ /* otherwise we have to keep the conv */
+ return;
+ }
+ }
+
/* kill the conv */
exchange(node, pred);
}
if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node))
return;
- pred = get_irn_n(node, 2);
+ assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val);
+ pred = get_irn_n(node, n_ia32_Conv_I2I_val);
if(!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred))
return;
if(get_mode_size_bits(conv_mode) < get_mode_size_bits(pred_mode))
return;
+ /* we can't eliminate an upconv signed->unsigned */
+ if (get_mode_size_bits(conv_mode) != get_mode_size_bits(pred_mode) &&
+ !get_mode_sign(conv_mode) && get_mode_sign(pred_mode))
+ return;
+
/* kill the conv */
exchange(node, pred);
}
Conv_I2I => {
reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] },
units => [ "GP" ],
+ ins => [ "base", "index", "val", "mem" ],
mode => $mode_gp,
modified_flags => $status_flags
},
Conv_I2I8Bit => {
reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] },
+ ins => [ "base", "index", "val", "mem" ],
units => [ "GP" ],
mode => $mode_gp,
modified_flags => $status_flags
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *noreg = ia32_new_NoReg_gp(env.cg);
ir_mode *mode = get_Load_mode(node);
+ ir_mode *res_mode;
ir_node *lptr = new_ptr;
int is_imm = 0;
ir_node *new_op;
ia32_collect_Projs(node, 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 (! be_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(irg, block, node, mode_Iu, pn_ia32_Load_res);
- be_new_Keep(arch_get_irn_reg_class(env.cg->arch_env, proj, -1), irg, block, 1, &proj);
- }
-
/* address might be a constant (symconst or absolute address) */
if (is_ia32_Const(new_ptr)) {
lptr = noreg;
if (mode_is_float(mode)) {
FP_USED(env.cg);
if (USE_SSE2(env.cg)) {
- new_op = new_rd_ia32_xLoad(dbgi, irg, block, lptr, noreg, new_mem);
+ new_op = new_rd_ia32_xLoad(dbgi, irg, block, lptr, noreg, new_mem);
+ res_mode = mode_xmm;
} else {
- new_op = new_rd_ia32_vfld(dbgi, irg, block, lptr, noreg, new_mem);
+ new_op = new_rd_ia32_vfld(dbgi, irg, block, lptr, noreg, new_mem);
+ res_mode = mode_vfp;
}
} else {
- new_op = new_rd_ia32_Load(dbgi, irg, block, lptr, noreg, new_mem);
+ new_op = new_rd_ia32_Load(dbgi, irg, block, lptr, noreg, new_mem);
+ res_mode = mode_Iu;
+ }
+
+ /*
+ check for special case: the loaded value might not be used
+ */
+ if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) {
+ /* add a result proj and a Keep to produce a pseudo use */
+ ir_node *proj = new_r_Proj(irg, block, new_op, mode_Iu,
+ pn_ia32_Load_res);
+ be_new_Keep(arch_get_irn_reg_class(env.cg->arch_env, proj, -1), irg, block, 1, &proj);
}
/* base is a constant address */