Commit 90f2e217 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Remove ia32_Sub64Bit. Replace it by Sub and Sbb.

[r15990]
parent 92c62afa
......@@ -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);
......
......@@ -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 => {
......
......@@ -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);
......
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