jcs's openbsd hax
openbsd
at rk3128 484 lines 17 kB view raw
1/* $OpenBSD: softfloat-specialize.h,v 1.3 2008/06/26 05:42:20 ray Exp $ */ 2/* $NetBSD: softfloat-specialize.h,v 1.1 2001/04/26 03:10:47 ross Exp $ */ 3 4/* This is a derivative work. */ 5 6/*- 7 * Copyright (c) 2001 The NetBSD Foundation, Inc. 8 * All rights reserved. 9 * 10 * This code is derived from software contributed to The NetBSD Foundation 11 * by Ross Harvey. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35/* 36=============================================================================== 37 38This C source fragment is part of the SoftFloat IEC/IEEE Floating-point 39Arithmetic Package, Release 2a. 40 41Written by John R. Hauser. This work was made possible in part by the 42International Computer Science Institute, located at Suite 600, 1947 Center 43Street, Berkeley, California 94704. Funding was partially provided by the 44National Science Foundation under grant MIP-9311980. The original version 45of this code was written as part of a project to build a fixed-point vector 46processor in collaboration with the University of California at Berkeley, 47overseen by Profs. Nelson Morgan and John Wawrzynek. More information 48is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 49arithmetic/SoftFloat.html'. 50 51THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable 52effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT 53WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS 54RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL 55RESPONSIBILITY FOR ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM 56THEIR OWN USE OF THE SOFTWARE, AND WHO ALSO EFFECTIVELY INDEMNIFY 57(possibly via similar legal warning) JOHN HAUSER AND THE INTERNATIONAL 58COMPUTER SCIENCE INSTITUTE AGAINST ALL LOSSES, COSTS, OR OTHER PROBLEMS 59ARISING FROM THE USE OF THE SOFTWARE BY THEIR CUSTOMERS AND CLIENTS. 60 61Derivative works are acceptable, even for commercial purposes, so long as 62(1) they include prominent notice that the work is derivative, and (2) they 63include prominent notice akin to these four paragraphs for those parts of 64this code that are retained. 65 66=============================================================================== 67*/ 68 69/* 70------------------------------------------------------------------------------- 71Underflow tininess-detection mode, statically initialized to default value. 72------------------------------------------------------------------------------- 73*/ 74 75/* [ MP safe, does not change dynamically ] */ 76int float_detect_tininess = float_tininess_after_rounding; 77 78/* 79------------------------------------------------------------------------------- 80Internal canonical NaN format. 81------------------------------------------------------------------------------- 82*/ 83typedef struct { 84 flag sign; 85 bits64 high, low; 86} commonNaNT; 87 88/* 89------------------------------------------------------------------------------- 90The pattern for a default generated single-precision NaN. 91------------------------------------------------------------------------------- 92*/ 93#define float32_default_nan 0xFFC00000 94 95/* 96------------------------------------------------------------------------------- 97Returns 1 if the single-precision floating-point value `a' is a NaN; 98otherwise returns 0. 99------------------------------------------------------------------------------- 100*/ 101static flag float32_is_nan( float32 a ) 102{ 103 104 return ( 0xFF000000 < (bits32) ( a<<1 ) ); 105 106} 107 108/* 109------------------------------------------------------------------------------- 110Returns 1 if the single-precision floating-point value `a' is a signaling 111NaN; otherwise returns 0. 112------------------------------------------------------------------------------- 113*/ 114flag float32_is_signaling_nan( float32 a ) 115{ 116 117 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 118 119} 120 121/* 122------------------------------------------------------------------------------- 123Returns the result of converting the single-precision floating-point NaN 124`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 125exception is raised. 126------------------------------------------------------------------------------- 127*/ 128static commonNaNT float32ToCommonNaN( float32 a ) 129{ 130 commonNaNT z; 131 132 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 133 z.sign = a>>31; 134 z.low = 0; 135 z.high = ( (bits64) a )<<41; 136 return z; 137 138} 139 140/* 141------------------------------------------------------------------------------- 142Returns the result of converting the canonical NaN `a' to the single- 143precision floating-point format. 144------------------------------------------------------------------------------- 145*/ 146static float32 commonNaNToFloat32( commonNaNT a ) 147{ 148 149 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); 150 151} 152 153/* 154------------------------------------------------------------------------------- 155Takes two single-precision floating-point values `a' and `b', one of which 156is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 157signaling NaN, the invalid exception is raised. 158------------------------------------------------------------------------------- 159*/ 160static float32 propagateFloat32NaN( float32 a, float32 b ) 161{ 162 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 163 164 aIsNaN = float32_is_nan( a ); 165 aIsSignalingNaN = float32_is_signaling_nan( a ); 166 bIsNaN = float32_is_nan( b ); 167 bIsSignalingNaN = float32_is_signaling_nan( b ); 168 a |= 0x00400000; 169 b |= 0x00400000; 170 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 171 if ( aIsSignalingNaN ) { 172 if ( bIsSignalingNaN ) goto returnLargerSignificand; 173 return bIsNaN ? b : a; 174 } 175 else if ( aIsNaN ) { 176 if ( bIsSignalingNaN | ! bIsNaN ) return a; 177 returnLargerSignificand: 178 if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b; 179 if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a; 180 return ( a < b ) ? a : b; 181 } 182 else { 183 return b; 184 } 185 186} 187 188 189/* 190------------------------------------------------------------------------------- 191Returns the result of converting the double-precision floating-point NaN 192`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 193exception is raised. 194------------------------------------------------------------------------------- 195*/ 196static commonNaNT float64ToCommonNaN( float64 a ) 197{ 198 commonNaNT z; 199 200 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 201 z.sign = a>>63; 202 z.low = 0; 203 z.high = a<<12; 204 return z; 205 206} 207 208/* 209------------------------------------------------------------------------------- 210Returns the result of converting the canonical NaN `a' to the double- 211precision floating-point format. 212------------------------------------------------------------------------------- 213*/ 214static float64 commonNaNToFloat64( commonNaNT a ) 215{ 216 217 return 218 ( ( (bits64) a.sign )<<63 ) 219 | LIT64( 0x7FF8000000000000 ) 220 | ( a.high>>12 ); 221 222} 223 224/* 225------------------------------------------------------------------------------- 226Takes two double-precision floating-point values `a' and `b', one of which 227is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 228signaling NaN, the invalid exception is raised. 229------------------------------------------------------------------------------- 230*/ 231static float64 propagateFloat64NaN( float64 a, float64 b ) 232{ 233 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 234 235 aIsNaN = float64_is_nan( a ); 236 aIsSignalingNaN = float64_is_signaling_nan( a ); 237 bIsNaN = float64_is_nan( b ); 238 bIsSignalingNaN = float64_is_signaling_nan( b ); 239 a |= LIT64( 0x0008000000000000 ); 240 b |= LIT64( 0x0008000000000000 ); 241 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 242 if ( aIsSignalingNaN ) { 243 if ( bIsSignalingNaN ) goto returnLargerSignificand; 244 return bIsNaN ? b : a; 245 } 246 else if ( aIsNaN ) { 247 if ( bIsSignalingNaN | ! bIsNaN ) return a; 248 returnLargerSignificand: 249 if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b; 250 if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a; 251 return ( a < b ) ? a : b; 252 } 253 else { 254 return b; 255 } 256 257} 258 259#ifdef FLOATX80 260 261/* 262------------------------------------------------------------------------------- 263The pattern for a default generated extended double-precision NaN. The 264`high' and `low' values hold the most- and least-significant bits, 265respectively. 266------------------------------------------------------------------------------- 267*/ 268#define floatx80_default_nan_high 0xFFFF 269#define floatx80_default_nan_low LIT64( 0xC000000000000000 ) 270 271/* 272------------------------------------------------------------------------------- 273Returns 1 if the extended double-precision floating-point value `a' is a 274NaN; otherwise returns 0. 275------------------------------------------------------------------------------- 276*/ 277static flag floatx80_is_nan( floatx80 a ) 278{ 279 280 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 281 282} 283 284/* 285------------------------------------------------------------------------------- 286Returns 1 if the extended double-precision floating-point value `a' is a 287signaling NaN; otherwise returns 0. 288------------------------------------------------------------------------------- 289*/ 290flag floatx80_is_signaling_nan( floatx80 a ) 291{ 292 bits64 aLow; 293 294 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 295 return 296 ( ( a.high & 0x7FFF ) == 0x7FFF ) 297 && (bits64) ( aLow<<1 ) 298 && ( a.low == aLow ); 299 300} 301 302/* 303------------------------------------------------------------------------------- 304Returns the result of converting the extended double-precision floating- 305point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 306invalid exception is raised. 307------------------------------------------------------------------------------- 308*/ 309static commonNaNT floatx80ToCommonNaN( floatx80 a ) 310{ 311 commonNaNT z; 312 313 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 314 z.sign = a.high>>15; 315 z.low = 0; 316 z.high = a.low<<1; 317 return z; 318 319} 320 321/* 322------------------------------------------------------------------------------- 323Returns the result of converting the canonical NaN `a' to the extended 324double-precision floating-point format. 325------------------------------------------------------------------------------- 326*/ 327static floatx80 commonNaNToFloatx80( commonNaNT a ) 328{ 329 floatx80 z; 330 331 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 332 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 333 return z; 334 335} 336 337/* 338------------------------------------------------------------------------------- 339Takes two extended double-precision floating-point values `a' and `b', one 340of which is a NaN, and returns the appropriate NaN result. If either `a' or 341`b' is a signaling NaN, the invalid exception is raised. 342------------------------------------------------------------------------------- 343*/ 344static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 345{ 346 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 347 348 aIsNaN = floatx80_is_nan( a ); 349 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 350 bIsNaN = floatx80_is_nan( b ); 351 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 352 a.low |= LIT64( 0xC000000000000000 ); 353 b.low |= LIT64( 0xC000000000000000 ); 354 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 355 if ( aIsSignalingNaN ) { 356 if ( bIsSignalingNaN ) goto returnLargerSignificand; 357 return bIsNaN ? b : a; 358 } 359 else if ( aIsNaN ) { 360 if ( bIsSignalingNaN | ! bIsNaN ) return a; 361 returnLargerSignificand: 362 if ( a.low < b.low ) return b; 363 if ( b.low < a.low ) return a; 364 return ( a.high < b.high ) ? a : b; 365 } 366 else { 367 return b; 368 } 369 370} 371 372#endif 373 374#ifdef FLOAT128 375 376/* 377------------------------------------------------------------------------------- 378The pattern for a default generated quadruple-precision NaN. The `high' and 379`low' values hold the most- and least-significant bits, respectively. 380------------------------------------------------------------------------------- 381*/ 382#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) 383#define float128_default_nan_low LIT64( 0x0000000000000000 ) 384 385/* 386------------------------------------------------------------------------------- 387Returns 1 if the quadruple-precision floating-point value `a' is a NaN; 388otherwise returns 0. 389------------------------------------------------------------------------------- 390*/ 391flag float128_is_nan( float128 a ) 392{ 393 394 return 395 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 396 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 397 398} 399 400/* 401------------------------------------------------------------------------------- 402Returns 1 if the quadruple-precision floating-point value `a' is a 403signaling NaN; otherwise returns 0. 404------------------------------------------------------------------------------- 405*/ 406flag float128_is_signaling_nan( float128 a ) 407{ 408 409 return 410 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 411 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 412 413} 414 415/* 416------------------------------------------------------------------------------- 417Returns the result of converting the quadruple-precision floating-point NaN 418`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 419exception is raised. 420------------------------------------------------------------------------------- 421*/ 422static commonNaNT float128ToCommonNaN( float128 a ) 423{ 424 commonNaNT z; 425 426 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 427 z.sign = a.high>>63; 428 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 429 return z; 430 431} 432 433/* 434------------------------------------------------------------------------------- 435Returns the result of converting the canonical NaN `a' to the quadruple- 436precision floating-point format. 437------------------------------------------------------------------------------- 438*/ 439static float128 commonNaNToFloat128( commonNaNT a ) 440{ 441 float128 z; 442 443 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 444 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 445 return z; 446 447} 448 449/* 450------------------------------------------------------------------------------- 451Takes two quadruple-precision floating-point values `a' and `b', one of 452which is a NaN, and returns the appropriate NaN result. If either `a' or 453`b' is a signaling NaN, the invalid exception is raised. 454------------------------------------------------------------------------------- 455*/ 456static float128 propagateFloat128NaN( float128 a, float128 b ) 457{ 458 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 459 460 aIsNaN = float128_is_nan( a ); 461 aIsSignalingNaN = float128_is_signaling_nan( a ); 462 bIsNaN = float128_is_nan( b ); 463 bIsSignalingNaN = float128_is_signaling_nan( b ); 464 a.high |= LIT64( 0x0000800000000000 ); 465 b.high |= LIT64( 0x0000800000000000 ); 466 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 467 if ( aIsSignalingNaN ) { 468 if ( bIsSignalingNaN ) goto returnLargerSignificand; 469 return bIsNaN ? b : a; 470 } 471 else if ( aIsNaN ) { 472 if ( bIsSignalingNaN | ! bIsNaN ) return a; 473 returnLargerSignificand: 474 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b; 475 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a; 476 return ( a.high < b.high ) ? a : b; 477 } 478 else { 479 return b; 480 } 481 482} 483 484#endif