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

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: 
1.1.1.6 ! root       54: #if defined(_ARCH_PPC)
1.1       root       55: 
                     56: /* correct (but slow) PowerPC rint() (glibc version is incorrect) */
1.1.1.6 ! root       57: static double qemu_rint(double x)
1.1       root       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) {
1.1.1.6 ! root      223:         return float_relation_less;
1.1       root      224:     } else if (a == b) {
1.1.1.6 ! root      225:         return float_relation_equal;
1.1       root      226:     } else if (a > b) {
1.1.1.6 ! root      227:         return float_relation_greater;
1.1       root      228:     } else {
1.1.1.6 ! root      229:         return float_relation_unordered;
1.1       root      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)) {
1.1.1.6 ! root      235:         return float_relation_less;
1.1       root      236:     } else if (a == b) {
1.1.1.6 ! root      237:         return float_relation_equal;
1.1       root      238:     } else if (isgreater(a, b)) {
1.1.1.6 ! root      239:         return float_relation_greater;
1.1       root      240:     } else {
1.1.1.6 ! root      241:         return float_relation_unordered;
1.1       root      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: 
1.1.1.6 ! root      253: int float32_is_nan( float32 a1 )
        !           254: {
        !           255:     float32u u;
        !           256:     uint64_t a;
        !           257:     u.f = a1;
        !           258:     a = u.i;
        !           259:     return ( 0xFF800000 < ( a<<1 ) );
        !           260: }
        !           261: 
1.1       root      262: /*----------------------------------------------------------------------------
                    263: | Software IEC/IEEE double-precision conversion routines.
                    264: *----------------------------------------------------------------------------*/
                    265: int float64_to_int32( float64 a STATUS_PARAM)
                    266: {
1.1.1.2   root      267:     return long_to_int32(lrint(a));
1.1       root      268: }
                    269: int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
                    270: {
                    271:     return (int)a;
                    272: }
                    273: int64_t float64_to_int64( float64 a STATUS_PARAM)
                    274: {
                    275:     return llrint(a);
                    276: }
                    277: int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
                    278: {
                    279:     return (int64_t)a;
                    280: }
                    281: float32 float64_to_float32( float64 a STATUS_PARAM)
                    282: {
                    283:     return a;
                    284: }
                    285: #ifdef FLOATX80
                    286: floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
                    287: {
                    288:     return a;
                    289: }
                    290: #endif
                    291: #ifdef FLOAT128
                    292: float128 float64_to_float128( float64 a STATUS_PARAM)
                    293: {
                    294:     return a;
                    295: }
                    296: #endif
                    297: 
1.1.1.5   root      298: unsigned int float64_to_uint32( float64 a STATUS_PARAM)
                    299: {
                    300:     int64_t v;
                    301:     unsigned int res;
                    302: 
                    303:     v = llrint(a);
                    304:     if (v < 0) {
                    305:         res = 0;
                    306:     } else if (v > 0xffffffff) {
                    307:         res = 0xffffffff;
                    308:     } else {
                    309:         res = v;
                    310:     }
                    311:     return res;
                    312: }
                    313: unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
                    314: {
                    315:     int64_t v;
                    316:     unsigned int res;
                    317: 
                    318:     v = (int64_t)a;
                    319:     if (v < 0) {
                    320:         res = 0;
                    321:     } else if (v > 0xffffffff) {
                    322:         res = 0xffffffff;
                    323:     } else {
                    324:         res = v;
                    325:     }
                    326:     return res;
                    327: }
                    328: uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
                    329: {
                    330:     int64_t v;
                    331: 
                    332:     v = llrint(a + (float64)INT64_MIN);
                    333: 
                    334:     return v - INT64_MIN;
                    335: }
                    336: uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
                    337: {
                    338:     int64_t v;
                    339: 
                    340:     v = (int64_t)(a + (float64)INT64_MIN);
                    341: 
                    342:     return v - INT64_MIN;
                    343: }
                    344: 
1.1       root      345: /*----------------------------------------------------------------------------
                    346: | Software IEC/IEEE double-precision operations.
                    347: *----------------------------------------------------------------------------*/
1.1.1.5   root      348: #if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
                    349: static inline float64 trunc(float64 x)
                    350: {
                    351:     return x < 0 ? -floor(-x) : floor(x);
                    352: }
                    353: #endif
1.1.1.4   root      354: float64 float64_trunc_to_int( float64 a STATUS_PARAM )
                    355: {
                    356:     return trunc(a);
                    357: }
                    358: 
1.1       root      359: float64 float64_round_to_int( float64 a STATUS_PARAM )
                    360: {
                    361: #if defined(__arm__)
                    362:     switch(STATUS(float_rounding_mode)) {
                    363:     default:
                    364:     case float_round_nearest_even:
                    365:         asm("rndd %0, %1" : "=f" (a) : "f"(a));
                    366:         break;
                    367:     case float_round_down:
                    368:         asm("rnddm %0, %1" : "=f" (a) : "f"(a));
                    369:         break;
                    370:     case float_round_up:
                    371:         asm("rnddp %0, %1" : "=f" (a) : "f"(a));
                    372:         break;
                    373:     case float_round_to_zero:
                    374:         asm("rnddz %0, %1" : "=f" (a) : "f"(a));
                    375:         break;
                    376:     }
                    377: #else
                    378:     return rint(a);
                    379: #endif
                    380: }
                    381: 
                    382: float64 float64_rem( float64 a, float64 b STATUS_PARAM)
                    383: {
                    384:     return remainder(a, b);
                    385: }
                    386: 
                    387: float64 float64_sqrt( float64 a STATUS_PARAM)
                    388: {
                    389:     return sqrt(a);
                    390: }
1.1.1.4   root      391: int float64_compare( float64 a, float64 b STATUS_PARAM )
1.1       root      392: {
                    393:     if (a < b) {
1.1.1.6 ! root      394:         return float_relation_less;
1.1       root      395:     } else if (a == b) {
1.1.1.6 ! root      396:         return float_relation_equal;
1.1       root      397:     } else if (a > b) {
1.1.1.6 ! root      398:         return float_relation_greater;
1.1       root      399:     } else {
1.1.1.6 ! root      400:         return float_relation_unordered;
1.1       root      401:     }
                    402: }
1.1.1.4   root      403: int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
1.1       root      404: {
                    405:     if (isless(a, b)) {
1.1.1.6 ! root      406:         return float_relation_less;
1.1       root      407:     } else if (a == b) {
1.1.1.6 ! root      408:         return float_relation_equal;
1.1       root      409:     } else if (isgreater(a, b)) {
1.1.1.6 ! root      410:         return float_relation_greater;
1.1       root      411:     } else {
1.1.1.6 ! root      412:         return float_relation_unordered;
1.1       root      413:     }
                    414: }
1.1.1.4   root      415: int float64_is_signaling_nan( float64 a1)
1.1       root      416: {
                    417:     float64u u;
                    418:     uint64_t a;
                    419:     u.f = a1;
                    420:     a = u.i;
                    421:     return
                    422:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    423:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    424: 
                    425: }
                    426: 
1.1.1.4   root      427: int float64_is_nan( float64 a1 )
                    428: {
                    429:     float64u u;
                    430:     uint64_t a;
                    431:     u.f = a1;
                    432:     a = u.i;
                    433: 
1.1.1.6 ! root      434:     return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) );
1.1.1.4   root      435: 
                    436: }
                    437: 
1.1       root      438: #ifdef FLOATX80
                    439: 
                    440: /*----------------------------------------------------------------------------
                    441: | Software IEC/IEEE extended double-precision conversion routines.
                    442: *----------------------------------------------------------------------------*/
                    443: int floatx80_to_int32( floatx80 a STATUS_PARAM)
                    444: {
1.1.1.2   root      445:     return long_to_int32(lrintl(a));
1.1       root      446: }
                    447: int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
                    448: {
                    449:     return (int)a;
                    450: }
                    451: int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
                    452: {
                    453:     return llrintl(a);
                    454: }
                    455: int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
                    456: {
                    457:     return (int64_t)a;
                    458: }
                    459: float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
                    460: {
                    461:     return a;
                    462: }
                    463: float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
                    464: {
                    465:     return a;
                    466: }
                    467: 
                    468: /*----------------------------------------------------------------------------
                    469: | Software IEC/IEEE extended double-precision operations.
                    470: *----------------------------------------------------------------------------*/
                    471: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
                    472: {
                    473:     return rintl(a);
                    474: }
                    475: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
                    476: {
                    477:     return remainderl(a, b);
                    478: }
                    479: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
                    480: {
                    481:     return sqrtl(a);
                    482: }
1.1.1.4   root      483: int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root      484: {
                    485:     if (a < b) {
1.1.1.6 ! root      486:         return float_relation_less;
1.1       root      487:     } else if (a == b) {
1.1.1.6 ! root      488:         return float_relation_equal;
1.1       root      489:     } else if (a > b) {
1.1.1.6 ! root      490:         return float_relation_greater;
1.1       root      491:     } else {
1.1.1.6 ! root      492:         return float_relation_unordered;
1.1       root      493:     }
                    494: }
1.1.1.4   root      495: int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root      496: {
                    497:     if (isless(a, b)) {
1.1.1.6 ! root      498:         return float_relation_less;
1.1       root      499:     } else if (a == b) {
1.1.1.6 ! root      500:         return float_relation_equal;
1.1       root      501:     } else if (isgreater(a, b)) {
1.1.1.6 ! root      502:         return float_relation_greater;
1.1       root      503:     } else {
1.1.1.6 ! root      504:         return float_relation_unordered;
1.1       root      505:     }
                    506: }
1.1.1.4   root      507: int floatx80_is_signaling_nan( floatx80 a1)
1.1       root      508: {
                    509:     floatx80u u;
1.1.1.6 ! root      510:     uint64_t aLow;
        !           511:     u.f = a1;
        !           512: 
        !           513:     aLow = u.i.low & ~ LIT64( 0x4000000000000000 );
        !           514:     return
        !           515:            ( ( u.i.high & 0x7FFF ) == 0x7FFF )
        !           516:         && (bits64) ( aLow<<1 )
        !           517:         && ( u.i.low == aLow );
        !           518: }
        !           519: 
        !           520: int floatx80_is_nan( floatx80 a1 )
        !           521: {
        !           522:     floatx80u u;
1.1       root      523:     u.f = a1;
                    524:     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
                    525: }
                    526: 
                    527: #endif

unix.superglobalmegacorp.com

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