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

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

unix.superglobalmegacorp.com

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