sparc: fix unsigned compares and cleanup cmp attributes
authorMatthias Braun <matze@braunis.de>
Thu, 22 Jul 2010 19:07:47 +0000 (19:07 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 22 Jul 2010 19:07:47 +0000 (19:07 +0000)
[r27786]

ir/be/sparc/sparc_emitter.c
ir/be/sparc/sparc_new_nodes.c
ir/be/sparc/sparc_new_nodes.h
ir/be/sparc/sparc_nodes_attr.h
ir/be/sparc/sparc_spec.pl
ir/be/sparc/sparc_transform.c

index 42f948c..d7e9579 100644 (file)
@@ -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);
 
index cc04b93..3feb193 100644 (file)
@@ -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);
index d5b5434..28c2bd0 100644 (file)
@@ -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.
  */
index eaa5149..ca40638 100644 (file)
@@ -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
index 2ad963e..fb97f01 100644 (file)
@@ -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 => {
index 9aa5464..1f9cf47 100644 (file)
@@ -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);
 }
 
 /**