(linenum→info "unix/slp.c:2238")

qemu/0.9.1/fpu/softfloat-native.h

    1: /* Native implementation of soft float functions */
    2: #include <math.h>
    3: 
    4: #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
    5: #include <ieeefp.h>
    6: #define fabsf(f) ((float)fabs(f))
    7: #else
    8: #include <fenv.h>
    9: #endif
   10: 
   11: /*
   12:  * Define some C99-7.12.3 classification macros and
   13:  *        some C99-.12.4 for Solaris systems OS less than 10,
   14:  *        or Solaris 10 systems running GCC 3.x or less.
   15:  *   Solaris 10 with GCC4 does not need these macros as they
   16:  *   are defined in <iso/math_c99.h> with a compiler directive
   17:  */
   18: #if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) && (__GNUC__ <= 4)))
   19: /*
   20:  * C99 7.12.3 classification macros
   21:  * and
   22:  * C99 7.12.14 comparison macros
   23:  *
   24:  * ... do not work on Solaris 10 using GNU CC 3.4.x.
   25:  * Try to workaround the missing / broken C99 math macros.
   26:  */
   27: 
   28: #define isnormal(x)             (fpclass(x) >= FP_NZERO)
   29: #define isgreater(x, y)         ((!unordered(x, y)) && ((x) > (y)))
   30: #define isgreaterequal(x, y)    ((!unordered(x, y)) && ((x) >= (y)))
   31: #define isless(x, y)            ((!unordered(x, y)) && ((x) < (y)))
   32: #define islessequal(x, y)       ((!unordered(x, y)) && ((x) <= (y)))
   33: #define isunordered(x,y)        unordered(x, y)
   34: #endif
   35: 
   36: #if defined(__sun__) && !defined(NEED_LIBSUNMATH)
   37: 
   38: #ifndef isnan
   39: # define isnan(x) \
   40:     (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
   41:      : sizeof (x) == sizeof (double) ? isnan_d (x) \
   42:      : isnan_f (x))
   43: static inline int isnan_f  (float       x) { return x != x; }
   44: static inline int isnan_d  (double      x) { return x != x; }
   45: static inline int isnan_ld (long double x) { return x != x; }
   46: #endif
   47: 
   48: #ifndef isinf
   49: # define isinf(x) \
   50:     (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
   51:      : sizeof (x) == sizeof (double) ? isinf_d (x) \
   52:      : isinf_f (x))
   53: static inline int isinf_f  (float       x) { return isnan (x - x); }
   54: static inline int isinf_d  (double      x) { return isnan (x - x); }
   55: static inline int isinf_ld (long double x) { return isnan (x - x); }
   56: #endif
   57: #endif
   58: 
   59: typedef float float32;
   60: typedef double float64;
   61: #ifdef FLOATX80
   62: typedef long double floatx80;
   63: #endif
   64: 
   65: typedef union {
   66:     float32 f;
   67:     uint32_t i;
   68: } float32u;
   69: typedef union {
   70:     float64 f;
   71:     uint64_t i;
   72: } float64u;
   73: #ifdef FLOATX80
   74: typedef union {
   75:     floatx80 f;
   76:     struct {
   77:         uint64_t low;
   78:         uint16_t high;
   79:     } i;
   80: } floatx80u;
   81: #endif
   82: 
   83: /*----------------------------------------------------------------------------
   84: | Software IEC/IEEE floating-point rounding mode.
   85: *----------------------------------------------------------------------------*/
   86: #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
   87: enum {
   88:     float_round_nearest_even = FP_RN,
   89:     float_round_down         = FP_RM,
   90:     float_round_up           = FP_RP,
   91:     float_round_to_zero      = FP_RZ
   92: };
   93: #elif defined(__arm__)
   94: enum {
   95:     float_round_nearest_even = 0,
   96:     float_round_down         = 1,
   97:     float_round_up           = 2,
   98:     float_round_to_zero      = 3
   99: };
  100: #else
  101: enum {
  102:     float_round_nearest_even = FE_TONEAREST,
  103:     float_round_down         = FE_DOWNWARD,
  104:     float_round_up           = FE_UPWARD,
  105:     float_round_to_zero      = FE_TOWARDZERO
  106: };
  107: #endif
  108: 
  109: typedef struct float_status {
  110:     signed char float_rounding_mode;
  111: #ifdef FLOATX80
  112:     signed char floatx80_rounding_precision;
  113: #endif
  114: } float_status;
  115: 
  116: void set_float_rounding_mode(int val STATUS_PARAM);
  117: #ifdef FLOATX80
  118: void set_floatx80_rounding_precision(int val STATUS_PARAM);
  119: #endif
  120: 
  121: /*----------------------------------------------------------------------------
  122: | Software IEC/IEEE integer-to-floating-point conversion routines.
  123: *----------------------------------------------------------------------------*/
  124: float32 int32_to_float32( int STATUS_PARAM);
  125: float32 uint32_to_float32( unsigned int STATUS_PARAM);
  126: float64 int32_to_float64( int STATUS_PARAM);
  127: float64 uint32_to_float64( unsigned int STATUS_PARAM);
  128: #ifdef FLOATX80
  129: floatx80 int32_to_floatx80( int STATUS_PARAM);
  130: #endif
  131: #ifdef FLOAT128
  132: float128 int32_to_float128( int STATUS_PARAM);
  133: #endif
  134: float32 int64_to_float32( int64_t STATUS_PARAM);
  135: float32 uint64_to_float32( uint64_t STATUS_PARAM);
  136: float64 int64_to_float64( int64_t STATUS_PARAM);
  137: float64 uint64_to_float64( uint64_t v STATUS_PARAM);
  138: #ifdef FLOATX80
  139: floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
  140: #endif
  141: #ifdef FLOAT128
  142: float128 int64_to_float128( int64_t STATUS_PARAM);
  143: #endif
  144: 
  145: /*----------------------------------------------------------------------------
  146: | Software IEC/IEEE single-precision conversion routines.
  147: *----------------------------------------------------------------------------*/
  148: int float32_to_int32( float32  STATUS_PARAM);
  149: int float32_to_int32_round_to_zero( float32  STATUS_PARAM);
  150: unsigned int float32_to_uint32( float32 a STATUS_PARAM);
  151: unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM);
  152: int64_t float32_to_int64( float32  STATUS_PARAM);
  153: int64_t float32_to_int64_round_to_zero( float32  STATUS_PARAM);
  154: float64 float32_to_float64( float32  STATUS_PARAM);
  155: #ifdef FLOATX80
  156: floatx80 float32_to_floatx80( float32  STATUS_PARAM);
  157: #endif
  158: #ifdef FLOAT128
  159: float128 float32_to_float128( float32  STATUS_PARAM);
  160: #endif
  161: 
  162: /*----------------------------------------------------------------------------
  163: | Software IEC/IEEE single-precision operations.
  164: *----------------------------------------------------------------------------*/
  165: float32 float32_round_to_int( float32  STATUS_PARAM);
  166: INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
  167: {
  168:     return a + b;
  169: }
  170: INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
  171: {
  172:     return a - b;
  173: }
  174: INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
  175: {
  176:     return a * b;
  177: }
  178: INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
  179: {
  180:     return a / b;
  181: }
  182: float32 float32_rem( float32, float32  STATUS_PARAM);
  183: float32 float32_sqrt( float32  STATUS_PARAM);
  184: INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
  185: {
  186:     return a == b;
  187: }
  188: INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
  189: {
  190:     return a <= b;
  191: }
  192: INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
  193: {
  194:     return a < b;
  195: }
  196: INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
  197: {
  198:     return a <= b && a >= b;
  199: }
  200: INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
  201: {
  202:     return islessequal(a, b);
  203: }
  204: INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
  205: {
  206:     return isless(a, b);
  207: }
  208: INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
  209: {
  210:     return isunordered(a, b);
  211: 
  212: }
  213: int float32_compare( float32, float32 STATUS_PARAM );
  214: int float32_compare_quiet( float32, float32 STATUS_PARAM );
  215: int float32_is_signaling_nan( float32 );
  216: 
  217: INLINE float32 float32_abs(float32 a)
  218: {
  219:     return fabsf(a);
  220: }
  221: 
  222: INLINE float32 float32_chs(float32 a)
  223: {
  224:     return -a;
  225: }
  226: 
  227: INLINE float32 float32_scalbn(float32 a, int n)
  228: {
  229:     return scalbnf(a, n);
  230: }
  231: 
  232: /*----------------------------------------------------------------------------
  233: | Software IEC/IEEE double-precision conversion routines.
  234: *----------------------------------------------------------------------------*/
  235: int float64_to_int32( float64 STATUS_PARAM );
  236: int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
  237: unsigned int float64_to_uint32( float64 STATUS_PARAM );
  238: unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
  239: int64_t float64_to_int64( float64 STATUS_PARAM );
  240: int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
  241: uint64_t float64_to_uint64( float64 STATUS_PARAM );
  242: uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM );
  243: float32 float64_to_float32( float64 STATUS_PARAM );
  244: #ifdef FLOATX80
  245: floatx80 float64_to_floatx80( float64 STATUS_PARAM );
  246: #endif
  247: #ifdef FLOAT128
  248: float128 float64_to_float128( float64 STATUS_PARAM );
  249: #endif
  250: 
  251: /*----------------------------------------------------------------------------
  252: | Software IEC/IEEE double-precision operations.
  253: *----------------------------------------------------------------------------*/
  254: float64 float64_round_to_int( float64 STATUS_PARAM );
  255: float64 float64_trunc_to_int( float64 STATUS_PARAM );
  256: INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
  257: {
  258:     return a + b;
  259: }
  260: INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
  261: {
  262:     return a - b;
  263: }
  264: INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
  265: {
  266:     return a * b;
  267: }
  268: INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
  269: {
  270:     return a / b;
  271: }
  272: float64 float64_rem( float64, float64 STATUS_PARAM );
  273: float64 float64_sqrt( float64 STATUS_PARAM );
  274: INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
  275: {
  276:     return a == b;
  277: }
  278: INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
  279: {
  280:     return a <= b;
  281: }
  282: INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
  283: {
  284:     return a < b;
  285: }
  286: INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
  287: {
  288:     return a <= b && a >= b;
  289: }
  290: INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
  291: {
  292:     return islessequal(a, b);
  293: }
  294: INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
  295: {
  296:     return isless(a, b);
  297: 
  298: }
  299: INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
  300: {
  301:     return isunordered(a, b);
  302: 
  303: }
  304: int float64_compare( float64, float64 STATUS_PARAM );
  305: int float64_compare_quiet( float64, float64 STATUS_PARAM );
  306: int float64_is_signaling_nan( float64 );
  307: int float64_is_nan( float64 );
  308: 
  309: INLINE float64 float64_abs(float64 a)
  310: {
  311:     return fabs(a);
  312: }
  313: 
  314: INLINE float64 float64_chs(float64 a)
  315: {
  316:     return -a;
  317: }
  318: 
  319: INLINE float64 float64_scalbn(float64 a, int n)
  320: {
  321:     return scalbn(a, n);
  322: }
  323: 
  324: #ifdef FLOATX80
  325: 
  326: /*----------------------------------------------------------------------------
  327: | Software IEC/IEEE extended double-precision conversion routines.
  328: *----------------------------------------------------------------------------*/
  329: int floatx80_to_int32( floatx80 STATUS_PARAM );
  330: int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
  331: int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
  332: int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
  333: float32 floatx80_to_float32( floatx80 STATUS_PARAM );
  334: float64 floatx80_to_float64( floatx80 STATUS_PARAM );
  335: #ifdef FLOAT128
  336: float128 floatx80_to_float128( floatx80 STATUS_PARAM );
  337: #endif
  338: 
  339: /*----------------------------------------------------------------------------
  340: | Software IEC/IEEE extended double-precision operations.
  341: *----------------------------------------------------------------------------*/
  342: floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
  343: INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
  344: {
  345:     return a + b;
  346: }
  347: INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
  348: {
  349:     return a - b;
  350: }
  351: INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
  352: {
  353:     return a * b;
  354: }
  355: INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
  356: {
  357:     return a / b;
  358: }
  359: floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
  360: floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
  361: INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
  362: {
  363:     return a == b;
  364: }
  365: INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
  366: {
  367:     return a <= b;
  368: }
  369: INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
  370: {
  371:     return a < b;
  372: }
  373: INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
  374: {
  375:     return a <= b && a >= b;
  376: }
  377: INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
  378: {
  379:     return islessequal(a, b);
  380: }
  381: INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
  382: {
  383:     return isless(a, b);
  384: 
  385: }
  386: INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
  387: {
  388:     return isunordered(a, b);
  389: 
  390: }
  391: int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
  392: int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
  393: int floatx80_is_signaling_nan( floatx80 );
  394: 
  395: INLINE floatx80 floatx80_abs(floatx80 a)
  396: {
  397:     return fabsl(a);
  398: }
  399: 
  400: INLINE floatx80 floatx80_chs(floatx80 a)
  401: {
  402:     return -a;
  403: }
  404: 
  405: INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
  406: {
  407:     return scalbnl(a, n);
  408: }
  409: 
  410: #endif
Syntax (Markdown)