From: Christian Würdig Date: Wed, 17 May 2006 09:22:22 +0000 (+0000) Subject: added support for 64bit ABS X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=99424627e00ccca19218776ae345b9feace582ca;p=libfirm added support for 64bit ABS --- diff --git a/ir/be/ia32/ia32_intrinsics.c b/ir/be/ia32/ia32_intrinsics.c index ac1b4f3fb..4463fe748 100644 --- a/ir/be/ia32/ia32_intrinsics.c +++ b/ir/be/ia32/ia32_intrinsics.c @@ -262,6 +262,46 @@ static int map_Minus(ir_node *call, void *ctx) { return 1; } +/** + * Map a Abs (a_l, a_h) + */ +static int map_Abs(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_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, *sign, *sub_l, *sub_h; + + /* + Code inspired by gcc output :) (although gcc doubles the + operation for t1 as t2 and uses t1 for operations with low part + and t2 for operations with high part which is actually unnecessary + because t1 and t2 represent the same value) + + t1 = SHRS a_h, 31 + t2 = a_l ^ t1 + t3 = a_h ^ t1 + l_res = t2 - t1 + h_res = t3 - t1 - carry + + */ + + sign = new_rd_ia32_l_Shrs(dbg, irg, block, a_h, new_Const_long(h_res_mode, 31), h_res_mode); + sub_l = new_rd_ia32_l_Eor(dbg, irg, block, a_l, sign, l_res_mode); + sub_h = new_rd_ia32_l_Eor(dbg, irg, block, a_h, sign, h_res_mode); + l_res = new_rd_ia32_l_Sub(dbg, irg, block, sub_l, sign, l_res_mode); + h_res = new_rd_ia32_l_SubC(dbg, irg, block, sub_h, sign, l_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, @@ -299,6 +339,14 @@ entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op, ent = &i_ents[iro_Mul]; mapper = map_Mul; break; + case iro_Minus: + ent = &i_ents[iro_Minus]; + mapper = map_Minus; + break; + case iro_Abs: + ent = &i_ents[iro_Abs]; + mapper = map_Abs; + 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); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index c25cf1bcd..a996025fb 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -304,6 +304,12 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Eor" => { + "op_flags" => "C", + "comment" => "construct lowered Eor: Eor(a, b) = Eor(b, a) = a EOR b", + "arity" => 2 +}, + "Max" => { "irn_flags" => "R", "comment" => "construct Max: Max(a, b) = Max(b, a) = a > b ? a : b", diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index aebf27abb..119aa9043 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -2284,6 +2284,7 @@ GEN_LOWERED_OP(Add) GEN_LOWERED_OP(SubC) GEN_LOWERED_OP(Sub) GEN_LOWERED_OP(Mul) +GEN_LOWERED_OP(Eor) GEN_LOWERED_UNOP(Minus) @@ -2636,12 +2637,14 @@ void ia32_register_transformers(void) { GEN(Mux); GEN(Psi); + /* transform ops from intrinsic lowering */ GEN(ia32_l_Add); GEN(ia32_l_AddC); GEN(ia32_l_Sub); GEN(ia32_l_SubC); GEN(ia32_l_Minus); GEN(ia32_l_Mul); + GEN(ia32_l_Eor); GEN(ia32_l_MulS); GEN(ia32_l_Shl); GEN(ia32_l_Shr);