From 86fe675b2126c88d1417ff62ac31dbb08a709b0e Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 7 May 2007 08:36:19 +0000 Subject: [PATCH] mips backend updates: - fixed the condition jump nodes - improvements to transform code - various bugfixes/updates for new be code [r13673] --- ir/be/mips/bearch_mips.c | 66 ++--- ir/be/mips/bearch_mips_t.h | 4 - ir/be/mips/mips_emitter.c | 30 ++- ir/be/mips/mips_emitter.h | 6 +- ir/be/mips/mips_new_nodes.c | 28 +- ir/be/mips/mips_nodes_attr.h | 10 +- ir/be/mips/mips_scheduler.c | 21 +- ir/be/mips/mips_spec.pl | 281 ++++++++------------ ir/be/mips/mips_transform.c | 498 +++++++++++++++++------------------ 9 files changed, 453 insertions(+), 491 deletions(-) diff --git a/ir/be/mips/bearch_mips.c b/ir/be/mips/bearch_mips.c index 015dbf03a..6939655a2 100644 --- a/ir/be/mips/bearch_mips.c +++ b/ir/be/mips/bearch_mips.c @@ -38,6 +38,7 @@ #include "iredges.h" #include "irdump.h" #include "irextbb.h" +#include "error.h" #include "bitset.h" #include "debug.h" @@ -206,19 +207,18 @@ static arch_irn_flags_t mips_get_flags(const void *self, const ir_node *irn) { return 0; } -static ir_entity *mips_get_frame_entity(const void *self, const ir_node *irn) { - if(is_mips_load_r(irn) || is_mips_store_r(irn)) { - mips_attr_t *attr = get_mips_attr(irn); - - return attr->stack_entity; - } +static +ir_entity *mips_get_frame_entity(const void *self, const ir_node *node) { + if(!is_mips_irn(node)) + return NULL; - return NULL; + mips_attr_t *attr = get_mips_attr(node); + return attr->stack_entity; } -static void mips_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent) { +static +void mips_set_frame_entity(const void *self, ir_node *irn, ir_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; } @@ -226,11 +226,13 @@ static void mips_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent * This function is called by the generic backend to correct offsets for * nodes accessing the stack. */ -static void mips_set_frame_offset(const void *self, ir_node *irn, int offset) { +static void mips_set_frame_offset(const void *self, ir_node *irn, int offset) +{ + panic("TODO"); +#if 0 mips_attr_t *attr = get_mips_attr(irn); - assert(is_mips_load_r(irn) || is_mips_store_r(irn)); - attr->stack_entity_offset = offset; +#endif } static int mips_get_sp_bias(const void *self, const ir_node *irn) { @@ -356,6 +358,7 @@ static void mips_create_block_sched(mips_code_gen_t *cg) { cg->bl_list = bl_list; } +#if 0 typedef struct _wenv_t { ir_node *list; } wenv_t; @@ -371,8 +374,10 @@ static void collect_copyb_nodes(ir_node *node, void *env) { wenv->list = node; } } +#endif static void replace_copyb_nodes(mips_code_gen_t *cg) { +#if 0 wenv_t env; ir_node *copy, *next; ir_node *old_bl, *new_bl, *jmp, *new_jmp, *mem; @@ -410,6 +415,8 @@ static void replace_copyb_nodes(mips_code_gen_t *cg) { } } } +#endif + (void) cg; } /** @@ -516,7 +523,6 @@ static void *mips_cg_init(be_irg_t *birg) { cg->isa = isa; cg->birg = birg; cg->bl_list = NULL; - FIRM_DBG_REGISTER(cg->mod, "firm.be.mips.cg"); cur_reg_set = cg->reg_set; @@ -565,7 +571,7 @@ static void *mips_init(FILE *file_handle) { mips_register_init(isa); mips_create_opcodes(); - mips_init_opcode_transforms(); + // mips_init_opcode_transforms(); /* we mark referenced global entities, so we can only emit those which * are actually referenced. (Note: you mustn't use the type visited flag @@ -682,20 +688,18 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap */ 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); + store = new_rd_mips_sw(dbg, irg, block, *mem, sp, reg); attr = get_mips_attr(store); - attr->modes.load_store_mode = mode_Iu; - attr->tv = new_tarval_from_long(16, mode_Is); + attr->tv = new_tarval_from_long(16, mode_Hs); - mm[4] = new_r_Proj(irg, block, store, mode_M, pn_Store_M); + mm[4] = store; 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); + store = new_rd_mips_sw(dbg, irg, block, *mem, sp, reg); attr = get_mips_attr(store); - attr->modes.load_store_mode = mode_Iu; - attr->tv = new_tarval_from_long(20, mode_Is); + attr->tv = new_tarval_from_long(20, mode_Hs); - mm[5] = new_r_Proj(irg, block, store, mode_M, pn_Store_M); + mm[5] = store; // TODO ideally we would route these mem edges directly towards the epilogue sync = new_r_Sync(irg, block, 2, mm+4); @@ -712,12 +716,11 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap //arch_set_irn_register(mips_get_arg_env(), sp, &mips_gp_regs[REG_SP]); 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); + store = new_rd_mips_sw(dbg, irg, block, *mem, sp, reg); attr = get_mips_attr(store); - attr->modes.load_store_mode = mode_Iu; - attr->tv = new_tarval_from_long(0, mode_Is); + attr->tv = new_tarval_from_long(0, mode_Hs); - *mem = new_r_Proj(irg, block, store, mode_M, pn_Store_M); + *mem = store; } // setup framepointer @@ -751,15 +754,14 @@ static void mips_abi_epilogue(void *self, ir_node *block, ir_node **mem, pmap *r //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); + load = new_rd_mips_lw(dbg, irg, block, *mem, sp); attr = get_mips_attr(load); - attr->modes.load_store_mode = mode_Iu; // sp is at the fp address already, so we have to do fp_save_offset - initial_frame_size - attr->tv = new_tarval_from_long(fp_save_offset - initial_frame_size, mode_Is); + attr->tv = new_tarval_from_long(fp_save_offset - initial_frame_size, mode_Hs); - fp = new_r_Proj(irg, block, load, mode_Iu, pn_Load_res); - 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]); + fp = new_r_Proj(irg, block, load, mode_Iu, pn_mips_lw_res); + *mem = new_r_Proj(irg, block, load, mode_Iu, pn_mips_lw_M); + arch_set_irn_register(env->arch_env, fp, &mips_gp_regs[REG_FP]); 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); diff --git a/ir/be/mips/bearch_mips_t.h b/ir/be/mips/bearch_mips_t.h index e1f54387b..a9a76c557 100644 --- a/ir/be/mips/bearch_mips_t.h +++ b/ir/be/mips/bearch_mips_t.h @@ -48,7 +48,6 @@ struct mips_code_gen_t { const be_irg_t *birg; /**< The be-irg (contains additional information about the irg) */ ir_node **bl_list; /**< The block schedule list. */ survive_dce_t *bl_list_sdce; /**< survive dce environment for the block schedule list */ - DEBUG_ONLY(firm_dbg_module_t *mod;) /**< debugging module */ }; struct mips_isa_t { @@ -73,9 +72,6 @@ struct mips_transform_env_t { ir_node *irn; /**< The irn, to be transformed */ ir_mode *mode; /**< The mode of the irn */ mips_code_gen_t *cg; /**< The code generator */ - DEBUG_ONLY(firm_dbg_module_t *mod;) /**< The firm debugger */ }; -ir_node *mips_new_NoReg(mips_code_gen_t *cg); - #endif diff --git a/ir/be/mips/mips_emitter.c b/ir/be/mips/mips_emitter.c index 7beb5b5d2..dd0e56ac5 100644 --- a/ir/be/mips/mips_emitter.c +++ b/ir/be/mips/mips_emitter.c @@ -231,10 +231,13 @@ static const char *node_const_to_str(ir_node *n) void mips_emit_immediate(mips_emit_env_t *env, const ir_node *node) { - const mips_attr_t *attr; + const mips_attr_t *attr = get_mips_attr(node); - attr = get_mips_attr(node); - be_emit_tarval(env->emit, attr->tv); + if(attr->tv != NULL) { + be_emit_tarval(env->emit, attr->tv); + } else { + be_emit_cstring(env->emit, "/* TODO */ 0"); + } } /* @@ -379,7 +382,7 @@ const char* mips_get_block_label(const ir_node* block) static void mips_emit_block_label(mips_emit_env_t *env, const ir_node *block) { - be_emit_irprintf(env->emit, "BLOCK_%ld", get_irn_node_nr(block)); + be_emit_irprintf(env->emit, "BLOCK_%d", get_irn_node_nr(block)); } static void mips_emit_Jump(mips_emit_env_t *env, const ir_node *node) @@ -392,7 +395,7 @@ static void mips_emit_Jump(mips_emit_env_t *env, const ir_node *node) be_emit_finish_line_gas(env->emit, node); } -ir_node *mips_get_jump_block(const ir_node* node, int projn) +ir_node *mips_get_jump_block(const ir_node* node, long projn) { const ir_edge_t *oute; for(oute = get_irn_out_edge_first(node); oute != NULL; @@ -409,7 +412,8 @@ ir_node *mips_get_jump_block(const ir_node* node, int projn) return NULL; } -void mips_emit_jump_target_proj(mips_emit_env_t *env, const ir_node *node, int projn) +void mips_emit_jump_target_proj(mips_emit_env_t *env, const ir_node *node, + long projn) { ir_node *jumpblock = mips_get_jump_block(node, projn); assert(jumpblock != NULL); @@ -425,6 +429,17 @@ void mips_emit_jump_target(mips_emit_env_t *env, const ir_node *node) mips_emit_block_label(env, jumpblock); } +void mips_emit_jump_or_fallthrough(mips_emit_env_t *env, const ir_node *node, + long pn) +{ + ir_node *jumpblock = mips_get_jump_block(node, pn); + assert(jumpblock != NULL); + + /* TODO: use fallthrough when possible */ + be_emit_cstring(env->emit, "b "); + mips_emit_block_label(env, jumpblock); +} + /************************************************************************ * ____ _ _ _ _ * * / ___|_ _(_) |_ ___| |__ | |_ _ _ __ ___ _ __ * @@ -523,7 +538,7 @@ void emit_mips_jump_table(mips_emit_env_t *env, const ir_node *irn) { for(i2 = lastval + 1; i2 < value; ++i2) { be_emit_cstring(env->emit, "\t.word "); - be_emit_ident(env->emit, attr->symconst_id); + be_emit_ident(env->emit, get_entity_ld_ident(attr->symconst)); be_emit_char(env->emit, '\n'); be_emit_write_line(env->emit); } @@ -624,6 +639,7 @@ void mips_register_emitters(void) { register_emitter(op_Jmp, mips_emit_Jump); register_emitter(op_Cmp, mips_emit_this_shouldnt_happen); register_emitter(op_Cond, mips_emit_this_shouldnt_happen); + register_emitter(op_Phi, mips_emit_nothing); } /** diff --git a/ir/be/mips/mips_emitter.h b/ir/be/mips/mips_emitter.h index d9ff7af56..6b11d3b0b 100644 --- a/ir/be/mips/mips_emitter.h +++ b/ir/be/mips/mips_emitter.h @@ -47,10 +47,12 @@ void mips_emit_dest_register(mips_emit_env_t *env, const ir_node *node, int pos) void mips_emit_immediate(mips_emit_env_t *env, const ir_node *node); void mips_emit_jump_target(mips_emit_env_t *env, const ir_node *node); void mips_emit_jump_target_proj(mips_emit_env_t *env, const ir_node *node, - int pn); + long pn); +void mips_emit_jump_or_fallthrough(mips_emit_env_t *env, const ir_node *node, + long pn); void mips_register_emitters(void); -ir_node *mips_get_jump_block(const ir_node* node, int projn); +ir_node *mips_get_jump_block(const ir_node* node, long projn); /** returns the label used for a block */ const char* mips_get_block_label(const ir_node* block); diff --git a/ir/be/mips/mips_new_nodes.c b/ir/be/mips/mips_new_nodes.c index 2f8f1913d..cc095d33a 100644 --- a/ir/be/mips/mips_new_nodes.c +++ b/ir/be/mips/mips_new_nodes.c @@ -198,9 +198,6 @@ static int mips_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { } fprintf(F, " (%d)\n", attr->flags); - if(attr->modes.load_store_mode != NULL) { - fprintf(F, " load_store_mode %s\n", get_mode_name(attr->modes.load_store_mode)); - } if(attr->stack_entity != NULL) { fprintf(F, " stack entity %s\n", get_entity_name(attr->stack_entity)); } @@ -208,8 +205,8 @@ static int mips_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { tarval_snprintf(buf, sizeof(buf), attr->tv); fprintf(F, " tarval %s\n", buf); } - if(attr->symconst_id != NULL) { - fprintf(F, " symconst '%s'\n", get_id_str(attr->symconst_id)); + if(attr->symconst != NULL) { + fprintf(F, " symconst '%s'\n", get_entity_name(attr->symconst)); } fprintf(F, "=== mips attr end ===\n"); @@ -389,6 +386,25 @@ void init_mips_attributes(ir_node *node, arch_irn_flags_t flags, const arch_regi memset((void *)attr->slots, 0, n_res * sizeof(attr->slots[0])); } +static +int mips_compare_attr(mips_attr_t *a, mips_attr_t *b) +{ + if(a->tv != b->tv) + return 1; + if(a->symconst != b->symconst) + return 1; + if(a->stack_entity != b->stack_entity) + return 1; + if(a->flags != b->flags) + return 1; + if(a->n_res != b->n_res) + return 1; + if(a->switch_default_pn != b->switch_default_pn) + return 1; + + return 0; +} + /************************************************************************ * ___ _____ _ _ _ * |_ _| ___|__ | | __| (_)_ __ __ _ @@ -398,6 +414,7 @@ void init_mips_attributes(ir_node *node, arch_irn_flags_t flags, const arch_regi * |___/ ************************************************************************/ +#if 0 // test if a tarval can be expressed in a 16bit immediate value static int is_tarval_16(ir_node* node) { @@ -467,6 +484,7 @@ void mips_init_opcode_transforms(void) { op_mips_sr->ops.transform_node = mips_transform_sr; op_mips_slt->ops.transform_node = mips_transform_slt; } +#endif /*************************************************************************************** * _ _ _ diff --git a/ir/be/mips/mips_nodes_attr.h b/ir/be/mips/mips_nodes_attr.h index 289473af4..5d1a4793b 100644 --- a/ir/be/mips/mips_nodes_attr.h +++ b/ir/be/mips/mips_nodes_attr.h @@ -33,15 +33,11 @@ typedef struct _mips_attr_t { arch_irn_flags_t flags; /**< indicating if spillable, rematerializeable ... etc. */ int n_res; /**< number of results for this node */ - tarval *tv; /**< contains the immediate value (if the node has any) */ - ident *symconst_id; /**< contains the ident (for la operations) */ + tarval *tv; /**< contains the immediate value */ + ir_entity *symconst; - union { - ir_mode *load_store_mode; /**< contains the mode of a load/store */ - ir_mode *original_mode; /**< contains the original mode of the node */ - } modes; + ir_mode *original_mode; /**< contains the original mode of the node */ ir_entity *stack_entity; /**< contains the entity on the stack for a load/store mode */ - int stack_entity_offset; /**< contains the real stack offset for the entity */ int switch_default_pn; /**< proj number of default case in switch */ const arch_register_req_t **in_req; /**< register requirements for arguments */ diff --git a/ir/be/mips/mips_scheduler.c b/ir/be/mips/mips_scheduler.c index 635a959ba..bd8b468fa 100644 --- a/ir/be/mips/mips_scheduler.c +++ b/ir/be/mips/mips_scheduler.c @@ -201,6 +201,22 @@ static ir_node *mips_scheduler_select(void *block_env, nodeset *ready_set, nodes #endif +static +int mips_to_appear_in_schedule(void *block_env, const ir_node *node) +{ + ir_fprintf(stderr, "check %+F\n", node); + if(!is_mips_irn(node)) + return -1; + + if(is_mips_zero(node)) + return 0; + + ir_fprintf(stderr, "Sched: %+F\n", node); + return 1; +} + +list_sched_selector_t mips_selector; + /** * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded */ @@ -216,7 +232,10 @@ const list_sched_selector_t *mips_get_list_sched_selector(const void *self, list mips_sched_selector.finish_graph = mips_scheduler_finish_graph; //return &mips_sched_selector; #endif - return selector; + memcpy(&mips_selector, selector, sizeof(mips_selector)); + mips_selector.to_appear_in_schedule = mips_to_appear_in_schedule; + + return &mips_selector; } const ilp_sched_selector_t *mips_get_ilp_sched_selector(const void *self) { diff --git a/ir/be/mips/mips_spec.pl b/ir/be/mips/mips_spec.pl index 31b633331..a96caf64c 100644 --- a/ir/be/mips/mips_spec.pl +++ b/ir/be/mips/mips_spec.pl @@ -135,6 +135,7 @@ $new_emit_syntax = 1; C => "${arch}_emit_immediate(env, node);", JumpTarget => "${arch}_emit_jump_target(env, node);", JumpTarget1 => "${arch}_emit_jump_target_proj(env, node, 1);", + JumpOrFallthrough => "${arch}_emit_jump_or_fallthrough(env, node, 0);", ); @@ -149,6 +150,8 @@ $new_emit_syntax = 1; # |_| # #--------------------------------------------------# +$default_cmp_attr = "return mips_compare_attr(attr_a, attr_b);"; + %nodes = ( #-----------------------------------------------------------------# @@ -359,23 +362,6 @@ lui => { mode => "mode_Iu", }, -# load lower immediate -lli => { - op_flags => "c", - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. ori %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', - mode => "mode_Iu", -}, - -la => { - op_flags => "c", - reg_req => { out => [ "gp" ] }, - emit => '. la %D1, %C', - cmp_attr => 'return attr_a->symconst_id != attr_b->symconst_id;', - mode => "mode_Iu", -}, - mflo => { reg_req => { in => [ "none" ], out => [ "gp" ] }, emit => '. mflo %D1', @@ -389,6 +375,9 @@ mfhi => { }, zero => { + state => "pinned", + op_flags => "c", + irn_flags => "I", reg_req => { out => [ "zero" ] }, emit => '', mode => "mode_Iu" @@ -405,128 +394,80 @@ zero => { slt => { reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => ' - if (mode_is_signed(get_irn_mode(node))) { - . slt %D1, %S1, %S2 - } - else { - . sltu %D1, %S1, %S2 - } -', + emit => '. slt %D1, %S1, %S2', + mode => "mode_Iu", +}, + +sltu => { + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. sltu %D1, %S1, %S2', mode => "mode_Iu", }, slti => { reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => ' - if (mode_is_signed(get_irn_mode(node))) { - . slti %D1, %S1, %C - } - else { - . sltiu %D1, %S1, %C - } -', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + emit => '. slti %D1, %S1, %C', + mode => "mode_Iu", +}, + +sltiu => { + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. slti %D1, %S1, %C', mode => "mode_Iu", }, beq => { - op_flags => "X|Y", - # TxT -> TxX - reg_req => { in => [ "gp", "gp" ], out => [ "in_r0", "none" ] }, - emit => '. beq %S1, %S2, %JumpTarget1' + op_flags => "X|Y", + reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] }, + outs => [ "false", "true" ], + emit => '. beq %S1, %S2, %JumpTarget1 + . %JumpOrFallthrough' }, bne => { - op_flags => "X|Y", - # TxT -> TxX - reg_req => { in => [ "gp", "gp" ], out => [ "in_r0", "none" ] }, - emit => '. bne %S1, %S2, %JumpTarget1' + op_flags => "X|Y", + reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] }, + outs => [ "false", "true" ], + emit => '. bne %S1, %S2, %JumpTarget1 + . %JumpOrFallthrough' }, bgtz => { - op_flags => "X|Y", - # TxT -> TxX - reg_req => { in => [ "gp" ], out => [ "in_r0", "none" ] }, - emit => '. bgtz %S1, %JumpTarget1' + op_flags => "X|Y", + reg_req => { in => [ "gp" ], out => [ "none", "none" ] }, + outs => [ "false", "true" ], + emit => '. bgtz %S1, %JumpTarget1 + . %JumpOrFallthrough' }, blez => { - op_flags => "X|Y", - # TxT -> TxX - reg_req => { in => [ "gp" ], out => [ "in_r0", "none" ] }, - emit => '. blez %S1, %JumpTarget1' -}, - -j => { - op_flags => "X", - reg_req => { in => [ "gp" ] }, - emit => '. j %S1', + op_flags => "X|Y", + reg_req => { in => [ "gp" ], out => [ "none", "none" ] }, + outs => [ "false", "true" ], + emit => '. blez %S1, %JumpTarget1 + . %JumpOrFallthrough' }, b => { op_flags => "X", - # -> X - reg_req => { in => [ ], out => [ "none" ] }, - emit => '. b %JumpTarget' + reg_req => { in => [ ], out => [ "none" ] }, + emit => '. b %JumpTarget', + mode => 'mode_X' }, -fallthrough => { +jr => { op_flags => "X", - # -> X - reg_req => { in => [ ], out => [ "none" ] }, - emit => '. /* fallthrough to %JumpTarget */' + reg_req => { in => [ "gp" ], out => [ "none" ] }, + emit => '. jr %S1', + mode => 'mode_X' }, SwitchJump => { op_flags => "X", - # -> X,X,... - reg_req => { in => [ "gp" ], out => [ "none" ] }, - emit => '. j %S1' + reg_req => { in => [ "gp" ], out => [ "none" ] }, + emit => '. jr %S1' }, -# _ _ -# | | ___ __ _ __| | -# | | / _ \ / _` |/ _` | -# | |__| (_) | (_| | (_| | -# |_____\___/ \__,_|\__,_| -# - -load_r => { - reg_req => { in => [ "none", "gp" ], out => [ "none", "none", "gp" ] }, - emit => ' - mips_attr_t* attr = get_mips_attr(node); - ir_mode *mode; - - mode = attr->modes.load_store_mode; - - switch (get_mode_size_bits(mode)) { - case 8: - if (mode_is_signed(mode)) { - . lb %D3, %C(%S2) - } else { - . lbu %D3, %C(%S2) - } - break; - case 16: - if (mode_is_signed(mode)) { - . lh %D3, %C(%S2) - } else { - . lhu %D3, %C(%S2) - } - break; - case 32: - . lw %D3, %C(%S2) - break; - default: - assert(! "Only 8, 16 and 32 bit loads supported"); - break; - } -', - cmp_attr => 'return attr_a->tv != attr_b->tv || attr_a->stack_entity != attr_b->stack_entity;', -}, - - # _ _ ______ _ # | | ___ __ _ __| | / / ___|| |_ ___ _ __ ___ # | | / _ \ / _` |/ _` | / /\___ \| __/ _ \| '__/ _ \ @@ -534,73 +475,73 @@ load_r => { # |_____\___/ \__,_|\__,_/_/ |____/ \__\___/|_| \___| # -store_r => { - reg_req => { in => [ "none", "gp", "gp" ], out => [ "none", "none" ] }, - emit => ' - mips_attr_t* attr = get_mips_attr(node); - ir_mode* mode; - - mode = attr->modes.load_store_mode; - - switch (get_mode_size_bits(mode)) { - case 8: - if (mode_is_signed(mode)) - . sb %S3, %C(%S2) - break; - case 16: - if (mode_is_signed(mode)) - . sh %S3, %C(%S2) - break; - case 32: - . sw %S3, %C(%S2) - break; - default: - assert(! "Only 8, 16 and 32 bit stores supported"); - break; - } -', - cmp_attr => 'return attr_a->tv != attr_b->tv;', -}, - -store_i => { - reg_req => { in => [ "none", "none", "gp" ], out => [ "none", "none" ] }, - emit => ' - mips_attr_t* attr = get_mips_attr(node); - ir_mode *mode; - - mode = attr->modes.load_store_mode; - - switch (get_mode_size_bits(mode)) { - case 8: - . sb %S3, %C - break; - case 16: - . sh %S3, %C - break; - case 32: - . sw %S3, %C - break; - default: - assert(! "Only 8, 16 and 32 bit stores supported"); - break; - } -', - cmp_attr => 'return attr_a->stack_entity != attr_b->stack_entity;', +lw => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp" ], out => [ "gp", "none" ] }, + outs => [ "res", "M" ], + emit => '. lw %D1, %C(%S2)', }, -move => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. move %D1, %S1', - mode => "mode_Iu" +lh => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp" ], out => [ "gp", "none" ] }, + outs => [ "res", "M" ], + emit => '. lh %D1, %C(%S2)', }, -# -# Conversion -# +lhu => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp" ], out => [ "gp", "none" ] }, + outs => [ "res", "M" ], + emit => '. lhu %D1, %C(%S2)', +}, + +lb => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp" ], out => [ "gp", "none" ] }, + outs => [ "res", "M" ], + emit => '. lb %D1, %C(%S2)', +}, + +lbu => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp" ], out => [ "gp", "none" ] }, + outs => [ "res", "M" ], + emit => '. lbu %D1, %C(%S2)', +}, + +sw => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp", "gp" ], out => [ "none" ] }, + emit => '. sw %S3, %C(%S2)', + mode => 'mode_M', +}, -reinterpret_conv => { - reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, - emit => '. # reinterpret %S1 -> %D1', +sh => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp", "gp" ], out => [ "none" ] }, + emit => '. sh %S3, %C(%S2)', + mode => 'mode_M', +}, + +sb => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "none", "gp", "gp" ], out => [ "none" ] }, + emit => '. sb %S3, %C(%S2)', + mode => 'mode_M', +}, + +move => { + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. move %D1, %S1', mode => "mode_Iu" }, diff --git a/ir/be/mips/mips_transform.c b/ir/be/mips/mips_transform.c index 5714e57c9..58ec79850 100644 --- a/ir/be/mips/mips_transform.c +++ b/ir/be/mips/mips_transform.c @@ -39,6 +39,7 @@ #include "dbginfo.h" #include "iropt_t.h" #include "debug.h" +#include "error.h" #include "../benode_t.h" #include "../beabi.h" @@ -95,55 +96,48 @@ MIPS_GENBINFUNC(sra) MIPS_GENUNFUNC(not) -static ir_node* mips_get_reg_node(mips_transform_env_t *env, const arch_register_t *reg) { - return be_abi_get_callee_save_irn(env->cg->birg->abi, reg); -} - -static ir_node* gen_zero_node(mips_transform_env_t *env, dbg_info *ebg, ir_graph *irg, ir_node *block) +static +ir_node* gen_zero(mips_transform_env_t *env) { - ir_node *zero = be_abi_get_callee_save_irn(env->cg->birg->abi, &mips_gp_regs[REG_ZERO]); - // TODO make zero nodes work - //ir_node *unknown = new_rd_mips_zero(dbg, irg, block, mode); + ir_graph *irg = env->irg; + ir_node *block = get_irg_start_block(irg); + ir_node *zero = new_rd_mips_zero(NULL, irg, block); + + arch_set_irn_register(env->cg->arch_env, zero, &mips_gp_regs[REG_ZERO]); return zero; } -static ir_node* gen_node_for_Const(mips_transform_env_t *env, dbg_info *dbg, ir_graph *irg, ir_node *block, ir_node *constant) +static +ir_node* gen_node_for_Const(mips_transform_env_t *env, dbg_info *dbg, ir_graph *irg, ir_node *block, ir_node *constant) { tarval* tv = get_Const_tarval(constant); - ir_node *lui; - ir_node *lli; + ir_node *upper_node; + ir_node *lower_node; mips_attr_t *attr; ir_mode* mode = get_irn_mode(constant); unsigned long val, lower, upper; val = get_tarval_long(tv); - if(val == 0) - return gen_zero_node(env, dbg, irg, block); lower = val & 0xffff; upper = (val >> 16) & 0xffff; if(upper == 0) { - ir_node *zero = gen_zero_node(env, dbg, irg, block); - ir_node *lli = new_rd_mips_lli(dbg, irg, block, zero); - attr = get_mips_attr(lli); - attr->tv = new_tarval_from_long(val, mode); - - return lli; + upper_node = gen_zero(env); + } else { + upper_node = new_rd_mips_lui(dbg, irg, block); + attr = get_mips_attr(upper_node); + attr->tv = new_tarval_from_long(val, mode); } - lui = new_rd_mips_lui(dbg, irg, block); - attr = get_mips_attr(lui); - attr->tv = new_tarval_from_long(val, mode); - if(lower == 0) - return lui; + return upper_node; - lli = new_rd_mips_lli(dbg, irg, block, lui); - attr = get_mips_attr(lli); - attr->tv = new_tarval_from_long(val, mode); + lower_node = new_rd_mips_ori(dbg, irg, block, upper_node); + attr = get_mips_attr(lower_node); + attr->tv = new_tarval_from_long(lower, mode); - return lli; + return lower_node; } static ir_node* exchange_node_for_Const(mips_transform_env_t *env, ir_node* pred, int n) { @@ -163,95 +157,113 @@ static ir_node* exchange_node_for_Const(mips_transform_env_t *env, ir_node* pred } static ir_node* gen_node_for_SymConst(mips_transform_env_t *env, ir_node* pred, int n) { - ir_node *result; - symconst_kind kind; mips_attr_t *attr; ir_node *node = env->irn; dbg_info *dbg = get_irn_dbg_info(pred); ir_graph *irg = get_irn_irg(node); ir_node *block; + ir_entity *entity; + ir_node *lui, *ori; - if (is_Phi(node)) { - ir_node *phipred = get_nodes_block(node); - block = get_Block_cfgpred_block(phipred, n); - } else { - block = get_nodes_block(node); - } + block = get_nodes_block(pred); - kind = get_SymConst_kind(pred); - if(kind == symconst_addr_ent) { - result = new_rd_mips_la(dbg, irg, block); - attr = get_mips_attr(result); - attr->symconst_id = get_entity_ld_ident(get_SymConst_entity(pred)); - return result; - } else if(kind == symconst_addr_name) { - result = new_rd_mips_la(dbg, irg, block); - attr = get_mips_attr(result); - attr->symconst_id = get_SymConst_name(pred); - return result; + if(get_SymConst_kind(pred) != symconst_addr_ent) { + panic("Only address entity symconsts supported in mips backend"); } - // TODO - assert(0); - return NULL; + entity = get_SymConst_entity(pred); + + lui = new_rd_mips_lui(dbg, irg, block); + attr = get_mips_attr(lui); + attr->symconst = entity; + + ori = new_rd_mips_ori(dbg, irg, block, lui); + attr = get_mips_attr(ori); + attr->symconst = entity; + + return ori; } +typedef ir_node* (*gen_load_func) (dbg_info *dbg, ir_graph *irg, + ir_node *block, ir_node *mem, ir_node *ptr); + /** * Generates a mips node for a firm Load node */ static ir_node *gen_node_for_Load(mips_transform_env_t *env) { - ir_node *node = env->irn; - ir_node *result = NULL; - ir_mode *mode; - ir_node *load_ptr; - mips_attr_t *attr; + ir_graph *irg = env->irg; + ir_node *node = env->irn; + dbg_info *dbg = get_irn_dbg_info(node); + ir_node *block = get_nodes_block(node); + ir_node *mem = get_Load_mem(node); + ir_node *ptr = get_Load_ptr(node); + ir_mode *mode = get_Load_mode(node); + int sign = get_mode_sign(mode); + ir_node *result; + gen_load_func func; ASSERT_NO_FLOAT(get_irn_mode(node)); - mode = get_Load_mode(node); assert(mode->vector_elem == 1); assert(mode->sort == irms_int_number || mode->sort == irms_reference); - load_ptr = get_Load_ptr(node); - assert(get_mode_sort(mode) == irms_reference || get_mode_sort(mode) == irms_int_number); - result = new_rd_mips_load_r(env->dbg, env->irg, env->block, - get_Load_mem(node), load_ptr, get_irn_mode(node)); - - attr = get_mips_attr(result); - attr->tv = new_tarval_from_long(0, mode_Iu); - attr->modes.load_store_mode = mode; + switch(get_mode_size_bits(mode)) { + case 32: + func = new_rd_mips_lw; + break; + case 16: + func = sign ? new_rd_mips_lh : new_rd_mips_lhu; + break; + case 8: + func = sign ? new_rd_mips_lb : new_rd_mips_lbu; + break; + default: + panic("mips backend only support 32, 16, 8 bit loads"); + } + result = func(dbg, irg, block, mem, ptr); return result; } +typedef ir_node* (*gen_store_func) (dbg_info *dbg, ir_graph *irg, + ir_node *block, ir_node *mem, ir_node *ptr, + ir_node *val); + /** * Generates a mips node for a firm Store node */ static ir_node *gen_node_for_Store(mips_transform_env_t *env) { - ir_node *node = env->irn; - ir_node *result = NULL; - ir_mode *mode; - mips_attr_t *attr; - ir_node *store_ptr; - - ASSERT_NO_FLOAT(env->mode); + ir_graph *irg = env->irg; + ir_node *node = env->irn; + dbg_info *dbg = get_irn_dbg_info(node); + ir_node *block = get_nodes_block(node); + ir_node *mem = get_Store_mem(node); + ir_node *ptr = get_Store_ptr(node); + ir_node *val = get_Store_value(node); + ir_mode *mode = get_irn_mode(val); + gen_store_func func; + ir_node *result; + + ASSERT_NO_FLOAT(mode); - store_ptr = get_Store_ptr(node); - mode = get_irn_mode(store_ptr); assert(mode->vector_elem == 1); assert(mode->sort == irms_int_number || mode->sort == irms_reference); - if(get_irn_opcode(store_ptr) == iro_SymConst) { - result = new_rd_mips_store_i(env->dbg, env->irg, env->block, get_Store_mem(node), - get_Store_ptr(node), get_Store_value(node), env->mode); - } else { - result = new_rd_mips_store_r(env->dbg, env->irg, env->block, get_Store_mem(node), - get_Store_ptr(node), get_Store_value(node), env->mode); + switch(get_mode_size_bits(mode)) { + case 32: + func = new_rd_mips_sw; + break; + case 16: + func = new_rd_mips_sh; + break; + case 8: + func = new_rd_mips_sb; + break; + default: + panic("store only supported for 32, 16, 8 bit values in mips backend"); } - attr = get_mips_attr(result); - attr->tv = new_tarval_from_long(0, mode_Iu); - attr->modes.load_store_mode = mode; + result = func(dbg, irg, block, mem, ptr, val); return result; } @@ -266,8 +278,8 @@ static ir_node *gen_node_for_div_Proj(mips_transform_env_t *env) { // set the div mode to the DivMod node attr = get_mips_attr(pred); - assert(attr->modes.original_mode == NULL || attr->modes.original_mode == env->mode); - attr->modes.original_mode = env->mode; + assert(attr->original_mode == NULL || attr->original_mode == env->mode); + attr->original_mode = env->mode; // we have to construct a new proj here, to avoid circular refs that // happen when we reuse the old one @@ -283,114 +295,11 @@ static ir_node *gen_node_for_div_Proj(mips_transform_env_t *env) { return proj; } -static ir_node *make_jmp_or_fallthrough(mips_transform_env_t *env) -{ - const ir_edge_t *edge; - ir_node *node = env->irn; - ir_node *next_block; - int our_block_sched_nr = mips_get_block_sched_nr(get_nodes_block(node)); - - edge = get_irn_out_edge_first(node); - next_block = get_edge_src_irn(edge); - - if(mips_get_sched_block(env->cg, our_block_sched_nr + 1) == next_block) { - return new_rd_mips_fallthrough(env->dbg, env->irg, env->block, mode_X); - } - - return new_rd_mips_b(env->dbg, env->irg, env->block, mode_X); -} - -static ir_node *gen_node_for_Cond_Proj(mips_transform_env_t *env, ir_node* node, int true_false) -{ - // we can't use get_Cond_selector here because the selector is already - // replaced by a mips_ compare node - ir_node *proj = get_Cond_selector(node); - ir_node *original_cmp = get_irn_n(proj, 0); - ir_node *cmp; - ir_node *condjmp; - ir_node *op1, *op2; - dbg_info *dbg = env->dbg; - ir_graph *irg = env->irg; - ir_node *block = env->block; - long n; - - n = get_Proj_proj(proj); - assert(n < 8 && "Only ordered comps supported"); - - assert(get_irn_opcode(original_cmp) == iro_Cmp); - op1 = get_Cmp_left(original_cmp); - op2 = get_Cmp_right(original_cmp); - - switch(n) { - case pn_Cmp_False: - if(true_false) - return NULL; - - return make_jmp_or_fallthrough(env); - - case pn_Cmp_Eq: - if(!true_false) - return make_jmp_or_fallthrough(env); - - condjmp = new_rd_mips_beq(dbg, irg, block, op1, op2, mode_T); - return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); - - case pn_Cmp_Lt: - if(!true_false) - return make_jmp_or_fallthrough(env); - - cmp = new_rd_mips_slt(dbg, irg, block, op1, op2); - condjmp = new_rd_mips_bgtz(dbg, irg, block, cmp, mode_T); - return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); - - case pn_Cmp_Le: - if(!true_false) - return make_jmp_or_fallthrough(env); - - cmp = new_rd_mips_slt(dbg, irg, block, op2, op1); - condjmp = new_rd_mips_blez(dbg, irg, block, cmp, mode_T); - return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); - - case pn_Cmp_Gt: - if(!true_false) - return make_jmp_or_fallthrough(env); - - cmp = new_rd_mips_slt(dbg, irg, block, op2, op1); - condjmp = new_rd_mips_bgtz(dbg, irg, block, cmp, mode_T); - return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); - - case pn_Cmp_Ge: - if(!true_false) - return make_jmp_or_fallthrough(env); - - cmp = new_rd_mips_slt(dbg, irg, block, op1, op2); - condjmp = new_rd_mips_blez(dbg, irg, block, cmp, mode_T); - return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); - - case pn_Cmp_Lg: - if(!true_false) - return make_jmp_or_fallthrough(env); - - condjmp = new_rd_mips_bne(dbg, irg, block, op1, op2, mode_T); - return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); - - case pn_Cmp_Leg: - if(!true_false) - return NULL; - - return make_jmp_or_fallthrough(env); - - default: - assert(0); - } - - return NULL; -} - -static ir_node *gen_node_for_Proj(mips_transform_env_t *env) +static +ir_node *gen_node_for_Proj(mips_transform_env_t *env) { ir_node *proj = env->irn; - long n; + ir_mode *mode = get_irn_mode(proj); ir_node *predecessor = get_Proj_pred(proj); // all DivMods, Div, Mod should be replaced by now @@ -401,6 +310,19 @@ static ir_node *gen_node_for_Proj(mips_transform_env_t *env) if(is_mips_div(predecessor)) return gen_node_for_div_Proj(env); + if(is_mips_lw(predecessor) || is_mips_lh(predecessor) + || is_mips_lhu(predecessor) || is_mips_lb(predecessor) + || is_mips_lbu(predecessor)) { + + long pn = get_Proj_proj(proj); + if(pn == pn_Load_M) { + set_Proj_proj(proj, pn_mips_lw_M); + } else if(pn == pn_Load_res) { + set_Proj_proj(proj, pn_mips_lw_res); + } + } + +#if 0 if(get_irn_opcode(predecessor) == iro_Cond) { ir_node *selector = get_Cond_selector(predecessor); ir_mode *mode = get_irn_mode(selector); @@ -411,11 +333,31 @@ static ir_node *gen_node_for_Proj(mips_transform_env_t *env) return gen_node_for_Cond_Proj(env, predecessor, n == pn_Cond_true); } } +#endif + + if(get_mode_sort(mode) == irms_int_number) { + set_irn_mode(proj, mode_Iu); + } return proj; } -static ir_node *gen_node_for_Cond(mips_transform_env_t *env) +static +ir_node *gen_node_for_Phi(mips_transform_env_t *env) +{ + ir_node *node = env->irn; + ir_mode *mode = get_irn_mode(node); + + if(get_mode_sort(mode) == irms_int_number) { + set_irn_mode(node, mode_Iu); + } + + return node; +} + +#if 0 +static +ir_node *gen_node_for_SwitchCond(mips_transform_env_t *env) { ir_node *selector = get_Cond_selector(env->irn); ir_mode *selector_mode = get_irn_mode(selector); @@ -514,46 +456,68 @@ static ir_node *gen_node_for_Cond(mips_transform_env_t *env) return switchjmp; } +#endif -static ir_node *create_conv_store_load(mips_transform_env_t *env, ir_mode* srcmode, ir_mode* dstmode) { - ir_node *nomem, *store, *mem_proj, *value_proj, *load; - ir_entity *mem_entity; - ir_node *node = env->irn; - ir_node *pred = get_Conv_op(node); - ir_node *sp; - // TODO HACK make this global... - ident* id; - ir_type *i32type; - ir_type *ptr_i32type; - mips_attr_t* attr; - - id = new_id_from_str("__conv0"); - i32type = new_type_primitive(new_id_from_str("ptr32"), mode_Iu); - ptr_i32type = new_d_type_pointer(id, i32type, mode_P, env->dbg); - mem_entity = new_d_entity(get_irg_frame_type(env->irg), id, ptr_i32type, env->dbg); - - sp = mips_get_reg_node(env, &mips_gp_regs[REG_SP]); - nomem = new_ir_node(env->dbg, env->irg, env->block, op_NoMem, mode_M, 0, NULL); - - store = new_rd_mips_store_r(env->dbg, env->irg, env->block, nomem, sp, pred, mode_T); - attr = get_mips_attr(store); - attr->tv = new_tarval_from_long(0, mode_Iu); - attr->modes.load_store_mode = srcmode; - attr->stack_entity = mem_entity; +static +ir_node *gen_node_for_Cond(mips_transform_env_t *env) +{ + ir_graph *irg = env->irg; + ir_node *node = env->irn; + dbg_info *dbg = get_irn_dbg_info(node); + ir_node *block = get_nodes_block(node); + ir_node *sel_proj = get_Cond_selector(node); + ir_node *cmp = get_Proj_pred(sel_proj); + ir_node *op1, *op2; + ir_node *res; + ir_node *slt; + ir_node *zero; + long pn = get_Proj_proj(sel_proj); + + op1 = get_Cmp_left(cmp); + op2 = get_Cmp_right(cmp); + switch(pn) { + case pn_Cmp_False: + case pn_Cmp_True: + case pn_Cmp_Leg: + panic("mips backend can't handle unoptimized constant Cond"); - mem_proj = new_ir_node(env->dbg, env->irg, env->block, op_Proj, mode_M, 1, &store); - set_Proj_proj(mem_proj, pn_Store_M); + case pn_Cmp_Eq: + res = new_rd_mips_beq(dbg, irg, block, op1, op2); + break; - load = new_rd_mips_load_r(env->dbg, env->irg, env->block, mem_proj, sp, mode_T); - attr = get_mips_attr(load); - attr->tv = new_tarval_from_long(0, mode_Iu); - attr->modes.load_store_mode = dstmode; - attr->stack_entity = mem_entity; + case pn_Cmp_Lt: + zero = gen_zero(env); + slt = new_rd_mips_slt(dbg, irg, block, op1, op2); + res = new_rd_mips_bne(dbg, irg, block, slt, zero); + break; - value_proj = new_ir_node(env->dbg, env->irg, env->block, op_Proj, env->mode, 1, &load); - set_Proj_proj(value_proj, pn_Load_res); + case pn_Cmp_Le: + zero = gen_zero(env); + slt = new_rd_mips_slt(dbg, irg, block, op2, op1); + res = new_rd_mips_beq(dbg, irg, block, slt, zero); + break; - return value_proj; + case pn_Cmp_Gt: + zero = gen_zero(env); + slt = new_rd_mips_slt(dbg, irg, block, op2, op1); + res = new_rd_mips_bne(dbg, irg, block, slt, zero); + break; + + case pn_Cmp_Ge: + zero = gen_zero(env); + slt = new_rd_mips_slt(dbg, irg, block, op2, op1); + res = new_rd_mips_bne(dbg, irg, block, slt, zero); + break; + + case pn_Cmp_Lg: + res = new_rd_mips_bne(dbg, irg, block, op1, op2); + break; + + default: + panic("mips backend doesn't handle unordered compares yet"); + } + + return res; } static ir_node *create_conv_and(mips_transform_env_t *env, long immediate) { @@ -584,16 +548,19 @@ static ir_node *gen_node_for_Conv(mips_transform_env_t *env) { dst_size = get_mode_size_bits(destmode); src_size = get_mode_size_bits(srcmode); + if(src_size == dst_size) { + /* unnecessary conv */ + return pred; + } + +#if 0 if(srcmode->size >= destmode->size) { assert(srcmode->size > destmode->size || srcmode->sign != destmode->sign); return new_rd_mips_reinterpret_conv(env->dbg, env->irg, env->block, pred); } +#endif if(srcmode->sign) { - if(srcmode->size == 8) { - return create_conv_store_load(env, mode_Bs, mode_Bs); - } else if(srcmode->size == 16) { - return create_conv_store_load(env, mode_Hs, mode_Hs); - } + /* TODO */ } else { if(src_size == 8) { return create_conv_and(env, 0xff); @@ -686,17 +653,29 @@ static ir_node *gen_node_for_Mul(mips_transform_env_t *env) { return mflo; } -static ir_node *gen_node_for_IJmp(mips_transform_env_t *env) { - ir_node *node = env->irn; +static +ir_node *gen_node_for_IJmp(mips_transform_env_t *env) { + ir_graph *irg = env->irg; + ir_node *node = env->irn; + dbg_info *dbg = get_irn_dbg_info(node); + ir_node *block = get_nodes_block(node); + ir_node *target = get_IJmp_target(node); - return new_rd_mips_j(env->dbg, env->irg, env->block, get_IJmp_target(node), node->mode); + return new_rd_mips_jr(dbg, irg, block, target); } -static ir_node *gen_node_for_Jmp(mips_transform_env_t *env) { - return make_jmp_or_fallthrough(env); +static +ir_node *gen_node_for_Jmp(mips_transform_env_t *env) { + ir_graph *irg = env->irg; + ir_node *node = env->irn; + dbg_info *dbg = get_irn_dbg_info(node); + ir_node *block = get_nodes_block(node); + + return new_rd_mips_b(dbg, irg, block); } -static ir_node *gen_node_for_Abs(mips_transform_env_t *env) { +static +ir_node *gen_node_for_Abs(mips_transform_env_t *env) { ir_node *node = env->irn; ir_node *sra, *add, *xor; mips_attr_t *attr; @@ -712,7 +691,8 @@ static ir_node *gen_node_for_Abs(mips_transform_env_t *env) { return xor; } -static ir_node *gen_node_for_Rot(mips_transform_env_t *env) { +static +ir_node *gen_node_for_Rot(mips_transform_env_t *env) { ir_node *node = env->irn; ir_node *subu, *srlv, *sllv, *or; @@ -726,9 +706,10 @@ static ir_node *gen_node_for_Rot(mips_transform_env_t *env) { static ir_node *gen_node_for_Unknown(mips_transform_env_t *env) { - return gen_zero_node(env, env->dbg, env->irg, env->block); + return gen_zero(env); } +#if 0 /* * lower a copyB into standard Firm assembler :-) */ @@ -881,11 +862,12 @@ static void mips_fix_CopyB_Proj(mips_transform_env_t* env) { set_Proj_proj(node, pn_Store_X_except); } } +#endif static void mips_transform_Spill(mips_transform_env_t* env) { ir_node *node = env->irn; ir_node *sched_point = NULL; - ir_node *store, *proj; + ir_node *store; ir_node *nomem = new_rd_NoMem(env->irg); ir_node *ptr = get_irn_n(node, 0); ir_node *val = get_irn_n(node, 1); @@ -896,21 +878,16 @@ static void mips_transform_Spill(mips_transform_env_t* env) { sched_point = sched_prev(node); } - store = new_rd_mips_store_r(env->dbg, env->irg, env->block, nomem, ptr, val, mode_T); + store = new_rd_mips_sw(env->dbg, env->irg, env->block, nomem, ptr, val); attr = get_mips_attr(store); attr->stack_entity = ent; - attr->modes.load_store_mode = get_irn_mode(val); - - proj = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M); if (sched_point) { sched_add_after(sched_point, store); - sched_add_after(store, proj); - sched_remove(node); } - exchange(node, proj); + exchange(node, store); } static void mips_transform_Reload(mips_transform_env_t* env) { @@ -919,7 +896,6 @@ static void mips_transform_Reload(mips_transform_env_t* env) { ir_node *load, *proj; ir_node *ptr = get_irn_n(node, 0); ir_node *mem = get_irn_n(node, 1); - ir_mode *mode = get_irn_mode(node); ir_entity *ent = be_get_frame_entity(node); const arch_register_t* reg; mips_attr_t *attr; @@ -928,12 +904,11 @@ static void mips_transform_Reload(mips_transform_env_t* env) { sched_point = sched_prev(node); } - load = new_rd_mips_load_r(env->dbg, env->irg, env->block, mem, ptr, mode_T); + load = new_rd_mips_lw(env->dbg, env->irg, env->block, mem, ptr); attr = get_mips_attr(load); attr->stack_entity = ent; - attr->modes.load_store_mode = mode; - proj = new_rd_Proj(env->dbg, env->irg, env->block, load, mode, pn_Load_res); + proj = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Iu, pn_mips_lw_res); if (sched_point) { sched_add_after(sched_point, load); @@ -949,6 +924,7 @@ static void mips_transform_Reload(mips_transform_env_t* env) { exchange(node, proj); } +#if 0 static ir_node *gen_node_for_StackParam(mips_transform_env_t *env) { ir_node *node = env->irn; @@ -967,6 +943,7 @@ static ir_node *gen_node_for_StackParam(mips_transform_env_t *env) return proj; } +#endif static ir_node *gen_node_for_AddSP(mips_transform_env_t *env) { @@ -1018,7 +995,6 @@ void mips_transform_node(ir_node *node, void *env) { tenv.dbg = get_irn_dbg_info(node); tenv.irg = current_ir_graph; tenv.irn = node; - DEBUG_ONLY(tenv.mod = cgenv->mod;) tenv.mode = get_irn_mode(node); tenv.cg = cgenv; @@ -1027,8 +1003,6 @@ void mips_transform_node(ir_node *node, void *env) { #define IGN(a) case iro_##a: break #define BAD(a) case iro_##a: goto bad - DBG((tenv.mod, LEVEL_1, "check %+F ... ", node)); - switch (code) { BINOP(Add, addu); BINOP(Sub, sub); @@ -1096,6 +1070,10 @@ void mips_transform_node(ir_node *node, void *env) { asm_node = gen_node_for_Cond(&tenv); break; + case iro_Phi: + asm_node = gen_node_for_Phi(&tenv); + break; + /* TODO: implement these nodes */ BAD(Mux); @@ -1111,7 +1089,6 @@ void mips_transform_node(ir_node *node, void *env) { IGN(Start); IGN(End); IGN(NoMem); - IGN(Phi); IGN(Break); IGN(Sync); @@ -1134,7 +1111,7 @@ void mips_transform_node(ir_node *node, void *env) { default: if(be_is_StackParam(node)) { - asm_node = gen_node_for_StackParam(&tenv); + //asm_node = gen_node_for_StackParam(&tenv); } else if(be_is_AddSP(node)) { asm_node = gen_node_for_AddSP(&tenv); } @@ -1147,9 +1124,6 @@ bad: if (asm_node != node) { exchange(node, asm_node); - DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node)); - } else { - DB((tenv.mod, LEVEL_1, "ignored\n")); } } @@ -1166,16 +1140,16 @@ void mips_pre_transform_node(ir_node *node, void *env) { tenv.dbg = get_irn_dbg_info(node); tenv.irg = current_ir_graph; tenv.irn = node; - DEBUG_ONLY(tenv.mod = cgenv->mod;) tenv.mode = get_irn_mode(node); tenv.cg = cgenv; if(is_Proj(node)) { +#if 0 ir_node* pred = get_Proj_pred(node); - if(get_irn_opcode(pred) == iro_CopyB) { mips_fix_CopyB_Proj(&tenv); } +#endif } for(i = 0; i < get_irn_arity(node); ++i) { @@ -1205,11 +1179,9 @@ void mips_after_ra_walker(ir_node *node, void *env) { tenv.dbg = get_irn_dbg_info(node); tenv.irg = current_ir_graph; tenv.irn = node; - DEBUG_ONLY(tenv.mod = cg->mod;) tenv.mode = get_irn_mode(node); tenv.cg = cg; - /* be_is_StackParam(node) || */ if (be_is_Reload(node)) { mips_transform_Reload(&tenv); } else if (be_is_Spill(node)) { -- 2.20.1