Annotation of qemu/fpu/softfloat-native.c, revision 1.1.1.5

1.1       root        1: /* Native implementation of soft float functions. Only a single status
                      2:    context is supported */
                      3: #include "softfloat.h"
                      4: #include <math.h>
                      5: 
                      6: void set_float_rounding_mode(int val STATUS_PARAM)
                      7: {
                      8:     STATUS(float_rounding_mode) = val;
1.1.1.3   root        9: #if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
1.1       root       10:     fpsetround(val);
                     11: #elif defined(__arm__)
                     12:     /* nothing to do */
                     13: #else
                     14:     fesetround(val);
                     15: #endif
                     16: }
                     17: 
                     18: #ifdef FLOATX80
                     19: void set_floatx80_rounding_precision(int val STATUS_PARAM)
                     20: {
                     21:     STATUS(floatx80_rounding_precision) = val;
                     22: }
                     23: #endif
                     24: 
1.1.1.3   root       25: #if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
                     26: #define lrint(d)               ((int32_t)rint(d))
                     27: #define llrint(d)              ((int64_t)rint(d))
                     28: #define lrintf(f)              ((int32_t)rint(f))
                     29: #define llrintf(f)             ((int64_t)rint(f))
                     30: #define sqrtf(f)               ((float)sqrt(f))
                     31: #define remainderf(fa, fb)     ((float)remainder(fa, fb))
                     32: #define rintf(f)               ((float)rint(f))
1.1.1.5 ! root       33: #if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
        !            34: extern long double rintl(long double);
        !            35: extern long double scalbnl(long double, int);
        !            36: 
        !            37: long long
        !            38: llrintl(long double x) {
        !            39:        return ((long long) rintl(x));
        !            40: }
        !            41: 
        !            42: long
        !            43: lrintl(long double x) {
        !            44:        return ((long) rintl(x));
        !            45: }
        !            46: 
        !            47: long double
        !            48: ldexpl(long double x, int n) {
        !            49:        return (scalbnl(x, n));
        !            50: }
        !            51: #endif
1.1       root       52: #endif
                     53: 
                     54: #if defined(__powerpc__)
                     55: 
                     56: /* correct (but slow) PowerPC rint() (glibc version is incorrect) */
                     57: double qemu_rint(double x)
                     58: {
                     59:     double y = 4503599627370496.0;
                     60:     if (fabs(x) >= y)
                     61:         return x;
1.1.1.5 ! root       62:     if (x < 0)
1.1       root       63:         y = -y;
                     64:     y = (x + y) - y;
                     65:     if (y == 0.0)
                     66:         y = copysign(y, x);
                     67:     return y;
                     68: }
                     69: 
                     70: #define rint qemu_rint
                     71: #endif
                     72: 
                     73: /*----------------------------------------------------------------------------
                     74: | Software IEC/IEEE integer-to-floating-point conversion routines.
                     75: *----------------------------------------------------------------------------*/
                     76: float32 int32_to_float32(int v STATUS_PARAM)
                     77: {
                     78:     return (float32)v;
                     79: }
                     80: 
1.1.1.5 ! root       81: float32 uint32_to_float32(unsigned int v STATUS_PARAM)
        !            82: {
        !            83:     return (float32)v;
        !            84: }
        !            85: 
1.1       root       86: float64 int32_to_float64(int v STATUS_PARAM)
                     87: {
                     88:     return (float64)v;
                     89: }
                     90: 
1.1.1.5 ! root       91: float64 uint32_to_float64(unsigned int v STATUS_PARAM)
        !            92: {
        !            93:     return (float64)v;
        !            94: }
        !            95: 
1.1       root       96: #ifdef FLOATX80
                     97: floatx80 int32_to_floatx80(int v STATUS_PARAM)
                     98: {
                     99:     return (floatx80)v;
                    100: }
                    101: #endif
                    102: float32 int64_to_float32( int64_t v STATUS_PARAM)
                    103: {
                    104:     return (float32)v;
                    105: }
1.1.1.5 ! root      106: float32 uint64_to_float32( uint64_t v STATUS_PARAM)
        !           107: {
        !           108:     return (float32)v;
        !           109: }
1.1       root      110: float64 int64_to_float64( int64_t v STATUS_PARAM)
                    111: {
                    112:     return (float64)v;
                    113: }
1.1.1.5 ! root      114: float64 uint64_to_float64( uint64_t v STATUS_PARAM)
        !           115: {
        !           116:     return (float64)v;
        !           117: }
1.1       root      118: #ifdef FLOATX80
                    119: floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
                    120: {
                    121:     return (floatx80)v;
                    122: }
                    123: #endif
                    124: 
1.1.1.2   root      125: /* XXX: this code implements the x86 behaviour, not the IEEE one.  */
                    126: #if HOST_LONG_BITS == 32
                    127: static inline int long_to_int32(long a)
                    128: {
                    129:     return a;
                    130: }
                    131: #else
                    132: static inline int long_to_int32(long a)
                    133: {
1.1.1.5 ! root      134:     if (a != (int32_t)a)
1.1.1.2   root      135:         a = 0x80000000;
                    136:     return a;
                    137: }
                    138: #endif
                    139: 
1.1       root      140: /*----------------------------------------------------------------------------
                    141: | Software IEC/IEEE single-precision conversion routines.
                    142: *----------------------------------------------------------------------------*/
                    143: int float32_to_int32( float32 a STATUS_PARAM)
                    144: {
1.1.1.2   root      145:     return long_to_int32(lrintf(a));
1.1       root      146: }
                    147: int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
                    148: {
                    149:     return (int)a;
                    150: }
                    151: int64_t float32_to_int64( float32 a STATUS_PARAM)
                    152: {
                    153:     return llrintf(a);
                    154: }
                    155: 
                    156: int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
                    157: {
                    158:     return (int64_t)a;
                    159: }
                    160: 
                    161: float64 float32_to_float64( float32 a STATUS_PARAM)
                    162: {
                    163:     return a;
                    164: }
                    165: #ifdef FLOATX80
                    166: floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
                    167: {
                    168:     return a;
                    169: }
                    170: #endif
                    171: 
1.1.1.5 ! root      172: unsigned int float32_to_uint32( float32 a STATUS_PARAM)
        !           173: {
        !           174:     int64_t v;
        !           175:     unsigned int res;
        !           176: 
        !           177:     v = llrintf(a);
        !           178:     if (v < 0) {
        !           179:         res = 0;
        !           180:     } else if (v > 0xffffffff) {
        !           181:         res = 0xffffffff;
        !           182:     } else {
        !           183:         res = v;
        !           184:     }
        !           185:     return res;
        !           186: }
        !           187: unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
        !           188: {
        !           189:     int64_t v;
        !           190:     unsigned int res;
        !           191: 
        !           192:     v = (int64_t)a;
        !           193:     if (v < 0) {
        !           194:         res = 0;
        !           195:     } else if (v > 0xffffffff) {
        !           196:         res = 0xffffffff;
        !           197:     } else {
        !           198:         res = v;
        !           199:     }
        !           200:     return res;
        !           201: }
        !           202: 
1.1       root      203: /*----------------------------------------------------------------------------
                    204: | Software IEC/IEEE single-precision operations.
                    205: *----------------------------------------------------------------------------*/
                    206: float32 float32_round_to_int( float32 a STATUS_PARAM)
                    207: {
                    208:     return rintf(a);
                    209: }
                    210: 
                    211: float32 float32_rem( float32 a, float32 b STATUS_PARAM)
                    212: {
                    213:     return remainderf(a, b);
                    214: }
                    215: 
                    216: float32 float32_sqrt( float32 a STATUS_PARAM)
                    217: {
                    218:     return sqrtf(a);
                    219: }
1.1.1.4   root      220: int float32_compare( float32 a, float32 b STATUS_PARAM )
1.1       root      221: {
                    222:     if (a < b) {
                    223:         return -1;
                    224:     } else if (a == b) {
                    225:         return 0;
                    226:     } else if (a > b) {
                    227:         return 1;
                    228:     } else {
                    229:         return 2;
                    230:     }
                    231: }
1.1.1.4   root      232: int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
1.1       root      233: {
                    234:     if (isless(a, b)) {
                    235:         return -1;
                    236:     } else if (a == b) {
                    237:         return 0;
                    238:     } else if (isgreater(a, b)) {
                    239:         return 1;
                    240:     } else {
                    241:         return 2;
                    242:     }
                    243: }
1.1.1.4   root      244: int float32_is_signaling_nan( float32 a1)
1.1       root      245: {
                    246:     float32u u;
                    247:     uint32_t a;
                    248:     u.f = a1;
                    249:     a = u.i;
                    250:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
                    251: }
                    252: 
                    253: /*----------------------------------------------------------------------------
                    254: | Software IEC/IEEE double-precision conversion routines.
                    255: *----------------------------------------------------------------------------*/
                    256: int float64_to_int32( float64 a STATUS_PARAM)
                    257: {
1.1.1.2   root      258:     return long_to_int32(lrint(a));
1.1       root      259: }
                    260: int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
                    261: {
                    262:     return (int)a;
                    263: }
                    264: int64_t float64_to_int64( float64 a STATUS_PARAM)
                    265: {
                    266:     return llrint(a);
                    267: }
                    268: int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
                    269: {
                    270:     return (int64_t)a;
                    271: }
                    272: float32 float64_to_float32( float64 a STATUS_PARAM)
                    273: {
                    274:     return a;
                    275: }
                    276: #ifdef FLOATX80
                    277: floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
                    278: {
                    279:     return a;
                    280: }
                    281: #endif
                    282: #ifdef FLOAT128
                    283: float128 float64_to_float128( float64 a STATUS_PARAM)
                    284: {
                    285:     return a;
                    286: }
                    287: #endif
                    288: 
1.1.1.5 ! root      289: unsigned int float64_to_uint32( float64 a STATUS_PARAM)
        !           290: {
        !           291:     int64_t v;
        !           292:     unsigned int res;
        !           293: 
        !           294:     v = llrint(a);
        !           295:     if (v < 0) {
        !           296:         res = 0;
        !           297:     } else if (v > 0xffffffff) {
        !           298:         res = 0xffffffff;
        !           299:     } else {
        !           300:         res = v;
        !           301:     }
        !           302:     return res;
        !           303: }
        !           304: unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
        !           305: {
        !           306:     int64_t v;
        !           307:     unsigned int res;
        !           308: 
        !           309:     v = (int64_t)a;
        !           310:     if (v < 0) {
        !           311:         res = 0;
        !           312:     } else if (v > 0xffffffff) {
        !           313:         res = 0xffffffff;
        !           314:     } else {
        !           315:         res = v;
        !           316:     }
        !           317:     return res;
        !           318: }
        !           319: uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
        !           320: {
        !           321:     int64_t v;
        !           322: 
        !           323:     v = llrint(a + (float64)INT64_MIN);
        !           324: 
        !           325:     return v - INT64_MIN;
        !           326: }
        !           327: uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
        !           328: {
        !           329:     int64_t v;
        !           330: 
        !           331:     v = (int64_t)(a + (float64)INT64_MIN);
        !           332: 
        !           333:     return v - INT64_MIN;
        !           334: }
        !           335: 
1.1       root      336: /*----------------------------------------------------------------------------
                    337: | Software IEC/IEEE double-precision operations.
                    338: *----------------------------------------------------------------------------*/
1.1.1.5 ! root      339: #if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
        !           340: static inline float64 trunc(float64 x)
        !           341: {
        !           342:     return x < 0 ? -floor(-x) : floor(x);
        !           343: }
        !           344: #endif
1.1.1.4   root      345: float64 float64_trunc_to_int( float64 a STATUS_PARAM )
                    346: {
                    347:     return trunc(a);
                    348: }
                    349: 
1.1       root      350: float64 float64_round_to_int( float64 a STATUS_PARAM )
                    351: {
                    352: #if defined(__arm__)
                    353:     switch(STATUS(float_rounding_mode)) {
                    354:     default:
                    355:     case float_round_nearest_even:
                    356:         asm("rndd %0, %1" : "=f" (a) : "f"(a));
                    357:         break;
                    358:     case float_round_down:
                    359:         asm("rnddm %0, %1" : "=f" (a) : "f"(a));
                    360:         break;
                    361:     case float_round_up:
                    362:         asm("rnddp %0, %1" : "=f" (a) : "f"(a));
                    363:         break;
                    364:     case float_round_to_zero:
                    365:         asm("rnddz %0, %1" : "=f" (a) : "f"(a));
                    366:         break;
                    367:     }
                    368: #else
                    369:     return rint(a);
                    370: #endif
                    371: }
                    372: 
                    373: float64 float64_rem( float64 a, float64 b STATUS_PARAM)
                    374: {
                    375:     return remainder(a, b);
                    376: }
                    377: 
                    378: float64 float64_sqrt( float64 a STATUS_PARAM)
                    379: {
                    380:     return sqrt(a);
                    381: }
1.1.1.4   root      382: int float64_compare( float64 a, float64 b STATUS_PARAM )
1.1       root      383: {
                    384:     if (a < b) {
                    385:         return -1;
                    386:     } else if (a == b) {
                    387:         return 0;
                    388:     } else if (a > b) {
                    389:         return 1;
                    390:     } else {
                    391:         return 2;
                    392:     }
                    393: }
1.1.1.4   root      394: int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
1.1       root      395: {
                    396:     if (isless(a, b)) {
                    397:         return -1;
                    398:     } else if (a == b) {
                    399:         return 0;
                    400:     } else if (isgreater(a, b)) {
                    401:         return 1;
                    402:     } else {
                    403:         return 2;
                    404:     }
                    405: }
1.1.1.4   root      406: int float64_is_signaling_nan( float64 a1)
1.1       root      407: {
                    408:     float64u u;
                    409:     uint64_t a;
                    410:     u.f = a1;
                    411:     a = u.i;
                    412:     return
                    413:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    414:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    415: 
                    416: }
                    417: 
1.1.1.4   root      418: int float64_is_nan( float64 a1 )
                    419: {
                    420:     float64u u;
                    421:     uint64_t a;
                    422:     u.f = a1;
                    423:     a = u.i;
                    424: 
                    425:     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
                    426: 
                    427: }
                    428: 
1.1       root      429: #ifdef FLOATX80
                    430: 
                    431: /*----------------------------------------------------------------------------
                    432: | Software IEC/IEEE extended double-precision conversion routines.
                    433: *----------------------------------------------------------------------------*/
                    434: int floatx80_to_int32( floatx80 a STATUS_PARAM)
                    435: {
1.1.1.2   root      436:     return long_to_int32(lrintl(a));
1.1       root      437: }
                    438: int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
                    439: {
                    440:     return (int)a;
                    441: }
                    442: int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
                    443: {
                    444:     return llrintl(a);
                    445: }
                    446: int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
                    447: {
                    448:     return (int64_t)a;
                    449: }
                    450: float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
                    451: {
                    452:     return a;
                    453: }
                    454: float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
                    455: {
                    456:     return a;
                    457: }
                    458: 
                    459: /*----------------------------------------------------------------------------
                    460: | Software IEC/IEEE extended double-precision operations.
                    461: *----------------------------------------------------------------------------*/
                    462: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
                    463: {
                    464:     return rintl(a);
                    465: }
                    466: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
                    467: {
                    468:     return remainderl(a, b);
                    469: }
                    470: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
                    471: {
                    472:     return sqrtl(a);
                    473: }
1.1.1.4   root      474: int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root      475: {
                    476:     if (a < b) {
                    477:         return -1;
                    478:     } else if (a == b) {
                    479:         return 0;
                    480:     } else if (a > b) {
                    481:         return 1;
                    482:     } else {
                    483:         return 2;
                    484:     }
                    485: }
1.1.1.4   root      486: int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root      487: {
                    488:     if (isless(a, b)) {
                    489:         return -1;
                    490:     } else if (a == b) {
                    491:         return 0;
                    492:     } else if (isgreater(a, b)) {
                    493:         return 1;
                    494:     } else {
                    495:         return 2;
                    496:     }
                    497: }
1.1.1.4   root      498: int floatx80_is_signaling_nan( floatx80 a1)
1.1       root      499: {
                    500:     floatx80u u;
                    501:     u.f = a1;
                    502:     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
                    503: }
                    504: 
                    505: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.