remove $Id$, it doesn't work with git anyway
[libfirm] / ir / lower / lower_dw.c
index ee210c1..9a24a80 100644 (file)
@@ -22,7 +22,6 @@
  * @brief   Lower double word operations, i.e. 64bit -> 32bit, 32bit -> 16bit etc.
  * @date    8.10.2004
  * @author  Michael Beck
- * @version $Id$
  */
 #include "config.h"
 
@@ -1228,6 +1227,18 @@ static ir_node *get_cfop_destination(const ir_node *cfop)
        return get_edge_src_irn(first);
 }
 
+static void lower_Switch(ir_node *node, ir_mode *high_mode)
+{
+       ir_node *selector = get_Switch_selector(node);
+       ir_mode *mode     = get_irn_mode(selector);
+       (void)high_mode;
+       if (mode == env->high_signed || mode == env->high_unsigned) {
+               /* we can't really handle Switch with 64bit offsets */
+               panic("Switch with 64bit jumptable not supported");
+       }
+       lower_node(selector);
+}
+
 /**
  * Translate a Cond.
  */
@@ -1235,7 +1246,6 @@ static void lower_Cond(ir_node *node, ir_mode *high_mode)
 {
        ir_node *left, *right, *block;
        ir_node *sel = get_Cond_selector(node);
-       ir_mode *m = get_irn_mode(sel);
        ir_mode *cmp_mode;
        const lower64_entry_t *lentry, *rentry;
        ir_node  *projT = NULL, *projF = NULL;
@@ -1250,15 +1260,6 @@ static void lower_Cond(ir_node *node, ir_mode *high_mode)
 
        (void) high_mode;
 
-       if (m != mode_b) {
-               if (m == env->high_signed || m == env->high_unsigned) {
-                       /* bad we can't really handle Switch with 64bit offsets */
-                       panic("Cond with 64bit jumptable not supported");
-               }
-               lower_node(sel);
-               return;
-       }
-
        if (!is_Cmp(sel)) {
                lower_node(sel);
                return;
@@ -2536,111 +2537,106 @@ static void lower_Builtin(ir_node *builtin, ir_mode *mode)
        assert(arity == 2);
 
        switch (kind) {
-       case ir_bk_ffs:
-               {
-                       const lower64_entry_t *entry          = get_node_entry(operand);
-                       ir_node               *in_high[1]     = {entry->high_word};
-                       ir_node               *in_low[1]      = {entry->low_word};
-                       ir_node               *number_of_bits = new_r_Const_long(irg, mode_Is, get_mode_size_bits(env->low_unsigned));
-                       ir_node               *zero_signed    = new_rd_Const(dbgi, irg, get_mode_null(mode_Is));
-                       ir_node               *zero_unsigned  = new_rd_Const(dbgi, irg, get_mode_null(mode_Iu));
-                       ir_node               *cmp_low        = new_rd_Cmp(dbgi, block, entry->low_word, zero_unsigned, ir_relation_equal);
-                       ir_node               *cmp_high       = new_rd_Cmp(dbgi, block, entry->high_word, zero_unsigned, ir_relation_equal);
-                       ir_node               *ffs_high       = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
-                       ir_node               *high_proj      = new_r_Proj(ffs_high, mode_Is, pn_Builtin_1_result);
-                       ir_node               *high           = new_rd_Add(dbgi, block, high_proj, number_of_bits, mode_Is);
-                       ir_node               *ffs_low        = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
-                       ir_node               *low            = new_r_Proj(ffs_low, mode_Is, pn_Builtin_1_result);
-                       ir_node               *mux_high       = new_rd_Mux(dbgi, block, cmp_high, high, zero_signed, mode_Is);
-
-                       if (! allow_ifconv(cmp_high, high, zero_signed))
-                               ir_nodeset_insert(&created_mux_nodes, mux_high);
-
-                       res = new_rd_Mux(dbgi, block, cmp_low, low, mux_high, mode_Is);
-
-                       if (! allow_ifconv(cmp_low, low, mux_high))
-                               ir_nodeset_insert(&created_mux_nodes, res);
-               }
+       case ir_bk_ffs: {
+               const lower64_entry_t *entry          = get_node_entry(operand);
+               ir_node               *in_high[1]     = {entry->high_word};
+               ir_node               *in_low[1]      = {entry->low_word};
+               ir_node               *number_of_bits = new_r_Const_long(irg, mode_Is, get_mode_size_bits(env->low_unsigned));
+               ir_node               *zero_signed    = new_rd_Const(dbgi, irg, get_mode_null(mode_Is));
+               ir_node               *zero_unsigned  = new_rd_Const(dbgi, irg, get_mode_null(mode_Iu));
+               ir_node               *cmp_low        = new_rd_Cmp(dbgi, block, entry->low_word, zero_unsigned, ir_relation_equal);
+               ir_node               *cmp_high       = new_rd_Cmp(dbgi, block, entry->high_word, zero_unsigned, ir_relation_equal);
+               ir_node               *ffs_high       = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
+               ir_node               *high_proj      = new_r_Proj(ffs_high, mode_Is, pn_Builtin_max+1);
+               ir_node               *high           = new_rd_Add(dbgi, block, high_proj, number_of_bits, mode_Is);
+               ir_node               *ffs_low        = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
+               ir_node               *low            = new_r_Proj(ffs_low, mode_Is, pn_Builtin_max+1);
+               ir_node               *mux_high       = new_rd_Mux(dbgi, block, cmp_high, high, zero_signed, mode_Is);
+
+               if (! allow_ifconv(cmp_high, high, zero_signed))
+                       ir_nodeset_insert(&created_mux_nodes, mux_high);
+
+               res = new_rd_Mux(dbgi, block, cmp_low, low, mux_high, mode_Is);
+
+               if (! allow_ifconv(cmp_low, low, mux_high))
+                       ir_nodeset_insert(&created_mux_nodes, res);
                break;
-       case ir_bk_clz:
-               {
-                       const lower64_entry_t *entry          = get_node_entry(operand);
-                       ir_node               *in_high[1]     = {entry->high_word};
-                       ir_node               *in_low[1]      = {entry->low_word};
-                       ir_node               *number_of_bits = new_r_Const_long(irg, mode_Is, get_mode_size_bits(mode));
-                       ir_node               *zero_unsigned  = new_rd_Const(dbgi, irg, get_mode_null(mode_Iu));
-                       ir_node               *cmp_high       = new_rd_Cmp(dbgi, block, entry->high_word, zero_unsigned, ir_relation_equal);
-                       ir_node               *clz_high       = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
-                       ir_node               *high           = new_r_Proj(clz_high, mode_Is, pn_Builtin_1_result);
-                       ir_node               *clz_low        = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
-                       ir_node               *low_proj       = new_r_Proj(clz_low, mode_Is, pn_Builtin_1_result);
-                       ir_node               *low            = new_rd_Add(dbgi, block, low_proj, number_of_bits, mode_Is);
-
-                       res = new_rd_Mux(dbgi, block, cmp_high, high, low, mode_Is);
-
-                       if (! allow_ifconv(cmp_high, high, low))
-                               ir_nodeset_insert(&created_mux_nodes, res);
-               }
+       }
+       case ir_bk_clz: {
+               const lower64_entry_t *entry          = get_node_entry(operand);
+               ir_node               *in_high[1]     = {entry->high_word};
+               ir_node               *in_low[1]      = {entry->low_word};
+               ir_node               *number_of_bits = new_r_Const_long(irg, mode_Is, get_mode_size_bits(mode));
+               ir_node               *zero_unsigned  = new_rd_Const(dbgi, irg, get_mode_null(mode_Iu));
+               ir_node               *cmp_high       = new_rd_Cmp(dbgi, block, entry->high_word, zero_unsigned, ir_relation_equal);
+               ir_node               *clz_high       = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
+               ir_node               *high           = new_r_Proj(clz_high, mode_Is, pn_Builtin_max+1);
+               ir_node               *clz_low        = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
+               ir_node               *low_proj       = new_r_Proj(clz_low, mode_Is, pn_Builtin_max+1);
+               ir_node               *low            = new_rd_Add(dbgi, block, low_proj, number_of_bits, mode_Is);
+
+               res = new_rd_Mux(dbgi, block, cmp_high, high, low, mode_Is);
+
+               if (! allow_ifconv(cmp_high, high, low))
+                       ir_nodeset_insert(&created_mux_nodes, res);
                break;
-       case ir_bk_ctz:
-               {
-                       const lower64_entry_t *entry          = get_node_entry(operand);
-                       ir_node               *in_high[1]     = {entry->high_word};
-                       ir_node               *in_low[1]      = {entry->low_word};
-                       ir_node               *number_of_bits = new_r_Const_long(irg, mode_Is, get_mode_size_bits(env->low_unsigned));
-                       ir_node               *zero_unsigned  = new_rd_Const(dbgi, irg, get_mode_null(mode_Iu));
-                       ir_node               *cmp_low        = new_rd_Cmp(dbgi, block, entry->low_word, zero_unsigned, ir_relation_equal);
-                       ir_node               *ffs_high       = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
-                       ir_node               *high_proj      = new_r_Proj(ffs_high, mode_Is, pn_Builtin_1_result);
-                       ir_node               *high           = new_rd_Add(dbgi, block, high_proj, number_of_bits, mode_Is);
-                       ir_node               *ffs_low        = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
-                       ir_node               *low            = new_r_Proj(ffs_low, mode_Is, pn_Builtin_1_result);
-
-                       res = new_rd_Mux(dbgi, block, cmp_low, low, high, mode_Is);
-
-                       if (! allow_ifconv(cmp_low, low, high))
-                               ir_nodeset_insert(&created_mux_nodes, res);
-               }
+       }
+       case ir_bk_ctz: {
+               const lower64_entry_t *entry          = get_node_entry(operand);
+               ir_node               *in_high[1]     = {entry->high_word};
+               ir_node               *in_low[1]      = {entry->low_word};
+               ir_node               *number_of_bits = new_r_Const_long(irg, mode_Is, get_mode_size_bits(env->low_unsigned));
+               ir_node               *zero_unsigned  = new_rd_Const(dbgi, irg, get_mode_null(mode_Iu));
+               ir_node               *cmp_low        = new_rd_Cmp(dbgi, block, entry->low_word, zero_unsigned, ir_relation_equal);
+               ir_node               *ffs_high       = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
+               ir_node               *high_proj      = new_r_Proj(ffs_high, mode_Is, pn_Builtin_max+1);
+               ir_node               *high           = new_rd_Add(dbgi, block, high_proj, number_of_bits, mode_Is);
+               ir_node               *ffs_low        = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
+               ir_node               *low            = new_r_Proj(ffs_low, mode_Is, pn_Builtin_max+1);
+
+               res = new_rd_Mux(dbgi, block, cmp_low, low, high, mode_Is);
+
+               if (! allow_ifconv(cmp_low, low, high))
+                       ir_nodeset_insert(&created_mux_nodes, res);
                break;
-       case ir_bk_popcount:
-               {
-                       const lower64_entry_t *entry         = get_node_entry(operand);
-                       ir_node               *in_high[1]    = {entry->high_word};
-                       ir_node               *in_low[1]     = {entry->low_word};
-                       ir_node               *popcount_high = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
-                       ir_node               *popcount_low  = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
-                       ir_node               *high          = new_r_Proj(popcount_high, mode_Is, pn_Builtin_1_result);
-                       ir_node               *low           = new_r_Proj(popcount_low, mode_Is, pn_Builtin_1_result);
-
-                       res = new_rd_Add(dbgi, block, high, low, mode_Is);
-               }
+       }
+       case ir_bk_popcount: {
+               const lower64_entry_t *entry         = get_node_entry(operand);
+               ir_node               *in_high[1]    = {entry->high_word};
+               ir_node               *in_low[1]     = {entry->low_word};
+               ir_node               *popcount_high = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
+               ir_node               *popcount_low  = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
+               ir_node               *high          = new_r_Proj(popcount_high, mode_Is, pn_Builtin_max+1);
+               ir_node               *low           = new_r_Proj(popcount_low, mode_Is, pn_Builtin_max+1);
+
+               res = new_rd_Add(dbgi, block, high, low, mode_Is);
                break;
-       case ir_bk_parity:
-               {
-                       const lower64_entry_t *entry = get_node_entry(operand);
-                       ir_node *in_high[1] = {entry->high_word};
-                       ir_node *in_low[1] = {entry->low_word};
-                       ir_node  *parity_high;
-                       ir_node  *parity_low;
-                       ir_node  *high;
-                       ir_node  *low;
-
-                       assert(arity == 2);
-
-                       parity_high = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
-                       high        = new_r_Proj(parity_high, mode_Is, pn_Builtin_1_result);
-                       parity_low  = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
-                       low         = new_r_Proj(parity_low, mode_Is, pn_Builtin_1_result);
-                       res         = new_rd_Eor(dbgi, block, high, low, mode_Is);
-               }
+       }
+       case ir_bk_parity: {
+               const lower64_entry_t *entry = get_node_entry(operand);
+               ir_node *in_high[1] = {entry->high_word};
+               ir_node *in_low[1] = {entry->low_word};
+               ir_node  *parity_high;
+               ir_node  *parity_low;
+               ir_node  *high;
+               ir_node  *low;
+
+               assert(arity == 2);
+
+               parity_high = new_rd_Builtin(dbgi, block, mem, 1, in_high, kind, lowered_type_high);
+               high        = new_r_Proj(parity_high, mode_Is, pn_Builtin_max+1);
+               parity_low  = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
+               low         = new_r_Proj(parity_low, mode_Is, pn_Builtin_max+1);
+               res         = new_rd_Eor(dbgi, block, high, low, mode_Is);
                break;
+       }
        default:
                panic("unexpected builtin");
        }
 
        turn_into_tuple(builtin, 2);
        set_irn_n(builtin, pn_Builtin_M, mem);
-       set_irn_n(builtin, pn_Builtin_1_result, res);
+       set_irn_n(builtin, pn_Builtin_max+1, res);
 }
 
 /**
@@ -2763,10 +2759,10 @@ static void setup_modes(void)
        /* produce lowered modes */
        env->high_signed   = doubleword_signed;
        env->high_unsigned = doubleword_unsigned;
-       env->low_signed    = new_ir_mode("WS", irms_int_number, size_bits, 1,
-                                        arithmetic, modulo_shift);
-       env->low_unsigned  = new_ir_mode("WU", irms_int_number, size_bits, 0,
-                                        arithmetic, modulo_shift);
+       env->low_signed    = new_int_mode("WS", arithmetic, size_bits, 1,
+                                         modulo_shift);
+       env->low_unsigned  = new_int_mode("WU", arithmetic, size_bits, 0,
+                                         modulo_shift);
 }
 
 static void enqueue_preds(ir_node *node)
@@ -2962,6 +2958,7 @@ void ir_prepare_dw_lowering(const lwrdw_param_t *new_param)
        ir_register_dw_lower_function(op_Start,   lower_Start);
        ir_register_dw_lower_function(op_Store,   lower_Store);
        ir_register_dw_lower_function(op_Sub,     lower_binop);
+       ir_register_dw_lower_function(op_Switch,  lower_Switch);
        ir_register_dw_lower_function(op_Unknown, lower_Unknown);
 }