missing include added
[libfirm] / ir / be / mips / mips_emitter.c
index 7beb5b5..158df07 100644 (file)
@@ -229,24 +229,78 @@ static const char *node_const_to_str(ir_node *n)
 }
 #endif
 
+void mips_emit_load_store_address(mips_emit_env_t *env, const ir_node *node,
+                                  int pos)
+{
+       const mips_load_store_attr_t *attr = get_mips_load_store_attr_const(node);
+
+       be_emit_irprintf(env->emit, "%d(", attr->offset);
+       mips_emit_source_register(env, node, pos);
+       be_emit_char(env->emit, ')');
+}
+
+void mips_emit_immediate_suffix(mips_emit_env_t *env, const ir_node *node,
+                                int pos)
+{
+       ir_node *op = get_irn_n(node, pos);
+       if(is_mips_Immediate(op))
+               be_emit_char(env->emit, 'i');
+}
+
 void mips_emit_immediate(mips_emit_env_t *env, const ir_node *node)
 {
-       const mips_attr_t *attr;
+       const mips_immediate_attr_t *attr = get_mips_immediate_attr_const(node);
+
+       switch(attr->imm_type) {
+       case MIPS_IMM_CONST:
+               be_emit_irprintf(env->emit, "%d", attr->val);
+               break;
+       case MIPS_IMM_SYMCONST_LO:
+               be_emit_cstring(env->emit, "%lo($");
+               be_emit_ident(env->emit, get_entity_ld_ident(attr->entity));
+               if(attr->val != 0) {
+                       be_emit_irprintf(env->emit, "%+d", attr->val);
+               }
+               be_emit_char(env->emit, ')');
+               break;
+       case MIPS_IMM_SYMCONST_HI:
+               be_emit_cstring(env->emit, "%hi($");
+               be_emit_ident(env->emit, get_entity_ld_ident(attr->entity));
+               if(attr->val != 0) {
+                       be_emit_irprintf(env->emit, "%+d", attr->val);
+               }
+               be_emit_char(env->emit, ')');
+               break;
+       default:
+               panic("invalid immediate type found");
+       }
+}
 
-       attr = get_mips_attr(node);
-       be_emit_tarval(env->emit, attr->tv);
+/**
+ * Emit the name of the destination register at given output position.
+ */
+void mips_emit_source_register_or_immediate(mips_emit_env_t *env,
+                                            const ir_node *node, int pos)
+{
+       const ir_node *op = get_irn_n(node, pos);
+       if(is_mips_Immediate(op)) {
+               mips_emit_immediate(env, op);
+       } else {
+               mips_emit_source_register(env, node, pos);
+       }
 }
 
+#if 0
 /*
  * Add a number to a prefix. This number will not be used a second time.
  */
-static
-char *get_unique_label(char *buf, size_t buflen, const char *prefix)
+static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
 {
        static unsigned long id = 0;
        snprintf(buf, buflen, "%s%lu", prefix, ++id);
        return buf;
 }
+#endif
 
 /************************************************************************/
 /* ABI Handling                                                         */
@@ -379,7 +433,7 @@ const char* mips_get_block_label(const ir_node* 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)
@@ -392,7 +446,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;
@@ -409,7 +463,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);
@@ -425,6 +480,17 @@ 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);
+}
+
 /************************************************************************
  *  ____          _ _       _         _                                 *
  * / ___|_      _(_) |_ ___| |__     | |_   _ _ __ ___  _ __            *
@@ -435,6 +501,7 @@ void mips_emit_jump_target(mips_emit_env_t *env, const ir_node *node)
  *                                                                      *
  ************************************************************************/
 
+#if 0
 /* jump table entry (target and corresponding number) */
 typedef struct _branch_t {
        ir_node *target;
@@ -454,7 +521,8 @@ typedef struct _jmp_tbl_t {
 /**
  * Compare two variables of type branch_t. Used to sort all switch cases
  */
-static int mips_cmp_branch_t(const void *a, const void *b) {
+static int mips_cmp_branch_t(const void *a, const void *b)
+{
        branch_t *b1 = (branch_t *)a;
        branch_t *b2 = (branch_t *)b;
 
@@ -477,11 +545,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);
@@ -523,7 +591,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);
                }
@@ -558,6 +626,7 @@ void dump_jump_tables(ir_node* node, void *data)
                be_emit_write_line(env->emit);
        }
 }
+#endif
 
 /***********************************************************************************
  *                  _          __                                             _
@@ -624,6 +693,7 @@ void mips_register_emitters(void) {
        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);
 }
 
 /**
@@ -673,7 +743,7 @@ void mips_emit_func_prolog(mips_emit_env_t *env, ir_graph *irg)
        be_emit_env_t *eenv = env->emit;
 
        // dump jump tables
-       irg_walk_graph(irg, NULL, dump_jump_tables, env);
+       //irg_walk_graph(irg, NULL, dump_jump_tables, env);
 
        be_emit_write_line(eenv);
        be_gas_emit_switch_section(eenv, GAS_SECTION_TEXT);
@@ -720,6 +790,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);