fixed warnings
[libfirm] / ir / be / mips / mips_emitter.c
index a46d66c..6a1ea25 100644 (file)
@@ -62,19 +62,19 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 static const arch_register_t *get_in_reg(const arch_env_t *arch_env,
                                          const ir_node *node, int pos)
 {
-    ir_node                *op;
-    const arch_register_t  *reg = NULL;
+       ir_node                *op;
+       const arch_register_t  *reg = NULL;
 
-    assert(get_irn_arity(node) > pos && "Invalid IN position");
+       assert(get_irn_arity(node) > pos && "Invalid IN position");
 
-    /* The out register of the operator at position pos is the
-       in register we need. */
-    op = get_irn_n(node, pos);
+       /* The out register of the operator at position pos is the
+          in register we need. */
+       op = get_irn_n(node, pos);
 
-    reg = arch_get_irn_register(arch_env, op);
+       reg = arch_get_irn_register(arch_env, op);
 
-    assert(reg && "no in register found");
-    return reg;
+       assert(reg && "no in register found");
+       return reg;
 }
 
 /**
@@ -83,33 +83,33 @@ static const arch_register_t *get_in_reg(const arch_env_t *arch_env,
 static const arch_register_t *get_out_reg(const arch_env_t *arch_env,
                                           const ir_node *node, int pos)
 {
-    ir_node                *proj;
-    const arch_register_t  *reg = NULL;
+       ir_node                *proj;
+       const arch_register_t  *reg = NULL;
 
-    /* 1st case: irn is not of mode_T, so it has only                 */
-    /*           one OUT register -> good                             */
-    /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
-    /*           Proj with the corresponding projnum for the register */
+       /* 1st case: irn is not of mode_T, so it has only                 */
+       /*           one OUT register -> good                             */
+       /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
+       /*           Proj with the corresponding projnum for the register */
 
-    if (get_irn_mode(node) != mode_T) {
-        reg = arch_get_irn_register(arch_env, node);
-    } else if (is_mips_irn(node)) {
-        reg = get_mips_out_reg(node, pos);
-    } else {
-        const ir_edge_t *edge;
-
-        foreach_out_edge(node, edge) {
-            proj = get_edge_src_irn(edge);
-            assert(is_Proj(proj) && "non-Proj from mode_T node");
-            if (get_Proj_proj(proj) == pos) {
-                reg = arch_get_irn_register(arch_env, proj);
-                break;
-            }
-        }
-    }
+       if (get_irn_mode(node) != mode_T) {
+               reg = arch_get_irn_register(arch_env, node);
+       } else if (is_mips_irn(node)) {
+               reg = get_mips_out_reg(node, pos);
+       } else {
+               const ir_edge_t *edge;
+
+               foreach_out_edge(node, edge) {
+                       proj = get_edge_src_irn(edge);
+                       assert(is_Proj(proj) && "non-Proj from mode_T node");
+                       if (get_Proj_proj(proj) == pos) {
+                               reg = arch_get_irn_register(arch_env, proj);
+                               break;
+                       }
+               }
+       }
 
-    assert(reg && "no out register found");
-    return reg;
+       assert(reg && "no out register found");
+       return reg;
 }
 
 /*************************************************************
@@ -123,17 +123,25 @@ static const arch_register_t *get_out_reg(const arch_env_t *arch_env,
  * |_|                                       |_|
  *************************************************************/
 
+/**
+ * Emit the name of the source register at given input position.
+ */
 void mips_emit_source_register(mips_emit_env_t *env, const ir_node *node,
                                int pos)
 {
        const arch_register_t *reg = get_in_reg(env->arch_env, node, pos);
+       be_emit_char(env->emit, '$');
        be_emit_string(env->emit, arch_register_get_name(reg));
 }
 
+/**
+ * Emit the name of the destination register at given output position.
+ */
 void mips_emit_dest_register(mips_emit_env_t *env, const ir_node *node,
                              int pos)
 {
        const arch_register_t *reg = get_out_reg(env->arch_env, node, pos);
+       be_emit_char(env->emit, '$');
        be_emit_string(env->emit, arch_register_get_name(reg));
 }
 
@@ -223,11 +231,13 @@ static const char *node_const_to_str(ir_node *n)
 
 void mips_emit_immediate(mips_emit_env_t *env, const ir_node *node)
 {
-       const mips_attr_t *attr;
+       const mips_attr_t *attr = get_mips_attr_const(node);
 
-       be_emit_char(env->emit, '$');
-       attr = get_mips_attr(node);
-       be_emit_tarval(env->emit, attr->tv);
+       if(attr->tv != NULL) {
+               be_emit_tarval(env->emit, attr->tv);
+       } else {
+               be_emit_cstring(env->emit, "/* TODO */ 0");
+       }
 }
 
 /*
@@ -294,7 +304,7 @@ void mips_emit_nops(mips_emit_env_t *env, int n)
        }
 }
 
-static void mips_emit_Perm(const ir_node *node, mips_emit_env_t *env)
+static void mips_emit_Perm(mips_emit_env_t *env, const ir_node *node)
 {
        assert(get_irn_arity(node) == 2);
 
@@ -329,29 +339,6 @@ static void mips_emit_Perm(const ir_node *node, mips_emit_env_t *env)
        /* mips_emit_nops(env, 3); */
 }
 
-
-static void mips_emit_Spill(mips_emit_env_t *env, const ir_node *node)
-{
-#if 0
-       FILE      *F   = env->out;
-       ir_entity *ent = be_get_frame_entity(node);
-
-       lc_efprintf(mips_get_arg_env(), F, "\tsw %1S, %d($fp)\n", node, get_entity_offset(ent));
-#endif
-       /* TODO lower spills and don't emit them... */
-}
-
-static void mips_emit_Reload(mips_emit_env_t *env, const ir_node *node)
-{
-#if 0
-       FILE      *F   = env->out;
-       ir_entity *ent = be_get_frame_entity(node);
-
-       lc_efprintf(mips_get_arg_env(), F, "\tlw %1D, %d($fp)\n", node, get_entity_offset(ent));
-#endif
-       /* TODO lower reloads instead of emitting them... */
-}
-
 /************************************************************************/
 /* Calls                                                                */
 /************************************************************************/
@@ -365,7 +352,7 @@ static void mips_emit_Call(mips_emit_env_t *env, const ir_node *node)
        /* call of immediate value (label) */
        callee = be_Call_get_entity(node);
        if(callee != NULL) {
-               be_emit_ident(env->emit, get_entity_ident(callee));
+               be_emit_ident(env->emit, get_entity_ld_ident(callee));
        } else {
                mips_emit_source_register(env, node, be_pos_Call_ptr);
        }
@@ -389,10 +376,13 @@ const char* mips_get_block_label(const ir_node* block)
        return buf;
 }
 
+/**
+ * Emits a block label from the given block.
+ */
 static
 void mips_emit_block_label(mips_emit_env_t *env, const ir_node *block)
 {
-       be_emit_irprintf(env->emit, "BLOCK_%ld", get_irn_node_nr(block));
+       be_emit_irprintf(env->emit, "BLOCK_%d", get_irn_node_nr(block));
 }
 
 static void mips_emit_Jump(mips_emit_env_t *env, const ir_node *node)
@@ -405,7 +395,7 @@ static void mips_emit_Jump(mips_emit_env_t *env, const ir_node *node)
        be_emit_finish_line_gas(env->emit, node);
 }
 
-ir_node *mips_get_jump_block(const ir_node* node, int projn)
+ir_node *mips_get_jump_block(const ir_node* node, long projn)
 {
        const ir_edge_t *oute;
        for(oute = get_irn_out_edge_first(node); oute != NULL;
@@ -422,7 +412,8 @@ ir_node *mips_get_jump_block(const ir_node* node, int projn)
        return NULL;
 }
 
-void mips_emit_jump_target_proj(mips_emit_env_t *env, const ir_node *node, int projn)
+void mips_emit_jump_target_proj(mips_emit_env_t *env, const ir_node *node,
+                                long projn)
 {
        ir_node *jumpblock = mips_get_jump_block(node, projn);
        assert(jumpblock != NULL);
@@ -438,13 +429,24 @@ void mips_emit_jump_target(mips_emit_env_t *env, const ir_node *node)
        mips_emit_block_label(env, jumpblock);
 }
 
+void mips_emit_jump_or_fallthrough(mips_emit_env_t *env, const ir_node *node,
+                                   long pn)
+{
+       ir_node *jumpblock = mips_get_jump_block(node, pn);
+       assert(jumpblock != NULL);
+
+       /* TODO: use fallthrough when possible */
+       be_emit_cstring(env->emit, "b ");
+       mips_emit_block_label(env, jumpblock);
+}
+
 /************************************************************************
- *  ____          _ _       _         _                                                                        *
- * / ___|_      _(_) |_ ___| |__     | |_   _ _ __ ___  _ __                   *
- * \___ \ \ /\ / / | __/ __| '_ \ _  | | | | | '_ ` _ \| '_ \                  *
- *  ___) \ V  V /| | || (__| | | | |_| | |_| | | | | | | |_) |                 *
- * |____/ \_/\_/ |_|\__\___|_| |_|\___/ \__,_|_| |_| |_| .__/                  *
- *                                                     |_|                             *
+ *  ____          _ _       _         _                                 *
+ * / ___|_      _(_) |_ ___| |__     | |_   _ _ __ ___  _ __            *
+ * \___ \ \ /\ / / | __/ __| '_ \ _  | | | | | '_ ` _ \| '_ \           *
+ *  ___) \ V  V /| | || (__| | | | |_| | |_| | | | | | | |_) |          *
+ * |____/ \_/\_/ |_|\__\___|_| |_|\___/ \__,_|_| |_| |_| .__/           *
+ *                                                     |_|              *
  *                                                                      *
  ************************************************************************/
 
@@ -490,11 +492,11 @@ const char* mips_get_jumptbl_label(const ir_node* switchjmp)
  * possible otherwise a cmp-jmp cascade). Stolen from ia32
  */
 void emit_mips_jump_table(mips_emit_env_t *env, const ir_node *irn) {
-       int              lastval, i, i2, pn;
-       jmp_tbl_t        tbl;
-       ir_node         *proj;
-       const ir_edge_t *edge;
-       mips_attr_t     *attr = get_mips_attr(irn);
+       int                lastval, i, i2, pn;
+       jmp_tbl_t          tbl;
+       ir_node           *proj;
+       const ir_edge_t   *edge;
+       const mips_attr_t *attr = get_mips_attr_const(irn);
 
        /* fill the table structure */
        tbl.label        = xmalloc(SNPRINTF_BUF_LEN);
@@ -536,7 +538,7 @@ void emit_mips_jump_table(mips_emit_env_t *env, const ir_node *irn) {
 
                for(i2 = lastval + 1; i2 < value; ++i2) {
                        be_emit_cstring(env->emit, "\t.word ");
-                       be_emit_ident(env->emit, attr->symconst_id);
+                       be_emit_ident(env->emit, get_entity_ld_ident(attr->symconst));
                        be_emit_char(env->emit, '\n');
                        be_emit_write_line(env->emit);
                }
@@ -582,20 +584,34 @@ void dump_jump_tables(ir_node* node, void *data)
  *
  ***********************************************************************************/
 
-static void mips_emit_nothing(ir_mode *mode, mips_emit_env_t *env)
+static void mips_emit_nothing(mips_emit_env_t *env, const ir_node *node)
 {
+       (void) env;
+       (void) node;
 }
 
-static void mips_emit_this_shouldnt_happen(ir_mode *mode, mips_emit_env_t *env)
+static void mips_emit_this_shouldnt_happen(mips_emit_env_t *env, const ir_node *node)
 {
-       assert(0);
+       (void) env;
+       panic("Found non-lowered node %+F while emitting", node);
+}
+
+/**
+ * The type of a emitter function.
+ */
+typedef void (*emit_func) (mips_emit_env_t *, const ir_node *);
+
+/**
+ * Set a node emitter. Make it a bit more type safe.
+ */
+static void register_emitter(ir_op *op, emit_func func) {
+       op->ops.generic = (op_func) func;
 }
 
 /**
  * Register emitter functions for mips backend
  */
-void mips_register_emitters(void)
-{
+void mips_register_emitters(void) {
        /* first clear the generic function pointer for all ops */
        clear_irp_opcodes_generic_func();
 
@@ -603,28 +619,29 @@ void mips_register_emitters(void)
        mips_register_spec_emitters();
 
        /* benode emitter */
-       op_be_IncSP->ops.generic = (op_func) mips_emit_IncSP;
-       op_be_SetSP->ops.generic = (op_func) mips_emit_this_shouldnt_happen;
-       op_be_AddSP->ops.generic = (op_func) mips_emit_this_shouldnt_happen;
-       op_be_Call->ops.generic = (op_func) mips_emit_Call;
-       op_be_Keep->ops.generic = (op_func) mips_emit_nothing;
-       op_be_Copy->ops.generic = (op_func) mips_emit_Copy;
-       op_be_Return->ops.generic = (op_func) mips_emit_Return;
-       op_be_RegParams->ops.generic = (op_func) mips_emit_nothing;
-       op_be_Spill->ops.generic = (op_func) mips_emit_Spill;
-       op_be_Reload->ops.generic = (op_func) mips_emit_Reload;
-       op_be_Perm->ops.generic = (op_func) mips_emit_Perm;
-
-       op_Start->ops.generic = (op_func) mips_emit_nothing;
-       op_Proj->ops.generic = (op_func) mips_emit_nothing;
-       op_SymConst->ops.generic = (op_func) mips_emit_nothing;
-       op_Jmp->ops.generic = (op_func) mips_emit_Jump;
-       op_Cmp->ops.generic = (op_func) mips_emit_this_shouldnt_happen;
-       op_Cond->ops.generic = (op_func) mips_emit_this_shouldnt_happen;
+       register_emitter(op_be_IncSP, mips_emit_IncSP);
+       register_emitter(op_be_SetSP, mips_emit_this_shouldnt_happen);
+       register_emitter(op_be_AddSP, mips_emit_this_shouldnt_happen);
+       register_emitter(op_be_Call, mips_emit_Call);
+       register_emitter(op_be_Copy, mips_emit_Copy);
+       register_emitter(op_be_Keep, mips_emit_nothing);
+       register_emitter(op_be_Barrier, mips_emit_nothing);
+       register_emitter(op_be_Return, mips_emit_Return);
+       register_emitter(op_be_RegParams, mips_emit_nothing);
+       register_emitter(op_be_Spill, mips_emit_this_shouldnt_happen);
+       register_emitter(op_be_Reload, mips_emit_this_shouldnt_happen);
+       register_emitter(op_be_Perm, mips_emit_Perm);
+
+       register_emitter(op_Start, mips_emit_nothing);
+       register_emitter(op_Proj, mips_emit_nothing);
+       register_emitter(op_SymConst, mips_emit_this_shouldnt_happen);
+       register_emitter(op_Const, mips_emit_this_shouldnt_happen);
+       register_emitter(op_Jmp, mips_emit_Jump);
+       register_emitter(op_Cmp, mips_emit_this_shouldnt_happen);
+       register_emitter(op_Cond, mips_emit_this_shouldnt_happen);
+       register_emitter(op_Phi, mips_emit_nothing);
 }
 
-typedef void (*emit_func) (mips_emit_env_t *, const ir_node *);
-
 /**
  * Emits assembly for a single node
  */
@@ -636,8 +653,7 @@ static void mips_emit_node(mips_emit_env_t *env, const ir_node *node)
                emit_func emit = (emit_func) op->ops.generic;
                (*emit) (env, node);
        } else {
-               be_emit_cstring(env->emit, "\t/* TODO */");
-               be_emit_finish_line_gas(env->emit, node);
+               panic("No emitter defined for node %+F", node);
        }
 }
 
@@ -669,7 +685,7 @@ void mips_gen_block(mips_emit_env_t *env, ir_node *block)
  */
 void mips_emit_func_prolog(mips_emit_env_t *env, ir_graph *irg)
 {
-       ident *irg_ident = get_entity_ident(get_irg_entity(irg));
+       ident *irg_ident = get_entity_ld_ident(get_irg_entity(irg));
        be_emit_env_t *eenv = env->emit;
 
        // dump jump tables
@@ -680,7 +696,7 @@ void mips_emit_func_prolog(mips_emit_env_t *env, ir_graph *irg)
 
        be_emit_cstring(eenv, "\t.balign\t4\n");
 
-       be_emit_cstring(eenv, "\t.global\t")
+       be_emit_cstring(eenv, "\t.global\t");
        be_emit_ident(eenv, irg_ident);
        be_emit_char(eenv, '\n');
 
@@ -720,6 +736,7 @@ void mips_gen_labels(ir_node *block, void *env)
 {
        ir_node *pred;
        int n = get_Block_n_cfgpreds(block);
+       (void) env;
 
        for (n--; n >= 0; n--) {
                pred = get_Block_cfgpred(block, n);