* 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.
From-SVN: r57388
+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
/* 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. */
/* 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. */
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
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;
}
#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));
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. */
{ "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. */
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
/* 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__
#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
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;
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. */
/* 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. */
/* 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. */
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
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));
#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
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.
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));
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.
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_UNIX_ASM)
#endif
+
+#define OVERRIDE_OPTIONS override_options ()
+
\f
/* Target machine storage layout */
&& !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. */
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},
#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));
{
const struct real_format *fmt;
- fmt = fmt_for_mode[mode - QFmode];
+ fmt = real_format_for_mode[mode - QFmode];
if (fmt == NULL)
abort ();
{
const struct real_format *fmt;
- fmt = fmt_for_mode[mode - QFmode];
+ fmt = real_format_for_mode[mode - QFmode];
if (fmt == NULL)
abort ();
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);
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)
{
const struct real_format *fmt;
- fmt = fmt_for_mode[mode - QFmode];
+ fmt = real_format_for_mode[mode - QFmode];
if (fmt == NULL)
abort ();
{
const struct real_format *fmt;
- fmt = fmt_for_mode[mode - QFmode];
+ fmt = real_format_for_mode[mode - QFmode];
if (fmt == NULL)
return 0;
}
}
-const struct real_format ieee_single =
+const struct real_format ieee_single_format =
{
encode_ieee_single,
decode_ieee_single,
}
}
-const struct real_format ieee_double =
+const struct real_format ieee_double_format =
{
encode_ieee_double,
decode_ieee_double,
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,
true
};
-const struct real_format ieee_extended_intel_96 =
+const struct real_format ieee_extended_intel_96_format =
{
encode_ieee_extended,
decode_ieee_extended,
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,
}
}
-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,
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 *,
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
*/
}
}
-const struct real_format i370_single =
+const struct real_format i370_single_format =
{
encode_i370_single,
decode_i370_single,
false
};
-const struct real_format i370_double =
+const struct real_format i370_double_format =
{
encode_i370_double,
decode_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 *));
}
}
-const struct real_format c4x_single =
+const struct real_format c4x_single_format =
{
encode_c4x_single,
decode_c4x_single,
false
};
-const struct real_format c4x_extended =
+const struct real_format c4x_extended_format =
{
encode_c4x_extended,
decode_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 */
+};
# 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,
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));
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. */
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 ();