From 90f2e217df8deecb71f08af6bb28f9decd6795b0 Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Fri, 28 Sep 2007 21:34:25 +0000 Subject: [PATCH] Remove ia32_Sub64Bit. Replace it by Sub and Sbb. [r15990] --- ir/be/ia32/ia32_intrinsics.c | 69 +++++++++++++++++++++--------------- ir/be/ia32/ia32_spec.pl | 27 ++++++-------- ir/be/ia32/ia32_transform.c | 56 ++++++++++++++++++++++------- 3 files changed, 94 insertions(+), 58 deletions(-) diff --git a/ir/be/ia32/ia32_intrinsics.c b/ir/be/ia32/ia32_intrinsics.c index 034a08e92..2670b726e 100644 --- a/ir/be/ia32/ia32_intrinsics.c +++ b/ir/be/ia32/ia32_intrinsics.c @@ -118,27 +118,33 @@ static int map_Add(ir_node *call, void *ctx) { /** * Map a Sub (a_l, a_h, b_l, b_h) */ -static int map_Sub(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_mode = get_type_mode(get_method_res_type(method, 0)); - ir_mode *h_mode = get_type_mode(get_method_res_type(method, 1)); - ir_node *l_res, *h_res, *res; +static int map_Sub(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_mode = get_type_mode(get_method_res_type(method, 0)); + ir_mode *h_mode = get_type_mode(get_method_res_type(method, 1)); + ir_mode *mode_flags = ia32_reg_classes[CLASS_ia32_flags].mode; + ir_node *sub_low, *sub_high, *flags; + ir_node *l_res, *h_res; (void) ctx; /* l_res = a_l - b_l */ /* h_res = a_h - b_h - carry */ - res = new_rd_ia32_Sub64Bit(dbg, irg, block, a_l, a_h, b_l, b_h); - l_res = new_r_Proj(irg, block, res, l_mode, pn_ia32_Sub64Bit_low_res); - h_res = new_r_Proj(irg, block, res, h_mode, pn_ia32_Sub64Bit_high_res); + sub_low = new_rd_ia32_l_Sub(dbg, irg, block, a_l, b_l, mode_T); + flags = new_r_Proj(irg, block, sub_low, mode_flags, pn_ia32_flags); + sub_high = new_rd_ia32_l_Sbb(dbg, irg, block, a_h, b_h, flags, h_mode); + + l_res = new_r_Proj(irg, block, sub_low, l_mode, pn_ia32_res); + h_res = sub_high; resolve_call(call, l_res, h_res, irg, block); return 1; @@ -521,17 +527,20 @@ static int map_Minus(ir_node *call, void *ctx) { * 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_mode = get_type_mode(get_method_res_type(method, 0)); - ir_mode *h_mode = get_type_mode(get_method_res_type(method, 1)); - ir_node *l_res, *h_res, *sign, *sub_l, *sub_h, *res; + 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_mode = get_type_mode(get_method_res_type(method, 0)); + ir_mode *h_mode = get_type_mode(get_method_res_type(method, 1)); + ir_mode *mode_flags = ia32_reg_classes[CLASS_ia32_flags].mode; + ir_node *l_res, *h_res, *sign, *sub_l, *sub_h; ir_node *sign_l; + ir_node *l_sub; + ir_node *flags; (void) ctx; /* @@ -553,9 +562,11 @@ static int map_Abs(ir_node *call, void *ctx) { sign_l = new_rd_Conv(dbg, irg, block, sign, l_mode); sub_l = new_rd_Eor(dbg, irg, block, a_l, sign_l, l_mode); sub_h = new_rd_Eor(dbg, irg, block, a_h, sign, h_mode); - res = new_rd_ia32_Sub64Bit(dbg, irg, block, sub_l, sub_h, sign, sign); - l_res = new_r_Proj(irg, block, res, l_mode, pn_ia32_Sub64Bit_low_res); - h_res = new_r_Proj(irg, block, res, h_mode, pn_ia32_Sub64Bit_high_res); + + l_sub = new_rd_ia32_l_Sub(dbg, irg, block, sub_l, sign_l, mode_T); + l_res = new_r_Proj(irg, block, l_sub, l_mode, pn_ia32_res); + flags = new_r_Proj(irg, block, l_sub, mode_flags, pn_ia32_flags); + h_res = new_rd_ia32_l_Sbb(dbg, irg, block, sub_h, sign, flags, h_mode); resolve_call(call, l_res, h_res, irg, block); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 03be7632a..dc0c49d8e 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -566,7 +566,7 @@ XorMem8Bit => { Sub => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "none", "flags" ] }, ins => [ "base", "index", "mem", "left", "right" ], am => "full,binary", emit => '. sub%M %binop', @@ -596,8 +596,8 @@ SubMem8Bit => { }, Sbb => { - reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 !in_r5" ] }, - ins => [ "base", "index", "mem", "left", "right" ], + reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4 !in_r5" ] }, + ins => [ "base", "index", "mem", "left", "right", "eflags" ], am => "full,binary", emit => '. sbb%M %binop', units => [ "GP" ], @@ -605,19 +605,14 @@ Sbb => { modified_flags => $status_flags }, -Sub64Bit => { - irn_flags => "R", - arity => 4, - reg_req => { in => [ "gp", "gp", "gp", "gp" ], out => [ "!in", "!in" ] }, - emit => ' -. movl %S0, %D0 -. movl %S1, %D1 -. subl %SI2, %D0 -. sbbl %SI3, %D1 -', - outs => [ "low_res", "high_res" ], - units => [ "GP" ], - modified_flags => $status_flags +l_Sub => { + reg_req => { in => [ "none", "none" ], out => [ "none" ] }, + ins => [ "left", "right" ], +}, + +l_Sbb => { + reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, + ins => [ "left", "right", "eflags" ], }, IDiv => { diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index b8e14c7d1..48f401278 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -3828,18 +3828,47 @@ static ir_node *gen_ia32_l_IMul(ir_node *node) { return muls; } -static ir_node *gen_ia32_Sub64Bit(ir_node *node) -{ - ir_node *a_l = be_transform_node(get_irn_n(node, 0)); - ir_node *a_h = be_transform_node(get_irn_n(node, 1)); - ir_node *b_l = create_immediate_or_transform(get_irn_n(node, 2), 0); - ir_node *b_h = create_immediate_or_transform(get_irn_n(node, 3), 0); - ir_node *block = be_transform_node(get_nodes_block(node)); - dbg_info *dbgi = get_irn_dbg_info(node); - ir_graph *irg = current_ir_graph; - ir_node *new_op = new_rd_ia32_Sub64Bit(dbgi, irg, block, a_l, a_h, b_l, b_h); - SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); - return new_op; +static ir_node *gen_ia32_l_Sub(ir_node *node) { + ir_node *left = get_irn_n(node, n_ia32_l_Sub_left); + ir_node *right = get_irn_n(node, n_ia32_l_Sub_right); + ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub, 0); + + if(is_Proj(lowered)) { + lowered = get_Proj_pred(lowered); + } else { + assert(is_ia32_Sub(lowered)); + set_irn_mode(lowered, mode_T); + } + + return lowered; +} + +static ir_node *gen_ia32_l_Sbb(ir_node *node) { + ir_node *src_block = get_nodes_block(node); + ir_node *block = be_transform_node(src_block); + ir_node *op1 = get_irn_n(node, n_ia32_l_Sbb_left); + ir_node *op2 = get_irn_n(node, n_ia32_l_Sbb_right); + ir_node *flags = get_irn_n(node, n_ia32_l_Sbb_eflags); + ir_node *new_flags = be_transform_node(flags); + ir_graph *irg = current_ir_graph; + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *new_node; + ia32_address_mode_t am; + ia32_address_t *addr = &am.addr; + + match_arguments(&am, src_block, op1, op2, match_commutative); + + new_node = new_rd_ia32_Sbb(dbgi, irg, block, addr->base, addr->index, + addr->mem, am.new_op1, am.new_op2, new_flags); + set_am_attributes(new_node, &am); + /* we can't use source address mode anymore when using immediates */ + if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)) + set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none); + SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); + + new_node = fix_mem_proj(new_node, &am); + + return new_node; } /** @@ -4525,7 +4554,6 @@ static void register_transformers(void) GEN(IJmp); /* transform ops from intrinsic lowering */ - GEN(ia32_Sub64Bit); GEN(ia32_l_Add); GEN(ia32_l_Adc); GEN(ia32_l_Neg); @@ -4537,6 +4565,8 @@ static void register_transformers(void) GEN(ia32_l_SarDep); GEN(ia32_l_ShlD); GEN(ia32_l_ShrD); + GEN(ia32_l_Sub); + GEN(ia32_l_Sbb); GEN(ia32_l_vfdiv); GEN(ia32_l_vfprem); GEN(ia32_l_vfmul); -- 2.20.1