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

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

unix.superglobalmegacorp.com

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