~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/nwfpe/softfloat-specialize

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php