X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Farm%2Fbearch_arm.c;h=eeb378f51624114e7192ee84851912d550e2f4d8;hb=01940748e783a49ba0f2a5edccd33346499401b3;hp=06deada20d934e2032ecc0d7777aa9e7970394e7;hpb=371f15ddc89adae025f1e9275968a2a6d29becc7;p=libfirm diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 06deada20..eeb378f51 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -23,9 +23,7 @@ * @author Oliver Richter, Tobias Gneist * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include "lc_opts.h" #include "lc_opts_enum.h" @@ -43,6 +41,7 @@ #include "bitset.h" #include "debug.h" +#include "array_t.h" #include "irtools.h" #include "../bearch_t.h" /* the general register allocator interface */ @@ -131,58 +130,6 @@ static const arch_register_req_t *arm_get_irn_reg_req(const ir_node *node, return arch_no_register_req; } -static void arm_set_irn_reg(ir_node *irn, const arch_register_t *reg) -{ - int pos = 0; - - if (get_irn_mode(irn) == mode_X) { - return; - } - - if (is_Proj(irn)) { - pos = get_Proj_proj(irn); - irn = skip_Proj(irn); - } - - if (is_arm_irn(irn)) { - const arch_register_t **slots; - - slots = get_arm_slots(irn); - slots[pos] = reg; - } - else { - /* here we set the registers for the Phi nodes */ - arm_set_firm_reg(irn, reg, cur_reg_set); - } -} - -static const arch_register_t *arm_get_irn_reg(const ir_node *irn) -{ - int pos = 0; - const arch_register_t *reg = NULL; - - if (is_Proj(irn)) { - - if (get_irn_mode(irn) == mode_X) { - return NULL; - } - - pos = get_Proj_proj(irn); - irn = skip_Proj_const(irn); - } - - if (is_arm_irn(irn)) { - const arch_register_t **slots; - slots = get_arm_slots(irn); - reg = slots[pos]; - } - else { - reg = arm_get_firm_reg(irn, cur_reg_set); - } - - return reg; -} - static arch_irn_class_t arm_classify(const ir_node *irn) { irn = skip_Proj_const(irn); @@ -190,36 +137,10 @@ static arch_irn_class_t arm_classify(const ir_node *irn) if (is_cfop(irn)) { return arch_irn_class_branch; } - else if (is_arm_irn(irn)) { - return arch_irn_class_normal; - } return 0; } -static arch_irn_flags_t arm_get_flags(const ir_node *irn) -{ - arch_irn_flags_t flags = arch_irn_flags_none; - - if(is_Unknown(irn)) { - return arch_irn_flags_ignore; - } - - if (is_Proj(irn) && mode_is_datab(get_irn_mode(irn))) { - ir_node *pred = get_Proj_pred(irn); - if (is_arm_irn(pred)) { - flags = get_arm_out_flags(pred, get_Proj_proj(irn)); - } - irn = pred; - } - - if (is_arm_irn(irn)) { - flags |= get_arm_flags(irn); - } - - return flags; -} - static ir_entity *arm_get_frame_entity(const ir_node *irn) { /* we do NOT transform be_Spill or be_Reload nodes, so we never have frame access using ARM nodes. */ @@ -254,10 +175,7 @@ static int arm_get_sp_bias(const ir_node *irn) static const arch_irn_ops_t arm_irn_ops = { arm_get_irn_reg_req, - arm_set_irn_reg, - arm_get_irn_reg, arm_classify, - arm_get_flags, arm_get_frame_entity, arm_set_frame_entity, arm_set_stack_bias, @@ -314,15 +232,6 @@ static void arm_finish_irg(void *self) } -/** - * These are some hooks which must be filled but are probably not needed. - */ -static void arm_before_sched(void *self) -{ - (void) self; - /* Some stuff you need to do after scheduling but before register allocation */ -} - static void arm_before_ra(void *self) { (void) self; @@ -383,10 +292,9 @@ static ir_node *convert_dbl_to_int(ir_node *bl, ir_node *arg, ir_node *mem, v = (v << 8) | get_tarval_sub_bits(tv, 1); v = (v << 8) | get_tarval_sub_bits(tv, 0); *resL = new_Const_long(mode_Is, v); - } - else if (get_irn_op(skip_Proj(arg)) == op_Load) { + } else if (is_Load(skip_Proj(arg))) { /* FIXME: handling of low/high depends on LE/BE here */ - assert(0); + panic("Unimplemented convert_dbl_to_int() case"); } else { ir_graph *irg = current_ir_graph; @@ -423,14 +331,12 @@ static ir_node *convert_sng_to_int(ir_node *bl, ir_node *arg) v = (v << 8) | get_tarval_sub_bits(tv, 1); v = (v << 8) | get_tarval_sub_bits(tv, 0); return new_Const_long(mode_Is, v); - } - else if (get_irn_op(skip_Proj(arg)) == op_Load) { + } else if (is_Load(skip_Proj(arg))) { ir_node *load; load = skip_Proj(arg); } - assert(0); - return NULL; + panic("Unimplemented convert_sng_to_int() case"); } /** @@ -563,7 +469,6 @@ static const arch_code_generator_if_t arm_code_gen_if = { arm_before_abi, /* before abi introduce */ arm_prepare_graph, NULL, /* spill */ - arm_before_sched, /* before scheduling hook */ arm_before_ra, /* before register allocation hook */ arm_after_ra, arm_finish_irg, @@ -583,11 +488,10 @@ static void *arm_cg_init(be_irg_t *birg) { int_tp = new_type_primitive(new_id_from_chars("int", 3), mode_Is); } - cg = xmalloc(sizeof(*cg)); + cg = XMALLOC(arm_code_gen_t); cg->impl = &arm_code_gen_if; cg->irg = birg->irg; cg->reg_set = new_set(arm_cmp_irn_reg_assoc, 1024); - cg->arch_env = birg->main_env->arch_env; cg->isa = isa; cg->birg = birg; cg->int_tp = int_tp; @@ -769,7 +673,7 @@ static arch_env_t *arm_init(FILE *file_handle) { if (inited) return NULL; - isa = xmalloc(sizeof(*isa)); + isa = XMALLOC(arm_isa_t); memcpy(isa, &arm_isa_template, sizeof(*isa)); arm_register_init(); @@ -881,62 +785,67 @@ typedef struct { static void *arm_abi_init(const be_abi_call_t *call, const arch_env_t *arch_env, ir_graph *irg) { - arm_abi_env_t *env = xmalloc(sizeof(env[0])); - be_abi_call_flags_t fl = be_abi_call_get_flags(call); + arm_abi_env_t *env = XMALLOC(arm_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; } -static void arm_abi_dont_save_regs(void *self, pset *s) -{ - arm_abi_env_t *env = self; - if (env->flags.try_omit_fp) - pset_insert_ptr(s, env->arch_env->bp); -} - - - /** - * Build the ARM prolog + * Generate the routine prologue. + * + * @param self The callback object. + * @param mem A pointer to the mem node. Update this if you define new memory. + * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes. + * @param stack_bias Points to the current stack bias, can be modified if needed. + * + * @return The register which shall be used as a stack frame base. + * + * All nodes which define registers in @p reg_map must keep @p reg_map current. */ -static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *reg_map) { - ir_node *keep, *store; - arm_abi_env_t *env = self; - ir_graph *irg = env->irg; - ir_node *block = get_irg_start_block(irg); - arch_register_class_t *gp = &arm_reg_classes[CLASS_arm_gp]; +static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias) { + arm_abi_env_t *env = self; + ir_node *keep, *store; + ir_graph *irg; + ir_node *block; + arch_register_class_t *gp; + + ir_node *fp, *ip, *lr, *pc; + ir_node *sp = be_abi_reg_map_get(reg_map, env->arch_env->sp); - ir_node *fp = be_abi_reg_map_get(reg_map, env->arch_env->bp); - ir_node *ip = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_R12]); - ir_node *sp = be_abi_reg_map_get(reg_map, env->arch_env->sp); - ir_node *lr = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_LR]); - ir_node *pc = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_PC]); + (void) stack_bias; if (env->flags.try_omit_fp) return env->arch_env->sp; + fp = be_abi_reg_map_get(reg_map, env->arch_env->bp); + ip = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_R12]); + lr = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_LR]); + pc = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_PC]); + + gp = &arm_reg_classes[CLASS_arm_gp]; + irg = env->irg; + block = get_irg_start_block(irg); + ip = be_new_Copy(gp, irg, block, sp); - arch_set_irn_register(env->arch_env, ip, &arm_gp_regs[REG_R12]); - be_set_constr_single_reg(ip, BE_OUT_POS(0), &arm_gp_regs[REG_R12] ); + be_set_constr_single_reg_out(ip, 0, &arm_gp_regs[REG_R12], arch_register_req_type_produces_sp); store = new_rd_arm_StoreStackM4Inc(NULL, irg, block, sp, fp, ip, lr, pc, *mem); sp = new_r_Proj(irg, block, store, env->arch_env->sp->reg_class->mode, pn_arm_StoreStackM4Inc_ptr); - arch_set_irn_register(env->arch_env, sp, env->arch_env->sp); + arch_set_irn_register(sp, env->arch_env->sp); *mem = new_r_Proj(irg, block, store, mode_M, pn_arm_StoreStackM4Inc_M); keep = be_new_CopyKeep_single(gp, irg, block, ip, sp, get_irn_mode(ip)); - be_node_set_reg_class(keep, 1, gp); - arch_set_irn_register(env->arch_env, keep, &arm_gp_regs[REG_R12]); - be_set_constr_single_reg(keep, BE_OUT_POS(0), &arm_gp_regs[REG_R12] ); + be_node_set_reg_class_in(keep, 1, gp); + be_set_constr_single_reg_out(keep, 0, &arm_gp_regs[REG_R12], arch_register_req_type_produces_sp); fp = new_rd_arm_Sub_i(NULL, irg, block, keep, get_irn_mode(fp), 4); - arch_set_irn_register(env->arch_env, fp, env->arch_env->bp); - fp = be_new_Copy(gp, irg, block, fp); // XXX Gammelfix: only be_ nodes can have the ignore flag set - arch_set_irn_register(env->arch_env, fp, env->arch_env->bp); - be_node_set_flags(fp, BE_OUT_POS(0), arch_irn_flags_ignore); + arch_set_irn_register(fp, env->arch_env->bp); + fp = be_new_Copy(gp, irg, block, fp); // XXX Gammelfix: only be_ have custom register requirements + be_set_constr_single_reg_out(fp, 0, env->arch_env->bp, 0); be_abi_reg_map_set(reg_map, env->arch_env->bp, fp); be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_R12], keep); @@ -960,24 +869,19 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m // TODO: Activate Omit fp in epilogue if (env->flags.try_omit_fp) { curr_sp = be_new_IncSP(env->arch_env->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0); - add_irn_dep(curr_sp, *mem); curr_lr = be_new_CopyKeep_single(&arm_reg_classes[CLASS_arm_gp], env->irg, bl, curr_lr, curr_sp, get_irn_mode(curr_lr)); - be_node_set_reg_class(curr_lr, 1, &arm_reg_classes[CLASS_arm_gp]); - arch_set_irn_register(env->arch_env, curr_lr, &arm_gp_regs[REG_LR]); - be_set_constr_single_reg(curr_lr, BE_OUT_POS(0), &arm_gp_regs[REG_LR] ); + be_set_constr_single_reg_out(curr_lr, 0, &arm_gp_regs[REG_LR], 0); 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); + be_set_constr_single_reg_out(curr_pc, BE_OUT_POS(0), &arm_gp_regs[REG_PC], 0); } else { ir_node *sub12_node; ir_node *load_node; sub12_node = new_rd_arm_Sub_i(NULL, env->irg, bl, curr_bp, mode_Iu, 12); // FIXME //set_arm_req_out_all(sub12_node, sub12_req); - arch_set_irn_register(env->arch_env, sub12_node, env->arch_env->sp); + arch_set_irn_register(sub12_node, env->arch_env->sp); load_node = new_rd_arm_LoadStackM3( NULL, env->irg, bl, sub12_node, *mem ); // FIXME //set_arm_req_out(load_node, &arm_default_req_arm_gp_r11, 0); @@ -987,9 +891,9 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m curr_sp = new_r_Proj(env->irg, bl, load_node, env->arch_env->sp->reg_class->mode, pn_arm_LoadStackM3_res1); curr_pc = new_r_Proj(env->irg, bl, load_node, mode_Iu, pn_arm_LoadStackM3_res2); *mem = new_r_Proj(env->irg, bl, load_node, mode_M, pn_arm_LoadStackM3_M); - arch_set_irn_register(env->arch_env, curr_bp, env->arch_env->bp); - arch_set_irn_register(env->arch_env, curr_sp, env->arch_env->sp); - arch_set_irn_register(env->arch_env, curr_pc, &arm_gp_regs[REG_PC]); + arch_set_irn_register(curr_bp, env->arch_env->bp); + arch_set_irn_register(curr_sp, env->arch_env->sp); + arch_set_irn_register(curr_pc, &arm_gp_regs[REG_PC]); } be_abi_reg_map_set(reg_map, env->arch_env->sp, curr_sp); be_abi_reg_map_set(reg_map, env->arch_env->bp, curr_bp); @@ -1001,7 +905,6 @@ static const be_abi_callbacks_t arm_abi_callbacks = { arm_abi_init, free, arm_get_between_type, - arm_abi_dont_save_regs, arm_abi_prologue, arm_abi_epilogue, }; @@ -1123,15 +1026,13 @@ static const be_execution_unit_t ***arm_get_allowed_execution_units(const void * (void) self; (void) irn; /* TODO */ - assert(0); - return NULL; + panic("Unimplemented arm_get_allowed_execution_units()"); } static const be_machine_t *arm_get_machine(const void *self) { (void) self; /* TODO */ - assert(0); - return NULL; + panic("Unimplemented arm_get_machine()"); } /** @@ -1184,6 +1085,21 @@ static int arm_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j) { return 1; } +static asm_constraint_flags_t arm_parse_asm_constraint(const void *self, const char **c) +{ + /* asm not supported */ + (void) self; + (void) c; + return ASM_CONSTRAINT_FLAG_INVALID; +} + +static int arm_is_valid_clobber(const void *self, const char *clobber) +{ + (void) self; + (void) clobber; + return 0; +} + /** * Returns the libFirm configuration parameter for this backend. */ @@ -1242,6 +1158,7 @@ static const lc_opt_table_entry_t arm_options[] = { const arch_isa_if_t arm_isa_if = { arm_init, arm_done, + NULL, /* handle_intrinsics */ arm_get_n_reg_class, arm_get_reg_class, arm_get_reg_class_for_mode, @@ -1254,6 +1171,9 @@ const arch_isa_if_t arm_isa_if = { arm_get_allowed_execution_units, arm_get_machine, arm_get_irg_list, + NULL, /* mark remat */ + arm_parse_asm_constraint, + arm_is_valid_clobber }; void be_init_arch_arm(void)