From c50a01163c10c9467986f78e5a82cb4975556043 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Thu, 17 Jun 2004 17:05:48 +0000 Subject: [PATCH] Bug 14610 Bug 14610 * Makefile.in (min-insn-modes.o): Correct dependencies. * real.c (encode_ieee_extended, decode_ieee_extended): Always produce/consume 12-byte little-endian Intel format. (encode_ieee_extended_128, decode_ieee_extended_128): Delete. (encode_ieee_extended_motorola, decode_ieee_extended_motorola) (encode_ieee_extended_intel_96, decode_ieee_extended_intel_96) (encode_ieee_extended_intel_128, decode_ieee_extended_intel_128): New functions which convert between 12-byte little-endian Intel format and the desired format. (ieee_extended_motorola_format, ieee_extended_intel_96_round_53_format) (ieee_extended_intel_96_format, ieee_extended_intel_128_format): Update. testsuite: * gcc.dg/ia64-float80-1.c, gcc.dg/ia64-float80-2.c: New testcases. From-SVN: r83295 --- gcc/ChangeLog | 18 ++- gcc/Makefile.in | 2 +- gcc/real.c | 151 ++++++++++++++++++++------ gcc/testsuite/ChangeLog | 9 +- gcc/testsuite/gcc.dg/ia64-float80-1.c | 12 ++ gcc/testsuite/gcc.dg/ia64-float80-2.c | 13 +++ 6 files changed, 166 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ia64-float80-1.c create mode 100644 gcc/testsuite/gcc.dg/ia64-float80-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a1a3c205a0..6c7e48588f1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-06-17 Zack Weinberg + + Bug 14610 + * Makefile.in (min-insn-modes.o): Correct dependencies. + * real.c (encode_ieee_extended, decode_ieee_extended): Always + produce/consume 12-byte little-endian Intel format. + (encode_ieee_extended_128, decode_ieee_extended_128): Delete. + (encode_ieee_extended_motorola, decode_ieee_extended_motorola) + (encode_ieee_extended_intel_96, decode_ieee_extended_intel_96) + (encode_ieee_extended_intel_128, decode_ieee_extended_intel_128): + New functions which convert between 12-byte little-endian Intel + format and the desired format. + (ieee_extended_motorola_format, ieee_extended_intel_96_round_53_format) + (ieee_extended_intel_96_format, ieee_extended_intel_128_format): + Update. + 2004-06-17 Zack Weinberg * expmed.c (expand_mult_const): In sanity check, compare only @@ -43,7 +59,7 @@ * tree-inline.c: Correct comment about this file's purpose. * tree-optimize.c: Likewise. * tree-tailcall.c: Likewise. - + * tree-alias-ander.h: Add standard top-of-file comment. * tree-alias-common.h: Likewise. * tree-alias-type.h: Likewise. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index dd7e65d4ca1..3db6176f03d 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2561,7 +2561,7 @@ $(BUILD_PREFIX_1)ggc-none.o: ggc-none.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYST sed -e 's/config[.]h/bconfig.h/' $(srcdir)/ggc-none.c > $(BUILD_PREFIX)ggc-none.c $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)ggc-none.c $(OUTPUT_OPTION) -min-insn-modes.o: insn-modes.c $(BCONFIG_H) $(SYSTEM_H) $(MACHMODE_H) +min-insn-modes.o: min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H) $(MACHMODE_H) $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \ min-insn-modes.c $(OUTPUT_OPTION) diff --git a/gcc/real.c b/gcc/real.c index a9bad46fffa..896aa9dd3e1 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -2912,20 +2912,14 @@ const struct real_format mips_double_format = }; -/* IEEE extended double precision format. This comes in three - flavors: Intel's as a 12 byte image, Intel's as a 16 byte image, - and Motorola's. */ - -static void encode_ieee_extended (const struct real_format *fmt, - long *, const REAL_VALUE_TYPE *); -static void decode_ieee_extended (const struct real_format *, - REAL_VALUE_TYPE *, const long *); - -static void encode_ieee_extended_128 (const struct real_format *fmt, - long *, const REAL_VALUE_TYPE *); -static void decode_ieee_extended_128 (const struct real_format *, - REAL_VALUE_TYPE *, const long *); - +/* 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 + 12- and 16-byte images may be big- or little endian; Motorola's is + always big endian. */ + +/* Helper subroutine which converts from the internal format to the + 12-byte little-endian Intel format. Functions below adjust this + for the other possible formats. */ static void encode_ieee_extended (const struct real_format *fmt, long *buf, const REAL_VALUE_TYPE *r) @@ -3033,20 +3027,65 @@ encode_ieee_extended (const struct real_format *fmt, long *buf, abort (); } + buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi; +} + +/* Convert from the internal format to the 12-byte Motorola format + for an IEEE extended real. */ +static void +encode_ieee_extended_motorola (const struct real_format *fmt, long *buf, + const REAL_VALUE_TYPE *r) +{ + long intermed[3]; + encode_ieee_extended (fmt, intermed, r); + + /* Motorola chips are assumed always to be big-endian. Also, the + padding in a Motorola extended real goes between the exponent and + the mantissa. At this point the mantissa is entirely within + elements 0 and 1 of intermed, and the exponent entirely within + element 2, so all we have to do is swap the order around, and + shift element 2 left 16 bits. */ + buf[0] = intermed[2] << 16; + buf[1] = intermed[1]; + buf[2] = intermed[0]; +} + +/* Convert from the internal format to the 12-byte Intel format for + an IEEE extended real. */ +static void +encode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf, + const REAL_VALUE_TYPE *r) +{ if (FLOAT_WORDS_BIG_ENDIAN) - buf[0] = image_hi << 16, buf[1] = sig_hi, buf[2] = sig_lo; + { + /* All the padding in an Intel-format extended real goes at the high + end, which in this case is after the mantissa, not the exponent. + Therefore we must shift everything down 16 bits. */ + long intermed[3]; + encode_ieee_extended (fmt, intermed, r); + buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16)); + buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16)); + buf[2] = (intermed[0] << 16); + } else - buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi; + /* encode_ieee_extended produces what we want directly. */ + encode_ieee_extended (fmt, buf, r); } +/* Convert from the internal format to the 16-byte Intel format for + an IEEE extended real. */ static void -encode_ieee_extended_128 (const struct real_format *fmt, long *buf, - const REAL_VALUE_TYPE *r) +encode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf, + const REAL_VALUE_TYPE *r) { - buf[3 * !FLOAT_WORDS_BIG_ENDIAN] = 0; - encode_ieee_extended (fmt, buf+!!FLOAT_WORDS_BIG_ENDIAN, r); + /* All the padding in an Intel-format extended real goes at the high end. */ + encode_ieee_extended_intel_96 (fmt, buf, r); + buf[3] = 0; } +/* As above, we have a helper function which converts from 12-byte + little-endian Intel format to internal format. Functions below + adjust for the other possible formats. */ static void decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r, const long *buf) @@ -3055,10 +3094,7 @@ decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r, bool sign; int exp; - if (FLOAT_WORDS_BIG_ENDIAN) - image_hi = buf[0] >> 16, sig_hi = buf[1], sig_lo = buf[2]; - else - sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2]; + sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2]; sig_lo &= 0xffffffff; sig_hi &= 0xffffffff; image_hi &= 0xffffffff; @@ -3135,17 +3171,62 @@ decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r, } } +/* Convert from the internal format to the 12-byte Motorola format + for an IEEE extended real. */ +static void +decode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r, + const long *buf) +{ + long intermed[3]; + + /* Motorola chips are assumed always to be big-endian. Also, the + padding in a Motorola extended real goes between the exponent and + the mantissa; remove it. */ + intermed[0] = buf[2]; + intermed[1] = buf[1]; + intermed[2] = (unsigned long)buf[0] >> 16; + + decode_ieee_extended (fmt, r, intermed); +} + +/* Convert from the internal format to the 12-byte Intel format for + an IEEE extended real. */ +static void +decode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r, + const long *buf) +{ + if (FLOAT_WORDS_BIG_ENDIAN) + { + /* All the padding in an Intel-format extended real goes at the high + end, which in this case is after the mantissa, not the exponent. + Therefore we must shift everything up 16 bits. */ + long intermed[3]; + + intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16)); + intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16)); + intermed[2] = ((unsigned long)buf[0] >> 16); + + decode_ieee_extended (fmt, r, intermed); + } + else + /* decode_ieee_extended produces what we want directly. */ + decode_ieee_extended (fmt, r, buf); +} + +/* Convert from the internal format to the 16-byte Intel format for + an IEEE extended real. */ static void -decode_ieee_extended_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r, - const long *buf) +decode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r, + const long *buf) { - decode_ieee_extended (fmt, r, buf+!!FLOAT_WORDS_BIG_ENDIAN); + /* All the padding in an Intel-format extended real goes at the high end. */ + decode_ieee_extended_intel_96 (fmt, r, buf); } const struct real_format ieee_extended_motorola_format = { - encode_ieee_extended, - decode_ieee_extended, + encode_ieee_extended_motorola, + decode_ieee_extended_motorola, 2, 1, 64, @@ -3162,8 +3243,8 @@ const struct real_format ieee_extended_motorola_format = const struct real_format ieee_extended_intel_96_format = { - encode_ieee_extended, - decode_ieee_extended, + encode_ieee_extended_intel_96, + decode_ieee_extended_intel_96, 2, 1, 64, @@ -3180,8 +3261,8 @@ const struct real_format ieee_extended_intel_96_format = const struct real_format ieee_extended_intel_128_format = { - encode_ieee_extended_128, - decode_ieee_extended_128, + encode_ieee_extended_intel_128, + decode_ieee_extended_intel_128, 2, 1, 64, @@ -3200,8 +3281,8 @@ const struct real_format ieee_extended_intel_128_format = to 53 bits instead of 64, e.g. FreeBSD. */ const struct real_format ieee_extended_intel_96_round_53_format = { - encode_ieee_extended, - decode_ieee_extended, + encode_ieee_extended_intel_96, + decode_ieee_extended_intel_96, 2, 1, 53, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 286cbb60575..9411b50a196 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-17 Zack Weinberg + + Bug 14610 + * gcc.dg/ia64-float80-1.c, gcc.dg/ia64-float80-2.c: New testcases. + 2004-06-15 Richard Henderson * gcc.dg/20001116-1.c: Move expected warning line. @@ -91,7 +96,7 @@ PR fortran/14957 * gfortran.fortran-torture/execute/stack_varsize.f90: Correct - syntax errors in end statements of contained subroutines. + syntax errors in end statements of contained subroutines. 2004-06-12 Tobias Schlueter @@ -192,7 +197,7 @@ 2004-06-09 Bud Davis - PR gfortran/15755 + PR gfortran/15755 * gfortran.fortran-torture/execute/backspace.c : New test. 2004-06-09 Paul Brook diff --git a/gcc/testsuite/gcc.dg/ia64-float80-1.c b/gcc/testsuite/gcc.dg/ia64-float80-1.c new file mode 100644 index 00000000000..dd39f3eb59a --- /dev/null +++ b/gcc/testsuite/gcc.dg/ia64-float80-1.c @@ -0,0 +1,12 @@ +/* Bug 14610 */ +/* { dg-do run { target ia64-*-* } } */ + +extern void abort(void); +volatile __float80 x = 30.0; + +int main(void) +{ + double d = x; + if (d != 30.0) abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ia64-float80-2.c b/gcc/testsuite/gcc.dg/ia64-float80-2.c new file mode 100644 index 00000000000..629312425c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ia64-float80-2.c @@ -0,0 +1,13 @@ +/* Bug 14610 */ +/* { dg-do run { target ia64-*-* } } */ +/* { dg-options "-minline-int-divide-max-throughput" } */ + +extern void abort(void); +volatile int j = 30; + +int main(void) +{ + if (29 % j != 29) abort(); + if (30 % j != 0) abort(); + return 0; +} -- 2.30.2