emit new block labels
[libfirm] / ir / be / mips / mips_emitter.c
index dd0e56a..a04d4d5 100644 (file)
@@ -54,6 +54,8 @@
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
+#define BLOCK_PREFIX ".L"
+
 #define SNPRINTF_BUF_LEN 128
 
 /**
@@ -229,27 +231,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 = get_mips_attr(node);
+       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");
+       }
+}
 
-       if(attr->tv != NULL) {
-               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 {
-               be_emit_cstring(env->emit, "/* TODO */ 0");
+               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                                                         */
@@ -382,7 +435,14 @@ 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_%d", get_irn_node_nr(block));
+       if (has_Block_label(block)) {
+               be_emit_string(env, be_gas_label_prefix());
+               be_emit_irprintf(env->emit, "%lu", get_Block_label(block));
+       } else {
+               be_emit_cstring(env, BLOCK_PREFIX);
+               be_emit_irprintf(env->emit, "%d", get_irn_node_nr(block));
+
+       }
 }
 
 static void mips_emit_Jump(mips_emit_env_t *env, const ir_node *node)
@@ -450,6 +510,7 @@ void mips_emit_jump_or_fallthrough(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;
@@ -469,7 +530,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;
 
@@ -492,11 +554,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);
@@ -573,6 +635,7 @@ void dump_jump_tables(ir_node* node, void *data)
                be_emit_write_line(env->emit);
        }
 }
+#endif
 
 /***********************************************************************************
  *                  _          __                                             _
@@ -689,7 +752,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);
@@ -736,6 +799,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);