xStore, xLoad should have base latency 0
[libfirm] / ir / be / ia32 / ia32_finish.c
index 923aa06..9b23cac 100644 (file)
@@ -93,13 +93,14 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
        if(mode_is_float(mode)) {
                int size;
                ir_entity *entity;
+               ir_mode *op_mode = get_ia32_ls_mode(irn);
 
                res = new_rd_ia32_xXor(dbg, irg, block, noreg, noreg, in2, noreg_fp, nomem);
-               size = get_mode_size_bits(mode);
+               size = get_mode_size_bits(op_mode);
                entity = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
                set_ia32_am_sc(res, entity);
                set_ia32_op_type(res, ia32_AddrModeS);
-               set_ia32_ls_mode(res, get_ia32_ls_mode(irn));
+               set_ia32_ls_mode(res, op_mode);
        } else {
                res = new_rd_ia32_Neg(dbg, irg, block, in2);
        }
@@ -171,6 +172,22 @@ static ir_node *create_immediate_from_am(ia32_code_gen_t *cg,
        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.
@@ -243,8 +260,7 @@ static void ia32_transform_lea_to_add_or_shl(ir_node *node, ia32_code_gen_t *cg)
                        }
 #endif
                        op1 = base;
-                       op2 = create_immediate_from_am(cg, node);
-                       goto make_add;
+                       goto make_add_immediate;
                }
                if(scale == 0 && !has_immediates) {
                        op1 = base;
@@ -255,20 +271,19 @@ static void ia32_transform_lea_to_add_or_shl(ir_node *node, ia32_code_gen_t *cg)
                return;
        } else if(out_reg == index_reg) {
                if(base == NULL) {
-                  if(has_immediates && scale == 0) {
-                          op1 = index;
-                          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) {
+                       if(has_immediates && scale == 0) {
+                               op1 = index;
+                               goto make_add_immediate;
+                       } 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;
@@ -281,6 +296,25 @@ static void ia32_transform_lea_to_add_or_shl(ir_node *node, ia32_code_gen_t *cg)
                return;
        }
 
+make_add_immediate:
+       if(cg->isa->opt & IA32_OPT_INCDEC) {
+               if(is_am_one(node)) {
+                       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;
+               }
+               if(is_am_minus_one(node)) {
+                       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;
+               }
+       }
+       op2 = create_immediate_from_am(cg, node);
+
 make_add:
        dbgi  = get_irn_dbg_info(node);
        block = get_nodes_block(node);
@@ -288,7 +322,6 @@ make_add:
        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_op_type(res, ia32_Normal);
        set_ia32_commutative(res);
        goto exchange;
 
@@ -299,7 +332,6 @@ make_shl:
        nomem = new_NoMem();
        res   = new_rd_ia32_Shl(dbgi, irg, block, op1, op2);
        arch_set_irn_register(arch_env, res, out_reg);
-       set_ia32_op_type(res, ia32_Normal);
        goto exchange;
 
 exchange:
@@ -349,6 +381,7 @@ static void assure_should_be_same_requirements(ia32_code_gen_t *cg,
        if(!need_constraint_copy(node))
                return;
 
+       op_tp = get_ia32_op_type(node);
        reqs  = get_ia32_out_req_all(node);
        n_res = get_ia32_n_res(node);
        block = get_nodes_block(node);
@@ -406,7 +439,7 @@ static void assure_should_be_same_requirements(ia32_code_gen_t *cg,
                                uses_out_reg_pos = i2;
                }
 
-               /* noone else is using the out reg, we can simply copy it
+               /* no-one else is using the out reg, we can simply copy it
                 * (the register can't be live since the operation will override it
                 *  anyway) */
                if(uses_out_reg == NULL) {