Added changes for inline assembler
[libfirm] / ir / be / arm / bearch_arm.c
index efb1123..34e5504 100644 (file)
@@ -581,114 +581,122 @@ static void *arm_cg_init(be_irg_t *birg) {
  * to runtime calls.
  */
 static void arm_handle_intrinsics(void) {
-  ir_type *tp, *int_tp, *uint_tp;
-  i_record records[8];
-  int n_records = 0;
+       ir_type *tp, *int_tp, *uint_tp;
+       i_record records[8];
+       int n_records = 0;
 
 #define ID(x) new_id_from_chars(x, sizeof(x)-1)
 
-  int_tp  = new_type_primitive(ID("int"), mode_Is);
-  uint_tp = new_type_primitive(ID("uint"), mode_Iu);
+       int_tp  = new_type_primitive(ID("int"), mode_Is);
+       uint_tp = new_type_primitive(ID("uint"), mode_Iu);
 
        /* ARM has neither a signed div instruction ... */
-  {
-    runtime_rt rt_Div;
-    i_instr_record *map_Div = &records[n_records++].i_instr;
-
-    tp = new_type_method(ID("rt_iDiv"), 2, 1);
-    set_method_param_type(tp, 0, int_tp);
-    set_method_param_type(tp, 1, int_tp);
-    set_method_res_type(tp, 0, int_tp);
-
-    rt_Div.ent             = new_entity(get_glob_type(), ID("__divsi3"), tp);
-    rt_Div.mode            = mode_T;
-    rt_Div.mem_proj_nr     = pn_Div_M;
-    rt_Div.exc_proj_nr     = pn_Div_X_except;
-    rt_Div.exc_mem_proj_nr = pn_Div_M;
-    rt_Div.res_proj_nr     = pn_Div_res;
-
-    set_entity_visibility(rt_Div.ent, visibility_external_allocated);
-
-    map_Div->kind     = INTRINSIC_INSTR;
-    map_Div->op       = op_Div;
-    map_Div->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
-    map_Div->ctx      = &rt_Div;
-  }
-       /* ... nor a signed div instruction ... */
-  {
-    runtime_rt rt_Div;
-    i_instr_record *map_Div = &records[n_records++].i_instr;
-
-    tp = new_type_method(ID("rt_uDiv"), 2, 1);
-    set_method_param_type(tp, 0, uint_tp);
-    set_method_param_type(tp, 1, uint_tp);
-    set_method_res_type(tp, 0, uint_tp);
-
-    rt_Div.ent             = new_entity(get_glob_type(), ID("__udivsi3"), tp);
-    rt_Div.mode            = mode_T;
-    rt_Div.mem_proj_nr     = pn_Div_M;
-    rt_Div.exc_proj_nr     = pn_Div_X_except;
-    rt_Div.exc_mem_proj_nr = pn_Div_M;
-    rt_Div.res_proj_nr     = pn_Div_res;
-
-    set_entity_visibility(rt_Div.ent, visibility_external_allocated);
-
-    map_Div->kind     = INTRINSIC_INSTR;
-    map_Div->op       = op_Div;
-    map_Div->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
-    map_Div->ctx      = &rt_Div;
-  }
+       {
+               runtime_rt rt_Div;
+               i_instr_record *map_Div = &records[n_records++].i_instr;
+
+               tp = new_type_method(ID("rt_iDiv"), 2, 1);
+               set_method_param_type(tp, 0, int_tp);
+               set_method_param_type(tp, 1, int_tp);
+               set_method_res_type(tp, 0, int_tp);
+
+               rt_Div.ent             = new_entity(get_glob_type(), ID("__divsi3"), tp);
+               rt_Div.mode            = mode_T;
+               rt_Div.res_mode        = mode_Is;
+               rt_Div.mem_proj_nr     = pn_Div_M;
+               rt_Div.regular_proj_nr = pn_Div_X_regular;
+               rt_Div.exc_proj_nr     = pn_Div_X_except;
+               rt_Div.exc_mem_proj_nr = pn_Div_M;
+               rt_Div.res_proj_nr     = pn_Div_res;
+
+               set_entity_visibility(rt_Div.ent, visibility_external_allocated);
+
+               map_Div->kind     = INTRINSIC_INSTR;
+               map_Div->op       = op_Div;
+               map_Div->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
+               map_Div->ctx      = &rt_Div;
+       }
+       /* ... nor an unsigned div instruction ... */
+       {
+               runtime_rt rt_Div;
+               i_instr_record *map_Div = &records[n_records++].i_instr;
+
+               tp = new_type_method(ID("rt_uDiv"), 2, 1);
+               set_method_param_type(tp, 0, uint_tp);
+               set_method_param_type(tp, 1, uint_tp);
+               set_method_res_type(tp, 0, uint_tp);
+
+               rt_Div.ent             = new_entity(get_glob_type(), ID("__udivsi3"), tp);
+               rt_Div.mode            = mode_T;
+               rt_Div.res_mode        = mode_Iu;
+               rt_Div.mem_proj_nr     = pn_Div_M;
+               rt_Div.regular_proj_nr = pn_Div_X_regular;
+               rt_Div.exc_proj_nr     = pn_Div_X_except;
+               rt_Div.exc_mem_proj_nr = pn_Div_M;
+               rt_Div.res_proj_nr     = pn_Div_res;
+
+               set_entity_visibility(rt_Div.ent, visibility_external_allocated);
+
+               map_Div->kind     = INTRINSIC_INSTR;
+               map_Div->op       = op_Div;
+               map_Div->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
+               map_Div->ctx      = &rt_Div;
+       }
        /* ... nor a signed mod instruction ... */
-  {
-    runtime_rt rt_Mod;
-    i_instr_record *map_Mod = &records[n_records++].i_instr;
-
-    tp = new_type_method(ID("rt_iMod"), 2, 1);
-    set_method_param_type(tp, 0, int_tp);
-    set_method_param_type(tp, 1, int_tp);
-    set_method_res_type(tp, 0, int_tp);
-
-    rt_Mod.ent             = new_entity(get_glob_type(), ID("__modsi3"), tp);
-    rt_Mod.mode            = mode_T;
-    rt_Mod.mem_proj_nr     = pn_Mod_M;
-    rt_Mod.exc_proj_nr     = pn_Mod_X_except;
-    rt_Mod.exc_mem_proj_nr = pn_Mod_M;
-    rt_Mod.res_proj_nr     = pn_Mod_res;
-
-    set_entity_visibility(rt_Mod.ent, visibility_external_allocated);
-
-    map_Mod->kind     = INTRINSIC_INSTR;
-    map_Mod->op       = op_Mod;
-    map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
-    map_Mod->ctx      = &rt_Mod;
-  }
-       /* ... nor a unsigned mod. */
-  {
-    runtime_rt rt_Mod;
-    i_instr_record *map_Mod = &records[n_records++].i_instr;
-
-    tp = new_type_method(ID("rt_uMod"), 2, 1);
-    set_method_param_type(tp, 0, uint_tp);
-    set_method_param_type(tp, 1, uint_tp);
-    set_method_res_type(tp, 0, uint_tp);
-
-    rt_Mod.ent             = new_entity(get_glob_type(), ID("__umodsi3"), tp);
-    rt_Mod.mode            = mode_T;
-    rt_Mod.mem_proj_nr     = pn_Mod_M;
-    rt_Mod.exc_proj_nr     = pn_Mod_X_except;
-    rt_Mod.exc_mem_proj_nr = pn_Mod_M;
-    rt_Mod.res_proj_nr     = pn_Mod_res;
-
-    set_entity_visibility(rt_Mod.ent, visibility_external_allocated);
-
-    map_Mod->kind     = INTRINSIC_INSTR;
-    map_Mod->op       = op_Mod;
-    map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
-    map_Mod->ctx      = &rt_Mod;
-  }
-
-  if (n_records > 0)
-    lower_intrinsics(records, n_records);
+       {
+               runtime_rt rt_Mod;
+               i_instr_record *map_Mod = &records[n_records++].i_instr;
+
+               tp = new_type_method(ID("rt_iMod"), 2, 1);
+               set_method_param_type(tp, 0, int_tp);
+               set_method_param_type(tp, 1, int_tp);
+               set_method_res_type(tp, 0, int_tp);
+
+               rt_Mod.ent             = new_entity(get_glob_type(), ID("__modsi3"), tp);
+               rt_Mod.mode            = mode_T;
+               rt_Mod.res_mode        = mode_Is;
+               rt_Mod.mem_proj_nr     = pn_Mod_M;
+               rt_Mod.regular_proj_nr = pn_Mod_X_regular;
+               rt_Mod.exc_proj_nr     = pn_Mod_X_except;
+               rt_Mod.exc_mem_proj_nr = pn_Mod_M;
+               rt_Mod.res_proj_nr     = pn_Mod_res;
+
+               set_entity_visibility(rt_Mod.ent, visibility_external_allocated);
+
+               map_Mod->kind     = INTRINSIC_INSTR;
+               map_Mod->op       = op_Mod;
+               map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
+               map_Mod->ctx      = &rt_Mod;
+       }
+       /* ... nor an unsigned mod. */
+       {
+               runtime_rt rt_Mod;
+               i_instr_record *map_Mod = &records[n_records++].i_instr;
+
+               tp = new_type_method(ID("rt_uMod"), 2, 1);
+               set_method_param_type(tp, 0, uint_tp);
+               set_method_param_type(tp, 1, uint_tp);
+               set_method_res_type(tp, 0, uint_tp);
+
+               rt_Mod.ent             = new_entity(get_glob_type(), ID("__umodsi3"), tp);
+               rt_Mod.mode            = mode_T;
+               rt_Mod.res_mode        = mode_Iu;
+               rt_Mod.mem_proj_nr     = pn_Mod_M;
+               rt_Mod.regular_proj_nr = pn_Mod_X_regular;
+               rt_Mod.exc_proj_nr     = pn_Mod_X_except;
+               rt_Mod.exc_mem_proj_nr = pn_Mod_M;
+               rt_Mod.res_proj_nr     = pn_Mod_res;
+
+               set_entity_visibility(rt_Mod.ent, visibility_external_allocated);
+
+               map_Mod->kind     = INTRINSIC_INSTR;
+               map_Mod->op       = op_Mod;
+               map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
+               map_Mod->ctx      = &rt_Mod;
+       }
+
+       if (n_records > 0)
+               lower_intrinsics(records, n_records);
 }
 
 /*****************************************************************
@@ -708,6 +716,8 @@ static arm_isa_t arm_isa_template = {
                &arm_gp_regs[REG_R11], /* base pointer */
                -1,                    /* stack direction */
                NULL,                  /* main environment */
+               7,                     /* spill costs */
+               5,                     /* reload costs */
        },
        0,                     /* use generic register names instead of SP, LR, PC */
        ARM_FPU_ARCH_FPE,      /* FPU architecture */
@@ -937,6 +947,7 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m
                curr_pc = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], env->irg, bl, curr_lr );
                arch_set_irn_register(env->arch_env, curr_pc, &arm_gp_regs[REG_PC]);
                be_set_constr_single_reg(curr_pc, BE_OUT_POS(0), &arm_gp_regs[REG_PC] );
+               be_node_set_flags(curr_pc, BE_OUT_POS(0), arch_irn_flags_ignore);
        } else {
                ir_node *sub12_node;
                ir_node *load_node;
@@ -1087,24 +1098,34 @@ static ir_graph **arm_get_irg_list(const void *self, ir_graph ***irg_list) {
        return NULL;
 }
 
+/**
+ * Called by the frontend to encode a register name into a backend specific way
+ */
+static unsigned arm_register_from_name(const char *regname) {
+       /* NYI */
+       return 0;
+}
+
 /**
  * Returns the libFirm configuration parameter for this backend.
  */
 static const backend_params *arm_get_libfirm_params(void) {
        static arch_dep_params_t ad = {
                1,  /* allow subs */
-               0,      /* Muls are fast enough on ARM */
-               31, /* shift would be ok */
+               1,      /* Muls are fast enough on ARM but ... */
+               1,  /* ... one shift would be possible better */
                0,  /* SMUL is needed, only in Arch M*/
                0,  /* UMUL is needed, only in Arch M */
                32, /* SMUL & UMUL available for 32 bit */
        };
        static backend_params p = {
+               1,     /* need dword lowering */
+               0,     /* don't support inlien assembler yet */
                NULL,  /* no additional opcodes */
                NULL,  /* will be set later */
-               1,     /* need dword lowering */
                NULL,  /* but yet no creator function */
                NULL,  /* context for create_intrinsic_fkt */
+               arm_register_from_name, /* register names */
        };
 
        p.dep_param = &ad;