From 12342f90557915d42293a1cec341f4f8f0c426bb Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Wed, 30 Dec 1992 07:08:14 +0000 Subject: [PATCH] (expand_expr): In NOP_EXPR case, truncate and reextend integer constants. From-SVN: r2987 --- gcc/expr.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/gcc/expr.c b/gcc/expr.c index 6265f21c039..3e3e6ce62b1 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4134,7 +4134,43 @@ expand_expr (exp, target, tmode, modifier) return target; } op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, 0); - if (GET_MODE (op0) == mode || GET_MODE (op0) == VOIDmode) + if (GET_MODE (op0) == mode) + return op0; + /* If arg is a constant integer being extended from a narrower mode, + we must really truncate to get the extended bits right. Otherwise + (unsigned long) (unsigned char) ("\377"[0]) + would come out as ffffffff. */ + if (GET_MODE (op0) == VOIDmode + && (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))) + < GET_MODE_BITSIZE (mode))) + { + /* MODE must be narrower than HOST_BITS_PER_INT. */ + int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))); + + if (width < HOST_BITS_PER_WIDE_INT) + { + HOST_WIDE_INT val = (GET_CODE (op0) == CONST_INT ? INTVAL (op0) + : CONST_DOUBLE_LOW (op0)); + if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))) + || !(val & ((HOST_WIDE_INT) 1 << (width - 1)))) + val &= ((HOST_WIDE_INT) 1 << width) - 1; + else + val |= ~(((HOST_WIDE_INT) 1 << width) - 1); + + op0 = GEN_INT (val); + } + else + { + op0 = (simplify_unary_operation + ((TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))) + ? ZERO_EXTEND : SIGN_EXTEND), + mode, op0, + TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))); + if (op0 == 0) + abort (); + } + } + if (GET_MODE (op0) == VOIDmode) return op0; if (modifier == EXPAND_INITIALIZER) return gen_rtx (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, mode, op0); -- 2.30.2