Commit 77105a55 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Treat the lower word of lowered 64bit operations always as unsigned. Using the...

Treat the lower word of lowered 64bit operations always as unsigned. Using the same signedness as the high word is wrong (for example x < 0).

[r15868]
parent c5c1706b
......@@ -101,8 +101,6 @@ static int map_Add(ir_node *call, void *ctx) {
ir_node *l_res, *h_res;
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
/* l_res = a_l + b_l */
/* h_res = a_h + b_h + carry */
......@@ -131,17 +129,16 @@ static int map_Sub(ir_node *call, void *ctx) {
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;
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
/* 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, l_mode, pn_ia32_Sub64Bit_high_res);
h_res = new_r_Proj(irg, block, res, h_mode, pn_ia32_Sub64Bit_high_res);
resolve_call(call, l_res, h_res, irg, block);
return 1;
......@@ -160,12 +157,11 @@ static int map_Shl(ir_node *call, void *ctx) {
ir_node *a_h = params[BINOP_Left_High];
ir_node *cnt = params[BINOP_Right_Low];
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 *c_mode;
ir_node *l_res, *h_res, *irn, *cond, *upper, *n_block, *l1, *l2, *h1, *h2, *in[2];
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
if (is_Const(cnt)) {
/* the shift count is a const, create better code */
tarval *tv = get_Const_tarval(cnt);
......@@ -173,12 +169,13 @@ static int map_Shl(ir_node *call, void *ctx) {
if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
/* simplest case: shift only the lower bits. Note that there is no
need to reduce the constant here, this is done by the hardware. */
h_res = new_rd_Shl(dbg, irg, block, a_l, cnt, l_mode);
ir_node *conv = new_rd_Conv(dbg, irg, block, a_l, h_mode);
h_res = new_rd_Shl(dbg, irg, block, conv, cnt, h_mode);
l_res = new_rd_Const(dbg, irg, block, l_mode, get_mode_null(l_mode));
} else {
/* h_res = SHLD a_h, a_l, cnt */
h_res = new_rd_ia32_l_ShlD(dbg, irg, block, a_h, a_l, cnt, l_mode);
h_res = new_rd_ia32_l_ShlD(dbg, irg, block, a_h, a_l, cnt, h_mode);
/* l_res = SHL a_l, cnt */
l_res = new_rd_ia32_l_ShlDep(dbg, irg, block, a_l, cnt, h_res, l_mode);
......@@ -192,7 +189,7 @@ static int map_Shl(ir_node *call, void *ctx) {
upper = get_nodes_block(call);
/* h_res = SHLD a_h, a_l, cnt */
h1 = new_rd_ia32_l_ShlD(dbg, irg, upper, a_h, a_l, cnt, l_mode);
h1 = new_rd_ia32_l_ShlD(dbg, irg, upper, a_h, a_l, cnt, h_mode);
/* l_res = SHL a_l, cnt */
l1 = new_rd_ia32_l_ShlDep(dbg, irg, upper, a_l, cnt, h1, l_mode);
......@@ -209,7 +206,7 @@ static int map_Shl(ir_node *call, void *ctx) {
/* the block for cnt >= 32 */
n_block = new_rd_Block(dbg, irg, 1, &in[1]);
h2 = l1;
h2 = new_rd_Conv(dbg, irg, n_block, l1, h_mode);
l2 = new_r_Const(irg, n_block, l_mode, get_mode_null(l_mode));
in[1] = new_r_Jmp(irg, n_block);
......@@ -222,7 +219,7 @@ static int map_Shl(ir_node *call, void *ctx) {
in[0] = h1;
in[1] = h2;
h_res = new_r_Phi(irg, block, 2, in, l_mode);
h_res = new_r_Phi(irg, block, 2, in, h_mode);
set_irn_link(l_res, h_res);
set_irn_link(h_res, NULL);
......@@ -248,12 +245,11 @@ static int map_Shr(ir_node *call, void *ctx) {
ir_node *a_h = params[BINOP_Left_High];
ir_node *cnt = params[BINOP_Right_Low];
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 *c_mode;
ir_node *l_res, *h_res, *irn, *cond, *upper, *n_block, *l1, *l2, *h1, *h2, *in[2];
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
if (is_Const(cnt)) {
/* the shift count is a const, create better code */
tarval *tv = get_Const_tarval(cnt);
......@@ -261,14 +257,15 @@ static int map_Shr(ir_node *call, void *ctx) {
if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
/* simplest case: shift only the higher bits. Note that there is no
need to reduce the constant here, this is done by the hardware. */
h_res = new_rd_Const(dbg, irg, block, l_mode, get_mode_null(l_mode));
l_res = new_rd_Shr(dbg, irg, block, a_h, cnt, l_mode);
ir_node *conv = new_rd_Conv(dbg, irg, block, a_h, l_mode);
h_res = new_rd_Const(dbg, irg, block, h_mode, get_mode_null(h_mode));
l_res = new_rd_Shr(dbg, irg, block, conv, cnt, l_mode);
} else {
/* l_res = SHRD a_h:a_l, cnt */
l_res = new_rd_ia32_l_ShrD(dbg, irg, block, a_l, a_h, cnt, l_mode);
/* h_res = SHR a_h, cnt */
h_res = new_rd_ia32_l_ShrDep(dbg, irg, block, a_h, cnt, l_res, l_mode);
h_res = new_rd_ia32_l_ShrDep(dbg, irg, block, a_h, cnt, l_res, h_mode);
}
resolve_call(call, l_res, h_res, irg, block);
return 1;
......@@ -281,7 +278,7 @@ static int map_Shr(ir_node *call, void *ctx) {
l1 = new_rd_ia32_l_ShrD(dbg, irg, upper, a_l, a_h, cnt, l_mode);
/* h_res = SHR a_h, cnt */
h1 = new_rd_ia32_l_ShrDep(dbg, irg, upper, a_h, cnt, l1, l_mode);
h1 = new_rd_ia32_l_ShrDep(dbg, irg, upper, a_h, cnt, l1, h_mode);
c_mode = get_irn_mode(cnt);
irn = new_r_Const_long(irg, upper, c_mode, 32);
......@@ -295,8 +292,8 @@ static int map_Shr(ir_node *call, void *ctx) {
/* the block for cnt >= 32 */
n_block = new_rd_Block(dbg, irg, 1, &in[1]);
l2 = h1;
h2 = new_r_Const(irg, n_block, l_mode, get_mode_null(l_mode));
l2 = new_rd_Conv(dbg, irg, n_block, h1, l_mode);
h2 = new_r_Const(irg, n_block, l_mode, get_mode_null(h_mode));
in[1] = new_r_Jmp(irg, n_block);
set_irn_in(block, 2, in);
......@@ -308,7 +305,7 @@ static int map_Shr(ir_node *call, void *ctx) {
in[0] = h1;
in[1] = h2;
h_res = new_r_Phi(irg, block, 2, in, l_mode);
h_res = new_r_Phi(irg, block, 2, in, h_mode);
set_irn_link(l_res, h_res);
set_irn_link(h_res, NULL);
......@@ -334,12 +331,11 @@ static int map_Shrs(ir_node *call, void *ctx) {
ir_node *a_h = params[BINOP_Left_High];
ir_node *cnt = params[BINOP_Right_Low];
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 *c_mode;
ir_node *l_res, *h_res, *irn, *cond, *upper, *n_block, *l1, *l2, *h1, *h2, *in[2];
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
if (is_Const(cnt)) {
/* the shift count is a const, create better code */
tarval *tv = get_Const_tarval(cnt);
......@@ -347,16 +343,17 @@ static int map_Shrs(ir_node *call, void *ctx) {
if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
/* simplest case: shift only the higher bits. Note that there is no
need to reduce the constant here, this is done by the hardware. */
ir_mode *c_mode = get_irn_mode(cnt);
ir_node *conv = new_rd_Conv(dbg, irg, block, a_h, l_mode);
ir_mode *c_mode = get_irn_mode(cnt);
h_res = new_rd_Shrs(dbg, irg, block, a_h, new_r_Const_long(irg, block, c_mode, 31), l_mode);
l_res = new_rd_Shrs(dbg, irg, block, a_h, cnt, l_mode);
h_res = new_rd_Shrs(dbg, irg, block, a_h, new_r_Const_long(irg, block, c_mode, 31), h_mode);
l_res = new_rd_Shrs(dbg, irg, block, conv, cnt, l_mode);
} else {
/* l_res = SHRD a_h:a_l, cnt */
l_res = new_rd_ia32_l_ShrD(dbg, irg, block, a_l, a_h, cnt, l_mode);
/* h_res = SAR a_h, cnt */
h_res = new_rd_ia32_l_SarDep(dbg, irg, block, a_h, cnt, l_res, l_mode);
h_res = new_rd_ia32_l_SarDep(dbg, irg, block, a_h, cnt, l_res, h_mode);
}
resolve_call(call, l_res, h_res, irg, block);
return 1;
......@@ -369,7 +366,7 @@ static int map_Shrs(ir_node *call, void *ctx) {
l1 = new_rd_ia32_l_ShrD(dbg, irg, upper, a_l, a_h, cnt, l_mode);
/* h_res = SAR a_h, cnt */
h1 = new_rd_ia32_l_SarDep(dbg, irg, upper, a_h, cnt, l1, l_mode);
h1 = new_rd_ia32_l_SarDep(dbg, irg, upper, a_h, cnt, l1, h_mode);
c_mode = get_irn_mode(cnt);
irn = new_r_Const_long(irg, upper, c_mode, 32);
......@@ -383,8 +380,8 @@ static int map_Shrs(ir_node *call, void *ctx) {
/* the block for cnt >= 32 */
n_block = new_rd_Block(dbg, irg, 1, &in[1]);
l2 = h1;
h2 = new_rd_Shrs(dbg, irg, n_block, a_h, new_r_Const_long(irg, block, c_mode, 31), l_mode);
l2 = new_rd_Conv(dbg, irg, n_block, h1, l_mode);
h2 = new_rd_Shrs(dbg, irg, n_block, a_h, new_r_Const_long(irg, block, c_mode, 31), h_mode);
in[1] = new_r_Jmp(irg, n_block);
set_irn_in(block, 2, in);
......@@ -396,7 +393,7 @@ static int map_Shrs(ir_node *call, void *ctx) {
in[0] = h1;
in[1] = h2;
h_res = new_r_Phi(irg, block, 2, in, l_mode);
h_res = new_r_Phi(irg, block, 2, in, h_mode);
set_irn_link(l_res, h_res);
set_irn_link(h_res, NULL);
......@@ -423,10 +420,10 @@ static int map_Mul(ir_node *call, void *ctx) {
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, *mul, *pEDX, *add;
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
/*
EDX:EAX = a_l * b_l
l_res = EAX
......@@ -450,12 +447,12 @@ static int map_Mul(ir_node *call, void *ctx) {
if (is_Shrs(b_h) && get_Shrs_left(b_h) == b_l && c1 == get_Shrs_right(b_h)) {
/* b is a sign extend: it's a 32 * 32 = 64 signed multiplication */
mul = new_rd_ia32_l_IMul(dbg, irg, block, a_l, b_l);
h_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EDX);
h_res = new_rd_Proj(dbg, irg, block, mul, h_mode, pn_ia32_l_Mul_EDX);
l_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EAX);
goto end;
}
/* we rely here on Consts being on the right site */
/* we rely here on Consts being on the right side */
if (is_Const(b_h) && is_Const(b_l)) {
tarval *th = get_Const_tarval(b_h);
tarval *tl = get_Const_tarval(b_l);
......@@ -467,7 +464,7 @@ static int map_Mul(ir_node *call, void *ctx) {
if ((h == 0 && l >= 0) || (h == -1 && l < 0)) {
/* b is a sign extended const */
mul = new_rd_ia32_l_IMul(dbg, irg, block, a_l, b_l);
h_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EDX);
h_res = new_rd_Proj(dbg, irg, block, mul, h_mode, pn_ia32_l_Mul_EDX);
l_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EAX);
goto end;
......@@ -476,17 +473,18 @@ static int map_Mul(ir_node *call, void *ctx) {
}
}
}
}
mul = new_rd_ia32_l_Mul(dbg, irg, block, a_l, b_l);
pEDX = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EDX);
pEDX = new_rd_Proj(dbg, irg, block, mul, h_mode, pn_ia32_l_Mul_EDX);
l_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EAX);
mul = new_rd_Mul(dbg, irg, block, a_h, b_l, l_mode);
add = new_rd_Add(dbg, irg, block, mul, pEDX, l_mode);
mul = new_rd_Mul(dbg, irg, block, a_l, b_h, l_mode);
h_res = new_rd_Add(dbg, irg, block, add, mul, l_mode);
b_l = new_rd_Conv(dbg, irg, block, b_l, h_mode);
mul = new_rd_Mul( dbg, irg, block, a_h, b_l, h_mode);
add = new_rd_Add( dbg, irg, block, mul, pEDX, h_mode);
a_l = new_rd_Conv(dbg, irg, block, a_l, h_mode);
mul = new_rd_Mul( dbg, irg, block, a_l, b_h, h_mode);
h_res = new_rd_Add( dbg, irg, block, add, mul, h_mode);
end:
resolve_call(call, l_res, h_res, irg, block);
......@@ -506,14 +504,13 @@ static int map_Minus(ir_node *call, void *ctx) {
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, *res;
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
res = new_rd_ia32_Minus64Bit(dbg, irg, block, a_l, a_h);
l_res = new_r_Proj(irg, block, res, l_mode, pn_ia32_Minus64Bit_low_res);
h_res = new_r_Proj(irg, block, res, l_mode, pn_ia32_Minus64Bit_high_res);
h_res = new_r_Proj(irg, block, res, h_mode, pn_ia32_Minus64Bit_high_res);
resolve_call(call, l_res, h_res, irg, block);
......@@ -532,11 +529,11 @@ static int map_Abs(ir_node *call, void *ctx) {
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_node *sign_l;
(void) ctx;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
/*
Code inspired by gcc output :) (although gcc doubles the
operation for t1 as t2 and uses t1 for operations with low part
......@@ -552,12 +549,13 @@ static int map_Abs(ir_node *call, void *ctx) {
*/
/* TODO: give a hint to the backend somehow to not create a cltd here... */
sign = new_rd_Shrs(dbg, irg, block, a_h, new_Const_long(l_mode, 31), l_mode);
sub_l = new_rd_Eor(dbg, irg, block, a_l, sign, l_mode);
sub_h = new_rd_Eor(dbg, irg, block, a_h, sign, l_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, l_mode, pn_ia32_Sub64Bit_high_res);
sign = new_rd_Shrs(dbg, irg, block, a_h, new_Const_long(l_mode, 31), h_mode);
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);
resolve_call(call, l_res, h_res, irg, block);
......@@ -572,14 +570,12 @@ static int map_Abs(ir_node *call, void *ctx) {
static int map_Div(ir_node *call, void *ctx) {
ia32_intrinsic_env_t *env = ctx;
ir_type *method = get_Call_type(call);
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 *ptr;
ir_entity *ent;
symconst_symbol sym;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
if (mode_is_signed(l_mode)) {
if (mode_is_signed(h_mode)) {
/* 64bit signed Division */
ent = env->divdi3;
if (ent == NULL) {
......@@ -589,7 +585,7 @@ static int map_Div(ir_node *call, void *ctx) {
set_entity_ld_ident(ent, ID("__divdi3"));
}
} else {
/* 64bit signed Division */
/* 64bit unsigned Division */
ent = env->udivdi3;
if (ent == NULL) {
/* create library entity */
......@@ -610,14 +606,12 @@ static int map_Div(ir_node *call, void *ctx) {
static int map_Mod(ir_node *call, void *ctx) {
ia32_intrinsic_env_t *env = ctx;
ir_type *method = get_Call_type(call);
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, 0));
ir_node *ptr;
ir_entity *ent;
symconst_symbol sym;
assert(l_mode == get_type_mode(get_method_res_type(method, 1)) && "64bit lowered into different modes");
if (mode_is_signed(l_mode)) {
if (mode_is_signed(h_mode)) {
/* 64bit signed Modulo */
ent = env->moddi3;
if (ent == NULL) {
......
......@@ -171,7 +171,7 @@ static ir_type *get_conv_type(ir_mode *imode, ir_mode *omode, lower_env_t *env)
/* set param types and result types */
n_param = 0;
if (imode == env->params->high_signed) {
set_method_param_type(mtd, n_param++, tp_s);
set_method_param_type(mtd, n_param++, tp_u);
set_method_param_type(mtd, n_param++, tp_s);
} else if (imode == env->params->high_unsigned) {
set_method_param_type(mtd, n_param++, tp_u);
......@@ -183,7 +183,7 @@ static ir_type *get_conv_type(ir_mode *imode, ir_mode *omode, lower_env_t *env)
n_res = 0;
if (omode == env->params->high_signed) {
set_method_res_type(mtd, n_res++, tp_s);
set_method_res_type(mtd, n_res++, tp_u);
set_method_res_type(mtd, n_res++, tp_s);
} else if (omode == env->params->high_unsigned) {
set_method_res_type(mtd, n_res++, tp_u);
......@@ -335,11 +335,12 @@ static void lower_Const(ir_node *node, ir_mode *mode, lower_env_t *env) {
ir_node *block = get_nodes_block(node);
int idx;
ir_graph *irg = current_ir_graph;
ir_mode *low_mode = env->params->low_unsigned;
tv = get_Const_tarval(node);
tv_l = tarval_convert_to(tv, mode);
low = new_rd_Const(dbg, irg, block, mode, tv_l);
tv_l = tarval_convert_to(tv, low_mode);
low = new_rd_Const(dbg, irg, block, low_mode, tv_l);
tv_h = tarval_convert_to(tarval_shrs(tv, env->tv_mode_bits), mode);
high = new_rd_Const(dbg, irg, block, mode, tv_h);
......@@ -594,8 +595,8 @@ static void lower_Div(ir_node *node, ir_mode *mode, lower_env_t *env) {
case pn_Div_res: /* Result of computation. */
idx = get_irn_idx(proj);
assert(idx < env->n_entries);
env->entries[idx]->low_word = new_r_Proj(current_ir_graph, block, irn, mode, 0);
env->entries[idx]->high_word = new_r_Proj(current_ir_graph, block, irn, mode, 1);
env->entries[idx]->low_word = new_r_Proj(current_ir_graph, block, irn, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(current_ir_graph, block, irn, mode, 1);
break;
default:
assert(0 && "unexpected Proj number");
......@@ -674,8 +675,8 @@ static void lower_Mod(ir_node *node, ir_mode *mode, lower_env_t *env) {
case pn_Mod_res: /* Result of computation. */
idx = get_irn_idx(proj);
assert(idx < env->n_entries);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
break;
default:
assert(0 && "unexpected Proj number");
......@@ -781,13 +782,13 @@ static void lower_DivMod(ir_node *node, ir_mode *mode, lower_env_t *env) {
case pn_DivMod_res_div: /* Result of Div. */
idx = get_irn_idx(proj);
assert(idx < env->n_entries);
env->entries[idx]->low_word = new_r_Proj(irg, block, resDiv, mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, resDiv, mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, resDiv, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, resDiv, mode, 1);
break;
case pn_DivMod_res_mod: /* Result of Mod. */
idx = get_irn_idx(proj);
env->entries[idx]->low_word = new_r_Proj(irg, block, resMod, mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, resMod, mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, resMod, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, resMod, mode, 1);
break;
default:
assert(0 && "unexpected Proj number");
......@@ -851,8 +852,8 @@ static void lower_Binop(ir_node *node, ir_mode *mode, lower_env_t *env) {
idx = get_irn_idx(node);
assert(idx < env->n_entries);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
} /* lower_Binop */
/**
......@@ -898,8 +899,8 @@ static void lower_Shiftop(ir_node *node, ir_mode *mode, lower_env_t *env) {
idx = get_irn_idx(node);
assert(idx < env->n_entries);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
} /* lower_Shiftop */
/**
......@@ -1076,8 +1077,8 @@ static void lower_Unop(ir_node *node, ir_mode *mode, lower_env_t *env) {
idx = get_irn_idx(node);
assert(idx < env->n_entries);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, env->params->low_unsigned, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
} /* lower_Unop */
/**
......@@ -1397,7 +1398,8 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env) {
static void lower_Conv_to_Ls(ir_node *node, lower_env_t *env) {
ir_node *op = get_Conv_op(node);
ir_mode *imode = get_irn_mode(op);
ir_mode *dst_mode = env->params->low_signed;
ir_mode *dst_mode_l = env->params->low_unsigned;
ir_mode *dst_mode_h = env->params->low_signed;
int idx = get_irn_idx(node);
ir_graph *irg = current_ir_graph;
ir_node *block = get_nodes_block(node);
......@@ -1415,20 +1417,20 @@ static void lower_Conv_to_Ls(ir_node *node, lower_env_t *env) {
pdeq_putr(env->waitq, node);
return;
} /* if */
env->entries[idx]->low_word = new_rd_Conv(dbg, irg, block, env->entries[op_idx]->low_word, dst_mode);
env->entries[idx]->high_word = new_rd_Conv(dbg, irg, block, env->entries[op_idx]->high_word, dst_mode);
env->entries[idx]->low_word = new_rd_Conv(dbg, irg, block, env->entries[op_idx]->low_word, dst_mode_l);
env->entries[idx]->high_word = new_rd_Conv(dbg, irg, block, env->entries[op_idx]->high_word, dst_mode_h);
} else {
/* simple case: create a high word */
if (imode != dst_mode)
op = new_rd_Conv(dbg, irg, block, op, dst_mode);
if (imode != dst_mode_l)
op = new_rd_Conv(dbg, irg, block, op, dst_mode_l);
env->entries[idx]->low_word = op;
if (mode_is_signed(imode)) {
env->entries[idx]->high_word = new_rd_Shrs(dbg, irg, block, op,
new_Const_long(mode_Iu, get_mode_size_bits(dst_mode) - 1), dst_mode);
new_Const_long(mode_Iu, get_mode_size_bits(dst_mode_h) - 1), dst_mode_h);
} else {
env->entries[idx]->high_word = new_Const(dst_mode, get_mode_null(dst_mode));
env->entries[idx]->high_word = new_Const(dst_mode_h, get_mode_null(dst_mode_h));
} /* if */
} /* if */
} else {
......@@ -1441,8 +1443,8 @@ static void lower_Conv_to_Ls(ir_node *node, lower_env_t *env) {
set_irn_pinned(call, get_irn_pinned(node));
irn = new_r_Proj(irg, block, call, mode_T, pn_Call_T_result);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, dst_mode, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, dst_mode, 1);
env->entries[idx]->low_word = new_r_Proj(irg, block, irn, dst_mode_l, 0);
env->entries[idx]->high_word = new_r_Proj(irg, block, irn, dst_mode_h, 1);
} /* if */
} /* lower_Conv_to_Ls */
......@@ -1665,7 +1667,7 @@ static ir_type *lower_mtp(ir_type *mtp, lower_env_t *env) {
ir_mode *mode = get_type_mode(tp);
if (mode == env->params->high_signed) {
set_method_param_type(res, n_param++, tp_s);
set_method_param_type(res, n_param++, tp_u);
set_method_param_type(res, n_param++, tp_s);
} else if (mode == env->params->high_unsigned) {
set_method_param_type(res, n_param++, tp_u);
......@@ -1684,7 +1686,7 @@ static ir_type *lower_mtp(ir_type *mtp, lower_env_t *env) {
ir_mode *mode = get_type_mode(tp);
if (mode == env->params->high_signed) {
set_method_res_type(res, n_res++, tp_s);
set_method_res_type(res, n_res++, tp_u);
set_method_res_type(res, n_res++, tp_s);
} else if (mode == env->params->high_unsigned) {
set_method_res_type(res, n_res++, tp_u);
......@@ -1832,6 +1834,8 @@ static void lower_Start(ir_node *node, ir_mode *mode, lower_env_t *env) {
idx = get_irn_idx(proj);
if (env->entries[idx]) {
ir_mode *low_mode = env->params->low_unsigned;
mode = get_irn_mode(proj);
if (mode == env->params->high_signed) {
......@@ -1842,7 +1846,7 @@ static void lower_Start(ir_node *node, ir_mode *mode, lower_env_t *env) {
dbg = get_irn_dbg_info(proj);
env->entries[idx]->low_word =
new_rd_Proj(dbg, irg, get_nodes_block(proj), args, mode, new_projs[proj_nr]);
new_rd_Proj(dbg, irg, get_nodes_block(proj), args, low_mode, new_projs[proj_nr]);
env->entries[idx]->high_word =
new_rd_Proj(dbg, irg, get_nodes_block(proj), args, mode, new_projs[proj_nr] + 1);
} /* if */
......@@ -1964,6 +1968,7 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env) {
idx = get_irn_idx(proj);
if (env->entries[idx]) {
ir_mode *mode = get_irn_mode(proj);
ir_mode *low_mode = env->params->low_unsigned;
dbg_info *dbg;
if (mode == env->params->high_signed) {
......@@ -1974,7 +1979,7 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env) {
dbg = get_irn_dbg_info(proj);
env->entries[idx]->low_word =
new_rd_Proj(dbg, irg, get_nodes_block(proj), results, mode, res_numbers[proj_nr]);
new_rd_Proj(dbg, irg, get_nodes_block(proj), results, low_mode, res_numbers[proj_nr]);
env->entries[idx]->high_word =
new_rd_Proj(dbg, irg, get_nodes_block(proj), results, mode, res_numbers[proj_nr] + 1);
} /* if */
......@@ -2002,8 +2007,11 @@ static void lower_Unknown(ir_node *node, ir_mode *mode, lower_env_t *env) {
* First step: just create two templates
*/
static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) {
ir_mode *mode_l = env->params->low_unsigned;
ir_graph *irg = current_ir_graph;
ir_node *block, *unk;
ir_node *block;
ir_node *unk_l;
ir_node *unk_h;
ir_node **inl, **inh;
dbg_info *dbg;
int idx, i, arity = get_Phi_n_preds(phi);
......@@ -2033,7 +2041,8 @@ static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) {
/* first create a new in array */
NEW_ARR_A(ir_node *, inl, arity);
NEW_ARR_A(ir_node *, inh, arity);
unk = new_r_Unknown(irg, mode);
unk_l = new_r_Unknown(irg, mode_l);
unk_h = new_r_Unknown(irg, mode);
for (i = 0; i < arity; ++i) {
ir_node *pred = get_Phi_pred(phi, i);
......@@ -2043,8 +2052,8 @@ static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) {
inl[i] = env->entries[idx]->low_word;
inh[i] = env->entries[idx]->high_word;
} else {
inl[i] = unk;
inh[i] = unk;
inl[i] = unk_l;
inh[i] = unk_h;
enq = 1;
} /* if */
} /* for */
......@@ -2054,7 +2063,7 @@ static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) {
idx = get_irn_idx(phi);