beabi: remove a bunch of unused/deprecated flags
[libfirm] / ir / be / TEMPLATE / bearch_TEMPLATE.c
index 5c8d97c..29ab627 100644 (file)
 /**
  * @file
  * @brief    The main TEMPLATE backend driver file.
- * @version  $Id$
  */
 #include "config.h"
 
-#include "pseudo_irg.h"
+#include "bearch_TEMPLATE_t.h"
+
 #include "irgwalk.h"
 #include "irprog.h"
 #include "irprintf.h"
 #include "ircons.h"
 #include "irgmod.h"
+#include "lower_calls.h"
+#include "lower_builtins.h"
 
 #include "bitset.h"
 #include "debug.h"
 
 #include "be.h"
-#include "../bearch.h"
-#include "../benode.h"
-#include "../belower.h"
-#include "../besched.h"
-#include "../beabi.h"
-#include "../bemodule.h"
-#include "../begnuas.h"
-#include "../belistsched.h"
-
-#include "bearch_TEMPLATE_t.h"
+#include "bearch.h"
+#include "benode.h"
+#include "belower.h"
+#include "besched.h"
+#include "beabi.h"
+#include "bemodule.h"
+#include "begnuas.h"
+#include "belistsched.h"
+#include "bestack.h"
+#include "bespillutil.h"
 
 #include "TEMPLATE_new_nodes.h"
 #include "gen_TEMPLATE_regalloc_if.h"
 #include "TEMPLATE_transform.h"
 #include "TEMPLATE_emitter.h"
-#include "TEMPLATE_map_regs.h"
-
-/* TODO: ugly, but we need it to get access to the registers assigned to Phi nodes */
-static set *cur_reg_set = NULL;
-
-/**************************************************
- *                         _ _              _  __
- *                        | | |            (_)/ _|
- *  _ __ ___  __ _    __ _| | | ___   ___   _| |_
- * | '__/ _ \/ _` |  / _` | | |/ _ \ / __| | |  _|
- * | | |  __/ (_| | | (_| | | | (_) | (__  | | |
- * |_|  \___|\__, |  \__,_|_|_|\___/ \___| |_|_|
- *            __/ |
- *           |___/
- **************************************************/
-
-static arch_irn_class_t TEMPLATE_classify(const ir_node *irn)
-{
-       (void) irn;
-       return 0;
-}
+
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
 static ir_entity *TEMPLATE_get_frame_entity(const ir_node *node)
 {
@@ -79,13 +62,6 @@ static ir_entity *TEMPLATE_get_frame_entity(const ir_node *node)
        return NULL;
 }
 
-static void TEMPLATE_set_frame_entity(ir_node *node, ir_entity *ent)
-{
-       (void) node;
-       (void) ent;
-       /* TODO: set the ir_entity assigned to the frame */
-}
-
 /**
  * This function is called by the generic backend to correct offsets for
  * nodes accessing the stack.
@@ -106,11 +82,7 @@ static int TEMPLATE_get_sp_bias(const ir_node *irn)
 /* fill register allocator interface */
 
 static const arch_irn_ops_t TEMPLATE_irn_ops = {
-       get_TEMPLATE_in_req,
-       get_TEMPLATE_out_req,
-       TEMPLATE_classify,
        TEMPLATE_get_frame_entity,
-       TEMPLATE_set_frame_entity,
        TEMPLATE_set_frame_offset,
        TEMPLATE_get_sp_bias,
        NULL,    /* get_inverse             */
@@ -119,25 +91,16 @@ static const arch_irn_ops_t TEMPLATE_irn_ops = {
        NULL,    /* perform_memory_operand  */
 };
 
-/**************************************************
- *                _                         _  __
- *               | |                       (_)/ _|
- *   ___ ___   __| | ___  __ _  ___ _ __    _| |_
- *  / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \  | |  _|
- * | (_| (_) | (_| |  __/ (_| |  __/ | | | | | |
- *  \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
- *                        __/ |
- *                       |___/
- **************************************************/
+
 
 /**
  * Transforms the standard firm graph into
  * a TEMLPATE firm graph
  */
-static void TEMPLATE_prepare_graph(void *self) {
-       TEMPLATE_code_gen_t *cg = self;
-
-       irg_walk_blkwise_graph(cg->irg, NULL, TEMPLATE_transform_node, cg);
+static void TEMPLATE_prepare_graph(ir_graph *irg)
+{
+       /* transform nodes into assembler instructions */
+       TEMPLATE_transform_graph(irg);
 }
 
 
@@ -145,190 +108,80 @@ static void TEMPLATE_prepare_graph(void *self) {
 /**
  * Called immediatly before emit phase.
  */
-static void TEMPLATE_finish_irg(void *self) {
-       TEMPLATE_code_gen_t *cg = self;
-       ir_graph            *irg = cg->irg;
-
-       dump_ir_block_graph_sched(irg, "-TEMPLATE-finished");
+static void TEMPLATE_finish_irg(ir_graph *irg)
+{
+       /* fix stack entity offsets */
+       be_abi_fix_stack_nodes(irg);
+       be_abi_fix_stack_bias(irg);
 }
 
 
-static void TEMPLATE_before_ra(void *self) {
-       (void) self;
+static void TEMPLATE_before_ra(ir_graph *irg)
+{
+       (void) irg;
        /* Some stuff you need to do after scheduling but before register allocation */
 }
 
-static void TEMPLATE_after_ra(void *self) {
-       (void) self;
-       /* Some stuff you need to do immediatly after register allocation */
-}
-
-
-
-/**
- * Emits the code, closes the output file and frees
- * the code generator interface.
- */
-static void TEMPLATE_emit_and_done(void *self) {
-       TEMPLATE_code_gen_t *cg = self;
-       ir_graph           *irg = cg->irg;
-
-       TEMPLATE_gen_routine(cg, irg);
-
-       cur_reg_set = NULL;
-
-       /* de-allocate code generator */
-       del_set(cg->reg_set);
-       free(cg);
-}
-
-static void *TEMPLATE_cg_init(be_irg_t *birg);
-
-static const arch_code_generator_if_t TEMPLATE_code_gen_if = {
-       TEMPLATE_cg_init,
-       NULL,                    /* get_pic_base hook */
-       NULL,                    /* before abi introduce hook */
-       TEMPLATE_prepare_graph,
-       NULL,                    /* spill hook */
-       TEMPLATE_before_ra,      /* before register allocation hook */
-       TEMPLATE_after_ra,       /* after register allocation hook */
-       TEMPLATE_finish_irg,
-       TEMPLATE_emit_and_done
-};
-
-/**
- * Initializes the code generator.
- */
-static void *TEMPLATE_cg_init(be_irg_t *birg) {
-       const arch_env_t    *arch_env = be_get_birg_arch_env(birg);
-       TEMPLATE_isa_t      *isa      = (TEMPLATE_isa_t *) arch_env;
-       TEMPLATE_code_gen_t *cg       = XMALLOC(TEMPLATE_code_gen_t);
-
-       cg->impl     = &TEMPLATE_code_gen_if;
-       cg->irg      = be_get_birg_irg(birg);
-       cg->reg_set  = new_set(TEMPLATE_cmp_irn_reg_assoc, 1024);
-       cg->isa      = isa;
-       cg->birg     = birg;
-       FIRM_DBG_REGISTER(cg->mod, "firm.be.TEMPLATE.cg");
-
-       cur_reg_set = cg->reg_set;
-
-       return (arch_code_generator_t *)cg;
+static void TEMPLATE_init_graph(ir_graph *irg)
+{
+       (void) irg;
 }
 
 
 
-/*****************************************************************
- *  ____             _                  _   _____  _____
- * |  _ \           | |                | | |_   _|/ ____|  /\
- * | |_) | __ _  ___| | _____ _ __   __| |   | | | (___   /  \
- * |  _ < / _` |/ __| |/ / _ \ '_ \ / _` |   | |  \___ \ / /\ \
- * | |_) | (_| | (__|   <  __/ | | | (_| |  _| |_ ____) / ____ \
- * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/    \_\
- *
- *****************************************************************/
-
+extern const arch_isa_if_t TEMPLATE_isa_if;
 static TEMPLATE_isa_t TEMPLATE_isa_template = {
        {
                &TEMPLATE_isa_if,             /* isa interface implementation */
-               &TEMPLATE_general_purpose_regs[REG_SP],  /* stack pointer register */
-               &TEMPLATE_general_purpose_regs[REG_BP],  /* base pointer register */
-               &TEMPLATE_reg_classes[CLASS_TEMPLATE_general_purpose],  /* link pointer register class */
-               -1,                          /* stack direction */
+               N_TEMPLATE_REGISTERS,
+               TEMPLATE_registers,
+               N_TEMPLATE_CLASSES,
+               TEMPLATE_reg_classes,
+               &TEMPLATE_registers[REG_SP],  /* stack pointer register */
+               &TEMPLATE_registers[REG_BP],  /* base pointer register */
+               &TEMPLATE_reg_classes[CLASS_TEMPLATE_gp],  /* link pointer register class */
                2,                           /* power of two stack alignment for calls, 2^2 == 4 */
                NULL,                        /* main environment */
                7,                           /* costs for a spill instruction */
                5,                           /* costs for a reload instruction */
+               false,                       /* no custom abi handling */
        },
 };
 
-/**
- * Initializes the backend ISA and opens the output file.
- */
-static arch_env_t *TEMPLATE_init(FILE *outfile) {
-       static int run_once = 0;
-       TEMPLATE_isa_t *isa;
-
-       if(run_once)
-               return NULL;
-       run_once = 1;
-
-       isa = XMALLOC(TEMPLATE_isa_t);
-       memcpy(isa, &TEMPLATE_isa_template, sizeof(*isa));
-
-       be_emit_init(outfile);
-
+static void TEMPLATE_init(void)
+{
        TEMPLATE_register_init();
        TEMPLATE_create_opcodes(&TEMPLATE_irn_ops);
-
-       return &isa->arch_env;
-}
-
-
-
-/**
- * Closes the output file and frees the ISA structure.
- */
-static void TEMPLATE_done(void *self) {
-       TEMPLATE_isa_t *isa = self;
-
-       /* emit now all global declarations */
-       be_gas_emit_decls(isa->arch_env.main_env, 0);
-
-       be_emit_exit();
-       free(self);
 }
 
-
-
-static unsigned TEMPLATE_get_n_reg_class(const void *self)
+static void TEMPLATE_finish(void)
 {
-       (void) self;
-       return N_CLASSES;
+       TEMPLATE_free_opcodes();
 }
 
-static const arch_register_class_t *TEMPLATE_get_reg_class(const void *self,
-                                                           unsigned i)
+static arch_env_t *TEMPLATE_begin_codegeneration(const be_main_env_t *env)
 {
-       (void) self;
-       assert(i < N_CLASSES);
-       return &TEMPLATE_reg_classes[i];
-}
+       TEMPLATE_isa_t *isa = XMALLOC(TEMPLATE_isa_t);
+       *isa = TEMPLATE_isa_template;
 
+       be_emit_init(env->file_handle);
+       be_gas_begin_compilation_unit(env);
 
+       return &isa->base;
+}
 
 /**
- * Get the register class which shall be used to store a value of a given mode.
- * @param self The this pointer.
- * @param mode The mode in question.
- * @return A register class which can hold values of the given mode.
+ * Closes the output file and frees the ISA structure.
  */
-const arch_register_class_t *TEMPLATE_get_reg_class_for_mode(const void *self,
-               const ir_mode *mode)
+static void TEMPLATE_end_codegeneration(void *self)
 {
-       (void) self;
-       if (mode_is_float(mode))
-               return &TEMPLATE_reg_classes[CLASS_TEMPLATE_floating_point];
-       else
-               return &TEMPLATE_reg_classes[CLASS_TEMPLATE_general_purpose];
-}
-
+       TEMPLATE_isa_t *isa = (TEMPLATE_isa_t*)self;
 
+       /* emit now all global declarations */
+       be_gas_end_compilation_unit(isa->base.main_env);
 
-typedef struct {
-       be_abi_call_flags_bits_t flags;
-       const arch_env_t *arch_env;
-       ir_graph *irg;
-} TEMPLATE_abi_env_t;
-
-static void *TEMPLATE_abi_init(const be_abi_call_t *call, const arch_env_t *arch_env, ir_graph *irg)
-{
-       TEMPLATE_abi_env_t *env = XMALLOC(TEMPLATE_abi_env_t);
-       be_abi_call_flags_t fl = be_abi_call_get_flags(call);
-       env->flags    = fl.bits;
-       env->irg      = irg;
-       env->arch_env = arch_env;
-       return env;
+       be_emit_exit();
+       free(self);
 }
 
 /**
@@ -336,16 +189,16 @@ static void *TEMPLATE_abi_init(const be_abi_call_t *call, const arch_env_t *arch
  * @param self The callback object.
  * @return The between type of for that call.
  */
-static ir_type *TEMPLATE_get_between_type(void *self)
+static ir_type *TEMPLATE_get_between_type(ir_graph *irg)
 {
        static ir_type *between_type = NULL;
        static ir_entity *old_bp_ent = NULL;
-       (void) self;
+       (void) irg;
 
-       if(!between_type) {
+       if (!between_type) {
                ir_entity *ret_addr_ent;
-               ir_type *ret_addr_type = new_type_primitive(new_id_from_str("return_addr"), mode_P);
-               ir_type *old_bp_type   = new_type_primitive(new_id_from_str("bp"), mode_P);
+               ir_type *ret_addr_type = new_type_primitive(mode_P);
+               ir_type *old_bp_type   = new_type_primitive(mode_P);
 
                between_type           = new_type_class(new_id_from_str("TEMPLATE_between_type"));
                old_bp_ent             = new_entity(between_type, new_id_from_str("old_bp"), old_bp_type);
@@ -359,38 +212,8 @@ static ir_type *TEMPLATE_get_between_type(void *self)
        return between_type;
 }
 
-/**
- * Build the prolog, return the BASE POINTER register
- */
-static const arch_register_t *TEMPLATE_abi_prologue(void *self, ir_node **mem,
-                                                    pmap *reg_map, int *stack_bias)
-{
-       TEMPLATE_abi_env_t *env = self;
-       (void) reg_map;
-       (void) mem;
-       (void) stack_bias;
-
-       if(env->flags.try_omit_fp)
-               return env->arch_env->sp;
-       return env->arch_env->bp;
-}
-
-/* Build the epilog */
-static void TEMPLATE_abi_epilogue(void *self, ir_node *bl, ir_node **mem,
-                                  pmap *reg_map)
-{
-       (void) self;
-       (void) bl;
-       (void) mem;
-       (void) reg_map;
-}
-
 static const be_abi_callbacks_t TEMPLATE_abi_callbacks = {
-       TEMPLATE_abi_init,
-       free,
        TEMPLATE_get_between_type,
-       TEMPLATE_abi_prologue,
-       TEMPLATE_abi_epilogue,
 };
 
 /**
@@ -399,21 +222,15 @@ static const be_abi_callbacks_t TEMPLATE_abi_callbacks = {
  * @param method_type The type of the method (procedure) in question.
  * @param abi         The abi object to be modified
  */
-void TEMPLATE_get_call_abi(const void *self, ir_type *method_type,
-                           be_abi_call_t *abi)
+static void TEMPLATE_get_call_abi(ir_type *method_type, be_abi_call_t *abi)
 {
        ir_type  *tp;
        ir_mode  *mode;
        int       i, n = get_method_n_params(method_type);
        be_abi_call_flags_t call_flags;
-       (void) self;
 
        /* set abi flags for calls */
-       call_flags.bits.left_to_right         = 0;
-       call_flags.bits.store_args_sequential = 1;
-       call_flags.bits.try_omit_fp           = 1;
-       call_flags.bits.fp_free               = 0;
-       call_flags.bits.call_has_imm          = 1;
+       call_flags.bits.call_has_imm = true;
 
        /* set stack parameter passing style */
        be_abi_call_set_flags(abi, call_flags, &TEMPLATE_abi_callbacks);
@@ -421,12 +238,12 @@ void TEMPLATE_get_call_abi(const void *self, ir_type *method_type,
        for (i = 0; i < n; i++) {
                /* TODO: implement register parameter: */
                /* reg = get reg for param i;          */
-               /* be_abi_call_param_reg(abi, i, reg); */
+               /* be_abi_call_param_reg(abi, i, reg, ABI_CONTEXT_BOTH); */
 
                /* default: all parameters on stack */
                tp   = get_method_param_type(method_type, i);
                mode = get_type_mode(tp);
-               be_abi_call_param_stack(abi, i, mode, 4, 0, 0);
+               be_abi_call_param_stack(abi, i, mode, 4, 0, 0, ABI_CONTEXT_BOTH);
        }
 
        /* TODO: set correct return register */
@@ -436,75 +253,45 @@ void TEMPLATE_get_call_abi(const void *self, ir_type *method_type,
                mode = get_type_mode(tp);
 
                be_abi_call_res_reg(abi, 0,
-                       mode_is_float(mode) ? &TEMPLATE_floating_point_regs[REG_F0] : &TEMPLATE_general_purpose_regs[REG_R0]);
+                       mode_is_float(mode) ? &TEMPLATE_registers[REG_F0] : &TEMPLATE_registers[REG_R0], ABI_CONTEXT_BOTH);
        }
 }
 
-int TEMPLATE_to_appear_in_schedule(void *block_env, const ir_node *irn)
-{
-       (void) block_env;
-
-       if(!is_TEMPLATE_irn(irn))
-               return -1;
-
-       return 1;
-}
-
-/**
- * Initializes the code generator interface.
- */
-static const arch_code_generator_if_t *TEMPLATE_get_code_generator_if(
-               void *self)
-{
-       (void) self;
-       return &TEMPLATE_code_gen_if;
-}
-
-list_sched_selector_t TEMPLATE_sched_selector;
-
-/**
- * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
- */
-static const list_sched_selector_t *TEMPLATE_get_list_sched_selector(
-               const void *self, list_sched_selector_t *selector)
+static void TEMPLATE_lower_for_target(void)
 {
-       (void) self;
-       (void) selector;
+       lower_builtins(0, NULL);
 
-       TEMPLATE_sched_selector = trivial_selector;
-       TEMPLATE_sched_selector.to_appear_in_schedule = TEMPLATE_to_appear_in_schedule;
-       return &TEMPLATE_sched_selector;
+       /* lower compound param handling */
+       lower_calls_with_compounds(LF_RETURN_HIDDEN);
 }
 
-static const ilp_sched_selector_t *TEMPLATE_get_ilp_sched_selector(
-               const void *self)
+static int TEMPLATE_is_mux_allowed(ir_node *sel, ir_node *mux_false,
+                                   ir_node *mux_true)
 {
-       (void) self;
-       return NULL;
-}
-
-/**
- * Returns the necessary byte alignment for storing a register of given class.
- */
-static int TEMPLATE_get_reg_class_alignment(const void *self,
-                                            const arch_register_class_t *cls) {
-       ir_mode *mode = arch_register_class_mode(cls);
-       (void) self;
-       return get_mode_size_bytes(mode);
+       (void) sel;
+       (void) mux_false;
+       (void) mux_true;
+       return false;
 }
 
 /**
  * Returns the libFirm configuration parameter for this backend.
  */
-static const backend_params *TEMPLATE_get_backend_params(void) {
+static const backend_params *TEMPLATE_get_backend_params(void)
+{
        static backend_params p = {
-               0,     /* no dword lowering */
                0,     /* no inline assembly */
-               NULL,  /* will be set later */
-               NULL,  /* no creator function */
-               NULL,  /* context for create_intrinsic_fkt */
-               NULL,  /* parameter for if conversion */
+               0,     /* no support for Rotl nodes */
+               0,     /* 0: little-endian, 1: big-endian */
+               1,     /* modulo shift efficient */
+               0,     /* non-modulo shift efficient */
+               NULL,  /* architecture dependent settings, will be set later */
+               TEMPLATE_is_mux_allowed,  /* parameter for if conversion */
+               32,    /* machine size - a 32bit CPU */
                NULL,  /* float arithmetic mode */
+               NULL,  /* long long type */
+               NULL,  /* unsigned long long type */
+               NULL,  /* long double type */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
                NULL,  /* no trampoline support: no trampoline builder */
@@ -513,71 +300,92 @@ static const backend_params *TEMPLATE_get_backend_params(void) {
        return &p;
 }
 
-static const be_execution_unit_t ***TEMPLATE_get_allowed_execution_units(
-               const void *self, const ir_node *irn)
-{
-       (void) self;
-       (void) irn;
-       /* TODO */
-       assert(0);
-       return NULL;
-}
-
-static const be_machine_t *TEMPLATE_get_machine(const void *self)
-{
-       (void) self;
-       /* TODO */
-       assert(0);
-       return NULL;
-}
-
-static ir_graph **TEMPLATE_get_backend_irg_list(const void *self,
-                                                ir_graph ***irgs)
-{
-       (void) self;
-       (void) irgs;
-       return NULL;
-}
-
-static asm_constraint_flags_t TEMPLATE_parse_asm_constraint(const void *self,
-                                                            const char **c)
+static asm_constraint_flags_t TEMPLATE_parse_asm_constraint(const char **c)
 {
-       (void) self;
        (void) c;
        return ASM_CONSTRAINT_FLAG_INVALID;
 }
 
-static int TEMPLATE_is_valid_clobber(const void *self, const char *clobber)
+static int TEMPLATE_is_valid_clobber(const char *clobber)
 {
-       (void) self;
        (void) clobber;
        return 0;
 }
 
+/**
+ * Check if the given register is callee or caller save.
+ */
+static int TEMPLATE_register_saved_by(const arch_register_t *reg, int callee)
+{
+       if (callee) {
+               /* check for callee saved */
+               if (reg->reg_class == &TEMPLATE_reg_classes[CLASS_TEMPLATE_gp]) {
+                       switch (reg->index) {
+                       case REG_GP_R7:
+                       case REG_GP_R8:
+                       case REG_GP_R9:
+                       case REG_GP_R10:
+                       case REG_GP_R11:
+                       case REG_GP_R12:
+                       case REG_GP_R13:
+                               return 1;
+                       default:
+                               return 0;
+                       }
+               }
+       } else {
+               /* check for caller saved */
+               if (reg->reg_class == &TEMPLATE_reg_classes[CLASS_TEMPLATE_gp]) {
+                       switch (reg->index) {
+                       case REG_GP_R0:
+                       case REG_GP_R1:
+                       case REG_GP_R2:
+                       case REG_GP_R3:
+                       case REG_GP_R4:
+                       case REG_GP_R5:
+                       case REG_GP_R6:
+                               return 1;
+                       default:
+                               return 0;
+                       }
+               } else if (reg->reg_class == &TEMPLATE_reg_classes[CLASS_TEMPLATE_fp]) {
+                       /* all FP registers are caller save */
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 const arch_isa_if_t TEMPLATE_isa_if = {
        TEMPLATE_init,
-       TEMPLATE_done,
-       NULL,                /* handle intrinsics */
-       TEMPLATE_get_n_reg_class,
-       TEMPLATE_get_reg_class,
-       TEMPLATE_get_reg_class_for_mode,
-       TEMPLATE_get_call_abi,
-       TEMPLATE_get_code_generator_if,
-       TEMPLATE_get_list_sched_selector,
-       TEMPLATE_get_ilp_sched_selector,
-       TEMPLATE_get_reg_class_alignment,
+       TEMPLATE_finish,
     TEMPLATE_get_backend_params,
-       TEMPLATE_get_allowed_execution_units,
-       TEMPLATE_get_machine,
-       TEMPLATE_get_backend_irg_list,
-       NULL,                    /* mark remat */
+       TEMPLATE_lower_for_target,
        TEMPLATE_parse_asm_constraint,
-       TEMPLATE_is_valid_clobber
+       TEMPLATE_is_valid_clobber,
+
+       TEMPLATE_begin_codegeneration,
+       TEMPLATE_end_codegeneration,
+       TEMPLATE_init_graph,
+       TEMPLATE_get_call_abi,
+       NULL, /* mark remat */
+       NULL, /* get_pic_base */
+       be_new_spill,
+       be_new_reload,
+       TEMPLATE_register_saved_by,
+
+       NULL, /* handle intrinsics */
+       NULL, /* before_abi */
+       TEMPLATE_prepare_graph,
+       TEMPLATE_before_ra,
+       TEMPLATE_finish_irg,
+       TEMPLATE_emit_routine,
 };
 
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_TEMPLATE)
 void be_init_arch_TEMPLATE(void)
 {
        be_register_isa_if("TEMPLATE", &TEMPLATE_isa_if);
+       FIRM_DBG_REGISTER(dbg, "firm.be.TEMPLATE.cg");
+       TEMPLATE_init_transform();
 }
-
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_TEMPLATE);