1 /* $OpenBSD: math_private.h,v 1.17 2014/06/02 19:31:17 kettenis Exp $ */ 2 /* 3 * ==================================================== 4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5 * 6 * Developed at SunPro, a Sun Microsystems, Inc. business. 7 * Permission to use, copy, modify, and distribute this 8 * software is freely granted, provided that this notice 9 * is preserved. 10 * ==================================================== 11 */ 12 13 /* 14 * from: @(#)fdlibm.h 5.1 93/09/24 15 */ 16 17 #ifndef _MATH_PRIVATE_OPENBSD_H_ 18 #define _MATH_PRIVATE_OPENBSD_H_ 19 20 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ 21 22 typedef union 23 { 24 long double value; 25 struct { 26 u_int32_t mswhi; 27 u_int32_t mswlo; 28 u_int32_t lswhi; 29 u_int32_t lswlo; 30 } parts32; 31 struct { 32 u_int64_t msw; 33 u_int64_t lsw; 34 } parts64; 35 } ieee_quad_shape_type; 36 37 #endif 38 39 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ 40 41 typedef union 42 { 43 long double value; 44 struct { 45 u_int32_t lswlo; 46 u_int32_t lswhi; 47 u_int32_t mswlo; 48 u_int32_t mswhi; 49 } parts32; 50 struct { 51 u_int64_t lsw; 52 u_int64_t msw; 53 } parts64; 54 } ieee_quad_shape_type; 55 56 #endif 57 58 /* Get two 64 bit ints from a long double. */ 59 60 #define GET_LDOUBLE_WORDS64(ix0,ix1,d) \ 61 do { \ 62 ieee_quad_shape_type qw_u; \ 63 qw_u.value = (d); \ 64 (ix0) = qw_u.parts64.msw; \ 65 (ix1) = qw_u.parts64.lsw; \ 66 } while (0) 67 68 /* Set a long double from two 64 bit ints. */ 69 70 #define SET_LDOUBLE_WORDS64(d,ix0,ix1) \ 71 do { \ 72 ieee_quad_shape_type qw_u; \ 73 qw_u.parts64.msw = (ix0); \ 74 qw_u.parts64.lsw = (ix1); \ 75 (d) = qw_u.value; \ 76 } while (0) 77 78 /* Get the more significant 64 bits of a long double mantissa. */ 79 80 #define GET_LDOUBLE_MSW64(v,d) \ 81 do { \ 82 ieee_quad_shape_type sh_u; \ 83 sh_u.value = (d); \ 84 (v) = sh_u.parts64.msw; \ 85 } while (0) 86 87 /* Set the more significant 64 bits of a long double mantissa from an int. */ 88 89 #define SET_LDOUBLE_MSW64(d,v) \ 90 do { \ 91 ieee_quad_shape_type sh_u; \ 92 sh_u.value = (d); \ 93 sh_u.parts64.msw = (v); \ 94 (d) = sh_u.value; \ 95 } while (0) 96 97 /* Get the least significant 64 bits of a long double mantissa. */ 98 99 #define GET_LDOUBLE_LSW64(v,d) \ 100 do { \ 101 ieee_quad_shape_type sh_u; \ 102 sh_u.value = (d); \ 103 (v) = sh_u.parts64.lsw; \ 104 } while (0) 105 106 /* A union which permits us to convert between a long double and 107 three 32 bit ints. */ 108 109 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ 110 111 typedef union 112 { 113 long double value; 114 struct { 115 #ifdef __LP64__ 116 int padh:32; 117 #endif 118 int exp:16; 119 int padl:16; 120 u_int32_t msw; 121 u_int32_t lsw; 122 } parts; 123 } ieee_extended_shape_type; 124 125 #endif 126 127 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ 128 129 typedef union 130 { 131 long double value; 132 struct { 133 u_int32_t lsw; 134 u_int32_t msw; 135 int exp:16; 136 int padl:16; 137 #ifdef __LP64__ 138 int padh:32; 139 #endif 140 } parts; 141 } ieee_extended_shape_type; 142 143 #endif 144 145 /* Get three 32 bit ints from a double. */ 146 147 #define GET_LDOUBLE_WORDS(se,ix0,ix1,d) \ 148 do { \ 149 ieee_extended_shape_type ew_u; \ 150 ew_u.value = (d); \ 151 (se) = ew_u.parts.exp; \ 152 (ix0) = ew_u.parts.msw; \ 153 (ix1) = ew_u.parts.lsw; \ 154 } while (0) 155 156 /* Set a double from two 32 bit ints. */ 157 158 #define SET_LDOUBLE_WORDS(d,se,ix0,ix1) \ 159 do { \ 160 ieee_extended_shape_type iw_u; \ 161 iw_u.parts.exp = (se); \ 162 iw_u.parts.msw = (ix0); \ 163 iw_u.parts.lsw = (ix1); \ 164 (d) = iw_u.value; \ 165 } while (0) 166 167 /* Get the more significant 32 bits of a long double mantissa. */ 168 169 #define GET_LDOUBLE_MSW(v,d) \ 170 do { \ 171 ieee_extended_shape_type sh_u; \ 172 sh_u.value = (d); \ 173 (v) = sh_u.parts.msw; \ 174 } while (0) 175 176 /* Set the more significant 32 bits of a long double mantissa from an int. */ 177 178 #define SET_LDOUBLE_MSW(d,v) \ 179 do { \ 180 ieee_extended_shape_type sh_u; \ 181 sh_u.value = (d); \ 182 sh_u.parts.msw = (v); \ 183 (d) = sh_u.value; \ 184 } while (0) 185 186 /* Get int from the exponent of a long double. */ 187 188 #define GET_LDOUBLE_EXP(se,d) \ 189 do { \ 190 ieee_extended_shape_type ge_u; \ 191 ge_u.value = (d); \ 192 (se) = ge_u.parts.exp; \ 193 } while (0) 194 195 /* Set exponent of a long double from an int. */ 196 197 #define SET_LDOUBLE_EXP(d,se) \ 198 do { \ 199 ieee_extended_shape_type se_u; \ 200 se_u.value = (d); \ 201 se_u.parts.exp = (se); \ 202 (d) = se_u.value; \ 203 } while (0) 204 205 /* 206 * Common routine to process the arguments to nan(), nanf(), and nanl(). 207 */ 208 void __scan_nan(uint32_t *__words, int __num_words, const char *__s); 209 210 /* 211 * Functions internal to the math package, yet not static. 212 */ 213 double __exp__D(double, double); 214 struct Double __log__D(double); 215 long double __p1evll(long double, void *, int); 216 long double __polevll(long double, void *, int); 217 218 #endif /* _MATH_PRIVATE_OPENBSD_H_ */ 219