-
- /* we can transform leas where the out register is the same as either the
- * base or index register back to an Add or Shl */
- if(out_reg == base_reg) {
- if(index == NULL) {
-#ifdef DEBUG_libfirm
- if(!has_immediates) {
- ir_fprintf(stderr, "Optimisation warning: found lea which is "
- "just a copy\n");
- }
-#endif
- op1 = base;
- if(cg->isa->opt & IA32_OPT_INCDEC) {
- if(is_am_one(node)) {
- goto make_inc;
- }
- if(is_am_minus_one(node)) {
- goto make_dec;
- }
- }
- op2 = create_immediate_from_am(cg, node);
- goto make_add;
- }
- if(scale == 0 && !has_immediates) {
- op1 = base;
- op2 = index;
- goto make_add;
- }
- /* can't create an add */
- return;
- } else if(out_reg == index_reg) {
- if(base == NULL) {
- if(has_immediates && scale == 0) {
- op1 = index;
- if(cg->isa->opt & IA32_OPT_INCDEC) {
- if(is_am_one(node)) {
- goto make_inc;
- }
- if(is_am_minus_one(node)) {
- goto make_dec;
- }
- }
- op2 = create_immediate_from_am(cg, node);
- goto make_add;
- } else if(!has_immediates && scale > 0) {
- op1 = index;
- op2 = create_immediate_from_int(cg, scale);
- goto make_shl;
- } else if(!has_immediates) {
-#ifdef DEBUG_libfirm
- ir_fprintf(stderr, "Optimisation warning: found lea which is "
- "just a copy\n");
-#endif
- }
- } else if(scale == 0 && !has_immediates) {
- op1 = index;
- op2 = base;
- goto make_add;
- }
- /* can't create an add */
- return;
- } else {
- /* can't create an add */
- return;
- }
-
-make_add:
- dbgi = get_irn_dbg_info(node);
- block = get_nodes_block(node);
- noreg = ia32_new_NoReg_gp(cg);
- nomem = new_NoMem();
- res = new_rd_ia32_Add(dbgi, irg, block, noreg, noreg, op1, op2, nomem);
- arch_set_irn_register(arch_env, res, out_reg);
- set_ia32_commutative(res);
- goto exchange;
-
-make_inc:
- dbgi = get_irn_dbg_info(node);
- block = get_nodes_block(node);
- res = new_rd_ia32_Inc(dbgi, irg, block, op1);
- arch_set_irn_register(arch_env, res, out_reg);
- goto exchange;
-
-make_dec:
- dbgi = get_irn_dbg_info(node);
- block = get_nodes_block(node);
- res = new_rd_ia32_Dec(dbgi, irg, block, op1);
- arch_set_irn_register(arch_env, res, out_reg);
- goto exchange;
-
-make_shl:
- dbgi = get_irn_dbg_info(node);
- block = get_nodes_block(node);
- noreg = ia32_new_NoReg_gp(cg);
- nomem = new_NoMem();
- res = new_rd_ia32_Shl(dbgi, irg, block, op1, op2);
- arch_set_irn_register(arch_env, res, out_reg);
- goto exchange;
-
-exchange:
- SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(cg, node));
-
- /* add new ADD/SHL to schedule */
- sched_add_before(node, res);
-
- DBG_OPT_LEA2ADD(node, res);
-
- /* remove the old LEA */
- sched_remove(node);
-
- /* exchange the Add and the LEA */
- exchange(node, res);
-}
-
-static INLINE int need_constraint_copy(ir_node *irn) {
- return ! is_ia32_Lea(irn) &&
- ! is_ia32_Conv_I2I(irn) &&
- ! is_ia32_Conv_I2I8Bit(irn) &&
- ! is_ia32_TestCMov(irn) &&
- ! is_ia32_CmpCMov(irn);