optabs.c (expand_binop): Sign-extend xop0 and xop1 from the widest mode in narrowing...
authorAlexandre Oliva <aoliva@redhat.com>
Sun, 6 May 2001 19:47:15 +0000 (19:47 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sun, 6 May 2001 19:47:15 +0000 (19:47 +0000)
* optabs.c (expand_binop): Sign-extend xop0 and xop1 from the
widest mode in narrowing and widening operations.

From-SVN: r41885

gcc/ChangeLog
gcc/optabs.c

index aee84f7d42f9ed38929a89e3b91a65be210c83f2..9074e177d29e2d13d2a4c5b746163550089f4493 100644 (file)
@@ -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>
index 4068fa863db14c373c95b2f52c758201b9524ecd..c6da81592fda9b265f5c9d42830142d709a2d06c 100644 (file)
@@ -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);