perform custom abi construction in sparc as well to handle floatingpoint
[libfirm] / ir / be / sparc / sparc_emitter.c
index 40da546..d9544a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
 #include "gen_sparc_emitter.h"
 #include "sparc_nodes_attr.h"
 #include "sparc_new_nodes.h"
+#include "gen_sparc_regalloc_if.h"
 
-#define SNPRINTF_BUF_LEN 128
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
-/**
- * attribute of SAVE node which follows immediatelly after the START node
- * we need this to correct all offsets since SPARC expects
- * some reserved stack space after the stackpointer
- */
-const sparc_save_attr_t *save_attr;
-
 /**
  * Returns the register at in position pos.
  */
@@ -116,25 +109,11 @@ static const arch_register_t *get_out_reg(const ir_node *node, int pos)
        return reg;
 }
 
-/*************************************************************
- *             _       _    __   _          _
- *            (_)     | |  / _| | |        | |
- *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
- * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
- * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
- * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
- * | |                                       | |
- * |_|                                       |_|
- *************************************************************/
-
 void sparc_emit_immediate(const ir_node *node)
 {
-       // TODO: make sure it's a valid simm13 ?
-       const sparc_attr_t *attr = get_sparc_attr_const(node);
-
-       assert(!(attr->immediate_value < -4096 || attr->immediate_value > 4096));
-
-       be_emit_irprintf("%d", attr->immediate_value);
+       int const val = get_sparc_attr_const(node)->immediate_value;
+       assert(-4096 <= val && val < 4096);
+       be_emit_irprintf("%d", val);
 }
 
 void sparc_emit_source_register(const ir_node *node, int pos)
@@ -167,16 +146,28 @@ void sparc_emit_reg_or_imm(const ir_node *node, int pos)
        }
 }
 
+static bool is_stack_pointer_relative(const ir_node *node)
+{
+       const arch_register_t *sp = &sparc_gp_regs[REG_SP];
+       return (is_sparc_St(node) && get_in_reg(node, n_sparc_St_ptr) == sp)
+           || (is_sparc_Ld(node) && get_in_reg(node, n_sparc_Ld_ptr) == sp);
+}
+
 /**
  * emit SP offset
  */
 void sparc_emit_offset(const ir_node *node)
 {
        const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
-       assert(attr->base.is_load_store);
-
-       if (attr->offset > 0)
-               be_emit_irprintf("+%ld", attr->offset);
+       long                           offset = attr->offset;
+
+       /* bad hack: the real stack stuff is behind the always-there spill
+        * space for the register window and stack */
+       if (is_stack_pointer_relative(node))
+               offset += SPARC_MIN_STACKSIZE;
+       if (offset != 0) {
+               be_emit_irprintf("%+ld", offset);
+       }
 }
 
 
@@ -186,19 +177,19 @@ void sparc_emit_offset(const ir_node *node)
 void sparc_emit_load_mode(const ir_node *node)
 {
        const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
-    ir_mode *mode      = attr->load_store_mode;
-    int      bits      = get_mode_size_bits(mode);
-    bool     is_signed = mode_is_signed(mode);
-
-    if (bits == 16) {
-        be_emit_string(is_signed ? "sh" : "uh");
-    } else if (bits == 8) {
-        be_emit_string(is_signed ? "sb" : "ub");
-    } else if (bits == 64) {
-        be_emit_string("d");
-    } else {
-        assert(bits == 32);
-    }
+       ir_mode *mode      = attr->load_store_mode;
+       int      bits      = get_mode_size_bits(mode);
+       bool     is_signed = mode_is_signed(mode);
+
+       if (bits == 16) {
+               be_emit_string(is_signed ? "sh" : "uh");
+       } else if (bits == 8) {
+               be_emit_string(is_signed ? "sb" : "ub");
+       } else if (bits == 64) {
+               be_emit_string("d");
+       } else {
+               assert(bits == 32);
+       }
 }
 
 /**
@@ -207,18 +198,87 @@ void sparc_emit_load_mode(const ir_node *node)
 void sparc_emit_store_mode(const ir_node *node)
 {
        const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
-    ir_mode *mode      = attr->load_store_mode;
-    int      bits      = get_mode_size_bits(mode);
+       ir_mode *mode      = attr->load_store_mode;
+       int      bits      = get_mode_size_bits(mode);
+
+       if (bits == 16) {
+               be_emit_string("h");
+       } else if (bits == 8) {
+               be_emit_string("b");
+       } else if (bits == 64) {
+               be_emit_string("d");
+       } else {
+               assert(bits == 32);
+       }
+}
+
+/**
+ * emit integer signed/unsigned prefix char
+ */
+void sparc_emit_mode_sign_prefix(const ir_node *node)
+{
+       ir_mode *mode      = get_irn_mode(node);
+       bool     is_signed = mode_is_signed(mode);
+       be_emit_string(is_signed ? "s" : "u");
+}
+
+/**
+ * emit FP load mode char
+ */
+void sparc_emit_fp_load_mode(const ir_node *node)
+{
+       const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
+       ir_mode *mode      = attr->load_store_mode;
+       int      bits      = get_mode_size_bits(mode);
+
+       assert(mode_is_float(mode));
 
-    if (bits == 16) {
-        be_emit_string("h");
-    } else if (bits == 8) {
-        be_emit_string("b");
-    } else if (bits == 64) {
-        be_emit_string("d");
-    } else {
-        assert(bits == 32);
-    }
+       if (bits == 32) {
+               be_emit_string("f");
+       } else if (bits == 64) {
+               be_emit_string("df");
+       } else {
+               panic("FP load mode > 64bits not implemented yet");
+       }
+}
+
+/**
+ * emit FP store mode char
+ */
+void sparc_emit_fp_store_mode(const ir_node *node)
+{
+       const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
+       ir_mode *mode      = attr->load_store_mode;
+       int      bits      = get_mode_size_bits(mode);
+
+       assert(mode_is_float(mode));
+
+       if (bits == 32) {
+               be_emit_string("f");
+       } else if (bits == 64) {
+               be_emit_string("df");
+       } else {
+               panic("FP store mode > 64bits not implemented yet");
+       }
+}
+
+/**
+ * emits the FP mode suffix char
+ */
+void sparc_emit_fp_mode_suffix(const ir_node *node)
+{
+       ir_mode *mode      = get_irn_mode(node);
+       int      bits      = get_mode_size_bits(mode);
+
+       assert(mode_is_float(mode));
+
+       if (bits == 32) {
+               be_emit_string("s");
+       } else if (bits == 64) {
+               be_emit_string("d");
+       } else {
+               panic("FP mode > 64bits not implemented yet");
+       }
 }
 
 /**
@@ -235,20 +295,9 @@ static void sparc_emit_cfop_target(const ir_node *node)
  */
 static void sparc_emit_entity(ir_entity *entity)
 {
-       be_emit_ident(get_entity_ld_ident(entity));
+       be_gas_emit_entity(entity);
 }
 
-/***********************************************************************************
- *                  _          __                                             _
- *                 (_)        / _|                                           | |
- *  _ __ ___   __ _ _ _ __   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| | __
- * | '_ ` _ \ / _` | | '_ \  |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
- * | | | | | | (_| | | | | | | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
- * |_| |_| |_|\__,_|_|_| |_| |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_\
- *
- ***********************************************************************************/
-
-
 /**
  * Emits code for stack space management
  */
@@ -275,12 +324,11 @@ static void emit_be_IncSP(const ir_node *irn)
 }
 
 /**
- * emits code for save instruction
- * and sets the current save_attr pointer
+ * emits code for save instruction with min. required stack space
  */
 static void emit_sparc_Save(const ir_node *irn)
 {
-       save_attr = get_sparc_save_attr_const(irn);
+       const sparc_save_attr_t *save_attr = get_sparc_save_attr_const(irn);
        be_emit_cstring("\tsave ");
        sparc_emit_source_register(irn, 0);
        be_emit_irprintf(", %d, ", -save_attr->initial_stacksize);
@@ -313,6 +361,65 @@ static void emit_sparc_LoImm(const ir_node *irn)
        be_emit_finish_line_gas(irn);
 }
 
+/**
+ * emit code for div with the correct sign prefix
+ */
+static void emit_sparc_Div(const ir_node *irn)
+{
+       be_emit_cstring("\t");
+       sparc_emit_mode_sign_prefix(irn);
+       be_emit_cstring("div ");
+
+       sparc_emit_source_register(irn, 0);
+       be_emit_cstring(", ");
+       sparc_emit_reg_or_imm(irn, 1);
+       be_emit_cstring(", ");
+       sparc_emit_dest_register(irn, 0);
+       be_emit_finish_line_gas(irn);
+}
+
+/**
+ * emit code for mul with the correct sign prefix
+ */
+static void emit_sparc_Mul(const ir_node *irn)
+{
+       be_emit_cstring("\t");
+       sparc_emit_mode_sign_prefix(irn);
+       be_emit_cstring("mul ");
+
+       sparc_emit_source_register(irn, 0);
+       be_emit_cstring(", ");
+       sparc_emit_reg_or_imm(irn, 1);
+       be_emit_cstring(", ");
+       sparc_emit_dest_register(irn, 0);
+       be_emit_finish_line_gas(irn);
+}
+
+/**
+ * emits code for mulh
+ */
+static void emit_sparc_Mulh(const ir_node *irn)
+{
+       be_emit_cstring("\t");
+       sparc_emit_mode_sign_prefix(irn);
+       be_emit_cstring("mul ");
+
+       sparc_emit_source_register(irn, 0);
+       be_emit_cstring(", ");
+       sparc_emit_reg_or_imm(irn, 1);
+       be_emit_cstring(", ");
+       sparc_emit_dest_register(irn, 0);
+       be_emit_finish_line_gas(irn);
+
+       // our result is in the y register now
+       // we just copy it to the assigned target reg
+       be_emit_cstring("\tmov ");
+       be_emit_char('%');
+       be_emit_string(arch_register_get_name(&sparc_flags_regs[REG_Y]));
+       be_emit_cstring(", ");
+       sparc_emit_dest_register(irn, 0);
+       be_emit_finish_line_gas(irn);
+}
 
 /**
  * Emits code for return node
@@ -320,6 +427,7 @@ static void emit_sparc_LoImm(const ir_node *irn)
 static void emit_be_Return(const ir_node *irn)
 {
        be_emit_cstring("\tret");
+       //be_emit_cstring("\tjmp %i7+8");
        be_emit_finish_line_gas(irn);
        be_emit_cstring("\trestore");
        be_emit_finish_line_gas(irn);
@@ -328,27 +436,28 @@ static void emit_be_Return(const ir_node *irn)
 /**
  * Emits code for Call node
  */
-static void emit_be_Call(const ir_node *irn)
+static void emit_sparc_Call(const ir_node *node)
 {
-       ir_entity *entity = be_Call_get_entity(irn);
+       const sparc_attr_t *attr   = get_sparc_attr_const(node);
+       ir_entity          *entity = attr->immediate_value_entity;
 
+       be_emit_cstring("\tcall ");
        if (entity != NULL) {
-               be_emit_cstring("\tcall ");
            sparc_emit_entity(entity);
-               be_emit_finish_line_gas(irn);
-               be_emit_cstring("\tnop");
-               be_emit_pad_comment();
-               be_emit_cstring("/* TODO: use delay slot */\n");
+               be_emit_cstring(", 0");
        } else {
-               be_emit_cstring("\tnop\n");
-               be_emit_pad_comment();
-               be_emit_cstring("/* TODO: Entity == NULL */\n");
-               be_emit_finish_line_gas(irn);
+               int last = get_irn_arity(node);
+               sparc_emit_source_register(node, last-1);
        }
+       be_emit_finish_line_gas(node);
+
+       /* fill delay slot */
+       be_emit_cstring("\tnop");
+       be_emit_finish_line_gas(node);
 }
 
 /**
- * TODO: check if this is correct
+ * Emit code for Perm node
  */
 static void emit_be_Perm(const ir_node *irn)
 {
@@ -377,31 +486,80 @@ static void emit_be_Perm(const ir_node *irn)
        be_emit_finish_line_gas(irn);
 }
 
+/**
+ * TODO: not really tested but seems to work with memperm_arity == 1
+ */
+static void emit_be_MemPerm(const ir_node *node)
+{
+       int i;
+       int memperm_arity;
+       int sp_change = 0;
+
+       /* TODO: this implementation is slower than necessary.
+          The longterm goal is however to avoid the memperm node completely */
+
+       memperm_arity = be_get_MemPerm_entity_arity(node);
+       // we use our local registers - so this is limited to 8 inputs !
+       if (memperm_arity > 8)
+               panic("memperm with more than 8 inputs not supported yet");
+
+       for (i = 0; i < memperm_arity; ++i) {
+               int offset;
+               ir_entity *entity = be_get_MemPerm_in_entity(node, i);
+
+               /* spill register */
+               sp_change += 4;
+               be_emit_irprintf("\tst %%l%d, [%%sp-%d]", i, sp_change);
+               be_emit_finish_line_gas(node);
+
+               /* load from entity */
+               offset = get_entity_offset(entity) + sp_change;
+               be_emit_irprintf("\tld [%%sp+%d], %%l%d", offset, i);
+               be_emit_finish_line_gas(node);
+       }
+
+       for (i = memperm_arity-1; i >= 0; --i) {
+               int        offset;
+               ir_entity *entity = be_get_MemPerm_out_entity(node, i);
+
+               /* store to new entity */
+               offset = get_entity_offset(entity) + sp_change;
+               be_emit_irprintf("\tst %%l%d, [%%sp+%d]", i, offset);
+               be_emit_finish_line_gas(node);
+               /* restore register */
+               be_emit_irprintf("\tld [%%sp-%d], %%l%d", sp_change, i);
+               sp_change -= 4;
+               be_emit_finish_line_gas(node);
+       }
+       assert(sp_change == 0);
+}
+
 /**
  * Emit a SymConst.
  */
 static void emit_sparc_SymConst(const ir_node *irn)
 {
        const sparc_symconst_attr_t *attr = get_sparc_symconst_attr_const(irn);
-       ident *id_symconst = get_entity_ident(attr->entity);
-       const char *label = get_id_str(id_symconst);
 
        //sethi %hi(const32),%reg
        //or    %reg,%lo(const32),%reg
 
-       be_emit_irprintf("\tsethi %%hi(%s), ", label);
+       be_emit_cstring("\tsethi %hi(");
+       be_gas_emit_entity(attr->entity);
+       be_emit_cstring("), ");
        sparc_emit_dest_register(irn, 0);
        be_emit_cstring("\n ");
 
        // TODO: could be combined with the following load/store instruction
        be_emit_cstring("\tor ");
        sparc_emit_dest_register(irn, 0);
-       be_emit_irprintf(", %%lo(%s), ", label);
+       be_emit_cstring(", %lo(");
+       be_gas_emit_entity(attr->entity);
+       be_emit_cstring("), ");
        sparc_emit_dest_register(irn, 0);
        be_emit_finish_line_gas(irn);
 }
 
-
 /**
  * Emits code for FrameAddr fix
  */
@@ -414,7 +572,7 @@ static void emit_sparc_FrameAddr(const ir_node *irn)
                be_emit_cstring("\tadd ");
                sparc_emit_source_register(irn, 0);
                be_emit_cstring(", ");
-               be_emit_irprintf("%ld", attr->fp_offset + save_attr->initial_stacksize);
+               be_emit_irprintf("%ld", attr->fp_offset);
        } else {
                be_emit_cstring("\tsub ");
                sparc_emit_source_register(irn, 0);
@@ -431,22 +589,19 @@ static void emit_sparc_FrameAddr(const ir_node *irn)
 /**
  * Emits code for Branch
  */
-static void emit_sparc_Branch(const ir_node *irn)
+static void emit_sparc_BXX(const ir_node *node)
 {
+       const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node);
+       int              proj_num    = attr->proj_num;
+       bool             is_unsigned = attr->is_unsigned;
+       const ir_node   *proj_true   = NULL;
+       const ir_node   *proj_false  = NULL;
        const ir_edge_t *edge;
-       const ir_node *proj_true  = NULL;
-       const ir_node *proj_false = NULL;
-       const ir_node *block;
-       const ir_node *next_block;
-       ir_node *op1 = get_irn_n(irn, 0);
-       const char *suffix;
-       int proj_num = get_sparc_jmp_cond_proj_num(irn);
-       const sparc_cmp_attr_t *cmp_attr = get_irn_generic_attr_const(op1);
-       // bool is_signed = !cmp_attr->is_unsigned;
-
-       assert(is_sparc_Cmp(op1) || is_sparc_Tst(op1));
-
-       foreach_out_edge(irn, edge) {
+       const ir_node   *block;
+       const ir_node   *next_block;
+       const char      *suffix;
+
+       foreach_out_edge(node, edge) {
                ir_node *proj = get_edge_src_irn(edge);
                long nr = get_Proj_proj(proj);
                if (nr == pn_Cond_true) {
@@ -456,12 +611,8 @@ static void emit_sparc_Branch(const ir_node *irn)
                }
        }
 
-       if (cmp_attr->ins_permuted) {
-               proj_num = get_mirrored_pnc(proj_num);
-       }
-
        /* for now, the code works for scheduled and non-schedules blocks */
-       block = get_nodes_block(irn);
+       block = get_nodes_block(node);
 
        /* we have a block schedule */
        next_block = get_irn_link(block);
@@ -478,20 +629,32 @@ static void emit_sparc_Branch(const ir_node *irn)
                proj_num   = get_negated_pnc(proj_num, mode_Iu);
        }
 
-
-       switch (proj_num) {
-               case pn_Cmp_Eq:  suffix = "e"; break;
-               case pn_Cmp_Lt:  suffix = "l"; break;
-               case pn_Cmp_Le:  suffix = "le"; break;
-               case pn_Cmp_Gt:  suffix = "g"; break;
-               case pn_Cmp_Ge:  suffix = "ge"; break;
-               case pn_Cmp_Lg:  suffix = "ne"; break;
-               case pn_Cmp_Leg: suffix = "a"; break;
-               default: panic("Cmp has unsupported pnc");
+       if (is_unsigned) {
+               switch (proj_num) {
+                       case pn_Cmp_Eq:  suffix = "e"; break;
+                       case pn_Cmp_Lt:  suffix = "lu"; break;
+                       case pn_Cmp_Le:  suffix = "leu"; break;
+                       case pn_Cmp_Gt:  suffix = "gu"; break;
+                       case pn_Cmp_Ge:  suffix = "geu"; break;
+                       case pn_Cmp_Lg:  suffix = "ne"; break;
+                       default: panic("Cmp has unsupported pnc");
+               }
+       } else {
+               switch (proj_num) {
+                       case pn_Cmp_Eq:  suffix = "e"; break;
+                       case pn_Cmp_Lt:  suffix = "l"; break;
+                       case pn_Cmp_Le:  suffix = "le"; break;
+                       case pn_Cmp_Gt:  suffix = "g"; break;
+                       case pn_Cmp_Ge:  suffix = "ge"; break;
+                       case pn_Cmp_Lg:  suffix = "ne"; break;
+                       default: panic("Cmp has unsupported pnc");
+               }
        }
 
        /* emit the true proj */
-       be_emit_irprintf("\tb%s ", suffix);
+       be_emit_cstring("\tb");
+       be_emit_string(suffix);
+       be_emit_char(' ');
        sparc_emit_cfop_target(proj_true);
        be_emit_finish_line_gas(proj_true);
 
@@ -516,7 +679,7 @@ static void emit_sparc_Branch(const ir_node *irn)
 /**
  * emit Jmp (which actually is a branch always (ba) instruction)
  */
-static void emit_sparc_Jmp(const ir_node *node)
+static void emit_sparc_Ba(const ir_node *node)
 {
        ir_node *block, *next_block;
 
@@ -593,47 +756,35 @@ static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
  */
 static void sparc_register_emitters(void)
 {
-
        /* first clear the generic function pointer for all ops */
        clear_irp_opcodes_generic_func();
-
        /* register all emitter functions defined in spec */
        sparc_register_spec_emitters();
 
        /* custom emitter */
-    set_emitter(op_be_IncSP,       emit_be_IncSP);
-    set_emitter(op_be_Return,      emit_be_Return);
-    set_emitter(op_be_Call,        emit_be_Call);
-    set_emitter(op_sparc_FrameAddr,  emit_sparc_FrameAddr);
-    set_emitter(op_sparc_Branch,   emit_sparc_Branch);
-    set_emitter(op_sparc_SymConst,   emit_sparc_SymConst);
-    set_emitter(op_sparc_Jmp,        emit_sparc_Jmp);
-    set_emitter(op_sparc_Save,        emit_sparc_Save);
-
-    set_emitter(op_sparc_HiImm,        emit_sparc_HiImm);
-    set_emitter(op_sparc_LoImm,        emit_sparc_LoImm);
-
-    set_emitter(op_be_Copy,        emit_be_Copy);
-    set_emitter(op_be_CopyKeep,    emit_be_Copy);
-
-    set_emitter(op_be_Perm,        emit_be_Perm);
-
-/*
-    set_emitter(op_arm_B,          emit_arm_B);
-    set_emitter(op_arm_CopyB,      emit_arm_CopyB);
-    set_emitter(op_arm_fpaConst,   emit_arm_fpaConst);
-    set_emitter(op_arm_fpaDbl2GP,  emit_arm_fpaDbl2GP);
-    set_emitter(op_arm_LdTls,      emit_arm_LdTls);
-    set_emitter(op_arm_SwitchJmp,  emit_arm_SwitchJmp);
-    set_emitter(op_be_MemPerm,     emit_be_MemPerm);
-
-*/
-    /* no need to emit anything for the following nodes */
-       set_emitter(op_Phi,            emit_nothing);
-       set_emitter(op_be_Keep,        emit_nothing);
-       set_emitter(op_be_Start,       emit_nothing);
-       set_emitter(op_be_Barrier,     emit_nothing);
-
+       set_emitter(op_be_Copy,         emit_be_Copy);
+       set_emitter(op_be_CopyKeep,     emit_be_Copy);
+       set_emitter(op_be_IncSP,        emit_be_IncSP);
+       set_emitter(op_be_MemPerm,      emit_be_MemPerm);
+       set_emitter(op_be_Perm,         emit_be_Perm);
+       set_emitter(op_be_Return,       emit_be_Return);
+       set_emitter(op_sparc_BXX,       emit_sparc_BXX);
+       set_emitter(op_sparc_Call,      emit_sparc_Call);
+       set_emitter(op_sparc_Div,       emit_sparc_Div);
+       set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr);
+       set_emitter(op_sparc_HiImm,     emit_sparc_HiImm);
+       set_emitter(op_sparc_Ba,        emit_sparc_Ba);
+       set_emitter(op_sparc_LoImm,     emit_sparc_LoImm);
+       set_emitter(op_sparc_Mul,       emit_sparc_Mul);
+       set_emitter(op_sparc_Mulh,      emit_sparc_Mulh);
+       set_emitter(op_sparc_Save,      emit_sparc_Save);
+       set_emitter(op_sparc_SymConst,  emit_sparc_SymConst);
+
+       /* no need to emit anything for the following nodes */
+       set_emitter(op_be_Barrier, emit_nothing);
+       set_emitter(op_be_Keep,    emit_nothing);
+       set_emitter(op_be_Start,   emit_nothing);
+       set_emitter(op_Phi,        emit_nothing);
 }
 
 /**
@@ -727,15 +878,17 @@ void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
        ir_node *last_block = NULL;
        ir_entity *entity     = get_irg_entity(irg);
        int i, n;
+       (void) cg;
 
        be_gas_elf_type_char = '#';
+       be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF_SPARC;
 
        /* register all emitter functions */
        sparc_register_emitters();
-       be_dbg_method_begin(entity, be_abi_get_stack_layout(cg->birg->abi));
+       be_dbg_method_begin(entity);
 
        /* create the block schedule. For now, we don't need it earlier. */
-       blk_sched = be_create_block_schedule(cg->irg, cg->birg->exec_freq);
+       blk_sched = be_create_block_schedule(irg);
 
        // emit function prolog
        sparc_emit_func_prolog(irg);
@@ -758,9 +911,6 @@ void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
                last_block = block;
        }
 
-
-       //irg_walk_blkwise_graph(irg, NULL, sparc_gen_block, NULL);
-
        // emit function epilog
        sparc_emit_func_epilog(irg);
 }