From 77105a553a245389095f3849d2143cb90b5d77ff Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Tue, 18 Sep 2007 15:17:52 +0000 Subject: [PATCH] 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] --- ir/be/ia32/ia32_intrinsics.c | 116 +++++++++++++++++------------------ ir/lower/lower_dw.c | 102 +++++++++++++++++------------- 2 files changed, 114 insertions(+), 104 deletions(-) diff --git a/ir/be/ia32/ia32_intrinsics.c b/ir/be/ia32/ia32_intrinsics.c index 859f6f32c..034a08e92 100644 --- a/ir/be/ia32/ia32_intrinsics.c +++ b/ir/be/ia32/ia32_intrinsics.c @@ -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) { diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index 413233816..0404cfdb3 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.c @@ -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); assert(idx < env->n_entries); - env->entries[idx]->low_word = new_rd_Phi(dbg, irg, block, arity, inl, mode); + env->entries[idx]->low_word = new_rd_Phi(dbg, irg, block, arity, inl, mode_l); env->entries[idx]->high_word = new_rd_Phi(dbg, irg, block, arity, inh, mode); if (enq) { @@ -2254,6 +2263,13 @@ static void lower_ops(ir_node *node, void *env) DB((dbg, LEVEL_1, " %+F\n", node)); func(node, mode, lenv); + if (entry) { + ir_node *low_node = entry->low_word; + if (low_node && mode_is_signed(get_irn_mode(low_node))) { + ir_fprintf(stderr, "WARNING: lower mode of %+F of lowered %+F is signed\n", + low_node, node); + } + } } /* if */ } /* if */ } /* lower_ops */ @@ -2331,11 +2347,11 @@ void lower_dw_ops(const lwrdw_param_t *param) } /* if */ if (! binop_tp_s) { binop_tp_s = new_type_method(IDENT("binop_s_intrinsic"), 4, 2); - set_method_param_type(binop_tp_s, 0, tp_s); + set_method_param_type(binop_tp_s, 0, tp_u); set_method_param_type(binop_tp_s, 1, tp_s); - set_method_param_type(binop_tp_s, 2, tp_s); + set_method_param_type(binop_tp_s, 2, tp_u); set_method_param_type(binop_tp_s, 3, tp_s); - set_method_res_type(binop_tp_s, 0, tp_s); + set_method_res_type(binop_tp_s, 0, tp_u); set_method_res_type(binop_tp_s, 1, tp_s); } /* if */ if (! shiftop_tp_u) { @@ -2348,11 +2364,11 @@ void lower_dw_ops(const lwrdw_param_t *param) } /* if */ if (! shiftop_tp_s) { shiftop_tp_s = new_type_method(IDENT("shiftop_s_intrinsic"), 3, 2); - set_method_param_type(shiftop_tp_s, 0, tp_s); + set_method_param_type(shiftop_tp_s, 0, tp_u); set_method_param_type(shiftop_tp_s, 1, tp_s); /* beware: shift count is always mode_Iu */ set_method_param_type(shiftop_tp_s, 2, tp_u); - set_method_res_type(shiftop_tp_s, 0, tp_s); + set_method_res_type(shiftop_tp_s, 0, tp_u); set_method_res_type(shiftop_tp_s, 1, tp_s); } /* if */ if (! unop_tp_u) { @@ -2364,9 +2380,9 @@ void lower_dw_ops(const lwrdw_param_t *param) } /* if */ if (! unop_tp_s) { unop_tp_s = new_type_method(IDENT("unop_s_intrinsic"), 2, 2); - set_method_param_type(unop_tp_s, 0, tp_s); + set_method_param_type(unop_tp_s, 0, tp_u); set_method_param_type(unop_tp_s, 1, tp_s); - set_method_res_type(unop_tp_s, 0, tp_s); + set_method_res_type(unop_tp_s, 0, tp_u); set_method_res_type(unop_tp_s, 1, tp_s); } /* if */ -- 2.20.1