Added phi handler
[libfirm] / ir / be / ia32 / ia32_emitter.c
index 8c714bd..d391370 100644 (file)
@@ -44,8 +44,13 @@ extern int obstack_printf(struct obstack *obst, char *fmt, ...);
 
 #define SNPRINTF_BUF_LEN 128
 
+/* global arch_env for lc_printf functions */
 static const arch_env_t *arch_env = NULL;
 
+/* indicates whether blocks are scheduled or not
+   (this variable is set automatically) */
+static int have_block_sched       = 0;
+
 /*************************************************************
  *             _       _    __   _          _
  *            (_)     | |  / _| | |        | |
@@ -292,7 +297,10 @@ char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
                        break;
                case ia32_AddrModeD:
                        if (get_ia32_cnst(n)) {
-                               lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %s", ia32_emit_am(n, env), get_ia32_cnst(n));
+                               lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s,%s%s",
+                                       ia32_emit_am(n, env),
+                                       get_ia32_sc(n) ? " OFFSET FLAT:" : " ",    /* In case of a symconst we must add OFFSET to */
+                                       get_ia32_cnst(n));                         /* tell the assembler to store it's address.   */
                        }
                        else {
                                const arch_register_t *in1 = get_in_reg(n, 2);
@@ -544,7 +552,6 @@ static char *get_cfop_target(const ir_node *irn, char *buf) {
        return buf;
 }
 
-static int have_block_sched = 0;
 /** Return the next block in Block schedule */
 static ir_node *next_blk_sched(const ir_node *block) {
        return have_block_sched ? get_irn_link(block) : NULL;
@@ -670,12 +677,7 @@ static void emit_ia32_TestJmp(const ir_node *irn, ia32_emit_env_t *env) {
        TestJmp_emitter(irn, env);
 }
 
-/**
- * Emits code for conditional test and jump with immediate.
- */
-static void emit_ia32_TestJmp_i(const ir_node *irn, ia32_emit_env_t *env) {
-       TestJmp_emitter(irn, env);
-}
+
 
 /*********************************************************
  *                 _ _       _
@@ -825,7 +827,7 @@ void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
                                        snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default case */");
                                        IA32_DO_EMIT;
                                }
-                               snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[i].target, buf), last_value);
+                               snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[i].target, buf));
                                snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", last_value);
                                IA32_DO_EMIT;
                        }
@@ -1215,6 +1217,9 @@ static void ia32_emit_node(const ir_node *irn, void *env) {
 static void ia32_gen_block(ir_node *block, void *env) {
        const ir_node *irn;
 
+       if (! is_Block(block))
+               return;
+
        fprintf(((ia32_emit_env_t *)env)->out, BLOCK_PREFIX("%ld:\n"), get_irn_node_nr(block));
        sched_foreach(block, irn) {
                ia32_emit_node(irn, env);
@@ -1294,7 +1299,7 @@ void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
        anchor list;
        ir_node *block;
 
-       emit_env.mod      = firm_dbg_register("ir.be.codegen.ia32");
+       emit_env.mod      = firm_dbg_register("firm.be.ia32.emitter");
        emit_env.out      = F;
        emit_env.arch_env = cg->arch_env;
        emit_env.cg       = cg;
@@ -1308,20 +1313,25 @@ void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
        ia32_emit_func_prolog(F, irg);
        irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env);
 
-#if 0
-       have_block_sched = 0;
-       irg_block_walk_graph(irg, NULL, ia32_gen_block, &emit_env);
-#else
-       compute_extbb(irg);
+       if (cg->opt.extbb) {
+               /* schedule extended basic blocks */
 
-       list.start = NULL;
-       list.end   = NULL;
-       irg_extblock_walk_graph(irg, NULL, create_block_list, &list);
+               compute_extbb(irg);
 
-       have_block_sched = 1;
-       for (block = list.start; block; block = get_irn_link(block))
-               ia32_gen_block(block, &emit_env);
-#endif
+               list.start = NULL;
+               list.end   = NULL;
+               irg_extblock_walk_graph(irg, NULL, create_block_list, &list);
+
+               have_block_sched = 1;
+               for (block = list.start; block; block = get_irn_link(block))
+                       ia32_gen_block(block, &emit_env);
+       }
+       else {
+               /* "normal" block schedule */
+
+               have_block_sched = 0;
+               irg_walk_blkwise_graph(irg, NULL, ia32_gen_block, &emit_env);
+       }
 
        ia32_emit_func_epilog(F, irg);
 }