Remove ia32_am_ternary. The only users were Div an IDiv, which are perfectly fine...
[libfirm] / ir / be / ia32 / ia32_emitter.c
index 6a6f0da..d9e1270 100644 (file)
@@ -74,6 +74,7 @@ static ia32_code_gen_t  *cg;
 static int               do_pic;
 static char              pic_base_label[128];
 static ir_label_t        exc_label_id;
+static int               mark_spill_reload = 0;
 
 /** Return the next block in Block schedule */
 static ir_node *get_prev_block_sched(const ir_node *block)
@@ -634,40 +635,40 @@ static const struct cmp2conditon_t cmp2condition_u[] = {
  */
 static ir_node *find_original_value(ir_node *node)
 {
-       inc_irg_visited(current_ir_graph);
-       while(1) {
-               mark_irn_visited(node);
-               if (be_is_Copy(node)) {
-                       node = be_get_Copy_op(node);
-               } else if (be_is_CopyKeep(node)) {
-                       node = be_get_CopyKeep_op(node);
-               } else if (is_Proj(node)) {
-                       ir_node *pred = get_Proj_pred(node);
-                       if (be_is_Perm(pred)) {
-                               node = get_irn_n(pred, get_Proj_proj(node));
-                       } else if (be_is_MemPerm(pred)) {
-                               node = get_irn_n(pred, get_Proj_proj(node) + 1);
-                       } else if (is_ia32_Load(pred)) {
-                               node = get_irn_n(pred, n_ia32_Load_mem);
-                       } else {
-                               return node;
-                       }
-               } else if (is_ia32_Store(node)) {
-                       node = get_irn_n(node, n_ia32_Store_val);
-               } else if (is_Phi(node)) {
-                       int i, arity;
-                       arity = get_irn_arity(node);
-                       for(i = 0; i < arity; ++i) {
-                               ir_node *in = get_irn_n(node, i);
-                               if (irn_visited(in))
-                                       continue;
-                               node = in;
-                               break;
-                       }
-                       assert(i < arity);
+       if (irn_visited(node))
+               return NULL;
+
+       mark_irn_visited(node);
+       if (be_is_Copy(node)) {
+               return find_original_value(be_get_Copy_op(node));
+       } else if (be_is_CopyKeep(node)) {
+               return find_original_value(be_get_CopyKeep_op(node));
+       } else if (is_Proj(node)) {
+               ir_node *pred = get_Proj_pred(node);
+               if (be_is_Perm(pred)) {
+                       return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
+               } else if (be_is_MemPerm(pred)) {
+                       return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
+               } else if (is_ia32_Load(pred)) {
+                       return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
                } else {
                        return node;
                }
+       } else if (is_ia32_Store(node)) {
+               return find_original_value(get_irn_n(node, n_ia32_Store_val));
+       } else if (is_Phi(node)) {
+               int i, arity;
+               arity = get_irn_arity(node);
+               for (i = 0; i < arity; ++i) {
+                       ir_node *in  = get_irn_n(node, i);
+                       ir_node *res = find_original_value(in);
+
+                       if (res != NULL)
+                               return res;
+               }
+               return NULL;
+       } else {
+               return node;
        }
 }
 
@@ -682,7 +683,9 @@ static int determine_final_pnc(const ir_node *node, int flags_pos,
                ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
                if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
                                || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
+                       inc_irg_visited(current_ir_graph);
                        cmp = find_original_value(cmp);
+                       assert(cmp != NULL);
                        assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
                               || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
                }
@@ -699,10 +702,6 @@ static int determine_final_pnc(const ir_node *node, int flags_pos,
                        pnc = get_mirrored_pnc(pnc);
                pnc |= ia32_pn_Cmp_float;
        } else {
-#if 0
-               assert(is_ia32_Cmp(flags) || is_ia32_Test(flags)
-                               || is_ia32_Cmp8Bit(flags) || is_ia32_Test8Bit(flags));
-#endif
                flags_attr = get_ia32_attr_const(flags);
 
                if (flags_attr->data.ins_permuted)
@@ -1932,9 +1931,25 @@ static void ia32_emit_node(ir_node *node)
 
        DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
 
-       if (is_ia32_irn(node) && get_ia32_exc_label(node)) {
-               /* emit the exception label of this instruction */
-               ia32_assign_exc_label(node);
+       if (is_ia32_irn(node)) {
+               if (get_ia32_exc_label(node)) {
+                       /* emit the exception label of this instruction */
+                       ia32_assign_exc_label(node);
+               }
+               if (mark_spill_reload) {
+                       if (is_ia32_is_spill(node)) {
+                               be_emit_cstring("\txchg %ebx, %ebx        /* spill mark */\n");
+                               be_emit_write_line();
+                       }
+                       if (is_ia32_is_reload(node)) {
+                               be_emit_cstring("\txchg %edx, %edx        /* reload mark */\n");
+                               be_emit_write_line();
+                       }
+                       if (is_ia32_is_remat(node)) {
+                               be_emit_cstring("\txchg %ecx, %ecx        /* remat mark */\n");
+                               be_emit_write_line();
+                       }
+               }
        }
        if (op->ops.generic) {
                emit_func_ptr func = (emit_func_ptr) op->ops.generic;
@@ -2230,7 +2245,20 @@ void ia32_gen_routine(ia32_code_gen_t *ia32_cg, ir_graph *irg)
        DEL_ARR_F(exc_list);
 }
 
+static const lc_opt_table_entry_t ia32_emitter_options[] = {
+       LC_OPT_ENT_BOOL("mark_spill_reload",   "mark spills and reloads with ud opcodes", &mark_spill_reload),
+       LC_OPT_LAST
+};
+
 void ia32_init_emitter(void)
 {
+       lc_opt_entry_t *be_grp;
+       lc_opt_entry_t *ia32_grp;
+
+       be_grp   = lc_opt_get_grp(firm_opt_get_root(), "be");
+       ia32_grp = lc_opt_get_grp(be_grp, "ia32");
+
+       lc_opt_add_table(ia32_grp, ia32_emitter_options);
+
        FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");
 }