Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) ===============================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) Arithmetic Package, Release 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) Written by John R. Hauser.  This work was made possible in part by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) International Computer Science Institute, located at Suite 600, 1947 Center
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) Street, Berkeley, California 94704.  Funding was partially provided by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) National Science Foundation under grant MIP-9311980.  The original version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) of this code was written as part of a project to build a fixed-point vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) processor in collaboration with the University of California at Berkeley,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) is available through the Web page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) Derivative works are acceptable, even for commercial purposes, so long as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) (1) they include prominent notice that the work is derivative, and (2) they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) include prominent notice akin to these three paragraphs for those parts of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) this code that are retained.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) ===============================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) Underflow tininess-detection mode, statically initialized to default value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) (The declaration in `softfloat.h' must match the `int8' type here.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) int8 float_detect_tininess = float_tininess_after_rounding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) Raises the exceptions specified by `flags'.  Floating-point traps can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) defined here if desired.  It is currently not possible for such a trap to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) substitute a result value.  If traps are not implemented, this routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) should be simply `float_exception_flags |= flags;'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) ScottB:  November 4, 1998
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) Moved this function out of softfloat-specialize into fpmodule.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) This effectively isolates all the changes required for integrating with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) Linux kernel into fpmodule.c.  Porting to NetBSD should only require modifying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) fpmodule.c to integrate with the NetBSD kernel (I hope!).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) void float_raise( int8 flags )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)     float_exception_flags |= flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) Internal canonical NaN format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)     flag sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)     bits64 high, low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) } commonNaNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) The pattern for a default generated single-precision NaN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define float32_default_nan 0xFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) Returns 1 if the single-precision floating-point value `a' is a NaN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) flag float32_is_nan( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)     return ( 0xFF000000 < (bits32) ( a<<1 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) Returns 1 if the single-precision floating-point value `a' is a signaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) NaN; otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) flag float32_is_signaling_nan( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) Returns the result of converting the single-precision floating-point NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) exception is raised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static commonNaNT float32ToCommonNaN( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)     commonNaNT z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)     z.sign = a>>31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)     z.low = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)     z.high = ( (bits64) a )<<41;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) Returns the result of converting the canonical NaN `a' to the single-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) precision floating-point format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static float32 commonNaNToFloat32( commonNaNT a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) Takes two single-precision floating-point values `a' and `b', one of which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) signaling NaN, the invalid exception is raised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static float32 propagateFloat32NaN( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)     aIsNaN = float32_is_nan( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)     aIsSignalingNaN = float32_is_signaling_nan( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)     bIsNaN = float32_is_nan( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)     bIsSignalingNaN = float32_is_signaling_nan( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)     a |= 0x00400000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)     b |= 0x00400000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)     if ( aIsNaN ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)         return b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) The pattern for a default generated double-precision NaN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) Returns 1 if the double-precision floating-point value `a' is a NaN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) flag float64_is_nan( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Returns 1 if the double-precision floating-point value `a' is a signaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) NaN; otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) flag float64_is_signaling_nan( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) Returns the result of converting the double-precision floating-point NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) exception is raised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static commonNaNT float64ToCommonNaN( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)     commonNaNT z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)     z.sign = a>>63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)     z.low = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)     z.high = a<<12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) Returns the result of converting the canonical NaN `a' to the double-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) precision floating-point format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static float64 commonNaNToFloat64( commonNaNT a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)           ( ( (bits64) a.sign )<<63 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)         | LIT64( 0x7FF8000000000000 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)         | ( a.high>>12 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) Takes two double-precision floating-point values `a' and `b', one of which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) signaling NaN, the invalid exception is raised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static float64 propagateFloat64NaN( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)     aIsNaN = float64_is_nan( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)     aIsSignalingNaN = float64_is_signaling_nan( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)     bIsNaN = float64_is_nan( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)     bIsSignalingNaN = float64_is_signaling_nan( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)     a |= LIT64( 0x0008000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)     b |= LIT64( 0x0008000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)     if ( aIsNaN ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)         return b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #ifdef FLOATX80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) The pattern for a default generated extended double-precision NaN.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) `high' and `low' values hold the most- and least-significant bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #define floatx80_default_nan_high 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) Returns 1 if the extended double-precision floating-point value `a' is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) NaN; otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) flag floatx80_is_nan( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) Returns 1 if the extended double-precision floating-point value `a' is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) signaling NaN; otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) flag floatx80_is_signaling_nan( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)     //register int lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)     bits64 aLow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)     //__asm__("mov %0, lr" : : "g" (lr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)     //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)     aLow = a.low & ~ LIT64( 0x4000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)            ( ( a.high & 0x7FFF ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)         && (bits64) ( aLow<<1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)         && ( a.low == aLow );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) Returns the result of converting the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) invalid exception is raised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static commonNaNT floatx80ToCommonNaN( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)     commonNaNT z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)     z.sign = a.high>>15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)     z.low = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)     z.high = a.low<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) Returns the result of converting the canonical NaN `a' to the extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) double-precision floating-point format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static floatx80 commonNaNToFloatx80( commonNaNT a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)     z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) Takes two extended double-precision floating-point values `a' and `b', one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) of which is a NaN, and returns the appropriate NaN result.  If either `a' or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) `b' is a signaling NaN, the invalid exception is raised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)     aIsNaN = floatx80_is_nan( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)     aIsSignalingNaN = floatx80_is_signaling_nan( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)     bIsNaN = floatx80_is_nan( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)     bIsSignalingNaN = floatx80_is_signaling_nan( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)     a.low |= LIT64( 0xC000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)     b.low |= LIT64( 0xC000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)     if ( aIsNaN ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)         return b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #endif