X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fbe%2Fsparc%2Fbearch_sparc.c;h=6ab6adadde9c4c5b2eb9b53792bd0e5274cbd51f;hb=2158510961e84fb11e9195c200335f2314e49055;hp=212b59a9eb1b93064e63f9dd2d3a470b7c068c62;hpb=b460e057a0751e29f22c5e4407d9a48299b8096c;p=libfirm diff --git a/ir/be/sparc/bearch_sparc.c b/ir/be/sparc/bearch_sparc.c index 212b59a9e..6ab6adadd 100644 --- a/ir/be/sparc/bearch_sparc.c +++ b/ir/be/sparc/bearch_sparc.c @@ -20,7 +20,7 @@ /** * @file * @brief The main sparc backend driver file. - * @version $Id: bearch_TEMPLATE.c 26673 2009-10-01 16:43:13Z matze $ + * @version $Id$ */ #include "config.h" @@ -65,6 +65,7 @@ #include "gen_sparc_regalloc_if.h" #include "sparc_transform.h" #include "sparc_emitter.h" +#include "sparc_map_regs.h" DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) @@ -74,10 +75,22 @@ static arch_irn_class_t sparc_classify(const ir_node *irn) return 0; } -static ir_entity *sparc_get_frame_entity(const ir_node *node) +static ir_entity *sparc_get_frame_entity(const ir_node *irn) { - (void) node; - /* TODO: return the ir_entity assigned to the frame */ + const sparc_attr_t *attr = get_sparc_attr_const(irn); + + if (is_sparc_FrameAddr(irn)) { + const sparc_symconst_attr_t *attr = get_irn_generic_attr_const(irn); + return attr->entity; + } + + if (attr->is_load_store) { + const sparc_load_store_attr_t *load_store_attr = get_sparc_load_store_attr_const(irn); + if (load_store_attr->is_frame_entity) { + return load_store_attr->entity; + } + } + return NULL; } @@ -85,6 +98,7 @@ static void sparc_set_frame_entity(ir_node *node, ir_entity *ent) { (void) node; (void) ent; + panic("sparc_set_frame_entity() called. This should not happen."); /* TODO: set the ir_entity assigned to the frame */ } @@ -94,9 +108,14 @@ static void sparc_set_frame_entity(ir_node *node, ir_entity *ent) */ static void sparc_set_frame_offset(ir_node *irn, int offset) { - (void) irn; - (void) offset; - /* TODO: correct offset if irn accesses the stack */ + if (is_sparc_FrameAddr(irn)) { + sparc_symconst_attr_t *attr = get_irn_generic_attr(irn); + attr->fp_offset += offset; + } else { + sparc_load_store_attr_t *attr = get_sparc_load_store_attr(irn); + assert(attr->base.is_load_store); + attr->offset += offset; + } } static int sparc_get_sp_bias(const ir_node *irn) @@ -174,10 +193,86 @@ static void sparc_before_ra(void *self) be_sched_fix_flags(cg->birg, &sparc_reg_classes[CLASS_sparc_flags], &sparc_flags_remat); } +/** + * transform reload node => load + */ +static void transform_Reload(ir_node *node) +{ + ir_graph *irg = get_irn_irg(node); + ir_node *block = get_nodes_block(node); + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *ptr = get_irg_frame(irg); + ir_node *mem = get_irn_n(node, be_pos_Reload_mem); + ir_mode *mode = get_irn_mode(node); + ir_entity *entity = be_get_frame_entity(node); + const arch_register_t *reg; + ir_node *proj; + ir_node *load; + + ir_node *sched_point = sched_prev(node); + + load = new_bd_sparc_Load(dbgi, block, ptr, mem, mode, entity, false, 0, true); + sched_add_after(sched_point, load); + sched_remove(node); + + proj = new_rd_Proj(dbgi, load, mode, pn_sparc_Load_res); + + reg = arch_get_irn_register(node); + arch_set_irn_register(proj, reg); + + exchange(node, proj); +} + +/** + * transform spill node => store + */ +static void transform_Spill(ir_node *node) +{ + ir_graph *irg = get_irn_irg(node); + ir_node *block = get_nodes_block(node); + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *ptr = get_irg_frame(irg); + ir_node *mem = new_NoMem(); + ir_node *val = get_irn_n(node, be_pos_Spill_val); + ir_mode *mode = get_irn_mode(val); + ir_entity *entity = be_get_frame_entity(node); + ir_node *sched_point; + ir_node *store; + + sched_point = sched_prev(node); + store = new_bd_sparc_Store(dbgi, block, ptr, val, mem, mode, entity, false, 0, true); + sched_remove(node); + sched_add_after(sched_point, store); + + exchange(node, store); +} + +/** + * walker to transform be_Spill and be_Reload nodes + */ +static void sparc_after_ra_walker(ir_node *block, void *data) +{ + ir_node *node, *prev; + (void) data; + + for (node = sched_last(block); !sched_is_begin(node); node = prev) { + prev = sched_prev(node); + + if (be_is_Reload(node)) { + transform_Reload(node); + } else if (be_is_Spill(node)) { + transform_Spill(node); + } + } +} + + static void sparc_after_ra(void *self) { - (void) self; - /* Some stuff you need to do immediatly after register allocation */ + sparc_code_gen_t *cg = self; + be_coalesce_spillslots(cg->birg); + + irg_block_walk_graph(cg->irg, NULL, sparc_after_ra_walker, NULL); } @@ -222,7 +317,7 @@ static void *sparc_cg_init(be_irg_t *birg) if (! int_tp) { /* create an integer type with machine size */ - int_tp = new_type_primitive(new_id_from_chars("int", 3), mode_Is); + int_tp = new_type_primitive(mode_Is); } cg = XMALLOC(sparc_code_gen_t); @@ -237,8 +332,6 @@ static void *sparc_cg_init(be_irg_t *birg) //cg->unknown_fpa = NULL; cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0; - FIRM_DBG_REGISTER(cg->mod, "firm.be.sparc.cg"); - /* enter the current code generator */ isa->cg = cg; @@ -271,7 +364,7 @@ static arch_env_t *sparc_init(FILE *outfile) static int run_once = 0; sparc_isa_t *isa; - if(run_once) + if (run_once) return NULL; run_once = 1; @@ -296,7 +389,7 @@ static void sparc_done(void *self) sparc_isa_t *isa = self; /* emit now all global declarations */ - be_gas_emit_decls(isa->arch_env.main_env, 0); + be_gas_emit_decls(isa->arch_env.main_env); be_emit_exit(); free(self); @@ -322,7 +415,7 @@ static const arch_register_class_t *sparc_get_reg_class(unsigned i) * @param mode The mode in question. * @return A register class which can hold values of the given mode. */ -const arch_register_class_t *sparc_get_reg_class_for_mode(const ir_mode *mode) +static const arch_register_class_t *sparc_get_reg_class_for_mode(const ir_mode *mode) { if (mode_is_float(mode)) return &sparc_reg_classes[CLASS_sparc_fp]; @@ -377,7 +470,7 @@ static const arch_register_t *sparc_abi_prologue(void *self, ir_node **mem, (void) mem; (void) stack_bias; - if(env->flags.try_omit_fp) + if (env->flags.try_omit_fp) return env->arch_env->sp; //panic("framepointer not implemented yet"); @@ -408,8 +501,8 @@ static const be_abi_callbacks_t sparc_abi_callbacks = { * @param method_type The type of the method (procedure) in question. * @param abi The abi object to be modified */ -void sparc_get_call_abi(const void *self, ir_type *method_type, - be_abi_call_t *abi) +static void sparc_get_call_abi(const void *self, ir_type *method_type, + be_abi_call_t *abi) { ir_type *tp; ir_mode *mode; @@ -428,13 +521,17 @@ void sparc_get_call_abi(const void *self, ir_type *method_type, be_abi_call_set_flags(abi, call_flags, &sparc_abi_callbacks); for (i = 0; i < n; i++) { - /* TODO: implement register parameter: */ /* reg = get reg for param i; */ /* be_abi_call_param_reg(abi, i, reg); */ - /* 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); + + /* pass args 0-5 via registers, remaining via stack */ + if (i < 6) { + be_abi_call_param_reg(abi, i, sparc_get_RegParam_reg(i)); + } else { + tp = get_method_param_type(method_type, i); + mode = get_type_mode(tp); + be_abi_call_param_stack(abi, i, mode, 4, 0, 0); + } } /* TODO: set correct return register */ @@ -448,11 +545,11 @@ void sparc_get_call_abi(const void *self, ir_type *method_type, } } -int sparc_to_appear_in_schedule(void *block_env, const ir_node *irn) +static int sparc_to_appear_in_schedule(void *block_env, const ir_node *irn) { (void) block_env; - if(!is_sparc_irn(irn)) + if (!is_sparc_irn(irn)) return -1; return 1; @@ -503,7 +600,8 @@ static int sparc_get_reg_class_alignment(const arch_register_class_t *cls) /** * Returns the libFirm configuration parameter for this backend. */ -static const backend_params *sparc_get_backend_params(void) { +static const backend_params *sparc_get_backend_params(void) +{ static backend_params p = { 0, /* no dword lowering */ 0, /* no inline assembly */ @@ -525,16 +623,14 @@ static const be_execution_unit_t ***sparc_get_allowed_execution_units( { (void) irn; /* TODO */ - assert(0); - return NULL; + panic("sparc_get_allowed_execution_units not implemented yet"); } static const be_machine_t *sparc_get_machine(const void *self) { (void) self; /* TODO */ - assert(0); - return NULL; + panic("sparc_get_machine not implemented yet"); } static ir_graph **sparc_get_backend_irg_list(const void *self, @@ -578,6 +674,7 @@ const arch_isa_if_t sparc_isa_if = { sparc_is_valid_clobber }; +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_sparc); void be_init_arch_sparc(void) { be_register_isa_if("sparc", &sparc_isa_if); @@ -585,4 +682,3 @@ void be_init_arch_sparc(void) sparc_init_transform(); sparc_init_emitter(); } -BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_sparc);