VirtualBox

Changeset 18985 in vbox for trunk/src/recompiler_new


Ignore:
Timestamp:
Apr 17, 2009 9:13:29 AM (16 years ago)
Author:
vboxsync
Message:

REM: FPU-related QEMU sync (mostly noop, as soft FPU not really used)

Location:
trunk/src/recompiler_new/fpu
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler_new/fpu/softfloat-macros.h

    r1 r18985  
    718718
    719719}
    720 
  • trunk/src/recompiler_new/fpu/softfloat-native.c

    r18967 r18985  
    3838#  define sqrtl(f)             (sqrt(f))
    3939#  define remainderl(fa, fb)   (remainder(fa, fb))
    40 # endif /* VBOX */
    41 #endif
    42 
    43 #if defined(__powerpc__)
     40# endif /* VBOX && _BSD */
     41
     42#if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
     43extern long double rintl(long double);
     44extern long double scalbnl(long double, int);
     45
     46long long
     47llrintl(long double x) {
     48        return ((long long) rintl(x));
     49}
     50
     51long
     52lrintl(long double x) {
     53        return ((long) rintl(x));
     54}
     55
     56long double
     57ldexpl(long double x, int n) {
     58        return (scalbnl(x, n));
     59}
     60#endif
     61#endif
     62
     63#if defined(_ARCH_PPC)
    4464
    4565/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
    46 double qemu_rint(double x)
     66static double qemu_rint(double x)
    4767{
    4868    double y = 4503599627370496.0;
     
    6888}
    6989
     90float32 uint32_to_float32(unsigned int v STATUS_PARAM)
     91{
     92    return (float32)v;
     93}
     94
    7095float64 int32_to_float64(int v STATUS_PARAM)
     96{
     97    return (float64)v;
     98}
     99
     100float64 uint32_to_float64(unsigned int v STATUS_PARAM)
    71101{
    72102    return (float64)v;
     
    83113    return (float32)v;
    84114}
     115float32 uint64_to_float32( uint64_t v STATUS_PARAM)
     116{
     117    return (float32)v;
     118}
    85119float64 int64_to_float64( int64_t v STATUS_PARAM)
     120{
     121    return (float64)v;
     122}
     123float64 uint64_to_float64( uint64_t v STATUS_PARAM)
    86124{
    87125    return (float64)v;
     
    96134/* XXX: this code implements the x86 behaviour, not the IEEE one.  */
    97135#if HOST_LONG_BITS == 32
    98 #ifndef VBOX
    99136static inline int long_to_int32(long a)
    100 #else /* VBOX */
    101 DECLINLINE(int) long_to_int32(long a)
    102 #endif /* VBOX */
    103137{
    104138    return a;
    105139}
    106140#else
    107 #ifndef VBOX
    108141static inline int long_to_int32(long a)
    109 #else /* VBOX */
    110 DECLINLINE(int) long_to_int32(long a)
    111 #endif /* VBOX */
    112142{
    113143    if (a != (int32_t)a)
     
    149179#endif
    150180
     181unsigned int float32_to_uint32( float32 a STATUS_PARAM)
     182{
     183    int64_t v;
     184    unsigned int res;
     185
     186    v = llrintf(a);
     187    if (v < 0) {
     188        res = 0;
     189    } else if (v > 0xffffffff) {
     190        res = 0xffffffff;
     191    } else {
     192        res = v;
     193    }
     194    return res;
     195}
     196unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
     197{
     198    int64_t v;
     199    unsigned int res;
     200
     201    v = (int64_t)a;
     202    if (v < 0) {
     203        res = 0;
     204    } else if (v > 0xffffffff) {
     205        res = 0xffffffff;
     206    } else {
     207        res = v;
     208    }
     209    return res;
     210}
     211
    151212/*----------------------------------------------------------------------------
    152213| Software IEC/IEEE single-precision operations.
     
    169230{
    170231    if (a < b) {
    171         return -1;
     232        return float_relation_less;
    172233    } else if (a == b) {
    173         return 0;
     234        return float_relation_equal;
    174235    } else if (a > b) {
    175         return 1;
    176     } else {
    177         return 2;
     236        return float_relation_greater;
     237    } else {
     238        return float_relation_unordered;
    178239    }
    179240}
     
    181242{
    182243    if (isless(a, b)) {
    183         return -1;
     244        return float_relation_less;
    184245    } else if (a == b) {
    185         return 0;
     246        return float_relation_equal;
    186247    } else if (isgreater(a, b)) {
    187         return 1;
    188     } else {
    189         return 2;
     248        return float_relation_greater;
     249    } else {
     250        return float_relation_unordered;
    190251    }
    191252}
     
    199260}
    200261
     262int float32_is_nan( float32 a1 )
     263{
     264    float32u u;
     265    uint64_t a;
     266    u.f = a1;
     267    a = u.i;
     268    return ( 0xFF800000 < ( a<<1 ) );
     269}
     270
    201271/*----------------------------------------------------------------------------
    202272| Software IEC/IEEE double-precision conversion routines.
     
    235305#endif
    236306
     307unsigned int float64_to_uint32( float64 a STATUS_PARAM)
     308{
     309    int64_t v;
     310    unsigned int res;
     311
     312    v = llrint(a);
     313    if (v < 0) {
     314        res = 0;
     315    } else if (v > 0xffffffff) {
     316        res = 0xffffffff;
     317    } else {
     318        res = v;
     319    }
     320    return res;
     321}
     322unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
     323{
     324    int64_t v;
     325    unsigned int res;
     326
     327    v = (int64_t)a;
     328    if (v < 0) {
     329        res = 0;
     330    } else if (v > 0xffffffff) {
     331        res = 0xffffffff;
     332    } else {
     333        res = v;
     334    }
     335    return res;
     336}
     337uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
     338{
     339    int64_t v;
     340
     341    v = llrint(a + (float64)INT64_MIN);
     342
     343    return v - INT64_MIN;
     344}
     345uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
     346{
     347    int64_t v;
     348
     349    v = (int64_t)(a + (float64)INT64_MIN);
     350
     351    return v - INT64_MIN;
     352}
     353
    237354/*----------------------------------------------------------------------------
    238355| Software IEC/IEEE double-precision operations.
    239356*----------------------------------------------------------------------------*/
     357#if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
     358static inline float64 trunc(float64 x)
     359{
     360    return x < 0 ? -floor(-x) : floor(x);
     361}
     362#endif
    240363float64 float64_trunc_to_int( float64 a STATUS_PARAM )
    241364{
     
    278401{
    279402    if (a < b) {
    280         return -1;
     403        return float_relation_less;
    281404    } else if (a == b) {
    282         return 0;
     405        return float_relation_equal;
    283406    } else if (a > b) {
    284         return 1;
    285     } else {
    286         return 2;
     407        return float_relation_greater;
     408    } else {
     409        return float_relation_unordered;
    287410    }
    288411}
     
    290413{
    291414    if (isless(a, b)) {
    292         return -1;
     415        return float_relation_less;
    293416    } else if (a == b) {
    294         return 0;
     417        return float_relation_equal;
    295418    } else if (isgreater(a, b)) {
    296         return 1;
    297     } else {
    298         return 2;
     419        return float_relation_greater;
     420    } else {
     421        return float_relation_unordered;
    299422    }
    300423}
     
    318441    a = u.i;
    319442
    320     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
     443    return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) );
    321444
    322445}
     
    370493{
    371494    if (a < b) {
    372         return -1;
     495        return float_relation_less;
    373496    } else if (a == b) {
    374         return 0;
     497        return float_relation_equal;
    375498    } else if (a > b) {
    376         return 1;
    377     } else {
    378         return 2;
     499        return float_relation_greater;
     500    } else {
     501        return float_relation_unordered;
    379502    }
    380503}
     
    382505{
    383506    if (isless(a, b)) {
    384         return -1;
     507        return float_relation_less;
    385508    } else if (a == b) {
    386         return 0;
     509        return float_relation_equal;
    387510    } else if (isgreater(a, b)) {
    388         return 1;
    389     } else {
    390         return 2;
     511        return float_relation_greater;
     512    } else {
     513        return float_relation_unordered;
    391514    }
    392515}
    393516int floatx80_is_signaling_nan( floatx80 a1)
     517{
     518    floatx80u u;
     519    uint64_t aLow;
     520    u.f = a1;
     521
     522    aLow = u.i.low & ~ LIT64( 0x4000000000000000 );
     523    return
     524           ( ( u.i.high & 0x7FFF ) == 0x7FFF )
     525        && (bits64) ( aLow<<1 )
     526        && ( u.i.low == aLow );
     527}
     528
     529int floatx80_is_nan( floatx80 a1 )
    394530{
    395531    floatx80u u;
  • trunk/src/recompiler_new/fpu/softfloat-native.h

    r14447 r18985  
    33
    44#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
    5 # include <ieeefp.h>
    6 # define fabsf(f) ((float)fabs(f))
     5#include <ieeefp.h>
    76#elif defined(_MSC_VER)
    87# include <fpieee.h>
     
    1110# endif
    1211#else
    13 # include <fenv.h>
     12#include <fenv.h>
     13#endif
     14
     15#if defined(__OpenBSD__) || defined(__NetBSD__)
     16#include <sys/param.h>
    1417#endif
    1518
     
    2124 *   are defined in <iso/math_c99.h> with a compiler directive
    2225 */
    23 #if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ( ( HOST_SOLARIS >= 10 ) && ( __GNUC__ <= 4) ))
     26#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) \
     27                                                        && (__GNUC__ <= 4))) \
     28    || (defined(__OpenBSD__) && (OpenBSD < 200811))
    2429/*
    2530 * C99 7.12.3 classification macros
     
    3035 * Try to workaround the missing / broken C99 math macros.
    3136 */
     37#if defined(__OpenBSD__)
     38#define unordered(x, y) (isnan(x) || isnan(y))
     39#endif
     40
     41#ifdef __NetBSD__
     42#ifndef isgreater
     43#define isgreater(x, y)         __builtin_isgreater(x, y)
     44#endif
     45#ifndef isgreaterequal
     46#define isgreaterequal(x, y)    __builtin_isgreaterequal(x, y)
     47#endif
     48#ifndef isless
     49#define isless(x, y)            __builtin_isless(x, y)
     50#endif
     51#ifndef islessequal
     52#define islessequal(x, y)       __builtin_islessequal(x, y)
     53#endif
     54#ifndef isunordered
     55#define isunordered(x, y)       __builtin_isunordered(x, y)
     56#endif
     57#endif
     58
    3259
    3360#define isnormal(x)             (fpclass(x) >= FP_NZERO)
     
    3764#define islessequal(x, y)       ((!unordered(x, y)) && ((x) <= (y)))
    3865#define isunordered(x,y)        unordered(x, y)
    39 #define isinf(x)                ((fpclass(x) == FP_NINF) || (fpclass(x) == FP_PINF))
    40 
    4166#elif defined(_MSC_VER)
    4267#include <float.h>
     
    4570#define islessequal(x, y)       ((!unordered(x, y)) && ((x) <= (y)))
    4671#define isunordered(x,y)        unordered(x, y)
     72#endif
     73
     74#if defined(__sun__) && !defined(NEED_LIBSUNMATH)
     75
     76#ifndef isnan
     77# define isnan(x) \
     78    (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
     79     : sizeof (x) == sizeof (double) ? isnan_d (x) \
     80     : isnan_f (x))
     81static inline int isnan_f  (float       x) { return x != x; }
     82static inline int isnan_d  (double      x) { return x != x; }
     83static inline int isnan_ld (long double x) { return x != x; }
     84#endif
     85
     86#ifndef isinf
     87# define isinf(x) \
     88    (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
     89     : sizeof (x) == sizeof (double) ? isinf_d (x) \
     90     : isinf_f (x))
     91static inline int isinf_f  (float       x) { return isnan (x - x); }
     92static inline int isinf_d  (double      x) { return isnan (x - x); }
     93static inline int isinf_ld (long double x) { return isnan (x - x); }
     94#endif
    4795#endif
    4896
     
    75123*----------------------------------------------------------------------------*/
    76124#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
     125#if defined(__OpenBSD__)
     126#define FE_RM FP_RM
     127#define FE_RP FP_RP
     128#define FE_RZ FP_RZ
     129#endif
    77130enum {
    78131    float_round_nearest_even = FP_RN,
     
    105158
    106159typedef struct float_status {
    107     signed char float_rounding_mode;
    108 #ifdef FLOATX80
    109     signed char floatx80_rounding_precision;
     160    int float_rounding_mode;
     161#ifdef FLOATX80
     162    int floatx80_rounding_precision;
    110163#endif
    111164} float_status;
     
    120173*----------------------------------------------------------------------------*/
    121174float32 int32_to_float32( int STATUS_PARAM);
     175float32 uint32_to_float32( unsigned int STATUS_PARAM);
    122176float64 int32_to_float64( int STATUS_PARAM);
     177float64 uint32_to_float64( unsigned int STATUS_PARAM);
    123178#ifdef FLOATX80
    124179floatx80 int32_to_floatx80( int STATUS_PARAM);
     
    128183#endif
    129184float32 int64_to_float32( int64_t STATUS_PARAM);
     185float32 uint64_to_float32( uint64_t STATUS_PARAM);
    130186float64 int64_to_float64( int64_t STATUS_PARAM);
     187float64 uint64_to_float64( uint64_t v STATUS_PARAM);
    131188#ifdef FLOATX80
    132189floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
     
    141198int float32_to_int32( float32  STATUS_PARAM);
    142199int float32_to_int32_round_to_zero( float32  STATUS_PARAM);
     200unsigned int float32_to_uint32( float32 a STATUS_PARAM);
     201unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM);
    143202int64_t float32_to_int64( float32  STATUS_PARAM);
    144203int64_t float32_to_int64_round_to_zero( float32  STATUS_PARAM);
     
    205264int float32_compare_quiet( float32, float32 STATUS_PARAM );
    206265int float32_is_signaling_nan( float32 );
     266int float32_is_nan( float32 );
    207267
    208268INLINE float32 float32_abs(float32 a)
     
    214274{
    215275    return -a;
     276}
     277
     278INLINE float32 float32_is_infinity(float32 a)
     279{
     280    return fpclassify(a) == FP_INFINITE;
     281}
     282
     283INLINE float32 float32_is_neg(float32 a)
     284{
     285    float32u u;
     286    u.f = a;
     287    return u.i >> 31;
     288}
     289
     290INLINE float32 float32_is_zero(float32 a)
     291{
     292    return fpclassify(a) == FP_ZERO;
     293}
     294
     295INLINE float32 float32_scalbn(float32 a, int n)
     296{
     297    return scalbnf(a, n);
    216298}
    217299
     
    221303int float64_to_int32( float64 STATUS_PARAM );
    222304int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
     305unsigned int float64_to_uint32( float64 STATUS_PARAM );
     306unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
    223307int64_t float64_to_int64( float64 STATUS_PARAM );
    224308int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
     309uint64_t float64_to_uint64( float64 STATUS_PARAM );
     310uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM );
    225311float32 float64_to_float32( float64 STATUS_PARAM );
    226312#ifdef FLOATX80
     
    297383{
    298384    return -a;
     385}
     386
     387INLINE float64 float64_is_infinity(float64 a)
     388{
     389    return fpclassify(a) == FP_INFINITE;
     390}
     391
     392INLINE float64 float64_is_neg(float64 a)
     393{
     394    float64u u;
     395    u.f = a;
     396    return u.i >> 63;
     397}
     398
     399INLINE float64 float64_is_zero(float64 a)
     400{
     401    return fpclassify(a) == FP_ZERO;
     402}
     403
     404INLINE float64 float64_scalbn(float64 a, int n)
     405{
     406    return scalbn(a, n);
    299407}
    300408
     
    369477int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
    370478int floatx80_is_signaling_nan( floatx80 );
     479int floatx80_is_nan( floatx80 );
    371480
    372481INLINE floatx80 floatx80_abs(floatx80 a)
     
    379488    return -a;
    380489}
    381 #endif
     490
     491INLINE floatx80 floatx80_is_infinity(floatx80 a)
     492{
     493    return fpclassify(a) == FP_INFINITE;
     494}
     495
     496INLINE floatx80 floatx80_is_neg(floatx80 a)
     497{
     498    floatx80u u;
     499    u.f = a;
     500    return u.i.high >> 15;
     501}
     502
     503INLINE floatx80 floatx80_is_zero(floatx80 a)
     504{
     505    return fpclassify(a) == FP_ZERO;
     506}
     507
     508INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
     509{
     510    return scalbnl(a, n);
     511}
     512
     513#endif
  • trunk/src/recompiler_new/fpu/softfloat-specialize.h

    r1 r18985  
    3131=============================================================================*/
    3232
    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 int8 float_detect_tininess = float_tininess_after_rounding;
     33#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
     34#define SNAN_BIT_IS_ONE         1
     35#else
     36#define SNAN_BIT_IS_ONE         0
     37#endif
    3838
    3939/*----------------------------------------------------------------------------
     
    4646void float_raise( int8 flags STATUS_PARAM )
    4747{
    48 
    4948    STATUS(float_exception_flags) |= flags;
    50 
    5149}
    5250
     
    6260| The pattern for a default generated single-precision NaN.
    6361*----------------------------------------------------------------------------*/
    64 #define float32_default_nan 0xFFC00000
    65 
    66 /*----------------------------------------------------------------------------
    67 | Returns 1 if the single-precision floating-point value `a' is a NaN;
    68 | otherwise returns 0.
    69 *----------------------------------------------------------------------------*/
    70 
    71 int float32_is_nan( float32 a )
    72 {
    73 
    74     return ( 0xFF000000 < (bits32) ( a<<1 ) );
    75 
     62#if defined(TARGET_SPARC)
     63#define float32_default_nan make_float32(0x7FFFFFFF)
     64#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
     65#define float32_default_nan make_float32(0x7FC00000)
     66#elif defined(TARGET_HPPA)
     67#define float32_default_nan make_float32(0x7FA00000)
     68#elif SNAN_BIT_IS_ONE
     69#define float32_default_nan make_float32(0x7FBFFFFF)
     70#else
     71#define float32_default_nan make_float32(0xFFC00000)
     72#endif
     73
     74/*----------------------------------------------------------------------------
     75| Returns 1 if the single-precision floating-point value `a' is a quiet
     76| NaN; otherwise returns 0.
     77*----------------------------------------------------------------------------*/
     78
     79int float32_is_nan( float32 a_ )
     80{
     81    uint32_t a = float32_val(a_);
     82#if SNAN_BIT_IS_ONE
     83    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
     84#else
     85    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
     86#endif
    7687}
    7788
     
    8192*----------------------------------------------------------------------------*/
    8293
    83 int float32_is_signaling_nan( float32 a )
    84 {
    85 
     94int float32_is_signaling_nan( float32 a_ )
     95{
     96    uint32_t a = float32_val(a_);
     97#if SNAN_BIT_IS_ONE
     98    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
     99#else
    86100    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
    87 
     101#endif
    88102}
    89103
     
    99113
    100114    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
    101     z.sign = a>>31;
     115    z.sign = float32_val(a)>>31;
    102116    z.low = 0;
    103     z.high = ( (bits64) a )<<41;
     117    z.high = ( (bits64) float32_val(a) )<<41;
    104118    return z;
    105 
    106119}
    107120
     
    113126static float32 commonNaNToFloat32( commonNaNT a )
    114127{
    115 
    116     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
    117 
     128    bits32 mantissa = a.high>>41;
     129    if ( mantissa )
     130        return make_float32(
     131            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
     132    else
     133        return float32_default_nan;
    118134}
    119135
     
    127143{
    128144    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
     145    bits32 av, bv, res;
     146
     147    if ( STATUS(default_nan_mode) )
     148        return float32_default_nan;
    129149
    130150    aIsNaN = float32_is_nan( a );
     
    132152    bIsNaN = float32_is_nan( b );
    133153    bIsSignalingNaN = float32_is_signaling_nan( b );
    134     a |= 0x00400000;
    135     b |= 0x00400000;
     154    av = float32_val(a);
     155    bv = float32_val(b);
     156#if SNAN_BIT_IS_ONE
     157    av &= ~0x00400000;
     158    bv &= ~0x00400000;
     159#else
     160    av |= 0x00400000;
     161    bv |= 0x00400000;
     162#endif
    136163    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    137164    if ( aIsSignalingNaN ) {
    138165        if ( bIsSignalingNaN ) goto returnLargerSignificand;
    139         return bIsNaN ? b : a;
     166        res = bIsNaN ? bv : av;
    140167    }
    141168    else if ( aIsNaN ) {
    142         if ( bIsSignalingNaN | ! bIsNaN ) return a;
     169        if ( bIsSignalingNaN | ! bIsNaN )
     170            res = av;
     171        else {
    143172 returnLargerSignificand:
    144         if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
    145         if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
    146         return ( a < b ) ? a : b;
     173            if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
     174                res = bv;
     175            else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
     176                res = av;
     177            else
     178                res = ( av < bv ) ? av : bv;
     179        }
    147180    }
    148181    else {
    149         return b;
    150     }
    151 
     182        res = bv;
     183    }
     184    return make_float32(res);
    152185}
    153186
     
    155188| The pattern for a default generated double-precision NaN.
    156189*----------------------------------------------------------------------------*/
    157 #define float64_default_nan LIT64( 0xFFF8000000000000 )
    158 
    159 /*----------------------------------------------------------------------------
    160 | Returns 1 if the double-precision floating-point value `a' is a NaN;
    161 | otherwise returns 0.
    162 *----------------------------------------------------------------------------*/
    163 
    164 int float64_is_nan( float64 a )
    165 {
    166 
    167     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
    168 
     190#if defined(TARGET_SPARC)
     191#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
     192#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
     193#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
     194#elif defined(TARGET_HPPA)
     195#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
     196#elif SNAN_BIT_IS_ONE
     197#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
     198#else
     199#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
     200#endif
     201
     202/*----------------------------------------------------------------------------
     203| Returns 1 if the double-precision floating-point value `a' is a quiet
     204| NaN; otherwise returns 0.
     205*----------------------------------------------------------------------------*/
     206
     207int float64_is_nan( float64 a_ )
     208{
     209    bits64 a = float64_val(a_);
     210#if SNAN_BIT_IS_ONE
     211    return
     212           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
     213        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
     214#else
     215    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
     216#endif
    169217}
    170218
     
    174222*----------------------------------------------------------------------------*/
    175223
    176 int float64_is_signaling_nan( float64 a )
    177 {
    178 
     224int float64_is_signaling_nan( float64 a_ )
     225{
     226    bits64 a = float64_val(a_);
     227#if SNAN_BIT_IS_ONE
     228    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
     229#else
    179230    return
    180231           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
    181232        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
    182 
     233#endif
    183234}
    184235
     
    194245
    195246    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
    196     z.sign = a>>63;
     247    z.sign = float64_val(a)>>63;
    197248    z.low = 0;
    198     z.high = a<<12;
     249    z.high = float64_val(a)<<12;
    199250    return z;
    200 
    201251}
    202252
     
    208258static float64 commonNaNToFloat64( commonNaNT a )
    209259{
    210 
    211     return
    212           ( ( (bits64) a.sign )<<63 )
    213         | LIT64( 0x7FF8000000000000 )
    214         | ( a.high>>12 );
    215 
     260    bits64 mantissa = a.high>>12;
     261
     262    if ( mantissa )
     263        return make_float64(
     264              ( ( (bits64) a.sign )<<63 )
     265            | LIT64( 0x7FF0000000000000 )
     266            | ( a.high>>12 ));
     267    else
     268        return float64_default_nan;
    216269}
    217270
     
    225278{
    226279    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
     280    bits64 av, bv, res;
     281
     282    if ( STATUS(default_nan_mode) )
     283        return float64_default_nan;
    227284
    228285    aIsNaN = float64_is_nan( a );
     
    230287    bIsNaN = float64_is_nan( b );
    231288    bIsSignalingNaN = float64_is_signaling_nan( b );
    232     a |= LIT64( 0x0008000000000000 );
    233     b |= LIT64( 0x0008000000000000 );
     289    av = float64_val(a);
     290    bv = float64_val(b);
     291#if SNAN_BIT_IS_ONE
     292    av &= ~LIT64( 0x0008000000000000 );
     293    bv &= ~LIT64( 0x0008000000000000 );
     294#else
     295    av |= LIT64( 0x0008000000000000 );
     296    bv |= LIT64( 0x0008000000000000 );
     297#endif
    234298    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    235299    if ( aIsSignalingNaN ) {
    236300        if ( bIsSignalingNaN ) goto returnLargerSignificand;
    237         return bIsNaN ? b : a;
     301        res = bIsNaN ? bv : av;
    238302    }
    239303    else if ( aIsNaN ) {
    240         if ( bIsSignalingNaN | ! bIsNaN ) return a;
     304        if ( bIsSignalingNaN | ! bIsNaN )
     305            res = av;
     306        else {
    241307 returnLargerSignificand:
    242         if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
    243         if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
    244         return ( a < b ) ? a : b;
     308            if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
     309                res = bv;
     310            else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
     311                res = av;
     312            else
     313                res = ( av < bv ) ? av : bv;
     314        }
    245315    }
    246316    else {
    247         return b;
    248     }
    249 
     317        res = bv;
     318    }
     319    return make_float64(res);
    250320}
    251321
     
    257327| respectively.
    258328*----------------------------------------------------------------------------*/
     329#if SNAN_BIT_IS_ONE
     330#define floatx80_default_nan_high 0x7FFF
     331#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
     332#else
    259333#define floatx80_default_nan_high 0xFFFF
    260334#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
     335#endif
    261336
    262337/*----------------------------------------------------------------------------
    263338| Returns 1 if the extended double-precision floating-point value `a' is a
    264 | NaN; otherwise returns 0.
     339| quiet NaN; otherwise returns 0.
    265340*----------------------------------------------------------------------------*/
    266341
    267342int floatx80_is_nan( floatx80 a )
    268343{
    269 
    270     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
    271 
    272 }
    273 
    274 /*----------------------------------------------------------------------------
    275 | Returns 1 if the extended double-precision floating-point value `a' is a
    276 | signaling NaN; otherwise returns 0.
    277 *----------------------------------------------------------------------------*/
    278 
    279 int floatx80_is_signaling_nan( floatx80 a )
    280 {
     344#if SNAN_BIT_IS_ONE
    281345    bits64 aLow;
    282346
     
    286350        && (bits64) ( aLow<<1 )
    287351        && ( a.low == aLow );
    288 
     352#else
     353    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
     354#endif
     355}
     356
     357/*----------------------------------------------------------------------------
     358| Returns 1 if the extended double-precision floating-point value `a' is a
     359| signaling NaN; otherwise returns 0.
     360*----------------------------------------------------------------------------*/
     361
     362int floatx80_is_signaling_nan( floatx80 a )
     363{
     364#if SNAN_BIT_IS_ONE
     365    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
     366#else
     367    bits64 aLow;
     368
     369    aLow = a.low & ~ LIT64( 0x4000000000000000 );
     370    return
     371           ( ( a.high & 0x7FFF ) == 0x7FFF )
     372        && (bits64) ( aLow<<1 )
     373        && ( a.low == aLow );
     374#endif
    289375}
    290376
     
    302388    z.sign = a.high>>15;
    303389    z.low = 0;
    304     z.high = a.low<<1;
     390    z.high = a.low;
    305391    return z;
    306 
    307392}
    308393
     
    316401    floatx80 z;
    317402
    318     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
     403    if (a.high)
     404        z.low = a.high;
     405    else
     406        z.low = floatx80_default_nan_low;
    319407    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
    320408    return z;
    321 
    322409}
    323410
     
    331418{
    332419    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
     420
     421    if ( STATUS(default_nan_mode) ) {
     422        a.low = floatx80_default_nan_low;
     423        a.high = floatx80_default_nan_high;
     424        return a;
     425    }
    333426
    334427    aIsNaN = floatx80_is_nan( a );
     
    336429    bIsNaN = floatx80_is_nan( b );
    337430    bIsSignalingNaN = floatx80_is_signaling_nan( b );
     431#if SNAN_BIT_IS_ONE
     432    a.low &= ~LIT64( 0xC000000000000000 );
     433    b.low &= ~LIT64( 0xC000000000000000 );
     434#else
    338435    a.low |= LIT64( 0xC000000000000000 );
    339436    b.low |= LIT64( 0xC000000000000000 );
     437#endif
    340438    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    341439    if ( aIsSignalingNaN ) {
     
    353451        return b;
    354452    }
    355 
    356453}
    357454
     
    364461| `low' values hold the most- and least-significant bits, respectively.
    365462*----------------------------------------------------------------------------*/
     463#if SNAN_BIT_IS_ONE
     464#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
     465#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
     466#else
    366467#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
    367468#define float128_default_nan_low  LIT64( 0x0000000000000000 )
    368 
    369 /*----------------------------------------------------------------------------
    370 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
    371 | otherwise returns 0.
     469#endif
     470
     471/*----------------------------------------------------------------------------
     472| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
     473| NaN; otherwise returns 0.
    372474*----------------------------------------------------------------------------*/
    373475
    374476int float128_is_nan( float128 a )
    375477{
    376 
     478#if SNAN_BIT_IS_ONE
     479    return
     480           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
     481        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
     482#else
    377483    return
    378484           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    379485        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    380 
     486#endif
    381487}
    382488
     
    388494int float128_is_signaling_nan( float128 a )
    389495{
    390 
     496#if SNAN_BIT_IS_ONE
     497    return
     498           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
     499        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
     500#else
    391501    return
    392502           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    393503        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    394 
     504#endif
    395505}
    396506
     
    409519    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
    410520    return z;
    411 
    412521}
    413522
     
    422531
    423532    shift128Right( a.high, a.low, 16, &z.high, &z.low );
    424     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
     533    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
    425534    return z;
    426 
    427535}
    428536
     
    436544{
    437545    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
     546
     547    if ( STATUS(default_nan_mode) ) {
     548        a.low = float128_default_nan_low;
     549        a.high = float128_default_nan_high;
     550        return a;
     551    }
    438552
    439553    aIsNaN = float128_is_nan( a );
     
    441555    bIsNaN = float128_is_nan( b );
    442556    bIsSignalingNaN = float128_is_signaling_nan( b );
     557#if SNAN_BIT_IS_ONE
     558    a.high &= ~LIT64( 0x0000800000000000 );
     559    b.high &= ~LIT64( 0x0000800000000000 );
     560#else
    443561    a.high |= LIT64( 0x0000800000000000 );
    444562    b.high |= LIT64( 0x0000800000000000 );
     563#endif
    445564    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    446565    if ( aIsSignalingNaN ) {
     
    458577        return b;
    459578    }
    460 
    461 }
    462 
    463 #endif
    464 
     579}
     580
     581#endif
  • trunk/src/recompiler_new/fpu/softfloat.c

    r1 r18985  
    3131=============================================================================*/
    3232
     33/* FIXME: Flush-To-Zero only effects results.  Denormal inputs should also
     34   be flushed to zero.  */
    3335#include "softfloat.h"
    3436
     
    176178{
    177179
    178     return a & 0x007FFFFF;
     180    return float32_val(a) & 0x007FFFFF;
    179181
    180182}
     
    187189{
    188190
    189     return ( a>>23 ) & 0xFF;
     191    return ( float32_val(a)>>23 ) & 0xFF;
    190192
    191193}
     
    198200{
    199201
    200     return a>>31;
     202    return float32_val(a)>>31;
    201203
    202204}
     
    234236{
    235237
    236     return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
     238    return make_float32(
     239          ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig);
    237240
    238241}
     
    291294           ) {
    292295            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
    293             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
     296            return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
    294297        }
    295298        if ( zExp < 0 ) {
     299            if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
    296300            isTiny =
    297301                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
     
    338342{
    339343
    340     return a & LIT64( 0x000FFFFFFFFFFFFF );
     344    return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF );
    341345
    342346}
     
    349353{
    350354
    351     return ( a>>52 ) & 0x7FF;
     355    return ( float64_val(a)>>52 ) & 0x7FF;
    352356
    353357}
     
    360364{
    361365
    362     return a>>63;
     366    return float64_val(a)>>63;
    363367
    364368}
     
    396400{
    397401
    398     return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
     402    return make_float64(
     403        ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig);
    399404
    400405}
     
    453458           ) {
    454459            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
    455             return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
     460            return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
    456461        }
    457462        if ( zExp < 0 ) {
     463            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
    458464            isTiny =
    459465                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
     
    634640        }
    635641        if ( zExp <= 0 ) {
     642            if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 );
    636643            isTiny =
    637644                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
     
    964971        }
    965972        if ( zExp < 0 ) {
     973            if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
    966974            isTiny =
    967975                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
     
    10511059    flag zSign;
    10521060
    1053     if ( a == 0 ) return 0;
     1061    if ( a == 0 ) return float32_zero;
    10541062    if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
    10551063    zSign = ( a < 0 );
     
    10711079    bits64 zSig;
    10721080
    1073     if ( a == 0 ) return 0;
     1081    if ( a == 0 ) return float64_zero;
    10741082    zSign = ( a < 0 );
    10751083    absA = zSign ? - a : a;
     
    11451153    int8 shiftCount;
    11461154
    1147     if ( a == 0 ) return 0;
     1155    if ( a == 0 ) return float32_zero;
    11481156    zSign = ( a < 0 );
    11491157    absA = zSign ? - a : a;
     
    11651173}
    11661174
     1175float32 uint64_to_float32( uint64 a STATUS_PARAM )
     1176{
     1177    int8 shiftCount;
     1178
     1179    if ( a == 0 ) return float32_zero;
     1180    shiftCount = countLeadingZeros64( a ) - 40;
     1181    if ( 0 <= shiftCount ) {
     1182        return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount );
     1183    }
     1184    else {
     1185        shiftCount += 7;
     1186        if ( shiftCount < 0 ) {
     1187            shift64RightJamming( a, - shiftCount, &a );
     1188        }
     1189        else {
     1190            a <<= shiftCount;
     1191        }
     1192        return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR );
     1193    }
     1194}
     1195
    11671196/*----------------------------------------------------------------------------
    11681197| Returns the result of converting the 64-bit two's complement integer `a'
     
    11751204    flag zSign;
    11761205
    1177     if ( a == 0 ) return 0;
     1206    if ( a == 0 ) return float64_zero;
    11781207    if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) {
    11791208        return packFloat64( 1, 0x43E, 0 );
     
    11811210    zSign = ( a < 0 );
    11821211    return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
     1212
     1213}
     1214
     1215float64 uint64_to_float64( uint64 a STATUS_PARAM )
     1216{
     1217    if ( a == 0 ) return float64_zero;
     1218    return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR );
    11831219
    11841220}
     
    12981334    shiftCount = aExp - 0x9E;
    12991335    if ( 0 <= shiftCount ) {
    1300         if ( a != 0xCF000000 ) {
     1336        if ( float32_val(a) != 0xCF000000 ) {
    13011337            float_raise( float_flag_invalid STATUS_VAR);
    13021338            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
     
    13771413    shiftCount = aExp - 0xBE;
    13781414    if ( 0 <= shiftCount ) {
    1379         if ( a != 0xDF000000 ) {
     1415        if ( float32_val(a) != 0xDF000000 ) {
    13801416            float_raise( float_flag_invalid STATUS_VAR);
    13811417            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
     
    15081544    bits32 lastBitMask, roundBitsMask;
    15091545    int8 roundingMode;
    1510     float32 z;
     1546    bits32 z;
    15111547
    15121548    aExp = extractFloat32Exp( a );
     
    15181554    }
    15191555    if ( aExp <= 0x7E ) {
    1520         if ( (bits32) ( a<<1 ) == 0 ) return a;
     1556        if ( (bits32) ( float32_val(a)<<1 ) == 0 ) return a;
    15211557        STATUS(float_exception_flags) |= float_flag_inexact;
    15221558        aSign = extractFloat32Sign( a );
     
    15281564            break;
    15291565         case float_round_down:
    1530             return aSign ? 0xBF800000 : 0;
     1566            return make_float32(aSign ? 0xBF800000 : 0);
    15311567         case float_round_up:
    1532             return aSign ? 0x80000000 : 0x3F800000;
     1568            return make_float32(aSign ? 0x80000000 : 0x3F800000);
    15331569        }
    15341570        return packFloat32( aSign, 0, 0 );
     
    15371573    lastBitMask <<= 0x96 - aExp;
    15381574    roundBitsMask = lastBitMask - 1;
    1539     z = a;
     1575    z = float32_val(a);
    15401576    roundingMode = STATUS(float_rounding_mode);
    15411577    if ( roundingMode == float_round_nearest_even ) {
     
    15441580    }
    15451581    else if ( roundingMode != float_round_to_zero ) {
    1546         if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
     1582        if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) {
    15471583            z += roundBitsMask;
    15481584        }
    15491585    }
    15501586    z &= ~ roundBitsMask;
    1551     if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact;
    1552     return z;
     1587    if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact;
     1588    return make_float32(z);
    15531589
    15541590}
     
    16081644            return a;
    16091645        }
    1610         if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
     1646        if ( aExp == 0 ) {
     1647            if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
     1648            return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
     1649        }
    16111650        zSig = 0x40000000 + aSig + bSig;
    16121651        zExp = aExp;
     
    19812020    aSign = extractFloat32Sign( a );
    19822021    if ( aExp == 0xFF ) {
    1983         if ( aSig ) return propagateFloat32NaN( a, 0 STATUS_VAR );
     2022        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
    19842023        if ( ! aSign ) return a;
    19852024        float_raise( float_flag_invalid STATUS_VAR);
     
    19922031    }
    19932032    if ( aExp == 0 ) {
    1994         if ( aSig == 0 ) return 0;
     2033        if ( aSig == 0 ) return float32_zero;
    19952034        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
    19962035    }
     
    20192058
    20202059/*----------------------------------------------------------------------------
     2060| Returns the binary log of the single-precision floating-point value `a'.
     2061| The operation is performed according to the IEC/IEEE Standard for Binary
     2062| Floating-Point Arithmetic.
     2063*----------------------------------------------------------------------------*/
     2064float32 float32_log2( float32 a STATUS_PARAM )
     2065{
     2066    flag aSign, zSign;
     2067    int16 aExp;
     2068    bits32 aSig, zSig, i;
     2069
     2070    aSig = extractFloat32Frac( a );
     2071    aExp = extractFloat32Exp( a );
     2072    aSign = extractFloat32Sign( a );
     2073
     2074    if ( aExp == 0 ) {
     2075        if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
     2076        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
     2077    }
     2078    if ( aSign ) {
     2079        float_raise( float_flag_invalid STATUS_VAR);
     2080        return float32_default_nan;
     2081    }
     2082    if ( aExp == 0xFF ) {
     2083        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
     2084        return a;
     2085    }
     2086
     2087    aExp -= 0x7F;
     2088    aSig |= 0x00800000;
     2089    zSign = aExp < 0;
     2090    zSig = aExp << 23;
     2091
     2092    for (i = 1 << 22; i > 0; i >>= 1) {
     2093        aSig = ( (bits64)aSig * aSig ) >> 23;
     2094        if ( aSig & 0x01000000 ) {
     2095            aSig >>= 1;
     2096            zSig |= i;
     2097        }
     2098    }
     2099
     2100    if ( zSign )
     2101        zSig = -zSig;
     2102
     2103    return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
     2104}
     2105
     2106/*----------------------------------------------------------------------------
    20212107| Returns 1 if the single-precision floating-point value `a' is equal to
    20222108| the corresponding value `b', and 0 otherwise.  The comparison is performed
     
    20352121        return 0;
    20362122    }
    2037     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
     2123    return ( float32_val(a) == float32_val(b) ) ||
     2124            ( (bits32) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
    20382125
    20392126}
     
    20492136{
    20502137    flag aSign, bSign;
     2138    bits32 av, bv;
    20512139
    20522140    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
     
    20582146    aSign = extractFloat32Sign( a );
    20592147    bSign = extractFloat32Sign( b );
    2060     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
    2061     return ( a == b ) || ( aSign ^ ( a < b ) );
     2148    av = float32_val(a);
     2149    bv = float32_val(b);
     2150    if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
     2151    return ( av == bv ) || ( aSign ^ ( av < bv ) );
    20622152
    20632153}
     
    20722162{
    20732163    flag aSign, bSign;
     2164    bits32 av, bv;
    20742165
    20752166    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
     
    20812172    aSign = extractFloat32Sign( a );
    20822173    bSign = extractFloat32Sign( b );
    2083     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
    2084     return ( a != b ) && ( aSign ^ ( a < b ) );
     2174    av = float32_val(a);
     2175    bv = float32_val(b);
     2176    if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
     2177    return ( av != bv ) && ( aSign ^ ( av < bv ) );
    20852178
    20862179}
     
    20952188int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
    20962189{
     2190    bits32 av, bv;
    20972191
    20982192    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
     
    21022196        return 0;
    21032197    }
    2104     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
     2198    av = float32_val(a);
     2199    bv = float32_val(b);
     2200    return ( av == bv ) || ( (bits32) ( ( av | bv )<<1 ) == 0 );
    21052201
    21062202}
     
    21162212{
    21172213    flag aSign, bSign;
     2214    bits32 av, bv;
    21182215
    21192216    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
     
    21272224    aSign = extractFloat32Sign( a );
    21282225    bSign = extractFloat32Sign( b );
    2129     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
    2130     return ( a == b ) || ( aSign ^ ( a < b ) );
     2226    av = float32_val(a);
     2227    bv = float32_val(b);
     2228    if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
     2229    return ( av == bv ) || ( aSign ^ ( av < bv ) );
    21312230
    21322231}
     
    21422241{
    21432242    flag aSign, bSign;
     2243    bits32 av, bv;
    21442244
    21452245    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
     
    21532253    aSign = extractFloat32Sign( a );
    21542254    bSign = extractFloat32Sign( b );
    2155     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
    2156     return ( a != b ) && ( aSign ^ ( a < b ) );
     2255    av = float32_val(a);
     2256    bv = float32_val(b);
     2257    if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
     2258    return ( av != bv ) && ( aSign ^ ( av < bv ) );
    21572259
    21582260}
     
    22972399    if ( 0 <= shiftCount ) {
    22982400        if ( 0x43E <= aExp ) {
    2299             if ( a != LIT64( 0xC3E0000000000000 ) ) {
     2401            if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) {
    23002402                float_raise( float_flag_invalid STATUS_VAR);
    23012403                if (    ! aSign
     
    24372539    bits64 lastBitMask, roundBitsMask;
    24382540    int8 roundingMode;
    2439     float64 z;
     2541    bits64 z;
    24402542
    24412543    aExp = extractFloat64Exp( a );
     
    24472549    }
    24482550    if ( aExp < 0x3FF ) {
    2449         if ( (bits64) ( a<<1 ) == 0 ) return a;
     2551        if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a;
    24502552        STATUS(float_exception_flags) |= float_flag_inexact;
    24512553        aSign = extractFloat64Sign( a );
     
    24572559            break;
    24582560         case float_round_down:
    2459             return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
     2561            return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
    24602562         case float_round_up:
    2461             return
    2462             aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
     2563            return make_float64(
     2564            aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ));
    24632565        }
    24642566        return packFloat64( aSign, 0, 0 );
     
    24672569    lastBitMask <<= 0x433 - aExp;
    24682570    roundBitsMask = lastBitMask - 1;
    2469     z = a;
     2571    z = float64_val(a);
    24702572    roundingMode = STATUS(float_rounding_mode);
    24712573    if ( roundingMode == float_round_nearest_even ) {
     
    24742576    }
    24752577    else if ( roundingMode != float_round_to_zero ) {
    2476         if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
     2578        if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
    24772579            z += roundBitsMask;
    24782580        }
    24792581    }
    24802582    z &= ~ roundBitsMask;
    2481     if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact;
    2482     return z;
     2583    if ( z != float64_val(a) )
     2584        STATUS(float_exception_flags) |= float_flag_inexact;
     2585    return make_float64(z);
    24832586
    24842587}
     
    25492652            return a;
    25502653        }
    2551         if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
     2654        if ( aExp == 0 ) {
     2655            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
     2656            return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
     2657        }
    25522658        zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
    25532659        zExp = aExp;
     
    29243030    }
    29253031    if ( aExp == 0 ) {
    2926         if ( aSig == 0 ) return 0;
     3032        if ( aSig == 0 ) return float64_zero;
    29273033        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
    29283034    }
     
    29483054
    29493055/*----------------------------------------------------------------------------
     3056| Returns the binary log of the double-precision floating-point value `a'.
     3057| The operation is performed according to the IEC/IEEE Standard for Binary
     3058| Floating-Point Arithmetic.
     3059*----------------------------------------------------------------------------*/
     3060float64 float64_log2( float64 a STATUS_PARAM )
     3061{
     3062    flag aSign, zSign;
     3063    int16 aExp;
     3064    bits64 aSig, aSig0, aSig1, zSig, i;
     3065
     3066    aSig = extractFloat64Frac( a );
     3067    aExp = extractFloat64Exp( a );
     3068    aSign = extractFloat64Sign( a );
     3069
     3070    if ( aExp == 0 ) {
     3071        if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
     3072        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
     3073    }
     3074    if ( aSign ) {
     3075        float_raise( float_flag_invalid STATUS_VAR);
     3076        return float64_default_nan;
     3077    }
     3078    if ( aExp == 0x7FF ) {
     3079        if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );
     3080        return a;
     3081    }
     3082
     3083    aExp -= 0x3FF;
     3084    aSig |= LIT64( 0x0010000000000000 );
     3085    zSign = aExp < 0;
     3086    zSig = (bits64)aExp << 52;
     3087    for (i = 1LL << 51; i > 0; i >>= 1) {
     3088        mul64To128( aSig, aSig, &aSig0, &aSig1 );
     3089        aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );
     3090        if ( aSig & LIT64( 0x0020000000000000 ) ) {
     3091            aSig >>= 1;
     3092            zSig |= i;
     3093        }
     3094    }
     3095
     3096    if ( zSign )
     3097        zSig = -zSig;
     3098    return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
     3099}
     3100
     3101/*----------------------------------------------------------------------------
    29503102| Returns 1 if the double-precision floating-point value `a' is equal to the
    29513103| corresponding value `b', and 0 otherwise.  The comparison is performed
     
    29553107int float64_eq( float64 a, float64 b STATUS_PARAM )
    29563108{
     3109    bits64 av, bv;
    29573110
    29583111    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
     
    29643117        return 0;
    29653118    }
    2966     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
     3119    av = float64_val(a);
     3120    bv = float64_val(b);
     3121    return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 );
    29673122
    29683123}
     
    29783133{
    29793134    flag aSign, bSign;
     3135    bits64 av, bv;
    29803136
    29813137    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
     
    29873143    aSign = extractFloat64Sign( a );
    29883144    bSign = extractFloat64Sign( b );
    2989     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
    2990     return ( a == b ) || ( aSign ^ ( a < b ) );
     3145    av = float64_val(a);
     3146    bv = float64_val(b);
     3147    if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
     3148    return ( av == bv ) || ( aSign ^ ( av < bv ) );
    29913149
    29923150}
     
    30013159{
    30023160    flag aSign, bSign;
     3161    bits64 av, bv;
    30033162
    30043163    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
     
    30103169    aSign = extractFloat64Sign( a );
    30113170    bSign = extractFloat64Sign( b );
    3012     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
    3013     return ( a != b ) && ( aSign ^ ( a < b ) );
     3171    av = float64_val(a);
     3172    bv = float64_val(b);
     3173    if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
     3174    return ( av != bv ) && ( aSign ^ ( av < bv ) );
    30143175
    30153176}
     
    30243185int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
    30253186{
     3187    bits64 av, bv;
    30263188
    30273189    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
     
    30313193        return 0;
    30323194    }
    3033     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
     3195    av = float64_val(a);
     3196    bv = float64_val(b);
     3197    return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 );
    30343198
    30353199}
     
    30453209{
    30463210    flag aSign, bSign;
     3211    bits64 av, bv;
    30473212
    30483213    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
     
    30563221    aSign = extractFloat64Sign( a );
    30573222    bSign = extractFloat64Sign( b );
    3058     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
    3059     return ( a == b ) || ( aSign ^ ( a < b ) );
     3223    av = float64_val(a);
     3224    bv = float64_val(b);
     3225    if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
     3226    return ( av == bv ) || ( aSign ^ ( av < bv ) );
    30603227
    30613228}
     
    30713238{
    30723239    flag aSign, bSign;
     3240    bits64 av, bv;
    30733241
    30743242    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
     
    30823250    aSign = extractFloat64Sign( a );
    30833251    bSign = extractFloat64Sign( b );
    3084     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
    3085     return ( a != b ) && ( aSign ^ ( a < b ) );
     3252    av = float64_val(a);
     3253    bv = float64_val(b);
     3254    if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
     3255    return ( av != bv ) && ( aSign ^ ( av < bv ) );
    30863256
    30873257}
     
    45334703        }
    45344704        add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
    4535         if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
     4705        if ( aExp == 0 ) {
     4706            if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
     4707            return packFloat128( zSign, 0, zSig0, zSig1 );
     4708        }
    45364709        zSig2 = 0;
    45374710        zSig0 |= LIT64( 0x0002000000000000 );
     
    49235096    } while ( 0 <= (sbits64) aSig0 );
    49245097    add128(
    4925         aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
     5098        aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 );
    49265099    if (    ( sigMean0 < 0 )
    49275100         || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
     
    52835456}
    52845457
     5458/* FIXME: This looks broken.  */
     5459uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
     5460{
     5461    int64_t v;
     5462
     5463    v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
     5464    v += float64_val(a);
     5465    v = float64_to_int64(make_float64(v) STATUS_VAR);
     5466
     5467    return v - INT64_MIN;
     5468}
     5469
     5470uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
     5471{
     5472    int64_t v;
     5473
     5474    v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
     5475    v += float64_val(a);
     5476    v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
     5477
     5478    return v - INT64_MIN;
     5479}
     5480
    52855481#define COMPARE(s, nan_exp)                                                  \
    52865482INLINE int float ## s ## _compare_internal( float ## s a, float ## s b,      \
     
    52885484{                                                                            \
    52895485    flag aSign, bSign;                                                       \
     5486    bits ## s av, bv;                                                        \
    52905487                                                                             \
    52915488    if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&                    \
     
    53025499    aSign = extractFloat ## s ## Sign( a );                                  \
    53035500    bSign = extractFloat ## s ## Sign( b );                                  \
     5501    av = float ## s ## _val(a);                                              \
     5502    bv = float ## s ## _val(b);                                              \
    53045503    if ( aSign != bSign ) {                                                  \
    5305         if ( (bits ## s) ( ( a | b )<<1 ) == 0 ) {                           \
     5504        if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) {                         \
    53065505            /* zero case */                                                  \
    53075506            return float_relation_equal;                                     \
     
    53105509        }                                                                    \
    53115510    } else {                                                                 \
    5312         if (a == b) {                                                        \
     5511        if (av == bv) {                                                      \
    53135512            return float_relation_equal;                                     \
    53145513        } else {                                                             \
    5315             return 1 - 2 * (aSign ^ ( a < b ));                              \
     5514            return 1 - 2 * (aSign ^ ( av < bv ));                            \
    53165515        }                                                                    \
    53175516    }                                                                        \
     
    53305529COMPARE(32, 0xff)
    53315530COMPARE(64, 0x7ff)
     5531
     5532INLINE int float128_compare_internal( float128 a, float128 b,
     5533                                      int is_quiet STATUS_PARAM )
     5534{
     5535    flag aSign, bSign;
     5536
     5537    if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
     5538          ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
     5539        ( ( extractFloat128Exp( b ) == 0x7fff ) &&
     5540          ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
     5541        if (!is_quiet ||
     5542            float128_is_signaling_nan( a ) ||
     5543            float128_is_signaling_nan( b ) ) {
     5544            float_raise( float_flag_invalid STATUS_VAR);
     5545        }
     5546        return float_relation_unordered;
     5547    }
     5548    aSign = extractFloat128Sign( a );
     5549    bSign = extractFloat128Sign( b );
     5550    if ( aSign != bSign ) {
     5551        if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
     5552            /* zero case */
     5553            return float_relation_equal;
     5554        } else {
     5555            return 1 - (2 * aSign);
     5556        }
     5557    } else {
     5558        if (a.low == b.low && a.high == b.high) {
     5559            return float_relation_equal;
     5560        } else {
     5561            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
     5562        }
     5563    }
     5564}
     5565
     5566int float128_compare( float128 a, float128 b STATUS_PARAM )
     5567{
     5568    return float128_compare_internal(a, b, 0 STATUS_VAR);
     5569}
     5570
     5571int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
     5572{
     5573    return float128_compare_internal(a, b, 1 STATUS_VAR);
     5574}
     5575
     5576/* Multiply A by 2 raised to the power N.  */
     5577float32 float32_scalbn( float32 a, int n STATUS_PARAM )
     5578{
     5579    flag aSign;
     5580    int16 aExp;
     5581    bits32 aSig;
     5582
     5583    aSig = extractFloat32Frac( a );
     5584    aExp = extractFloat32Exp( a );
     5585    aSign = extractFloat32Sign( a );
     5586
     5587    if ( aExp == 0xFF ) {
     5588        return a;
     5589    }
     5590    if ( aExp != 0 )
     5591        aSig |= 0x00800000;
     5592    else if ( aSig == 0 )
     5593        return a;
     5594
     5595    aExp += n - 1;
     5596    aSig <<= 7;
     5597    return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
     5598}
     5599
     5600float64 float64_scalbn( float64 a, int n STATUS_PARAM )
     5601{
     5602    flag aSign;
     5603    int16 aExp;
     5604    bits64 aSig;
     5605
     5606    aSig = extractFloat64Frac( a );
     5607    aExp = extractFloat64Exp( a );
     5608    aSign = extractFloat64Sign( a );
     5609
     5610    if ( aExp == 0x7FF ) {
     5611        return a;
     5612    }
     5613    if ( aExp != 0 )
     5614        aSig |= LIT64( 0x0010000000000000 );
     5615    else if ( aSig == 0 )
     5616        return a;
     5617
     5618    aExp += n - 1;
     5619    aSig <<= 10;
     5620    return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
     5621}
     5622
     5623#ifdef FLOATX80
     5624floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
     5625{
     5626    flag aSign;
     5627    int16 aExp;
     5628    bits64 aSig;
     5629
     5630    aSig = extractFloatx80Frac( a );
     5631    aExp = extractFloatx80Exp( a );
     5632    aSign = extractFloatx80Sign( a );
     5633
     5634    if ( aExp == 0x7FF ) {
     5635        return a;
     5636    }
     5637    if (aExp == 0 && aSig == 0)
     5638        return a;
     5639
     5640    aExp += n;
     5641    return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
     5642                                          aSign, aExp, aSig, 0 STATUS_VAR );
     5643}
     5644#endif
     5645
     5646#ifdef FLOAT128
     5647float128 float128_scalbn( float128 a, int n STATUS_PARAM )
     5648{
     5649    flag aSign;
     5650    int32 aExp;
     5651    bits64 aSig0, aSig1;
     5652
     5653    aSig1 = extractFloat128Frac1( a );
     5654    aSig0 = extractFloat128Frac0( a );
     5655    aExp = extractFloat128Exp( a );
     5656    aSign = extractFloat128Sign( a );
     5657    if ( aExp == 0x7FFF ) {
     5658        return a;
     5659    }
     5660    if ( aExp != 0 )
     5661        aSig0 |= LIT64( 0x0001000000000000 );
     5662    else if ( aSig0 == 0 && aSig1 == 0 )
     5663        return a;
     5664
     5665    aExp += n - 1;
     5666    return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
     5667                                          STATUS_VAR );
     5668
     5669}
     5670#endif
  • trunk/src/recompiler_new/fpu/softfloat.h

    r13384 r18985  
    3636#include <VBox/types.h>
    3737#endif
     38
     39#if defined(HOST_SOLARIS) && defined(NEEDS_LIBSUNMATH)
     40#include <sunmath.h>
     41#endif
     42
     43#include <inttypes.h>
    3844#include "config.h"
    3945
     
    4955typedef uint8_t uint8;
    5056typedef int8_t int8;
     57#ifndef _AIX
    5158typedef int uint16;
    5259typedef int int16;
     60#endif
    5361typedef unsigned int uint32;
    5462typedef signed int int32;
     
    7280
    7381#define LIT64( a ) a##LL
    74 #ifdef _MSC_VER
    75 #define INLINE
    76 #else
    7782#define INLINE static inline
    78 #endif
    7983
    8084/*----------------------------------------------------------------------------
     
    9599#endif
    96100#endif /* !CONFIG_SOFTFLOAT */
     101
    97102#if defined(VBOX) && (!defined(FLOATX80) || defined(CONFIG_SOFTFLOAT))
    98103# error misconfigured
     
    117122| Software IEC/IEEE floating-point types.
    118123*----------------------------------------------------------------------------*/
     124/* Use structures for soft-float types.  This prevents accidentally mixing
     125   them with native int/float types.  A sufficiently clever compiler and
     126   sane ABI should be able to see though these structs.  However
     127   x86/gcc 3.x seems to struggle a bit, so leave them disabled by default.  */
     128//#define USE_SOFTFLOAT_STRUCT_TYPES
     129#ifdef USE_SOFTFLOAT_STRUCT_TYPES
     130typedef struct {
     131    uint32_t v;
     132} float32;
     133/* The cast ensures an error if the wrong type is passed.  */
     134#define float32_val(x) (((float32)(x)).v)
     135#define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
     136typedef struct {
     137    uint64_t v;
     138} float64;
     139#define float64_val(x) (((float64)(x)).v)
     140#define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
     141#else
    119142typedef uint32_t float32;
    120143typedef uint64_t float64;
     144#define float32_val(x) (x)
     145#define float64_val(x) (x)
     146#define make_float32(x) (x)
     147#define make_float64(x) (x)
     148#endif
    121149#ifdef FLOATX80
    122150typedef struct {
     
    171199    signed char floatx80_rounding_precision;
    172200#endif
     201    flag flush_to_zero;
     202    flag default_nan_mode;
    173203} float_status;
    174204
    175205void set_float_rounding_mode(int val STATUS_PARAM);
    176206void set_float_exception_flags(int val STATUS_PARAM);
     207INLINE void set_flush_to_zero(flag val STATUS_PARAM)
     208{
     209    STATUS(flush_to_zero) = val;
     210}
     211INLINE void set_default_nan_mode(flag val STATUS_PARAM)
     212{
     213    STATUS(default_nan_mode) = val;
     214}
    177215INLINE int get_float_exception_flags(float_status *status)
    178216{
     
    203241#endif
    204242float32 int64_to_float32( int64_t STATUS_PARAM );
     243float32 uint64_to_float32( uint64_t STATUS_PARAM );
    205244float64 int64_to_float64( int64_t STATUS_PARAM );
     245float64 uint64_to_float64( uint64_t STATUS_PARAM );
    206246#ifdef FLOATX80
    207247floatx80 int64_to_floatx80( int64_t STATUS_PARAM );
     
    238278float32 float32_rem( float32, float32 STATUS_PARAM );
    239279float32 float32_sqrt( float32 STATUS_PARAM );
     280float32 float32_log2( float32 STATUS_PARAM );
    240281int float32_eq( float32, float32 STATUS_PARAM );
    241282int float32_le( float32, float32 STATUS_PARAM );
     
    246287int float32_compare( float32, float32 STATUS_PARAM );
    247288int float32_compare_quiet( float32, float32 STATUS_PARAM );
     289int float32_is_nan( float32 );
    248290int float32_is_signaling_nan( float32 );
    249 int float64_is_nan( float64 a );
     291float32 float32_scalbn( float32, int STATUS_PARAM );
    250292
    251293INLINE float32 float32_abs(float32 a)
    252294{
    253     return a & 0x7fffffff;
     295    return make_float32(float32_val(a) & 0x7fffffff);
    254296}
    255297
    256298INLINE float32 float32_chs(float32 a)
    257299{
    258     return a ^ 0x80000000;
    259 }
     300    return make_float32(float32_val(a) ^ 0x80000000);
     301}
     302
     303INLINE int float32_is_infinity(float32 a)
     304{
     305    return (float32_val(a) & 0x7fffffff) == 0x7f800000;
     306}
     307
     308INLINE int float32_is_neg(float32 a)
     309{
     310    return float32_val(a) >> 31;
     311}
     312
     313INLINE int float32_is_zero(float32 a)
     314{
     315    return (float32_val(a) & 0x7fffffff) == 0;
     316}
     317
     318#define float32_zero make_float32(0)
     319#define float32_one make_float32(0x3f800000)
    260320
    261321/*----------------------------------------------------------------------------
     
    268328int64_t float64_to_int64( float64 STATUS_PARAM );
    269329int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
     330uint64_t float64_to_uint64 (float64 a STATUS_PARAM);
     331uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
    270332float32 float64_to_float32( float64 STATUS_PARAM );
    271333#ifdef FLOATX80
     
    287349float64 float64_rem( float64, float64 STATUS_PARAM );
    288350float64 float64_sqrt( float64 STATUS_PARAM );
     351float64 float64_log2( float64 STATUS_PARAM );
    289352int float64_eq( float64, float64 STATUS_PARAM );
    290353int float64_le( float64, float64 STATUS_PARAM );
     
    295358int float64_compare( float64, float64 STATUS_PARAM );
    296359int float64_compare_quiet( float64, float64 STATUS_PARAM );
     360int float64_is_nan( float64 a );
    297361int float64_is_signaling_nan( float64 );
     362float64 float64_scalbn( float64, int STATUS_PARAM );
    298363
    299364INLINE float64 float64_abs(float64 a)
    300365{
    301     return a & 0x7fffffffffffffffLL;
     366    return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
    302367}
    303368
    304369INLINE float64 float64_chs(float64 a)
    305370{
    306     return a ^ 0x8000000000000000LL;
    307 }
     371    return make_float64(float64_val(a) ^ 0x8000000000000000LL);
     372}
     373
     374INLINE int float64_is_infinity(float64 a)
     375{
     376    return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
     377}
     378
     379INLINE int float64_is_neg(float64 a)
     380{
     381    return float64_val(a) >> 63;
     382}
     383
     384INLINE int float64_is_zero(float64 a)
     385{
     386    return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
     387}
     388
     389#define float64_zero make_float64(0)
     390#define float64_one make_float64(0x3ff0000000000000LL)
    308391
    309392#ifdef FLOATX80
     
    338421int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
    339422int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
     423int floatx80_is_nan( floatx80 );
    340424int floatx80_is_signaling_nan( floatx80 );
     425floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM );
    341426
    342427INLINE floatx80 floatx80_abs(floatx80 a)
     
    350435    a.high ^= 0x8000;
    351436    return a;
     437}
     438
     439INLINE int floatx80_is_infinity(floatx80 a)
     440{
     441    return (a.high & 0x7fff) == 0x7fff && a.low == 0;
     442}
     443
     444INLINE int floatx80_is_neg(floatx80 a)
     445{
     446    return a.high >> 15;
     447}
     448
     449INLINE int floatx80_is_zero(floatx80 a)
     450{
     451    return (a.high & 0x7fff) == 0 && a.low == 0;
    352452}
    353453
     
    385485int float128_le_quiet( float128, float128 STATUS_PARAM );
    386486int float128_lt_quiet( float128, float128 STATUS_PARAM );
     487int float128_compare( float128, float128 STATUS_PARAM );
     488int float128_compare_quiet( float128, float128 STATUS_PARAM );
     489int float128_is_nan( float128 );
    387490int float128_is_signaling_nan( float128 );
     491float128 float128_scalbn( float128, int STATUS_PARAM );
    388492
    389493INLINE float128 float128_abs(float128 a)
     
    399503}
    400504
     505INLINE int float128_is_infinity(float128 a)
     506{
     507    return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
     508}
     509
     510INLINE int float128_is_neg(float128 a)
     511{
     512    return a.high >> 63;
     513}
     514
     515INLINE int float128_is_zero(float128 a)
     516{
     517    return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
     518}
     519
    401520#endif
    402521
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette