summaryrefslogtreecommitdiff
path: root/perl.h
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2015-02-08 12:45:01 -0500
committerJarkko Hietaniemi <jhi@iki.fi>2015-02-08 21:54:51 -0500
commit30419b527d2c5a06cefe2db9183f59e2697c47fc (patch)
tree15c65c264ee110d44c090ee386c480a38bcbb38c /perl.h
parent29b62199cd4c359dfc6b9d690341de40d105ca5f (diff)
downloadperl-30419b527d2c5a06cefe2db9183f59e2697c47fc.tar.gz
infnan: the nan quiet/signaling bit is not enough
Diffstat (limited to 'perl.h')
-rw-r--r--perl.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/perl.h b/perl.h
index cfbadefd6c..b4ac7f5621 100644
--- a/perl.h
+++ b/perl.h
@@ -4363,6 +4363,38 @@ static const union { unsigned int __i; float __f; } __PL_nan_u =
* Though IEEE-754-logically correct, some compilers (like Visual C 2003)
* falsely misoptimize that to zero (x-x is zero, right?) */
+/* x86 80-bit extended precision mantissa bits:
+ *
+ * 63 62 61 30387+ pre-387
+ * -------- ---- --------
+ * 0 0 0 invalid infinity
+ * 0 0 n invalid snan
+ * 0 1 * invalid snan
+ * 1 0 0 infinity snan
+ * 1 0 n snan
+ * 1 1 0 qnan (1.#IND)
+ * 1 1 n qnan
+ *
+ * This means that there are 61 bits for nan payload.
+ */
+#if defined(USE_LONG_DOUBLE) && (LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN)
+# define NV_NAN_BITS 61
+#elif defined(__hppa) /* XXX Configure scan */
+# define NV_NAN_BITS 50 /* qnan: 7f f4 00 00 00 00 00 00 */
+#elif defined(__mips) && UVSIZE == 4 /* IRIX64/MIPS cc -32 */
+# define NV_NAN_BITS 35 /* qnan: 7f ff 2f 30 00 00 00 00
+ * +inf: 7f ff 2f 20 00 00 00 00
+ * -inf: 7f ff 2f 28 00 00 00 00 */
+#else
+# define NV_NAN_BITS (NV_MANT_REAL_DIG - 1)
+#endif
+/* IRIX64/MIPS cc -64 is something bizarre:
+ * qnan 00 00 0f ff ff ff ae 90
+ * +inf 00 00 0f ff ff ff ae 80
+ * -inf 00 00 0f ff ff ff ae 88
+ * In other words, it doesn't seem to follow any IEEE pattern for infnan,
+ * and even seems more little-endian than big-endian. */
+
#ifndef __cplusplus
# if !defined(WIN32) && !defined(VMS)
#ifndef crypt