This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
NV_INF/NV_NAN fallback where int32 is coerced to IEEE754 float.
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 4bd7c92..865daa8 100644 (file)
--- a/perl.h
+++ b/perl.h
 
 /* gcc -Wall:
  * for silencing unused variables that are actually used most of the time,
- * but we cannot quite get rid of, such as "ax" in PPCODE+noargs xsubs
+ * but we cannot quite get rid of, such as "ax" in PPCODE+noargs xsubs,
+ * or variables/arguments that are used only in certain configurations.
  */
 #ifndef PERL_UNUSED_ARG
 #  if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */
 #    include <note.h>
 #    define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x))
 #  else
-#    define PERL_UNUSED_ARG(x) ((void)x)
+#    define PERL_UNUSED_ARG(x) ((void)sizeof(x))
 #  endif
 #endif
 #ifndef PERL_UNUSED_VAR
-#  define PERL_UNUSED_VAR(x) ((void)x)
+#  define PERL_UNUSED_VAR(x) ((void)sizeof(x))
 #endif
 
 #if defined(USE_ITHREADS) || defined(PERL_GLOBAL_STRUCT)
@@ -1894,6 +1895,14 @@ typedef NVTYPE NV;
 #       define Perl_floor floorl
 #       define Perl_ceil ceill
 #       define Perl_fmod fmodl
+#       define Perl_acos acosl
+#       define Perl_asin asinl
+#       define Perl_atan atanl
+#       define Perl_cosh coshl
+#       define Perl_log10 log10l
+#       define Perl_sinh sinhl
+#       define Perl_tan tanl
+#       define Perl_tanh tanhl
 #   endif
 /* e.g. libsunmath doesn't have modfl and frexpl as of mid-March 2000 */
 #   ifdef HAS_MODFL
@@ -1992,6 +2001,14 @@ EXTERN_C long double modfl(long double, long double *);
 #   define Perl_modf(x,y) modf(x,y)
 #   define Perl_frexp(x,y) frexp(x,y)
 #   define Perl_ldexp(x,y) ldexp(x,y)
+#   define Perl_acos acos
+#   define Perl_asin asin
+#   define Perl_atan atan
+#   define Perl_cosh cosh
+#   define Perl_log10 log10
+#   define Perl_sinh sinh
+#   define Perl_tan tan
+#   define Perl_tanh tanh
 #   ifndef Perl_isnan
 #       ifdef HAS_ISNAN
 #           define Perl_isnan(x) isnan(x)
@@ -2032,7 +2049,7 @@ EXTERN_C long double modfl(long double, long double *);
 #        define Perl_fp_class(x)       fpclassify(x)
 #        define Perl_fp_class_pinf(x)  (Perl_fp_class(x)==FP_PLUS_INF)
 #        define Perl_fp_class_ninf(x)  (Perl_fp_class(x)==FP_MINUS_INF)
-#        define Perl_fp_class_snan(x)  (Perl_fp_class(x)==FP_QNAN)
+#        define Perl_fp_class_snan(x)  (Perl_fp_class(x)==FP_SNAN)
 #        define Perl_fp_class_qnan(x)  (Perl_fp_class(x)==FP_QNAN)
 #        define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_PLUS_NORM)
 #        define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_MINUS_NORM)
@@ -2052,6 +2069,9 @@ EXTERN_C long double modfl(long double, long double *);
 #    ifdef __VMS
      /* FP_INFINITE and others are here rather than in math.h as C99 stipulates */
 #        include <fp.h>
+     /* oh, and the isnormal macro has a typo in it! */
+#    undef isnormal
+#    define isnormal(x) Perl_fp_class_norm(x)
 #    endif
 #    if defined(FP_INFINITE) && defined(FP_NAN)
 #        define Perl_fp_class(x)       fp_classify(x)
@@ -2194,7 +2214,7 @@ EXTERN_C long double modfl(long double, long double *);
  * returns a set of bits. */
 #    define Perl_fp_class_snan(x) (_fpclass(x) & _FPCLASS_SNAN)
 #    define Perl_fp_class_qnan(x) (_fpclass(x) & _FPCLASS_QNAN)
-#    define Perl_fp_class_nan(x) (_fpclass(x) & (_FPCLASS_QNAN|_FPCLASS_QNAN))
+#    define Perl_fp_class_nan(x) (_fpclass(x) & (_FPCLASS_SNAN|_FPCLASS_QNAN))
 #    define Perl_fp_class_ninf(x) (_fpclass(x) & _FPCLASS_NINF))
 #    define Perl_fp_class_pinf(x) (_fpclass(x) & _FPCLASS_PINF))
 #    define Perl_fp_class_inf(x) (_fpclass(x) & (_FPCLASS_NINF|_FPCLASS_PINF))
@@ -4121,6 +4141,29 @@ END_EXTERN_C
 #  define NV_INF (NV)INF
 #endif
 #if !defined(NV_INF)
+#  if INTSIZE == 4
+/* At this point we assume the IEEE 754 floating point (and of course,
+ * we also assume a floating point format that can encode an infinity).
+ * We will coerce an int32 (which will encode the infinity) into
+ * a 32-bit float, which will then be cast into NV.
+ *
+ * Note that we intentionally use a float and 32-bit int, instead of
+ * shifting a small integer into a full IV, and from that into a full
+ * NV, because:
+ *
+ * (1) an IV might not be wide enough to cover all the bits of an NV.
+ * (2) the exponent part (including the infinity and nan bits) of a NV
+ *     might be wider than just 16 bits.
+ *
+ * Below the NV_NAN logic has similar __PL_nan_u fallback, the only
+ * difference being the int32 constant being coerced. */
+#    define __PL_inf_float_int32 0x7F800000
+static const union { unsigned int __i; float __f; } __PL_inf_u =
+    { __PL_inf_float_int32 };
+#    define NV_INF ((NV)(__PL_inf_u.__f))
+#  endif
+#endif
+#if !defined(NV_INF)
 #  define NV_INF ((NV)1.0/0.0) /* Some compilers will warn. */
 #endif
 
@@ -4153,7 +4196,16 @@ END_EXTERN_C
 #if !defined(NV_NAN) && defined(SNAN)
 #  define NV_NAN (NV)SNAN
 #endif
-#if !defined(NV_NAN) && defined(NV_INF)
+#if !defined(NV_NAN)
+#  if INTSIZE == 4
+/* See the discussion near __PL_inf_u. */
+#    define __PL_nan_float_int32 0x7FC00000
+static const union { unsigned int __i; float __f; } __PL_nan_u =
+    { __PL_nan_float_int32 };
+#    define NV_NAN ((NV)(__PL_nan_u.__f))
+#  endif
+#endif
+#if !defined(NV_NAN)
 #  define NV_NAN ((NV)0.0/0.0) /* Some compilers will warn. */
 #endif