DBG_OPT_SUB2NEGADD(irn, res);
}
-static INLINE int need_constraint_copy(ir_node *irn) {
- /* the 3 operand form of IMul needs no constraint copy */
- if(is_ia32_IMul(irn)) {
- ir_node *right = get_irn_n(irn, n_ia32_IMul_right);
- if(is_ia32_Immediate(right))
+static INLINE int need_constraint_copy(ir_node *irn)
+{
+ /* TODO this should be determined from the node specification */
+ switch (get_ia32_irn_opcode(irn)) {
+ case iro_ia32_IMul: {
+ /* the 3 operand form of IMul needs no constraint copy */
+ ir_node *right = get_irn_n(irn, n_ia32_IMul_right);
+ return !is_ia32_Immediate(right);
+ }
+
+ case iro_ia32_Lea:
+ case iro_ia32_Conv_I2I:
+ case iro_ia32_Conv_I2I8Bit:
+ case iro_ia32_CMov:
return 0;
- }
- return ! is_ia32_Lea(irn) &&
- ! is_ia32_Conv_I2I(irn) &&
- ! is_ia32_Conv_I2I8Bit(irn) &&
- ! is_ia32_CMov(irn);
+ default:
+ return 1;
+ }
}
/**
* register -> base or index is broken then.
* Solution: Turn back this address mode into explicit Load + Operation.
*/
-static void fix_am_source(ir_node *irn, void *env) {
+static void fix_am_source(ir_node *irn, void *env)
+{
ia32_code_gen_t *cg = env;
const arch_env_t *arch_env = cg->arch_env;
ir_node *base;
if (! is_ia32_irn(irn) || get_ia32_op_type(irn) != ia32_AddrModeS)
return;
/* only need to fix binary operations */
- if (get_ia32_am_arity(irn) != ia32_am_binary)
+ if (get_ia32_am_support(irn) != ia32_am_binary)
return;
base = get_irn_n(irn, n_ia32_base);
/* copy address mode information to load */
set_ia32_op_type(load, ia32_AddrModeS);
ia32_copy_am_attrs(load, irn);
+ if (is_ia32_is_reload(irn))
+ set_ia32_is_reload(load);
/* insert the load into schedule */
sched_add_before(irn, load);
arch_set_irn_register(cg->arch_env, load_res, out_reg);
/* set the new input operand */
- set_irn_n(irn, n_ia32_binary_right, load_res);
- if(get_irn_mode(irn) == mode_T) {
+ if (is_ia32_Immediate(get_irn_n(irn, n_ia32_binary_right)))
+ set_irn_n(irn, n_ia32_binary_left, load_res);
+ else
+ set_irn_n(irn, n_ia32_binary_right, load_res);
+ if (get_irn_mode(irn) == mode_T) {
const ir_edge_t *edge, *next;
foreach_out_edge_safe(irn, edge, next) {
ir_node *node = get_edge_src_irn(edge);
} else if (pn == pn_ia32_mem) {
set_Proj_pred(node, load);
set_Proj_proj(node, pnmem);
+ } else {
+ panic("Unexpected Proj");
}
}
set_irn_mode(irn, mode_Iu);