From c378db2a15d92914dcbe4c6bf08a6b4558ecc708 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20W=C3=BCrdig?= Date: Wed, 17 May 2006 09:21:56 +0000 Subject: [PATCH] added extra shift lowering [r7743] --- ir/lower/lower_dw.c | 74 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index 179fdc0e1..c8d013266 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.c @@ -59,7 +59,7 @@ static set *conv_types; static pmap *lowered_type; /** The types for the binop and unop intrinsics. */ -static ir_type *binop_tp_u, *binop_tp_s, *unop_tp_u, *unop_tp_s, *tp_s, *tp_u; +static ir_type *binop_tp_u, *binop_tp_s, *unop_tp_u, *unop_tp_s, *shiftop_tp_u, *shiftop_tp_s, *tp_s, *tp_u; /** the debug handle */ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) @@ -851,6 +851,51 @@ static void lower_Binop(ir_node *node, ir_mode *mode, lower_env_t *env) { env->entries[idx]->high_word = new_r_Proj(current_ir_graph, block, irn, mode, 1); } +/** + * Translate a Shiftop. + * + * Create an intrinsic Call. + */ +static void lower_Shiftop(ir_node *node, ir_mode *mode, lower_env_t *env) { + ir_node *block, *irn; + ir_node *in[3]; + dbg_info *dbg; + ir_type *mtp; + int idx; + node_entry_t *entry; + + irn = get_binop_left(node); + entry = env->entries[get_irn_idx(irn)]; + assert(entry); + + if (! entry->low_word) { + /* not ready yet, wait */ + pdeq_putr(env->waitq, node); + return; + } + + in[0] = entry->low_word; + in[1] = entry->high_word; + + /* The shift count is always mode_Iu in firm, so there is no need for lowering */ + in[2] = get_binop_right(node); + + dbg = get_irn_dbg_info(node); + block = get_nodes_block(node); + + mtp = mode_is_signed(mode) ? shiftop_tp_s : shiftop_tp_u; + irn = get_intrinsic_address(mtp, get_irn_op(node), mode, mode, block, env); + irn = new_rd_Call(dbg, current_ir_graph, block, get_irg_no_mem(current_ir_graph), + irn, 3, in, mtp); + set_irn_pinned(irn, get_irn_pinned(node)); + irn = new_r_Proj(current_ir_graph, block, irn, mode_T, pn_Call_T_result); + + idx = get_irn_idx(node); + assert(idx < env->n_entries); + env->entries[idx]->low_word = new_r_Proj(current_ir_graph, block, irn, mode, 0); + env->entries[idx]->high_word = new_r_Proj(current_ir_graph, block, irn, mode, 1); +} + /** * Translate an Unop. * @@ -1924,7 +1969,6 @@ void lower_dw_ops(const lwrdw_param_t *param) if (! binop_tp_u) { binop_tp_u = new_type_method(IDENT("binop_u_intrinsic"), 4, 2); - set_method_param_type(binop_tp_u, 0, tp_u); set_method_param_type(binop_tp_u, 1, tp_u); set_method_param_type(binop_tp_u, 2, tp_u); @@ -1941,6 +1985,23 @@ void lower_dw_ops(const lwrdw_param_t *param) set_method_res_type(binop_tp_s, 0, tp_s); set_method_res_type(binop_tp_s, 1, tp_s); } + if (! shiftop_tp_u) { + shiftop_tp_u = new_type_method(IDENT("shiftop_u_intrinsic"), 3, 2); + set_method_param_type(shiftop_tp_u, 0, tp_u); + set_method_param_type(shiftop_tp_u, 1, tp_u); + set_method_param_type(shiftop_tp_u, 2, tp_u); + set_method_res_type(shiftop_tp_u, 0, tp_u); + set_method_res_type(shiftop_tp_u, 1, tp_u); + } + if (! shiftop_tp_s) { + shiftop_tp_s = new_type_method(IDENT("shiftop_s_intrinsic"), 3, 2); + set_method_param_type(shiftop_tp_s, 0, tp_s); + set_method_param_type(shiftop_tp_s, 1, tp_s); + /* beware: shift count is always mode_Iu */ + set_method_param_type(shiftop_tp_s, 2, tp_u); + set_method_res_type(shiftop_tp_s, 0, tp_s); + set_method_res_type(shiftop_tp_s, 1, tp_s); + } if (! unop_tp_u) { unop_tp_u = new_type_method(IDENT("unop_u_intrinsic"), 2, 2); set_method_param_type(unop_tp_u, 0, tp_u); @@ -1967,6 +2028,7 @@ void lower_dw_ops(const lwrdw_param_t *param) #define LOWER2(op, fkt) op_##op->ops.generic = (op_func)fkt #define LOWER(op) LOWER2(op, lower_##op) #define LOWER_BIN(op) LOWER2(op, lower_Binop) +#define LOWER_SHIFT(op) LOWER2(op, lower_Shiftop) #define LOWER_UN(op) LOWER2(op, lower_Unop) LOWER(Load); @@ -1986,10 +2048,10 @@ void lower_dw_ops(const lwrdw_param_t *param) LOWER_BIN(Add); LOWER_BIN(Sub); LOWER_BIN(Mul); - LOWER_BIN(Shl); - LOWER_BIN(Shr); - LOWER_BIN(Shrs); - LOWER_BIN(Rot); + LOWER_SHIFT(Shl); + LOWER_SHIFT(Shr); + LOWER_SHIFT(Shrs); + LOWER_SHIFT(Rot); LOWER_UN(Minus); LOWER(DivMod); LOWER(Div); -- 2.20.1