OSDN Git Service

* real.c (struct real_format): Move to real.h.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Sep 2002 16:10:36 +0000 (16:10 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Sep 2002 16:10:36 +0000 (16:10 +0000)
(real_format_for_mode): Rename from fmt_for_mode; update all users;
initialize with ieee defaults.
(real_to_target_fmt, real_from_target_fmt): New.
(ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
ieee_extended_intel_96_format, ieee_extended_intel_128_format,
ieee_quad_format, i370_single_format, i370_double_format,
c4x_single_format, c4x_extended_format): Rename from s/_format//.
(ieee_quad_format): Fix emin.
(format_for_size, init_real_once): Remove.
* real.h (struct real_format): Move from real.c.
(real_format_for_mode): Declare.
(real_to_target_fmt, real_from_target_fmt): Declare.
(ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
ieee_extended_intel_96_format, ieee_extended_intel_128_format,
ieee_quad_format, vax_f_format, vax_d_format, vax_g_format,
i370_single_format, i370_double_format, c4x_single_format,
c4x_extended_format): Declare.
* toplev.c (do_compile): Don't call init_real_once.

* defaults.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
* doc/tm.texi (INTEL_EXTENDED_IEEE_FORMAT): Remove.

* config/alpha/alpha.h (TARGET_FLOAT_FORMAT): Define.
* config/alpha/osf5.h (LONG_DOUBLE_TYPE_SIZE): 64, if vax mode.
* config/alpha/alpha.c (override_options): Set real_format_for_mode
for VAX, if enabled.

* config/c4x/c4x.c (c4x_override_options): Set real_format_for_mode
for C4X.

* config/i370/i370.h (OVERRIDE_OPTIONS): New.
* config/i370/i370.c (override_options): New.
* config/i370/i370-protos.h: Update.

* config/i386/i386.c (override_options): Set real_format_for_mode
for Intel 80-bit extended.
* config/i386/i386.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.

* config/i960/i960.h (LONG_DOUBLE_TYPE_SIZE): Mind -mlong-double-64.
(OVERRIDE_OPTIONS): Move code...
* config/i960/i960.c (i960_initialize): ... here.  Set
real_format_for_mode for Intel 80-bit extended.

* config/ia64/ia64.c (ia64_override_options): Set real_format_for_mode
for Intel 80-bit extended, if enabled.

* config/m68k/m68k.c (override_options): Set real_format_for_mode
        for Motorola 96-bit extended.

* config/vax/vax.h (OVERRIDE_OPTIONS): New.
* config/vax/vax.c (override_options): New.
* config/vax/vax-protos.h: Update.

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

24 files changed:
gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/osf5.h
gcc/config/c4x/c4x.c
gcc/config/i370/i370-protos.h
gcc/config/i370/i370.c
gcc/config/i370/i370.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i960/i960.c
gcc/config/i960/i960.h
gcc/config/ia64/hpux_longdouble.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/m68k/m68k.c
gcc/config/vax/vax-protos.h
gcc/config/vax/vax.c
gcc/config/vax/vax.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/real.c
gcc/real.h
gcc/toplev.c

index 7e7b463..62058c3 100644 (file)
@@ -1,3 +1,59 @@
+2002-09-21  Richard Henderson  <rth@redhat.com>
+
+       * real.c (struct real_format): Move to real.h.
+       (real_format_for_mode): Rename from fmt_for_mode; update all users;
+       initialize with ieee defaults.
+       (real_to_target_fmt, real_from_target_fmt): New.
+       (ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
+       ieee_extended_intel_96_format, ieee_extended_intel_128_format,
+       ieee_quad_format, i370_single_format, i370_double_format, 
+       c4x_single_format, c4x_extended_format): Rename from s/_format//.
+       (ieee_quad_format): Fix emin.
+       (format_for_size, init_real_once): Remove.
+       * real.h (struct real_format): Move from real.c.
+       (real_format_for_mode): Declare.
+       (real_to_target_fmt, real_from_target_fmt): Declare.
+       (ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
+       ieee_extended_intel_96_format, ieee_extended_intel_128_format,
+       ieee_quad_format, vax_f_format, vax_d_format, vax_g_format,
+       i370_single_format, i370_double_format, c4x_single_format,
+       c4x_extended_format): Declare.
+       * toplev.c (do_compile): Don't call init_real_once.
+
+       * defaults.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
+       * doc/tm.texi (INTEL_EXTENDED_IEEE_FORMAT): Remove.
+
+       * config/alpha/alpha.h (TARGET_FLOAT_FORMAT): Define.
+       * config/alpha/osf5.h (LONG_DOUBLE_TYPE_SIZE): 64, if vax mode.
+       * config/alpha/alpha.c (override_options): Set real_format_for_mode
+       for VAX, if enabled.
+
+       * config/c4x/c4x.c (c4x_override_options): Set real_format_for_mode
+       for C4X.
+
+       * config/i370/i370.h (OVERRIDE_OPTIONS): New.
+       * config/i370/i370.c (override_options): New.
+       * config/i370/i370-protos.h: Update.
+
+       * config/i386/i386.c (override_options): Set real_format_for_mode
+       for Intel 80-bit extended.
+       * config/i386/i386.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
+
+       * config/i960/i960.h (LONG_DOUBLE_TYPE_SIZE): Mind -mlong-double-64.
+       (OVERRIDE_OPTIONS): Move code...
+       * config/i960/i960.c (i960_initialize): ... here.  Set
+       real_format_for_mode for Intel 80-bit extended.
+
+       * config/ia64/ia64.c (ia64_override_options): Set real_format_for_mode
+       for Intel 80-bit extended, if enabled.
+
+       * config/m68k/m68k.c (override_options): Set real_format_for_mode
+        for Motorola 96-bit extended.
+
+       * config/vax/vax.h (OVERRIDE_OPTIONS): New.
+       * config/vax/vax.c (override_options): New.
+       * config/vax/vax-protos.h: Update.
+
 2002-09-21  Alan Modra  <amodra@bigpond.net.au>
 
        * config/rs6000/rs6000.md (builtin_setjmp_receiver): Add
index f7963be..d26cb54 100644 (file)
@@ -567,6 +567,14 @@ override_options ()
 
   /* Set up function hooks.  */
   init_machine_status = alpha_init_machine_status;
+
+  /* Tell the compiler when we're using VAX floating point.  */
+  if (TARGET_FLOAT_VAX)
+    {
+      real_format_for_mode[SFmode - QFmode] = &vax_f_format;
+      real_format_for_mode[DFmode - QFmode] = &vax_g_format;
+      real_format_for_mode[TFmode - QFmode] = NULL;
+    }
 }
 \f
 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
index cf20383..4e94e88 100644 (file)
@@ -411,6 +411,10 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
 /* Define the size of `long long'.  The default is the twice the word size.  */
 #define LONG_LONG_TYPE_SIZE 64
 
+/* We're IEEE unless someone says to use VAX.  */
+#define TARGET_FLOAT_FORMAT \
+  (TARGET_FLOAT_VAX ? VAX_FLOAT_FORMAT : IEEE_FLOAT_FORMAT)
+
 /* The two floating-point formats we support are S-floating, which is
    4 bytes, and T-floating, which is 8 bytes.  `float' is S and `double'
    and `long double' are T.  */
index 59b3ae1..e483124 100644 (file)
    the Free Software Foundation, 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+/* Tru64 5.1 uses IEEE QUAD format.  */
+/* ??? However, since there is no support for VAX H_floating, we must
+   drop back to a 64-bit long double to avoid a crash looking for the
+   format associated with TFmode.  */
 #undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE  128
+#define LONG_DOUBLE_TYPE_SIZE  (TARGET_FLOAT_VAX ? 64 : 128)
 
 /* In Tru64 UNIX V5.1, Compaq introduced a new assembler
    (/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
index 83ab331..cbf0567 100644 (file)
@@ -294,6 +294,11 @@ c4x_override_options ()
      This provides compatibility with the old -mno-aliases option.  */
   if (! TARGET_ALIASES && ! flag_argument_noalias)
     flag_argument_noalias = 1;
+
+  /* We're C4X floating point, not IEEE floating point.  */
+  memset (real_format_for_mode, 0, sizeof real_format_for_mode);
+  real_format_for_mode[QFmode - QFmode] = &c4x_single_format;
+  real_format_for_mode[HFmode - QFmode] = &c4x_extended_format;
 }
 
 
index 8ca7ca6..a3f4acd 100644 (file)
@@ -24,6 +24,8 @@ Boston, MA 02111-1307, USA.  */
 #ifndef GCC_I370_PROTOS_H
 #define GCC_I370_PROTOS_H
 
+extern void override_options PARAMS ((void));
+
 #ifdef RTX_CODE
 extern int i370_branch_dest PARAMS ((rtx));
 extern int i370_branch_length PARAMS ((rtx));
index 92d2795..b4474db 100644 (file)
@@ -315,6 +315,18 @@ static const unsigned char ebcasc[256] =
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
+/* Set global variables as needed for the options enabled.  */
+
+void
+override_options ()
+{
+  /* We're 370 floating point, not IEEE floating point.  */
+  memset (real_format_for_mode, 0, sizeof real_format_for_mode);
+  real_format_for_mode[SFmode - QFmode] = &i370_single_format;
+  real_format_for_mode[DFmode - QFmode] = &i370_double_format;
+}
+
+
 /* Map characters from one character set to another.
    C is the character to be translated.  */
 
index d4c2939..a2aff67 100644 (file)
@@ -76,6 +76,8 @@ extern int mvs_function_name_length;
   { "no-char-instructions", -1, N_("Do not generate char instructions")}, \
   { "", TARGET_DEFAULT, 0} }
 
+#define OVERRIDE_OPTIONS  override_options ()
+
 /* To use IBM supplied macro function prologue and epilogue, define the
    following to 1.  Should only be needed if IBM changes the definition
    of their prologue and epilogue.  */
index f36206c..252c724 100644 (file)
@@ -937,6 +937,11 @@ override_options ()
 
   int const pta_size = ARRAY_SIZE (processor_alias_table);
 
+  /* By default our XFmode is the 80-bit extended format.  If we have
+     use TFmode instead, it's also the 80-bit format, but with padding.  */
+  real_format_for_mode[XFmode - QFmode] = &ieee_extended_intel_96_format;
+  real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
+
 #ifdef SUBTARGET_OVERRIDE_OPTIONS
   SUBTARGET_OVERRIDE_OPTIONS;
 #endif
index 2d46a9f..7cd3962 100644 (file)
@@ -631,8 +631,7 @@ extern int x86_prefetch_sse;
 
 /* Define for XFmode or TFmode extended real floating point support.
    The XFmode is specified by i386 ABI, while TFmode may be faster
-   due to alignment and simplifications in the address calculations.
- */
+   due to alignment and simplifications in the address calculations.  */
 #define LONG_DOUBLE_TYPE_SIZE (TARGET_128BIT_LONG_DOUBLE ? 128 : 96)
 #define MAX_LONG_DOUBLE_TYPE_SIZE 128
 #ifdef __x86_64__
@@ -640,9 +639,6 @@ extern int x86_prefetch_sse;
 #else
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
 #endif
-/* Tell real.c that this is the 80-bit Intel extended float format
-   packaged in a 128-bit or 96bit entity.  */
-#define INTEL_EXTENDED_IEEE_FORMAT 1
 
 /* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
    FPU, assume that the fpcw is set to extended precision; when using
index 7ebbb9e..7dbe852 100644 (file)
@@ -100,11 +100,47 @@ static int ret_label = 0;
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
-/* Initialize variables before compiling any files.  */
+/* Override conflicting target switch options.
+   Doesn't actually detect if more than one -mARCH option is given, but
+   does handle the case of two blatantly conflicting -mARCH options.
+
+   Also initialize variables before compiling any files.  */
 
 void
 i960_initialize ()
 {
+  if (TARGET_K_SERIES && TARGET_C_SERIES)
+    {
+      warning ("conflicting architectures defined - using C series");
+      target_flags &= ~TARGET_FLAG_K_SERIES;
+    }
+  if (TARGET_K_SERIES && TARGET_MC)
+    {
+      warning ("conflicting architectures defined - using K series");
+      target_flags &= ~TARGET_FLAG_MC;
+    }
+  if (TARGET_C_SERIES && TARGET_MC)
+    {
+      warning ("conflicting architectures defined - using C series");
+      target_flags &= ~TARGET_FLAG_MC;
+    }
+  if (TARGET_IC_COMPAT3_0)
+    {
+      flag_short_enums = 1;
+      flag_signed_char = 1;
+      target_flags |= TARGET_FLAG_CLEAN_LINKAGE;
+      if (TARGET_IC_COMPAT2_0)
+       {
+         warning ("iC2.0 and iC3.0 are incompatible - using iC3.0");
+         target_flags &= ~TARGET_FLAG_IC_COMPAT2_0;
+       }
+    }
+  if (TARGET_IC_COMPAT2_0)
+    {
+      flag_signed_char = 1;
+      target_flags |= TARGET_FLAG_CLEAN_LINKAGE;
+    }
+
   if (TARGET_IC_COMPAT2_0)
     {
       i960_maxbitalignment = 8;
@@ -115,6 +151,9 @@ i960_initialize ()
       i960_maxbitalignment = 128;
       i960_last_maxbitalignment = 8;
     }
+
+  /* Tell the compiler which flavor of XFmode we're using.  */
+  real_format_for_mode[XFmode - QFmode] = &ieee_extended_intel_96_format;
 }
 \f
 /* Return true if OP can be used as the source of an fp move insn.  */
index 37c9afb..a669cf4 100644 (file)
@@ -335,44 +335,7 @@ extern int target_flags;
 /* Override conflicting target switch options.
    Doesn't actually detect if more than one -mARCH option is given, but
    does handle the case of two blatantly conflicting -mARCH options.  */
-#define OVERRIDE_OPTIONS                                       \
-{                                                              \
-  if (TARGET_K_SERIES && TARGET_C_SERIES)                      \
-    {                                                          \
-      warning ("conflicting architectures defined - using C series"); \
-      target_flags &= ~TARGET_FLAG_K_SERIES;                   \
-    }                                                          \
-  if (TARGET_K_SERIES && TARGET_MC)                            \
-    {                                                          \
-      warning ("conflicting architectures defined - using K series"); \
-      target_flags &= ~TARGET_FLAG_MC;                         \
-    }                                                          \
-  if (TARGET_C_SERIES && TARGET_MC)                            \
-    {                                                          \
-      warning ("conflicting architectures defined - using C series");\
-      target_flags &= ~TARGET_FLAG_MC;                         \
-    }                                                          \
-  if (TARGET_IC_COMPAT3_0)                                     \
-    {                                                          \
-      flag_short_enums = 1;                                    \
-      flag_signed_char = 1;                                    \
-      target_flags |= TARGET_FLAG_CLEAN_LINKAGE;               \
-      if (TARGET_IC_COMPAT2_0)                                 \
-       {                                                       \
-         warning ("iC2.0 and iC3.0 are incompatible - using iC3.0"); \
-         target_flags &= ~TARGET_FLAG_IC_COMPAT2_0;            \
-       }                                                       \
-    }                                                          \
-  if (TARGET_IC_COMPAT2_0)                                     \
-    {                                                          \
-      flag_signed_char = 1;                                    \
-      target_flags |= TARGET_FLAG_CLEAN_LINKAGE;               \
-    }                                                          \
-  /* ??? See the LONG_DOUBLE_TYPE_SIZE definition below.  */   \
-  if (TARGET_LONG_DOUBLE_64)                                   \
-    warning ("the -mlong-double-64 option does not work yet");\
-  i960_initialize ();                                          \
-}
+#define OVERRIDE_OPTIONS  i960_initialize ()
 
 /* Don't enable anything by default.  The user is expected to supply a -mARCH
    option.  If none is given, then -mka is added by CC1_SPEC.  */
@@ -402,10 +365,7 @@ extern int target_flags;
 /* Width in bits of a long double.  Define to 96, and let
    ROUND_TYPE_ALIGN adjust the alignment for speed.  */
 #define        LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_64 ? 64 : 96)
-
-/* ??? This must be a constant, because real.c and real.h test it with #if.  */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 96
+#define MAX_LONG_DOUBLE_TYPE_SIZE 96
 
 /* Define this to set long double type size to use in libgcc2.c, which can
    not depend on target_flags.  */
index bfc12d4..d1af4a0 100644 (file)
@@ -18,8 +18,7 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* Tell real.c that we are not using INTEL_EXTENDED_IEEE_FORMAT */
-
+/* We are using IEEE quad precision, not a double-extended with padding.  */
 #undef INTEL_EXTENDED_IEEE_FORMAT
 #define INTEL_EXTENDED_IEEE_FORMAT 0
 
index c27a6fb..ad2d9b7 100644 (file)
@@ -4182,6 +4182,10 @@ ia64_override_options ()
   ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE;
 
   init_machine_status = ia64_init_machine_status;
+
+  /* Tell the compiler which flavor of TFmode we're using.  */
+  if (INTEL_EXTENDED_IEEE_FORMAT)
+    real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
 }
 \f
 static enum attr_itanium_requires_unit0 ia64_safe_itanium_requires_unit0 PARAMS((rtx));
index 8c8708d..31dd3cd 100644 (file)
@@ -381,9 +381,8 @@ while (0)
 
 #define LONG_DOUBLE_TYPE_SIZE 128
 
-/* Tell real.c that this is the 80-bit Intel extended float format
-   packaged in a 128-bit entity.  */
-
+/* By default we use the 80-bit Intel extended float format packaged
+   in a 128-bit entity.  */
 #define INTEL_EXTENDED_IEEE_FORMAT 1
 
 #define DEFAULT_SIGNED_CHAR 1
index cc03879..6114664 100644 (file)
@@ -174,6 +174,9 @@ override_options ()
       else
        m68k_align_funcs = i;
     }
+
+  /* Tell the compiler which flavor of XFmode we're using.  */
+  real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
 }
 \f
 /* This function generates the assembly code for function entry.
index f3a239d..059994f 100644 (file)
@@ -18,6 +18,8 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+extern void override_options PARAMS ((void));
+
 #ifdef RTX_CODE
 extern const char *rev_cond_name PARAMS ((rtx));
 extern void split_quadword_operands PARAMS ((rtx *, rtx *, int));
index c00189f..1a83eba 100644 (file)
@@ -66,6 +66,18 @@ static void vms_globalize_label PARAMS ((FILE *, const char *));
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
+/* Set global variables as needed for the options enabled.  */
+
+void
+override_options ()
+{
+  /* We're VAX floating point, not IEEE floating point.  */
+  memset (real_format_for_mode, 0, sizeof real_format_for_mode);
+  real_format_for_mode[SFmode - QFmode] = &vax_f_format;
+  real_format_for_mode[DFmode - QFmode]
+    = (TARGET_G_FLOAT ? &vax_g_format : &vax_d_format);
+}
+
 /* Generate the assembly code for function entry.  FILE is a stdio
    stream to output the code to.  SIZE is an int: how many units of
    temporary storage to allocate.
index e51f064..6651a02 100644 (file)
@@ -106,6 +106,9 @@ extern int target_flags;
 #ifndef TARGET_DEFAULT
 #define TARGET_DEFAULT (MASK_UNIX_ASM)
 #endif
+
+#define OVERRIDE_OPTIONS override_options ()
+
 \f
 /* Target machine storage layout */
 
index 3412775..700d04e 100644 (file)
@@ -576,10 +576,6 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
    && !ROUND_TOWARDS_ZERO)
 #endif
 
-#ifndef INTEL_EXTENDED_IEEE_FORMAT
-#define INTEL_EXTENDED_IEEE_FORMAT 0
-#endif
-
 /* If FLOAT_WORDS_BIG_ENDIAN and HOST_FLOAT_WORDS_BIG_ENDIAN are not defined
    in the header files, then this implies the word-endianness is the same as
    for integers.  */
index 2fd4a7b..c328ce7 100644 (file)
@@ -1530,13 +1530,6 @@ target machine.  If this is undefined, the default is
 the largest value that @code{LONG_DOUBLE_TYPE_SIZE} can have at run-time.
 This is used in @code{cpp}.
 
-@findex INTEL_EXTENDED_IEEE_FORMAT
-@item INTEL_EXTENDED_IEEE_FORMAT
-Define this macro to be 1 if the target machine uses 80-bit floating-point
-values with 128-bit size and alignment.  This is used in @file{real.c}.
-This also distinguishes the Intel 80-bit floating-point format from the
-Motorola 96-bit floating-point format.
-
 @findex TARGET_FLT_EVAL_METHOD
 @item TARGET_FLT_EVAL_METHOD
 A C expression for the value for @code{FLT_EVAL_METHOD} in @file{float.h},
index d746ab6..1f73f9d 100644 (file)
  #error "Some constant folding done by hand to avoid shift count warnings"
 #endif
 
-/* Describes the properties of the specific target format in use.  */
-struct real_format
-{
-  /* Move to and from the target bytes.  */
-  void (*encode) (const struct real_format *, long *,
-                 const REAL_VALUE_TYPE *);
-  void (*decode) (const struct real_format *, REAL_VALUE_TYPE *,
-                 const long *);
-
-  /* The radix of the exponent and digits of the significand.  */
-  int b;
-
-  /* log2(b).  */
-  int log2_b;
-
-  /* Size of the significand in digits of radix B.  */
-  int p;
-
-  /* The minimum negative integer, x, such that b**(x-1) is normalized.  */
-  int emin;
-
-  /* The maximum integer, x, such that b**(x-1) is representable.  */
-  int emax;
-
-  /* Properties of the format.  */
-  bool has_nans;
-  bool has_inf;
-  bool has_denorm;
-  bool has_signed_zero;
-  bool qnan_msb_set;
-};
-
-
-static const struct real_format *fmt_for_mode[TFmode - QFmode + 1];
-
-
 static void get_zero PARAMS ((REAL_VALUE_TYPE *, int));
 static void get_canonical_qnan PARAMS ((REAL_VALUE_TYPE *, int));
 static void get_canonical_snan PARAMS ((REAL_VALUE_TYPE *, int));
@@ -1942,7 +1906,7 @@ real_nan (r, str, quiet, mode)
 {
   const struct real_format *fmt;
 
-  fmt = fmt_for_mode[mode - QFmode];
+  fmt = real_format_for_mode[mode - QFmode];
   if (fmt == NULL)
     abort ();
 
@@ -2211,7 +2175,7 @@ real_convert (r, mode, a)
 {
   const struct real_format *fmt;
 
-  fmt = fmt_for_mode[mode - QFmode];
+  fmt = real_format_for_mode[mode - QFmode];
   if (fmt == NULL)
     abort ();
 
@@ -2247,26 +2211,21 @@ exact_real_truncate (mode, a)
   return real_identical (&t, a);
 }
 
-/* Write R to the target format of MODE.  Place the words of the 
-   result in target word order in BUF.  There are always 32 bits
-   in each long, no matter the size of the host long.
+/* Write R to the given target format.  Place the words of the result
+   in target word order in BUF.  There are always 32 bits in each
+   long, no matter the size of the host long.
 
    Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE.  */
 
 long
-real_to_target (buf, r_orig, mode)
+real_to_target_fmt (buf, r_orig, fmt)
      long *buf;
      const REAL_VALUE_TYPE *r_orig;
-     enum machine_mode mode;
+     const struct real_format *fmt;
 {
   REAL_VALUE_TYPE r;
-  const struct real_format *fmt;
   long buf1;
 
-  fmt = fmt_for_mode[mode - QFmode];
-  if (fmt == NULL)
-    abort ();
-
   r = *r_orig;
   round_for_format (fmt, &r);
 
@@ -2277,9 +2236,37 @@ real_to_target (buf, r_orig, mode)
   return *buf;
 }
 
-/* Read R from the target format of MODE.  Read the words of the
-   result in target word order in BUF.  There are always 32 bits
-   in each long, no matter the size of the host long.  */
+/* Similar, but look up the format from MODE.  */
+
+long
+real_to_target (buf, r, mode)
+     long *buf;
+     const REAL_VALUE_TYPE *r;
+     enum machine_mode mode;
+{
+  const struct real_format *fmt;
+
+  fmt = real_format_for_mode[mode - QFmode];
+  if (fmt == NULL)
+    abort ();
+
+  return real_to_target_fmt (buf, r, fmt);
+}
+
+/* Read R from the given target format.  Read the words of the result
+   in target word order in BUF.  There are always 32 bits in each
+   long, no matter the size of the host long.  */
+
+void
+real_from_target_fmt (r, buf, fmt)
+     REAL_VALUE_TYPE *r;
+     const long *buf;
+     const struct real_format *fmt;
+{
+  (*fmt->decode) (fmt, r, buf);
+}     
+
+/* Similar, but look up the format from MODE.  */
 
 void
 real_from_target (r, buf, mode)
@@ -2289,7 +2276,7 @@ real_from_target (r, buf, mode)
 {
   const struct real_format *fmt;
 
-  fmt = fmt_for_mode[mode - QFmode];
+  fmt = real_format_for_mode[mode - QFmode];
   if (fmt == NULL)
     abort ();
 
@@ -2305,7 +2292,7 @@ significand_size (mode)
 {
   const struct real_format *fmt;
 
-  fmt = fmt_for_mode[mode - QFmode];
+  fmt = real_format_for_mode[mode - QFmode];
   if (fmt == NULL)
     return 0;
 
@@ -2467,7 +2454,7 @@ decode_ieee_single (fmt, r, buf)
     }
 }
 
-const struct real_format ieee_single = 
+const struct real_format ieee_single_format = 
   {
     encode_ieee_single,
     decode_ieee_single,
@@ -2660,7 +2647,7 @@ decode_ieee_double (fmt, r, buf)
     }
 }
 
-const struct real_format ieee_double = 
+const struct real_format ieee_double_format = 
   {
     encode_ieee_double,
     decode_ieee_double,
@@ -2915,7 +2902,7 @@ decode_ieee_extended_128 (fmt, r, buf)
   decode_ieee_extended (fmt, r, buf+!!FLOAT_WORDS_BIG_ENDIAN);
 }
 
-const struct real_format ieee_extended_motorola = 
+const struct real_format ieee_extended_motorola_format = 
   {
     encode_ieee_extended,
     decode_ieee_extended,
@@ -2931,7 +2918,7 @@ const struct real_format ieee_extended_motorola =
     true
   };
 
-const struct real_format ieee_extended_intel_96 = 
+const struct real_format ieee_extended_intel_96_format = 
   {
     encode_ieee_extended,
     decode_ieee_extended,
@@ -2947,7 +2934,7 @@ const struct real_format ieee_extended_intel_96 =
     true
   };
 
-const struct real_format ieee_extended_intel_128 = 
+const struct real_format ieee_extended_intel_128_format = 
   {
     encode_ieee_extended_128,
     decode_ieee_extended_128,
@@ -3200,14 +3187,14 @@ decode_ieee_quad (fmt, r, buf)
     }
 }
 
-const struct real_format ieee_quad = 
+const struct real_format ieee_quad_format = 
   {
     encode_ieee_quad,
     decode_ieee_quad,
     2,
     1,
     113,
-    -16382,
+    -16381,
     16384,
     true,
     true,
@@ -3215,10 +3202,17 @@ const struct real_format ieee_quad =
     true,
     true
   };
-
 \f
-/* The VAX floating point formats.  */
+/* Descriptions of VAX floating point formats can be found beginning at
+
+   http://www.openvms.compaq.com:8000/73final/4515/4515pro_013.html#f_floating_point_format
+
+   The thing to remember is that they're almost IEEE, except for word
+   order, exponent bias, and the lack of infinities, nans, and denormals.
 
+   We don't implement the H_floating format here, simply because neither
+   the VAX or Alpha ports use it.  */
+   
 static void encode_vax_f PARAMS ((const struct real_format *fmt,
                                  long *, const REAL_VALUE_TYPE *));
 static void decode_vax_f PARAMS ((const struct real_format *,
@@ -3547,11 +3541,10 @@ const struct real_format vax_g_format =
     false,
     false
   };
-
 \f
-/* The IBM S/390 floating point formats.  A good reference for these can
-   be found in chapter 9 of "ESA/390 Principles of Operation", IBM document
-   number SA22-7201-01.  An on-line version can be found here:
+/* A good reference for these can be found in chapter 9 of
+   "ESA/390 Principles of Operation", IBM document number SA22-7201-01.
+   An on-line version can be found here:
 
    http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/DZ9AR001/9.1?DT=19930923083613
 */
@@ -3714,7 +3707,7 @@ decode_i370_double (fmt, r, buf)
     }
 }
 
-const struct real_format i370_single =
+const struct real_format i370_single_format =
   {
     encode_i370_single,
     decode_i370_single,
@@ -3730,7 +3723,7 @@ const struct real_format i370_single =
     false
   };
 
-const struct real_format i370_double =
+const struct real_format i370_double_format =
   {
     encode_i370_double,
     decode_i370_double,
@@ -3745,9 +3738,25 @@ const struct real_format i370_double =
     false, /* ??? The encoding does allow for "unnormals".  */
     false
   };
-
 \f
-/* TMS320C[34]x twos complement floating point format.  */
+/* The "twos-compliment" c4x format is officially defined as
+
+       x = s(~s).f * 2**e
+
+   This is rather misleading.  One must remember that F is signed.
+   A better description would be
+
+       x = -1**s * ((s + 1 + .f) * 2**e
+
+   So if we have a (4 bit) fraction of .1000 with a sign bit of 1,
+   that's -1 * (1+1+(-.5)) == -1.5.  I think.
+
+   The constructions here are taken from Tables 5-1 and 5-2 of the
+   TMS320C4x User's Guide wherein step-by-step instructions for
+   conversion from IEEE are presented.  That's close enough to our
+   internal representation so as to make things easy.
+
+   See http://www-s.ti.com/sc/psheets/spru063c/spru063c.pdf  */
 
 static void encode_c4x_single PARAMS ((const struct real_format *fmt,
                                       long *, const REAL_VALUE_TYPE *));
@@ -3928,7 +3937,7 @@ decode_c4x_extended (fmt, r, buf)
     }
 }
 
-const struct real_format c4x_single = 
+const struct real_format c4x_single_format = 
   {
     encode_c4x_single,
     decode_c4x_single,
@@ -3944,7 +3953,7 @@ const struct real_format c4x_single =
     false
   };
 
-const struct real_format c4x_extended = 
+const struct real_format c4x_extended_format = 
   {
     encode_c4x_extended,
     decode_c4x_extended,
@@ -3959,105 +3968,20 @@ const struct real_format c4x_extended =
     false,
     false
   };
-
 \f
-/* Initialize things at start of compilation.  */
-
-static const struct real_format * format_for_size PARAMS ((int));
-
-static const struct real_format *
-format_for_size (size)
-     int size;
-{
-#ifndef TARGET_G_FORMAT
-#define TARGET_G_FORMAT 0
-#endif
-
-  switch (TARGET_FLOAT_FORMAT)
-    {
-    case IEEE_FLOAT_FORMAT:
-      switch (size)
-       {
-       case 32:
-         return &ieee_single;
-
-       case 64:
-         return &ieee_double;
-
-       case 96:
-         if (!INTEL_EXTENDED_IEEE_FORMAT)
-           return &ieee_extended_motorola;
-         else
-           return &ieee_extended_intel_96;
-
-       case 128:
-         if (!INTEL_EXTENDED_IEEE_FORMAT)
-           return &ieee_quad;
-         else
-           return &ieee_extended_intel_128;
-       }
-      break;
-
-    case VAX_FLOAT_FORMAT:
-      switch (size)
-       {
-       case 32:
-         return &vax_f_format;
-
-       case 64:
-         if (TARGET_G_FORMAT)
-           return &vax_g_format;
-         else
-           return &vax_d_format;
-       }
-      break;
-
-    case IBM_FLOAT_FORMAT:
-      switch (size)
-       {
-       case 32:
-         return &i370_single;
-       case 64:
-         return &i370_double;
-       }
-      break;
-
-    case C4X_FLOAT_FORMAT:
-      switch (size)
-       {
-       case 32:
-         return &c4x_single;
-       case 64:
-         return &c4x_extended;
-       }
-      break;
-    }
-
-  abort ();
-}
+/* Set up default mode to format mapping for IEEE.  Everyone else has
+   to set these values in OVERRIDE_OPTIONS.  */
 
-void
-init_real_once ()
+const struct real_format *real_format_for_mode[TFmode - QFmode + 1] =
 {
-  int i;
-
-  /* Set up the mode->format table.  */
-  for (i = 0; i < 3; ++i)
-    {
-      enum machine_mode mode;
-      int size;
-
-      if (i == 0)
-       size = FLOAT_TYPE_SIZE;
-      else if (i == 1)
-       size = DOUBLE_TYPE_SIZE;
-      else
-       size = LONG_DOUBLE_TYPE_SIZE;
-
-      mode = mode_for_size (size, MODE_FLOAT, 0);
-      if (mode == BLKmode)
-       abort ();
+  NULL,                                /* QFmode */
+  NULL,                                /* HFmode */
+  NULL,                                /* TQFmode */
+  &ieee_single_format,         /* SFmode */
+  &ieee_double_format,         /* DFmode */
 
-      fmt_for_mode[mode - QFmode] = format_for_size (size);
-    }
-}
+  /* We explicitly don't handle XFmode.  There are two formats,
+     pretty much equally common.  Choose one in OVERRIDE_OPTIONS.  */
+  NULL,                                /* XFmode */
+  &ieee_quad_format            /* TFmode */
+};
index d59e520..6f8f7d8 100644 (file)
@@ -95,10 +95,44 @@ extern char test_real_width
 # endif
 #endif
 
-/* Declare functions in real.c.  */
 
-/* Initialize the emulator.  */
-extern void init_real_once     PARAMS ((void));
+/* Describes the properties of the specific target format in use.  */
+struct real_format
+{
+  /* Move to and from the target bytes.  */
+  void (*encode) (const struct real_format *, long *, const REAL_VALUE_TYPE *);
+  void (*decode) (const struct real_format *, REAL_VALUE_TYPE *, const long *);
+
+  /* The radix of the exponent and digits of the significand.  */
+  int b;
+
+  /* log2(b).  */
+  int log2_b;
+
+  /* Size of the significand in digits of radix B.  */
+  int p;
+
+  /* The minimum negative integer, x, such that b**(x-1) is normalized.  */
+  int emin;
+
+  /* The maximum integer, x, such that b**(x-1) is representable.  */
+  int emax;
+
+  /* Properties of the format.  */
+  bool has_nans;
+  bool has_inf;
+  bool has_denorm;
+  bool has_signed_zero;
+  bool qnan_msb_set;
+};
+
+
+/* The target format used for each floating floating point mode.
+   Indexed by MODE - QFmode.  */
+extern const struct real_format *real_format_for_mode[TFmode - QFmode + 1];
+
+
+/* Declare functions in real.c.  */
 
 /* Binary or unary arithmetic on tree_code.  */
 extern void real_arithmetic    PARAMS ((REAL_VALUE_TYPE *, int,
@@ -156,9 +190,13 @@ extern void real_from_integer      PARAMS ((REAL_VALUE_TYPE *,
                                         unsigned HOST_WIDE_INT,
                                         HOST_WIDE_INT, int));
 
+extern long real_to_target_fmt PARAMS ((long *, const REAL_VALUE_TYPE *,
+                                        const struct real_format *));
 extern long real_to_target     PARAMS ((long *, const REAL_VALUE_TYPE *,
                                         enum machine_mode));
 
+extern void real_from_target_fmt PARAMS ((REAL_VALUE_TYPE *, const long *,
+                                         const struct real_format *));
 extern void real_from_target   PARAMS ((REAL_VALUE_TYPE *, const long *,
                                         enum machine_mode));
 
@@ -171,6 +209,23 @@ extern void real_2expN             PARAMS ((REAL_VALUE_TYPE *, int));
 
 extern unsigned int real_hash  PARAMS ((const REAL_VALUE_TYPE *));
 
+
+/* Target formats defined in real.c.  */
+extern const struct real_format ieee_single_format;
+extern const struct real_format ieee_double_format;
+extern const struct real_format ieee_extended_motorola_format;
+extern const struct real_format ieee_extended_intel_96_format;
+extern const struct real_format ieee_extended_intel_128_format;
+extern const struct real_format ieee_quad_format;
+extern const struct real_format vax_f_format;
+extern const struct real_format vax_d_format;
+extern const struct real_format vax_g_format;
+extern const struct real_format i370_single_format;
+extern const struct real_format i370_double_format;
+extern const struct real_format c4x_single_format;
+extern const struct real_format c4x_extended_format;
+
+
 /* ====================================================================== */
 /* Crap.  */
 
index eec8455..366dfdf 100644 (file)
@@ -5322,11 +5322,6 @@ do_compile ()
   init_timevar ();
   timevar_start (TV_TOTAL);
 
-  /* We need to initialize real.c in order to define __FLT_MIN__ etc,
-     which must happen even with -E.  But with -E we'll suppress the
-     rest of backend_init.  */
-  init_real_once ();
-
   /* Set up the back-end if requested.  */
   if (!no_backend)
     backend_init ();