Fix problems in splitting DF constants on big endian hosts & Davids patch for power...
authorMichael Meissner <meissner@gcc.gnu.org>
Thu, 13 Nov 1997 16:59:07 +0000 (16:59 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Thu, 13 Nov 1997 16:59:07 +0000 (16:59 +0000)
From-SVN: r16454

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index af1f8f2bb40b2459cd06c0ae4959dd5462f15993..984a0443655cf01a607b8312dfd1d6cc5c9ccad0 100644 (file)
@@ -1,3 +1,13 @@
+Thu Nov 13 11:07:41 1997  Michael Meissner  <meissner@cygnus.com>
+
+       * rs6000.c (num_insns_constant): Use REAL_VALUE_FROM_CONST_DOUBLE to
+       pick apart floating point values, instead of using CONST_DOUBLE_LOW
+       and CONST_DOUBLE_HIGH.
+
+       * rs6000.md (define_splits for DF constants): Use the appropriate
+       REAL_VALUE_* interface to pick apart DF floating point constants in
+       a machine independent fashion.
+
 Thu Nov 13 00:06:58 1997  J"orn Rennecke <amylaar@cygnus.co.uk>
 
        * fold-const.c (fold_truthop): When changing a one-bit comparison
@@ -66,6 +76,11 @@ Mon Nov 10 00:05:56 1997  Jeffrey A Law  (law@cygnus.com)
        * alias.c (MAX_ALIAS_LOOP_PASSES): Define.
        (init_alias_analysis): Break out of loops after MAX_ALIAS_LOOP_PASSES.
 
+Sun Nov  9 14:34:47 1997  David Edelsohn  <edelsohn@mhpcc.edu>
+
+        * rs6000.md (lshrdi3_power): Delete '&' from first alternative and
+        swap instruction order.
+
 Sun Nov  9 02:07:16 1997  Jeffrey A Law  (law@cygnus.com)
 
        * fixinc.svr4 (__STDC__): Add another case.
index aa128019dc539b95b6cd7010ed3014c04f3e615c..557ef8b92948ce7606442c4f33f6ebfb7176c921 100644 (file)
@@ -673,28 +673,47 @@ num_insns_constant (op, mode)
       return num_insns_constant_wide ((HOST_WIDE_INT)l);
     }
 
-  else if (GET_CODE (op) == CONST_DOUBLE && TARGET_32BIT)
-    return (num_insns_constant_wide (CONST_DOUBLE_LOW (op))
-           + num_insns_constant_wide (CONST_DOUBLE_HIGH (op)));
-
-  else if (GET_CODE (op) == CONST_DOUBLE && TARGET_64BIT)
+  else if (GET_CODE (op) == CONST_DOUBLE)
     {
-      HOST_WIDE_INT low  = CONST_DOUBLE_LOW (op);
-      HOST_WIDE_INT high = CONST_DOUBLE_HIGH (op);
-
-      if (high == 0 && (low & 0x80000000) == 0)
-       return num_insns_constant_wide (low);
+      HOST_WIDE_INT low;
+      HOST_WIDE_INT high;
+      long l[2];
+      REAL_VALUE_TYPE rv;
+      int endian = (WORDS_BIG_ENDIAN == 0);
 
-      else if (((high & 0xffffffff) == 0xffffffff)
-              && ((low & 0x80000000) != 0))
-       return num_insns_constant_wide (low);
+      if (mode == VOIDmode || mode == DImode)
+       {
+         high = CONST_DOUBLE_HIGH (op);
+         low  = CONST_DOUBLE_LOW (op);
+       }
+      else
+       {
+         REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
+         REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+         high = l[endian];
+         low  = l[1 - endian];
+       }
 
-      else if (low == 0)
-       return num_insns_constant_wide (high) + 1;
+      if (TARGET_32BIT)
+       return (num_insns_constant_wide (low)
+               + num_insns_constant_wide (high));
 
       else
-       return (num_insns_constant_wide (high)
-               + num_insns_constant_wide (low) + 1);
+       {
+         if (high == 0 && (low & 0x80000000) == 0)
+           return num_insns_constant_wide (low);
+
+         else if (((high & 0xffffffff) == 0xffffffff)
+                  && ((low & 0x80000000) != 0))
+           return num_insns_constant_wide (low);
+
+         else if (low == 0)
+           return num_insns_constant_wide (high) + 1;
+
+         else
+           return (num_insns_constant_wide (high)
+                   + num_insns_constant_wide (low) + 1);
+       }
     }
 
   else
index 29b6f22e98e50007a95363ebd02d288559300535..b9bd408e423160d36708b438e07e78e448d6e4ce 100644 (file)
   [(set_attr "length" "8")])
 
 (define_insn "lshrdi3_power"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
        (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
                     (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
    (clobber (match_scratch:SI 3 "=X,q,q,q"))]
   "TARGET_POWER"
   "@
-   {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
+   {s%A2i|s%A2wi} %L0,%1,%h2\;{cal %0,0(0)|li %0,0}
    sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
    sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
    sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
   "
 {
   int endian = (WORDS_BIG_ENDIAN == 0);
+  long l[2];
+  REAL_VALUE_TYPE rv;
+
+  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+  REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+
   operands[2] = operand_subword (operands[0], endian, 0, DFmode);
   operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
-
-#ifdef HOST_WORDS_BIG_ENDIAN
-  operands[4] = GEN_INT (CONST_DOUBLE_LOW  (operands[1]));
-  operands[5] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
-#else
-  operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
-  operands[5] = GEN_INT (CONST_DOUBLE_LOW  (operands[1]));
-#endif
+  operands[4] = GEN_INT (l[endian]);
+  operands[5] = GEN_INT (l[1 - endian]);
 }")
 
 (define_split
   HOST_WIDE_INT high;
   HOST_WIDE_INT low;
   int endian = (WORDS_BIG_ENDIAN == 0);
+  long l[2];
+  REAL_VALUE_TYPE rv;
   rtx high_reg = operand_subword (operands[0], endian, 0, DFmode);
   rtx low_reg  = operand_subword (operands[0], 1 - endian, 0, DFmode);
 
-#ifdef HOST_WORDS_BIG_ENDIAN
-  high = CONST_DOUBLE_LOW  (operands[1]);
-  low  = CONST_DOUBLE_HIGH (operands[1]);
-#else
-  high = CONST_DOUBLE_HIGH (operands[1]);
-  low  = CONST_DOUBLE_LOW  (operands[1]);
-#endif
+  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+  REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+  high = l[endian];
+  low  = l[1 - endian];
 
   if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
       || (low & 0xffff) == 0)
    (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
   "
 {
-  HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
-  HOST_WIDE_INT low  = CONST_DOUBLE_LOW  (operands[1]);
+  HOST_WIDE_INT high;
+  HOST_WIDE_INT low;
+  long l[2];
+  REAL_VALUE_TYPE rv;
   int endian = (WORDS_BIG_ENDIAN == 0);
 
+  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+  REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+  high = l[endian];
+  low  = l[1 - endian];
+
   operands[2] = operand_subword (operands[0], endian, 0, DFmode);
   operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
   operands[4] = GEN_INT (high & 0xffff0000);