this repo has no description
at fixPythonPipStalling 280 lines 13 kB view raw
1/* 2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22/******************************************************************************* 23* * 24* File logb.c, * 25* Functions logb. * 26* Implementation of IEEE-754 logb for the PowerPC platforms. * 27* * 28* Copyright � 1991-2001 Apple Computer, Inc. All rights reserved. * 29* * 30* Written by A. Sazegari, started on June 1991. * 31* Modified and ported by Robert A. Murley (ram) for Mac OS X. * 32* * 33* A MathLib v4 file. * 34* * 35* Change History (most recent last): * 36* * 37* August 26 1991: removed CFront Version 1.1d17 warnings. * 38* August 27 1991: no errors reported by the test suite. * 39* November 11 1991: changed CLASSEXTENDED to the macro CLASSIFY and * 40* + or - infinity to constants. * 41* November 18 1991: changed the macro CLASSIFY to CLASSEXTENDEDint to * 42* improve performance. * 43* February 07 1992: changed bit operations to macros ( object size is * 44* unchanged ). * 45* September 24 1992: took the "#include support.h" out. * 46* December 03 1992: first rs/6000 port. * 47* August 30 1992: set the divide by zero for the zero argument case. * 48* October 05 1993: corrected the environment. * 49* October 17 1994: replaced all environmental functions with __setflm. * 50* May 28 1997: made speed improvements. * 51* April 30 2001: first mac os x port using gcc. * 52* July 16 2001: replaced __setflm with FEGETENVD/FESETENVD. * 53* August 28 2001: added description of logb function. * 54* September 06 2001: added #if __ppc__. * 55* September 09 2001: added more comments. * 56* September 10 2001: added macros to detect PowerPC and correct compiler. * 57* October 08 2001: removed <CoreServices/CoreServices.h>. * 58* changed compiler errors to warnings. * 59* November 06 2001: commented out warning about Intel architectures. * 60* * 61* W A R N I N G: * 62* These routines require a 64-bit double precision IEEE-754 model. * 63* They are written for PowerPC only and are expecting the compiler * 64* to generate the correct sequence of multiply-add fused instructions. * 65* * 66* These routines are not intended for 32-bit Intel architectures. * 67* * 68* A version of gcc higher than 932 is required. * 69* * 70* GCC compiler options: * 71* optimization level 3 (-O3) * 72* -fschedule-insns -finline-functions -funroll-all-loops * 73* * 74******************************************************************************** 75* The C math library offers a similar function called "frexp". It is * 76* different in details from logb, but similar in spirit. This current * 77* implementation of logb follows the recommendation in IEEE Standard 854 * 78* which is different in its handling of denormalized numbers from the IEEE * 79* Standard 754. * 80*******************************************************************************/ 81 82#include "math.h" 83#include "fenv.h" 84#include "fp_private.h" 85#include "fenv_private.h" 86 87static const double twoTo52 = 0x1.0p+52; // 4.50359962737049600e15; 88static const double klTod = 4503601774854144.0; // 0x1.000008p52 89static const hexdouble minusInf = HEXDOUBLE(0xfff00000, 0x00000000); 90 91static const float twoTo23 = 0x1.0p+23f; // 8388608.0e0; 92static const hexsingle minusInff = { 0xff800000 }; 93 94/******************************************************************************* 95* L O G B * 96******************************************************************************** 97* * 98* logb extracts the exponent of its argument, as a signed integral * 99* value. A subnormal argument is treated as though it were first * 100* normalized. Thus * 101* 1 <= x * 2^( - Logb ( x ) ) < 2 * 102*******************************************************************************/ 103 104double logb ( double x ) 105{ 106 hexdouble xInHex; 107 int32_t shiftedExp; 108 109 xInHex.d = x; 110 __NOOP; 111 __NOOP; 112 __NOOP; 113 shiftedExp = ( xInHex.i.hi & 0x7ff00000 ) >> 20; 114 115 if (unlikely( shiftedExp == 2047 )) 116 { // NaN or INF 117 if ( ( ( xInHex.i.hi & 0x80000000 ) == 0 ) || ( x != x ) ) 118 return x; // NaN or +INF return x 119 else 120 return -x; // -INF returns +INF 121 } 122 123 if (likely( shiftedExp != 0 )) // normal number 124 shiftedExp -= 1023; // unbias exponent 125 else if ( x == 0.0 ) 126 { // zero 127 hexdouble OldEnvironment; 128 FEGETENVD_GRP( OldEnvironment.d ); // raise zero divide for DOMAIN error 129 OldEnvironment.i.lo |= FE_DIVBYZERO; 130 FESETENVD_GRP( OldEnvironment.d ); 131 return ( minusInf.d ); // return -infinity 132 } 133 else 134 { // subnormal number 135 xInHex.d *= twoTo52; // scale up 136 __NOOP; 137 __NOOP; 138 __NOOP; 139 shiftedExp = ( xInHex.i.hi & 0x7ff00000 ) >> 20; 140 shiftedExp -= 1075; // unbias exponent 141 } 142 143 if (unlikely( shiftedExp == 0 )) // zero result 144 return ( 0.0 ); 145 else 146 { // nonzero result 147 xInHex.d = klTod; 148 __NOOP; 149 __NOOP; 150 __NOOP; 151 xInHex.i.lo += shiftedExp; 152 return ( xInHex.d - klTod ); 153 } 154} 155 156int ilogb ( double x ) 157{ 158 hexdouble xInHex; 159 int32_t shiftedExp; 160 161 xInHex.d = x; 162 __NOOP; 163 __NOOP; 164 __NOOP; 165 shiftedExp = ( xInHex.i.hi & 0x7ff00000 ) >> 20; 166 167 if (unlikely( shiftedExp == 2047 )) 168 { // NaN or INF 169 if (x != x) 170 return FP_ILOGBNAN; 171 else 172 { 173 feraiseexcept( FE_INVALID ); // raise invalid for DOMAIN error 174 return INT32_MAX; 175 } 176 } 177 178 if (likely( shiftedExp != 0 )) // normal number 179 shiftedExp -= 1023; // unbias exponent 180 else if ( x == 0.0 ) 181 { // zero 182 feraiseexcept( FE_INVALID ); // raise invalid for DOMAIN error 183 return FP_ILOGB0; // return -infinity 184 } 185 else 186 { // subnormal number 187 xInHex.d *= twoTo52; // scale up 188 __NOOP; 189 __NOOP; 190 __NOOP; 191 shiftedExp = ( xInHex.i.hi & 0x7ff00000 ) >> 20; 192 shiftedExp -= 1075; // unbias exponent 193 } 194 195 return shiftedExp; 196} 197 198float logbf ( float x ) 199{ 200 hexsingle xInHex; 201 int32_t shiftedExp; 202 203 xInHex.fval = x; 204 __NOOP; 205 __NOOP; 206 __NOOP; 207 shiftedExp = ( xInHex.lval & 0x7f800000 ) >> 23; 208 209 if (unlikely( shiftedExp == 255 )) 210 { // NaN or INF 211 if ( ( ( xInHex.lval & 0x80000000 ) == 0 ) || ( x != x ) ) 212 return x; // NaN or +INF return x 213 else 214 return -x; // -INF returns +INF 215 } 216 217 if (likely( shiftedExp != 0 )) // normal number 218 shiftedExp -= 127; // unbias exponent 219 else if ( x == 0.0 ) 220 { // zero 221 hexdouble OldEnvironment; 222 FEGETENVD_GRP( OldEnvironment.d ); // raise zero divide for DOMAIN error 223 OldEnvironment.i.lo |= FE_DIVBYZERO; 224 FESETENVD_GRP( OldEnvironment.d ); 225 return ( minusInff.fval ); // return -infinity 226 } 227 else 228 { // subnormal number 229 xInHex.fval *= twoTo23; // scale up 230 __NOOP; 231 __NOOP; 232 __NOOP; 233 shiftedExp = ( xInHex.lval & 0x7f800000 ) >> 23; 234 shiftedExp -= 150; // unbias exponent 235 } 236 237 return (float)shiftedExp; 238} 239 240int ilogbf ( float x ) 241{ 242 hexsingle xInHex; 243 int32_t shiftedExp; 244 245 xInHex.fval = x; 246 __NOOP; 247 __NOOP; 248 __NOOP; 249 shiftedExp = ( xInHex.lval & 0x7f800000 ) >> 23; 250 251 if (unlikely( shiftedExp == 255 )) 252 { // NaN or INF 253 if (x != x) 254 return FP_ILOGBNAN; 255 else 256 { 257 feraiseexcept( FE_INVALID ); // raise invalid for DOMAIN error 258 return INT32_MAX; 259 } 260 } 261 262 if (likely( shiftedExp != 0 )) // normal number 263 shiftedExp -= 127; // unbias exponent 264 else if ( x == 0.0 ) 265 { // zero 266 feraiseexcept( FE_INVALID ); // raise invalid for DOMAIN error 267 return FP_ILOGB0; // return -infinity 268 } 269 else 270 { // subnormal number 271 xInHex.fval *= twoTo23; // scale up 272 __NOOP; 273 __NOOP; 274 __NOOP; 275 shiftedExp = ( xInHex.lval & 0x7f800000 ) >> 23; 276 shiftedExp -= 150; // unbias exponent 277 } 278 279 return shiftedExp; 280}