this repo has no description
at fixPythonPipStalling 376 lines 15 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: fenv.c * 25* * 26* Contains: C source code for PowerPC implementations of floating-point * 27* environmental functions defined in C99. * 28* * 29* Copyright � 1992-2001 Apple Computer, Inc. All rights reserved. * 30* * 31* Written by Jon Okada, started on November 1992. * 32* Modified by A. sazegari (ali) for MathLib v3. * 33* Modified and ported by Robert A. Murley (ram) for Mac OS X. * 34* * 35* A MathLib v4 file. * 36* * 37* Change History (most recent first): * 38* * 39* 06 Nov 01 ram commented out warning about Intel architectures. * 40* 08 Oct 01 ram removed <CoreServices/CoreServices.h>. * 41* changed compiler errors to warnings. * 42* 18 Sep 01 ali added <CoreServices/CoreServices.h> to get <fenv.h>. * 43* 10 Sep 01 ali added macros to detect PowerPC and correct compiler. * 44* 09 Sep 01 ali added more comments. * 45* 05 Sep 01 ram added #ifdef __ppc__. * 46* 16 Jul 01 ram Moved exception flag symbols to fenv_private.h. * 47* Replaced __setflm with FEGETENVD and FESETENVD. * 48* 29 Sep 94 ali use __setflm for generating INEXACT, INVALID and * 49* DIVBYZERO in feraiseexecpt. * 50* 28 Sep 94 PAF Modified to use __setflm * 51* 07 Oct 93 ali corrected a mistake in setting flags for underflow * 52* and overflow in the feraiseexcept * 53* 07 Apr 93 ali included fenv.h and deleted the unnecessary macros * 54* 03 Feb 93 JPO Reflecting changes in NCEG specification, changed * 55* the following functions from type int to void: * 56* feclearexcept, fegetexceptflag, feraiseexcept, and * 57* fesetexceptflag. Changed the functionality of * 58* fesetexceptflag to match interpretation of the author * 59* of the NCEG spec. * 60* 21 Jan 93 JPO Added default environment _FE_DFL_ENV. * 61* 10 Dec 92 JPO Put underscore in names of low level routines * 62* (_getFPSCR and _setFPSCR). * 63* 30 Nov 92 JPO First created. * 64* * 65* W A R N I N G: * 66* These routines require a 64-bit double precision IEEE-754 model. * 67* They are written for PowerPC only and are expecting the compiler * 68* to generate the correct sequence of multiply-add fused instructions. * 69* * 70* These routines are not intended for 32-bit Intel architectures. * 71* * 72* A version of gcc higher than 932 is required. * 73* * 74* GCC compiler options: * 75* optimization level 3 (-O3) * 76* -fschedule-insns -finline-functions -funroll-all-loops * 77* * 78*******************************************************************************/ 79 80#include "fp_private.h" 81#include "fenv_private.h" 82 83/****************************************************************************** 84* Implementations of functions which provide access to the exception flags. * 85* The "int" input argument is constructed by bitwise ORs of the exception * 86* macros defined in fenv.h: for example, FE_OVERFLOW | FE_INEXACT. * 87******************************************************************************/ 88 89static int _fegetexceptflag ( fexcept_t *flagp, int excepts ) 90{ 91 hexdouble temp; 92 fenv_t excstate; 93 uint32_t mask; 94 95 mask = excepts & FE_ALL_EXCEPT; 96 FEGETENVD_GRP( temp.d ); 97 excstate = temp.i.lo & FE_ALL_FLAGS; 98 mask &= excstate; 99 if (mask == 0) 100 *flagp = 0; 101 else { 102 if ( (mask & FE_INVALID) == 0 ) excstate &= FE_NO_INVALID; 103 mask |= FE_NO_EXCEPT; 104 *flagp = excstate & mask; 105 } 106 107 return 0; 108} 109 110static int _fesetexceptflag ( const fexcept_t *flagp, int excepts ) 111{ 112 hexdouble ifpscr; 113 uint32_t mask; 114 115 mask = excepts & FE_ALL_EXCEPT; 116 if (mask != 0) { // take action if mask != 0 117 FEGETENVD_GRP( ifpscr.d ); // read current environment 118 if (excepts & FE_INVALID) // special case: INVALID 119 ifpscr.i.lo = (ifpscr.i.lo & FE_NO_INVALID) | (*flagp & FE_ALL_INVALID); 120 ifpscr.i.lo = (ifpscr.i.lo & (~mask)) | (*flagp & mask); 121 if (ifpscr.i.lo & FE_ALL_EXCEPT) 122 ifpscr.i.lo |= FE_SET_FX; 123 else 124 ifpscr.i.lo &= FE_CLR_FX; 125 FESETENVD_GRP( ifpscr.d ); 126 } 127 128 return 0; 129} 130 131#if defined(BUILDING_FOR_CARBONCORE_LEGACY) 132 133/* default environment object */ 134const fenv_t _FE_DFL_ENV = (const fenv_t) 0L; 135 136/**************************************************************************** 137 the "feclearexcept" function clears the exceptions represented by its 138 argument. 139****************************************************************************/ 140 141int feclearexcept ( int excepts ) 142{ 143 hexdouble ifpscr; 144 uint32_t mask; 145 146 mask = excepts & FE_ALL_EXCEPT; 147 if (( excepts & FE_INVALID) != 0 ) mask |= FE_ALL_INVALID; 148 FEGETENVD_GRP( ifpscr.d ); 149 mask = ~mask; 150 //if (( excepts & FE_INVALID) != 0 ) mask &= FE_NO_INVALID; 151 ifpscr.i.lo &= mask; 152 if (( ifpscr.i.lo & FE_ALL_EXCEPT ) == 0) 153 ifpscr.i.lo &= FE_CLR_FX; 154 FESETENVD_GRP( ifpscr.d ); 155 return 0; 156} 157 158/**************************************************************************** 159 the "feraiseexcept" function raises the exceptions represented by its 160 argument. 161****************************************************************************/ 162 163int feraiseexcept ( int excepts ) 164{ 165 uint32_t mask; 166 hexdouble ifpscr; 167 168 mask = excepts & FE_ALL_EXCEPT; 169 170 FEGETENVD_GRP( ifpscr.d ); 171 172 if ((mask & FE_INVALID) != 0) 173 { 174 ifpscr.i.lo |= SET_INVALID; 175 mask &= ~FE_INVALID; 176 } 177 178 if (( mask & ( FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INEXACT )) != 0) 179 ifpscr.i.lo |= mask; 180 181 FESETENVD_GRP( ifpscr.d ); 182 return 0; 183} 184 185/**************************************************************************** 186 The function "fetestexcept" determines which of the specified subset of 187 the exception flags are currently set. It returns the bitwise OR of a 188 subset of the exception macros included in "excepts". 189****************************************************************************/ 190 191int fetestexcept ( int excepts ) 192{ 193 hexdouble temp; 194 195 FEGETENVD_GRP( temp.d ); 196 return (int) ((excepts & FE_ALL_EXCEPT) & temp.i.lo); 197} 198 199 200/* The following functions provide control of rounding direction modes. */ 201 202/**************************************************************************** 203 The function "fegetround" returns the value of the rounding direction 204 macro which represents the current rounding direction. 205****************************************************************************/ 206 207int fegetround ( void ) 208{ 209 hexdouble temp; 210 211 FEGETENVD_GRP( temp.d ); 212 return (int) (temp.i.lo & FE_ALL_RND); 213} 214 215 216/**************************************************************************** 217 The function "fesetround" establishes the rounding direction 218 represented by its argument. It returns zero if and only if 219 the argument matches a rounding direction macro. If not, the 220 rounding direction is not changed. 221****************************************************************************/ 222 223int fesetround ( int round ) 224{ 225 if ((round & FE_NO_RND)) 226 return 1; 227 else 228 { 229 hexdouble temp; 230 231 FEGETENVD_GRP( temp.d ); 232 temp.i.lo = (temp.i.lo & FE_NO_RND) | round; 233 FESETENVD_GRP( temp.d ); 234 return 0; 235 } 236} 237 238 239/* The following functions manage the floating-point environment--- 240 exception flags and dynamic modes---as one entity. */ 241 242/**************************************************************************** 243 The function "fgetenv" stores the current environment in the 244 object pointed to by its pointer argument "envp". 245****************************************************************************/ 246 247int fegetenv ( fenv_t *envp ) 248{ 249 hexdouble temp; 250 251 FEGETENVD_GRP( temp.d ); 252 *envp = temp.i.lo; 253 return 0; 254} 255 256 257/**************************************************************************** 258 The function "feholdexcept" saves the current environment in 259 the object pointed to by its argument "envp" and clears the 260 exception flags. It returns zero. This function supersedes 261 the SANE function "procentry". 262****************************************************************************/ 263 264int feholdexcept ( fenv_t *envp ) 265{ 266 hexdouble ifpscr; 267 268 FEGETENVD_GRP( ifpscr.d ); 269 *envp = ifpscr.i.lo; 270 ifpscr.i.lo &= (FE_NO_FLAGS & FE_NO_ENABLES); 271 FESETENVD_GRP( ifpscr.d ); 272 return 0; 273} 274 275 276/**************************************************************************** 277 The function "fesetenv" establishes the floating-point environment 278 represented by the object pointed to by its argument "envp". The 279 value of "*env_p" must be set by a call to "fegetenv" or 280 "feholdexcept", by the macro "FE_DFL_ENV", or by an implementation- 281 defined macro of type "fenv_t". 282****************************************************************************/ 283 284int fesetenv ( const fenv_t *envp ) 285{ 286 hexdouble temp; 287 288 temp.i.lo = *envp; 289 FESETENVD_GRP( temp.d ); 290 291 return 0; 292} 293 294 295/**************************************************************************** 296 The function "feupdateenv" saves the current exceptions in its 297 automatic storage, installs the environment pointed to by its 298 pointer argument "envp", and then re-raises the saved exceptions. 299 This function, which supersedes the SANE function "procexit", can 300 be used in conjunction with "feholdexcept" to write routines which 301 hide spurious exceptions from their callers. 302****************************************************************************/ 303 304int feupdateenv ( const fenv_t *envp ) 305{ 306 int newexc; 307 hexdouble temp; 308 309 FEGETENVD_GRP( temp.d ); 310 newexc = temp.i.lo & FE_ALL_EXCEPT; 311 temp.i.lo = *envp; 312 FESETENVD_GRP( temp.d ); 313 feraiseexcept(newexc); 314 return 0; 315} 316 317/* Legacy entry point */ 318void fegetexcept ( fexcept_t *flagp, int excepts ) 319{ 320 _fegetexceptflag (flagp, excepts ); 321} 322 323/* Legacy entry point */ 324void fesetexcept ( fexcept_t *flagp, int excepts ) 325{ 326 _fesetexceptflag ( flagp, excepts ); 327} 328 329#else /* !BUILDING_FOR_CARBONCORE_LEGACY */ 330 331/**************************************************************************** 332 "fegetexceptflag" stores a representation of the exception flags indicated by 333 the argument "excepts" through the pointer argument "flagp". 334****************************************************************************/ 335 336int fegetexceptflag ( fexcept_t *flagp, int excepts ) 337{ 338 return _fegetexceptflag (flagp, excepts ); 339} 340 341 342/**************************************************************************** 343 "fesetexceptflag" sets the exception flags indicated by the argument "excepts", 344 to the corresponding state represented in the object pointed to by "flagp". 345 This function does not raise exceptions, but only sets the state of the 346 flags. 347****************************************************************************/ 348 349int fesetexceptflag ( const fexcept_t *flagp, int excepts ) 350{ 351 return _fesetexceptflag ( flagp, excepts ); 352} 353 354/**************************************************************************** 355 The float.h macro FLT_ROUNDS has a value derived from fegetround() -- 356 Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown 357****************************************************************************/ 358 359int __fegetfltrounds( void ) 360{ 361 switch ( fegetround() ) 362 { 363 case FE_TONEAREST: 364 return 1; 365 case FE_TOWARDZERO: 366 return 0; 367 case FE_UPWARD: 368 return 2; 369 case FE_DOWNWARD: 370 return 3; 371 default: 372 return -1; 373 } 374} 375 376#endif /* !BUILDING_FOR_CARBONCORE_LEGACY */