Add preliminary support for Clz instruction.
[libfirm] / ir / be / arm / bearch_arm.c
index 47130ff..c844dc1 100644 (file)
@@ -28,7 +28,6 @@
 #include "lc_opts.h"
 #include "lc_opts_enum.h"
 
-#include "pseudo_irg.h"
 #include "irgwalk.h"
 #include "irprog.h"
 #include "irprintf.h"
@@ -93,13 +92,6 @@ static ir_entity *arm_get_frame_entity(const ir_node *irn)
        return NULL;
 }
 
-static void arm_set_frame_entity(ir_node *irn, ir_entity *ent)
-{
-       (void) irn;
-       (void) ent;
-       panic("arm_set_frame_entity() called. This should not happen.");
-}
-
 /**
  * This function is called by the generic backend to correct offsets for
  * nodes accessing the stack.
@@ -130,7 +122,6 @@ static const arch_irn_ops_t arm_irn_ops = {
        get_arm_in_req,
        arm_classify,
        arm_get_frame_entity,
-       arm_set_frame_entity,
        arm_set_stack_bias,
        arm_get_sp_bias,
        NULL,    /* get_inverse             */
@@ -262,10 +253,60 @@ static void arm_after_ra_walker(ir_node *block, void *data)
        }
 }
 
+static void arm_collect_frame_entity_nodes(ir_node *node, void *data)
+{
+       be_fec_env_t  *env = data;
+       const ir_mode *mode;
+       int            align;
+       ir_entity     *entity;
+       const arm_load_store_attr_t *attr;
+
+       if (be_is_Reload(node) && be_get_frame_entity(node) == NULL) {
+               mode  = get_irn_mode(node);
+               align = get_mode_size_bytes(mode);
+               be_node_needs_frame_entity(env, node, mode, align);
+               return;
+       }
+
+       switch (get_arm_irn_opcode(node)) {
+       case iro_arm_Ldf:
+       case iro_arm_Ldr:
+               break;
+       default:
+               return;
+       }
+
+       attr   = get_arm_load_store_attr_const(node);
+       entity = attr->entity;
+       mode   = attr->load_store_mode;
+       align  = get_mode_size_bytes(mode);
+       if (entity != NULL)
+               return;
+       if (!attr->is_frame_entity)
+               return;
+       be_node_needs_frame_entity(env, node, mode, align);
+}
+
+static void arm_set_frame_entity(ir_node *node, ir_entity *entity)
+{
+       if (is_be_node(node)) {
+               be_node_set_frame_entity(node, entity);
+       } else {
+               arm_load_store_attr_t *attr = get_arm_load_store_attr(node);
+               attr->entity = entity;
+       }
+}
+
 static void arm_after_ra(void *self)
 {
-       arm_code_gen_t *cg = self;
-       be_coalesce_spillslots(cg->irg);
+       arm_code_gen_t *cg  = self;
+       ir_graph       *irg = cg->irg;
+
+       be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg);
+
+       irg_walk_graph(irg, NULL, arm_collect_frame_entity_nodes, fec_env);
+       be_assign_entities(fec_env, arm_set_frame_entity);
+       be_free_frame_entity_coalescer(fec_env);
 
        irg_block_walk_graph(cg->irg, NULL, arm_after_ra_walker, NULL);
 }
@@ -282,7 +323,6 @@ static void arm_emit_and_done(void *self)
        arm_gen_routine(cg, irg);
 
        /* de-allocate code generator */
-       del_set(cg->reg_set);
        free(self);
 }
 
@@ -306,25 +346,14 @@ static const arch_code_generator_if_t arm_code_gen_if = {
  */
 static void *arm_cg_init(ir_graph *irg)
 {
-       static ir_type *int_tp = NULL;
-       arm_isa_t      *isa = (arm_isa_t *) be_get_irg_arch_env(irg);
+       arm_isa_t      *isa = (arm_isa_t*) be_get_irg_arch_env(irg);
        arm_code_gen_t *cg;
 
-       if (! int_tp) {
-               /* create an integer type with machine size */
-               int_tp = new_type_primitive(mode_Is);
-       }
-
-       cg = XMALLOC(arm_code_gen_t);
-       cg->impl         = &arm_code_gen_if;
-       cg->irg          = irg;
-       cg->reg_set      = new_set(arm_cmp_irn_reg_assoc, 1024);
-       cg->isa          = isa;
-       cg->int_tp       = int_tp;
-       cg->have_fp_insn = 0;
-       cg->dump         = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
-
-       FIRM_DBG_REGISTER(cg->mod, "firm.be.arm.cg");
+       cg       = XMALLOCZ(arm_code_gen_t);
+       cg->impl = &arm_code_gen_if;
+       cg->irg  = irg;
+       cg->isa  = isa;
+       cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
 
        /* enter the current code generator */
        isa->cg = cg;
@@ -348,8 +377,8 @@ static void arm_handle_intrinsics(void)
 
 #define ID(x) new_id_from_chars(x, sizeof(x)-1)
 
-       int_tp  = new_type_primitive(mode_Is);
-       uint_tp = new_type_primitive(mode_Iu);
+       int_tp  = get_type_for_mode(mode_Is);
+       uint_tp = get_type_for_mode(mode_Iu);
 
        /* ARM has neither a signed div instruction ... */
        {
@@ -461,7 +490,7 @@ static void arm_handle_intrinsics(void)
                lower_intrinsics(records, n_records, /*part_block_used=*/0);
 }
 
-
+const arch_isa_if_t arm_isa_if;
 static arm_isa_t arm_isa_template = {
        {
                &arm_isa_if,           /* isa interface */
@@ -475,7 +504,6 @@ static arm_isa_t arm_isa_template = {
                5,                     /* reload costs */
                true,                  /* we do have custom abi handling */
        },
-       0,                     /* use generic register names instead of SP, LR, PC */
        ARM_FPU_ARCH_FPE,      /* FPU architecture */
        NULL,                  /* current code generator */
 };
@@ -510,7 +538,7 @@ static arch_env_t *arm_init(FILE *file_handle)
        be_emit_write_line();
 
        inited = 1;
-       return &isa->arch_env;
+       return &isa->base;
 }
 
 
@@ -522,7 +550,7 @@ static void arm_done(void *self)
 {
        arm_isa_t *isa = self;
 
-       be_gas_emit_decls(isa->arch_env.main_env);
+       be_gas_emit_decls(isa->base.main_env);
 
        be_emit_exit();
        free(self);
@@ -717,7 +745,6 @@ static lc_opt_enum_int_var_t arch_fpu_var = {
 
 static const lc_opt_table_entry_t arm_options[] = {
        LC_OPT_ENT_ENUM_INT("fpunit",    "select the floating point unit", &arch_fpu_var),
-       LC_OPT_ENT_BOOL("gen_reg_names", "use generic register names", &arm_isa_template.gen_reg_names),
        LC_OPT_LAST
 };