* @brief Lower double word operations, i.e. 64bit -> 32bit, 32bit -> 16bit etc.
* @date 8.10.2004
* @author Michael Beck
- * @version $Id$
*/
#include "config.h"
* (and can't handle anything else) */
if (modulo_shift != get_mode_size_bits(shr_mode)
|| modulo_shift2<<1 != modulo_shift) {
- panic("Shl lowering only implemented for modulo shift shr operations");
+ panic("Shl lowering only implemented for modulo shift shl operations");
}
if (!is_po2(modulo_shift) || !is_po2(modulo_shift2)) {
panic("Shl lowering only implemented for power-of-2 modes");
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.
*/
{
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;
(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;
ir_type *res;
size_t i;
size_t n_params;
- size_t n_res;
+ size_t n_results;
bool must_be_lowered;
res = (ir_type*)pmap_get(lowered_builtin_type_high, mtp);
return res;
n_params = get_method_n_params(mtp);
- n_res = get_method_n_ress(mtp);
+ n_results = get_method_n_ress(mtp);
must_be_lowered = false;
- /* count new number of params */
+ /* check for double word parameter */
for (i = n_params; i > 0;) {
ir_type *tp = get_method_param_type(mtp, --i);
return mtp;
}
- res = new_d_type_method(n_params, n_res, get_type_dbg_info(mtp));
+ res = new_d_type_method(n_params, n_results, get_type_dbg_info(mtp));
/* set param types and result types */
for (i = 0; i < n_params; ++i) {
set_method_param_type(res, i, tp);
}
}
- for (i = n_res = 0; i < n_res; ++i) {
+ for (i = n_results = 0; i < n_results; ++i) {
ir_type *tp = get_method_res_type(mtp, i);
set_method_res_type(res, i, tp);
ir_type *res;
size_t i;
size_t n_params;
- size_t n_ress;
+ size_t n_results;
bool must_be_lowered;
res = (ir_type*)pmap_get(lowered_builtin_type_low, mtp);
return res;
n_params = get_method_n_params(mtp);
- n_ress = get_method_n_ress(mtp);
+ n_results = get_method_n_ress(mtp);
must_be_lowered = false;
- /* count new number of params */
+ /* check for double word parameter */
for (i = n_params; i > 0;) {
ir_type *tp = get_method_param_type(mtp, --i);
}
}
- /* count new number of results */
- for (i = n_ress; i > 0;) {
- ir_type *tp = get_method_res_type(mtp, --i);
-
- if (is_Primitive_type(tp)) {
- ir_mode *mode = get_type_mode(tp);
-
- if (mode == env->high_signed || mode == env->high_unsigned) {
- must_be_lowered = true;
- }
- }
- }
if (!must_be_lowered) {
set_type_link(mtp, NULL);
return mtp;
}
- res = new_d_type_method(n_params, n_ress, get_type_dbg_info(mtp));
+ res = new_d_type_method(n_params, n_results, get_type_dbg_info(mtp));
/* set param types and result types */
for (i = 0; i < n_params; ++i) {
set_method_param_type(res, i, tp);
}
}
- for (i = 0; i < n_ress; ++i) {
+ for (i = 0; i < n_results; ++i) {
ir_type *tp = get_method_res_type(mtp, i);
set_method_res_type(res, i, tp);
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);
}
/**
/* 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)
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);
}