X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_emitter.c;h=4cd44f10d3da8e912347a84317c8f1f434f51a13;hb=a1a465eb2b3f54027b29f829423fffd0396937f4;hp=fbd37614e78e64a6465000fa9f762acc76c04511;hpb=2a71b11dca7b76908f86689dce38d8bc73291a8c;p=libfirm diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index fbd37614e..4cd44f10d 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -128,13 +128,6 @@ static void ia32_dump_function_size(FILE *F, const char *name) * |_| |_| *************************************************************/ -/** - * returns true if a node has x87 registers - */ -static INLINE int has_x87_register(const ir_node *n) { - return is_irn_machine_user(n, 0); -} - /* We always pass the ir_node which is a pointer. */ static int ia32_get_arg_type(const lc_arg_occ_t *occ) { return lc_arg_type_ptr; @@ -627,7 +620,7 @@ const char *ia32_emit_am(const ir_node *n, ia32_emit_env_t *env) { /* obstack_free with NULL results in an uninitialized obstack */ obstack_init(obst); - p = pointer_size(mode, has_x87_register(n) || is_ia32_GetST0(n) || is_ia32_SetST0(n)); + p = pointer_size(mode, ia32_has_x87_register(n) || is_ia32_GetST0(n) || is_ia32_SetST0(n)); if (p) obstack_printf(obst, "%s ", p); @@ -693,7 +686,7 @@ const char *ia32_emit_adr(const ir_node *irn, ia32_emit_env_t *env) static char buf[SNPRINTF_BUF_LEN]; ir_mode *mode = get_ia32_ls_mode(irn); const char *adr = get_ia32_cnst(irn); - const char *pref = pointer_size(mode, has_x87_register(irn)); + const char *pref = pointer_size(mode, ia32_has_x87_register(irn)); snprintf(buf, SNPRINTF_BUF_LEN, "%s %s", pref ? pref : "", adr); return buf; @@ -1745,7 +1738,7 @@ static void Copy_emitter(const ir_node *irn, ir_node *op, ia32_emit_env_t *emit_ char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN]; if (REGS_ARE_EQUAL(arch_get_irn_register(aenv, irn), arch_get_irn_register(aenv, op)) || - arch_register_type_is(arch_get_irn_register(aenv, op), joker)) + arch_register_type_is(arch_get_irn_register(aenv, op), virtual)) return; if (mode_is_float(get_irn_mode(irn))) @@ -1826,7 +1819,7 @@ static void emit_ia32_Const(const ir_node *n, ia32_emit_env_t *env) { lc_esnprintf(arg_env, cmd_buf, 256, "mov %1D, OFFSET FLAT:%C ", n, n); lc_esnprintf(arg_env, cmnt_buf, 256, "/* Move address of SymConst into register */"); } else { - assert(mode == get_tarval_mode(tv)); + assert(mode == get_tarval_mode(tv) || (mode_is_reference(get_tarval_mode(tv)) && mode == mode_Iu)); /* beware: in some rare cases mode is mode_b which has no tarval_null() */ if (tv == get_tarval_b_false() || tv == get_tarval_null(mode)) { const char *instr = "xor"; @@ -2157,37 +2150,55 @@ static int is_first_loop_block(ir_node *block, ir_node *prev_block, ia32_emit_en * and emits code for each node. */ static void ia32_gen_block(ir_node *block, ir_node *last_block, ia32_emit_env_t *env) { - ir_graph *irg = get_irn_irg(block); - ir_node *start_block = get_irg_start_block(irg); + ir_graph *irg = get_irn_irg(block); + ir_node *start_block = get_irg_start_block(irg); + int need_label = 1; + FILE *F = env->out; const ir_node *irn; - int need_label = 1; - FILE *F = env->out; + int i; assert(is_Block(block)); - if(block == start_block) + if (block == start_block) need_label = 0; if (need_label && get_irn_arity(block) == 1) { ir_node *pred_block = get_Block_cfgpred_block(block, 0); - if(pred_block == last_block && get_irn_n_edges_kind(pred_block, EDGE_KIND_BLOCK) <= 2) + if (pred_block == last_block && get_irn_n_edges_kind(pred_block, EDGE_KIND_BLOCK) <= 2) need_label = 0; } - // special case because the start block contains no jump instruction - if(last_block == start_block) { + /* special case: if one of our cfg preds is a switch-jmp we need a label, */ + /* otherwise there might be jump table entries jumping to */ + /* non-existent (omitted) labels */ + for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) { + ir_node *pred = get_Block_cfgpred(block, i); + + if (is_Proj(pred)) { + assert(get_irn_mode(pred) == mode_X); + if (is_ia32_SwitchJmp(get_Proj_pred(pred))) { + need_label = 1; + break; + } + } + } + + /* special case because the start block contains no jump instruction */ + if (last_block == start_block) { const ir_edge_t *edge; ir_node *startsucc = NULL; foreach_block_succ(start_block, edge) { startsucc = get_edge_src_irn(edge); - if(startsucc != start_block) + if (startsucc != start_block) break; } assert(startsucc != NULL); - if(startsucc != block) { + /* if the last block was the start block and we are not inside the */ + /* start successor, emit a jump to the start successor */ + if (startsucc != block) { char buf[SNPRINTF_BUF_LEN]; ir_snprintf(buf, sizeof(buf), BLOCK_PREFIX("%d"), get_irn_node_nr(startsucc)); @@ -2201,21 +2212,22 @@ static void ia32_gen_block(ir_node *block, ir_node *last_block, ia32_emit_env_t int align = 1; ir_exec_freq *execfreqs = env->cg->birg->execfreqs; - // align the loop headers - if(!is_first_loop_block(block, last_block, env)) { - - // align blocks where the previous block has no fallthrough + /* align the loop headers */ + if (! is_first_loop_block(block, last_block, env)) { + /* align blocks where the previous block has no fallthrough */ arity = get_irn_arity(block); - for(i = 0; i < arity; ++i) { + + for (i = 0; i < arity; ++i) { ir_node *predblock = get_Block_cfgpred_block(block, i); - if(predblock == last_block) { + + if (predblock == last_block) { align = 0; break; } } } - if(align) + if (align) ia32_emit_align_label(env->out, env->isa->opt_arch); ir_snprintf(cmd_buf, sizeof(cmd_buf), BLOCK_PREFIX("%d:"), @@ -2226,11 +2238,12 @@ static void ia32_gen_block(ir_node *block, ir_node *last_block, ia32_emit_env_t fprintf(F, "/* preds:"); arity = get_irn_arity(block); - for(i = 0; i < arity; ++i) { + for (i = 0; i < arity; ++i) { ir_node *predblock = get_Block_cfgpred_block(block, i); fprintf(F, " %ld", get_irn_node_nr(predblock)); } - if(execfreqs != NULL) { + + if (execfreqs != NULL) { fprintf(F, " freq: %f", get_block_execfreq(execfreqs, block)); }