This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
IRIX: floating point: do not flush to zero
authorJarkko Hietaniemi <jhi@iki.fi>
Wed, 4 Mar 2015 00:15:25 +0000 (19:15 -0500)
committerJarkko Hietaniemi <jhi@iki.fi>
Wed, 4 Mar 2015 01:00:14 +0000 (20:00 -0500)
Fix for [perl #123767] IRIX64 blead (ddce084a) opbasic/arith.t failure

Use the PERL_SYS_FPU_INIT to initialize the FPU flags appropriately.

perl.h
t/opbasic/arith.t

diff --git a/perl.h b/perl.h
index 1df9e71..109ab6a 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -2918,6 +2918,26 @@ typedef struct padname PADNAME;
          signal(SIGFPE, SIG_IGN); \
      } STMT_END
 #endif
+/* In IRIX the default for Flush to Zero bit is true,
+ * which means that results going below the minimum of normal
+ * floating points go to zero, instead of going denormal/subnormal.
+ * This is unlike almost any other system running Perl, so let's clear it.
+ * [perl #123767] IRIX64 blead (ddce084a) opbasic/arith.t failure, originally
+ * [perl #120426] small numbers shouldn't round to zero if they have extra floating digits
+ *
+ * XXX The flush-to-zero behaviour should be a Configure scan.
+ * To change the behaviour usually requires some system-specific
+ * incantation, though, like the below. */
+#ifdef __sgi
+#  include <sys/fpu.h>
+#  define PERL_SYS_FPU_INIT \
+     STMT_START { \
+         union fpc_csr csr; \
+         csr.fc_word = get_fpc_csr(); \
+         csr.fc_struct.flush = 0; \
+         set_fpc_csr(csr.fc_word); \
+     } STMT_END
+#endif
 
 #ifndef PERL_SYS_FPU_INIT
 #  define PERL_SYS_FPU_INIT NOOP
index 3493968..7992260 100644 (file)
@@ -467,6 +467,7 @@ try $T++,  0.153000e-305 != 0.0,           '0.153000e-305';
 try $T++,  0.1530000e-305 != 0.0,          '0.1530000e-305';
 try $T++,  0.1530001e-305 != 0.0,          '0.1530001e-305';
 try $T++,  1.17549435100e-38 != 0.0,       'min single';
+# For flush-to-zero systems this may flush-to-zero, see PERL_SYS_FPU_INIT
 try $T++,  2.2250738585072014e-308 != 0.0, 'min double';
 
 # string-to-nv should equal float literals