From: Christian Würdig Date: Mon, 15 May 2006 16:52:48 +0000 (+0000) Subject: added support for Shl, Shr, Shrs and Mul X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=119cc812b0b16092c6e1913b4b577d411b32b908;p=libfirm added support for Shl, Shr, Shrs and Mul --- diff --git a/ir/be/ia32/ia32_intrinsics.c b/ir/be/ia32/ia32_intrinsics.c index 15ac3dd84..4927e6533 100644 --- a/ir/be/ia32/ia32_intrinsics.c +++ b/ir/be/ia32/ia32_intrinsics.c @@ -112,6 +112,127 @@ static int map_Sub(ir_node *call, void *ctx) { return 1; } +/** + * Map a Shl (a_l, a_h, count) + */ +static int map_Shl(ir_node *call, void *ctx) { + ir_graph *irg = current_ir_graph; + dbg_info *dbg = get_irn_dbg_info(call); + ir_node *block = get_nodes_block(call); + ir_node **params = get_Call_param_arr(call); + ir_type *method = get_Call_type(call); + ir_node *a_l = params[BINOP_Left_Low]; + ir_node *a_h = params[BINOP_Left_High]; + ir_node *cnt = params[BINOP_Right_Low]; + ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); + ir_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1)); + ir_node *l_res, *h_res; + + /* h_res = SHLD a_h, a_l, cnt */ + l_res = new_rd_ia32_l_ShlD(dbg, irg, block, a_h, a_l, cnt, l_res_mode); + + /* l_res = SHL a_l, cnt */ + h_res = new_rd_ia32_l_Shl(dbg, irg, block, a_l, cnt, h_res_mode); + + resolve_call(call, l_res, h_res, irg, block); + + return 1; +} + +/** + * Map a Shr (a_l, a_h, count) + */ +static int map_Shr(ir_node *call, void *ctx) { + ir_graph *irg = current_ir_graph; + dbg_info *dbg = get_irn_dbg_info(call); + ir_node *block = get_nodes_block(call); + ir_node **params = get_Call_param_arr(call); + ir_type *method = get_Call_type(call); + ir_node *a_l = params[BINOP_Left_Low]; + ir_node *a_h = params[BINOP_Left_High]; + ir_node *cnt = params[BINOP_Right_Low]; + ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); + ir_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1)); + ir_node *l_res, *h_res; + + /* l_res = SHRD a_l, a_h, cnt */ + l_res = new_rd_ia32_l_ShrD(dbg, irg, block, a_l, a_h, cnt, l_res_mode); + + /* h_res = SHR a_h, cnt */ + h_res = new_rd_ia32_l_Shr(dbg, irg, block, a_h, cnt, h_res_mode); + + resolve_call(call, l_res, h_res, irg, block); + + return 1; +} + +/** + * Map a Shrs (a_l, a_h, count) + */ +static int map_Shrs(ir_node *call, void *ctx) { + ir_graph *irg = current_ir_graph; + dbg_info *dbg = get_irn_dbg_info(call); + ir_node *block = get_nodes_block(call); + ir_node **params = get_Call_param_arr(call); + ir_type *method = get_Call_type(call); + ir_node *a_l = params[BINOP_Left_Low]; + ir_node *a_h = params[BINOP_Left_High]; + ir_node *cnt = params[BINOP_Right_Low]; + ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); + ir_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1)); + ir_node *l_res, *h_res; + + /* l_res = SHRD a_l, a_h, cnt */ + l_res = new_rd_ia32_l_ShrD(dbg, irg, block, a_l, a_h, cnt, l_res_mode); + + /* h_res = SAR a_h, cnt */ + h_res = new_rd_ia32_l_Shrs(dbg, irg, block, a_h, cnt, h_res_mode); + + resolve_call(call, l_res, h_res, irg, block); + + return 1; +} + +/** + * Map a Mul (a_l, a_h, b_l, b_h) + */ +static int map_Mul(ir_node *call, void *ctx) { + ir_graph *irg = current_ir_graph; + dbg_info *dbg = get_irn_dbg_info(call); + ir_node *block = get_nodes_block(call); + ir_node **params = get_Call_param_arr(call); + ir_type *method = get_Call_type(call); + ir_node *a_l = params[BINOP_Left_Low]; + ir_node *a_h = params[BINOP_Left_High]; + ir_node *b_l = params[BINOP_Right_Low]; + ir_node *b_h = params[BINOP_Right_High]; + ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); + ir_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1)); + ir_node *l_res, *h_res, *mul, *pEDX, *add; + + /* + EDX:EAX = a_l * b_l + l_res = EAX + + t1 = b_l * a_h + t2 = t1 + EDX + t3 = a_l * b_h + h_res = t2 + t3 + */ + mul = new_rd_ia32_l_MulS(dbg, irg, block, a_l, b_l); + pEDX = new_rd_Proj(dbg, irg, block, mul, l_res_mode, pn_ia32_l_MulS_EDX); + l_res = new_rd_Proj(dbg, irg, block, mul, l_res_mode, pn_ia32_l_MulS_EAX); + + mul = new_rd_ia32_l_Mul(dbg, irg, block, a_h, b_l, h_res_mode); + add = new_rd_ia32_l_Add(dbg, irg, block, mul, pEDX, h_res_mode); + mul = new_rd_ia32_l_Mul(dbg, irg, block, a_l, b_h, h_res_mode); + h_res = new_rd_ia32_l_Add(dbg, irg, block, add, mul, h_res_mode); + + resolve_call(call, l_res, h_res, irg, block); + + return 1; +} + /* Ia32 implementation of intrinsic mapping. */ entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op, const ir_mode *imode, const ir_mode *omode, @@ -133,6 +254,22 @@ entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op, ent = &i_ents[iro_Sub]; mapper = map_Sub; break; + case iro_Shl: + ent = &i_ents[iro_Shl]; + mapper = map_Shl; + break; + case iro_Shr: + ent = &i_ents[iro_Shr]; + mapper = map_Shr; + break; + case iro_Shrs: + ent = &i_ents[iro_Shrs]; + mapper = map_Shrs; + break; + case iro_Mul: + ent = &i_ents[iro_Mul]; + mapper = map_Mul; + break; default: fprintf(stderr, "FIXME: unhandled op for ia32 intrinsic function %s\n", get_id_str(op->name)); return def_create_intrinsic_fkt(method, op, imode, omode, context);