aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-05-06 19:47:15 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2001-05-06 19:47:15 +0000
commit3c04502e2b0443114b2057dd2383308b3078cf7c (patch)
treef51487f0e2aa2816e161b63bfa5e94383466bc0d /gcc
parent7cbdf5753752f1c995114ac0b7f9071840458d88 (diff)
downloadgcc-3c04502e2b0443114b2057dd2383308b3078cf7c.zip
gcc-3c04502e2b0443114b2057dd2383308b3078cf7c.tar.gz
gcc-3c04502e2b0443114b2057dd2383308b3078cf7c.tar.bz2
optabs.c (expand_binop): Sign-extend xop0 and xop1 from the widest mode in narrowing and widening operations.
* optabs.c (expand_binop): Sign-extend xop0 and xop1 from the widest mode in narrowing and widening operations. From-SVN: r41885
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/optabs.c12
2 files changed, 14 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aee84f7..9074e17 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
2001-05-06 Alexandre Oliva <aoliva@redhat.com>
+ * optabs.c (expand_binop): Sign-extend xop0 and xop1 from the
+ widest mode in narrowing and widening operations.
+
* config/mips/mips.md: Sign extend CONST_INTs.
2001-05-06 Andreas Jaeger <aj@suse.de>
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 4068fa8..c6da815 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -725,13 +725,20 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
/* In case the insn wants input operands in modes different from
the result, convert the operands. It would seem that we
don't need to convert CONST_INTs, but we do, so that they're
- a properly sign-extended for their modes. */
+ a properly sign-extended for their modes; we choose the
+ widest mode between mode and mode[01], so that, in a widening
+ operation, we call convert_modes with different FROM and TO
+ modes, which ensures the value is sign-extended. Shift
+ operations are an exception, because the second operand needs
+ not be extended to the mode of the result. */
if (GET_MODE (op0) != mode0
&& mode0 != VOIDmode)
xop0 = convert_modes (mode0,
GET_MODE (op0) != VOIDmode
? GET_MODE (op0)
+ : GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode0)
+ ? mode
: mode0,
xop0, unsignedp);
@@ -740,6 +747,9 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
xop1 = convert_modes (mode1,
GET_MODE (op1) != VOIDmode
? GET_MODE (op1)
+ : (GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode1)
+ && ! shift_op)
+ ? mode
: mode1,
xop1, unsignedp);