(standard_68881_constant_p): Initialize REAL_VALUE_TYPE binary constants from decimal...
authorRichard Stallman <rms@gnu.org>
Wed, 31 Mar 1993 21:12:24 +0000 (21:12 +0000)
committerRichard Stallman <rms@gnu.org>
Wed, 31 Mar 1993 21:12:24 +0000 (21:12 +0000)
(standard_68881_constant_p): Initialize REAL_VALUE_TYPE
binary constants from decimal values.  Use REAL_VALUE_... macros.
(standard_sun_fpa_constant_p): Likewise.
(print_operand, floating_exact_log2): Use REAL_VALUE_... macros.
(init_68881_table): New function.

From-SVN: r3971

gcc/config/m68k/m68k.c

index a5d210cd4934a153d890f4567c36c451bb54f275..8939e98535bccf8b87ecc3ae5cca83d936e89470 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for Motorola 68000 family.
-   Copyright (C) 1987 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -1246,43 +1246,89 @@ output_move_const_single (operands)
    The value, anded with 0xff, gives the code to use in fmovecr
    to get the desired constant.  */
 
-/* ??? This code should be fixed for cross-compilation. */
+/* This code has been fixed for cross-compilation. */
+  
+static int inited_68881_table = 0;
+
+char *strings_68881[7] = {
+  "0.0",
+  "1.0",
+  "10.0",
+  "100.0",
+  "10000.0",
+  "1e8",
+  "1e16"
+  };
+
+int codes_68881[7] = {
+  0x0f,
+  0x32,
+  0x33,
+  0x34,
+  0x35,
+  0x36,
+  0x37
+  };
+
+REAL_VALUE_TYPE values_68881[7];
+
+/* Set up values_68881 array by converting the decimal values
+   strings_68881 to binary.   */
+
+void
+init_68881_table ()
+{
+  int i;
+  REAL_VALUE_TYPE r;
+  enum machine_mode mode;
+
+  mode = DFmode;
+  for (i = 0; i < 7; i++)
+    {
+      if (i == 6)
+        mode = SFmode;
+      r = REAL_VALUE_ATOF (strings_68881[i], mode);
+      values_68881[i] = r;
+    }
+  inited_68881_table = 1;
+}
 
 int
 standard_68881_constant_p (x)
      rtx x;
 {
-  register double d;
+  REAL_VALUE_TYPE r;
+  int i;
+  enum machine_mode mode;
 
   /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
   if (TARGET_68040)
     return 0;
 
+#ifndef REAL_ARITHMETIC
 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
   if (! flag_pretend_float)
     return 0;
+#endif
 #endif
 
-  REAL_VALUE_FROM_CONST_DOUBLE (d, x);
-
-  if (d == 0)
-    return 0x0f;
-  /* Note: there are various other constants available
-     but it is a nuisance to put in their values here.  */
-  if (d == 1)
-    return 0x32;
-  if (d == 10)
-    return 0x33;
-  if (d == 100)
-    return 0x34;
-  if (d == 10000)
-    return 0x35;
-  if (d == 1e8)
-    return 0x36;
+  if (! inited_68881_table)
+    init_68881_table ();
+
+  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+
+  for (i = 0; i < 6; i++)
+    {
+      if (REAL_VALUES_EQUAL (r, values_68881[i]))
+        return (codes_68881[i]);
+    }
+  
   if (GET_MODE (x) == SFmode)
     return 0;
-  if (d == 1e16)
-    return 0x37;
+
+  if (REAL_VALUES_EQUAL (r, values_68881[6]))
+    return (codes_68881[6]);
+
   /* larger powers of ten in the constants ram are not used
      because they are not equal to a `double' C constant.  */
   return 0;
@@ -1295,25 +1341,29 @@ int
 floating_exact_log2 (x)
      rtx x;
 {
-  register double d, d1;
+  REAL_VALUE_TYPE r, r1;
   int i;
 
+#ifndef REAL_ARITHMETIC
 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
   if (! flag_pretend_float)
     return 0;
+#endif
 #endif
 
-  REAL_VALUE_FROM_CONST_DOUBLE (d, x);
+  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
 
-  if (! (d > 0))
+  if (REAL_VALUES_LESS (r, dconst0))
     return 0;
 
-  for (d1 = 1.0, i = 0; d1 < d; d1 *= 2.0, i++)
-    ;
-
-  if (d == d1)
-    return i;
-
+  i = 0;
+  while (REAL_VALUES_LESS (r1, r))
+    {
+      r1 = REAL_VALUE_LDEXP (dconst1, i);
+      if (REAL_VALUES_EQUAL (r1, r))
+        return i;
+      i = i + 1;
+    }
   return 0;
 }
 \f
@@ -1322,131 +1372,161 @@ floating_exact_log2 (x)
    from the Sun FPA's constant RAM.
    The value returned, anded with 0x1ff, gives the code to use in fpmove
    to get the desired constant. */
-#define S_E (2.718281745910644531)
-#define D_E (2.718281828459045091)
-#define S_PI (3.141592741012573242)
-#define D_PI (3.141592653589793116)
-#define S_SQRT2 (1.414213538169860840)
-#define D_SQRT2 (1.414213562373095145)
-#define S_LOG2ofE (1.442695021629333496)
-#define D_LOG2ofE (1.442695040888963387)
-#define S_LOG2of10 (3.321928024291992188)
-#define D_LOG2of10 (3.321928024887362182)
-#define S_LOGEof2 (0.6931471824645996094)
-#define D_LOGEof2 (0.6931471805599452862)
-#define S_LOGEof10 (2.302585124969482442)
-#define D_LOGEof10 (2.302585092994045901)
-#define S_LOG10of2 (0.3010300099849700928)
-#define D_LOG10of2 (0.3010299956639811980)
-#define S_LOG10ofE (0.4342944920063018799)
-#define D_LOG10ofE (0.4342944819032518167)
-
-/* This code should be fixed for cross-compilation. */
+
+static int inited_FPA_table = 0;
+
+char *strings_FPA[38] = {
+/* small rationals */
+  "0.0",
+  "1.0",
+  "0.5",
+  "-1.0",
+  "2.0",
+  "3.0",
+  "4.0",
+  "8.0",
+  "0.25",
+  "0.125",
+  "10.0",
+  "-0.5",
+/* Decimal equivalents of double precision values */
+  "2.718281828459045091", /* D_E */
+  "6.283185307179586477", /* 2 pi */
+  "3.141592653589793116", /* D_PI */
+  "1.570796326794896619", /* pi/2 */
+  "1.414213562373095145", /* D_SQRT2 */
+  "0.7071067811865475244", /* 1/sqrt(2) */
+  "-1.570796326794896619", /* -pi/2 */
+  "1.442695040888963387", /* D_LOG2ofE */
+  "3.321928024887362182", /* D_LOG2of10 */
+  "0.6931471805599452862", /* D_LOGEof2 */
+  "2.302585092994045901", /* D_LOGEof10 */
+  "0.3010299956639811980", /* D_LOG10of2 */
+  "0.4342944819032518167", /* D_LOG10ofE */
+/* Decimal equivalents of single precision values */
+  "2.718281745910644531", /* S_E */
+  "6.283185307179586477", /* 2 pi */
+  "3.141592741012573242", /* S_PI */
+  "1.570796326794896619", /* pi/2 */
+  "1.414213538169860840", /* S_SQRT2 */
+  "0.7071067811865475244", /* 1/sqrt(2) */
+  "-1.570796326794896619", /* -pi/2 */
+  "1.442695021629333496", /* S_LOG2ofE */
+  "3.321928024291992188", /* S_LOG2of10 */
+  "0.6931471824645996094", /* S_LOGEof2 */
+  "2.302585124969482442", /* S_LOGEof10 */
+  "0.3010300099849700928", /* S_LOG10of2 */
+  "0.4342944920063018799", /* S_LOG10ofE */
+};
+
+
+int codes_FPA[38] = {
+/* small rationals */
+  0x200,
+  0xe,
+  0xf,
+  0x10,
+  0x11,
+  0xb1,
+  0x12,
+  0x13,
+  0x15,
+  0x16,
+  0x17,
+  0x2e,
+/* double precision */
+  0x8,
+  0x9,
+  0xa,
+  0xb,
+  0xc,
+  0xd,
+  0x27,
+  0x28,
+  0x29,
+  0x2a,
+  0x2b,
+  0x2c,
+  0x2d,
+/* single precision */
+  0x8,
+  0x9,
+  0xa,
+  0xb,
+  0xc,
+  0xd,
+  0x27,
+  0x28,
+  0x29,
+  0x2a,
+  0x2b,
+  0x2c,
+  0x2d
+  };
+
+REAL_VALUE_TYPE values_FPA[38];
+
+/* This code has been fixed for cross-compilation. */
+
+void
+init_FPA_table ()
+{
+  enum machine_mode mode;
+  int i;
+  REAL_VALUE_TYPE r;
+
+  mode = DFmode;
+  for (i = 0; i < 38; i++)
+    {
+      if (i == 25)
+        mode = SFmode;
+      r = REAL_VALUE_ATOF (strings_FPA[i], mode);
+      values_FPA[i] = r;
+    }
+  inited_FPA_table = 1;
+}
+
 
 int
 standard_sun_fpa_constant_p (x)
      rtx x;
 {
-  register double d;
+  REAL_VALUE_TYPE r;
+  int i;
 
+#ifndef REAL_ARITHMETIC
 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
   if (! flag_pretend_float)
     return 0;
 #endif
+#endif
+
+  if (! inited_FPA_table)
+    init_FPA_table ();
+
+  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+
+  for (i=0; i<12; i++)
+    {
+      if (REAL_VALUES_EQUAL (r, values_FPA[i]))
+        return (codes_FPA[i]);
+    }
 
-  REAL_VALUE_FROM_CONST_DOUBLE (d, x);
-
-  if (d == 0.0)
-    return 0x200;              /* 0 once 0x1ff is anded with it */
-  if (d == 1.0)
-    return 0xe;
-  if (d == 0.5)
-    return 0xf;
-  if (d == -1.0)
-    return 0x10;
-  if (d == 2.0)
-    return 0x11;
-  if (d == 3.0)
-    return 0xB1;
-  if (d == 4.0)
-    return 0x12;
-  if (d == 8.0)
-    return 0x13;
-  if (d == 0.25)
-    return 0x15;
-  if (d == 0.125)
-    return 0x16;
-  if (d == 10.0)
-    return 0x17;
-  if (d == -(1.0/2.0))
-    return 0x2E;
-
-/*
- * Stuff that looks different if it's single or double
- */
   if (GET_MODE (x) == SFmode)
     {
-      if (d == S_E)
-       return 0x8;
-      if (d == (2*S_PI))
-       return 0x9;
-      if (d == S_PI)
-       return 0xA;
-      if (d == (S_PI / 2.0))
-       return 0xB;
-      if (d == S_SQRT2)
-       return 0xC;
-      if (d == (1.0 / S_SQRT2))
-       return 0xD;
-      /* Large powers of 10 in the constant 
-        ram are not used because they are
-        not equal to a C double constant  */
-      if (d == -(S_PI / 2.0))
-       return 0x27;
-      if (d == S_LOG2ofE)
-       return 0x28;
-      if (d == S_LOG2of10)
-       return 0x29;
-      if (d == S_LOGEof2)
-       return 0x2A;
-      if (d == S_LOGEof10)
-       return 0x2B;
-      if (d == S_LOG10of2)
-       return 0x2C;
-      if (d == S_LOG10ofE)
-       return 0x2D;
+      for (i=25; i<38; i++)
+        {
+          if (REAL_VALUES_EQUAL (r, values_FPA[i]))
+            return (codes_FPA[i]);
+        }
     }
   else
     {
-      if (d == D_E)
-       return 0x8;
-      if (d == (2*D_PI))
-       return 0x9;
-      if (d == D_PI)
-       return 0xA;
-      if (d == (D_PI / 2.0))
-       return 0xB;
-      if (d == D_SQRT2)
-       return 0xC;
-      if (d == (1.0 / D_SQRT2))
-       return 0xD;
-      /* Large powers of 10 in the constant 
-        ram are not used because they are
-        not equal to a C double constant  */
-      if (d == -(D_PI / 2.0))
-       return 0x27;
-      if (d == D_LOG2ofE)
-       return 0x28;
-      if (d == D_LOG2of10)
-       return 0x29;
-      if (d == D_LOGEof2)
-       return 0x2A;
-      if (d == D_LOGEof10)
-       return 0x2B;
-      if (d == D_LOG10of2)
-       return 0x2C;
-      if (d == D_LOG10ofE)
-       return 0x2D;
+      for (i=12; i<25; i++)
+        {
+          if (REAL_VALUES_EQUAL (r, values_FPA[i]))
+            return (codes_FPA[i]);
+        }
     }
   return 0x0;
 }
@@ -1601,17 +1681,21 @@ print_operand (file, op, letter)
 #endif
   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
     {
-      double d;
-      union { float f; int i; } u1;
-      REAL_VALUE_FROM_CONST_DOUBLE (d, op);
-      u1.f = d;
-      PRINT_OPERAND_PRINT_FLOAT (letter, file);
+      REAL_VALUE_TYPE r;
+      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
+      ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
+    }
+  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
+    {
+      REAL_VALUE_TYPE r;
+      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
+      ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
     }
   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode)
     {
-      double d;
-      REAL_VALUE_FROM_CONST_DOUBLE (d, op);
-      ASM_OUTPUT_DOUBLE_OPERAND (file, d);
+      REAL_VALUE_TYPE r;
+      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
+      ASM_OUTPUT_DOUBLE_OPERAND (file, r);
     }
   else
     {