X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fmips%2Fbearch_mips.c;h=b4f72149a77b4c98bb25668ab55620078a039924;hb=11dd35912fd6ad1f7637137c4c3f9e0628b8387f;hp=0f27cab4bc72f8270c5be4cfb2e07b2b0defe286;hpb=cc18a73b9046e11cdfd4065377d3cac59170aabb;p=libfirm diff --git a/ir/be/mips/bearch_mips.c b/ir/be/mips/bearch_mips.c index 0f27cab4b..b4f72149a 100644 --- a/ir/be/mips/bearch_mips.c +++ b/ir/be/mips/bearch_mips.c @@ -132,7 +132,7 @@ static const arch_register_req_t *mips_get_irn_reg_req(const void *self, arch_re assert(0 && "floating point not supported (yet)"); } else if (mode_is_int(mode) || mode_is_reference(mode)) { - memcpy(req, &(mips_default_req_mips_general_purpose.req), sizeof(*req)); + memcpy(req, &(mips_default_req_mips_gp.req), sizeof(*req)); } else if (mode == mode_T || mode == mode_M) { DBG((mod, LEVEL_1, "ignoring Phi node %+F\n", irn)); @@ -237,6 +237,12 @@ static entity *mips_get_frame_entity(const void *self, const ir_node *irn) { return NULL; } +static void mips_set_frame_entity(const void *self, ir_node *irn, entity *ent) { + mips_attr_t *attr = get_mips_attr(irn); + assert(is_mips_load_r(irn) || is_mips_store_r(irn)); + attr->stack_entity = ent; +} + /** * This function is called by the generic backend to correct offsets for * nodes accessing the stack. @@ -257,7 +263,12 @@ static const arch_irn_ops_if_t mips_irn_ops_if = { mips_classify, mips_get_flags, mips_get_frame_entity, - mips_set_frame_offset + mips_set_frame_entity, + mips_set_frame_offset, + NULL, /* get_inverse */ + NULL, /* get_op_estimated_cost */ + NULL, /* possible_memory_operand */ + NULL, /* perform_memory_operand */ }; mips_irn_ops_t mips_irn_ops = { @@ -447,10 +458,11 @@ static void mips_prepare_graph(void *self) { /** * Called immediately before emit phase. */ -static void mips_finish_irg(ir_graph *irg, mips_code_gen_t *cg) { - /* TODO: - fix offsets for nodes accessing stack - - ... - */ +static void mips_finish_irg(void *self) { + mips_code_gen_t *cg = self; + ir_graph *irg = cg->irg; + + dump_ir_block_graph_sched(irg, "-mips-finished"); } @@ -477,17 +489,15 @@ static void mips_after_ra(void* self) { static void mips_emit_and_done(void *self) { mips_code_gen_t *cg = self; ir_graph *irg = cg->irg; - FILE *out = cg->out; + FILE *out = cg->isa->out; mips_register_emitters(); if (cg->emit_decls) { - mips_gen_decls(cg->out); + mips_gen_decls(out); cg->emit_decls = 0; } - mips_finish_irg(irg, cg); - dump_ir_block_graph_sched(irg, "-mips-finished"); mips_gen_routine(out, irg, cg); cur_reg_set = NULL; @@ -501,30 +511,31 @@ static void mips_emit_and_done(void *self) { free(cg); } -static void *mips_cg_init(FILE *F, const be_irg_t *birg); +static void *mips_cg_init(const be_irg_t *birg); static const arch_code_generator_if_t mips_code_gen_if = { mips_cg_init, - NULL, /* before abi introduce */ + NULL, /* before abi introduce */ mips_prepare_graph, mips_before_sched, /* before scheduling hook */ mips_before_ra, /* before register allocation hook */ mips_after_ra, + mips_finish_irg, mips_emit_and_done }; /** * Initializes the code generator. */ -static void *mips_cg_init(FILE *F, const be_irg_t *birg) { +static void *mips_cg_init(const be_irg_t *birg) { mips_isa_t *isa = (mips_isa_t *)birg->main_env->arch_env->isa; mips_code_gen_t *cg = xmalloc(sizeof(*cg)); cg->impl = &mips_code_gen_if; cg->irg = birg->irg; cg->reg_set = new_set(mips_cmp_irn_reg_assoc, 1024); - cg->out = F; cg->arch_env = birg->main_env->arch_env; + cg->isa = isa; cg->birg = birg; cg->bl_list = NULL; FIRM_DBG_REGISTER(cg->mod, "firm.be.mips.cg"); @@ -556,16 +567,17 @@ static void *mips_cg_init(FILE *F, const be_irg_t *birg) { static mips_isa_t mips_isa_template = { &mips_isa_if, - &mips_general_purpose_regs[REG_SP], - &mips_general_purpose_regs[REG_FP], + &mips_gp_regs[REG_SP], + &mips_gp_regs[REG_FP], -1, // stack direction - 0 // num codegens?!? TODO what is this? + 0, // num codegens?!? TODO what is this? + NULL }; /** * Initializes the backend ISA and opens the output file. */ -static void *mips_init(void) { +static void *mips_init(FILE *file_handle) { static int inited = 0; mips_isa_t *isa; @@ -575,6 +587,8 @@ static void *mips_init(void) { isa = xcalloc(1, sizeof(*isa)); memcpy(isa, &mips_isa_template, sizeof(*isa)); + isa->out = file_handle; + mips_register_init(isa); mips_create_opcodes(); mips_init_opcode_transforms(); @@ -610,7 +624,7 @@ static const arch_register_class_t *mips_get_reg_class(const void *self, int i) */ const arch_register_class_t *mips_get_reg_class_for_mode(const void *self, const ir_mode *mode) { ASSERT_NO_FLOAT(mode); - return &mips_reg_classes[CLASS_mips_general_purpose]; + return &mips_reg_classes[CLASS_mips_gp]; } typedef struct { @@ -648,8 +662,8 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap dbg_info *dbg = NULL; // TODO where can I get this from? ir_node *block = get_irg_start_block(env->irg); mips_attr_t *attr; - ir_node *sp = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_SP]); - ir_node *fp = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_FP]); + ir_node *sp = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_SP]); + ir_node *fp = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_FP]); int initialstackframesize; if(env->debug) { @@ -667,13 +681,13 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap sp = new_rd_mips_addi(dbg, irg, block, sp, mode_Is); attr = get_mips_attr(sp); attr->tv = new_tarval_from_long(-initialstackframesize, mode_Is); - mips_set_irn_reg(NULL, sp, &mips_general_purpose_regs[REG_SP]); - //arch_set_irn_register(mips_get_arg_env(), sp, &mips_general_purpose_regs[REG_SP]); + mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); + //arch_set_irn_register(mips_get_arg_env(), sp, &mips_gp_regs[REG_SP]); /* TODO: where to get an edge with a0-a3 int i; for(i = 0; i < 4; ++i) { - ir_node *reg = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_A0 + i]); + ir_node *reg = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_A0 + i]); ir_node *store = new_rd_mips_store_r(dbg, irg, block, *mem, sp, reg, mode_T); attr = get_mips_attr(store); attr->load_store_mode = mode_Iu; @@ -683,7 +697,7 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap } */ - reg = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_FP]); + reg = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_FP]); store = new_rd_mips_store_r(dbg, irg, block, *mem, sp, reg, mode_T); attr = get_mips_attr(store); attr->modes.load_store_mode = mode_Iu; @@ -691,7 +705,7 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap mm[4] = new_r_Proj(irg, block, store, mode_M, pn_Store_M); - reg = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_RA]); + reg = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_RA]); store = new_rd_mips_store_r(dbg, irg, block, *mem, sp, reg, mode_T); attr = get_mips_attr(store); attr->modes.load_store_mode = mode_Iu; @@ -710,10 +724,10 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap sp = new_rd_mips_addi(dbg, irg, block, sp, mode_Is); attr = get_mips_attr(sp); attr->tv = new_tarval_from_long(-initialstackframesize, mode_Is); - mips_set_irn_reg(NULL, sp, &mips_general_purpose_regs[REG_SP]); - //arch_set_irn_register(mips_get_arg_env(), sp, &mips_general_purpose_regs[REG_SP]); + mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); + //arch_set_irn_register(mips_get_arg_env(), sp, &mips_gp_regs[REG_SP]); - reg = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_FP]); + reg = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_FP]); store = new_rd_mips_store_r(dbg, irg, block, *mem, sp, reg, mode_T); attr = get_mips_attr(store); attr->modes.load_store_mode = mode_Iu; @@ -726,13 +740,13 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap fp = new_rd_mips_addi(dbg, irg, block, sp, mode_Is); attr = get_mips_attr(fp); attr->tv = new_tarval_from_long(initialstackframesize, mode_Is); - mips_set_irn_reg(NULL, fp, &mips_general_purpose_regs[REG_FP]); - //arch_set_irn_register(mips_get_arg_env(), fp, &mips_general_purpose_regs[REG_FP]); + mips_set_irn_reg(NULL, fp, &mips_gp_regs[REG_FP]); + //arch_set_irn_register(mips_get_arg_env(), fp, &mips_gp_regs[REG_FP]); - be_abi_reg_map_set(reg_map, &mips_general_purpose_regs[REG_FP], fp); - be_abi_reg_map_set(reg_map, &mips_general_purpose_regs[REG_SP], sp); + be_abi_reg_map_set(reg_map, &mips_gp_regs[REG_FP], fp); + be_abi_reg_map_set(reg_map, &mips_gp_regs[REG_SP], sp); - return &mips_general_purpose_regs[REG_SP]; + return &mips_gp_regs[REG_SP]; } static void mips_abi_epilogue(void *self, ir_node *block, ir_node **mem, pmap *reg_map) @@ -741,19 +755,19 @@ static void mips_abi_epilogue(void *self, ir_node *block, ir_node **mem, pmap *r ir_graph *irg = env->irg; dbg_info *dbg = NULL; // TODO where can I get this from? mips_attr_t *attr; - ir_node *sp = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_SP]); - ir_node *fp = be_abi_reg_map_get(reg_map, &mips_general_purpose_regs[REG_FP]); + ir_node *sp = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_SP]); + ir_node *fp = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_FP]); ir_node *load; int initial_frame_size = env->debug ? 24 : 4; int fp_save_offset = env->debug ? 16 : 0; // restore sp - //sp = be_new_IncSP(&mips_general_purpose_regs[REG_SP], irg, block, sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_against); + //sp = be_new_IncSP(&mips_gp_regs[REG_SP], irg, block, sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_against); // copy fp to sp sp = new_rd_mips_move(dbg, irg, block, fp, mode_Iu); - mips_set_irn_reg(NULL, sp, &mips_general_purpose_regs[REG_SP]); - //arch_set_irn_register(mips_get_arg_env(), fp, &mips_general_purpose_regs[REG_SP]); + mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); + //arch_set_irn_register(mips_get_arg_env(), fp, &mips_gp_regs[REG_SP]); // 1. restore fp load = new_rd_mips_load_r(dbg, irg, block, *mem, sp, mode_T); @@ -763,11 +777,11 @@ static void mips_abi_epilogue(void *self, ir_node *block, ir_node **mem, pmap *r attr->tv = new_tarval_from_long(fp_save_offset - initial_frame_size, mode_Is); fp = new_r_Proj(irg, block, load, mode_Iu, pn_Load_res); - mips_set_irn_reg(NULL, fp, &mips_general_purpose_regs[REG_FP]); - //arch_set_irn_register(mips_get_arg_env(), fp, &mips_general_purpose_regs[REG_FP]); + mips_set_irn_reg(NULL, fp, &mips_gp_regs[REG_FP]); + //arch_set_irn_register(mips_get_arg_env(), fp, &mips_gp_regs[REG_FP]); - be_abi_reg_map_set(reg_map, &mips_general_purpose_regs[REG_FP], fp); - be_abi_reg_map_set(reg_map, &mips_general_purpose_regs[REG_SP], sp); + be_abi_reg_map_set(reg_map, &mips_gp_regs[REG_FP], fp); + be_abi_reg_map_set(reg_map, &mips_gp_regs[REG_SP], sp); } /** @@ -864,7 +878,7 @@ static void mips_get_call_abi(const void *self, ir_type *method_type, be_abi_cal for (i = 0; i < n; i++) { // first 4 params in $a0-$a3, the others on the stack if(i < 4) { - reg = &mips_general_purpose_regs[REG_A0 + i]; + reg = &mips_gp_regs[REG_A0 + i]; be_abi_call_param_reg(abi, i, reg); } else { /* default: all parameters on stack */ @@ -882,7 +896,7 @@ static void mips_get_call_abi(const void *self, ir_type *method_type, be_abi_cal mode = get_type_mode(tp); ASSERT_NO_FLOAT(mode); - reg = &mips_general_purpose_regs[REG_V0 + i]; + reg = &mips_gp_regs[REG_V0 + i]; be_abi_call_res_reg(abi, i, reg); } } @@ -906,6 +920,38 @@ static const arch_code_generator_if_t *mips_get_code_generator_if(void *self) { return &mips_code_gen_if; } +/** + * Returns the necessary byte alignment for storing a register of given class. + */ +static int mips_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) { + ir_mode *mode = arch_register_class_mode(cls); + return get_mode_size_bytes(mode); +} + +/** + * Returns the libFirm configuration parameter for this backend. + */ +static const backend_params *mips_get_libfirm_params(void) { + static arch_dep_params_t ad = { + 1, /* allow subs */ + 0, /* Muls are fast enough on Mips */ + 31, /* shift would be ok */ + 0, /* no Mulhs */ + 0, /* no Mulhu */ + 32, /* Mulhs & Mulhu available for 32 bit */ + }; + static backend_params p = { + 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 */ + }; + + p.dep_param = &ad; + return &p; +} + #ifdef WITH_LIBCORE static void mips_register_options(lc_opt_entry_t *ent) { @@ -913,9 +959,6 @@ static void mips_register_options(lc_opt_entry_t *ent) #endif /* WITH_LIBCORE */ const arch_isa_if_t mips_isa_if = { -#ifdef WITH_LIBCORE - mips_register_options, -#endif mips_init, mips_done, mips_get_n_reg_class, @@ -925,4 +968,9 @@ const arch_isa_if_t mips_isa_if = { mips_get_irn_handler, mips_get_code_generator_if, mips_get_list_sched_selector, + mips_get_reg_class_alignment, + mips_get_libfirm_params, +#ifdef WITH_LIBCORE + mips_register_options +#endif };