1 /* $OpenBSD: softfloat.h,v 1.1 2002/04/28 20:55:14 pvalchev Exp $ */ 2 /* $NetBSD: softfloat.h,v 1.1 2001/04/26 03:10:48 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 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by the NetBSD 24 * Foundation, Inc. and its contributors. 25 * 4. Neither the name of The NetBSD Foundation nor the names of its 26 * contributors may be used to endorse or promote products derived 27 * from this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 31 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 32 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 33 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 * POSSIBILITY OF SUCH DAMAGE. 40 */ 41 42 /* 43 =============================================================================== 44 45 This C header file is part of the SoftFloat IEC/IEEE Floating-point 46 Arithmetic Package, Release 2a. 47 48 Written by John R. Hauser. This work was made possible in part by the 49 International Computer Science Institute, located at Suite 600, 1947 Center 50 Street, Berkeley, California 94704. Funding was partially provided by the 51 National Science Foundation under grant MIP-9311980. The original version 52 of this code was written as part of a project to build a fixed-point vector 53 processor in collaboration with the University of California at Berkeley, 54 overseen by Profs. Nelson Morgan and John Wawrzynek. More information 55 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 56 arithmetic/SoftFloat.html'. 57 58 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable 59 effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT 60 WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS 61 RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL 62 RESPONSIBILITY FOR ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM 63 THEIR OWN USE OF THE SOFTWARE, AND WHO ALSO EFFECTIVELY INDEMNIFY 64 (possibly via similar legal warning) JOHN HAUSER AND THE INTERNATIONAL 65 COMPUTER SCIENCE INSTITUTE AGAINST ALL LOSSES, COSTS, OR OTHER PROBLEMS 66 ARISING FROM THE USE OF THE SOFTWARE BY THEIR CUSTOMERS AND CLIENTS. 67 68 Derivative works are acceptable, even for commercial purposes, so long as 69 (1) they include prominent notice that the work is derivative, and (2) they 70 include prominent notice akin to these four paragraphs for those parts of 71 this code that are retained. 72 73 =============================================================================== 74 */ 75 76 #ifndef NO_IEEE 77 78 #include <sys/types.h> 79 80 #if !defined(_KERNEL) && !defined(_STANDALONE) 81 #include <ieeefp.h> 82 #else 83 #include "machine/ieeefp.h" 84 #endif 85 #include <sys/endian.h> 86 87 /* 88 ------------------------------------------------------------------------------- 89 The macro `FLOATX80' must be defined to enable the extended double-precision 90 floating-point format `floatx80'. If this macro is not defined, the 91 `floatx80' type will not be defined, and none of the functions that either 92 input or output the `floatx80' type will be defined. The same applies to 93 the `FLOAT128' macro and the quadruple-precision format `float128'. 94 ------------------------------------------------------------------------------- 95 */ 96 /* #define FLOATX80 */ 97 /* #define FLOAT128 */ 98 99 /* 100 ------------------------------------------------------------------------------- 101 Software IEC/IEEE floating-point types. 102 ------------------------------------------------------------------------------- 103 */ 104 typedef u_int32_t float32; 105 typedef u_int64_t float64; 106 #ifdef FLOATX80 107 typedef struct { 108 #if BYTE_ORDER == BIG_ENDIAN 109 u_int16_t high; 110 u_int64_t low; 111 #else 112 u_int64_t low; 113 u_int16_t high; 114 #endif 115 } floatx80; 116 #endif 117 #ifdef FLOAT128 118 typedef struct { 119 u_int64_t high, low; 120 } float128; 121 #endif 122 123 /* 124 * Some of the global variables that used to be here have been removed for 125 * fairly obvious (defopt-MULTIPROCESSOR) reasons. The rest (which don't 126 * change dynamically) will be removed later. [ross] 127 */ 128 129 #define float_rounding_mode() fpgetround() 130 131 /* 132 ------------------------------------------------------------------------------- 133 Software IEC/IEEE floating-point underflow tininess-detection mode. 134 ------------------------------------------------------------------------------- 135 */ 136 137 extern int float_detect_tininess; 138 enum { 139 float_tininess_after_rounding = 1, 140 float_tininess_before_rounding = 0 141 }; 142 143 /* 144 ------------------------------------------------------------------------------- 145 Software IEC/IEEE floating-point rounding mode. 146 ------------------------------------------------------------------------------- 147 */ 148 149 enum { 150 float_round_nearest_even = FP_RN, 151 float_round_to_zero = FP_RZ, 152 float_round_down = FP_RM, 153 float_round_up = FP_RP 154 }; 155 156 /* 157 ------------------------------------------------------------------------------- 158 Software IEC/IEEE floating-point exception flags. 159 ------------------------------------------------------------------------------- 160 */ 161 162 enum { 163 float_flag_inexact = FP_X_IMP, 164 float_flag_underflow = FP_X_UFL, 165 float_flag_overflow = FP_X_OFL, 166 float_flag_divbyzero = FP_X_DZ, 167 float_flag_invalid = FP_X_INV 168 }; 169 170 /* 171 ------------------------------------------------------------------------------- 172 Software IEC/IEEE integer-to-floating-point conversion routines. 173 ------------------------------------------------------------------------------- 174 */ 175 float32 int32_to_float32( int ); 176 float64 int32_to_float64( int ); 177 #ifdef FLOATX80 178 floatx80 int32_to_floatx80( int ); 179 #endif 180 #ifdef FLOAT128 181 float128 int32_to_float128( int ); 182 #endif 183 #ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */ 184 float32 int64_to_float32( int64_t ); 185 float64 int64_to_float64( int64_t ); 186 #ifdef FLOATX80 187 floatx80 int64_to_floatx80( int64_t ); 188 #endif 189 #ifdef FLOAT128 190 float128 int64_to_float128( int64_t ); 191 #endif 192 #endif 193 194 /* 195 ------------------------------------------------------------------------------- 196 Software IEC/IEEE single-precision conversion routines. 197 ------------------------------------------------------------------------------- 198 */ 199 int float32_to_int32( float32 ); 200 int float32_to_int32_round_to_zero( float32 ); 201 #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ 202 int64_t float32_to_int64( float32 ); 203 int64_t float32_to_int64_round_to_zero( float32 ); 204 #endif 205 float64 float32_to_float64( float32 ); 206 #ifdef FLOATX80 207 floatx80 float32_to_floatx80( float32 ); 208 #endif 209 #ifdef FLOAT128 210 float128 float32_to_float128( float32 ); 211 #endif 212 213 /* 214 ------------------------------------------------------------------------------- 215 Software IEC/IEEE single-precision operations. 216 ------------------------------------------------------------------------------- 217 */ 218 float32 float32_round_to_int( float32 ); 219 float32 float32_add( float32, float32 ); 220 float32 float32_sub( float32, float32 ); 221 float32 float32_mul( float32, float32 ); 222 float32 float32_div( float32, float32 ); 223 float32 float32_rem( float32, float32 ); 224 float32 float32_sqrt( float32 ); 225 int float32_eq( float32, float32 ); 226 int float32_le( float32, float32 ); 227 int float32_lt( float32, float32 ); 228 int float32_eq_signaling( float32, float32 ); 229 int float32_le_quiet( float32, float32 ); 230 int float32_lt_quiet( float32, float32 ); 231 #ifndef SOFTFLOAT_FOR_GCC 232 int float32_is_signaling_nan( float32 ); 233 #endif 234 235 /* 236 ------------------------------------------------------------------------------- 237 Software IEC/IEEE double-precision conversion routines. 238 ------------------------------------------------------------------------------- 239 */ 240 int float64_to_int32( float64 ); 241 int float64_to_int32_round_to_zero( float64 ); 242 #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ 243 int64_t float64_to_int64( float64 ); 244 int64_t float64_to_int64_round_to_zero( float64 ); 245 #endif 246 float32 float64_to_float32( float64 ); 247 #ifdef FLOATX80 248 floatx80 float64_to_floatx80( float64 ); 249 #endif 250 #ifdef FLOAT128 251 float128 float64_to_float128( float64 ); 252 #endif 253 254 /* 255 ------------------------------------------------------------------------------- 256 Software IEC/IEEE double-precision operations. 257 ------------------------------------------------------------------------------- 258 */ 259 #define float64_default_nan 0xFFF8000000000000LL 260 261 static __inline int 262 float64_is_nan(float64 a) 263 { 264 return 0xFFE0000000000000LL < a << 1; 265 } 266 267 static __inline int 268 float64_is_signaling_nan(float64 a) 269 { 270 return (a >> 51 & 0xFFF) == 0xFFE && (a & 0x0007FFFFFFFFFFFFLL); 271 } 272 273 float64 float64_round_to_int( float64 ); 274 float64 float64_add( float64, float64 ); 275 float64 float64_sub( float64, float64 ); 276 float64 float64_mul( float64, float64 ); 277 float64 float64_div( float64, float64 ); 278 float64 float64_rem( float64, float64 ); 279 float64 float64_sqrt( float64 ); 280 int float64_eq( float64, float64 ); 281 int float64_le( float64, float64 ); 282 int float64_lt( float64, float64 ); 283 int float64_eq_signaling( float64, float64 ); 284 int float64_le_quiet( float64, float64 ); 285 int float64_lt_quiet( float64, float64 ); 286 #ifndef SOFTFLOAT_FOR_GCC 287 int float64_is_signaling_nan( float64 ); 288 #endif 289 290 #ifdef FLOATX80 291 292 /* 293 ------------------------------------------------------------------------------- 294 Software IEC/IEEE extended double-precision conversion routines. 295 ------------------------------------------------------------------------------- 296 */ 297 int floatx80_to_int32( floatx80 ); 298 int floatx80_to_int32_round_to_zero( floatx80 ); 299 int64_t floatx80_to_int64( floatx80 ); 300 int64_t floatx80_to_int64_round_to_zero( floatx80 ); 301 float32 floatx80_to_float32( floatx80 ); 302 float64 floatx80_to_float64( floatx80 ); 303 #ifdef FLOAT128 304 float128 floatx80_to_float128( floatx80 ); 305 #endif 306 307 /* 308 ------------------------------------------------------------------------------- 309 Software IEC/IEEE extended double-precision rounding precision. Valid 310 values are 32, 64, and 80. 311 ------------------------------------------------------------------------------- 312 */ 313 extern int floatx80_rounding_precision; 314 315 /* 316 ------------------------------------------------------------------------------- 317 Software IEC/IEEE extended double-precision operations. 318 ------------------------------------------------------------------------------- 319 */ 320 floatx80 floatx80_round_to_int( floatx80 ); 321 floatx80 floatx80_add( floatx80, floatx80 ); 322 floatx80 floatx80_sub( floatx80, floatx80 ); 323 floatx80 floatx80_mul( floatx80, floatx80 ); 324 floatx80 floatx80_div( floatx80, floatx80 ); 325 floatx80 floatx80_rem( floatx80, floatx80 ); 326 floatx80 floatx80_sqrt( floatx80 ); 327 int floatx80_eq( floatx80, floatx80 ); 328 int floatx80_le( floatx80, floatx80 ); 329 int floatx80_lt( floatx80, floatx80 ); 330 int floatx80_eq_signaling( floatx80, floatx80 ); 331 int floatx80_le_quiet( floatx80, floatx80 ); 332 int floatx80_lt_quiet( floatx80, floatx80 ); 333 int floatx80_is_signaling_nan( floatx80 ); 334 335 #endif 336 337 #ifdef FLOAT128 338 339 /* 340 ------------------------------------------------------------------------------- 341 Software IEC/IEEE quadruple-precision conversion routines. 342 ------------------------------------------------------------------------------- 343 */ 344 int float128_to_int32( float128 ); 345 int float128_to_int32_round_to_zero( float128 ); 346 int64_t float128_to_int64( float128 ); 347 int64_t float128_to_int64_round_to_zero( float128 ); 348 float32 float128_to_float32( float128 ); 349 float64 float128_to_float64( float128 ); 350 #ifdef FLOATX80 351 floatx80 float128_to_floatx80( float128 ); 352 #endif 353 354 /* 355 ------------------------------------------------------------------------------- 356 Software IEC/IEEE quadruple-precision operations. 357 ------------------------------------------------------------------------------- 358 */ 359 float128 float128_round_to_int( float128 ); 360 float128 float128_add( float128, float128 ); 361 float128 float128_sub( float128, float128 ); 362 float128 float128_mul( float128, float128 ); 363 float128 float128_div( float128, float128 ); 364 float128 float128_rem( float128, float128 ); 365 float128 float128_sqrt( float128 ); 366 int float128_eq( float128, float128 ); 367 int float128_le( float128, float128 ); 368 int float128_lt( float128, float128 ); 369 int float128_eq_signaling( float128, float128 ); 370 int float128_le_quiet( float128, float128 ); 371 int float128_lt_quiet( float128, float128 ); 372 int float128_is_signaling_nan( float128 ); 373 374 #endif 375 376 #endif /* !NO_IEEE */