diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-21 16:10:36 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-21 16:10:36 +0000 |
commit | 1268285a29c29c7772fc29e3ab2e19fc4d264cc2 (patch) | |
tree | cf255ab7cc385de8be819f436b5513ec3c5357c2 /gcc/real.c | |
parent | 3160db1dc46f78ddbaa809d1904690ab8d22e51f (diff) | |
download | gcc-1268285a29c29c7772fc29e3ab2e19fc4d264cc2.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57388 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/real.c')
-rw-r--r-- | gcc/real.c | 264 |
1 files changed, 94 insertions, 170 deletions
diff --git a/gcc/real.c b/gcc/real.c index d746ab61223..1f73f9de2e9 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 */ +}; |