| 1 | /* Configuration for math routines. | 
| 2 |    Copyright (C) 2017-2018 Free Software Foundation, Inc. | 
| 3 |    This file is part of the GNU C Library. | 
| 4 |  | 
| 5 |    The GNU C Library is free software; you can redistribute it and/or | 
| 6 |    modify it under the terms of the GNU Lesser General Public | 
| 7 |    License as published by the Free Software Foundation; either | 
| 8 |    version 2.1 of the License, or (at your option) any later version. | 
| 9 |  | 
| 10 |    The GNU C Library is distributed in the hope that it will be useful, | 
| 11 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 12 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 13 |    Lesser General Public License for more details. | 
| 14 |  | 
| 15 |    You should have received a copy of the GNU Lesser General Public | 
| 16 |    License along with the GNU C Library; if not, see | 
| 17 |    <http://www.gnu.org/licenses/>.  */ | 
| 18 |  | 
| 19 | #ifndef _MATH_CONFIG_H | 
| 20 | #define _MATH_CONFIG_H | 
| 21 |  | 
| 22 | #include <math.h> | 
| 23 | #include <math_private.h> | 
| 24 | #include <nan-high-order-bit.h> | 
| 25 | #include <stdint.h> | 
| 26 |  | 
| 27 | #ifndef WANT_ROUNDING | 
| 28 | /* Correct special case results in non-nearest rounding modes.  */ | 
| 29 | # define WANT_ROUNDING 1 | 
| 30 | #endif | 
| 31 | #ifndef WANT_ERRNO | 
| 32 | /* Set errno according to ISO C with (math_errhandling & MATH_ERRNO) != 0.  */ | 
| 33 | # define WANT_ERRNO 1 | 
| 34 | #endif | 
| 35 | #ifndef WANT_ERRNO_UFLOW | 
| 36 | /* Set errno to ERANGE if result underflows to 0 (in all rounding modes).  */ | 
| 37 | # define WANT_ERRNO_UFLOW (WANT_ROUNDING && WANT_ERRNO) | 
| 38 | #endif | 
| 39 |  | 
| 40 | #ifndef TOINT_INTRINSICS | 
| 41 | # define TOINT_INTRINSICS 0 | 
| 42 | #endif | 
| 43 | #ifndef TOINT_RINT | 
| 44 | # define TOINT_RINT 0 | 
| 45 | #endif | 
| 46 | #ifndef TOINT_SHIFT | 
| 47 | # define TOINT_SHIFT 1 | 
| 48 | #endif | 
| 49 |  | 
| 50 | static inline uint32_t | 
| 51 | asuint (float f) | 
| 52 | { | 
| 53 |   union | 
| 54 |   { | 
| 55 |     float f; | 
| 56 |     uint32_t i; | 
| 57 |   } u = {f}; | 
| 58 |   return u.i; | 
| 59 | } | 
| 60 |  | 
| 61 | static inline float | 
| 62 | asfloat (uint32_t i) | 
| 63 | { | 
| 64 |   union | 
| 65 |   { | 
| 66 |     uint32_t i; | 
| 67 |     float f; | 
| 68 |   } u = {i}; | 
| 69 |   return u.f; | 
| 70 | } | 
| 71 |  | 
| 72 | static inline uint64_t | 
| 73 | asuint64 (double f) | 
| 74 | { | 
| 75 |   union | 
| 76 |   { | 
| 77 |     double f; | 
| 78 |     uint64_t i; | 
| 79 |   } u = {f}; | 
| 80 |   return u.i; | 
| 81 | } | 
| 82 |  | 
| 83 | static inline double | 
| 84 | asdouble (uint64_t i) | 
| 85 | { | 
| 86 |   union | 
| 87 |   { | 
| 88 |     uint64_t i; | 
| 89 |     double f; | 
| 90 |   } u = {i}; | 
| 91 |   return u.f; | 
| 92 | } | 
| 93 |  | 
| 94 | static inline int | 
| 95 | issignalingf_inline (float x) | 
| 96 | { | 
| 97 |   uint32_t ix = asuint (x); | 
| 98 |   if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN) | 
| 99 |     return (ix & 0x7fc00000) == 0x7fc00000; | 
| 100 |   return 2 * (ix ^ 0x00400000) > 2u * 0x7fc00000; | 
| 101 | } | 
| 102 |  | 
| 103 | #define NOINLINE __attribute__ ((noinline)) | 
| 104 |  | 
| 105 | attribute_hidden float __math_oflowf (uint32_t); | 
| 106 | attribute_hidden float __math_uflowf (uint32_t); | 
| 107 | attribute_hidden float __math_may_uflowf (uint32_t); | 
| 108 | attribute_hidden float __math_divzerof (uint32_t); | 
| 109 | attribute_hidden float __math_invalidf (float); | 
| 110 |  | 
| 111 | /* Shared between expf, exp2f and powf.  */ | 
| 112 | #define EXP2F_TABLE_BITS 5 | 
| 113 | #define EXP2F_POLY_ORDER 3 | 
| 114 | extern const struct exp2f_data | 
| 115 | { | 
| 116 |   uint64_t tab[1 << EXP2F_TABLE_BITS]; | 
| 117 |   double shift_scaled; | 
| 118 |   double poly[EXP2F_POLY_ORDER]; | 
| 119 |   double shift; | 
| 120 |   double invln2_scaled; | 
| 121 |   double poly_scaled[EXP2F_POLY_ORDER]; | 
| 122 | } __exp2f_data attribute_hidden; | 
| 123 |  | 
| 124 | #define LOGF_TABLE_BITS 4 | 
| 125 | #define LOGF_POLY_ORDER 4 | 
| 126 | extern const struct logf_data | 
| 127 | { | 
| 128 |   struct | 
| 129 |   { | 
| 130 |     double invc, logc; | 
| 131 |   } tab[1 << LOGF_TABLE_BITS]; | 
| 132 |   double ln2; | 
| 133 |   double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1.  */ | 
| 134 | } __logf_data attribute_hidden; | 
| 135 |  | 
| 136 | #define LOG2F_TABLE_BITS 4 | 
| 137 | #define LOG2F_POLY_ORDER 4 | 
| 138 | extern const struct log2f_data | 
| 139 | { | 
| 140 |   struct | 
| 141 |   { | 
| 142 |     double invc, logc; | 
| 143 |   } tab[1 << LOG2F_TABLE_BITS]; | 
| 144 |   double poly[LOG2F_POLY_ORDER]; | 
| 145 | } __log2f_data attribute_hidden; | 
| 146 |  | 
| 147 | #define POWF_LOG2_TABLE_BITS 4 | 
| 148 | #define POWF_LOG2_POLY_ORDER 5 | 
| 149 | #if TOINT_INTRINSICS | 
| 150 | # define POWF_SCALE_BITS EXP2F_TABLE_BITS | 
| 151 | #else | 
| 152 | # define POWF_SCALE_BITS 0 | 
| 153 | #endif | 
| 154 | #define POWF_SCALE ((double) (1 << POWF_SCALE_BITS)) | 
| 155 | extern const struct powf_log2_data | 
| 156 | { | 
| 157 |   struct | 
| 158 |   { | 
| 159 |     double invc, logc; | 
| 160 |   } tab[1 << POWF_LOG2_TABLE_BITS]; | 
| 161 |   double poly[POWF_LOG2_POLY_ORDER]; | 
| 162 | } __powf_log2_data attribute_hidden; | 
| 163 |  | 
| 164 | #endif | 
| 165 |  |