Annotation of previous_trunk/src/cpu/fpp-softfloat.h, revision 1.1

1.1     ! root        1: /*
        !             2:   * UAE - The Un*x Amiga Emulator
        !             3:   *
        !             4:   * MC68881 emulation
        !             5:   *
        !             6:   * Conversion routines for hosts knowing floating point format.
        !             7:   *
        !             8:   * Copyright 1996 Herman ten Brugge
        !             9:   * Modified 2005 Peter Keunecke
        !            10:   */
        !            11: 
        !            12: #ifndef FPP_H
        !            13: #define FPP_H
        !            14: 
        !            15: #include <softfloat.h>
        !            16: 
        !            17: float_ctrl fp_ctrl;
        !            18: 
        !            19: #define        FPCR_ROUNDING_MODE      0x00000030
        !            20: #define        FPCR_ROUND_NEAR         0x00000000
        !            21: #define        FPCR_ROUND_ZERO         0x00000010
        !            22: #define        FPCR_ROUND_MINF         0x00000020
        !            23: #define        FPCR_ROUND_PINF         0x00000030
        !            24: 
        !            25: #define        FPCR_ROUNDING_PRECISION 0x000000c0
        !            26: #define        FPCR_PRECISION_SINGLE   0x00000040
        !            27: #define        FPCR_PRECISION_DOUBLE   0x00000080
        !            28: #define FPCR_PRECISION_EXTENDED        0x00000000
        !            29: 
        !            30: extern uae_u32 fpp_get_fpsr (void);
        !            31: 
        !            32: 
        !            33: /* Functions for setting host/library modes and getting status */
        !            34: STATIC_INLINE void init_fp_mode(void)
        !            35: {
        !            36:     float_init(&fp_ctrl);
        !            37: }
        !            38: STATIC_INLINE void set_fp_mode(uae_u32 mode_control)
        !            39: {
        !            40:     set_float_detect_tininess(float_tininess_before_rounding, &fp_ctrl);
        !            41:     
        !            42:     switch(mode_control & FPCR_ROUNDING_PRECISION) {
        !            43:         case FPCR_PRECISION_SINGLE: // single
        !            44:             set_float_rounding_precision(32, &fp_ctrl);
        !            45:             break;
        !            46:         case FPCR_PRECISION_DOUBLE: // double
        !            47:             set_float_rounding_precision(64, &fp_ctrl);
        !            48:             break;
        !            49:         case FPCR_PRECISION_EXTENDED: // extended
        !            50:             set_float_rounding_precision(80, &fp_ctrl);
        !            51:             break;
        !            52:         default: // double
        !            53:             set_float_rounding_precision(64, &fp_ctrl);
        !            54:             break;
        !            55:     }
        !            56: 
        !            57:     switch(mode_control & FPCR_ROUNDING_MODE) {
        !            58:         case FPCR_ROUND_NEAR: // to neareset
        !            59:             set_float_rounding_mode(float_round_nearest_even, &fp_ctrl);
        !            60:             break;
        !            61:         case FPCR_ROUND_ZERO: // to zero
        !            62:             set_float_rounding_mode(float_round_to_zero, &fp_ctrl);
        !            63:             break;
        !            64:         case FPCR_ROUND_MINF: // to minus
        !            65:             set_float_rounding_mode(float_round_down, &fp_ctrl);
        !            66:             break;
        !            67:         case FPCR_ROUND_PINF: // to plus
        !            68:             set_float_rounding_mode(float_round_up, &fp_ctrl);
        !            69:             break;
        !            70:     }
        !            71: }
        !            72: STATIC_INLINE void get_fp_status(uae_u32 *status)
        !            73: {
        !            74:     int8 flags = get_float_exception_flags(&fp_ctrl);
        !            75:     
        !            76:     if (flags & float_flag_signaling)
        !            77:         *status |= 0x4000;
        !            78:     if (flags & float_flag_invalid)
        !            79:         *status |= 0x2000;
        !            80:     if (flags & float_flag_overflow)
        !            81:         *status |= 0x1000;
        !            82:     if (flags & float_flag_underflow)
        !            83:         *status |= 0x0800;
        !            84:     if (flags & float_flag_divbyzero)
        !            85:         *status |= 0x0400;
        !            86:     if (flags & float_flag_inexact)
        !            87:         *status |= 0x0200;
        !            88:     if (flags & float_flag_decimal)
        !            89:         *status |= 0x0100;
        !            90: }
        !            91: STATIC_INLINE void clear_fp_status(void)
        !            92: {
        !            93:     set_float_exception_flags(0, &fp_ctrl);
        !            94: }
        !            95: 
        !            96: /* Helper functions */
        !            97: STATIC_INLINE const char *fp_print(fptype *fx)
        !            98: {
        !            99:     static char fs[32];
        !           100:     bool n, u, d;
        !           101:     fptype x;
        !           102:     int32 len;
        !           103:     int8 save_exception_flags;
        !           104:     
        !           105:     n = floatx80_is_negative(*fx);
        !           106:     u = floatx80_is_unnormal(*fx);
        !           107:     d = floatx80_is_denormal(*fx);
        !           108: 
        !           109:     if (floatx80_is_infinity(*fx)) {
        !           110:         sprintf(fs, "%c%s", n?'-':'+', "inf");
        !           111:     } else if (floatx80_is_signaling_nan(*fx)) {
        !           112:         sprintf(fs, "%c%s", n?'-':'+', "snan");
        !           113:     } else if (floatx80_is_nan(*fx)) {
        !           114:         sprintf(fs, "%c%s", n?'-':'+', "nan");
        !           115:     } else {
        !           116:         len = 17;
        !           117:         save_exception_flags = get_float_exception_flags(&fp_ctrl);
        !           118:         set_float_exception_flags(0, &fp_ctrl);
        !           119:         x = floatx80_to_floatdecimal(*fx, &len, &fp_ctrl);
        !           120:         
        !           121:         sprintf(fs, "%c%01lld.%016llde%c%04d%s%s", n?'-':'+',
        !           122:                 x.low/LIT64(10000000000000000), x.low%LIT64(10000000000000000),
        !           123:                 (x.high&0x4000)?'-':'+', x.high&0x3FFF, d?"D":u?"U":"",
        !           124:                 (get_float_exception_flags(&fp_ctrl)&float_flag_inexact)?"~":"");
        !           125: 
        !           126:         set_float_exception_flags(save_exception_flags, &fp_ctrl);
        !           127:     }
        !           128:     
        !           129:     return fs;
        !           130: }
        !           131: 
        !           132: /* Functions for detecting float type */
        !           133: STATIC_INLINE bool fp_is_snan(fptype *fp)
        !           134: {
        !           135:     return floatx80_is_signaling_nan(*fp) != 0;
        !           136: }
        !           137: STATIC_INLINE void fp_unset_snan(fptype *fp)
        !           138: {
        !           139:     fp->low |= LIT64(0x4000000000000000);
        !           140: }
        !           141: STATIC_INLINE bool fp_is_nan (fptype *fp)
        !           142: {
        !           143:     return floatx80_is_nan(*fp) != 0;
        !           144: }
        !           145: STATIC_INLINE bool fp_is_infinity (fptype *fp)
        !           146: {
        !           147:     return floatx80_is_infinity(*fp) != 0;
        !           148: }
        !           149: STATIC_INLINE bool fp_is_zero(fptype *fp)
        !           150: {
        !           151:     return floatx80_is_zero(*fp) != 0;
        !           152: }
        !           153: STATIC_INLINE bool fp_is_neg(fptype *fp)
        !           154: {
        !           155:     return floatx80_is_negative(*fp) != 0;
        !           156: }
        !           157: STATIC_INLINE bool fp_is_denormal(fptype *fp)
        !           158: {
        !           159:     return floatx80_is_denormal(*fp) != 0;
        !           160: }
        !           161: STATIC_INLINE bool fp_is_unnormal(fptype *fp)
        !           162: {
        !           163:     return floatx80_is_unnormal(*fp) != 0;
        !           164: }
        !           165: 
        !           166: /* Function for normalizing unnormals */
        !           167: STATIC_INLINE void fp_normalize(fptype *fp)
        !           168: {
        !           169:     *fp = floatx80_normalize(*fp);
        !           170: }
        !           171: 
        !           172: /* Functions for converting between float formats */
        !           173: STATIC_INLINE void to_single(fptype *fp, uae_u32 wrd1)
        !           174: {
        !           175:     float32 f = wrd1;
        !           176:     *fp = float32_to_floatx80_allowunnormal(f);
        !           177: }
        !           178: STATIC_INLINE uae_u32 from_single(fptype *fp)
        !           179: {
        !           180:     float32 f = floatx80_to_float32(*fp, &fp_ctrl);
        !           181:     return f;
        !           182: }
        !           183: 
        !           184: STATIC_INLINE void to_double(fptype *fp, uae_u32 wrd1, uae_u32 wrd2)
        !           185: {
        !           186:     float64 f = ((float64)wrd1 << 32) | wrd2;
        !           187:     *fp = float64_to_floatx80_allowunnormal(f);
        !           188: }
        !           189: STATIC_INLINE void from_double(fptype *fp, uae_u32 *wrd1, uae_u32 *wrd2)
        !           190: {
        !           191:     float64 f = floatx80_to_float64(*fp, &fp_ctrl);
        !           192:     *wrd1 = f >> 32;
        !           193:     *wrd2 = (uae_u32)f;
        !           194: }
        !           195: 
        !           196: STATIC_INLINE void to_exten(fptype *fp, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
        !           197: {
        !           198:     fp->high = (uae_u16)(wrd1 >> 16);
        !           199:     fp->low = ((uae_u64)wrd2 << 32) | wrd3;
        !           200: }
        !           201: STATIC_INLINE void from_exten(fptype *fp, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
        !           202: {
        !           203:     floatx80 f = floatx80_to_floatx80(*fp, &fp_ctrl);
        !           204:     *wrd1 = (uae_u32)(f.high << 16);
        !           205:     *wrd2 = f.low >> 32;
        !           206:     *wrd3 = (uae_u32)f.low;
        !           207: }
        !           208: STATIC_INLINE void to_exten_fmovem(fptype *fp, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
        !           209: {
        !           210:     fp->high = (uae_u16)(wrd1 >> 16);
        !           211:     fp->low = ((uae_u64)wrd2 << 32) | wrd3;
        !           212: }
        !           213: STATIC_INLINE void from_exten_fmovem(fptype *fp, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
        !           214: {
        !           215:     *wrd1 = (uae_u32)(fp->high << 16);
        !           216:     *wrd2 = fp->low >> 32;
        !           217:     *wrd3 = (uae_u32)fp->low;
        !           218: }
        !           219: 
        !           220: STATIC_INLINE uae_s64 to_int(fptype *src, int size)
        !           221: {
        !           222:     switch (size) {
        !           223:         case 0: return floatx80_to_int8(*src, &fp_ctrl);
        !           224:         case 1: return floatx80_to_int16(*src, &fp_ctrl);
        !           225:         case 2: return floatx80_to_int32(*src, &fp_ctrl);
        !           226:         default: return 0;
        !           227:     }
        !           228: }
        !           229: STATIC_INLINE fptype from_int(uae_s32 src)
        !           230: {
        !           231:     return int32_to_floatx80(src);
        !           232: }
        !           233: 
        !           234: STATIC_INLINE void to_pack(fptype *fp, uae_u32 *wrd)
        !           235: {
        !           236:     floatx80 f;
        !           237:     int i;
        !           238:     uae_s32 exp;
        !           239:     uae_s64 mant;
        !           240:     uae_u32 pack_exp, pack_int, pack_se, pack_sm;
        !           241:     uae_u64 pack_frac;
        !           242:     
        !           243:     if (((wrd[0] >> 16) & 0x7fff) == 0x7fff) {
        !           244:         // infinity has extended exponent and all 0 packed fraction
        !           245:         // nans are copies bit by bit
        !           246:         to_exten(fp, wrd[0], wrd[1], wrd[2]);
        !           247:         return;
        !           248:     }
        !           249:     if (!(wrd[0] & 0xf) && !wrd[1] && !wrd[2]) {
        !           250:         // exponent is not cared about, if mantissa is zero
        !           251:         wrd[0] &= 0x80000000;
        !           252:         to_exten(fp, wrd[0], wrd[1], wrd[2]);
        !           253:         return;
        !           254:     }
        !           255:     
        !           256:     pack_exp = (wrd[0] >> 16) & 0xFFF;              // packed exponent
        !           257:     pack_int = wrd[0] & 0xF;                        // packed integer part
        !           258:     pack_frac = ((uae_u64)wrd[1] << 32) | wrd[2];   // packed fraction
        !           259:     pack_se = (wrd[0] >> 30) & 1;                   // sign of packed exponent
        !           260:     pack_sm = (wrd[0] >> 31) & 1;                   // sign of packed significand
        !           261:     
        !           262:     exp = 0;
        !           263:     
        !           264:     for (i = 0; i < 3; i++) {
        !           265:         exp *= 10;
        !           266:         exp += (pack_exp >> (8 - i * 4)) & 0xF;
        !           267:     }
        !           268:     
        !           269:     if (pack_se) {
        !           270:         exp = -exp;
        !           271:     }
        !           272:     
        !           273:     exp -= 16;
        !           274:     
        !           275:     if (exp < 0) {
        !           276:         exp = -exp;
        !           277:         pack_se = 1;
        !           278:     }
        !           279:     
        !           280:     mant = pack_int;
        !           281:     
        !           282:     for (i = 0; i < 16; i++) {
        !           283:         mant *= 10;
        !           284:         mant += (pack_frac >> (60 - i * 4)) & 0xF;
        !           285:     }
        !           286: 
        !           287:     f.high = exp & 0x3FFF;
        !           288:     f.high |= pack_se ? 0x4000 : 0;
        !           289:     f.high |= pack_sm ? 0x8000 : 0;
        !           290:     f.low = mant;
        !           291:     
        !           292:     *fp = floatdecimal_to_floatx80(f, &fp_ctrl);
        !           293: }
        !           294: STATIC_INLINE void from_pack(fptype *fp, uae_u32 *wrd, uae_s32 kfactor)
        !           295: {
        !           296:     floatx80 f = floatx80_to_floatdecimal(*fp, &kfactor, &fp_ctrl);
        !           297:     
        !           298:     uae_u32 pack_exp, pack_exp4, pack_int, pack_se, pack_sm;
        !           299:     uae_u64 pack_frac;
        !           300:     
        !           301:     uae_u32 exponent;
        !           302:     uae_u64 significand;
        !           303: 
        !           304:     uae_s32 len;
        !           305:     uae_u64 digit;
        !           306:     
        !           307:     if ((f.high & 0x7FFF) == 0x7FFF) {
        !           308:         wrd[0] = (uae_u32)(f.high << 16);
        !           309:         wrd[1] = f.low >> 32;
        !           310:         wrd[2] = (uae_u32)f.low;
        !           311:     } else {
        !           312:         exponent = f.high & 0x3FFF;
        !           313:         significand = f.low;
        !           314:         
        !           315:         pack_int = 0;
        !           316:         pack_frac = 0;
        !           317:         len = kfactor; // SoftFloat saved len to kfactor variable
        !           318:         while (len > 0) {
        !           319:             len--;
        !           320:             digit = significand % 10;
        !           321:             significand /= 10;
        !           322:             if (len == 0) {
        !           323:                 pack_int = digit;
        !           324:             } else {
        !           325:                 pack_frac |= digit << (64 - len * 4);
        !           326:             }
        !           327:         }
        !           328:         
        !           329:         pack_exp = 0;
        !           330:         pack_exp4 = 0;
        !           331:         len = 4;
        !           332:         while (len > 0) {
        !           333:             len--;
        !           334:             digit = exponent % 10;
        !           335:             exponent /= 10;
        !           336:             if (len == 0) {
        !           337:                 pack_exp4 = digit;
        !           338:             } else {
        !           339:                 pack_exp |= digit << (12 - len * 4);
        !           340:             }
        !           341:         }
        !           342:         
        !           343:         pack_se = f.high & 0x4000;
        !           344:         pack_sm = f.high & 0x8000;
        !           345:         
        !           346:         wrd[0] = pack_exp << 16;
        !           347:         wrd[0] |= pack_exp4 << 12;
        !           348:         wrd[0] |= pack_int;
        !           349:         wrd[0] |= pack_se ? 0x40000000 : 0;
        !           350:         wrd[0] |= pack_sm ? 0x80000000 : 0;
        !           351:         
        !           352:         wrd[1] = pack_frac >> 32;
        !           353:         wrd[2] = pack_frac & 0xffffffff;
        !           354:     }
        !           355: }
        !           356: 
        !           357: /* Functions for returning exception state data */
        !           358: STATIC_INLINE fptype fp_get_internal_overflow(void)
        !           359: {
        !           360:     return getFloatInternalOverflow(&fp_ctrl);
        !           361: }
        !           362: STATIC_INLINE fptype fp_get_internal_underflow(void)
        !           363: {
        !           364:     return getFloatInternalUnderflow(&fp_ctrl);
        !           365: }
        !           366: STATIC_INLINE fptype fp_get_internal_round_all(void)
        !           367: {
        !           368:     return getFloatInternalRoundedAll(&fp_ctrl);
        !           369: }
        !           370: STATIC_INLINE fptype fp_get_internal_round(void)
        !           371: {
        !           372:     return getFloatInternalRoundedSome(&fp_ctrl);
        !           373: }
        !           374: STATIC_INLINE fptype fp_get_internal_round_exten(void)
        !           375: {
        !           376:     return getFloatInternalFloatx80(&fp_ctrl);
        !           377: }
        !           378: STATIC_INLINE fptype fp_get_internal(void)
        !           379: {
        !           380:     return getFloatInternalUnrounded(&fp_ctrl);
        !           381: }
        !           382: STATIC_INLINE uae_u32 fp_get_internal_grs(void)
        !           383: {
        !           384:     return (uae_u32)getFloatInternalGRS(&fp_ctrl);
        !           385: }
        !           386: 
        !           387: /* Function for denormalizing */
        !           388: STATIC_INLINE void fp_denormalize(fptype *fp, int esign)
        !           389: {
        !           390:     *fp = floatx80_denormalize(*fp, esign);
        !           391: }
        !           392: 
        !           393: /* Functions for rounding */
        !           394: 
        !           395: // round to float with extended precision exponent
        !           396: STATIC_INLINE void fp_round32(fptype *fp)
        !           397: {
        !           398:     *fp = floatx80_round32(*fp, &fp_ctrl);
        !           399: }
        !           400: 
        !           401: // round to double with extended precision exponent
        !           402: STATIC_INLINE void fp_round64(fptype *fp)
        !           403: {
        !           404:     *fp = floatx80_round64(*fp, &fp_ctrl);
        !           405: }
        !           406: 
        !           407: // round to float
        !           408: STATIC_INLINE void fp_round_single(fptype *fp)
        !           409: {
        !           410:     *fp = floatx80_round_to_float32(*fp, &fp_ctrl);
        !           411: }
        !           412: 
        !           413: // round to double
        !           414: STATIC_INLINE void fp_round_double(fptype *fp)
        !           415: {
        !           416:     *fp = floatx80_round_to_float64(*fp, &fp_ctrl);
        !           417: }
        !           418: 
        !           419: // round to selected precision
        !           420: STATIC_INLINE void fp_round(fptype *a)
        !           421: {
        !           422:     switch(get_float_rounding_precision(&fp_ctrl)) {
        !           423:         case 32:
        !           424:             *a = floatx80_round_to_float32(*a, &fp_ctrl);
        !           425:             break;
        !           426:         case 64:
        !           427:             *a = floatx80_round_to_float64(*a, &fp_ctrl);
        !           428:             break;
        !           429:         default:
        !           430:             break;
        !           431:     }
        !           432: }
        !           433: 
        !           434: /* Arithmetic functions */
        !           435: STATIC_INLINE void fp_move(fptype *a, fptype *b)
        !           436: {
        !           437:     *a = floatx80_move(*b, &fp_ctrl);
        !           438: }
        !           439: STATIC_INLINE void fp_int(fptype *a, fptype *b)
        !           440: {
        !           441:     *a = floatx80_round_to_int(*b, &fp_ctrl);
        !           442: }
        !           443: STATIC_INLINE void fp_intrz(fptype *a, fptype *b)
        !           444: {
        !           445:     *a = floatx80_round_to_int_toward_zero(*b, &fp_ctrl);
        !           446: }
        !           447: STATIC_INLINE void fp_sqrt(fptype *a, fptype *b)
        !           448: {
        !           449:     *a = floatx80_sqrt(*b, &fp_ctrl);
        !           450: }
        !           451: STATIC_INLINE void fp_abs(fptype *a, fptype *b)
        !           452: {
        !           453:     *a = floatx80_abs(*b, &fp_ctrl);
        !           454: }
        !           455: STATIC_INLINE void fp_neg(fptype *a, fptype *b)
        !           456: {
        !           457:     *a = floatx80_neg(*b, &fp_ctrl);
        !           458: }
        !           459: STATIC_INLINE void fp_getexp(fptype *a, fptype *b)
        !           460: {
        !           461:     *a = floatx80_getexp(*b, &fp_ctrl);
        !           462: }
        !           463: STATIC_INLINE void fp_getman(fptype *a, fptype *b)
        !           464: {
        !           465:     *a = floatx80_getman(*b, &fp_ctrl);
        !           466: }
        !           467: STATIC_INLINE void fp_div(fptype *a, fptype *b)
        !           468: {
        !           469:     *a = floatx80_div(*a, *b, &fp_ctrl);
        !           470: }
        !           471: STATIC_INLINE void fp_mod(fptype *a, fptype *b, uae_u64 *q, uae_s8 *s)
        !           472: {
        !           473:     *a = floatx80_mod(*a, *b, q, s, &fp_ctrl);
        !           474: }
        !           475: STATIC_INLINE void fp_add(fptype *a, fptype *b)
        !           476: {
        !           477:     *a = floatx80_add(*a, *b, &fp_ctrl);
        !           478: }
        !           479: STATIC_INLINE void fp_mul(fptype *a, fptype *b)
        !           480: {
        !           481:     *a = floatx80_mul(*a, *b, &fp_ctrl);
        !           482: }
        !           483: STATIC_INLINE void fp_sgldiv(fptype *a, fptype *b)
        !           484: {
        !           485:     *a = floatx80_sgldiv(*a, *b, &fp_ctrl);
        !           486: }
        !           487: STATIC_INLINE void fp_rem(fptype *a, fptype *b, uae_u64 *q, uae_s8 *s)
        !           488: {
        !           489:     *a = floatx80_rem(*a, *b, q, s, &fp_ctrl);
        !           490: }
        !           491: STATIC_INLINE void fp_scale(fptype *a, fptype *b)
        !           492: {
        !           493:     *a = floatx80_scale(*a, *b, &fp_ctrl);
        !           494: }
        !           495: STATIC_INLINE void fp_sglmul(fptype *a, fptype *b)
        !           496: {
        !           497:     *a = floatx80_sglmul(*a, *b, &fp_ctrl);
        !           498: }
        !           499: STATIC_INLINE void fp_sub(fptype *a, fptype *b)
        !           500: {
        !           501:     *a = floatx80_sub(*a, *b, &fp_ctrl);
        !           502: }
        !           503: STATIC_INLINE void fp_cmp(fptype *a, fptype *b)
        !           504: {
        !           505:     *a = floatx80_cmp(*a, *b, &fp_ctrl);
        !           506: }
        !           507: STATIC_INLINE void fp_tst(fptype *a, fptype *b)
        !           508: {
        !           509:     *a = floatx80_tst(*b, &fp_ctrl);
        !           510: }
        !           511: 
        !           512: STATIC_INLINE void fp_sinh(fptype *a, fptype *b)
        !           513: {
        !           514:     *a = floatx80_sinh(*b, &fp_ctrl);
        !           515: }
        !           516: STATIC_INLINE void fp_lognp1(fptype *a, fptype *b)
        !           517: {
        !           518:     *a = floatx80_lognp1(*b, &fp_ctrl);
        !           519: }
        !           520: STATIC_INLINE void fp_etoxm1(fptype *a, fptype *b)
        !           521: {
        !           522:     *a = floatx80_etoxm1(*b, &fp_ctrl);
        !           523: }
        !           524: STATIC_INLINE void fp_tanh(fptype *a, fptype *b)
        !           525: {
        !           526:     *a = floatx80_tanh(*b, &fp_ctrl);
        !           527: }
        !           528: STATIC_INLINE void fp_atan(fptype *a, fptype *b)
        !           529: {
        !           530:     *a = floatx80_atan(*b, &fp_ctrl);
        !           531: }
        !           532: STATIC_INLINE void fp_asin(fptype *a, fptype *b)
        !           533: {
        !           534:     *a = floatx80_asin(*b, &fp_ctrl);
        !           535: }
        !           536: STATIC_INLINE void fp_atanh(fptype *a, fptype *b)
        !           537: {
        !           538:     *a = floatx80_atanh(*b, &fp_ctrl);
        !           539: }
        !           540: STATIC_INLINE void fp_sin(fptype *a, fptype *b)
        !           541: {
        !           542:     *a = floatx80_sin(*b, &fp_ctrl);
        !           543: }
        !           544: STATIC_INLINE void fp_tan(fptype *a, fptype *b)
        !           545: {
        !           546:     *a = floatx80_tan(*b, &fp_ctrl);
        !           547: }
        !           548: STATIC_INLINE void fp_etox(fptype *a, fptype *b)
        !           549: {
        !           550:     *a = floatx80_etox(*b, &fp_ctrl);
        !           551: }
        !           552: STATIC_INLINE void fp_twotox(fptype *a, fptype *b)
        !           553: {
        !           554:     *a = floatx80_twotox(*b, &fp_ctrl);
        !           555: }
        !           556: STATIC_INLINE void fp_tentox(fptype *a, fptype *b)
        !           557: {
        !           558:     *a = floatx80_tentox(*b, &fp_ctrl);
        !           559: }
        !           560: STATIC_INLINE void fp_logn(fptype *a, fptype *b)
        !           561: {
        !           562:     *a = floatx80_logn(*b, &fp_ctrl);
        !           563: }
        !           564: STATIC_INLINE void fp_log10(fptype *a, fptype *b)
        !           565: {
        !           566:     *a = floatx80_log10(*b, &fp_ctrl);
        !           567: }
        !           568: STATIC_INLINE void fp_log2(fptype *a, fptype *b)
        !           569: {
        !           570:     *a = floatx80_log2(*b, &fp_ctrl);
        !           571: }
        !           572: STATIC_INLINE void fp_cosh(fptype *a, fptype *b)
        !           573: {
        !           574:     *a = floatx80_cosh(*b, &fp_ctrl);
        !           575: }
        !           576: STATIC_INLINE void fp_acos(fptype *a, fptype *b)
        !           577: {
        !           578:     *a = floatx80_acos(*b, &fp_ctrl);
        !           579: }
        !           580: STATIC_INLINE void fp_cos(fptype *a, fptype *b)
        !           581: {
        !           582:     *a = floatx80_cos(*b, &fp_ctrl);
        !           583: }
        !           584: 
        !           585: /* Functions with fixed precision */
        !           586: STATIC_INLINE void fp_move_single(fptype *a, fptype *b)
        !           587: {
        !           588:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           589:     set_float_rounding_precision(32, &fp_ctrl);
        !           590:     *a = floatx80_move(*b, &fp_ctrl);
        !           591:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           592: }
        !           593: STATIC_INLINE void fp_abs_single(fptype *a, fptype *b)
        !           594: {
        !           595:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           596:     set_float_rounding_precision(32, &fp_ctrl);
        !           597:     *a = floatx80_abs(*b, &fp_ctrl);
        !           598:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           599: }
        !           600: STATIC_INLINE void fp_neg_single(fptype *a, fptype *b)
        !           601: {
        !           602:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           603:     set_float_rounding_precision(32, &fp_ctrl);
        !           604:     *a = floatx80_neg(*b, &fp_ctrl);
        !           605:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           606: }
        !           607: STATIC_INLINE void fp_add_single(fptype *a, fptype *b)
        !           608: {
        !           609:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           610:     set_float_rounding_precision(32, &fp_ctrl);
        !           611:     *a = floatx80_add(*a, *b, &fp_ctrl);
        !           612:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           613: }
        !           614: STATIC_INLINE void fp_sub_single(fptype *a, fptype *b)
        !           615: {
        !           616:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           617:     set_float_rounding_precision(32, &fp_ctrl);
        !           618:     *a = floatx80_sub(*a, *b, &fp_ctrl);
        !           619:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           620: }
        !           621: STATIC_INLINE void fp_mul_single(fptype *a, fptype *b)
        !           622: {
        !           623:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           624:     set_float_rounding_precision(32, &fp_ctrl);
        !           625:     *a = floatx80_mul(*a, *b, &fp_ctrl);
        !           626:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           627: }
        !           628: STATIC_INLINE void fp_div_single(fptype *a, fptype *b)
        !           629: {
        !           630:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           631:     set_float_rounding_precision(32, &fp_ctrl);
        !           632:     *a = floatx80_div(*a, *b, &fp_ctrl);
        !           633:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           634: }
        !           635: STATIC_INLINE void fp_sqrt_single(fptype *a, fptype *b)
        !           636: {
        !           637:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           638:     set_float_rounding_precision(32, &fp_ctrl);
        !           639:     *a = floatx80_sqrt(*b, &fp_ctrl);
        !           640:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           641: }
        !           642: STATIC_INLINE void fp_move_double(fptype *a, fptype *b)
        !           643: {
        !           644:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           645:     set_float_rounding_precision(64, &fp_ctrl);
        !           646:     *a = floatx80_move(*b, &fp_ctrl);
        !           647:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           648: }
        !           649: STATIC_INLINE void fp_abs_double(fptype *a, fptype *b)
        !           650: {
        !           651:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           652:     set_float_rounding_precision(64, &fp_ctrl);
        !           653:     *a = floatx80_abs(*b, &fp_ctrl);
        !           654:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           655: }
        !           656: STATIC_INLINE void fp_neg_double(fptype *a, fptype *b)
        !           657: {
        !           658:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           659:     set_float_rounding_precision(64, &fp_ctrl);
        !           660:     *a = floatx80_neg(*b, &fp_ctrl);
        !           661:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           662: }
        !           663: STATIC_INLINE void fp_add_double(fptype *a, fptype *b)
        !           664: {
        !           665:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           666:     set_float_rounding_precision(64, &fp_ctrl);
        !           667:     *a = floatx80_add(*a, *b, &fp_ctrl);
        !           668:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           669: }
        !           670: STATIC_INLINE void fp_sub_double(fptype *a, fptype *b)
        !           671: {
        !           672:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           673:     set_float_rounding_precision(64, &fp_ctrl);
        !           674:     *a = floatx80_sub(*a, *b, &fp_ctrl);
        !           675:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           676: }
        !           677: STATIC_INLINE void fp_mul_double(fptype *a, fptype *b)
        !           678: {
        !           679:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           680:     set_float_rounding_precision(64, &fp_ctrl);
        !           681:     *a = floatx80_mul(*a, *b, &fp_ctrl);
        !           682:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           683: }
        !           684: STATIC_INLINE void fp_div_double(fptype *a, fptype *b)
        !           685: {
        !           686:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           687:     set_float_rounding_precision(64, &fp_ctrl);
        !           688:     *a = floatx80_div(*a, *b, &fp_ctrl);
        !           689:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           690: }
        !           691: STATIC_INLINE void fp_sqrt_double(fptype *a, fptype *b)
        !           692: {
        !           693:     int8 oldprec = get_float_rounding_precision(&fp_ctrl);
        !           694:     set_float_rounding_precision(64, &fp_ctrl);
        !           695:     *a = floatx80_sqrt(*b, &fp_ctrl);
        !           696:     set_float_rounding_precision(oldprec, &fp_ctrl);
        !           697: }
        !           698: 
        !           699: 
        !           700: 
        !           701: #if 0 /* Old fallback functions disabled */
        !           702: static const long double twoto32 = 4294967296.0;
        !           703: 
        !           704: STATIC_INLINE void to_native(long double *fp, fptype fpx)
        !           705: {
        !           706:     int expon;
        !           707:     long double frac;
        !           708:     
        !           709:     expon = fpx.high & 0x7fff;
        !           710:     
        !           711:     if (floatx80_is_zero(fpx)) {
        !           712:         *fp = floatx80_is_negative(fpx) ? -0.0 : +0.0;
        !           713:         return;
        !           714:     }
        !           715:     if (floatx80_is_nan(fpx)) {
        !           716:         *fp = sqrtl(-1);
        !           717:         return;
        !           718:     }
        !           719:     if (floatx80_is_infinity(fpx)) {
        !           720:         *fp = floatx80_is_negative(fpx) ? logl(0.0) : (1.0/0.0);
        !           721:         return;
        !           722:     }
        !           723:     
        !           724:     frac = (long double)fpx.low / (long double)(twoto32 * 2147483648.0);
        !           725:     if (floatx80_is_negative(fpx))
        !           726:         frac = -frac;
        !           727:     *fp = ldexpl (frac, expon - 16383);
        !           728: }
        !           729: STATIC_INLINE void from_native(long double fp, fptype *fpx)
        !           730: {
        !           731:     int expon;
        !           732:     long double frac;
        !           733:     
        !           734:     if (signbit(fp))
        !           735:         fpx->high = 0x8000;
        !           736:     else
        !           737:         fpx->high = 0x0000;
        !           738:     
        !           739:     if (isnan(fp)) {
        !           740:         fpx->high |= 0x7fff;
        !           741:         fpx->low = LIT64(0xffffffffffffffff);
        !           742:         return;
        !           743:     }
        !           744:     if (isinf(fp)) {
        !           745:         fpx->high |= 0x7fff;
        !           746:         fpx->low = LIT64(0x0000000000000000);
        !           747:         return;
        !           748:     }
        !           749:     if (fp == 0.0) {
        !           750:         fpx->low = LIT64(0x0000000000000000);
        !           751:         return;
        !           752:     }
        !           753:     if (fp < 0.0)
        !           754:         fp = -fp;
        !           755:     
        !           756:     frac = frexpl (fp, &expon);
        !           757:     frac += 0.5 / (twoto32 * twoto32);
        !           758:     if (frac >= 1.0) {
        !           759:         frac /= 2.0;
        !           760:         expon++;
        !           761:     }
        !           762:     fpx->high |= (expon + 16383 - 1) & 0x7fff;
        !           763:     fpx->low = (bits64)(frac * (long double)(twoto32 * twoto32));
        !           764:     
        !           765:     while (!(fpx->low & LIT64( 0x8000000000000000))) {
        !           766:         if (fpx->high == 0) {
        !           767:             break;
        !           768:         }
        !           769:         fpx->low <<= 1;
        !           770:         fpx->high--;
        !           771:     }
        !           772: }
        !           773: 
        !           774: STATIC_INLINE void fp_sinhf(fptype *a, fptype *b)
        !           775: {
        !           776:     flag e = 0;
        !           777:     floatx80_sinh_check(*a, &e);
        !           778:     if (e) return;
        !           779:     long double fp;
        !           780:     to_native(&fp, *b);
        !           781:     fp = sinhl(fp);
        !           782:     from_native(fp, a);
        !           783:     fp_round(a);
        !           784: }
        !           785: STATIC_INLINE void fp_lognp1f(fptype *a, fptype *b)
        !           786: {
        !           787:     flag e = 0;
        !           788:     floatx80_lognp1_check(*a, &e);
        !           789:     if (e) return;
        !           790:     long double fp;
        !           791:     to_native(&fp, *b);
        !           792:     fp = log1pl(fp);
        !           793:     from_native(fp, a);
        !           794:     fp_round(a);
        !           795: }
        !           796: STATIC_INLINE void fp_etoxm1f(fptype *a, fptype *b)
        !           797: {
        !           798:     flag e = 0;
        !           799:     floatx80_etoxm1_check(*a, &e);
        !           800:     if (e) return;
        !           801:     long double fp;
        !           802:     to_native(&fp, *b);
        !           803:     fp = expm1l(fp);
        !           804:     from_native(fp, a);
        !           805:     fp_round(a);
        !           806: }
        !           807: STATIC_INLINE void fp_tanhf(fptype *a, fptype *b)
        !           808: {
        !           809:     flag e = 0;
        !           810:     floatx80_tanh_check(*a, &e);
        !           811:     if (e) return;
        !           812:     long double fp;
        !           813:     to_native(&fp, *b);
        !           814:     fp = tanhl(fp);
        !           815:     from_native(fp, a);
        !           816:     fp_round(a);
        !           817: }
        !           818: STATIC_INLINE void fp_atanf(fptype *a, fptype *b)
        !           819: {
        !           820:     flag e = 0;
        !           821:     floatx80_atan_check(*a, &e);
        !           822:     if (e) return;
        !           823:     long double fp;
        !           824:     to_native(&fp, *b);
        !           825:     fp = atanl(fp);
        !           826:     from_native(fp, a);
        !           827:     fp_round(a);
        !           828: }
        !           829: STATIC_INLINE void fp_asinf(fptype *a, fptype *b)
        !           830: {
        !           831:     flag e = 0;
        !           832:     floatx80_asin_check(*a, &e);
        !           833:     if (e) return;
        !           834:     long double fp;
        !           835:     to_native(&fp, *b);
        !           836:     fp = asinl(fp);
        !           837:     from_native(fp, a);
        !           838:     fp_round(a);
        !           839: }
        !           840: STATIC_INLINE void fp_atanhf(fptype *a, fptype *b)
        !           841: {
        !           842:     flag e = 0;
        !           843:     floatx80_atanh_check(*a, &e);
        !           844:     if (e) return;
        !           845:     long double fp;
        !           846:     to_native(&fp, *b);
        !           847:     fp = atanhl(fp);
        !           848:     from_native(fp, a);
        !           849:     fp_round(a);
        !           850: }
        !           851: STATIC_INLINE void fp_sinf(fptype *a, fptype *b)
        !           852: {
        !           853:     flag e = 0;
        !           854:     floatx80_sin_check(*a, &e);
        !           855:     if (e) return;
        !           856:     long double fp;
        !           857:     to_native(&fp, *b);
        !           858:     fp = sinl(fp);
        !           859:     from_native(fp, a);
        !           860:     fp_round(a);
        !           861: }
        !           862: STATIC_INLINE void fp_tanf(fptype *a, fptype *b)
        !           863: {
        !           864:     flag e = 0;
        !           865:     floatx80_tan_check(*a, &e);
        !           866:     if (e) return;
        !           867:     long double fp;
        !           868:     to_native(&fp, *b);
        !           869:     fp = tanl(fp);
        !           870:     from_native(fp, a);
        !           871:     fp_round(a);
        !           872: }
        !           873: STATIC_INLINE void fp_etoxf(fptype *a, fptype *b)
        !           874: {
        !           875:     flag e = 0;
        !           876:     floatx80_etox_check(*a, &e);
        !           877:     if (e) return;
        !           878:     long double fp;
        !           879:     to_native(&fp, *b);
        !           880:     fp = expl(fp);
        !           881:     from_native(fp, a);
        !           882:     fp_round(a);
        !           883: }
        !           884: STATIC_INLINE void fp_twotoxf(fptype *a, fptype *b)
        !           885: {
        !           886:     flag e = 0;
        !           887:     floatx80_twotox_check(*a, &e);
        !           888:     if (e) return;
        !           889:     long double fp;
        !           890:     to_native(&fp, *b);
        !           891:     fp = powl(2.0, fp);
        !           892:     from_native(fp, a);
        !           893:     fp_round(a);
        !           894: }
        !           895: STATIC_INLINE void fp_tentoxf(fptype *a, fptype *b)
        !           896: {
        !           897:     flag e = 0;
        !           898:     floatx80_tentox_check(*a, &e);
        !           899:     if (e) return;
        !           900:     long double fp;
        !           901:     to_native(&fp, *b);
        !           902:     fp = powl(10.0, fp);
        !           903:     from_native(fp, a);
        !           904:     fp_round(a);
        !           905: }
        !           906: STATIC_INLINE void fp_lognf(fptype *a, fptype *b)
        !           907: {
        !           908:     flag e = 0;
        !           909:     floatx80_logn_check(*a, &e);
        !           910:     if (e) return;
        !           911:     long double fp;
        !           912:     to_native(&fp, *b);
        !           913:     fp = logl(fp);
        !           914:     from_native(fp, a);
        !           915:     fp_round(a);
        !           916: }
        !           917: STATIC_INLINE void fp_log10f(fptype *a, fptype *b)
        !           918: {
        !           919:     flag e = 0;
        !           920:     floatx80_log10_check(*a, &e);
        !           921:     if (e) return;
        !           922:     long double fp;
        !           923:     to_native(&fp, *b);
        !           924:     fp = log10l(fp);
        !           925:     from_native(fp, a);
        !           926:     fp_round(a);
        !           927: }
        !           928: STATIC_INLINE void fp_log2f(fptype *a, fptype *b)
        !           929: {
        !           930:     flag e = 0;
        !           931:     floatx80_log2_check(*a, &e);
        !           932:     if (e) return;
        !           933:     long double fp;
        !           934:     to_native(&fp, *b);
        !           935:     fp = log2l(fp);
        !           936:     from_native(fp, a);
        !           937:     fp_round(a);
        !           938: }
        !           939: STATIC_INLINE void fp_coshf(fptype *a, fptype *b)
        !           940: {
        !           941:     flag e = 0;
        !           942:     floatx80_cosh_check(*a, &e);
        !           943:     if (e) return;
        !           944:     long double fp;
        !           945:     to_native(&fp, *b);
        !           946:     fp = coshl(fp);
        !           947:     from_native(fp, a);
        !           948:     fp_round(a);
        !           949: }
        !           950: STATIC_INLINE void fp_acosf(fptype *a, fptype *b)
        !           951: {
        !           952:     flag e = 0;
        !           953:     floatx80_acos_check(*a, &e);
        !           954:     if (e) return;
        !           955:     long double fp;
        !           956:     to_native(&fp, *b);
        !           957:     fp = acosl(fp);
        !           958:     from_native(fp, a);
        !           959:     fp_round(a);
        !           960: }
        !           961: STATIC_INLINE void fp_cosf(fptype *a, fptype *b)
        !           962: {
        !           963:     flag e = 0;
        !           964:     floatx80_cos_check(*a, &e);
        !           965:     if (e) return;
        !           966:     long double fp;
        !           967:     to_native(&fp, *b);
        !           968:     fp = cosl(fp);
        !           969:     from_native(fp, a);
        !           970:     fp_round(a);
        !           971: }
        !           972: #endif
        !           973: 
        !           974: #endif

unix.superglobalmegacorp.com

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