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

unix.superglobalmegacorp.com

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