simplify begnuas.c by not sorting entities into sections
[libfirm] / ir / lower / lower_dw.c
index 7484331..a0cd50f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -288,7 +288,7 @@ static void prepare_links(ir_node *node, void *env)
 
                lenv->entries[get_irn_idx(node)] = link;
                lenv->flags |= MUST_BE_LOWERED;
-       } else if (get_irn_op(node) == op_Conv) {
+       } else if (is_Conv(node)) {
                /* Conv nodes have two modes */
                ir_node *pred = get_Conv_op(node);
                mode = get_irn_mode(pred);
@@ -525,7 +525,7 @@ static ir_node *get_intrinsic_address(ir_type *method, ir_op *op,
                ent = entry->ent;
        }  /* if */
        sym.entity_p = ent;
-       return new_r_SymConst(current_ir_graph, block, sym, symconst_addr_ent);
+       return new_r_SymConst(current_ir_graph, block, mode_P_code, sym, symconst_addr_ent);
 }  /* get_intrinsic_address */
 
 /**
@@ -915,7 +915,7 @@ static void lower_Shr(ir_node *node, ir_mode *mode, lower_env_t *env) {
                tarval *tv = get_Const_tarval(right);
 
                if (tarval_is_long(tv) &&
-                       get_tarval_long(tv) >= get_mode_size_bits(mode)) {
+                       get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) {
                        ir_node *block = get_nodes_block(node);
                        ir_node *left = get_Shr_left(node);
                        ir_node *c;
@@ -950,7 +950,7 @@ static void lower_Shl(ir_node *node, ir_mode *mode, lower_env_t *env) {
                tarval *tv = get_Const_tarval(right);
 
                if (tarval_is_long(tv) &&
-                       get_tarval_long(tv) >= get_mode_size_bits(mode)) {
+                       get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) {
                        ir_mode *mode_l;
                        ir_node *block = get_nodes_block(node);
                        ir_node *left = get_Shl_left(node);
@@ -987,7 +987,7 @@ static void lower_Shrs(ir_node *node, ir_mode *mode, lower_env_t *env) {
                tarval *tv = get_Const_tarval(right);
 
                if (tarval_is_long(tv) &&
-                       get_tarval_long(tv) >= get_mode_size_bits(mode)) {
+                       get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) {
                        ir_node *block = get_nodes_block(node);
                        ir_node *left = get_Shrs_left(node);
                        long shf_cnt = get_tarval_long(tv) - get_mode_size_bits(mode);
@@ -1022,7 +1022,7 @@ static void lower_Rot(ir_node *node, ir_mode *mode, lower_env_t *env) {
                tarval *tv = get_Const_tarval(right);
 
                if (tarval_is_long(tv) &&
-                       get_tarval_long(tv) == get_mode_size_bits(mode)) {
+                       get_tarval_long(tv) == (int) get_mode_size_bits(mode)) {
                        ir_node *left = get_Rot_left(node);
                        ir_node *h, *l;
                        int idx = get_irn_idx(left);
@@ -1244,13 +1244,28 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env) {
                assert(projT && projF);
 
                /* create a new high compare */
-               block = get_nodes_block(cmp);
+               block = get_nodes_block(node);
                dbg   = get_irn_dbg_info(cmp);
                irg   = current_ir_graph;
+               pnc   = get_Proj_proj(sel);
+
+               if (is_Const(right) && is_Const_null(right)) {
+                       if (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) {
+                               /* x ==/!= 0 ==> or(low,high) ==/!= 0 */
+                               ir_mode *mode = env->params->low_unsigned;
+                               ir_node *low  = new_r_Conv(irg, block, lentry->low_word, mode);
+                               ir_node *high = new_r_Conv(irg, block, lentry->high_word, mode);
+                               ir_node *or   = new_rd_Or(dbg, irg, block, low, high, mode);
+                               ir_node *cmp  = new_rd_Cmp(dbg, irg, block, or, new_Const_long(mode, 0));
+
+                               ir_node *proj = new_r_Proj(irg, block, cmp, mode_b, pnc);
+                               set_Cond_selector(node, proj);
+                               return;
+                       }
+               }
 
                cmpH = new_rd_Cmp(dbg, irg, block, lentry->high_word, rentry->high_word);
 
-               pnc = get_Proj_proj(sel);
                if (pnc == pn_Cmp_Eq) {
                        /* simple case:a == b <==> a_h == b_h && a_l == b_l */
                        pmap_entry *entry = pmap_find(env->proj_2_block, projF);
@@ -1998,10 +2013,11 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env) {
  * Translate an Unknown into two.
  */
 static void lower_Unknown(ir_node *node, ir_mode *mode, lower_env_t *env) {
-       int idx = get_irn_idx(node);
+       int      idx = get_irn_idx(node);
        ir_graph *irg = current_ir_graph;
+       ir_mode  *low_mode = env->params->low_unsigned;
 
-       env->entries[idx]->low_word  =
+       env->entries[idx]->low_word  = new_r_Unknown(irg, low_mode);
        env->entries[idx]->high_word = new_r_Unknown(irg, mode);
 }  /* lower_Unknown */
 
@@ -2013,9 +2029,7 @@ static void lower_Unknown(ir_node *node, ir_mode *mode, lower_env_t *env) {
 static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) {
        ir_mode  *mode_l = env->params->low_unsigned;
        ir_graph *irg = current_ir_graph;
-       ir_node  *block;
-       ir_node  *unk_l;
-       ir_node  *unk_h;
+       ir_node  *block, *unk_l, *unk_h, *phi_l, *phi_h;
        ir_node  **inl, **inh;
        dbg_info *dbg;
        int      idx, i, arity = get_Phi_n_preds(phi);
@@ -2067,8 +2081,13 @@ static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) {
 
        idx = get_irn_idx(phi);
        assert(idx < env->n_entries);
-       env->entries[idx]->low_word  = new_rd_Phi(dbg, irg, block, arity, inl, mode_l);
-       env->entries[idx]->high_word = new_rd_Phi(dbg, irg, block, arity, inh, mode);
+       env->entries[idx]->low_word  = phi_l = new_rd_Phi(dbg, irg, block, arity, inl, mode_l);
+       env->entries[idx]->high_word = phi_h = new_rd_Phi(dbg, irg, block, arity, inh, mode);
+
+       /* Don't forget to link the new Phi nodes into the block! */
+       set_irn_link(phi_l, get_irn_link(block));
+       set_irn_link(phi_h, phi_l);
+       set_irn_link(block, phi_h);
 
        if (enq) {
                /* not yet finished */
@@ -2295,6 +2314,13 @@ static int cmp_conv_tp(const void *elt, const void *key, size_t size) {
        return (e1->imode - e2->imode) | (e1->omode - e2->omode);
 }  /* static int cmp_conv_tp */
 
+/**
+ * Enter a lowering function into an ir_op.
+ */
+static void enter_lower_func(ir_op *op, lower_func func) {
+       op->ops.generic = (op_func)func;
+}
+
 /*
  * Do the lowering.
  */
@@ -2391,7 +2417,7 @@ void lower_dw_ops(const lwrdw_param_t *param)
        /* first clear the generic function pointer for all ops */
        clear_irp_opcodes_generic_func();
 
-#define LOWER2(op, fkt)   op_##op->ops.generic = (op_func)fkt
+#define LOWER2(op, fkt)   enter_lower_func(op_##op, fkt)
 #define LOWER(op)         LOWER2(op, lower_##op)
 #define LOWER_BIN(op)     LOWER2(op, lower_Binop)
 #define LOWER_UN(op)      LOWER2(op, lower_Unop)