- } else {
- res = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, nomem, res, in1);
- set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);
- set_ia32_commutative(res);
- }
-
- SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(cg, irn));
- /* copy register */
- slots = get_ia32_slots(res);
- slots[0] = in2_reg;
-
- /* exchange the add and the sub */
- edges_reroute(irn, res, irg);
-
- /* add to schedule */
- sched_add_before(irn, res);
-
- /* remove the old sub */
- sched_remove(irn);
- arity = get_irn_arity(irn);
- for(i = 0; i < arity; ++i) {
- set_irn_n(irn, i, new_Bad());
- }
-
- DBG_OPT_SUB2NEGADD(irn, res);
-}
-
-static INLINE int is_noreg(ia32_code_gen_t *cg, const ir_node *node)
-{
- return node == cg->noreg_gp;
-}
-
-static ir_node *create_immediate_from_int(ia32_code_gen_t *cg, int val)
-{
- ir_graph *irg = current_ir_graph;
- ir_node *start_block = get_irg_start_block(irg);
- ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block, NULL,
- 0, val);
- arch_set_irn_register(cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
-
- return immediate;
-}
-
-static ir_node *create_immediate_from_am(ia32_code_gen_t *cg,
- const ir_node *node)
-{
- ir_graph *irg = get_irn_irg(node);
- ir_node *block = get_nodes_block(node);
- int offset = get_ia32_am_offs_int(node);
- int sc_sign = is_ia32_am_sc_sign(node);
- ir_entity *entity = get_ia32_am_sc(node);
- ir_node *res;
-
- res = new_rd_ia32_Immediate(NULL, irg, block, entity, sc_sign, offset);
- arch_set_irn_register(cg->arch_env, res, &ia32_gp_regs[REG_GP_NOREG]);
- return res;
-}
-
-static int is_am_one(const ir_node *node)
-{
- int offset = get_ia32_am_offs_int(node);
- ir_entity *entity = get_ia32_am_sc(node);
-
- return offset == 1 && entity == NULL;
-}
-
-static int is_am_minus_one(const ir_node *node)
-{
- int offset = get_ia32_am_offs_int(node);
- ir_entity *entity = get_ia32_am_sc(node);
-
- return offset == -1 && entity == NULL;
-}
-
-/**
- * Transforms a LEA into an Add or SHL if possible.
- * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
- */
-static void ia32_transform_lea_to_add_or_shl(ir_node *node, ia32_code_gen_t *cg)
-{
- const arch_env_t *arch_env = cg->arch_env;
- ir_graph *irg = current_ir_graph;
- ir_node *base;
- ir_node *index;
- const arch_register_t *base_reg;
- const arch_register_t *index_reg;
- const arch_register_t *out_reg;
- int scale;
- int has_immediates;
- ir_node *op1;
- ir_node *op2;
- dbg_info *dbgi;
- ir_node *block;
- ir_node *res;
- ir_node *noreg;
- ir_node *nomem;
-
- if(!is_ia32_Lea(node))
- return;
-
- base = get_irn_n(node, n_ia32_Lea_base);
- index = get_irn_n(node, n_ia32_Lea_index);
-
- if(is_noreg(cg, base)) {
- base = NULL;
- base_reg = NULL;
- } else {
- base_reg = arch_get_irn_register(arch_env, base);
- }
- if(is_noreg(cg, index)) {
- index = NULL;
- index_reg = NULL;
- } else {
- index_reg = arch_get_irn_register(arch_env, index);
- }