From: Matthias Braun Date: Thu, 22 Jul 2010 19:07:47 +0000 (+0000) Subject: sparc: fix unsigned compares and cleanup cmp attributes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;ds=inline;h=b4e27346b89bc9998aa4c110e185599c7b593e01;p=libfirm sparc: fix unsigned compares and cleanup cmp attributes [r27786] --- diff --git a/ir/be/sparc/sparc_emitter.c b/ir/be/sparc/sparc_emitter.c index 42f948ca1..d7e9579eb 100644 --- a/ir/be/sparc/sparc_emitter.c +++ b/ir/be/sparc/sparc_emitter.c @@ -591,22 +591,19 @@ static void emit_sparc_FrameAddr(const ir_node *irn) /** * Emits code for Branch */ -static void emit_sparc_BXX(const ir_node *irn) +static void emit_sparc_BXX(const ir_node *node) { + const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node); + int proj_num = attr->proj_num; + bool is_unsigned = attr->is_unsigned; + const ir_node *proj_true = NULL; + const ir_node *proj_false = NULL; const ir_edge_t *edge; - const ir_node *proj_true = NULL; - const ir_node *proj_false = NULL; - const ir_node *block; - const ir_node *next_block; - ir_node *op1 = get_irn_n(irn, 0); - const char *suffix; - int proj_num = get_sparc_jmp_cond_proj_num(irn); - const sparc_cmp_attr_t *cmp_attr = get_irn_generic_attr_const(op1); - // bool is_signed = !cmp_attr->is_unsigned; - - assert(is_sparc_Cmp(op1) || is_sparc_Tst(op1)); - - foreach_out_edge(irn, edge) { + const ir_node *block; + const ir_node *next_block; + const char *suffix; + + foreach_out_edge(node, edge) { ir_node *proj = get_edge_src_irn(edge); long nr = get_Proj_proj(proj); if (nr == pn_Cond_true) { @@ -616,12 +613,8 @@ static void emit_sparc_BXX(const ir_node *irn) } } - if (cmp_attr->ins_permuted) { - proj_num = get_mirrored_pnc(proj_num); - } - /* for now, the code works for scheduled and non-schedules blocks */ - block = get_nodes_block(irn); + block = get_nodes_block(node); /* we have a block schedule */ next_block = get_irn_link(block); @@ -638,20 +631,32 @@ static void emit_sparc_BXX(const ir_node *irn) proj_num = get_negated_pnc(proj_num, mode_Iu); } - - switch (proj_num) { - case pn_Cmp_Eq: suffix = "e"; break; - case pn_Cmp_Lt: suffix = "l"; break; - case pn_Cmp_Le: suffix = "le"; break; - case pn_Cmp_Gt: suffix = "g"; break; - case pn_Cmp_Ge: suffix = "ge"; break; - case pn_Cmp_Lg: suffix = "ne"; break; - case pn_Cmp_Leg: suffix = "a"; break; - default: panic("Cmp has unsupported pnc"); + if (is_unsigned) { + switch (proj_num) { + case pn_Cmp_Eq: suffix = "e"; break; + case pn_Cmp_Lt: suffix = "lu"; break; + case pn_Cmp_Le: suffix = "leu"; break; + case pn_Cmp_Gt: suffix = "gu"; break; + case pn_Cmp_Ge: suffix = "geu"; break; + case pn_Cmp_Lg: suffix = "ne"; break; + default: panic("Cmp has unsupported pnc"); + } + } else { + switch (proj_num) { + case pn_Cmp_Eq: suffix = "e"; break; + case pn_Cmp_Lt: suffix = "l"; break; + case pn_Cmp_Le: suffix = "le"; break; + case pn_Cmp_Gt: suffix = "g"; break; + case pn_Cmp_Ge: suffix = "ge"; break; + case pn_Cmp_Lg: suffix = "ne"; break; + default: panic("Cmp has unsupported pnc"); + } } /* emit the true proj */ - be_emit_irprintf("\tb%s ", suffix); + be_emit_cstring("\tb"); + be_emit_string(suffix); + be_emit_char(' '); sparc_emit_cfop_target(proj_true); be_emit_finish_line_gas(proj_true); diff --git a/ir/be/sparc/sparc_new_nodes.c b/ir/be/sparc/sparc_new_nodes.c index cc04b93c8..3feb19341 100644 --- a/ir/be/sparc/sparc_new_nodes.c +++ b/ir/be/sparc/sparc_new_nodes.c @@ -55,11 +55,6 @@ static bool has_load_store_attr(const ir_node *node) return is_sparc_Ld(node) || is_sparc_St(node); } -static bool has_cmp_attr(const ir_node *node) -{ - return is_sparc_Cmp(node) || is_sparc_Tst(node); -} - static bool has_jmp_cond_attr(const ir_node *node) { return is_sparc_BXX(node); @@ -115,10 +110,12 @@ static void sparc_set_attr_imm(ir_node *res, int immediate_value) attr->immediate_value = immediate_value; } -void set_sparc_jmp_cond_proj_num(ir_node *node, int proj_num) +static void init_sparc_jmp_cond_attr(ir_node *node, int proj_num, + bool is_unsigned) { sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr(node); - attr->proj_num = proj_num; + attr->proj_num = proj_num; + attr->is_unsigned = is_unsigned; } void set_sparc_jmp_switch_n_projs(ir_node *node, int n_projs) @@ -135,12 +132,6 @@ void set_sparc_jmp_switch_default_proj_num(ir_node *node, long def_proj_num) -int get_sparc_jmp_cond_proj_num(const ir_node *node) -{ - const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node); - return attr->proj_num; -} - int get_sparc_jmp_switch_n_projs(const ir_node *node) { const sparc_jmp_switch_attr_t *attr = get_sparc_jmp_switch_attr_const(node); @@ -213,18 +204,6 @@ const sparc_jmp_switch_attr_t *get_sparc_jmp_switch_attr_const(const ir_node *no return (const sparc_jmp_switch_attr_t*) get_irn_generic_attr_const(node); } -sparc_cmp_attr_t *get_sparc_cmp_attr(ir_node *node) -{ - assert(has_cmp_attr(node)); - return (sparc_cmp_attr_t*) get_irn_generic_attr_const(node); -} - -const sparc_cmp_attr_t *get_sparc_cmp_attr_const(const ir_node *node) -{ - assert(has_cmp_attr(node)); - return (const sparc_cmp_attr_t*) get_irn_generic_attr_const(node); -} - sparc_save_attr_t *get_sparc_save_attr(ir_node *node) { assert(has_save_attr(node)); @@ -302,13 +281,6 @@ static void init_sparc_load_store_attributes(ir_node *res, ir_mode *ls_mode, attr->base.is_load_store = true; } -static void init_sparc_cmp_attr(ir_node *res, bool ins_permuted, bool is_unsigned) -{ - sparc_cmp_attr_t *attr = get_sparc_cmp_attr(res); - attr->ins_permuted = ins_permuted; - attr->is_unsigned = is_unsigned; -} - static void init_sparc_symconst_attributes(ir_node *res, ir_entity *entity) { sparc_symconst_attr_t *attr = get_sparc_symconst_attr(res); @@ -390,7 +362,8 @@ static int cmp_attr_sparc_jmp_cond(ir_node *a, ir_node *b) if (cmp_attr_sparc(a, b)) return 1; - return attr_a->proj_num != attr_b->proj_num; + return attr_a->proj_num != attr_b->proj_num + || attr_a->is_unsigned != attr_b->is_unsigned; } static int cmp_attr_sparc_jmp_switch(ir_node *a, ir_node *b) @@ -405,18 +378,6 @@ static int cmp_attr_sparc_jmp_switch(ir_node *a, ir_node *b) || attr_a->n_projs != attr_b->n_projs; } -static int cmp_attr_sparc_cmp(ir_node *a, ir_node *b) -{ - const sparc_cmp_attr_t *attr_a = get_sparc_cmp_attr_const(a); - const sparc_cmp_attr_t *attr_b = get_sparc_cmp_attr_const(b); - - if (cmp_attr_sparc(a, b)) - return 1; - - return attr_a->ins_permuted != attr_b->ins_permuted - || attr_a->is_unsigned != attr_b->is_unsigned; -} - static int cmp_attr_sparc_save(ir_node *a, ir_node *b) { const sparc_save_attr_t *attr_a = get_sparc_save_attr_const(a); diff --git a/ir/be/sparc/sparc_new_nodes.h b/ir/be/sparc/sparc_new_nodes.h index d5b5434d2..28c2bd07b 100644 --- a/ir/be/sparc/sparc_new_nodes.h +++ b/ir/be/sparc/sparc_new_nodes.h @@ -45,9 +45,6 @@ const sparc_jmp_cond_attr_t *get_sparc_jmp_cond_attr_const(const ir_node *node); sparc_jmp_switch_attr_t *get_sparc_jmp_switch_attr(ir_node *node); const sparc_jmp_switch_attr_t *get_sparc_jmp_switch_attr_const(const ir_node *node); -sparc_cmp_attr_t *get_sparc_cmp_attr(ir_node *node); -const sparc_cmp_attr_t *get_sparc_cmp_attr_const(const ir_node *node); - sparc_save_attr_t *get_sparc_save_attr(ir_node *node); const sparc_save_attr_t *get_sparc_save_attr_const(const ir_node *node); @@ -66,18 +63,6 @@ const arch_register_req_t *get_sparc_in_req(const ir_node *node, int pos); */ void set_sparc_req_in(ir_node *node, const arch_register_req_t *req, int pos); - -/** - * Returns the proj num - */ -int get_sparc_jmp_cond_proj_num(const ir_node *node); - -/** - * Sets the proj num - */ -void set_sparc_jmp_cond_proj_num(ir_node *node, int proj_num); - - /** * Returns the number of projs of a SwitchJmp. */ diff --git a/ir/be/sparc/sparc_nodes_attr.h b/ir/be/sparc/sparc_nodes_attr.h index eaa51492d..ca40638ee 100644 --- a/ir/be/sparc/sparc_nodes_attr.h +++ b/ir/be/sparc/sparc_nodes_attr.h @@ -88,6 +88,7 @@ typedef struct sparc_jmp_cond_attr_t sparc_jmp_cond_attr_t; struct sparc_jmp_cond_attr_t { sparc_attr_t base; /**< generic attribute */ int proj_num; + bool is_unsigned : 1; }; /** @@ -100,14 +101,4 @@ struct sparc_jmp_switch_attr_t { long default_proj_num; }; -/** - * attributes for Cmp - */ -typedef struct sparc_cmp_attr_t sparc_cmp_attr_t; -struct sparc_cmp_attr_t { - sparc_attr_t base; /**< generic attribute */ - bool ins_permuted : 1; - bool is_unsigned : 1; -}; - #endif diff --git a/ir/be/sparc/sparc_spec.pl b/ir/be/sparc/sparc_spec.pl index 2ad963eb7..fb97f0158 100644 --- a/ir/be/sparc/sparc_spec.pl +++ b/ir/be/sparc/sparc_spec.pl @@ -140,7 +140,6 @@ $default_copy_attr = "sparc_copy_attr"; "\tinit_sparc_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);", sparc_symconst_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n". "\tinit_sparc_symconst_attributes(res, entity);", - sparc_cmp_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n", sparc_jmp_cond_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);", sparc_jmp_switch_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);", sparc_save_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);", @@ -153,7 +152,6 @@ $default_copy_attr = "sparc_copy_attr"; sparc_symconst_attr_t => "cmp_attr_sparc_symconst", sparc_jmp_cond_attr_t => "cmp_attr_sparc_jmp_cond", sparc_jmp_switch_attr_t => "cmp_attr_sparc_jmp_switch", - sparc_cmp_attr_t => "cmp_attr_sparc_cmp", sparc_save_attr_t => "cmp_attr_sparc_save", ); @@ -162,15 +160,12 @@ $default_copy_attr = "sparc_copy_attr"; my %cmp_operand_constructors = ( imm => { - attr => "int immediate_value, bool ins_permuted, bool is_unsigned", - custominit => "sparc_set_attr_imm(res, immediate_value);" . - "\tinit_sparc_cmp_attr(res, ins_permuted, is_unsigned);", + attr => "int immediate_value", + custominit => "sparc_set_attr_imm(res, immediate_value);", reg_req => { in => [ "gp" ], out => [ "flags" ] }, - ins => [ "left" ], + ins => [ "left" ], }, reg => { - attr => "bool ins_permuted, bool is_unsigned", - custominit => "init_sparc_cmp_attr(res, ins_permuted, is_unsigned);", reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] }, ins => [ "left", "right" ], }, @@ -321,9 +316,9 @@ BXX => { state => "pinned", mode => "mode_T", reg_req => { in => [ "flags" ], out => [ "none", "none" ] }, - attr => "int proj_num", + attr => "int proj_num, bool is_unsigned", attr_type => "sparc_jmp_cond_attr_t", - init_attr => "\tset_sparc_jmp_cond_proj_num(res, proj_num);", + init_attr => "\tinit_sparc_jmp_cond_attr(res, proj_num, is_unsigned);", }, Ba => { @@ -338,7 +333,6 @@ Cmp => { irn_flags => [ "rematerializable", "modify_flags" ], emit => '. cmp %S1, %R2I', mode => $mode_flags, - attr_type => "sparc_cmp_attr_t", constructors => \%cmp_operand_constructors, }, @@ -346,11 +340,8 @@ Tst => { irn_flags => [ "rematerializable", "modify_flags" ], emit => '. tst %S1', mode => $mode_flags, - attr_type => "sparc_cmp_attr_t", - attr => "bool ins_permuted, bool is_unsigned", - custominit => "init_sparc_cmp_attr(res, ins_permuted, is_unsigned);", reg_req => { in => [ "gp" ], out => [ "flags" ] }, - ins => [ "left" ], + ins => [ "val" ], }, SwitchJmp => { diff --git a/ir/be/sparc/sparc_transform.c b/ir/be/sparc/sparc_transform.c index 9aa54647a..1f9cf472b 100644 --- a/ir/be/sparc/sparc_transform.c +++ b/ir/be/sparc/sparc_transform.c @@ -709,6 +709,20 @@ static ir_node *gen_SwitchJmp(ir_node *node) return new_bd_sparc_SwitchJmp(dbgi, block, sub, n_projs, get_Cond_default_proj(node) - translation); } +static bool is_cmp_unsigned(ir_node *b_value) +{ + ir_node *pred; + ir_node *op; + + if (!is_Proj(b_value)) + panic("can't determine cond signednes"); + pred = get_Proj_pred(b_value); + if (!is_Cmp(pred)) + panic("can't determine cond signednes (no cmp)"); + op = get_Cmp_left(pred); + return !mode_is_signed(get_irn_mode(op)); +} + /** * Transform Cond nodes */ @@ -718,6 +732,8 @@ static ir_node *gen_Cond(ir_node *node) ir_mode *mode = get_irn_mode(selector); ir_node *block; ir_node *flag_node; + bool is_unsigned; + pn_Cmp pnc; dbg_info *dbgi; // switch/case jumps @@ -727,11 +743,14 @@ static ir_node *gen_Cond(ir_node *node) // regular if/else jumps assert(is_Proj(selector)); - - block = be_transform_node(get_nodes_block(node)); - dbgi = get_irn_dbg_info(node); - flag_node = be_transform_node(get_Proj_pred(selector)); - return new_bd_sparc_BXX(dbgi, block, flag_node, get_Proj_proj(selector)); + assert(is_Cmp(get_Proj_pred(selector))); + + block = be_transform_node(get_nodes_block(node)); + dbgi = get_irn_dbg_info(node); + flag_node = be_transform_node(get_Proj_pred(selector)); + pnc = get_Proj_proj(selector); + is_unsigned = is_cmp_unsigned(selector); + return new_bd_sparc_BXX(dbgi, block, flag_node, pnc, is_unsigned); } /** @@ -746,7 +765,6 @@ static ir_node *gen_Cmp(ir_node *node) dbg_info *dbgi = get_irn_dbg_info(node); ir_node *new_op1; ir_node *new_op2; - bool is_unsigned; if (mode_is_float(cmp_mode)) { panic("FloatCmp not implemented"); @@ -759,7 +777,6 @@ static ir_node *gen_Cmp(ir_node *node) */ assert(get_irn_mode(op2) == cmp_mode); - is_unsigned = !mode_is_signed(cmp_mode); /* compare with 0 can be done with Tst */ /* @@ -781,7 +798,7 @@ static ir_node *gen_Cmp(ir_node *node) new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode); new_op2 = be_transform_node(op2); new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode); - return new_bd_sparc_Cmp_reg(dbgi, block, new_op1, new_op2, false, is_unsigned); + return new_bd_sparc_Cmp_reg(dbgi, block, new_op1, new_op2); } /**