Commit 00a2fb25 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

mips: Handle lowering of 64 bit addition.

Now 'long long f(long long a, long long b) { return a + b; }' can be translated.
parent f7433936
......@@ -275,6 +275,28 @@ static ir_entity *mips_create_64_intrinsic_fkt(ir_type *const method, ir_op cons
panic("TODO");
}
static void mips_lower_add64(ir_node *const node, ir_mode *const mode)
{
dbg_info *const dbg = get_irn_dbg_info(node);
ir_node *const block = get_nodes_block(node);
ir_node *const left = get_Add_left(node);
ir_node *const right = get_Add_right(node);
ir_node *const left_low = get_lowered_low(left);
ir_node *const left_high = get_lowered_high(left);
ir_node *const right_low = get_lowered_low(right);
ir_node *const right_high = get_lowered_high(right);
ir_node *const res_low = new_rd_Add(dbg, block, left_low, right_low);
ir_node *const cmp_carry = new_rd_Cmp(dbg, block, res_low, right_low, ir_relation_less);
ir_graph *const irg = get_irn_irg(node);
ir_node *const one = new_r_Const(irg, get_mode_one(mode));
ir_node *const zero = new_r_Const(irg, get_mode_null(mode));
ir_node *const carry = new_rd_Mux(dbg, block, cmp_carry, zero, one);
ir_node *const sum_high = new_rd_Add(dbg, block, left_high, right_high);
ir_node *const res_high = new_rd_Add(dbg, block, sum_high, carry);
ir_set_dw_lowered(node, res_low, res_high);
}
static void mips_lower64(void)
{
ir_mode *const word_unsigned = mips_reg_classes[CLASS_mips_gp].mode;
......@@ -288,6 +310,7 @@ static void mips_lower64(void)
};
ir_prepare_dw_lowering(&lower_dw_params);
ir_register_dw_lower_function(op_Add, mips_lower_add64);
ir_lower_dw_ops();
}
......@@ -300,6 +323,7 @@ static void mips_lower_for_target(void)
}
mips_lower64();
be_after_irp_transform("lower-64");
}
static unsigned mips_get_op_estimated_cost(ir_node const *const node)
......
......@@ -773,6 +773,22 @@ static ir_node *gen_Minus(ir_node *const node)
panic("TODO");
}
static ir_node *gen_Mux(ir_node *const node)
{
ir_mode *const mode = get_irn_mode(node);
if (be_mode_needs_gp_reg(mode)) {
if (is_irn_null(get_Mux_false(node)) && is_irn_one(get_Mux_true(node))) {
ir_node *const sel = get_Mux_sel(node);
if (is_Cmp(sel)) {
ir_relation const rel = get_Cmp_relation(sel);
if (rel == ir_relation_less || rel == ir_relation_greater)
return be_transform_node(sel);
}
}
}
panic("TODO");
}
static ir_node *gen_Not(ir_node *const node)
{
dbg_info *const dbgi = get_irn_dbg_info(node);
......@@ -1183,6 +1199,7 @@ static void mips_register_transformers(void)
be_set_transform_function(op_Mul, gen_Mul);
be_set_transform_function(op_Minus, gen_Minus);
be_set_transform_function(op_Mod, gen_Mod);
be_set_transform_function(op_Mux, gen_Mux);
be_set_transform_function(op_Not, gen_Not);
be_set_transform_function(op_Or, gen_Or);
be_set_transform_function(op_Phi, gen_Phi);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment