* alpha.c (alpha_emit_set_const_1): Handle narrow hosts better.
authorRichard Henderson <rth@cygnus.com>
Fri, 21 Nov 1997 02:08:30 +0000 (18:08 -0800)
committerJeff Law <law@gcc.gnu.org>
Fri, 21 Nov 1997 02:08:30 +0000 (19:08 -0700)
From-SVN: r16627

gcc/ChangeLog
gcc/config/alpha/alpha.c

index 47734de0db21817f12136c025785b8f07b7069d6..3771facf013d9f1dc8ce0e9624aa0038475cb4f0 100644 (file)
@@ -1,3 +1,7 @@
+Thu Nov 20 16:11:50 1997  Richard Henderson  <rth@cygnus.com>
+
+       * alpha.c (alpha_emit_set_const_1): Handle narrow hosts better.
+
 Thu Nov 20 16:11:50 1997  Klaus Kaempf  <kkaempf@progis.de>
 
        * alpha/vms.h (ASM_OUTPUT_ADDR_VEC_ELT): Add an L for the local label
index ae119f3cc989eb3547378d54c0640a0892b54f28..6155a1dc6a3e1b936cd8c2b3a82e3827f7047c8b 100644 (file)
@@ -904,12 +904,10 @@ alpha_emit_set_const_1 (target, mode, c, n)
 
   /* If this is a sign-extended 32-bit constant, we can do this in at most
      three insns, so do it if we have enough insns left.  We always have
-     a sign-extended 32-bit constant when compiling on a narrow machine. 
-     Note that we cannot handle the constant 0x80000000.  */
+     a sign-extended 32-bit constant when compiling on a narrow machine.   */
 
-  if ((HOST_BITS_PER_WIDE_INT != 64
-       || c >> 31 == -1 || c >> 31 == 0)
-      && c != 0x80000000U)
+  if (HOST_BITS_PER_WIDE_INT != 64
+      || c >> 31 == -1 || c >> 31 == 0)
     {
       HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
       HOST_WIDE_INT tmp1 = c - low;
@@ -928,7 +926,18 @@ alpha_emit_set_const_1 (target, mode, c, n)
        }
 
       if (c == low || (low == 0 && extra == 0))
-       return copy_to_suggested_reg (GEN_INT (c), target, mode);
+       {
+         /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
+            but that meant that we can't handle INT_MIN on 32-bit machines
+            (like NT/Alpha), because we recurse indefinitely through 
+            emit_move_insn to gen_movdi.  So instead, since we know exactly
+            what we want, create it explicitly.  */
+
+         if (target == NULL)
+           target = gen_reg_rtx (mode);
+         emit_insn (gen_rtx (SET, VOIDmode, target, GEN_INT (c)));
+         return target;
+       }
       else if (n >= 2 + (extra != 0))
        {
          temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
@@ -1006,9 +1015,11 @@ alpha_emit_set_const_1 (target, mode, c, n)
       /* Now try high-order zero bits.  Here we try the shifted-in bits as
         all zero and all ones.  Be careful to avoid shifting outside the
         mode and to avoid shifting outside the host wide int size.  */
+      /* On narrow hosts, don't shift a 1 into the high bit, since we'll
+        confuse the recursive call and set all of the high 32 bits.  */
 
       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
-                  - floor_log2 (c) - 1)) > 0)
+                  - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
        for (; bits > 0; bits--)
          if ((temp = alpha_emit_set_const (subtarget, mode,
                                            c << bits, i)) != 0