1 /* 2 * Replacements for missing platform functions. 3 * 4 * Unlike the originals, fpclassify() and signbit() replacements don't 5 * work on any floating point types, only doubles. The C typing here 6 * mimics the standard prototypes. 7 */ 8 9 #include "duk_internal.h" 10 11 #if defined(DUK_USE_COMPUTED_NAN) 12 DUK_INTERNAL double duk_computed_nan; 13 #endif 14 15 #if defined(DUK_USE_COMPUTED_INFINITY) 16 DUK_INTERNAL double duk_computed_infinity; 17 #endif 18 19 #if defined(DUK_USE_REPL_FPCLASSIFY) duk_repl_fpclassify(double x)20DUK_INTERNAL int duk_repl_fpclassify(double x) { 21 duk_double_union u; 22 duk_uint_fast16_t expt; 23 duk_small_int_t mzero; 24 25 u.d = x; 26 expt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL); 27 if (expt > 0x0000UL && expt < 0x7ff0UL) { 28 /* expt values [0x001,0x7fe] = normal */ 29 return DUK_FP_NORMAL; 30 } 31 32 mzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0); 33 if (expt == 0x0000UL) { 34 /* expt 0x000 is zero/subnormal */ 35 if (mzero) { 36 return DUK_FP_ZERO; 37 } else { 38 return DUK_FP_SUBNORMAL; 39 } 40 } else { 41 /* expt 0xfff is infinite/nan */ 42 if (mzero) { 43 return DUK_FP_INFINITE; 44 } else { 45 return DUK_FP_NAN; 46 } 47 } 48 } 49 #endif 50 51 #if defined(DUK_USE_REPL_SIGNBIT) duk_repl_signbit(double x)52DUK_INTERNAL int duk_repl_signbit(double x) { 53 duk_double_union u; 54 u.d = x; 55 return (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL); 56 } 57 #endif 58 59 #if defined(DUK_USE_REPL_ISFINITE) duk_repl_isfinite(double x)60DUK_INTERNAL int duk_repl_isfinite(double x) { 61 int c = DUK_FPCLASSIFY(x); 62 if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) { 63 return 0; 64 } else { 65 return 1; 66 } 67 } 68 #endif 69 70 #if defined(DUK_USE_REPL_ISNAN) duk_repl_isnan(double x)71DUK_INTERNAL int duk_repl_isnan(double x) { 72 int c = DUK_FPCLASSIFY(x); 73 return (c == DUK_FP_NAN); 74 } 75 #endif 76 77 #if defined(DUK_USE_REPL_ISINF) duk_repl_isinf(double x)78DUK_INTERNAL int duk_repl_isinf(double x) { 79 int c = DUK_FPCLASSIFY(x); 80 return (c == DUK_FP_INFINITE); 81 } 82 #endif 83