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)
*/
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;
}
}
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));
}
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)
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;
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");
}