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