X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_emitter.c;h=fb11964d7f57e986827fd28e223a8cd3dff899a2;hb=3bf79be6379b877beb90b9bd6ea285b2d928dbd8;hp=8612528a56045f59b5d1ff036b1a4eedea20028e;hpb=80856828546f1fbf56f46f642e9a952fe46f2c0b;p=libfirm diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 8612528a5..fb11964d7 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -23,6 +23,8 @@ #include "../besched_t.h" #include "../benode_t.h" +#include "../beabi.h" +#include "../be_dbgout.h" #include "ia32_emitter.h" #include "gen_ia32_emitter.h" @@ -1789,22 +1791,24 @@ static void emit_ia32_Const(const ir_node *n, ia32_emit_env_t *env) { FILE *F = env->out; char cmd_buf[256], cmnt_buf[256]; const lc_arg_env_t *arg_env = ia32_get_arg_env(); - - if (get_ia32_Immop_tarval(n) == get_tarval_null(get_irn_mode(n))) { - const char *instr = "xor"; - if (env->isa->opt_arch == arch_pentium_4) { - /* P4 prefers sub r, r, others xor r, r */ - instr = "sub"; - } - lc_esnprintf(arg_env, cmd_buf, 256, "%s %1D, %1D ", instr, n, n); - lc_esnprintf(arg_env, cmnt_buf, 256, "/* optimized mov 0 to register */"); - } - else { - if (get_ia32_op_type(n) == ia32_SymConst) { - 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 { + ir_mode *mode = get_irn_mode(n); + tarval *tv = get_ia32_Immop_tarval(n); + + if (get_ia32_op_type(n) == ia32_SymConst) { + 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)); + /* 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"; + if (env->isa->opt_arch == arch_pentium_4) { + /* P4 prefers sub r, r, others xor r, r */ + instr = "sub"; + } + lc_esnprintf(arg_env, cmd_buf, 256, "%s %1D, %1D ", instr, n, n); + lc_esnprintf(arg_env, cmnt_buf, 256, "/* optimized mov 0 to register */"); + } else { lc_esnprintf(arg_env, cmd_buf, 256, "mov %1D, %C ", n, n); lc_esnprintf(arg_env, cmnt_buf, 256, "/* Mov Const into register */"); } @@ -1836,6 +1840,30 @@ static void emit_ia32_AddSP(const ir_node *irn, ia32_emit_env_t *emit_env) { IA32_DO_EMIT(irn); } +/** + * Emits code to increase stack pointer. + */ +static void emit_ia32_SubSP(const ir_node *irn, ia32_emit_env_t *emit_env) { + FILE *F = emit_env->out; + char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN]; + + if (is_ia32_ImmConst(irn)) { + lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1D, %C", irn, irn); + } + else if (is_ia32_ImmSymConst(irn)) { + if (get_ia32_op_type(irn) == ia32_Normal) + lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1D, OFFSET_FLAT:%C", irn, irn); + else /* source address mode */ + lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1D, [%s%s]", irn, get_id_str(get_ia32_am_sc(irn)), get_ia32_am_offs(irn)); + } + else { + lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1D, %2S", irn, irn); + } + snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* free space on stack */"); + + IA32_DO_EMIT(irn); +} + /** * Emits code to load the TLS base */ @@ -1921,6 +1949,7 @@ static void ia32_register_emitters(void) { IA32_EMIT(Conv_I2I8Bit); IA32_EMIT(Const); IA32_EMIT(AddSP); + IA32_EMIT(SubSP); IA32_EMIT(LdTls); IA32_EMIT(xCmp); IA32_EMIT(xCmpSet); @@ -1959,6 +1988,36 @@ static void ia32_register_emitters(void) { #undef IA32_EMIT } +static const char *last_name = NULL; +static unsigned last_line = -1; +static unsigned num = -1; + +/** + * Emit the debug support for node irn. + */ +static void ia32_emit_dbg(const ir_node *irn, ia32_emit_env_t *env) { + dbg_info *db = get_irn_dbg_info(irn); + unsigned lineno; + const char *fname = be_retrieve_dbg_info(db, &lineno); + + if (fname) { + if (last_name != fname) { + last_line = -1; + be_dbg_include_begin(env->cg->birg->main_env->db_handle, fname); + last_name = fname; + } + if (last_line != lineno) { + char name[64]; + FILE *F = env->out; + + snprintf(name, sizeof(name), ".LM%u", ++num); + last_line = lineno; + be_dbg_line(env->cg->birg->main_env->db_handle, lineno, name); + fprintf(F, "%s:\n", name); + } + } +} + /** * Emits code for a node. */ @@ -1971,6 +2030,7 @@ static void ia32_emit_node(const ir_node *irn, void *env) { if (op->ops.generic) { void (*emit)(const ir_node *, void *) = (void (*)(const ir_node *, void *))op->ops.generic; + ia32_emit_dbg(irn, emit_env); (*emit)(irn, env); } else { @@ -2073,6 +2133,7 @@ static void ia32_gen_block(ir_node *block, void *env) { } /* emit the contents of the block */ + ia32_emit_dbg(block, env); sched_foreach(block, irn) { ia32_emit_node(irn, env); } @@ -2081,12 +2142,15 @@ static void ia32_gen_block(ir_node *block, void *env) { /** * Emits code for function start. */ -static void ia32_emit_func_prolog(FILE *F, ir_graph *irg, cpu_support cpu) { +static void ia32_emit_func_prolog(FILE *F, ir_graph *irg, ia32_emit_env_t *emit_env) { entity *irg_ent = get_irg_entity(irg); const char *irg_name = get_entity_ld_name(irg_ent); + cpu_support cpu = emit_env->isa->opt_arch; + const be_irg_t *birg = emit_env->cg->birg; fprintf(F, "\n"); ia32_switch_section(F, SECTION_TEXT); + be_dbg_method_begin(birg->main_env->db_handle, irg_ent, be_abi_get_stack_layout(birg->abi)); ia32_emit_align_func(F, cpu); if (get_entity_visibility(irg_ent) == visibility_external_visible) { fprintf(F, ".globl %s\n", irg_name); @@ -2098,10 +2162,12 @@ static void ia32_emit_func_prolog(FILE *F, ir_graph *irg, cpu_support cpu) { /** * Emits code for function end */ -static void ia32_emit_func_epilog(FILE *F, ir_graph *irg) { +static void ia32_emit_func_epilog(FILE *F, ir_graph *irg, ia32_emit_env_t *emit_env) { const char *irg_name = get_entity_ld_name(get_irg_entity(irg)); + const be_irg_t *birg = emit_env->cg->birg; ia32_dump_function_size(F, irg_name); + be_dbg_method_end(birg->main_env->db_handle); fprintf(F, "\n"); } @@ -2138,7 +2204,7 @@ void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) { ia32_register_emitters(); - ia32_emit_func_prolog(F, irg, emit_env.isa->opt_arch); + ia32_emit_func_prolog(F, irg, &emit_env); irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env); if ((cg->opt & IA32_OPT_EXTBB) && cg->blk_sched) { @@ -2163,5 +2229,5 @@ void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) { irg_walk_blkwise_graph(irg, NULL, ia32_gen_block, &emit_env); } - ia32_emit_func_epilog(F, irg); + ia32_emit_func_epilog(F, irg, &emit_env); }