pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a constant can be...
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>
Sat, 10 Nov 2001 00:22:52 +0000 (00:22 +0000)
committerJeff Law <law@gcc.gnu.org>
Sat, 10 Nov 2001 00:22:52 +0000 (17:22 -0700)
* pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a
constant can be loaded in a single instruction to a register.  When
loading immediate constants, use PLUS instead of HIGH/LO_SUM.  Use
depdi for insertion of most significant 32-bits on 64-bit hosts.
* pa.h (LEGITIMATE_CONSTANT_P): Accept constants that can be built
with ldil/ldo/depdi instruction sequence on 64-bit hosts.
* pa.md: New addmove pattern for adding constant_int to HImode
register and moving result to HImode register.  Remove HImode HIGH
and LO_SUM patterns.

From-SVN: r46908

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md

index 6b78f4f56e2eae18e97ab3af2e98f4846039db52..783c2de91b13f4e038d5442fbad79f8dba30f4c4 100644 (file)
@@ -1,3 +1,15 @@
+2001-11-09  John David Anglin  <dave@hiauly1.hia.nrc.ca>
+
+       * pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a
+       constant can be loaded in a single instruction to a register.  When
+       loading immediate constants, use PLUS instead of HIGH/LO_SUM.  Use
+       depdi for insertion of most significant 32-bits on 64-bit hosts.
+       * pa.h (LEGITIMATE_CONSTANT_P): Accept constants that can be built
+       with ldil/ldo/depdi instruction sequence on 64-bit hosts.
+       * pa.md: New addmove pattern for adding constant_int to HImode
+       register and moving result to HImode register.  Remove HImode HIGH
+       and LO_SUM patterns.
+
 2001-11-09  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * Makefile.in: Update.
index f3d9070af6a9454cc7df9a9d30d0f6d4fde6fa0e..4a7e7dce3490d0aa24469d22c6a6fd797779fae6 100644 (file)
@@ -1394,7 +1394,8 @@ emit_move_sequence (operands, mode, scratch_reg)
   else if (register_operand (operand0, mode))
     {
       if (register_operand (operand1, mode)
-         || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
+         || (GET_CODE (operand1) == CONST_INT
+             && cint_ok_for_move (INTVAL (operand1)))
          || (operand1 == CONST0_RTX (mode))
          || (GET_CODE (operand1) == HIGH
              && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
@@ -1596,8 +1597,8 @@ emit_move_sequence (operands, mode, scratch_reg)
       else if (GET_CODE (operand1) != CONST_INT
               || ! cint_ok_for_move (INTVAL (operand1)))
        {
+         rtx extend = NULL_RTX;
          rtx temp;
-         int need_zero_extend = 0;
 
          if (TARGET_64BIT && GET_CODE (operand1) == CONST_INT
              && HOST_BITS_PER_WIDE_INT > 32
@@ -1606,15 +1607,18 @@ emit_move_sequence (operands, mode, scratch_reg)
              HOST_WIDE_INT val = INTVAL (operand1);
              HOST_WIDE_INT nval;
 
-             /* If the value is the same after a 32->64bit sign
-                extension, then we can use it as-is.  Else we will
-                need to sign extend the constant from 32->64bits
-                then zero extend the result from 32->64bits.  */
+             /* Extract the low order 32 bits of the value and sign extend.
+                If the new value is the same as the original value, we can
+                can use the original value as-is.  If the new value is
+                different, we use it and insert the most-significant 32-bits
+                of the original value into the final result.  */
              nval = ((val & (((HOST_WIDE_INT) 2 << 31) - 1))
                      ^ ((HOST_WIDE_INT) 1 << 31)) - ((HOST_WIDE_INT) 1 << 31);
              if (val != nval)
                {
-                 need_zero_extend = 1;
+#if HOST_BITS_PER_WIDE_INT > 32
+                 extend = GEN_INT (val >> 32);
+#endif
                  operand1 = GEN_INT (nval);
                }
            }
@@ -1624,19 +1628,44 @@ emit_move_sequence (operands, mode, scratch_reg)
          else
            temp = gen_reg_rtx (mode);
 
-         emit_insn (gen_rtx_SET (VOIDmode, temp,
-                                 gen_rtx_HIGH (mode, operand1)));
-         operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
-         emit_move_insn (operands[0], operands[1]);
+         if (GET_CODE (operand1) == CONST_INT)
+           {
+             /* Directly break constant into low and high parts.  This
+                provides better optimization opportunities because various
+                passes recognize constants split with PLUS but not LO_SUM.
+                We use a 14-bit signed low part except when the addition
+                of 0x4000 to the high part might change the sign of the
+                high part.  */
+             HOST_WIDE_INT value = INTVAL (operand1);
+             HOST_WIDE_INT low = value & 0x3fff;
+             HOST_WIDE_INT high = value & ~ 0x3fff;
+
+             if (low >= 0x2000)
+               {
+                 if (high == 0x7fffc000 || (mode == HImode && high == 0x4000))
+                   high += 0x2000;
+                 else
+                   high += 0x4000;
+               }
 
-         if (need_zero_extend)
+             low = value - high;
+
+             emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high)));
+             operands[1] = gen_rtx_PLUS (mode, temp, GEN_INT (low));
+           }
+         else
            {
-             emit_insn (gen_zero_extendsidi2 (operands[0],
-                                              gen_rtx_SUBREG (SImode,
-                                                              operands[0],
-                                                              4)));
+             emit_insn (gen_rtx_SET (VOIDmode, temp,
+                                     gen_rtx_HIGH (mode, operand1)));
+             operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
            }
 
+         emit_move_insn (operands[0], operands[1]);
+
+         if (extend != NULL_RTX)
+           emit_insn (gen_insv (operands[0], GEN_INT (32), const0_rtx,
+                                extend));
+
          return 1;
        }
     }
index 09f5bbc0241a7a5ddb297a8d42fcb6101e37e316..7abded2b7494e4a4906c31c13a40e26ba76b3a4a 100644 (file)
@@ -1106,8 +1106,8 @@ extern int may_call_alloca;
    && !(TARGET_64BIT && GET_CODE (X) == CONST_DOUBLE)          \
    && !(TARGET_64BIT && GET_CODE (X) == CONST_INT              \
        && !(HOST_BITS_PER_WIDE_INT <= 32                       \
-            || (INTVAL (X) >= (HOST_WIDE_INT) -1 << 31         \
-                && INTVAL (X) < (HOST_WIDE_INT) 1 << 32)       \
+            || (INTVAL (X) >= (HOST_WIDE_INT) -32 << 31        \
+                && INTVAL (X) < (HOST_WIDE_INT) 32 << 31)      \
             || cint_ok_for_move (INTVAL (X))))                 \
    && !function_label_operand (X, VOIDmode))
 
index f3757202afdb69dde02c2f68a243dc2b2742008d..3c86b27f33b99935196c379a5ecb0108f3a039cf 100644 (file)
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
-       (high:HI (match_operand 1 "const_int_operand" "")))]
+       (plus:HI (match_operand:HI 1 "register_operand" "r")
+                (match_operand 2 "const_int_operand" "J")))]
   ""
-  "ldil L'%G1,%0"
-  [(set_attr "type" "move")
-   (set_attr "length" "4")])
-
-(define_insn ""
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
-                  (match_operand 2 "const_int_operand" "")))]
-  ""
-  "ldo R'%G2(%1),%0"
-  [(set_attr "type" "move")
+  "ldo %2(%1),%0"
+  [(set_attr "type" "binary")
+   (set_attr "pa_combine_type" "addmove")
    (set_attr "length" "4")])
 
 (define_expand "movqi"