From 58145e4deb905cb924d9a11d836d08e1584dc52d Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 18 Jan 2007 19:45:13 +0000 Subject: [PATCH] real.h (real_format): Add a canonical_nan_lsbs_set field. gcc/ * real.h (real_format): Add a canonical_nan_lsbs_set field. (coldfire_single_format): Declare. (coldfire_double_format): Likewise. * real.c (encode_ieee_single): Use canonical_nan_lsbs_set instead of qnan_msb_set to determine the lower bits of a canonical NaN significand. (encode_ieee_double): Likewise. (encode_ieee_quad): Likewise. (ieee_single_format): Initialize canonical_nan_lsbs_set. (mips_single_format): Likewise. (ieee_double_format): Likewise. (mips_double_format): Likewise. (ieee_extended_motorola_format): Likewise. (ieee_extended_intel_96_format): Likewise. (ieee_extended_intel_128_format): Likewise. (ieee_extended_intel_96_round_53_format): Likewise. (ibm_extended_format): Likewise. (mips_extended_format): Likewise. (ieee_quad_format): Likewise. (mips_quad_format): Likewise. (vax_f_format): Likewise. (vax_d_format): Likewise. (vax_g_format): Likewise. (i370_single_format): Likewise. (i370_double_format): Likewise. (decimal_single_format): Likewise. (decimal_double_format): Likewise. (decimal_quad_format): Likewise. (c4x_single_format): Likewise. (c4x_extended_format): Likewise. (real_internal_format): Likewise. (coldfire_single_format): New real_format. (coldfire_double_format): Likewise. * config/pdp11/pdp11.c (pdp11_f_format): Initialize canonical_nan_lsbs_set. (pdp11_d_format): Likewise. * config/m68k/m68k.c (override_options): Override REAL_FORMAT_MODE if TARGET_COLDFIRE_CPU. From-SVN: r120922 --- gcc/ChangeLog | 41 +++++++++++ gcc/config/m68k/m68k.c | 6 ++ gcc/config/pdp11/pdp11.c | 2 + gcc/real.c | 145 ++++++++++++++++++++++++++------------- gcc/real.h | 3 + 5 files changed, 150 insertions(+), 47 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2459a97ce57..646470a8df9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,44 @@ +2007-01-18 Richard Sandiford + + * real.h (real_format): Add a canonical_nan_lsbs_set field. + (coldfire_single_format): Declare. + (coldfire_double_format): Likewise. + * real.c (encode_ieee_single): Use canonical_nan_lsbs_set instead + of qnan_msb_set to determine the lower bits of a canonical + NaN significand. + (encode_ieee_double): Likewise. + (encode_ieee_quad): Likewise. + (ieee_single_format): Initialize canonical_nan_lsbs_set. + (mips_single_format): Likewise. + (ieee_double_format): Likewise. + (mips_double_format): Likewise. + (ieee_extended_motorola_format): Likewise. + (ieee_extended_intel_96_format): Likewise. + (ieee_extended_intel_128_format): Likewise. + (ieee_extended_intel_96_round_53_format): Likewise. + (ibm_extended_format): Likewise. + (mips_extended_format): Likewise. + (ieee_quad_format): Likewise. + (mips_quad_format): Likewise. + (vax_f_format): Likewise. + (vax_d_format): Likewise. + (vax_g_format): Likewise. + (i370_single_format): Likewise. + (i370_double_format): Likewise. + (decimal_single_format): Likewise. + (decimal_double_format): Likewise. + (decimal_quad_format): Likewise. + (c4x_single_format): Likewise. + (c4x_extended_format): Likewise. + (real_internal_format): Likewise. + (coldfire_single_format): New real_format. + (coldfire_double_format): Likewise. + * config/pdp11/pdp11.c (pdp11_f_format): Initialize + canonical_nan_lsbs_set. + (pdp11_d_format): Likewise. + * config/m68k/m68k.c (override_options): Override REAL_FORMAT_MODE + if TARGET_COLDFIRE_CPU. + 2007-01-18 Richard Sandiford * config/m68k/m68k-protos.h (m68k_output_pic_call): Delete. diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 03d59b98f9b..aa91b72df00 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -512,6 +512,12 @@ override_options (void) : (m68k_cpu_flags & FL_COLDFIRE) != 0 ? FPUTYPE_COLDFIRE : FPUTYPE_68881); + if (TARGET_COLDFIRE_FPU) + { + REAL_MODE_FORMAT (SFmode) = &coldfire_single_format; + REAL_MODE_FORMAT (DFmode) = &coldfire_double_format; + } + /* Sanity check to ensure that msep-data and mid-sahred-library are not * both specified together. Doing so simply doesn't make sense. */ diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 4036b12449a..3e295b174b6 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -78,6 +78,7 @@ const struct real_format pdp11_f_format = false, false, false, + false, false }; @@ -96,6 +97,7 @@ const struct real_format pdp11_d_format = false, false, false, + false, false }; diff --git a/gcc/real.c b/gcc/real.c index b6e5ed6ee3e..b966917ae8f 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -2681,18 +2681,12 @@ encode_ieee_single (const struct real_format *fmt, long *buf, if (fmt->has_nans) { if (r->canonical) - sig = 0; + sig = (fmt->canonical_nan_lsbs_set ? (1 << 22) - 1 : 0); if (r->signalling == fmt->qnan_msb_set) sig &= ~(1 << 22); else sig |= 1 << 22; - /* We overload qnan_msb_set here: it's only clear for - mips_ieee_single, which wants all mantissa bits but the - quiet/signalling one set in canonical NaNs (at least - Quiet ones). */ - if (r->canonical && !fmt->qnan_msb_set) - sig |= (1 << 22) - 1; - else if (sig == 0) + if (sig == 0) sig = 1 << 21; image |= 255 << 23; @@ -2787,7 +2781,8 @@ const struct real_format ieee_single_format = true, true, true, - true + true, + false }; const struct real_format mips_single_format = @@ -2806,9 +2801,29 @@ const struct real_format mips_single_format = true, true, true, - false + false, + true }; +const struct real_format coldfire_single_format = + { + encode_ieee_single, + decode_ieee_single, + 2, + 1, + 24, + 24, + -125, + 128, + 31, + 31, + true, + true, + true, + true, + true, + true + }; /* IEEE double-precision format. */ @@ -2860,21 +2875,23 @@ encode_ieee_double (const struct real_format *fmt, long *buf, if (fmt->has_nans) { if (r->canonical) - sig_hi = sig_lo = 0; + { + if (fmt->canonical_nan_lsbs_set) + { + sig_hi = (1 << 19) - 1; + sig_lo = 0xffffffff; + } + else + { + sig_hi = 0; + sig_lo = 0; + } + } if (r->signalling == fmt->qnan_msb_set) sig_hi &= ~(1 << 19); else sig_hi |= 1 << 19; - /* We overload qnan_msb_set here: it's only clear for - mips_ieee_single, which wants all mantissa bits but the - quiet/signalling one set in canonical NaNs (at least - Quiet ones). */ - if (r->canonical && !fmt->qnan_msb_set) - { - sig_hi |= (1 << 19) - 1; - sig_lo = 0xffffffff; - } - else if (sig_hi == 0 && sig_lo == 0) + if (sig_hi == 0 && sig_lo == 0) sig_hi = 1 << 18; image_hi |= 2047 << 20; @@ -3012,7 +3029,8 @@ const struct real_format ieee_double_format = true, true, true, - true + true, + false }; const struct real_format mips_double_format = @@ -3031,9 +3049,29 @@ const struct real_format mips_double_format = true, true, true, - false + false, + true }; +const struct real_format coldfire_double_format = + { + encode_ieee_double, + decode_ieee_double, + 2, + 1, + 53, + 53, + -1021, + 1024, + 63, + 63, + true, + true, + true, + true, + true, + true + }; /* IEEE extended real format. This comes in three flavors: Intel's as a 12 byte image, Intel's as a 16 byte image, and Motorola's. Intel @@ -3361,7 +3399,8 @@ const struct real_format ieee_extended_motorola_format = true, true, true, - true + true, + false }; const struct real_format ieee_extended_intel_96_format = @@ -3380,7 +3419,8 @@ const struct real_format ieee_extended_intel_96_format = true, true, true, - true + true, + false }; const struct real_format ieee_extended_intel_128_format = @@ -3399,7 +3439,8 @@ const struct real_format ieee_extended_intel_128_format = true, true, true, - true + true, + false }; /* The following caters to i386 systems that set the rounding precision @@ -3420,7 +3461,8 @@ const struct real_format ieee_extended_intel_96_round_53_format = true, true, true, - true + true, + false }; /* IBM 128-bit extended precision format: a pair of IEEE double precision @@ -3506,7 +3548,8 @@ const struct real_format ibm_extended_format = true, true, true, - true + true, + false }; const struct real_format mips_extended_format = @@ -3525,7 +3568,8 @@ const struct real_format mips_extended_format = true, true, true, - false + false, + true }; @@ -3575,8 +3619,11 @@ encode_ieee_quad (const struct real_format *fmt, long *buf, if (r->canonical) { - /* Don't use bits from the significand. The - initialization above is right. */ + if (fmt->canonical_nan_lsbs_set) + { + image3 |= 0x7fff; + image2 = image1 = image0 = 0xffffffff; + } } else if (HOST_BITS_PER_LONG == 32) { @@ -3598,16 +3645,7 @@ encode_ieee_quad (const struct real_format *fmt, long *buf, image3 &= ~0x8000; else image3 |= 0x8000; - /* We overload qnan_msb_set here: it's only clear for - mips_ieee_single, which wants all mantissa bits but the - quiet/signalling one set in canonical NaNs (at least - Quiet ones). */ - if (r->canonical && !fmt->qnan_msb_set) - { - image3 |= 0x7fff; - image2 = image1 = image0 = 0xffffffff; - } - else if (((image3 & 0xffff) | image2 | image1 | image0) == 0) + if (((image3 & 0xffff) | image2 | image1 | image0) == 0) image3 |= 0x4000; } else @@ -3792,7 +3830,8 @@ const struct real_format ieee_quad_format = true, true, true, - true + true, + false }; const struct real_format mips_quad_format = @@ -3811,7 +3850,8 @@ const struct real_format mips_quad_format = true, true, true, - false + false, + true }; /* Descriptions of VAX floating point formats can be found beginning at @@ -4109,6 +4149,7 @@ const struct real_format vax_f_format = false, false, false, + false, false }; @@ -4128,6 +4169,7 @@ const struct real_format vax_d_format = false, false, false, + false, false }; @@ -4147,6 +4189,7 @@ const struct real_format vax_g_format = false, false, false, + false, false }; @@ -4323,6 +4366,7 @@ const struct real_format i370_single_format = false, false, /* ??? The encoding does allow for "unnormals". */ false, /* ??? The encoding does allow for "unnormals". */ + false, false }; @@ -4342,6 +4386,7 @@ const struct real_format i370_double_format = false, false, /* ??? The encoding does allow for "unnormals". */ false, /* ??? The encoding does allow for "unnormals". */ + false, false }; @@ -4416,7 +4461,8 @@ const struct real_format decimal_single_format = true, true, true, - true + true, + false }; /* Double precision decimal floating point (IEEE 754R). */ @@ -4436,7 +4482,8 @@ const struct real_format decimal_double_format = true, true, true, - true + true, + false }; /* Quad precision decimal floating point (IEEE 754R). */ @@ -4456,7 +4503,8 @@ const struct real_format decimal_quad_format = true, true, true, - true + true, + false }; /* The "twos-complement" c4x format is officially defined as @@ -4665,6 +4713,7 @@ const struct real_format c4x_single_format = false, false, false, + false, false }; @@ -4684,6 +4733,7 @@ const struct real_format c4x_extended_format = false, false, false, + false, false }; @@ -4728,7 +4778,8 @@ const struct real_format real_internal_format = true, false, true, - true + true, + false }; /* Calculate the square root of X in mode MODE, and store the result diff --git a/gcc/real.h b/gcc/real.h index 4198b02aee6..81ee855dbfa 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -155,6 +155,7 @@ struct real_format bool has_denorm; bool has_signed_zero; bool qnan_msb_set; + bool canonical_nan_lsbs_set; }; @@ -255,8 +256,10 @@ extern unsigned int real_hash (const REAL_VALUE_TYPE *); /* Target formats defined in real.c. */ extern const struct real_format ieee_single_format; extern const struct real_format mips_single_format; +extern const struct real_format coldfire_single_format; extern const struct real_format ieee_double_format; extern const struct real_format mips_double_format; +extern const struct real_format coldfire_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_96_round_53_format;