sparc: implement float->unsigned conversions
[libfirm] / ir / be / beprefalloc.c
index 63ed2ce..338b7a4 100644 (file)
@@ -22,7 +22,6 @@
  * @brief       Preference Guided Register Assignment
  * @author      Matthias Braun
  * @date        14.2.2009
- * @version     $Id$
  *
  * The idea is to allocate registers in 2 passes:
  * 1. A first pass to determine "preferred" registers for live-ranges. This
@@ -1246,6 +1245,13 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node,
        lpp_free(lpp);
 }
 
+static bool is_aligned(unsigned num, unsigned alignment)
+{
+       unsigned mask = alignment-1;
+       assert(is_po2(alignment));
+       return (num&mask) == 0;
+}
+
 /**
  * Enforce constraints at a node by live range splits.
  *
@@ -1265,7 +1271,8 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node,
        /* construct a list of register occupied by live-through values */
        unsigned *live_through_regs = NULL;
 
-       /* see if any use constraints are not met */
+       /* see if any use constraints are not met and whether double-width
+        * values are involved */
        bool double_width = false;
        bool good = true;
        for (i = 0; i < arity; ++i) {
@@ -1282,16 +1289,22 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node,
                req = arch_get_irn_register_req_in(node, i);
                if (req->width > 1)
                        double_width = true;
+               reg       = arch_get_irn_register(op);
+               reg_index = arch_register_get_index(reg);
+               if (req->type & arch_register_req_type_aligned) {
+                       if (!is_aligned(reg_index, req->width)) {
+                               good = false;
+                               continue;
+                       }
+               }
                if (!(req->type & arch_register_req_type_limited))
                        continue;
 
                limited   = req->limited;
-               reg       = arch_get_irn_register(op);
-               reg_index = arch_register_get_index(reg);
                if (!rbitset_is_set(limited, reg_index)) {
                        /* found an assignment outside the limited set */
                        good = false;
-                       break;
+                       continue;
                }
        }
 
@@ -1997,8 +2010,8 @@ static void be_pref_alloc_cls(void)
 {
        size_t i;
 
-       lv = be_assure_liveness(irg);
-       be_liveness_assure_sets(lv);
+       be_assure_live_sets(irg);
+       lv = be_get_irg_liveness(irg);
 
        ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
 
@@ -2096,8 +2109,7 @@ static void be_pref_alloc(ir_graph *new_irg)
 
                /* we most probably constructed new Phis so liveness info is invalid
                 * now */
-               /* TODO: test liveness_introduce */
-               be_liveness_invalidate(lv);
+               be_invalidate_live_sets(irg);
                free(normal_regs);
 
                stat_ev_ctx_pop("regcls");