From 2bb6de3a7e8d27b8f7ea7139fbee5f33c32bf3e5 Mon Sep 17 00:00:00 2001 From: Jerry DeLisle Date: Sun, 15 Jul 2007 16:26:22 +0000 Subject: [PATCH] re PR libfortran/32611 (Print sign of negative zero) 2007-07-15 Jerry DeLisle Francois-Xavier Coudert PR fortran/32611 * runtime/compile_options.c (set_std): Remove. (set_options): New function. (init_compile_options): Add initialization for -fsign-zero option. * gfortran.map (GFORTRAN_1.0): Rename _gfortran_set_std into _gfortran_set_options. * libgfortran.h (compile_options_t): Add sign_zero field. * io/write.c (output_float): Use the sign bit of the value to determine if a negative sign should be emitted for zero values. Do not emit the negative sign for zero if -fno-sign-zero was set during compile. Co-Authored-By: Francois-Xavier Coudert From-SVN: r126654 --- libgfortran/ChangeLog | 14 ++++++++++++ libgfortran/gfortran.map | 2 +- libgfortran/io/write.c | 22 ++++++++++++++---- libgfortran/libgfortran.h | 1 + libgfortran/runtime/compile_options.c | 33 +++++++++++++++------------ 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 25bb24bfb19..a6b20fb7511 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,17 @@ +2007-07-15 Jerry DeLisle + Francois-Xavier Coudert + + PR fortran/32611 + * runtime/compile_options.c (set_std): Remove. + (set_options): New function. + (init_compile_options): Add initialization for -fsign-zero option. + * gfortran.map (GFORTRAN_1.0): Rename _gfortran_set_std into + _gfortran_set_options. + * libgfortran.h (compile_options_t): Add sign_zero field. + * io/write.c (output_float): Use the sign bit of the value to determine + if a negative sign should be emitted for zero values. Do not emit the + negative sign for zero if -fno-sign-zero was set during compile. + 2007-07-14 Jerry DeLisle PR libgfortran/32752 diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map index 71c809a11f5..76dba0ce406 100644 --- a/libgfortran/gfortran.map +++ b/libgfortran/gfortran.map @@ -590,7 +590,7 @@ GFORTRAN_1.0 { _gfortran_set_fpe; _gfortran_set_max_subrecord_length; _gfortran_set_record_marker; - _gfortran_set_std; + _gfortran_set_options; _gfortran_shape_16; _gfortran_shape_4; _gfortran_shape_8; diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c index 766d268993b..b4e5d3efb8f 100644 --- a/libgfortran/io/write.c +++ b/libgfortran/io/write.c @@ -465,6 +465,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value) int leadzero; int nblanks; int i; + int sign_bit; sign_t sign; ft = f->format; @@ -482,6 +483,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value) For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits after the decimal point, plus another one before the decimal point. */ sign = calculate_sign (dtp, value < 0.0); + sign_bit = signbit (value); if (value < 0) value = -value; @@ -547,9 +549,15 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value) /* Read the exponent back in. */ e = atoi (&buffer[ndigits + 3]) + 1; - /* Make sure zero comes out as 0.0e0. */ + /* Make sure zero comes out as 0.0e0. */ if (value == 0.0) - e = 0; + { + e = 0; + if (compile_options.sign_zero == 1) + sign = calculate_sign (dtp, sign_bit); + else + sign = calculate_sign (dtp, 0); + } /* Normalize the fractional component. */ buffer[2] = buffer[1]; @@ -751,7 +759,14 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value) break; } if (i == ndigits) - sign = calculate_sign (dtp, 0); + { + /* The output is zero, so set the sign according to the sign bit unless + -fno-sign-zero was specified. */ + if (compile_options.sign_zero == 1) + sign = calculate_sign (dtp, sign_bit); + else + sign = calculate_sign (dtp, 0); + } /* Work out how much padding is needed. */ nblanks = w - (nbefore + nzero + nafter + edigits + 1); @@ -776,7 +791,6 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value) /* Pad to full field width. */ - if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank) { memset (out, ' ', nblanks); diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index 8a86f41785d..e0cfa450e29 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -382,6 +382,7 @@ typedef struct int convert; int dump_core; int backtrace; + int sign_zero; size_t record_marker; int max_subrecord_length; } diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index dc404da7b53..0976a39eade 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -1,5 +1,5 @@ /* Handling of compile-time options that influence the library. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU Fortran 95 runtime library (libgfortran). @@ -35,23 +35,25 @@ Boston, MA 02110-1301, USA. */ /* Useful compile-time options will be stored in here. */ compile_options_t compile_options; - -/* Prototypes */ -extern void set_std (GFC_INTEGER_4, GFC_INTEGER_4, GFC_INTEGER_4, - GFC_INTEGER_4, GFC_INTEGER_4); -export_proto(set_std); - +/* Set the usual compile-time options. */ +extern void set_options (int , int []); +export_proto(set_options); void -set_std (GFC_INTEGER_4 warn_std, GFC_INTEGER_4 allow_std, - GFC_INTEGER_4 pedantic, GFC_INTEGER_4 dump_core, - GFC_INTEGER_4 backtrace) +set_options (int num, int options[]) { - compile_options.pedantic = pedantic; - compile_options.warn_std = warn_std; - compile_options.allow_std = allow_std; - compile_options.dump_core = dump_core; - compile_options.backtrace = backtrace; + if (num >= 1) + compile_options.warn_std = options[0]; + if (num >= 2) + compile_options.allow_std = options[1]; + if (num >= 3) + compile_options.pedantic = options[2]; + if (num >= 4) + compile_options.dump_core = options[3]; + if (num >= 5) + compile_options.backtrace = options[4]; + if (num >= 6) + compile_options.sign_zero = options[5]; } @@ -67,6 +69,7 @@ init_compile_options (void) compile_options.pedantic = 0; compile_options.dump_core = 0; compile_options.backtrace = 0; + compile_options.sign_zero = 1; } /* Function called by the front-end to tell us the