Patchwork [Fortran] PR57496 use finiteq etc. for __float in write_float.def

login
register
mail settings
Submitter Tobias Burnus
Date June 1, 2013, 6:54 p.m.
Message ID <51AA437C.3040605@net-b.de>
Download mbox | patch
Permalink /patch/248088/
State New
Headers show

Comments

Tobias Burnus - June 1, 2013, 6:54 p.m.
Regarding REAL(10): I tried to find out what goes wrong in that case, 
but I failed.

I would really appreciate some help. See PR57496. My feeling is that the 
error is related to x87 FPU vs. CPU handling, but I failed to understand 
why and when it happens.


Regarding REAL(16):

Tobias Burnus wrote:
> Found when looking at the issue of the PR, but unrelated. For 
> __float128, we have to use the libquadmath functions - not the "long 
> double" ones.

Actually, the patch *does* solve the problem for REAL(16). I have now 
attached a slighly updated version, which converts another "isfinite" 
which I missed in the previous patch.

> The patch is rather obvious, though I wonder whether it could clash 
> with some #defines of the system headers on some systems.
> Build and regtested on x86-64-gnu-linux.
> OK for the trunk?

OK?

Tobias
Tobias Burnus - June 3, 2013, 9:24 a.m.
Janne has approved the patch on IRC, hence, I committed it as Rev. 199598.

Thus, the REAL(16) issue is now solved.

However, REAL(10) still fails - and has still to be debugged. See PR.

Tobias

Patch

2013-06-01  Tobias Burnus  <burnus@net-b.de>

	PR fortran/57496
	* io/write_float.def (ISFINITE2Q, ISFINITE2, ISFINITE2L, ISFINITE,
	SIGNBIT2Q, SIGNBIT2, SIGNBIT2L, SIGNBIT, ISNAN2Q, ISNAN2, ISNAN2L,
	ISNAN): New macros.
	(output_float_FMT_G_,WRITE_FLOAT): Use them.

diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index a157f0b..4f0fa72 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -961,6 +961,34 @@  __qmath_(quadmath_snprintf) (buffer, size, "%+-#.*Qf", \
 #endif
 
 
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define ISFINITE2Q(val) finiteq(val)
+#endif
+#define ISFINITE2(val) isfinite(val)
+#define ISFINITE2L(val) isfinite(val)
+
+#define ISFINITE(suff,val) TOKENPASTE(ISFINITE2,suff)(val)
+
+
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define SIGNBIT2Q(val) signbitq(val)
+#endif
+#define SIGNBIT2(val) signbit(val)
+#define SIGNBIT2L(val) signbit(val)
+
+#define SIGNBIT(suff,val) TOKENPASTE(SIGNBIT2,suff)(val)
+
+
+#if defined(GFC_REAL_16_IS_FLOAT128)
+#define ISNAN2Q(val) isnanq(val)
+#endif
+#define ISNAN2(val) isnan(val)
+#define ISNAN2L(val) isnan(val)
+
+#define ISNAN(suff,val) TOKENPASTE(ISNAN2,suff)(val)
+
+
+
 /* Generate corresponding I/O format for FMT_G and output.
    The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
    LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
@@ -1127,7 +1155,7 @@  OUTPUT_FLOAT_FMT_G(16,L)
 {\
     GFC_REAL_ ## x tmp;				\
     tmp = * (GFC_REAL_ ## x *)source;				\
-    if (isfinite (tmp))						\
+    if (ISFINITE (y,tmp))					\
       nprinted = DTOA(y,0,tmp);					\
     else\
       nprinted = -1;\
@@ -1194,10 +1222,10 @@  determine_en_precision (st_parameter_dt *dtp, const fnode *f,
 {\
 	GFC_REAL_ ## x tmp;\
 	tmp = * (GFC_REAL_ ## x *)source;\
-	sign_bit = signbit (tmp);\
-	if (!isfinite (tmp))\
+	sign_bit = SIGNBIT (y,tmp);\
+	if (!ISFINITE (y,tmp))\
 	  { \
-	    write_infnan (dtp, f, isnan (tmp), sign_bit);\
+	    write_infnan (dtp, f, ISNAN (y,tmp), sign_bit);\
 	    return;\
 	  }\
 	tmp = sign_bit ? -tmp : tmp;\