OSDN Git Service

* optabs.c (expand_binop): Sign-extend xop0 and xop1 from the
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 May 2001 19:47:15 +0000 (19:47 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 May 2001 19:47:15 +0000 (19:47 +0000)
widest mode in narrowing and widening operations.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41885 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/optabs.c

index aee84f7..9074e17 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 4068fa8..c6da815 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);