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

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       root       33: #endif
                     34: 
                     35: #if defined(__powerpc__)
                     36: 
                     37: /* correct (but slow) PowerPC rint() (glibc version is incorrect) */
                     38: double qemu_rint(double x)
                     39: {
                     40:     double y = 4503599627370496.0;
                     41:     if (fabs(x) >= y)
                     42:         return x;
                     43:     if (x < 0) 
                     44:         y = -y;
                     45:     y = (x + y) - y;
                     46:     if (y == 0.0)
                     47:         y = copysign(y, x);
                     48:     return y;
                     49: }
                     50: 
                     51: #define rint qemu_rint
                     52: #endif
                     53: 
                     54: /*----------------------------------------------------------------------------
                     55: | Software IEC/IEEE integer-to-floating-point conversion routines.
                     56: *----------------------------------------------------------------------------*/
                     57: float32 int32_to_float32(int v STATUS_PARAM)
                     58: {
                     59:     return (float32)v;
                     60: }
                     61: 
                     62: float64 int32_to_float64(int v STATUS_PARAM)
                     63: {
                     64:     return (float64)v;
                     65: }
                     66: 
                     67: #ifdef FLOATX80
                     68: floatx80 int32_to_floatx80(int v STATUS_PARAM)
                     69: {
                     70:     return (floatx80)v;
                     71: }
                     72: #endif
                     73: float32 int64_to_float32( int64_t v STATUS_PARAM)
                     74: {
                     75:     return (float32)v;
                     76: }
                     77: float64 int64_to_float64( int64_t v STATUS_PARAM)
                     78: {
                     79:     return (float64)v;
                     80: }
                     81: #ifdef FLOATX80
                     82: floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
                     83: {
                     84:     return (floatx80)v;
                     85: }
                     86: #endif
                     87: 
1.1.1.2   root       88: /* XXX: this code implements the x86 behaviour, not the IEEE one.  */
                     89: #if HOST_LONG_BITS == 32
                     90: static inline int long_to_int32(long a)
                     91: {
                     92:     return a;
                     93: }
                     94: #else
                     95: static inline int long_to_int32(long a)
                     96: {
                     97:     if (a != (int32_t)a) 
                     98:         a = 0x80000000;
                     99:     return a;
                    100: }
                    101: #endif
                    102: 
1.1       root      103: /*----------------------------------------------------------------------------
                    104: | Software IEC/IEEE single-precision conversion routines.
                    105: *----------------------------------------------------------------------------*/
                    106: int float32_to_int32( float32 a STATUS_PARAM)
                    107: {
1.1.1.2   root      108:     return long_to_int32(lrintf(a));
1.1       root      109: }
                    110: int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
                    111: {
                    112:     return (int)a;
                    113: }
                    114: int64_t float32_to_int64( float32 a STATUS_PARAM)
                    115: {
                    116:     return llrintf(a);
                    117: }
                    118: 
                    119: int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
                    120: {
                    121:     return (int64_t)a;
                    122: }
                    123: 
                    124: float64 float32_to_float64( float32 a STATUS_PARAM)
                    125: {
                    126:     return a;
                    127: }
                    128: #ifdef FLOATX80
                    129: floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
                    130: {
                    131:     return a;
                    132: }
                    133: #endif
                    134: 
                    135: /*----------------------------------------------------------------------------
                    136: | Software IEC/IEEE single-precision operations.
                    137: *----------------------------------------------------------------------------*/
                    138: float32 float32_round_to_int( float32 a STATUS_PARAM)
                    139: {
                    140:     return rintf(a);
                    141: }
                    142: 
                    143: float32 float32_rem( float32 a, float32 b STATUS_PARAM)
                    144: {
                    145:     return remainderf(a, b);
                    146: }
                    147: 
                    148: float32 float32_sqrt( float32 a STATUS_PARAM)
                    149: {
                    150:     return sqrtf(a);
                    151: }
                    152: char float32_compare( float32 a, float32 b STATUS_PARAM )
                    153: {
                    154:     if (a < b) {
                    155:         return -1;
                    156:     } else if (a == b) {
                    157:         return 0;
                    158:     } else if (a > b) {
                    159:         return 1;
                    160:     } else {
                    161:         return 2;
                    162:     }
                    163: }
                    164: char float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
                    165: {
                    166:     if (isless(a, b)) {
                    167:         return -1;
                    168:     } else if (a == b) {
                    169:         return 0;
                    170:     } else if (isgreater(a, b)) {
                    171:         return 1;
                    172:     } else {
                    173:         return 2;
                    174:     }
                    175: }
                    176: char float32_is_signaling_nan( float32 a1)
                    177: {
                    178:     float32u u;
                    179:     uint32_t a;
                    180:     u.f = a1;
                    181:     a = u.i;
                    182:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
                    183: }
                    184: 
                    185: /*----------------------------------------------------------------------------
                    186: | Software IEC/IEEE double-precision conversion routines.
                    187: *----------------------------------------------------------------------------*/
                    188: int float64_to_int32( float64 a STATUS_PARAM)
                    189: {
1.1.1.2   root      190:     return long_to_int32(lrint(a));
1.1       root      191: }
                    192: int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
                    193: {
                    194:     return (int)a;
                    195: }
                    196: int64_t float64_to_int64( float64 a STATUS_PARAM)
                    197: {
                    198:     return llrint(a);
                    199: }
                    200: int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
                    201: {
                    202:     return (int64_t)a;
                    203: }
                    204: float32 float64_to_float32( float64 a STATUS_PARAM)
                    205: {
                    206:     return a;
                    207: }
                    208: #ifdef FLOATX80
                    209: floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
                    210: {
                    211:     return a;
                    212: }
                    213: #endif
                    214: #ifdef FLOAT128
                    215: float128 float64_to_float128( float64 a STATUS_PARAM)
                    216: {
                    217:     return a;
                    218: }
                    219: #endif
                    220: 
                    221: /*----------------------------------------------------------------------------
                    222: | Software IEC/IEEE double-precision operations.
                    223: *----------------------------------------------------------------------------*/
                    224: float64 float64_round_to_int( float64 a STATUS_PARAM )
                    225: {
                    226: #if defined(__arm__)
                    227:     switch(STATUS(float_rounding_mode)) {
                    228:     default:
                    229:     case float_round_nearest_even:
                    230:         asm("rndd %0, %1" : "=f" (a) : "f"(a));
                    231:         break;
                    232:     case float_round_down:
                    233:         asm("rnddm %0, %1" : "=f" (a) : "f"(a));
                    234:         break;
                    235:     case float_round_up:
                    236:         asm("rnddp %0, %1" : "=f" (a) : "f"(a));
                    237:         break;
                    238:     case float_round_to_zero:
                    239:         asm("rnddz %0, %1" : "=f" (a) : "f"(a));
                    240:         break;
                    241:     }
                    242: #else
                    243:     return rint(a);
                    244: #endif
                    245: }
                    246: 
                    247: float64 float64_rem( float64 a, float64 b STATUS_PARAM)
                    248: {
                    249:     return remainder(a, b);
                    250: }
                    251: 
                    252: float64 float64_sqrt( float64 a STATUS_PARAM)
                    253: {
                    254:     return sqrt(a);
                    255: }
                    256: char float64_compare( float64 a, float64 b STATUS_PARAM )
                    257: {
                    258:     if (a < b) {
                    259:         return -1;
                    260:     } else if (a == b) {
                    261:         return 0;
                    262:     } else if (a > b) {
                    263:         return 1;
                    264:     } else {
                    265:         return 2;
                    266:     }
                    267: }
                    268: char float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
                    269: {
                    270:     if (isless(a, b)) {
                    271:         return -1;
                    272:     } else if (a == b) {
                    273:         return 0;
                    274:     } else if (isgreater(a, b)) {
                    275:         return 1;
                    276:     } else {
                    277:         return 2;
                    278:     }
                    279: }
                    280: char float64_is_signaling_nan( float64 a1)
                    281: {
                    282:     float64u u;
                    283:     uint64_t a;
                    284:     u.f = a1;
                    285:     a = u.i;
                    286:     return
                    287:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    288:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    289: 
                    290: }
                    291: 
                    292: #ifdef FLOATX80
                    293: 
                    294: /*----------------------------------------------------------------------------
                    295: | Software IEC/IEEE extended double-precision conversion routines.
                    296: *----------------------------------------------------------------------------*/
                    297: int floatx80_to_int32( floatx80 a STATUS_PARAM)
                    298: {
1.1.1.2   root      299:     return long_to_int32(lrintl(a));
1.1       root      300: }
                    301: int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
                    302: {
                    303:     return (int)a;
                    304: }
                    305: int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
                    306: {
                    307:     return llrintl(a);
                    308: }
                    309: int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
                    310: {
                    311:     return (int64_t)a;
                    312: }
                    313: float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
                    314: {
                    315:     return a;
                    316: }
                    317: float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
                    318: {
                    319:     return a;
                    320: }
                    321: 
                    322: /*----------------------------------------------------------------------------
                    323: | Software IEC/IEEE extended double-precision operations.
                    324: *----------------------------------------------------------------------------*/
                    325: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
                    326: {
                    327:     return rintl(a);
                    328: }
                    329: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
                    330: {
                    331:     return remainderl(a, b);
                    332: }
                    333: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
                    334: {
                    335:     return sqrtl(a);
                    336: }
                    337: char floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
                    338: {
                    339:     if (a < b) {
                    340:         return -1;
                    341:     } else if (a == b) {
                    342:         return 0;
                    343:     } else if (a > b) {
                    344:         return 1;
                    345:     } else {
                    346:         return 2;
                    347:     }
                    348: }
                    349: char floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
                    350: {
                    351:     if (isless(a, b)) {
                    352:         return -1;
                    353:     } else if (a == b) {
                    354:         return 0;
                    355:     } else if (isgreater(a, b)) {
                    356:         return 1;
                    357:     } else {
                    358:         return 2;
                    359:     }
                    360: }
                    361: char floatx80_is_signaling_nan( floatx80 a1)
                    362: {
                    363:     floatx80u u;
                    364:     u.f = a1;
                    365:     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
                    366: }
                    367: 
                    368: #endif

unix.superglobalmegacorp.com

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