Commit 01b92965 authored by Christian Würdig's avatar Christian Würdig
Browse files

fixed 64Bit intrinsic mapping

parent e42cd381
...@@ -74,13 +74,14 @@ static int map_Add(ir_node *call, void *ctx) { ...@@ -74,13 +74,14 @@ static int map_Add(ir_node *call, void *ctx) {
ir_node *b_h = params[BINOP_Right_High]; ir_node *b_h = params[BINOP_Right_High];
ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); 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_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1));
ir_node *l_res, *h_res; ir_node *l_res, *h_res, *add;
/* l_res = a_l + b_l */ /* l_res = a_l + b_l */
l_res = new_rd_ia32_l_Add(dbg, irg, block, a_l, b_l, l_res_mode);
/* h_res = a_h + b_h + carry */ /* h_res = a_h + b_h + carry */
h_res = new_rd_ia32_l_AddC(dbg, irg, block, a_h, b_h, h_res_mode);
add = new_rd_ia32_Add64Bit(dbg, irg, block, a_l, a_h, b_l, b_h);
l_res = new_r_Proj(irg, block, add, l_res_mode, pn_ia32_Add64Bit_low_res);
h_res = new_r_Proj(irg, block, add, h_res_mode, pn_ia32_Add64Bit_high_res);
resolve_call(call, l_res, h_res, irg, block); resolve_call(call, l_res, h_res, irg, block);
return 1; return 1;
...@@ -101,16 +102,16 @@ static int map_Sub(ir_node *call, void *ctx) { ...@@ -101,16 +102,16 @@ static int map_Sub(ir_node *call, void *ctx) {
ir_node *b_h = params[BINOP_Right_High]; ir_node *b_h = params[BINOP_Right_High];
ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); 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_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1));
ir_node *l_res, *h_res; ir_node *l_res, *h_res, *res;
/* l_res = a_l - b_l */ /* l_res = a_l - b_l */
l_res = new_rd_ia32_l_Sub(dbg, irg, block, a_l, b_l, l_res_mode);
/* h_res = a_h - b_h - carry */ /* h_res = a_h - b_h - carry */
h_res = new_rd_ia32_l_SubC(dbg, irg, block, a_h, b_h, h_res_mode);
resolve_call(call, l_res, h_res, irg, block); 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_res_mode, pn_ia32_Sub64Bit_low_res);
h_res = new_r_Proj(irg, block, res, h_res_mode, pn_ia32_Sub64Bit_high_res);
resolve_call(call, l_res, h_res, irg, block);
return 1; return 1;
} }
...@@ -135,10 +136,10 @@ static int map_Shl(ir_node *call, void *ctx) { ...@@ -135,10 +136,10 @@ static int map_Shl(ir_node *call, void *ctx) {
/* l_res = SHL a_l, cnt */ /* l_res = SHL a_l, cnt */
h_res = new_rd_ia32_l_Shl(dbg, irg, block, a_l, cnt, h_res_mode); h_res = new_rd_ia32_l_Shl(dbg, irg, block, a_l, cnt, h_res_mode);
add_irn_dep(h_res, l_res); add_irn_dep(h_res, l_res);
resolve_call(call, l_res, h_res, irg, block); resolve_call(call, l_res, h_res, irg, block);
return 1; return 1;
} }
...@@ -163,10 +164,10 @@ static int map_Shr(ir_node *call, void *ctx) { ...@@ -163,10 +164,10 @@ static int map_Shr(ir_node *call, void *ctx) {
/* h_res = SHR a_h, cnt */ /* h_res = SHR a_h, cnt */
h_res = new_rd_ia32_l_Shr(dbg, irg, block, a_h, cnt, h_res_mode); h_res = new_rd_ia32_l_Shr(dbg, irg, block, a_h, cnt, h_res_mode);
add_irn_dep(h_res, l_res); add_irn_dep(h_res, l_res);
resolve_call(call, l_res, h_res, irg, block); resolve_call(call, l_res, h_res, irg, block);
return 1; return 1;
} }
...@@ -191,10 +192,10 @@ static int map_Shrs(ir_node *call, void *ctx) { ...@@ -191,10 +192,10 @@ static int map_Shrs(ir_node *call, void *ctx) {
/* h_res = SAR a_h, cnt */ /* h_res = SAR a_h, cnt */
h_res = new_rd_ia32_l_Shrs(dbg, irg, block, a_h, cnt, h_res_mode); h_res = new_rd_ia32_l_Shrs(dbg, irg, block, a_h, cnt, h_res_mode);
add_irn_dep(h_res, l_res); add_irn_dep(h_res, l_res);
resolve_call(call, l_res, h_res, irg, block); resolve_call(call, l_res, h_res, irg, block);
return 1; return 1;
} }
...@@ -225,6 +226,7 @@ static int map_Mul(ir_node *call, void *ctx) { ...@@ -225,6 +226,7 @@ static int map_Mul(ir_node *call, void *ctx) {
h_res = t2 + t3 h_res = t2 + t3
*/ */
mul = new_rd_ia32_l_MulS(dbg, irg, block, a_l, b_l); mul = new_rd_ia32_l_MulS(dbg, irg, block, a_l, b_l);
set_ia32_res_mode(mul, l_res_mode);
pEDX = new_rd_Proj(dbg, irg, block, mul, l_res_mode, pn_ia32_l_MulS_EDX); 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); l_res = new_rd_Proj(dbg, irg, block, mul, l_res_mode, pn_ia32_l_MulS_EAX);
...@@ -251,17 +253,17 @@ static int map_Minus(ir_node *call, void *ctx) { ...@@ -251,17 +253,17 @@ static int map_Minus(ir_node *call, void *ctx) {
ir_node *a_h = params[BINOP_Left_High]; ir_node *a_h = params[BINOP_Left_High];
ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); 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_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1));
ir_node *l_res, *h_res, *cnst; ir_node *l_res, *h_res, *cnst, *res;
/* l_res = 0 - a_l */ /* too bad: we need 0 in a register here */
l_res = new_rd_ia32_l_Minus(dbg, irg, block, a_l, l_res_mode); cnst = new_Const_long(h_res_mode, 0);
/* l_res = 0 - a_l */
/* h_res = 0 - a_h - carry */ /* h_res = 0 - a_h - carry */
/* too bad: we need 0 in a register here */ res = new_rd_ia32_Minus64Bit(dbg, irg, block, cnst, a_l, a_h);
cnst = new_Const_long(h_res_mode, 0); l_res = new_r_Proj(irg, block, res, l_res_mode, pn_ia32_Minus64Bit_low_res);
h_res = new_rd_ia32_l_SubC(dbg, irg, block, cnst, a_h, h_res_mode); h_res = new_r_Proj(irg, block, res, h_res_mode, pn_ia32_Minus64Bit_high_res);
add_irn_dep(h_res, l_res);
resolve_call(call, l_res, h_res, irg, block); resolve_call(call, l_res, h_res, irg, block);
...@@ -281,7 +283,7 @@ static int map_Abs(ir_node *call, void *ctx) { ...@@ -281,7 +283,7 @@ static int map_Abs(ir_node *call, void *ctx) {
ir_node *a_h = params[BINOP_Left_High]; ir_node *a_h = params[BINOP_Left_High];
ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0)); 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_mode *h_res_mode = get_type_mode(get_method_res_type(method, 1));
ir_node *l_res, *h_res, *sign, *sub_l, *sub_h; ir_node *l_res, *h_res, *sign, *sub_l, *sub_h, *res;
/* /*
Code inspired by gcc output :) (although gcc doubles the Code inspired by gcc output :) (although gcc doubles the
...@@ -300,9 +302,9 @@ static int map_Abs(ir_node *call, void *ctx) { ...@@ -300,9 +302,9 @@ static int map_Abs(ir_node *call, void *ctx) {
sign = new_rd_ia32_l_Shrs(dbg, irg, block, a_h, new_Const_long(h_res_mode, 31), h_res_mode); 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_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); 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); res = new_rd_ia32_Sub64Bit(dbg, irg, block, sub_l, sub_h, sign, sign);
h_res = new_rd_ia32_l_SubC(dbg, irg, block, sub_h, sign, l_res_mode); l_res = new_r_Proj(irg, block, res, l_res_mode, pn_ia32_Sub64Bit_low_res);
add_irn_dep(h_res, l_res); h_res = new_r_Proj(irg, block, res, h_res_mode, pn_ia32_Sub64Bit_high_res);
resolve_call(call, l_res, h_res, irg, block); resolve_call(call, l_res, h_res, irg, block);
......
...@@ -236,6 +236,20 @@ $comment_string = "/*"; ...@@ -236,6 +236,20 @@ $comment_string = "/*";
"outs" => [ "res", "M" ], "outs" => [ "res", "M" ],
}, },
"Add64Bit" => {
"irn_flags" => "R",
"comment" => "construct 64Bit Add: Add(a_l, a_h, b_l, b_h) = a_l + b_l; a_h + b_h + carry",
"arity" => 4,
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "!in", "!in" ] },
"emit" => '
. mov %D1, %S1 /* mov a_l into assigned l_res register */
. mov %D2, %S2 /* mov a_h into assigned h_res register */
. add %D1, %S3 /* a_l + b_l */
. adc %D2, %S4 /* a_h + b_h + carry */
',
"outs" => [ "low_res", "high_res" ],
},
"l_Add" => { "l_Add" => {
"op_flags" => "C", "op_flags" => "C",
"irn_flags" => "R", "irn_flags" => "R",
...@@ -386,6 +400,20 @@ $comment_string = "/*"; ...@@ -386,6 +400,20 @@ $comment_string = "/*";
"outs" => [ "res", "M" ], "outs" => [ "res", "M" ],
}, },
"Sub64Bit" => {
"irn_flags" => "R",
"comment" => "construct 64Bit Sub: Sub(a_l, a_h, b_l, b_h) = a_l - b_l; a_h - b_h - borrow",
"arity" => 4,
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "!in", "!in" ] },
"emit" => '
. mov %D1, %S1 /* mov a_l into assigned l_res register */
. mov %D2, %S2 /* mov a_h into assigned h_res register */
. sub %D1, %S3 /* a_l - b_l */
. sbb %D2, %S4 /* a_h - b_h - borrow */
',
"outs" => [ "low_res", "high_res" ],
},
"l_Sub" => { "l_Sub" => {
"irn_flags" => "R", "irn_flags" => "R",
"cmp_attr" => " return 1;\n", "cmp_attr" => " return 1;\n",
...@@ -576,6 +604,21 @@ else { ...@@ -576,6 +604,21 @@ else {
"outs" => [ "res", "M" ], "outs" => [ "res", "M" ],
}, },
"Minus64Bit" => {
"irn_flags" => "R",
"comment" => "construct 64Bit Minus: Minus(a_l, a_h, 0) = 0 - a_l; 0 - a_h - borrow",
"arity" => 4,
"reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in", "!in" ] },
"emit" => '
. mov %D1, %S1 /* l_res */
. mov %D2, %S1 /* h_res */
. sub %D1, %S2 /* 0 - a_l -> low_res */
. sbb %D2, %S3 /* 0 - a_h - borrow -> high_res */
',
"outs" => [ "low_res", "high_res" ],
},
"l_Minus" => { "l_Minus" => {
"cmp_attr" => " return 1;\n", "cmp_attr" => " return 1;\n",
"comment" => "construct lowered Minus: Minus(a) = -a", "comment" => "construct lowered Minus: Minus(a) = -a",
......
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