this repo has no description
at fixPythonPipStalling 123 lines 3.9 kB view raw
1 2/* 3 * required_arithmetic.h 4 * 5 * by Ian Ollmann 6 * 7 * Copyright (c) Apple Inc, 2007. All Rights Reserved. 8 * 9 * The function of this header is to provide various cLibm routines with 10 * interfaces that cause arithmetic to *always* happen. This header is needed 11 * in various places in Libm, because we use arithmetic to set floating point 12 * state flags. Frequently the product of that arithmetic is not used for the 13 * numerical result of the function, so the compiler erroneously optimizes 14 * it away. The intent of this header is to provide basic operators that 15 * utilize compiler and/or platform specific devices (such as volatile asms) 16 * to prevent the compiler from optimizing away the arithmetic. If no such 17 * device is available, you can encapsulate these operations as non-inlined 18 * functions with the implementation in a separate compilation unit or static 19 * library as required to prevent the compiler from removing them. 20 * 21 * Sample implementations are provided for __i386__, both as sample code and 22 * so we can test the library. Other architectures are required to provide 23 * their own implementation. 24 * 25 */ 26 27#if defined( __GNUC__ ) 28 #define ALWAYS_INLINE_NO_DEBUG __attribute__ (( __always_inline__, __nodebug__ )) 29#else 30 #define ALWAYS_INLINE_NO_DEBUG 31#endif 32 33#ifndef __arm__ 34 #error This file is for ARM with VFP only 35#endif 36 37 38#pragma mark - 39#pragma mark Declarations 40 41static inline float required_add_float( float a, float b ) ALWAYS_INLINE_NO_DEBUG; 42static inline float required_multiply_float( float a, float b ) ALWAYS_INLINE_NO_DEBUG; 43static inline float required_divide_float( float a, float b ) ALWAYS_INLINE_NO_DEBUG; 44static inline int required_convert_float_to_int( float a ) ALWAYS_INLINE_NO_DEBUG; 45 46static inline double required_add_double( double a, double b ) ALWAYS_INLINE_NO_DEBUG; 47static inline double required_multiply_double( double a, double b ) ALWAYS_INLINE_NO_DEBUG; 48static inline double required_divide_double( double a, double b ) ALWAYS_INLINE_NO_DEBUG; 49static inline int required_convert_double_to_int( double a ) ALWAYS_INLINE_NO_DEBUG; 50 51#pragma mark - 52#pragma mark Implementation 53 54// --------------------- single precision ------------------------- 55 56static inline float required_add_float( float a, float b ) 57{ 58 register float r; 59 __asm__ __volatile__ ( "fadds %0, %1, %2" : "=w" (r) : "w" (a), "w" (b) ); 60 return r; 61} 62 63static inline float required_multiply_float( float a, float b ) 64{ 65 register float r; 66 __asm__ __volatile__ ( "fmuls %0, %1, %2" : "=w" (r) : "w" (a), "w" (b) ); 67 return r; 68} 69 70static inline float required_divide_float( float a, float b ) 71{ 72 register float r; 73 __asm__ __volatile__ ( "fdivs %0, %1, %2" : "=w" (r) : "w" (a), "w" (b) ); 74 return r; 75} 76 77//rounds toward zero 78static inline int required_convert_float_to_int( float a ) 79{ 80 register float temp; 81 register int result; 82 83 __asm__ __volatile__ ( "ftosizs %0, %1" : "=w" (temp) : "w" (a) ); 84 __asm__ __volatile__ ( "fmrs %0, %1" : "=r" (result) : "w" (temp) ); 85 86 return result; 87} 88 89// ---------------- double precision -------------------------- 90 91static inline double required_add_double( double a, double b ) 92{ 93 register double r; 94 __asm__ __volatile__ ( "faddd %P0, %P1, %P2" : "=w" (r) : "w" (a), "w" (b) ); 95 return r; 96} 97 98static inline double required_multiply_double( double a, double b ) 99{ 100 register double r; 101 __asm__ __volatile__ ( "fmuld %P0, %P1, %P2" : "=w" (r) : "w" (a), "w" (b) ); 102 return r; 103} 104 105static inline double required_divide_double( double a, double b ) 106{ 107 register double r; 108 __asm__ __volatile__ ( "fdivd %P0, %P1, %P2" : "=w" (r) : "w" (a), "w" (b) ); 109 return r; 110} 111 112//rounds toward zero 113static inline int required_convert_double_to_int( double a ) 114{ 115 register float temp; 116 register int result; 117 118 __asm__ __volatile__ ( "ftosizd %0, %P1" : "=w" (temp) : "w" (a) ); 119 __asm__ __volatile__ ( "fmrs %0, %1" : "=r" (result) : "w" (temp) ); 120 121 return result; 122} 123