aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog56
-rw-r--r--gcc/config/alpha/alpha.c8
-rw-r--r--gcc/config/alpha/alpha.h4
-rw-r--r--gcc/config/alpha/osf5.h6
-rw-r--r--gcc/config/c4x/c4x.c5
-rw-r--r--gcc/config/i370/i370-protos.h2
-rw-r--r--gcc/config/i370/i370.c12
-rw-r--r--gcc/config/i370/i370.h2
-rw-r--r--gcc/config/i386/i386.c5
-rw-r--r--gcc/config/i386/i386.h6
-rw-r--r--gcc/config/i960/i960.c41
-rw-r--r--gcc/config/i960/i960.h44
-rw-r--r--gcc/config/ia64/hpux_longdouble.h3
-rw-r--r--gcc/config/ia64/ia64.c4
-rw-r--r--gcc/config/ia64/ia64.h5
-rw-r--r--gcc/config/m68k/m68k.c3
-rw-r--r--gcc/config/vax/vax-protos.h2
-rw-r--r--gcc/config/vax/vax.c12
-rw-r--r--gcc/config/vax/vax.h3
-rw-r--r--gcc/defaults.h4
-rw-r--r--gcc/doc/tm.texi7
-rw-r--r--gcc/real.c264
-rw-r--r--gcc/real.h61
-rw-r--r--gcc/toplev.c5
24 files changed, 321 insertions, 243 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7e7b463..62058c3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index f7963be..d26cb54 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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;
+ }
}
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index cf20383..4e94e88 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -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. */
diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h
index 59b3ae1..e483124 100644
--- a/gcc/config/alpha/osf5.h
+++ b/gcc/config/alpha/osf5.h
@@ -18,8 +18,12 @@
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
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index 83ab331..cbf0567 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -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;
}
diff --git a/gcc/config/i370/i370-protos.h b/gcc/config/i370/i370-protos.h
index 8ca7ca6..a3f4acd 100644
--- a/gcc/config/i370/i370-protos.h
+++ b/gcc/config/i370/i370-protos.h
@@ -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));
diff --git a/gcc/config/i370/i370.c b/gcc/config/i370/i370.c
index 92d2795..b4474db 100644
--- a/gcc/config/i370/i370.c
+++ b/gcc/config/i370/i370.c
@@ -315,6 +315,18 @@ static const unsigned char ebcasc[256] =
struct gcc_target targetm = TARGET_INITIALIZER;
+/* 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. */
diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h
index d4c2939..a2aff67 100644
--- a/gcc/config/i370/i370.h
+++ b/gcc/config/i370/i370.h
@@ -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. */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index f36206c..252c724 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 2d46a9f..7cd3962 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index 7ebbb9e..7dbe852 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -100,11 +100,47 @@ static int ret_label = 0;
struct gcc_target targetm = TARGET_INITIALIZER;
-/* 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;
}
/* Return true if OP can be used as the source of an fp move insn. */
diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h
index 37c9afb..a669cf4 100644
--- a/gcc/config/i960/i960.h
+++ b/gcc/config/i960/i960.h
@@ -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. */
diff --git a/gcc/config/ia64/hpux_longdouble.h b/gcc/config/ia64/hpux_longdouble.h
index bfc12d4..d1af4a0 100644
--- a/gcc/config/ia64/hpux_longdouble.h
+++ b/gcc/config/ia64/hpux_longdouble.h
@@ -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
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index c27a6fb..ad2d9b7 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -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;
}
static enum attr_itanium_requires_unit0 ia64_safe_itanium_requires_unit0 PARAMS((rtx));
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 8c8708d..31dd3cd 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -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
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index cc03879..6114664 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -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;
}
/* This function generates the assembly code for function entry.
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index f3a239d..059994f 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -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));
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index c00189f..1a83eba 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -66,6 +66,18 @@ static void vms_globalize_label PARAMS ((FILE *, const char *));
struct gcc_target targetm = TARGET_INITIALIZER;
+/* 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.
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index e51f064..6651a02 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -106,6 +106,9 @@ extern int target_flags;
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_UNIX_ASM)
#endif
+
+#define OVERRIDE_OPTIONS override_options ()
+
/* Target machine storage layout */
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 3412775..700d04e 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -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. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 2fd4a7b..c328ce7 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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},
diff --git a/gcc/real.c b/gcc/real.c
index d746ab6..1f73f9d 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -70,42 +70,6 @@
#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
};
-
-/* 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
};
-
-/* 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
};
-
-/* 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
};
-
-/* 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 */
+};
diff --git a/gcc/real.h b/gcc/real.h
index d59e520..6f8f7d8 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -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. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index eec8455..366dfdf 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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 ();