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

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: #else
                     16:     fesetround(val);
                     17: #endif
                     18: }
                     19: 
                     20: #ifdef FLOATX80
                     21: void set_floatx80_rounding_precision(int val STATUS_PARAM)
                     22: {
                     23:     STATUS(floatx80_rounding_precision) = val;
                     24: }
                     25: #endif
                     26: 
1.1.1.8   root       27: #if defined(CONFIG_BSD) || \
                     28:     (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1.1.3   root       29: #define lrint(d)               ((int32_t)rint(d))
                     30: #define llrint(d)              ((int64_t)rint(d))
                     31: #define lrintf(f)              ((int32_t)rint(f))
                     32: #define llrintf(f)             ((int64_t)rint(f))
                     33: #define sqrtf(f)               ((float)sqrt(f))
                     34: #define remainderf(fa, fb)     ((float)remainder(fa, fb))
                     35: #define rintf(f)               ((float)rint(f))
1.1.1.8   root       36: #if !defined(__sparc__) && \
                     37:     (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1.1.5   root       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.10! root      257: int float32_is_quiet_nan( float32 a1 )
1.1.1.6   root      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.8   root      352: #if defined(__sun__) && \
                    353:     (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1.1.5   root      354: static inline float64 trunc(float64 x)
                    355: {
                    356:     return x < 0 ? -floor(-x) : floor(x);
                    357: }
                    358: #endif
1.1.1.4   root      359: float64 float64_trunc_to_int( float64 a STATUS_PARAM )
                    360: {
                    361:     return trunc(a);
                    362: }
                    363: 
1.1       root      364: float64 float64_round_to_int( float64 a STATUS_PARAM )
                    365: {
                    366:     return rint(a);
                    367: }
                    368: 
                    369: float64 float64_rem( float64 a, float64 b STATUS_PARAM)
                    370: {
                    371:     return remainder(a, b);
                    372: }
                    373: 
                    374: float64 float64_sqrt( float64 a STATUS_PARAM)
                    375: {
                    376:     return sqrt(a);
                    377: }
1.1.1.4   root      378: int float64_compare( float64 a, float64 b STATUS_PARAM )
1.1       root      379: {
                    380:     if (a < b) {
1.1.1.6   root      381:         return float_relation_less;
1.1       root      382:     } else if (a == b) {
1.1.1.6   root      383:         return float_relation_equal;
1.1       root      384:     } else if (a > b) {
1.1.1.6   root      385:         return float_relation_greater;
1.1       root      386:     } else {
1.1.1.6   root      387:         return float_relation_unordered;
1.1       root      388:     }
                    389: }
1.1.1.4   root      390: int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
1.1       root      391: {
                    392:     if (isless(a, b)) {
1.1.1.6   root      393:         return float_relation_less;
1.1       root      394:     } else if (a == b) {
1.1.1.6   root      395:         return float_relation_equal;
1.1       root      396:     } else if (isgreater(a, b)) {
1.1.1.6   root      397:         return float_relation_greater;
1.1       root      398:     } else {
1.1.1.6   root      399:         return float_relation_unordered;
1.1       root      400:     }
                    401: }
1.1.1.4   root      402: int float64_is_signaling_nan( float64 a1)
1.1       root      403: {
                    404:     float64u u;
                    405:     uint64_t a;
                    406:     u.f = a1;
                    407:     a = u.i;
                    408:     return
                    409:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    410:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    411: 
                    412: }
                    413: 
1.1.1.10! root      414: int float64_is_quiet_nan( float64 a1 )
1.1.1.4   root      415: {
                    416:     float64u u;
                    417:     uint64_t a;
                    418:     u.f = a1;
                    419:     a = u.i;
                    420: 
1.1.1.6   root      421:     return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) );
1.1.1.4   root      422: 
                    423: }
                    424: 
1.1       root      425: #ifdef FLOATX80
                    426: 
                    427: /*----------------------------------------------------------------------------
                    428: | Software IEC/IEEE extended double-precision conversion routines.
                    429: *----------------------------------------------------------------------------*/
                    430: int floatx80_to_int32( floatx80 a STATUS_PARAM)
                    431: {
1.1.1.2   root      432:     return long_to_int32(lrintl(a));
1.1       root      433: }
                    434: int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
                    435: {
                    436:     return (int)a;
                    437: }
                    438: int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
                    439: {
                    440:     return llrintl(a);
                    441: }
                    442: int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
                    443: {
                    444:     return (int64_t)a;
                    445: }
                    446: float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
                    447: {
                    448:     return a;
                    449: }
                    450: float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
                    451: {
                    452:     return a;
                    453: }
                    454: 
                    455: /*----------------------------------------------------------------------------
                    456: | Software IEC/IEEE extended double-precision operations.
                    457: *----------------------------------------------------------------------------*/
                    458: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
                    459: {
                    460:     return rintl(a);
                    461: }
                    462: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
                    463: {
                    464:     return remainderl(a, b);
                    465: }
                    466: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
                    467: {
                    468:     return sqrtl(a);
                    469: }
1.1.1.4   root      470: int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root      471: {
                    472:     if (a < b) {
1.1.1.6   root      473:         return float_relation_less;
1.1       root      474:     } else if (a == b) {
1.1.1.6   root      475:         return float_relation_equal;
1.1       root      476:     } else if (a > b) {
1.1.1.6   root      477:         return float_relation_greater;
1.1       root      478:     } else {
1.1.1.6   root      479:         return float_relation_unordered;
1.1       root      480:     }
                    481: }
1.1.1.4   root      482: int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root      483: {
                    484:     if (isless(a, b)) {
1.1.1.6   root      485:         return float_relation_less;
1.1       root      486:     } else if (a == b) {
1.1.1.6   root      487:         return float_relation_equal;
1.1       root      488:     } else if (isgreater(a, b)) {
1.1.1.6   root      489:         return float_relation_greater;
1.1       root      490:     } else {
1.1.1.6   root      491:         return float_relation_unordered;
1.1       root      492:     }
                    493: }
1.1.1.4   root      494: int floatx80_is_signaling_nan( floatx80 a1)
1.1       root      495: {
                    496:     floatx80u u;
1.1.1.6   root      497:     uint64_t aLow;
                    498:     u.f = a1;
                    499: 
                    500:     aLow = u.i.low & ~ LIT64( 0x4000000000000000 );
                    501:     return
                    502:            ( ( u.i.high & 0x7FFF ) == 0x7FFF )
                    503:         && (bits64) ( aLow<<1 )
                    504:         && ( u.i.low == aLow );
                    505: }
                    506: 
1.1.1.10! root      507: int floatx80_is_quiet_nan( floatx80 a1 )
1.1.1.6   root      508: {
                    509:     floatx80u u;
1.1       root      510:     u.f = a1;
                    511:     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
                    512: }
                    513: 
                    514: #endif

unix.superglobalmegacorp.com

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