X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fsparc%2Fsparc_transform.c;h=74d08767a404c6b0b8984f4986f08a89d4433fda;hb=f8cc15664f571aa7ef89d6f6bc8d5bd2b8ca7d53;hp=78a1cbb6e364902fea5c7c9293b4963c95125506;hpb=b3c0ae4f67bcfea7110ebd20d1466f1020e9564e;p=libfirm diff --git a/ir/be/sparc/sparc_transform.c b/ir/be/sparc/sparc_transform.c index 78a1cbb6e..74d08767a 100644 --- a/ir/be/sparc/sparc_transform.c +++ b/ir/be/sparc/sparc_transform.c @@ -21,7 +21,6 @@ * @file * @brief code selection (transform FIRM into SPARC FIRM) * @author Hannes Rapp, Matthias Braun - * @version $Id$ */ #include "config.h" @@ -42,11 +41,11 @@ #include "error.h" #include "util.h" -#include "../benode.h" -#include "../beirg.h" -#include "../beutil.h" -#include "../betranshlp.h" -#include "../beabihelper.h" +#include "benode.h" +#include "beirg.h" +#include "beutil.h" +#include "betranshlp.h" +#include "beabihelper.h" #include "bearch_sparc_t.h" #include "sparc_nodes_attr.h" @@ -998,6 +997,24 @@ static ir_node *gen_helper_bitop(ir_node *node, flags, new_not_reg, new_not_imm); } + if (is_Const(op2) && get_irn_n_edges(op2) == 1) { + ir_tarval *tv = get_Const_tarval(op2); + long value = get_tarval_long(tv); + if (!sparc_is_value_imm_encodeable(value)) { + long notvalue = ~value; + if ((notvalue & 0x3ff) == 0) { + ir_node *block = get_nodes_block(node); + ir_node *new_block = be_transform_node(block); + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *new_op2 + = new_bd_sparc_SetHi(NULL, new_block, NULL, notvalue); + ir_node *new_op1 = be_transform_node(op1); + ir_node *result + = new_not_reg(dbgi, new_block, new_op1, new_op2); + return result; + } + } + } return gen_helper_binop_args(node, op1, op2, flags | MATCH_COMMUTATIVE, new_reg, new_imm); @@ -1153,18 +1170,23 @@ static ir_node *gen_Const(ir_node *node) } } -static ir_node *gen_SwitchJmp(ir_node *node) +static ir_node *gen_Switch(ir_node *node) { - dbg_info *dbgi = get_irn_dbg_info(node); - ir_node *block = be_transform_node(get_nodes_block(node)); - ir_node *selector = get_Cond_selector(node); - ir_node *new_selector = be_transform_node(selector); - long default_pn = get_Cond_default_proj(node); - ir_entity *entity; - ir_node *table_address; - ir_node *idx; - ir_node *load; - ir_node *address; + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *block = get_nodes_block(node); + ir_node *new_block = be_transform_node(block); + ir_graph *irg = get_irn_irg(block); + ir_node *selector = get_Switch_selector(node); + ir_node *new_selector = be_transform_node(selector); + const ir_switch_table *table = get_Switch_table(node); + unsigned n_outs = get_Switch_n_outs(node); + ir_entity *entity; + ir_node *table_address; + ir_node *idx; + ir_node *load; + ir_node *address; + + table = ir_switch_table_duplicate(irg, table); /* switch with smaller mode not implemented yet */ assert(get_mode_size_bits(get_irn_mode(selector)) == 32); @@ -1174,22 +1196,21 @@ static ir_node *gen_SwitchJmp(ir_node *node) add_entity_linkage(entity, IR_LINKAGE_CONSTANT); /* construct base address */ - table_address = make_address(dbgi, block, entity, 0); + table_address = make_address(dbgi, new_block, entity, 0); /* scale index */ - idx = new_bd_sparc_Sll_imm(dbgi, block, new_selector, NULL, 2); + idx = new_bd_sparc_Sll_imm(dbgi, new_block, new_selector, NULL, 2); /* load from jumptable */ - load = new_bd_sparc_Ld_reg(dbgi, block, table_address, idx, + load = new_bd_sparc_Ld_reg(dbgi, new_block, table_address, idx, get_irg_no_mem(current_ir_graph), mode_gp); address = new_r_Proj(load, mode_gp, pn_sparc_Ld_res); - return new_bd_sparc_SwitchJmp(dbgi, block, address, default_pn, entity); + return new_bd_sparc_SwitchJmp(dbgi, new_block, address, n_outs, table, entity); } static ir_node *gen_Cond(ir_node *node) { ir_node *selector = get_Cond_selector(node); - ir_mode *mode = get_irn_mode(selector); ir_node *cmp_left; ir_mode *cmp_mode; ir_node *block; @@ -1197,11 +1218,6 @@ static ir_node *gen_Cond(ir_node *node) ir_relation relation; dbg_info *dbgi; - /* switch/case jumps */ - if (mode != mode_b) { - return gen_SwitchJmp(node); - } - /* note: after lower_mode_b we are guaranteed to have a Cmp input */ block = be_transform_node(get_nodes_block(node)); dbgi = get_irn_dbg_info(node); @@ -1269,6 +1285,18 @@ static ir_node *gen_Cmp(ir_node *node) new_bd_sparc_XNorCCZero_reg, new_bd_sparc_XNorCCZero_imm, MATCH_NONE); + } else if (is_Add(op1)) { + return gen_helper_binop(op1, MATCH_COMMUTATIVE, + new_bd_sparc_AddCCZero_reg, + new_bd_sparc_AddCCZero_imm); + } else if (is_Sub(op1)) { + return gen_helper_binop(op1, MATCH_NONE, + new_bd_sparc_SubCCZero_reg, + new_bd_sparc_SubCCZero_imm); + } else if (is_Mul(op1)) { + return gen_helper_binop(op1, MATCH_COMMUTATIVE, + new_bd_sparc_MulCCZero_reg, + new_bd_sparc_MulCCZero_imm); } } @@ -2396,6 +2424,7 @@ static ir_node *gen_Proj(ir_node *node) return gen_Proj_Call(node); case iro_Cmp: return gen_Proj_Cmp(node); + case iro_Switch: case iro_Cond: return be_duplicate_node(node); case iro_Div: @@ -2468,6 +2497,7 @@ static void sparc_register_transformers(void) be_set_transform_function(op_Start, gen_Start); be_set_transform_function(op_Store, gen_Store); be_set_transform_function(op_Sub, gen_Sub); + be_set_transform_function(op_Switch, gen_Switch); be_set_transform_function(op_SymConst, gen_SymConst); be_set_transform_function(op_Unknown, gen_Unknown); @@ -2490,11 +2520,12 @@ void sparc_transform_graph(ir_graph *irg) node_to_stack = pmap_create(); - mode_gp = mode_Iu; - mode_fp = mode_F; + mode_gp = sparc_reg_classes[CLASS_sparc_gp].mode; + mode_fp = sparc_reg_classes[CLASS_sparc_fp].mode; mode_fp2 = mode_D; - mode_flags = mode_Bu; //mode_fp4 = ? + mode_flags = sparc_reg_classes[CLASS_sparc_flags_class].mode; + assert(sparc_reg_classes[CLASS_sparc_fpflags_class].mode == mode_flags); start_mem = NULL; start_g0 = NULL;