Annotation of hatari/src/cpu/softfloat/softfloat_fpsp.c, revision 1.1

1.1     ! root        1: 
        !             2: /*============================================================================
        !             3: 
        !             4:  This C source file is an extension to the SoftFloat IEC/IEEE Floating-point
        !             5:  Arithmetic Package, Release 2a.
        !             6: 
        !             7:  Written by Andreas Grabher for Previous, NeXT Computer Emulator.
        !             8:  
        !             9: =============================================================================*/
        !            10: 
        !            11: #include <stdint.h>
        !            12: #include <stdlib.h>
        !            13: 
        !            14: #include "softfloat.h"
        !            15: #include "softfloat-specialize.h"
        !            16: #include "softfloat_fpsp_tables.h"
        !            17: 
        !            18: 
        !            19: /*----------------------------------------------------------------------------
        !            20: | Algorithms for transcendental functions supported by MC68881 and MC68882 
        !            21: | mathematical coprocessors. The functions are derived from FPSP library.
        !            22: *----------------------------------------------------------------------------*/
        !            23: 
        !            24: #define pi_sig      LIT64(0xc90fdaa22168c235)
        !            25: #define pi_sig0     LIT64(0xc90fdaa22168c234)
        !            26: #define pi_sig1     LIT64(0xc4c6628b80dc1cd1)
        !            27: 
        !            28: #define pi_exp      0x4000
        !            29: #define piby2_exp   0x3FFF
        !            30: #define piby4_exp   0x3FFE
        !            31: 
        !            32: #define one_exp     0x3FFF
        !            33: #define one_sig     LIT64(0x8000000000000000)
        !            34: 
        !            35: #define SET_PREC \
        !            36:        int8_t user_rnd_mode, user_rnd_prec; \
        !            37:        user_rnd_mode = status->float_rounding_mode; \
        !            38:        user_rnd_prec = status->floatx80_rounding_precision; \
        !            39:        status->float_rounding_mode = float_round_nearest_even; \
        !            40:        status->floatx80_rounding_precision = 80
        !            41: 
        !            42: #define RESET_PREC \
        !            43:        status->float_rounding_mode = user_rnd_mode; \
        !            44:        status->floatx80_rounding_precision = user_rnd_prec
        !            45: 
        !            46: /*----------------------------------------------------------------------------
        !            47:  | Function for compactifying extended double-precision floating point values.
        !            48:  *----------------------------------------------------------------------------*/
        !            49: 
        !            50: static int32_t floatx80_make_compact(int32_t aExp, uint64_t aSig)
        !            51: {
        !            52:        return (aExp<<16)|(aSig>>48);
        !            53: }
        !            54: 
        !            55: 
        !            56: /*----------------------------------------------------------------------------
        !            57:  | Arc cosine
        !            58:  *----------------------------------------------------------------------------*/
        !            59: 
        !            60: floatx80 floatx80_acos(floatx80 a, float_status *status)
        !            61: {
        !            62:        flag aSign;
        !            63:        int32_t aExp;
        !            64:        uint64_t aSig;
        !            65:        
        !            66:        
        !            67:        int32_t compact;
        !            68:        floatx80 fp0, fp1, one;
        !            69:        
        !            70:        aSig = extractFloatx80Frac(a);
        !            71:        aExp = extractFloatx80Exp(a);
        !            72:        aSign = extractFloatx80Sign(a);
        !            73:        
        !            74:        if (aExp == 0x7FFF && (uint64_t) (aSig<<1)) {
        !            75:                return propagateFloatx80NaNOneArg(a, status);
        !            76:        }
        !            77:        if (aExp == 0 && aSig == 0) {
        !            78:                float_raise(float_flag_inexact, status);
        !            79:                return roundAndPackFloatx80(status->floatx80_rounding_precision, 0, piby2_exp, pi_sig, 0, status);
        !            80:        }
        !            81: 
        !            82:        compact = floatx80_make_compact(aExp, aSig);
        !            83:        
        !            84:        if (compact >= 0x3FFF8000) { // |X| >= 1
        !            85:                if (aExp == one_exp && aSig == one_sig) { // |X| == 1
        !            86:                        if (aSign) { // X == -1
        !            87:                                a = packFloatx80(0, pi_exp, pi_sig);
        !            88:                                float_raise(float_flag_inexact, status);
        !            89:                                return floatx80_move(a, status);
        !            90:                        } else { // X == +1
        !            91:                                return packFloatx80(0, 0, 0);
        !            92:                        }
        !            93:                } else { // |X| > 1
        !            94:                        float_raise(float_flag_invalid, status);
        !            95:                        a.low = floatx80_default_nan_low;
        !            96:                        a.high = floatx80_default_nan_high;
        !            97:                        return a;
        !            98:                }
        !            99:        } // |X| < 1
        !           100:        
        !           101:        SET_PREC;
        !           102:        
        !           103:        one = packFloatx80(0, one_exp, one_sig);
        !           104:        fp0 = a;
        !           105:        
        !           106:        fp1 = floatx80_add(one, fp0, status);   // 1 + X
        !           107:        fp0 = floatx80_sub(one, fp0, status);   // 1 - X
        !           108:        fp0 = floatx80_div(fp0, fp1, status);   // (1-X)/(1+X)
        !           109:        fp0 = floatx80_sqrt(fp0, status);       // SQRT((1-X)/(1+X))
        !           110:        fp0 = floatx80_atan(fp0, status);       // ATAN(SQRT((1-X)/(1+X)))
        !           111:        
        !           112:        RESET_PREC;
        !           113:        
        !           114:        a = floatx80_add(fp0, fp0, status);     // 2 * ATAN(SQRT((1-X)/(1+X)))
        !           115:        
        !           116:        float_raise(float_flag_inexact, status);
        !           117:        
        !           118:        return a;
        !           119: }
        !           120: 
        !           121: /*----------------------------------------------------------------------------
        !           122:  | Arc sine
        !           123:  *----------------------------------------------------------------------------*/
        !           124: 
        !           125: floatx80 floatx80_asin(floatx80 a, float_status *status)
        !           126: {
        !           127:        flag aSign;
        !           128:        int32_t aExp;
        !           129:        uint64_t aSig;
        !           130:        
        !           131:        int32_t compact;
        !           132:        floatx80 fp0, fp1, fp2, one;
        !           133:        
        !           134:        aSig = extractFloatx80Frac(a);
        !           135:        aExp = extractFloatx80Exp(a);
        !           136:        aSign = extractFloatx80Sign(a);
        !           137:        
        !           138:        if (aExp == 0x7FFF && (uint64_t) (aSig<<1)) {
        !           139:                return propagateFloatx80NaNOneArg(a, status);
        !           140:        }
        !           141:        
        !           142:        if (aExp == 0 && aSig == 0) {
        !           143:                return packFloatx80(aSign, 0, 0);
        !           144:        }
        !           145: 
        !           146:        compact = floatx80_make_compact(aExp, aSig);
        !           147:        
        !           148:        if (compact >= 0x3FFF8000) { // |X| >= 1
        !           149:                if (aExp == one_exp && aSig == one_sig) { // |X| == 1
        !           150:                        float_raise(float_flag_inexact, status);
        !           151:                        a = packFloatx80(aSign, piby2_exp, pi_sig);
        !           152:                        return floatx80_move(a, status);
        !           153:                } else { // |X| > 1
        !           154:                        float_raise(float_flag_invalid, status);
        !           155:                        a.low = floatx80_default_nan_low;
        !           156:                        a.high = floatx80_default_nan_high;
        !           157:                        return a;
        !           158:                }
        !           159: 
        !           160:        } // |X| < 1
        !           161:        
        !           162:        SET_PREC;
        !           163:        
        !           164:        one = packFloatx80(0, one_exp, one_sig);
        !           165:        fp0 = a;
        !           166: 
        !           167:        fp1 = floatx80_sub(one, fp0, status);   // 1 - X
        !           168:        fp2 = floatx80_add(one, fp0, status);   // 1 + X
        !           169:        fp1 = floatx80_mul(fp2, fp1, status);   // (1+X)*(1-X)
        !           170:        fp1 = floatx80_sqrt(fp1, status);       // SQRT((1+X)*(1-X))
        !           171:        fp0 = floatx80_div(fp0, fp1, status);   // X/SQRT((1+X)*(1-X))
        !           172: 
        !           173:        RESET_PREC;
        !           174: 
        !           175:        a = floatx80_atan(fp0, status);         // ATAN(X/SQRT((1+X)*(1-X)))
        !           176:        
        !           177:        float_raise(float_flag_inexact, status);
        !           178: 
        !           179:        return a;
        !           180: }
        !           181: 
        !           182: /*----------------------------------------------------------------------------
        !           183:  | Arc tangent
        !           184:  *----------------------------------------------------------------------------*/
        !           185: 
        !           186: floatx80 floatx80_atan(floatx80 a, float_status *status)
        !           187: {
        !           188:        flag aSign;
        !           189:        int32_t aExp;
        !           190:        uint64_t aSig;
        !           191:        
        !           192:        int32_t compact, tbl_index;
        !           193:        floatx80 fp0, fp1, fp2, fp3, xsave;
        !           194: 
        !           195:        aSig = extractFloatx80Frac(a);
        !           196:        aExp = extractFloatx80Exp(a);
        !           197:        aSign = extractFloatx80Sign(a);
        !           198:        
        !           199:        if (aExp == 0x7FFF) {
        !           200:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !           201:                a = packFloatx80(aSign, piby2_exp, pi_sig);
        !           202:                float_raise(float_flag_inexact, status);
        !           203:                return floatx80_move(a, status);
        !           204:        }
        !           205:        
        !           206:        if (aExp == 0 && aSig == 0) {
        !           207:                return packFloatx80(aSign, 0, 0);
        !           208:        }
        !           209:        
        !           210:        compact = floatx80_make_compact(aExp, aSig);
        !           211:        
        !           212:        SET_PREC;
        !           213: 
        !           214:        if (compact < 0x3FFB8000 || compact > 0x4002FFFF) { // |X| >= 16 or |X| < 1/16
        !           215:                if (compact > 0x3FFF8000) { // |X| >= 16
        !           216:                        if (compact > 0x40638000) { // |X| > 2^(100)
        !           217:                                fp0 = packFloatx80(aSign, piby2_exp, pi_sig);
        !           218:                                fp1 = packFloatx80(aSign, 0x0001, one_sig);
        !           219:                                
        !           220:                                RESET_PREC;
        !           221:                                
        !           222:                                a = floatx80_sub(fp0, fp1, status);
        !           223:                                
        !           224:                                float_raise(float_flag_inexact, status);
        !           225:                                
        !           226:                                return a;
        !           227:                        } else {
        !           228:                                fp0 = a;
        !           229:                                fp1 = packFloatx80(1, one_exp, one_sig); // -1
        !           230:                                fp1 = floatx80_div(fp1, fp0, status); // X' = -1/X
        !           231:                                xsave = fp1;
        !           232:                                fp0 = floatx80_mul(fp1, fp1, status); // Y = X'*X'
        !           233:                                fp1 = floatx80_mul(fp0, fp0, status); // Z = Y*Y
        !           234:                                fp3 = float64_to_floatx80(LIT64(0xBFB70BF398539E6A), status); // C5
        !           235:                                fp2 = float64_to_floatx80(LIT64(0x3FBC7187962D1D7D), status); // C4
        !           236:                                fp3 = floatx80_mul(fp3, fp1, status); // Z*C5
        !           237:                                fp2 = floatx80_mul(fp2, fp1, status); // Z*C4
        !           238:                                fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBFC24924827107B8), status), status); // C3+Z*C5
        !           239:                                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FC999999996263E), status), status); // C2+Z*C4
        !           240:                                fp1 = floatx80_mul(fp1, fp3, status); // Z*(C3+Z*C5)
        !           241:                                fp2 = floatx80_mul(fp2, fp0, status); // Y*(C2+Z*C4)
        !           242:                                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0xBFD5555555555536), status), status); // C1+Z*(C3+Z*C5)
        !           243:                                fp0 = floatx80_mul(fp0, xsave, status); // X'*Y
        !           244:                                fp1 = floatx80_add(fp1, fp2, status); // [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
        !           245:                                fp0 = floatx80_mul(fp0, fp1, status); // X'*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]) ??
        !           246:                                fp0 = floatx80_add(fp0, xsave, status);
        !           247:                                fp1 = packFloatx80(aSign, piby2_exp, pi_sig);
        !           248:                                
        !           249:                                RESET_PREC;
        !           250: 
        !           251:                                a = floatx80_add(fp0, fp1, status);
        !           252:                                
        !           253:                                float_raise(float_flag_inexact, status);
        !           254:                                
        !           255:                                return a;
        !           256:                        }
        !           257:                } else { // |X| < 1/16
        !           258:                        if (compact < 0x3FD78000) { // |X| < 2^(-40)
        !           259:                                RESET_PREC;
        !           260:                                
        !           261:                                a = floatx80_move(a, status);
        !           262:                                
        !           263:                                float_raise(float_flag_inexact, status);
        !           264:                                
        !           265:                                return a;
        !           266:                        } else {
        !           267:                                fp0 = a;
        !           268:                                xsave = a;
        !           269:                                fp0 = floatx80_mul(fp0, fp0, status); // Y = X*X
        !           270:                                fp1 = floatx80_mul(fp0, fp0, status); // Z = Y*Y
        !           271:                                fp2 = float64_to_floatx80(LIT64(0x3FB344447F876989), status); // B6
        !           272:                                fp3 = float64_to_floatx80(LIT64(0xBFB744EE7FAF45DB), status); // B5
        !           273:                                fp2 = floatx80_mul(fp2, fp1, status); // Z*B6
        !           274:                                fp3 = floatx80_mul(fp3, fp1, status); // Z*B5
        !           275:                                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FBC71C646940220), status), status); // B4+Z*B6
        !           276:                                fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBFC24924921872F9), status), status); // B3+Z*B5
        !           277:                                fp2 = floatx80_mul(fp2, fp1, status); // Z*(B4+Z*B6)
        !           278:                                fp1 = floatx80_mul(fp1, fp3, status); // Z*(B3+Z*B5)
        !           279:                                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FC9999999998FA9), status), status); // B2+Z*(B4+Z*B6)
        !           280:                                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0xBFD5555555555555), status), status); // B1+Z*(B3+Z*B5)
        !           281:                                fp2 = floatx80_mul(fp2, fp0, status); // Y*(B2+Z*(B4+Z*B6))
        !           282:                                fp0 = floatx80_mul(fp0, xsave, status); // X*Y
        !           283:                                fp1 = floatx80_add(fp1, fp2, status); // [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
        !           284:                                fp0 = floatx80_mul(fp0, fp1, status); // X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
        !           285:                                
        !           286:                                RESET_PREC;
        !           287:                                
        !           288:                                a = floatx80_add(fp0, xsave, status);
        !           289:                                
        !           290:                                float_raise(float_flag_inexact, status);
        !           291:                                
        !           292:                                return a;
        !           293:                        }
        !           294:                }
        !           295:        } else {
        !           296:                aSig &= LIT64(0xF800000000000000);
        !           297:                aSig |= LIT64(0x0400000000000000);
        !           298:                xsave = packFloatx80(aSign, aExp, aSig); // F
        !           299:                fp0 = a;
        !           300:                fp1 = a; // X
        !           301:                fp2 = packFloatx80(0, one_exp, one_sig); // 1
        !           302:                fp1 = floatx80_mul(fp1, xsave, status); // X*F
        !           303:                fp0 = floatx80_sub(fp0, xsave, status); // X-F
        !           304:                fp1 = floatx80_add(fp1, fp2, status); // 1 + X*F
        !           305:                fp0 = floatx80_div(fp0, fp1, status); // U = (X-F)/(1+X*F)
        !           306:                
        !           307:                tbl_index = compact;
        !           308:                
        !           309:                tbl_index &= 0x7FFF0000;
        !           310:                tbl_index -= 0x3FFB0000;
        !           311:                tbl_index >>= 1;
        !           312:                tbl_index += compact&0x00007800;
        !           313:                tbl_index >>= 11;
        !           314:                
        !           315:                fp3 = atan_tbl[tbl_index];
        !           316:                
        !           317:                fp3.high |= aSign ? 0x8000 : 0; // ATAN(F)
        !           318:                
        !           319:                fp1 = floatx80_mul(fp0, fp0, status); // V = U*U
        !           320:                fp2 = float64_to_floatx80(LIT64(0xBFF6687E314987D8), status); // A3
        !           321:                fp2 = floatx80_add(fp2, fp1, status); // A3+V
        !           322:                fp2 = floatx80_mul(fp2, fp1, status); // V*(A3+V)
        !           323:                fp1 = floatx80_mul(fp1, fp0, status); // U*V
        !           324:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x4002AC6934A26DB3), status), status); // A2+V*(A3+V)
        !           325:                fp1 = floatx80_mul(fp1, float64_to_floatx80(LIT64(0xBFC2476F4E1DA28E), status), status); // A1+U*V
        !           326:                fp1 = floatx80_mul(fp1, fp2, status); // A1*U*V*(A2+V*(A3+V))
        !           327:                fp0 = floatx80_add(fp0, fp1, status); // ATAN(U)
        !           328:                
        !           329:                RESET_PREC;
        !           330:                
        !           331:                a = floatx80_add(fp0, fp3, status); // ATAN(X)
        !           332:                
        !           333:                float_raise(float_flag_inexact, status);
        !           334:                
        !           335:                return a;
        !           336:        }
        !           337: }
        !           338: 
        !           339: /*----------------------------------------------------------------------------
        !           340:  | Hyperbolic arc tangent
        !           341:  *----------------------------------------------------------------------------*/
        !           342: 
        !           343: floatx80 floatx80_atanh(floatx80 a, float_status *status)
        !           344: {
        !           345:        flag aSign;
        !           346:        int32_t aExp;
        !           347:        uint64_t aSig;
        !           348:        
        !           349:        int32_t compact;
        !           350:        floatx80 fp0, fp1, fp2, one;
        !           351: 
        !           352:        aSig = extractFloatx80Frac(a);
        !           353:        aExp = extractFloatx80Exp(a);
        !           354:        aSign = extractFloatx80Sign(a);
        !           355:        
        !           356:        if (aExp == 0x7FFF && (uint64_t) (aSig<<1)) {
        !           357:                return propagateFloatx80NaNOneArg(a, status);
        !           358:        }
        !           359:        
        !           360:        if (aExp == 0 && aSig == 0) {
        !           361:                return packFloatx80(aSign, 0, 0);
        !           362:        }
        !           363:        
        !           364:        compact = floatx80_make_compact(aExp, aSig);
        !           365:        
        !           366:        if (compact >= 0x3FFF8000) { // |X| >= 1
        !           367:                if (aExp == one_exp && aSig == one_sig) { // |X| == 1
        !           368:                        float_raise(float_flag_divbyzero, status);
        !           369:                        return packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low);
        !           370:                } else { // |X| > 1
        !           371:                        float_raise(float_flag_invalid, status);
        !           372:                        a.low = floatx80_default_nan_low;
        !           373:                        a.high = floatx80_default_nan_high;
        !           374:                        return a;
        !           375:                }
        !           376:        } // |X| < 1
        !           377:        
        !           378:        SET_PREC;
        !           379:        
        !           380:        one = packFloatx80(0, one_exp, one_sig);
        !           381:        fp2 = packFloatx80(aSign, 0x3FFE, one_sig); // SIGN(X) * (1/2)
        !           382:        fp0 = packFloatx80(0, aExp, aSig); // Y = |X|
        !           383:        fp1 = packFloatx80(1, aExp, aSig); // -Y
        !           384:        fp0 = floatx80_add(fp0, fp0, status); // 2Y
        !           385:        fp1 = floatx80_add(fp1, one, status); // 1-Y
        !           386:        fp0 = floatx80_div(fp0, fp1, status); // Z = 2Y/(1-Y)
        !           387:        fp0 = floatx80_lognp1(fp0, status); // LOG1P(Z)
        !           388:        
        !           389:        RESET_PREC;
        !           390:        
        !           391:        a = floatx80_mul(fp0, fp2, status); // ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z)
        !           392:        
        !           393:        float_raise(float_flag_inexact, status);
        !           394:        
        !           395:        return a;
        !           396: }
        !           397: 
        !           398: /*----------------------------------------------------------------------------
        !           399:  | Cosine
        !           400:  *----------------------------------------------------------------------------*/
        !           401: 
        !           402: floatx80 floatx80_cos(floatx80 a, float_status *status)
        !           403: {
        !           404:        flag aSign, xSign;
        !           405:        int32_t aExp, xExp;
        !           406:        uint64_t aSig, xSig;
        !           407:        
        !           408:        int32_t compact, l, n, j;
        !           409:        floatx80 fp0, fp1, fp2, fp3, fp4, fp5, x, invtwopi, twopi1, twopi2;
        !           410:        float32 posneg1, twoto63;
        !           411:        flag adjn, endflag;
        !           412:        
        !           413:        aSig = extractFloatx80Frac(a);
        !           414:        aExp = extractFloatx80Exp(a);
        !           415:        aSign = extractFloatx80Sign(a);
        !           416:        
        !           417:        if (aExp == 0x7FFF) {
        !           418:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !           419:                float_raise(float_flag_invalid, status);
        !           420:                a.low = floatx80_default_nan_low;
        !           421:                a.high = floatx80_default_nan_high;
        !           422:                return a;
        !           423:        }
        !           424:        
        !           425:        if (aExp == 0 && aSig == 0) {
        !           426:                return packFloatx80(0, one_exp, one_sig);
        !           427:        }
        !           428:        
        !           429:        adjn = 1;
        !           430:        
        !           431:        SET_PREC;
        !           432:        
        !           433:        compact = floatx80_make_compact(aExp, aSig);
        !           434:        
        !           435:        fp0 = a;
        !           436:        
        !           437:        if (compact < 0x3FD78000 || compact > 0x4004BC7E) { // 2^(-40) > |X| > 15 PI
        !           438:                if (compact > 0x3FFF8000) { // |X| >= 15 PI
        !           439:                        // REDUCEX
        !           440:                        fp1 = packFloatx80(0, 0, 0);
        !           441:                        if (compact == 0x7FFEFFFF) {
        !           442:                                twopi1 = packFloatx80(aSign ^ 1, 0x7FFE, LIT64(0xC90FDAA200000000));
        !           443:                                twopi2 = packFloatx80(aSign ^ 1, 0x7FDC, LIT64(0x85A308D300000000));
        !           444:                                fp0 = floatx80_add(fp0, twopi1, status);
        !           445:                                fp1 = fp0;
        !           446:                                fp0 = floatx80_add(fp0, twopi2, status);
        !           447:                                fp1 = floatx80_sub(fp1, fp0, status);
        !           448:                                fp1 = floatx80_add(fp1, twopi2, status);
        !           449:                        }
        !           450:                loop:
        !           451:                        xSign = extractFloatx80Sign(fp0);
        !           452:                        xExp = extractFloatx80Exp(fp0);
        !           453:                        xExp -= 0x3FFF;
        !           454:                        if (xExp <= 28) {
        !           455:                                l = 0;
        !           456:                                endflag = 1;
        !           457:                        } else {
        !           458:                                l = xExp - 27;
        !           459:                                endflag = 0;
        !           460:                        }
        !           461:                        invtwopi = packFloatx80(0, 0x3FFE - l, LIT64(0xA2F9836E4E44152A)); // INVTWOPI
        !           462:                        twopi1 = packFloatx80(0, 0x3FFF + l, LIT64(0xC90FDAA200000000));
        !           463:                        twopi2 = packFloatx80(0, 0x3FDD + l, LIT64(0x85A308D300000000));
        !           464:                        
        !           465:                        twoto63 = 0x5F000000;
        !           466:                        twoto63 |= xSign ? 0x80000000 : 0x00000000; // SIGN(INARG)*2^63 IN SGL
        !           467:                        
        !           468:                        fp2 = floatx80_mul(fp0, invtwopi, status);
        !           469:                        fp2 = floatx80_add(fp2, float32_to_floatx80(twoto63, status), status); // THE FRACTIONAL PART OF FP2 IS ROUNDED
        !           470:                        fp2 = floatx80_sub(fp2, float32_to_floatx80(twoto63, status), status); // FP2 is N
        !           471:                        fp4 = floatx80_mul(twopi1, fp2, status); // W = N*P1
        !           472:                        fp5 = floatx80_mul(twopi2, fp2, status); // w = N*P2
        !           473:                        fp3 = floatx80_add(fp4, fp5, status); // FP3 is P
        !           474:                        fp4 = floatx80_sub(fp4, fp3, status); // W-P
        !           475:                        fp0 = floatx80_sub(fp0, fp3, status); // FP0 is A := R - P
        !           476:                        fp4 = floatx80_add(fp4, fp5, status); // FP4 is p = (W-P)+w
        !           477:                        fp3 = fp0; // FP3 is A
        !           478:                        fp1 = floatx80_sub(fp1, fp4, status); // FP1 is a := r - p
        !           479:                        fp0 = floatx80_add(fp0, fp1, status); // FP0 is R := A+a
        !           480:                        
        !           481:                        if (endflag > 0) {
        !           482:                                n = floatx80_to_int32(fp2, status);
        !           483:                                goto sincont;
        !           484:                        }
        !           485:                        fp3 = floatx80_sub(fp3, fp0, status); // A-R
        !           486:                        fp1 = floatx80_add(fp1, fp3, status); // FP1 is r := (A-R)+a
        !           487:                        goto loop;
        !           488:                } else {
        !           489:                        // SINSM
        !           490:                        fp0 = float32_to_floatx80(0x3F800000, status); // 1
        !           491:                        
        !           492:                        RESET_PREC;
        !           493:                        
        !           494:                        if (adjn) {
        !           495:                                // COSTINY
        !           496:                                a = floatx80_sub(fp0, float32_to_floatx80(0x00800000, status), status);
        !           497:                        } else {
        !           498:                                // SINTINY
        !           499:                                a = floatx80_move(a, status);
        !           500:                        }
        !           501:                        float_raise(float_flag_inexact, status);
        !           502:                        
        !           503:                        return a;
        !           504:                }
        !           505:        } else {
        !           506:                fp1 = floatx80_mul(fp0, float64_to_floatx80(LIT64(0x3FE45F306DC9C883), status), status); // X*2/PI
        !           507:                
        !           508:                n = floatx80_to_int32(fp1, status);
        !           509:                j = 32 + n;
        !           510:                
        !           511:                fp0 = floatx80_sub(fp0, pi_tbl[j], status); // X-Y1
        !           512:                fp0 = floatx80_sub(fp0, float32_to_floatx80(pi_tbl2[j], status), status); // FP0 IS R = (X-Y1)-Y2
        !           513:                
        !           514:        sincont:
        !           515:                if ((n + adjn) & 1) {
        !           516:                        // COSPOLY
        !           517:                        fp0 = floatx80_mul(fp0, fp0, status); // FP0 IS S
        !           518:                        fp1 = floatx80_mul(fp0, fp0, status); // FP1 IS T
        !           519:                        fp2 = float64_to_floatx80(LIT64(0x3D2AC4D0D6011EE3), status); // B8
        !           520:                        fp3 = float64_to_floatx80(LIT64(0xBDA9396F9F45AC19), status); // B7
        !           521:                        
        !           522:                        xSign = extractFloatx80Sign(fp0); // X IS S
        !           523:                        xExp = extractFloatx80Exp(fp0);
        !           524:                        xSig = extractFloatx80Frac(fp0);
        !           525:                        
        !           526:                        if (((n + adjn) >> 1) & 1) {
        !           527:                                xSign ^= 1;
        !           528:                                posneg1 = 0xBF800000; // -1
        !           529:                        } else {
        !           530:                                xSign ^= 0;
        !           531:                                posneg1 = 0x3F800000; // 1
        !           532:                        } // X IS NOW R'= SGN*R
        !           533:                        
        !           534:                        fp2 = floatx80_mul(fp2, fp1, status); // TB8
        !           535:                        fp3 = floatx80_mul(fp3, fp1, status); // TB7
        !           536:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3E21EED90612C972), status), status); // B6+TB8
        !           537:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBE927E4FB79D9FCF), status), status); // B5+TB7
        !           538:                        fp2 = floatx80_mul(fp2, fp1, status); // T(B6+TB8)
        !           539:                        fp3 = floatx80_mul(fp3, fp1, status); // T(B5+TB7)
        !           540:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3EFA01A01A01D423), status), status); // B4+T(B6+TB8)
        !           541:                        fp4 = packFloatx80(1, 0x3FF5, LIT64(0xB60B60B60B61D438));
        !           542:                        fp3 = floatx80_add(fp3, fp4, status); // B3+T(B5+TB7)
        !           543:                        fp2 = floatx80_mul(fp2, fp1, status); // T(B4+T(B6+TB8))
        !           544:                        fp1 = floatx80_mul(fp1, fp3, status); // T(B3+T(B5+TB7))
        !           545:                        fp4 = packFloatx80(0, 0x3FFA, LIT64(0xAAAAAAAAAAAAAB5E));
        !           546:                        fp2 = floatx80_add(fp2, fp4, status); // B2+T(B4+T(B6+TB8))
        !           547:                        fp1 = floatx80_add(fp1, float32_to_floatx80(0xBF000000, status), status); // B1+T(B3+T(B5+TB7))
        !           548:                        fp0 = floatx80_mul(fp0, fp2, status); // S(B2+T(B4+T(B6+TB8)))
        !           549:                        fp0 = floatx80_add(fp0, fp1, status); // [B1+T(B3+T(B5+TB7))]+[S(B2+T(B4+T(B6+TB8)))]
        !           550:                        
        !           551:                        x = packFloatx80(xSign, xExp, xSig);
        !           552:                        fp0 = floatx80_mul(fp0, x, status);
        !           553:                        
        !           554:                        RESET_PREC;
        !           555:                        
        !           556:                        a = floatx80_add(fp0, float32_to_floatx80(posneg1, status), status);
        !           557:                        
        !           558:                        float_raise(float_flag_inexact, status);
        !           559:                        
        !           560:                        return a;
        !           561:                } else {
        !           562:                        // SINPOLY
        !           563:                        xSign = extractFloatx80Sign(fp0); // X IS R
        !           564:                        xExp = extractFloatx80Exp(fp0);
        !           565:                        xSig = extractFloatx80Frac(fp0);
        !           566:                        
        !           567:                        xSign ^= ((n + adjn) >> 1) & 1; // X IS NOW R'= SGN*R
        !           568:                        
        !           569:                        fp0 = floatx80_mul(fp0, fp0, status); // FP0 IS S
        !           570:                        fp1 = floatx80_mul(fp0, fp0, status); // FP1 IS T
        !           571:                        fp3 = float64_to_floatx80(LIT64(0xBD6AAA77CCC994F5), status); // A7
        !           572:                        fp2 = float64_to_floatx80(LIT64(0x3DE612097AAE8DA1), status); // A6
        !           573:                        fp3 = floatx80_mul(fp3, fp1, status); // T*A7
        !           574:                        fp2 = floatx80_mul(fp2, fp1, status); // T*A6
        !           575:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBE5AE6452A118AE4), status), status); // A5+T*A7
        !           576:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3EC71DE3A5341531), status), status); // A4+T*A6
        !           577:                        fp3 = floatx80_mul(fp3, fp1, status); // T(A5+TA7)
        !           578:                        fp2 = floatx80_mul(fp2, fp1, status); // T(A4+TA6)
        !           579:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBF2A01A01A018B59), status), status); // A3+T(A5+TA7)
        !           580:                        fp4 = packFloatx80(0, 0x3FF8, LIT64(0x88888888888859AF));
        !           581:                        fp2 = floatx80_add(fp2, fp4, status); // A2+T(A4+TA6)
        !           582:                        fp1 = floatx80_mul(fp1, fp3, status); // T(A3+T(A5+TA7))
        !           583:                        fp2 = floatx80_mul(fp2, fp0, status); // S(A2+T(A4+TA6))
        !           584:                        fp4 = packFloatx80(1, 0x3FFC, LIT64(0xAAAAAAAAAAAAAA99));
        !           585:                        fp1 = floatx80_add(fp1, fp4, status); // A1+T(A3+T(A5+TA7))
        !           586:                        fp1 = floatx80_add(fp1, fp2, status); // [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
        !           587:                        
        !           588:                        x = packFloatx80(xSign, xExp, xSig);
        !           589:                        fp0 = floatx80_mul(fp0, x, status); // R'*S
        !           590:                        fp0 = floatx80_mul(fp0, fp1, status); // SIN(R')-R'
        !           591:                        
        !           592:                        RESET_PREC;
        !           593:                        
        !           594:                        a = floatx80_add(fp0, x, status);
        !           595:                        
        !           596:                        float_raise(float_flag_inexact, status);
        !           597:                        
        !           598:                        return a;
        !           599:                }
        !           600:        }
        !           601: }
        !           602: 
        !           603: /*----------------------------------------------------------------------------
        !           604:  | Hyperbolic cosine
        !           605:  *----------------------------------------------------------------------------*/
        !           606: 
        !           607: floatx80 floatx80_cosh(floatx80 a, float_status *status)
        !           608: {
        !           609:        flag aSign;
        !           610:        int32_t aExp;
        !           611:        uint64_t aSig;
        !           612:        
        !           613:        int32_t compact;
        !           614:        floatx80 fp0, fp1;
        !           615:        
        !           616:        aSig = extractFloatx80Frac(a);
        !           617:        aExp = extractFloatx80Exp(a);
        !           618:        aSign = extractFloatx80Sign(a);
        !           619:        
        !           620:        if (aExp == 0x7FFF) {
        !           621:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !           622:                return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !           623:        }
        !           624:        
        !           625:        if (aExp == 0 && aSig == 0) {
        !           626:                return packFloatx80(0, one_exp, one_sig);
        !           627:        }
        !           628:        
        !           629:        SET_PREC;
        !           630:        
        !           631:        compact = floatx80_make_compact(aExp, aSig);
        !           632:        
        !           633:        if (compact > 0x400CB167) {
        !           634:                if (compact > 0x400CB2B3) {
        !           635:                        RESET_PREC;
        !           636:                        return roundAndPackFloatx80(status->floatx80_rounding_precision, 0, 0x8000, one_sig, 0, status);
        !           637:                } else {
        !           638:                        fp0 = packFloatx80(0, aExp, aSig);
        !           639:                        fp0 = floatx80_sub(fp0, float64_to_floatx80(LIT64(0x40C62D38D3D64634), status), status);
        !           640:                        fp0 = floatx80_sub(fp0, float64_to_floatx80(LIT64(0x3D6F90AEB1E75CC7), status), status);
        !           641:                        fp0 = floatx80_etox(fp0, status);
        !           642:                        fp1 = packFloatx80(0, 0x7FFB, one_sig);
        !           643:                        
        !           644:                        RESET_PREC;
        !           645: 
        !           646:                        a = floatx80_mul(fp0, fp1, status);
        !           647:                        
        !           648:                        float_raise(float_flag_inexact, status);
        !           649:                        
        !           650:                        return a;
        !           651:                }
        !           652:        }
        !           653:        
        !           654:        fp0 = packFloatx80(0, aExp, aSig); // |X|
        !           655:        fp0 = floatx80_etox(fp0, status); // EXP(|X|)
        !           656:        fp0 = floatx80_mul(fp0, float32_to_floatx80(0x3F000000, status), status); // (1/2)*EXP(|X|)
        !           657:        fp1 = float32_to_floatx80(0x3E800000, status); // 1/4
        !           658:        fp1 = floatx80_div(fp1, fp0, status); // 1/(2*EXP(|X|))
        !           659:        
        !           660:        RESET_PREC;
        !           661:        
        !           662:        a = floatx80_add(fp0, fp1, status);
        !           663:        
        !           664:        float_raise(float_flag_inexact, status);
        !           665:        
        !           666:        return a;
        !           667: }
        !           668: 
        !           669: /*----------------------------------------------------------------------------
        !           670:  | e to x
        !           671:  *----------------------------------------------------------------------------*/
        !           672: 
        !           673: floatx80 floatx80_etox(floatx80 a, float_status *status)
        !           674: {
        !           675:        flag aSign;
        !           676:        int32_t aExp;
        !           677:        uint64_t aSig;
        !           678:        
        !           679:        int32_t compact, n, j, k, m, m1;
        !           680:        floatx80 fp0, fp1, fp2, fp3, l2, scale, adjscale;
        !           681:        flag adjflag;
        !           682: 
        !           683:        aSig = extractFloatx80Frac(a);
        !           684:        aExp = extractFloatx80Exp(a);
        !           685:        aSign = extractFloatx80Sign(a);
        !           686:        
        !           687:        if (aExp == 0x7FFF) {
        !           688:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !           689:                if (aSign) return packFloatx80(0, 0, 0);
        !           690:                return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !           691:        }
        !           692:        
        !           693:        if (aExp == 0 && aSig == 0) {
        !           694:                return packFloatx80(0, one_exp, one_sig);
        !           695:        }
        !           696:        
        !           697:        SET_PREC;
        !           698:        
        !           699:        adjflag = 0;
        !           700:        
        !           701:        if (aExp >= 0x3FBE) { // |X| >= 2^(-65)
        !           702:                compact = floatx80_make_compact(aExp, aSig);
        !           703:                
        !           704:                if (compact < 0x400CB167) { // |X| < 16380 log2
        !           705:                        fp0 = a;
        !           706:                        fp1 = a;
        !           707:                        fp0 = floatx80_mul(fp0, float32_to_floatx80(0x42B8AA3B, status), status); // 64/log2 * X
        !           708:                        adjflag = 0;
        !           709:                        n = floatx80_to_int32(fp0, status); // int(64/log2*X)
        !           710:                        fp0 = int32_to_floatx80(n);
        !           711:                        
        !           712:                        j = n & 0x3F; // J = N mod 64
        !           713:                        m = n / 64; // NOTE: this is really arithmetic right shift by 6
        !           714:                        if (n < 0 && j) { // arithmetic right shift is division and round towards minus infinity
        !           715:                                m--;
        !           716:                        }
        !           717:                        m += 0x3FFF; // biased exponent of 2^(M)
        !           718:                        
        !           719:                expcont1:
        !           720:                        fp2 = fp0; // N
        !           721:                        fp0 = floatx80_mul(fp0, float32_to_floatx80(0xBC317218, status), status); // N * L1, L1 = lead(-log2/64)
        !           722:                        l2 = packFloatx80(0, 0x3FDC, LIT64(0x82E308654361C4C6));
        !           723:                        fp2 = floatx80_mul(fp2, l2, status); // N * L2, L1+L2 = -log2/64
        !           724:                        fp0 = floatx80_add(fp0, fp1, status); // X + N*L1
        !           725:                        fp0 = floatx80_add(fp0, fp2, status); // R
        !           726:                        
        !           727:                        fp1 = floatx80_mul(fp0, fp0, status); // S = R*R
        !           728:                        fp2 = float32_to_floatx80(0x3AB60B70, status); // A5
        !           729:                        fp2 = floatx80_mul(fp2, fp1, status); // fp2 is S*A5
        !           730:                        fp3 = floatx80_mul(float32_to_floatx80(0x3C088895, status), fp1, status); // fp3 is S*A4
        !           731:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FA5555555554431), status), status); // fp2 is A3+S*A5
        !           732:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0x3FC5555555554018), status), status); // fp3 is A2+S*A4
        !           733:                        fp2 = floatx80_mul(fp2, fp1, status); // fp2 is S*(A3+S*A5)
        !           734:                        fp3 = floatx80_mul(fp3, fp1, status); // fp3 is S*(A2+S*A4)
        !           735:                        fp2 = floatx80_add(fp2, float32_to_floatx80(0x3F000000, status), status); // fp2 is A1+S*(A3+S*A5)
        !           736:                        fp3 = floatx80_mul(fp3, fp0, status); // fp3 IS R*S*(A2+S*A4)
        !           737:                        fp2 = floatx80_mul(fp2, fp1, status); // fp2 IS S*(A1+S*(A3+S*A5))
        !           738:                        fp0 = floatx80_add(fp0, fp3, status); // fp0 IS R+R*S*(A2+S*A4)
        !           739:                        fp0 = floatx80_add(fp0, fp2, status); // fp0 IS EXP(R) - 1
        !           740:                        
        !           741:                        fp1 = exp_tbl[j];
        !           742:                        fp0 = floatx80_mul(fp0, fp1, status); // 2^(J/64)*(Exp(R)-1)
        !           743:                        fp0 = floatx80_add(fp0, float32_to_floatx80(exp_tbl2[j], status), status); // accurate 2^(J/64)
        !           744:                        fp0 = floatx80_add(fp0, fp1, status); // 2^(J/64) + 2^(J/64)*(Exp(R)-1)
        !           745:                        
        !           746:                        scale = packFloatx80(0, m, one_sig);
        !           747:                        if (adjflag) {
        !           748:                                adjscale = packFloatx80(0, m1, one_sig);
        !           749:                                fp0 = floatx80_mul(fp0, adjscale, status);
        !           750:                        }
        !           751:                        
        !           752:                        RESET_PREC;
        !           753:                        
        !           754:                        a = floatx80_mul(fp0, scale, status);
        !           755:                        
        !           756:                        float_raise(float_flag_inexact, status);
        !           757:                        
        !           758:                        return a;
        !           759:                } else { // |X| >= 16380 log2
        !           760:                        if (compact > 0x400CB27C) { // |X| >= 16480 log2
        !           761:                                RESET_PREC;
        !           762:                                if (aSign) {
        !           763:                                        a = roundAndPackFloatx80(status->floatx80_rounding_precision, 0, -0x1000, aSig, 0, status);
        !           764:                                } else {
        !           765:                                        a = roundAndPackFloatx80(status->floatx80_rounding_precision, 0, 0x8000, aSig, 0, status);
        !           766:                                }
        !           767:                                float_raise(float_flag_inexact, status);
        !           768:                                
        !           769:                                return a;
        !           770:                        } else {
        !           771:                                fp0 = a;
        !           772:                                fp1 = a;
        !           773:                                fp0 = floatx80_mul(fp0, float32_to_floatx80(0x42B8AA3B, status), status); // 64/log2 * X
        !           774:                                adjflag = 1;
        !           775:                                n = floatx80_to_int32(fp0, status); // int(64/log2*X)
        !           776:                                fp0 = int32_to_floatx80(n);
        !           777:                                
        !           778:                                j = n & 0x3F; // J = N mod 64
        !           779:                                k = n / 64; // NOTE: this is really arithmetic right shift by 6
        !           780:                                if (n < 0 && j) { // arithmetic right shift is division and round towards minus infinity
        !           781:                                        k--;
        !           782:                                }
        !           783:                                m1 = k / 2; // NOTE: this is really arithmetic right shift by 1
        !           784:                                if (k < 0 && (k & 1)) { // arithmetic right shift is division and round towards minus infinity
        !           785:                                        m1--;
        !           786:                                }
        !           787:                                m = k - m1;
        !           788:                                m1 += 0x3FFF; // biased exponent of 2^(M1)
        !           789:                                m += 0x3FFF; // biased exponent of 2^(M)
        !           790:                                
        !           791:                                goto expcont1;
        !           792:                        }
        !           793:                }
        !           794:        } else { // |X| < 2^(-65)
        !           795:                RESET_PREC;
        !           796:                
        !           797:                a = floatx80_add(a, float32_to_floatx80(0x3F800000, status), status); // 1 + X
        !           798:                
        !           799:                float_raise(float_flag_inexact, status);
        !           800:                
        !           801:                return a;
        !           802:        }
        !           803: }
        !           804: 
        !           805: /*----------------------------------------------------------------------------
        !           806:  | e to x minus 1
        !           807:  *----------------------------------------------------------------------------*/
        !           808: 
        !           809: floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
        !           810: {
        !           811:        flag aSign;
        !           812:        int32_t aExp;
        !           813:        uint64_t aSig;
        !           814:        
        !           815:        int32_t compact, n, j, m, m1;
        !           816:        floatx80 fp0, fp1, fp2, fp3, l2, sc, onebysc;
        !           817:        
        !           818:        aSig = extractFloatx80Frac(a);
        !           819:        aExp = extractFloatx80Exp(a);
        !           820:        aSign = extractFloatx80Sign(a);
        !           821:        
        !           822:        if (aExp == 0x7FFF) {
        !           823:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !           824:                if (aSign) return packFloatx80(aSign, one_exp, one_sig);
        !           825:                return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !           826:        }
        !           827:        
        !           828:        if (aExp == 0 && aSig == 0) {
        !           829:                return packFloatx80(aSign, 0, 0);
        !           830:        }
        !           831:        
        !           832:        SET_PREC;
        !           833:        
        !           834:        if (aExp >= 0x3FFD) { // |X| >= 1/4
        !           835:                compact = floatx80_make_compact(aExp, aSig);
        !           836:                
        !           837:                if (compact <= 0x4004C215) { // |X| <= 70 log2
        !           838:                        fp0 = a;
        !           839:                        fp1 = a;
        !           840:                        fp0 = floatx80_mul(fp0, float32_to_floatx80(0x42B8AA3B, status), status); // 64/log2 * X
        !           841:                        n = floatx80_to_int32(fp0, status); // int(64/log2*X)
        !           842:                        fp0 = int32_to_floatx80(n);
        !           843:                        
        !           844:                        j = n & 0x3F; // J = N mod 64
        !           845:                        m = n / 64; // NOTE: this is really arithmetic right shift by 6
        !           846:                        if (n < 0 && j) { // arithmetic right shift is division and round towards minus infinity
        !           847:                                m--;
        !           848:                        }
        !           849:                        m1 = -m;
        !           850:                        //m += 0x3FFF; // biased exponent of 2^(M)
        !           851:                        //m1 += 0x3FFF; // biased exponent of -2^(-M)
        !           852:                        
        !           853:                        fp2 = fp0; // N
        !           854:                        fp0 = floatx80_mul(fp0, float32_to_floatx80(0xBC317218, status), status); // N * L1, L1 = lead(-log2/64)
        !           855:                        l2 = packFloatx80(0, 0x3FDC, LIT64(0x82E308654361C4C6));
        !           856:                        fp2 = floatx80_mul(fp2, l2, status); // N * L2, L1+L2 = -log2/64
        !           857:                        fp0 = floatx80_add(fp0, fp1, status); // X + N*L1
        !           858:                        fp0 = floatx80_add(fp0, fp2, status); // R
        !           859:                        
        !           860:                        fp1 = floatx80_mul(fp0, fp0, status); // S = R*R
        !           861:                        fp2 = float32_to_floatx80(0x3950097B, status); // A6
        !           862:                        fp2 = floatx80_mul(fp2, fp1, status); // fp2 is S*A6
        !           863:                        fp3 = floatx80_mul(float32_to_floatx80(0x3AB60B6A, status), fp1, status); // fp3 is S*A5
        !           864:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3F81111111174385), status), status); // fp2 IS A4+S*A6
        !           865:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0x3FA5555555554F5A), status), status); // fp3 is A3+S*A5
        !           866:                        fp2 = floatx80_mul(fp2, fp1, status); // fp2 IS S*(A4+S*A6)
        !           867:                        fp3 = floatx80_mul(fp3, fp1, status); // fp3 IS S*(A3+S*A5)
        !           868:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FC5555555555555), status), status); // fp2 IS A2+S*(A4+S*A6)
        !           869:                        fp3 = floatx80_add(fp3, float32_to_floatx80(0x3F000000, status), status); // fp3 IS A1+S*(A3+S*A5)
        !           870:                        fp2 = floatx80_mul(fp2, fp1, status); // fp2 IS S*(A2+S*(A4+S*A6))
        !           871:                        fp1 = floatx80_mul(fp1, fp3, status); // fp1 IS S*(A1+S*(A3+S*A5))
        !           872:                        fp2 = floatx80_mul(fp2, fp0, status); // fp2 IS R*S*(A2+S*(A4+S*A6))
        !           873:                        fp0 = floatx80_add(fp0, fp1, status); // fp0 IS R+S*(A1+S*(A3+S*A5))
        !           874:                        fp0 = floatx80_add(fp0, fp2, status); // fp0 IS EXP(R) - 1
        !           875:                        
        !           876:                        fp0 = floatx80_mul(fp0, exp_tbl[j], status); // 2^(J/64)*(Exp(R)-1)
        !           877:                        
        !           878:                        if (m >= 64) {
        !           879:                                fp1 = float32_to_floatx80(exp_tbl2[j], status);
        !           880:                                onebysc = packFloatx80(1, m1 + 0x3FFF, one_sig); // -2^(-M)
        !           881:                                fp1 = floatx80_add(fp1, onebysc, status);
        !           882:                                fp0 = floatx80_add(fp0, fp1, status);
        !           883:                                fp0 = floatx80_add(fp0, exp_tbl[j], status);
        !           884:                        } else if (m < -3) {
        !           885:                                fp0 = floatx80_add(fp0, float32_to_floatx80(exp_tbl2[j], status), status);
        !           886:                                fp0 = floatx80_add(fp0, exp_tbl[j], status);
        !           887:                                onebysc = packFloatx80(1, m1 + 0x3FFF, one_sig); // -2^(-M)
        !           888:                                fp0 = floatx80_add(fp0, onebysc, status);
        !           889:                        } else { // -3 <= m <= 63
        !           890:                                fp1 = exp_tbl[j];
        !           891:                                fp0 = floatx80_add(fp0, float32_to_floatx80(exp_tbl2[j], status), status);
        !           892:                                onebysc = packFloatx80(1, m1 + 0x3FFF, one_sig); // -2^(-M)
        !           893:                                fp1 = floatx80_add(fp1, onebysc, status);
        !           894:                                fp0 = floatx80_add(fp0, fp1, status);
        !           895:                        }
        !           896:                        
        !           897:                        sc = packFloatx80(0, m + 0x3FFF, one_sig);
        !           898:                        
        !           899:                        RESET_PREC;
        !           900:                        
        !           901:                        a = floatx80_mul(fp0, sc, status);
        !           902:                        
        !           903:                        float_raise(float_flag_inexact, status);
        !           904:                        
        !           905:                        return a;
        !           906:                } else { // |X| > 70 log2
        !           907:                        if (aSign) {
        !           908:                                fp0 = float32_to_floatx80(0xBF800000, status); // -1
        !           909:                                
        !           910:                                RESET_PREC;
        !           911:                                
        !           912:                                a = floatx80_add(fp0, float32_to_floatx80(0x00800000, status), status); // -1 + 2^(-126)
        !           913:                                
        !           914:                                float_raise(float_flag_inexact, status);
        !           915:                                
        !           916:                                return a;
        !           917:                        } else {
        !           918:                                RESET_PREC;
        !           919:                                
        !           920:                                return floatx80_etox(a, status);
        !           921:                        }
        !           922:                }
        !           923:        } else { // |X| < 1/4
        !           924:                if (aExp >= 0x3FBE) {
        !           925:                        fp0 = a;
        !           926:                        fp0 = floatx80_mul(fp0, fp0, status); // S = X*X
        !           927:                        fp1 = float32_to_floatx80(0x2F30CAA8, status); // B12
        !           928:                        fp1 = floatx80_mul(fp1, fp0, status); // S * B12
        !           929:                        fp2 = float32_to_floatx80(0x310F8290, status); // B11
        !           930:                        fp1 = floatx80_add(fp1, float32_to_floatx80(0x32D73220, status), status); // B10
        !           931:                        fp2 = floatx80_mul(fp2, fp0, status);
        !           932:                        fp1 = floatx80_mul(fp1, fp0, status);
        !           933:                        fp2 = floatx80_add(fp2, float32_to_floatx80(0x3493F281, status), status); // B9
        !           934:                        fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3EC71DE3A5774682), status), status); // B8
        !           935:                        fp2 = floatx80_mul(fp2, fp0, status);
        !           936:                        fp1 = floatx80_mul(fp1, fp0, status);
        !           937:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3EFA01A019D7CB68), status), status); // B7
        !           938:                        fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3F2A01A01A019DF3), status), status); // B6
        !           939:                        fp2 = floatx80_mul(fp2, fp0, status);
        !           940:                        fp1 = floatx80_mul(fp1, fp0, status);
        !           941:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3F56C16C16C170E2), status), status); // B5
        !           942:                        fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3F81111111111111), status), status); // B4
        !           943:                        fp2 = floatx80_mul(fp2, fp0, status);
        !           944:                        fp1 = floatx80_mul(fp1, fp0, status);
        !           945:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FA5555555555555), status), status); // B3
        !           946:                        fp3 = packFloatx80(0, 0x3FFC, LIT64(0xAAAAAAAAAAAAAAAB));
        !           947:                        fp1 = floatx80_add(fp1, fp3, status); // B2
        !           948:                        fp2 = floatx80_mul(fp2, fp0, status);
        !           949:                        fp1 = floatx80_mul(fp1, fp0, status);
        !           950:                        
        !           951:                        fp2 = floatx80_mul(fp2, fp0, status);
        !           952:                        fp1 = floatx80_mul(fp1, a, status);
        !           953:                        
        !           954:                        fp0 = floatx80_mul(fp0, float32_to_floatx80(0x3F000000, status), status); // S*B1
        !           955:                        fp1 = floatx80_add(fp1, fp2, status); // Q
        !           956:                        fp0 = floatx80_add(fp0, fp1, status); // S*B1+Q
        !           957:                        
        !           958:                        RESET_PREC;
        !           959:                        
        !           960:                        a = floatx80_add(fp0, a, status);
        !           961:                        
        !           962:                        float_raise(float_flag_inexact, status);
        !           963:                        
        !           964:                        return a;
        !           965:                } else { // |X| < 2^(-65)
        !           966:                        sc = packFloatx80(1, 1, one_sig);
        !           967:                        fp0 = a;
        !           968: 
        !           969:                        if (aExp < 0x0033) { // |X| < 2^(-16382)
        !           970:                                fp0 = floatx80_mul(fp0, float64_to_floatx80(LIT64(0x48B0000000000000), status), status);
        !           971:                                fp0 = floatx80_add(fp0, sc, status);
        !           972:                                
        !           973:                                RESET_PREC;
        !           974: 
        !           975:                                a = floatx80_mul(fp0, float64_to_floatx80(LIT64(0x3730000000000000), status), status);
        !           976:                        } else {
        !           977:                                RESET_PREC;
        !           978:                                
        !           979:                                a = floatx80_add(fp0, sc, status);
        !           980:                        }
        !           981:                        
        !           982:                        float_raise(float_flag_inexact, status);
        !           983:                        
        !           984:                        return a;
        !           985:                }
        !           986:        }
        !           987: }
        !           988: 
        !           989: /*----------------------------------------------------------------------------
        !           990:  | Log base 10
        !           991:  *----------------------------------------------------------------------------*/
        !           992: 
        !           993: floatx80 floatx80_log10(floatx80 a, float_status *status)
        !           994: {
        !           995:        flag aSign;
        !           996:        int32_t aExp;
        !           997:        uint64_t aSig;
        !           998:        
        !           999:        floatx80 fp0, fp1;
        !          1000:        
        !          1001:        aSig = extractFloatx80Frac(a);
        !          1002:        aExp = extractFloatx80Exp(a);
        !          1003:        aSign = extractFloatx80Sign(a);
        !          1004:        
        !          1005:        if (aExp == 0x7FFF) {
        !          1006:                if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status);
        !          1007:                if (aSign == 0)
        !          1008:                        return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !          1009:        }
        !          1010:        
        !          1011:        if (aExp == 0 && aSig == 0) {
        !          1012:                float_raise(float_flag_divbyzero, status);
        !          1013:                return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low);
        !          1014:        }
        !          1015:        
        !          1016:        if (aSign) {
        !          1017:                float_raise(float_flag_invalid, status);
        !          1018:                a.low = floatx80_default_nan_low;
        !          1019:                a.high = floatx80_default_nan_high;
        !          1020:                return a;
        !          1021:        }
        !          1022:        
        !          1023:        SET_PREC;
        !          1024:        
        !          1025:        fp0 = floatx80_logn(a, status);
        !          1026:        fp1 = packFloatx80(0, 0x3FFD, LIT64(0xDE5BD8A937287195)); // INV_L10
        !          1027:        
        !          1028:        RESET_PREC;
        !          1029:        
        !          1030:        a = floatx80_mul(fp0, fp1, status); // LOGN(X)*INV_L10
        !          1031:        
        !          1032:        float_raise(float_flag_inexact, status);
        !          1033:        
        !          1034:        return a;
        !          1035: }
        !          1036: 
        !          1037: /*----------------------------------------------------------------------------
        !          1038:  | Log base 2
        !          1039:  *----------------------------------------------------------------------------*/
        !          1040: 
        !          1041: floatx80 floatx80_log2(floatx80 a, float_status *status)
        !          1042: {
        !          1043:        flag aSign;
        !          1044:        int32_t aExp;
        !          1045:        uint64_t aSig;
        !          1046:        
        !          1047:        floatx80 fp0, fp1;
        !          1048:        
        !          1049:        aSig = extractFloatx80Frac(a);
        !          1050:        aExp = extractFloatx80Exp(a);
        !          1051:        aSign = extractFloatx80Sign(a);
        !          1052:        
        !          1053:        if (aExp == 0x7FFF) {
        !          1054:                if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status);
        !          1055:                if (aSign == 0)
        !          1056:                        return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !          1057:        }
        !          1058:        
        !          1059:        if (aExp == 0) {
        !          1060:                if (aSig == 0) {
        !          1061:                        float_raise(float_flag_divbyzero, status);
        !          1062:                        return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low);
        !          1063:                }
        !          1064:                normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
        !          1065:        }
        !          1066:        
        !          1067:        if (aSign) {
        !          1068:                float_raise(float_flag_invalid, status);
        !          1069:                a.low = floatx80_default_nan_low;
        !          1070:                a.high = floatx80_default_nan_high;
        !          1071:                return a;
        !          1072:        }
        !          1073:        
        !          1074:        SET_PREC;
        !          1075:        
        !          1076:        if (aSig == one_sig) { // X is 2^k
        !          1077:                RESET_PREC;
        !          1078:                
        !          1079:                a = int32_to_floatx80(aExp-0x3FFF);
        !          1080:        } else {
        !          1081:                fp0 = floatx80_logn(a, status);
        !          1082:                fp1 = packFloatx80(0, 0x3FFF, LIT64(0xB8AA3B295C17F0BC)); // INV_L2
        !          1083:                
        !          1084:                RESET_PREC;
        !          1085:                
        !          1086:                a = floatx80_mul(fp0, fp1, status); // LOGN(X)*INV_L2
        !          1087:        }
        !          1088:        
        !          1089:        float_raise(float_flag_inexact, status);
        !          1090:        
        !          1091:        return a;
        !          1092: }
        !          1093: 
        !          1094: /*----------------------------------------------------------------------------
        !          1095:  | Log base e
        !          1096:  *----------------------------------------------------------------------------*/
        !          1097: 
        !          1098: floatx80 floatx80_logn(floatx80 a, float_status *status)
        !          1099: {
        !          1100:        flag aSign;
        !          1101:        int32_t aExp;
        !          1102:        uint64_t aSig, fSig;
        !          1103:        
        !          1104:        int32_t compact, j, k, adjk;
        !          1105:        floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu;
        !          1106:        
        !          1107:        aSig = extractFloatx80Frac(a);
        !          1108:        aExp = extractFloatx80Exp(a);
        !          1109:        aSign = extractFloatx80Sign(a);
        !          1110:        
        !          1111:        if (aExp == 0x7FFF) {
        !          1112:                if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status);
        !          1113:                if (aSign == 0)
        !          1114:                        return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !          1115:        }
        !          1116:        
        !          1117:        adjk = 0;
        !          1118:        
        !          1119:        if (aExp == 0) {
        !          1120:                if (aSig == 0) { // zero
        !          1121:                        float_raise(float_flag_divbyzero, status);
        !          1122:                        return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low);
        !          1123:                }
        !          1124: #if 1
        !          1125:                if ((aSig & one_sig) == 0) { // denormal
        !          1126:                        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
        !          1127:                        adjk = -100;
        !          1128:                        aExp += 100;
        !          1129:                        a = packFloatx80(aSign, aExp, aSig);
        !          1130:                }
        !          1131: #else
        !          1132:                normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
        !          1133: #endif
        !          1134:        }
        !          1135:        
        !          1136:        if (aSign) {
        !          1137:                float_raise(float_flag_invalid, status);
        !          1138:                a.low = floatx80_default_nan_low;
        !          1139:                a.high = floatx80_default_nan_high;
        !          1140:                return a;
        !          1141:        }
        !          1142:        
        !          1143:        SET_PREC;
        !          1144:        
        !          1145:        compact = floatx80_make_compact(aExp, aSig);
        !          1146:        
        !          1147:        if (compact < 0x3FFEF07D || compact > 0x3FFF8841) { // |X| < 15/16 or |X| > 17/16
        !          1148:                k = aExp - 0x3FFF;
        !          1149:                k += adjk;
        !          1150:                fp1 = int32_to_floatx80(k);
        !          1151:                
        !          1152:                fSig = (aSig & LIT64(0xFE00000000000000)) | LIT64(0x0100000000000000);
        !          1153:                j = (fSig >> 56) & 0x7E; // DISPLACEMENT FOR 1/F
        !          1154:                
        !          1155:                f = packFloatx80(0, 0x3FFF, fSig); // F
        !          1156:                fp0 = packFloatx80(0, 0x3FFF, aSig); // Y
        !          1157:                
        !          1158:                fp0 = floatx80_sub(fp0, f, status); // Y-F
        !          1159:                
        !          1160:                // LP1CONT1
        !          1161:                fp0 = floatx80_mul(fp0, log_tbl[j], status); // FP0 IS U = (Y-F)/F
        !          1162:                logof2 = packFloatx80(0, 0x3FFE, LIT64(0xB17217F7D1CF79AC));
        !          1163:                klog2 = floatx80_mul(fp1, logof2, status); // FP1 IS K*LOG2
        !          1164:                fp2 = floatx80_mul(fp0, fp0, status); // FP2 IS V=U*U
        !          1165:                
        !          1166:                fp3 = fp2;
        !          1167:                fp1 = fp2;
        !          1168:                
        !          1169:                fp1 = floatx80_mul(fp1, float64_to_floatx80(LIT64(0x3FC2499AB5E4040B), status), status); // V*A6
        !          1170:                fp2 = floatx80_mul(fp2, float64_to_floatx80(LIT64(0xBFC555B5848CB7DB), status), status); // V*A5
        !          1171:                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3FC99999987D8730), status), status); // A4+V*A6
        !          1172:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0xBFCFFFFFFF6F7E97), status), status); // A3+V*A5
        !          1173:                fp1 = floatx80_mul(fp1, fp3, status); // V*(A4+V*A6)
        !          1174:                fp2 = floatx80_mul(fp2, fp3, status); // V*(A3+V*A5)
        !          1175:                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3FD55555555555A4), status), status); // A2+V*(A4+V*A6)
        !          1176:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0xBFE0000000000008), status), status); // A1+V*(A3+V*A5)
        !          1177:                fp1 = floatx80_mul(fp1, fp3, status); // V*(A2+V*(A4+V*A6))
        !          1178:                fp2 = floatx80_mul(fp2, fp3, status); // V*(A1+V*(A3+V*A5))
        !          1179:                fp1 = floatx80_mul(fp1, fp0, status); // U*V*(A2+V*(A4+V*A6))
        !          1180:                fp0 = floatx80_add(fp0, fp2, status); // U+V*(A1+V*(A3+V*A5))
        !          1181:                
        !          1182:                fp1 = floatx80_add(fp1, log_tbl[j+1], status); // LOG(F)+U*V*(A2+V*(A4+V*A6))
        !          1183:                fp0 = floatx80_add(fp0, fp1, status); // FP0 IS LOG(F) + LOG(1+U)
        !          1184:                
        !          1185:                RESET_PREC;
        !          1186:                
        !          1187:                a = floatx80_add(fp0, klog2, status);
        !          1188:                
        !          1189:                float_raise(float_flag_inexact, status);
        !          1190:                
        !          1191:                return a;
        !          1192:        } else { // |X-1| >= 1/16
        !          1193:                fp0 = a;
        !          1194:                fp1 = a;
        !          1195:                fp1 = floatx80_sub(fp1, float32_to_floatx80(0x3F800000, status), status); // FP1 IS X-1
        !          1196:                fp0 = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // FP0 IS X+1
        !          1197:                fp1 = floatx80_add(fp1, fp1, status); // FP1 IS 2(X-1)
        !          1198:                
        !          1199:                // LP1CONT2
        !          1200:                fp1 = floatx80_div(fp1, fp0, status); // U
        !          1201:                saveu = fp1;
        !          1202:                fp0 = floatx80_mul(fp1, fp1, status); // FP0 IS V = U*U
        !          1203:                fp1 = floatx80_mul(fp0, fp0, status); // FP1 IS W = V*V
        !          1204:                
        !          1205:                fp3 = float64_to_floatx80(LIT64(0x3F175496ADD7DAD6), status); // B5
        !          1206:                fp2 = float64_to_floatx80(LIT64(0x3F3C71C2FE80C7E0), status); // B4
        !          1207:                fp3 = floatx80_mul(fp3, fp1, status); // W*B5
        !          1208:                fp2 = floatx80_mul(fp2, fp1, status); // W*B4
        !          1209:                fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0x3F624924928BCCFF), status), status); // B3+W*B5
        !          1210:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3F899999999995EC), status), status); // B2+W*B4
        !          1211:                fp1 = floatx80_mul(fp1, fp3, status); // W*(B3+W*B5)
        !          1212:                fp2 = floatx80_mul(fp2, fp0, status); // V*(B2+W*B4)
        !          1213:                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3FB5555555555555), status), status); // B1+W*(B3+W*B5)
        !          1214:                
        !          1215:                fp0 = floatx80_mul(fp0, saveu, status); // FP0 IS U*V
        !          1216:                fp1 = floatx80_add(fp1, fp2, status); // B1+W*(B3+W*B5) + V*(B2+W*B4)
        !          1217:                fp0 = floatx80_mul(fp0, fp1, status); // U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
        !          1218:                
        !          1219:                RESET_PREC;
        !          1220:                
        !          1221:                a = floatx80_add(fp0, saveu, status);
        !          1222:                
        !          1223:                float_raise(float_flag_inexact, status);
        !          1224:                
        !          1225:                return a;
        !          1226:        }
        !          1227: }
        !          1228: 
        !          1229: /*----------------------------------------------------------------------------
        !          1230:  | Log base e of x plus 1
        !          1231:  *----------------------------------------------------------------------------*/
        !          1232: 
        !          1233: floatx80 floatx80_lognp1(floatx80 a, float_status *status)
        !          1234: {
        !          1235:        flag aSign;
        !          1236:        int32_t aExp;
        !          1237:        uint64_t aSig, fSig;
        !          1238:        
        !          1239:        int32_t compact, j, k;
        !          1240:        floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu;
        !          1241:        
        !          1242:        aSig = extractFloatx80Frac(a);
        !          1243:        aExp = extractFloatx80Exp(a);
        !          1244:        aSign = extractFloatx80Sign(a);
        !          1245:        
        !          1246:        if (aExp == 0x7FFF) {
        !          1247:                if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status);
        !          1248:                if (aSign) {
        !          1249:                        float_raise(float_flag_invalid, status);
        !          1250:                        a.low = floatx80_default_nan_low;
        !          1251:                        a.high = floatx80_default_nan_high;
        !          1252:                        return a;
        !          1253:                }
        !          1254:                return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !          1255:        }
        !          1256:        
        !          1257:        if (aExp == 0 && aSig == 0) {
        !          1258:                return packFloatx80(aSign, 0, 0);
        !          1259:        }
        !          1260:        
        !          1261:        if (aSign && aExp >= one_exp) {
        !          1262:                if (aExp == one_exp && aSig == one_sig) {
        !          1263:                        float_raise(float_flag_divbyzero, status);
        !          1264:                        packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low);
        !          1265:                }
        !          1266:                float_raise(float_flag_invalid, status);
        !          1267:                a.low = floatx80_default_nan_low;
        !          1268:                a.high = floatx80_default_nan_high;
        !          1269:                return a;
        !          1270:        }
        !          1271:        
        !          1272:        if (aExp < 0x3f99 || (aExp == 0x3f99 && aSig == one_sig)) { // <= min threshold
        !          1273:                float_raise(float_flag_inexact, status);
        !          1274:                return floatx80_move(a, status);
        !          1275:        }
        !          1276:        
        !          1277:        SET_PREC;
        !          1278:        
        !          1279:        compact = floatx80_make_compact(aExp, aSig);
        !          1280:        
        !          1281:        fp0 = a; // Z
        !          1282:        fp1 = a;
        !          1283:        
        !          1284:        fp0 = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // X = (1+Z)
        !          1285:        
        !          1286:        aExp = extractFloatx80Exp(fp0);
        !          1287:        aSig = extractFloatx80Frac(fp0);
        !          1288:        
        !          1289:        compact = floatx80_make_compact(aExp, aSig);
        !          1290:        
        !          1291:        if (compact < 0x3FFE8000 || compact > 0x3FFFC000) { // |X| < 1/2 or |X| > 3/2
        !          1292:                k = aExp - 0x3FFF;
        !          1293:                fp1 = int32_to_floatx80(k);
        !          1294:                
        !          1295:                fSig = (aSig & LIT64(0xFE00000000000000)) | LIT64(0x0100000000000000);
        !          1296:                j = (fSig >> 56) & 0x7E; // DISPLACEMENT FOR 1/F
        !          1297:                
        !          1298:                f = packFloatx80(0, 0x3FFF, fSig); // F
        !          1299:                fp0 = packFloatx80(0, 0x3FFF, aSig); // Y
        !          1300:                
        !          1301:                fp0 = floatx80_sub(fp0, f, status); // Y-F
        !          1302:                
        !          1303:        lp1cont1:
        !          1304:                // LP1CONT1
        !          1305:                fp0 = floatx80_mul(fp0, log_tbl[j], status); // FP0 IS U = (Y-F)/F
        !          1306:                logof2 = packFloatx80(0, 0x3FFE, LIT64(0xB17217F7D1CF79AC));
        !          1307:                klog2 = floatx80_mul(fp1, logof2, status); // FP1 IS K*LOG2
        !          1308:                fp2 = floatx80_mul(fp0, fp0, status); // FP2 IS V=U*U
        !          1309:                
        !          1310:                fp3 = fp2;
        !          1311:                fp1 = fp2;
        !          1312:                
        !          1313:                fp1 = floatx80_mul(fp1, float64_to_floatx80(LIT64(0x3FC2499AB5E4040B), status), status); // V*A6
        !          1314:                fp2 = floatx80_mul(fp2, float64_to_floatx80(LIT64(0xBFC555B5848CB7DB), status), status); // V*A5
        !          1315:                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3FC99999987D8730), status), status); // A4+V*A6
        !          1316:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0xBFCFFFFFFF6F7E97), status), status); // A3+V*A5
        !          1317:                fp1 = floatx80_mul(fp1, fp3, status); // V*(A4+V*A6)
        !          1318:                fp2 = floatx80_mul(fp2, fp3, status); // V*(A3+V*A5)
        !          1319:                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3FD55555555555A4), status), status); // A2+V*(A4+V*A6)
        !          1320:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0xBFE0000000000008), status), status); // A1+V*(A3+V*A5)
        !          1321:                fp1 = floatx80_mul(fp1, fp3, status); // V*(A2+V*(A4+V*A6))
        !          1322:                fp2 = floatx80_mul(fp2, fp3, status); // V*(A1+V*(A3+V*A5))
        !          1323:                fp1 = floatx80_mul(fp1, fp0, status); // U*V*(A2+V*(A4+V*A6))
        !          1324:                fp0 = floatx80_add(fp0, fp2, status); // U+V*(A1+V*(A3+V*A5))
        !          1325:                
        !          1326:                fp1 = floatx80_add(fp1, log_tbl[j+1], status); // LOG(F)+U*V*(A2+V*(A4+V*A6))
        !          1327:                fp0 = floatx80_add(fp0, fp1, status); // FP0 IS LOG(F) + LOG(1+U)
        !          1328:                
        !          1329:                RESET_PREC;
        !          1330:                
        !          1331:                a = floatx80_add(fp0, klog2, status);
        !          1332:                
        !          1333:                float_raise(float_flag_inexact, status);
        !          1334:                
        !          1335:                return a;
        !          1336:        } else if (compact < 0x3FFEF07D || compact > 0x3FFF8841) { // |X| < 1/16 or |X| > -1/16
        !          1337:                // LP1CARE
        !          1338:                fSig = (aSig & LIT64(0xFE00000000000000)) | LIT64(0x0100000000000000);
        !          1339:                f = packFloatx80(0, 0x3FFF, fSig); // F
        !          1340:                j = (fSig >> 56) & 0x7E; // DISPLACEMENT FOR 1/F
        !          1341: 
        !          1342:                if (compact >= 0x3FFF8000) { // 1+Z >= 1
        !          1343:                        // KISZERO
        !          1344:                        fp0 = floatx80_sub(float32_to_floatx80(0x3F800000, status), f, status); // 1-F
        !          1345:                        fp0 = floatx80_add(fp0, fp1, status); // FP0 IS Y-F = (1-F)+Z
        !          1346:                        fp1 = packFloatx80(0, 0, 0); // K = 0
        !          1347:                } else {
        !          1348:                        // KISNEG
        !          1349:                        fp0 = floatx80_sub(float32_to_floatx80(0x40000000, status), f, status); // 2-F
        !          1350:                        fp1 = floatx80_add(fp1, fp1, status); // 2Z
        !          1351:                        fp0 = floatx80_add(fp0, fp1, status); // FP0 IS Y-F = (2-F)+2Z
        !          1352:                        fp1 = packFloatx80(1, one_exp, one_sig); // K = -1
        !          1353:                }
        !          1354:                goto lp1cont1;
        !          1355:        } else {
        !          1356:                // LP1ONE16
        !          1357:                fp1 = floatx80_add(fp1, fp1, status); // FP1 IS 2Z
        !          1358:                fp0 = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // FP0 IS 1+X
        !          1359:                
        !          1360:                // LP1CONT2
        !          1361:                fp1 = floatx80_div(fp1, fp0, status); // U
        !          1362:                saveu = fp1;
        !          1363:                fp0 = floatx80_mul(fp1, fp1, status); // FP0 IS V = U*U
        !          1364:                fp1 = floatx80_mul(fp0, fp0, status); // FP1 IS W = V*V
        !          1365:                
        !          1366:                fp3 = float64_to_floatx80(LIT64(0x3F175496ADD7DAD6), status); // B5
        !          1367:                fp2 = float64_to_floatx80(LIT64(0x3F3C71C2FE80C7E0), status); // B4
        !          1368:                fp3 = floatx80_mul(fp3, fp1, status); // W*B5
        !          1369:                fp2 = floatx80_mul(fp2, fp1, status); // W*B4
        !          1370:                fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0x3F624924928BCCFF), status), status); // B3+W*B5
        !          1371:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3F899999999995EC), status), status); // B2+W*B4
        !          1372:                fp1 = floatx80_mul(fp1, fp3, status); // W*(B3+W*B5)
        !          1373:                fp2 = floatx80_mul(fp2, fp0, status); // V*(B2+W*B4)
        !          1374:                fp1 = floatx80_add(fp1, float64_to_floatx80(LIT64(0x3FB5555555555555), status), status); // B1+W*(B3+W*B5)
        !          1375:                
        !          1376:                fp0 = floatx80_mul(fp0, saveu, status); // FP0 IS U*V
        !          1377:                fp1 = floatx80_add(fp1, fp2, status); // B1+W*(B3+W*B5) + V*(B2+W*B4)
        !          1378:                fp0 = floatx80_mul(fp0, fp1, status); // U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
        !          1379:                
        !          1380:                RESET_PREC;
        !          1381:                
        !          1382:                a = floatx80_add(fp0, saveu, status);
        !          1383:                
        !          1384:                float_raise(float_flag_inexact, status);
        !          1385:                
        !          1386:                return a;
        !          1387:        }
        !          1388: }
        !          1389: 
        !          1390: /*----------------------------------------------------------------------------
        !          1391:  | Sine
        !          1392:  *----------------------------------------------------------------------------*/
        !          1393: 
        !          1394: floatx80 floatx80_sin(floatx80 a, float_status *status)
        !          1395: {
        !          1396:        flag aSign, xSign;
        !          1397:        int32_t aExp, xExp;
        !          1398:        uint64_t aSig, xSig;
        !          1399:        
        !          1400:        int32_t compact, l, n, j;
        !          1401:        floatx80 fp0, fp1, fp2, fp3, fp4, fp5, x, invtwopi, twopi1, twopi2;
        !          1402:        float32 posneg1, twoto63;
        !          1403:        flag adjn, endflag;
        !          1404: 
        !          1405:        aSig = extractFloatx80Frac(a);
        !          1406:        aExp = extractFloatx80Exp(a);
        !          1407:        aSign = extractFloatx80Sign(a);
        !          1408:        
        !          1409:        if (aExp == 0x7FFF) {
        !          1410:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !          1411:                float_raise(float_flag_invalid, status);
        !          1412:                a.low = floatx80_default_nan_low;
        !          1413:                a.high = floatx80_default_nan_high;
        !          1414:                return a;
        !          1415:        }
        !          1416:        
        !          1417:        if (aExp == 0 && aSig == 0) {
        !          1418:                return packFloatx80(aSign, 0, 0);
        !          1419:        }
        !          1420:        
        !          1421:        adjn = 0;
        !          1422:        
        !          1423:        SET_PREC;
        !          1424:        
        !          1425:        compact = floatx80_make_compact(aExp, aSig);
        !          1426:        
        !          1427:        fp0 = a;
        !          1428:        
        !          1429:        if (compact < 0x3FD78000 || compact > 0x4004BC7E) { // 2^(-40) > |X| > 15 PI
        !          1430:                if (compact > 0x3FFF8000) { // |X| >= 15 PI
        !          1431:                        // REDUCEX
        !          1432:                        fp1 = packFloatx80(0, 0, 0);
        !          1433:                        if (compact == 0x7FFEFFFF) {
        !          1434:                                twopi1 = packFloatx80(aSign ^ 1, 0x7FFE, LIT64(0xC90FDAA200000000));
        !          1435:                                twopi2 = packFloatx80(aSign ^ 1, 0x7FDC, LIT64(0x85A308D300000000));
        !          1436:                                fp0 = floatx80_add(fp0, twopi1, status);
        !          1437:                                fp1 = fp0;
        !          1438:                                fp0 = floatx80_add(fp0, twopi2, status);
        !          1439:                                fp1 = floatx80_sub(fp1, fp0, status);
        !          1440:                                fp1 = floatx80_add(fp1, twopi2, status);
        !          1441:                        }
        !          1442:                loop:
        !          1443:                        xSign = extractFloatx80Sign(fp0);
        !          1444:                        xExp = extractFloatx80Exp(fp0);
        !          1445:                        xExp -= 0x3FFF;
        !          1446:                        if (xExp <= 28) {
        !          1447:                                l = 0;
        !          1448:                                endflag = 1;
        !          1449:                        } else {
        !          1450:                                l = xExp - 27;
        !          1451:                                endflag = 0;
        !          1452:                        }
        !          1453:                        invtwopi = packFloatx80(0, 0x3FFE - l, LIT64(0xA2F9836E4E44152A)); // INVTWOPI
        !          1454:                        twopi1 = packFloatx80(0, 0x3FFF + l, LIT64(0xC90FDAA200000000));
        !          1455:                        twopi2 = packFloatx80(0, 0x3FDD + l, LIT64(0x85A308D300000000));
        !          1456:                        
        !          1457:                        twoto63 = 0x5F000000;
        !          1458:                        twoto63 |= xSign ? 0x80000000 : 0x00000000; // SIGN(INARG)*2^63 IN SGL
        !          1459:                        
        !          1460:                        fp2 = floatx80_mul(fp0, invtwopi, status);
        !          1461:                        fp2 = floatx80_add(fp2, float32_to_floatx80(twoto63, status), status); // THE FRACTIONAL PART OF FP2 IS ROUNDED
        !          1462:                        fp2 = floatx80_sub(fp2, float32_to_floatx80(twoto63, status), status); // FP2 is N
        !          1463:                        fp4 = floatx80_mul(twopi1, fp2, status); // W = N*P1
        !          1464:                        fp5 = floatx80_mul(twopi2, fp2, status); // w = N*P2
        !          1465:                        fp3 = floatx80_add(fp4, fp5, status); // FP3 is P
        !          1466:                        fp4 = floatx80_sub(fp4, fp3, status); // W-P
        !          1467:                        fp0 = floatx80_sub(fp0, fp3, status); // FP0 is A := R - P
        !          1468:                        fp4 = floatx80_add(fp4, fp5, status); // FP4 is p = (W-P)+w
        !          1469:                        fp3 = fp0; // FP3 is A
        !          1470:                        fp1 = floatx80_sub(fp1, fp4, status); // FP1 is a := r - p
        !          1471:                        fp0 = floatx80_add(fp0, fp1, status); // FP0 is R := A+a
        !          1472:                        
        !          1473:                        if (endflag > 0) {
        !          1474:                                n = floatx80_to_int32(fp2, status);
        !          1475:                                goto sincont;
        !          1476:                        }
        !          1477:                        fp3 = floatx80_sub(fp3, fp0, status); // A-R
        !          1478:                        fp1 = floatx80_add(fp1, fp3, status); // FP1 is r := (A-R)+a
        !          1479:                        goto loop;
        !          1480:                } else {
        !          1481:                        // SINSM
        !          1482:                        fp0 = float32_to_floatx80(0x3F800000, status); // 1
        !          1483:                        
        !          1484:                        RESET_PREC;
        !          1485:                        
        !          1486:                        if (adjn) {
        !          1487:                                // COSTINY
        !          1488:                                a = floatx80_sub(fp0, float32_to_floatx80(0x00800000, status), status);
        !          1489:                        } else {
        !          1490:                                // SINTINY
        !          1491:                                a = floatx80_move(a, status);
        !          1492:                        }
        !          1493:                        float_raise(float_flag_inexact, status);
        !          1494:                        
        !          1495:                        return a;
        !          1496:                }
        !          1497:        } else {
        !          1498:                fp1 = floatx80_mul(fp0, float64_to_floatx80(LIT64(0x3FE45F306DC9C883), status), status); // X*2/PI
        !          1499:                
        !          1500:                n = floatx80_to_int32(fp1, status);
        !          1501:                j = 32 + n;
        !          1502:                
        !          1503:                fp0 = floatx80_sub(fp0, pi_tbl[j], status); // X-Y1
        !          1504:                fp0 = floatx80_sub(fp0, float32_to_floatx80(pi_tbl2[j], status), status); // FP0 IS R = (X-Y1)-Y2
        !          1505:                
        !          1506:        sincont:
        !          1507:                if ((n + adjn) & 1) {
        !          1508:                        // COSPOLY
        !          1509:                        fp0 = floatx80_mul(fp0, fp0, status); // FP0 IS S
        !          1510:                        fp1 = floatx80_mul(fp0, fp0, status); // FP1 IS T
        !          1511:                        fp2 = float64_to_floatx80(LIT64(0x3D2AC4D0D6011EE3), status); // B8
        !          1512:                        fp3 = float64_to_floatx80(LIT64(0xBDA9396F9F45AC19), status); // B7
        !          1513:                        
        !          1514:                        xSign = extractFloatx80Sign(fp0); // X IS S
        !          1515:                        xExp = extractFloatx80Exp(fp0);
        !          1516:                        xSig = extractFloatx80Frac(fp0);
        !          1517:                        
        !          1518:                        if (((n + adjn) >> 1) & 1) {
        !          1519:                                xSign ^= 1;
        !          1520:                                posneg1 = 0xBF800000; // -1
        !          1521:                        } else {
        !          1522:                                xSign ^= 0;
        !          1523:                                posneg1 = 0x3F800000; // 1
        !          1524:                        } // X IS NOW R'= SGN*R
        !          1525:                        
        !          1526:                        fp2 = floatx80_mul(fp2, fp1, status); // TB8
        !          1527:                        fp3 = floatx80_mul(fp3, fp1, status); // TB7
        !          1528:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3E21EED90612C972), status), status); // B6+TB8
        !          1529:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBE927E4FB79D9FCF), status), status); // B5+TB7
        !          1530:                        fp2 = floatx80_mul(fp2, fp1, status); // T(B6+TB8)
        !          1531:                        fp3 = floatx80_mul(fp3, fp1, status); // T(B5+TB7)
        !          1532:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3EFA01A01A01D423), status), status); // B4+T(B6+TB8)
        !          1533:                        fp4 = packFloatx80(1, 0x3FF5, LIT64(0xB60B60B60B61D438));
        !          1534:                        fp3 = floatx80_add(fp3, fp4, status); // B3+T(B5+TB7)
        !          1535:                        fp2 = floatx80_mul(fp2, fp1, status); // T(B4+T(B6+TB8))
        !          1536:                        fp1 = floatx80_mul(fp1, fp3, status); // T(B3+T(B5+TB7))
        !          1537:                        fp4 = packFloatx80(0, 0x3FFA, LIT64(0xAAAAAAAAAAAAAB5E));
        !          1538:                        fp2 = floatx80_add(fp2, fp4, status); // B2+T(B4+T(B6+TB8))
        !          1539:                        fp1 = floatx80_add(fp1, float32_to_floatx80(0xBF000000, status), status); // B1+T(B3+T(B5+TB7))
        !          1540:                        fp0 = floatx80_mul(fp0, fp2, status); // S(B2+T(B4+T(B6+TB8)))
        !          1541:                        fp0 = floatx80_add(fp0, fp1, status); // [B1+T(B3+T(B5+TB7))]+[S(B2+T(B4+T(B6+TB8)))]
        !          1542:                        
        !          1543:                        x = packFloatx80(xSign, xExp, xSig);
        !          1544:                        fp0 = floatx80_mul(fp0, x, status);
        !          1545:                        
        !          1546:                        RESET_PREC;
        !          1547:                        
        !          1548:                        a = floatx80_add(fp0, float32_to_floatx80(posneg1, status), status);
        !          1549:                        
        !          1550:                        float_raise(float_flag_inexact, status);
        !          1551:                        
        !          1552:                        return a;
        !          1553:                } else {
        !          1554:                        // SINPOLY
        !          1555:                        xSign = extractFloatx80Sign(fp0); // X IS R
        !          1556:                        xExp = extractFloatx80Exp(fp0);
        !          1557:                        xSig = extractFloatx80Frac(fp0);
        !          1558:                        
        !          1559:                        xSign ^= ((n + adjn) >> 1) & 1; // X IS NOW R'= SGN*R
        !          1560:                        
        !          1561:                        fp0 = floatx80_mul(fp0, fp0, status); // FP0 IS S
        !          1562:                        fp1 = floatx80_mul(fp0, fp0, status); // FP1 IS T
        !          1563:                        fp3 = float64_to_floatx80(LIT64(0xBD6AAA77CCC994F5), status); // A7
        !          1564:                        fp2 = float64_to_floatx80(LIT64(0x3DE612097AAE8DA1), status); // A6
        !          1565:                        fp3 = floatx80_mul(fp3, fp1, status); // T*A7
        !          1566:                        fp2 = floatx80_mul(fp2, fp1, status); // T*A6
        !          1567:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBE5AE6452A118AE4), status), status); // A5+T*A7
        !          1568:                        fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3EC71DE3A5341531), status), status); // A4+T*A6
        !          1569:                        fp3 = floatx80_mul(fp3, fp1, status); // T(A5+TA7)
        !          1570:                        fp2 = floatx80_mul(fp2, fp1, status); // T(A4+TA6)
        !          1571:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBF2A01A01A018B59), status), status); // A3+T(A5+TA7)
        !          1572:                        fp4 = packFloatx80(0, 0x3FF8, LIT64(0x88888888888859AF));
        !          1573:                        fp2 = floatx80_add(fp2, fp4, status); // A2+T(A4+TA6)
        !          1574:                        fp1 = floatx80_mul(fp1, fp3, status); // T(A3+T(A5+TA7))
        !          1575:                        fp2 = floatx80_mul(fp2, fp0, status); // S(A2+T(A4+TA6))
        !          1576:                        fp4 = packFloatx80(1, 0x3FFC, LIT64(0xAAAAAAAAAAAAAA99));
        !          1577:                        fp1 = floatx80_add(fp1, fp4, status); // A1+T(A3+T(A5+TA7))
        !          1578:                        fp1 = floatx80_add(fp1, fp2, status); // [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
        !          1579:                        
        !          1580:                        x = packFloatx80(xSign, xExp, xSig);
        !          1581:                        fp0 = floatx80_mul(fp0, x, status); // R'*S
        !          1582:                        fp0 = floatx80_mul(fp0, fp1, status); // SIN(R')-R'
        !          1583:                        
        !          1584:                        RESET_PREC;
        !          1585:                        
        !          1586:                        a = floatx80_add(fp0, x, status);
        !          1587:                        
        !          1588:                        float_raise(float_flag_inexact, status);
        !          1589:                        
        !          1590:                        return a;
        !          1591:                }
        !          1592:        }
        !          1593: }
        !          1594: 
        !          1595: /*----------------------------------------------------------------------------
        !          1596:  | Hyperbolic sine
        !          1597:  *----------------------------------------------------------------------------*/
        !          1598: 
        !          1599: floatx80 floatx80_sinh(floatx80 a, float_status *status)
        !          1600: {
        !          1601:        flag aSign;
        !          1602:        int32_t aExp;
        !          1603:        uint64_t aSig;
        !          1604:        
        !          1605:        int32_t compact;
        !          1606:        floatx80 fp0, fp1, fp2;
        !          1607:        float32 fact;
        !          1608:        
        !          1609:        aSig = extractFloatx80Frac(a);
        !          1610:        aExp = extractFloatx80Exp(a);
        !          1611:        aSign = extractFloatx80Sign(a);
        !          1612:        
        !          1613:        if (aExp == 0x7FFF) {
        !          1614:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !          1615:                return packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low);
        !          1616:        }
        !          1617:        
        !          1618:        if (aExp == 0 && aSig == 0) {
        !          1619:                return packFloatx80(aSign, 0, 0);
        !          1620:        }
        !          1621:        
        !          1622:        SET_PREC;
        !          1623:        
        !          1624:        compact = floatx80_make_compact(aExp, aSig);
        !          1625: 
        !          1626:        if (compact > 0x400CB167) {
        !          1627:                // SINHBIG
        !          1628:                if (compact > 0x400CB2B3) {
        !          1629:                        RESET_PREC;
        !          1630:                        
        !          1631:                        return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign, 0x8000, aSig, 0, status);
        !          1632:                } else {
        !          1633:                        fp0 = floatx80_abs(a, status); // Y = |X|
        !          1634:                        fp0 = floatx80_sub(fp0, float64_to_floatx80(LIT64(0x40C62D38D3D64634), status), status); // (|X|-16381LOG2_LEAD)
        !          1635:                        fp0 = floatx80_sub(fp0, float64_to_floatx80(LIT64(0x3D6F90AEB1E75CC7), status), status); // |X| - 16381 LOG2, ACCURATE
        !          1636:                        fp0 = floatx80_etox(fp0, status);
        !          1637:                        fp2 = packFloatx80(aSign, 0x7FFB, one_sig);
        !          1638:                        
        !          1639:                        RESET_PREC;
        !          1640:                        
        !          1641:                        a = floatx80_mul(fp0, fp2, status);
        !          1642:                        
        !          1643:                        float_raise(float_flag_inexact, status);
        !          1644:                        
        !          1645:                        return a;
        !          1646:                }
        !          1647:        } else { // |X| < 16380 LOG2
        !          1648:                fp0 = floatx80_abs(a, status); // Y = |X|
        !          1649:                fp0 = floatx80_etoxm1(fp0, status); // FP0 IS Z = EXPM1(Y)
        !          1650:                fp1 = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // 1+Z
        !          1651:                fp2 = fp0;
        !          1652:                fp0 = floatx80_div(fp0, fp1, status); // Z/(1+Z)
        !          1653:                fp0 = floatx80_add(fp0, fp2, status);
        !          1654:                
        !          1655:                fact = 0x3F000000;
        !          1656:                fact |= aSign ? 0x80000000 : 0x00000000;
        !          1657:                
        !          1658:                RESET_PREC;
        !          1659:                
        !          1660:                a = floatx80_mul(fp0, float32_to_floatx80(fact, status), status);
        !          1661:                
        !          1662:                float_raise(float_flag_inexact, status);
        !          1663:                
        !          1664:                return a;
        !          1665:        }
        !          1666: }
        !          1667: 
        !          1668: /*----------------------------------------------------------------------------
        !          1669:  | Tangent
        !          1670:  *----------------------------------------------------------------------------*/
        !          1671: 
        !          1672: floatx80 floatx80_tan(floatx80 a, float_status *status)
        !          1673: {
        !          1674:        flag aSign, xSign;
        !          1675:        int32_t aExp, xExp;
        !          1676:        uint64_t aSig, xSig;
        !          1677:        
        !          1678:        int32_t compact, l, n, j;
        !          1679:        floatx80 fp0, fp1, fp2, fp3, fp4, fp5, invtwopi, twopi1, twopi2;
        !          1680:        float32 twoto63;
        !          1681:        flag endflag;
        !          1682:        
        !          1683:        aSig = extractFloatx80Frac(a);
        !          1684:        aExp = extractFloatx80Exp(a);
        !          1685:        aSign = extractFloatx80Sign(a);
        !          1686:        
        !          1687:        if (aExp == 0x7FFF) {
        !          1688:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !          1689:                float_raise(float_flag_invalid, status);
        !          1690:                a.low = floatx80_default_nan_low;
        !          1691:                a.high = floatx80_default_nan_high;
        !          1692:                return a;
        !          1693:        }
        !          1694:        
        !          1695:        if (aExp == 0 && aSig == 0) {
        !          1696:                return packFloatx80(aSign, 0, 0);
        !          1697:        }
        !          1698:        
        !          1699:        SET_PREC;
        !          1700:        
        !          1701:        compact = floatx80_make_compact(aExp, aSig);
        !          1702:        
        !          1703:        fp0 = a;
        !          1704:        
        !          1705:        if (compact < 0x3FD78000 || compact > 0x4004BC7E) { // 2^(-40) > |X| > 15 PI
        !          1706:                if (compact > 0x3FFF8000) { // |X| >= 15 PI
        !          1707:                        // REDUCEX
        !          1708:                        fp1 = packFloatx80(0, 0, 0);
        !          1709:                        if (compact == 0x7FFEFFFF) {
        !          1710:                                twopi1 = packFloatx80(aSign ^ 1, 0x7FFE, LIT64(0xC90FDAA200000000));
        !          1711:                                twopi2 = packFloatx80(aSign ^ 1, 0x7FDC, LIT64(0x85A308D300000000));
        !          1712:                                fp0 = floatx80_add(fp0, twopi1, status);
        !          1713:                                fp1 = fp0;
        !          1714:                                fp0 = floatx80_add(fp0, twopi2, status);
        !          1715:                                fp1 = floatx80_sub(fp1, fp0, status);
        !          1716:                                fp1 = floatx80_add(fp1, twopi2, status);
        !          1717:                        }
        !          1718:                loop:
        !          1719:                        xSign = extractFloatx80Sign(fp0);
        !          1720:                        xExp = extractFloatx80Exp(fp0);
        !          1721:                        xExp -= 0x3FFF;
        !          1722:                        if (xExp <= 28) {
        !          1723:                                l = 0;
        !          1724:                                endflag = 1;
        !          1725:                        } else {
        !          1726:                                l = xExp - 27;
        !          1727:                                endflag = 0;
        !          1728:                        }
        !          1729:                        invtwopi = packFloatx80(0, 0x3FFE - l, LIT64(0xA2F9836E4E44152A)); // INVTWOPI
        !          1730:                        twopi1 = packFloatx80(0, 0x3FFF + l, LIT64(0xC90FDAA200000000));
        !          1731:                        twopi2 = packFloatx80(0, 0x3FDD + l, LIT64(0x85A308D300000000));
        !          1732:                        
        !          1733:                        twoto63 = 0x5F000000;
        !          1734:                        twoto63 |= xSign ? 0x80000000 : 0x00000000; // SIGN(INARG)*2^63 IN SGL
        !          1735:                        
        !          1736:                        fp2 = floatx80_mul(fp0, invtwopi, status);
        !          1737:                        fp2 = floatx80_add(fp2, float32_to_floatx80(twoto63, status), status); // THE FRACTIONAL PART OF FP2 IS ROUNDED
        !          1738:                        fp2 = floatx80_sub(fp2, float32_to_floatx80(twoto63, status), status); // FP2 is N
        !          1739:                        fp4 = floatx80_mul(twopi1, fp2, status); // W = N*P1
        !          1740:                        fp5 = floatx80_mul(twopi2, fp2, status); // w = N*P2
        !          1741:                        fp3 = floatx80_add(fp4, fp5, status); // FP3 is P
        !          1742:                        fp4 = floatx80_sub(fp4, fp3, status); // W-P
        !          1743:                        fp0 = floatx80_sub(fp0, fp3, status); // FP0 is A := R - P
        !          1744:                        fp4 = floatx80_add(fp4, fp5, status); // FP4 is p = (W-P)+w
        !          1745:                        fp3 = fp0; // FP3 is A
        !          1746:                        fp1 = floatx80_sub(fp1, fp4, status); // FP1 is a := r - p
        !          1747:                        fp0 = floatx80_add(fp0, fp1, status); // FP0 is R := A+a
        !          1748:                        
        !          1749:                        if (endflag > 0) {
        !          1750:                                n = floatx80_to_int32(fp2, status);
        !          1751:                                goto tancont;
        !          1752:                        }
        !          1753:                        fp3 = floatx80_sub(fp3, fp0, status); // A-R
        !          1754:                        fp1 = floatx80_add(fp1, fp3, status); // FP1 is r := (A-R)+a
        !          1755:                        goto loop;
        !          1756:                } else {
        !          1757:                        RESET_PREC;
        !          1758:                        
        !          1759:                        a = floatx80_move(a, status);
        !          1760:                        
        !          1761:                        float_raise(float_flag_inexact, status);
        !          1762:                        
        !          1763:                        return a;
        !          1764:                }
        !          1765:        } else {
        !          1766:                fp1 = floatx80_mul(fp0, float64_to_floatx80(LIT64(0x3FE45F306DC9C883), status), status); // X*2/PI
        !          1767:                
        !          1768:                n = floatx80_to_int32(fp1, status);
        !          1769:                j = 32 + n;
        !          1770:                
        !          1771:                fp0 = floatx80_sub(fp0, pi_tbl[j], status); // X-Y1
        !          1772:                fp0 = floatx80_sub(fp0, float32_to_floatx80(pi_tbl2[j], status), status); // FP0 IS R = (X-Y1)-Y2
        !          1773:                
        !          1774:        tancont:
        !          1775:                if (n & 1) {
        !          1776:                        // NODD
        !          1777:                        fp1 = fp0; // R
        !          1778:                        fp0 = floatx80_mul(fp0, fp0, status); // S = R*R
        !          1779:                        fp3 = float64_to_floatx80(LIT64(0x3EA0B759F50F8688), status); // Q4
        !          1780:                        fp2 = float64_to_floatx80(LIT64(0xBEF2BAA5A8924F04), status); // P3
        !          1781:                        fp3 = floatx80_mul(fp3, fp0, status); // SQ4
        !          1782:                        fp2 = floatx80_mul(fp2, fp0, status); // SP3
        !          1783:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBF346F59B39BA65F), status), status); // Q3+SQ4
        !          1784:                        fp4 = packFloatx80(0, 0x3FF6, LIT64(0xE073D3FC199C4A00));
        !          1785:                        fp2 = floatx80_add(fp2, fp4, status); // P2+SP3
        !          1786:                        fp3 = floatx80_mul(fp3, fp0, status); // S(Q3+SQ4)
        !          1787:                        fp2 = floatx80_mul(fp2, fp0, status); // S(P2+SP3)
        !          1788:                        fp4 = packFloatx80(0, 0x3FF9, LIT64(0xD23CD68415D95FA1));
        !          1789:                        fp3 = floatx80_add(fp3, fp4, status); // Q2+S(Q3+SQ4)
        !          1790:                        fp4 = packFloatx80(1, 0x3FFC, LIT64(0x8895A6C5FB423BCA));
        !          1791:                        fp2 = floatx80_add(fp2, fp4, status); // P1+S(P2+SP3)
        !          1792:                        fp3 = floatx80_mul(fp3, fp0, status); // S(Q2+S(Q3+SQ4))
        !          1793:                        fp2 = floatx80_mul(fp2, fp0, status); // S(P1+S(P2+SP3))
        !          1794:                        fp4 = packFloatx80(1, 0x3FFD, LIT64(0xEEF57E0DA84BC8CE));
        !          1795:                        fp3 = floatx80_add(fp3, fp4, status); // Q1+S(Q2+S(Q3+SQ4))
        !          1796:                        fp2 = floatx80_mul(fp2, fp1, status); // RS(P1+S(P2+SP3))
        !          1797:                        fp0 = floatx80_mul(fp0, fp3, status); // S(Q1+S(Q2+S(Q3+SQ4)))
        !          1798:                        fp1 = floatx80_add(fp1, fp2, status); // R+RS(P1+S(P2+SP3))
        !          1799:                        fp0 = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // 1+S(Q1+S(Q2+S(Q3+SQ4)))
        !          1800:                        
        !          1801:                        xSign = extractFloatx80Sign(fp1);
        !          1802:                        xExp = extractFloatx80Exp(fp1);
        !          1803:                        xSig = extractFloatx80Frac(fp1);
        !          1804:                        xSign ^= 1;
        !          1805:                        fp1 = packFloatx80(xSign, xExp, xSig);
        !          1806: 
        !          1807:                        RESET_PREC;
        !          1808:                        
        !          1809:                        a = floatx80_div(fp0, fp1, status);
        !          1810:                        
        !          1811:                        float_raise(float_flag_inexact, status);
        !          1812:                        
        !          1813:                        return a;
        !          1814:                } else {
        !          1815:                        fp1 = floatx80_mul(fp0, fp0, status); // S = R*R
        !          1816:                        fp3 = float64_to_floatx80(LIT64(0x3EA0B759F50F8688), status); // Q4
        !          1817:                        fp2 = float64_to_floatx80(LIT64(0xBEF2BAA5A8924F04), status); // P3
        !          1818:                        fp3 = floatx80_mul(fp3, fp1, status); // SQ4
        !          1819:                        fp2 = floatx80_mul(fp2, fp1, status); // SP3
        !          1820:                        fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0xBF346F59B39BA65F), status), status); // Q3+SQ4
        !          1821:                        fp4 = packFloatx80(0, 0x3FF6, LIT64(0xE073D3FC199C4A00));
        !          1822:                        fp2 = floatx80_add(fp2, fp4, status); // P2+SP3
        !          1823:                        fp3 = floatx80_mul(fp3, fp1, status); // S(Q3+SQ4)
        !          1824:                        fp2 = floatx80_mul(fp2, fp1, status); // S(P2+SP3)
        !          1825:                        fp4 = packFloatx80(0, 0x3FF9, LIT64(0xD23CD68415D95FA1));
        !          1826:                        fp3 = floatx80_add(fp3, fp4, status); // Q2+S(Q3+SQ4)
        !          1827:                        fp4 = packFloatx80(1, 0x3FFC, LIT64(0x8895A6C5FB423BCA));
        !          1828:                        fp2 = floatx80_add(fp2, fp4, status); // P1+S(P2+SP3)
        !          1829:                        fp3 = floatx80_mul(fp3, fp1, status); // S(Q2+S(Q3+SQ4))
        !          1830:                        fp2 = floatx80_mul(fp2, fp1, status); // S(P1+S(P2+SP3))
        !          1831:                        fp4 = packFloatx80(1, 0x3FFD, LIT64(0xEEF57E0DA84BC8CE));
        !          1832:                        fp3 = floatx80_add(fp3, fp4, status); // Q1+S(Q2+S(Q3+SQ4))
        !          1833:                        fp2 = floatx80_mul(fp2, fp0, status); // RS(P1+S(P2+SP3))
        !          1834:                        fp1 = floatx80_mul(fp1, fp3, status); // S(Q1+S(Q2+S(Q3+SQ4)))
        !          1835:                        fp0 = floatx80_add(fp0, fp2, status); // R+RS(P1+S(P2+SP3))
        !          1836:                        fp1 = floatx80_add(fp1, float32_to_floatx80(0x3F800000, status), status); // 1+S(Q1+S(Q2+S(Q3+SQ4)))
        !          1837:                        
        !          1838:                        RESET_PREC;
        !          1839:                        
        !          1840:                        a = floatx80_div(fp0, fp1, status);
        !          1841:                        
        !          1842:                        float_raise(float_flag_inexact, status);
        !          1843:                        
        !          1844:                        return a;
        !          1845:                }
        !          1846:        }
        !          1847: }
        !          1848: 
        !          1849: /*----------------------------------------------------------------------------
        !          1850:  | Hyperbolic tangent
        !          1851:  *----------------------------------------------------------------------------*/
        !          1852: 
        !          1853: floatx80 floatx80_tanh(floatx80 a, float_status *status)
        !          1854: {
        !          1855:        flag aSign, vSign;
        !          1856:        int32_t aExp, vExp;
        !          1857:        uint64_t aSig, vSig;
        !          1858:        
        !          1859:        int32_t compact;
        !          1860:        floatx80 fp0, fp1;
        !          1861:        float32 sign;
        !          1862:        
        !          1863:        aSig = extractFloatx80Frac(a);
        !          1864:        aExp = extractFloatx80Exp(a);
        !          1865:        aSign = extractFloatx80Sign(a);
        !          1866:        
        !          1867:        if (aExp == 0x7FFF) {
        !          1868:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !          1869:                return packFloatx80(aSign, one_exp, one_sig);
        !          1870:        }
        !          1871:        
        !          1872:        if (aExp == 0 && aSig == 0) {
        !          1873:                return packFloatx80(aSign, 0, 0);
        !          1874:        }
        !          1875:        
        !          1876:        SET_PREC;
        !          1877:        
        !          1878:        compact = floatx80_make_compact(aExp, aSig);
        !          1879:        
        !          1880:        if (compact < 0x3FD78000 || compact > 0x3FFFDDCE) {
        !          1881:                // TANHBORS
        !          1882:                if (compact < 0x3FFF8000) {
        !          1883:                        // TANHSM
        !          1884:                        RESET_PREC;
        !          1885:                        
        !          1886:                        a = floatx80_move(a, status);
        !          1887:                        
        !          1888:                        float_raise(float_flag_inexact, status);
        !          1889:                        
        !          1890:                        return a;
        !          1891:                } else {
        !          1892:                        if (compact > 0x40048AA1) {
        !          1893:                                // TANHHUGE
        !          1894:                                sign = 0x3F800000;
        !          1895:                                sign |= aSign ? 0x80000000 : 0x00000000;
        !          1896:                                fp0 = float32_to_floatx80(sign, status);
        !          1897:                                sign &= 0x80000000;
        !          1898:                                sign ^= 0x80800000; // -SIGN(X)*EPS
        !          1899:                                
        !          1900:                                RESET_PREC;
        !          1901:                                
        !          1902:                                a = floatx80_add(fp0, float32_to_floatx80(sign, status), status);
        !          1903:                                
        !          1904:                                float_raise(float_flag_inexact, status);
        !          1905:                                
        !          1906:                                return a;
        !          1907:                        } else {
        !          1908:                                fp0 = packFloatx80(0, aExp+1, aSig); // Y = 2|X|
        !          1909:                                fp0 = floatx80_etox(fp0, status); // FP0 IS EXP(Y)
        !          1910:                                fp0 = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // EXP(Y)+1
        !          1911:                                sign = aSign ? 0x80000000 : 0x00000000;
        !          1912:                                fp1 = floatx80_div(float32_to_floatx80(sign^0xC0000000, status), fp0, status); // -SIGN(X)*2 / [EXP(Y)+1]
        !          1913:                                fp0 = float32_to_floatx80(sign | 0x3F800000, status); // SIGN
        !          1914:                                
        !          1915:                                RESET_PREC;
        !          1916:                                
        !          1917:                                a = floatx80_add(fp1, fp0, status);
        !          1918:                                
        !          1919:                                float_raise(float_flag_inexact, status);
        !          1920:                                
        !          1921:                                return a;
        !          1922:                        }
        !          1923:                }
        !          1924:        } else { // 2**(-40) < |X| < (5/2)LOG2
        !          1925:                fp0 = packFloatx80(0, aExp+1, aSig); // Y = 2|X|
        !          1926:                fp0 = floatx80_etoxm1(fp0, status); // FP0 IS Z = EXPM1(Y)
        !          1927:                fp1 = floatx80_add(fp0, float32_to_floatx80(0x40000000, status), status); // Z+2
        !          1928:                
        !          1929:                vSign = extractFloatx80Sign(fp1);
        !          1930:                vExp = extractFloatx80Exp(fp1);
        !          1931:                vSig = extractFloatx80Frac(fp1);
        !          1932:                
        !          1933:                fp1 = packFloatx80(vSign ^ aSign, vExp, vSig);
        !          1934:                
        !          1935:                RESET_PREC;
        !          1936:                
        !          1937:                a = floatx80_div(fp0, fp1, status);
        !          1938:                
        !          1939:                float_raise(float_flag_inexact, status);
        !          1940:                
        !          1941:                return a;
        !          1942:        }
        !          1943: }
        !          1944: 
        !          1945: /*----------------------------------------------------------------------------
        !          1946:  | 10 to x
        !          1947:  *----------------------------------------------------------------------------*/
        !          1948: 
        !          1949: floatx80 floatx80_tentox(floatx80 a, float_status *status)
        !          1950: {
        !          1951:        flag aSign;
        !          1952:        int32_t aExp;
        !          1953:        uint64_t aSig;
        !          1954:        
        !          1955:        int32_t compact, n, j, l, m, m1;
        !          1956:        floatx80 fp0, fp1, fp2, fp3, adjfact, fact1, fact2;
        !          1957:        
        !          1958:        aSig = extractFloatx80Frac(a);
        !          1959:        aExp = extractFloatx80Exp(a);
        !          1960:        aSign = extractFloatx80Sign(a);
        !          1961:        
        !          1962:        if (aExp == 0x7FFF) {
        !          1963:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !          1964:                if (aSign) return packFloatx80(0, 0, 0);
        !          1965:                return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !          1966:        }
        !          1967:        
        !          1968:        if (aExp == 0 && aSig == 0) {
        !          1969:                return packFloatx80(0, one_exp, one_sig);
        !          1970:        }
        !          1971:        
        !          1972:        SET_PREC;
        !          1973:        
        !          1974:        fp0 = a;
        !          1975:        
        !          1976:        compact = floatx80_make_compact(aExp, aSig);
        !          1977:        
        !          1978:        if (compact < 0x3FB98000 || compact > 0x400B9B07) { // |X| > 16480 LOG2/LOG10 or |X| < 2^(-70)
        !          1979:                if (compact > 0x3FFF8000) { // |X| > 16480
        !          1980:                        RESET_PREC;
        !          1981:                        
        !          1982:                        if (aSign) {
        !          1983:                                return roundAndPackFloatx80(status->floatx80_rounding_precision, 0, -0x1000, aSig, 0, status);
        !          1984:                        } else {
        !          1985:                                return roundAndPackFloatx80(status->floatx80_rounding_precision, 0, 0x8000, aSig, 0, status);
        !          1986:                        }
        !          1987:                } else { // |X| < 2^(-70)
        !          1988:                        RESET_PREC;
        !          1989:                        
        !          1990:                        a = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // 1 + X
        !          1991:                        
        !          1992:                        float_raise(float_flag_inexact, status);
        !          1993:                        
        !          1994:                        return a;
        !          1995:                }
        !          1996:        } else { // 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
        !          1997:                fp1 = fp0; // X
        !          1998:                fp1 = floatx80_mul(fp1, float64_to_floatx80(LIT64(0x406A934F0979A371), status), status); // X*64*LOG10/LOG2
        !          1999:                n = floatx80_to_int32(fp1, status); // N=INT(X*64*LOG10/LOG2)
        !          2000:                fp1 = int32_to_floatx80(n);
        !          2001: 
        !          2002:                j = n & 0x3F;
        !          2003:                l = n / 64; // NOTE: this is really arithmetic right shift by 6
        !          2004:                if (n < 0 && j) { // arithmetic right shift is division and round towards minus infinity
        !          2005:                        l--;
        !          2006:                }
        !          2007:                m = l / 2; // NOTE: this is really arithmetic right shift by 1
        !          2008:                if (l < 0 && (l & 1)) { // arithmetic right shift is division and round towards minus infinity
        !          2009:                        m--;
        !          2010:                }
        !          2011:                m1 = l - m;
        !          2012:                m1 += 0x3FFF; // ADJFACT IS 2^(M')
        !          2013: 
        !          2014:                adjfact = packFloatx80(0, m1, one_sig);
        !          2015:                fact1 = exp2_tbl[j];
        !          2016:                fact1.high += m;
        !          2017:                fact2.high = exp2_tbl2[j]>>16;
        !          2018:                fact2.high += m;
        !          2019:                fact2.low = (uint64_t)(exp2_tbl2[j] & 0xFFFF);
        !          2020:                fact2.low <<= 48;
        !          2021:                
        !          2022:                fp2 = fp1; // N
        !          2023:                fp1 = floatx80_mul(fp1, float64_to_floatx80(LIT64(0x3F734413509F8000), status), status); // N*(LOG2/64LOG10)_LEAD
        !          2024:                fp3 = packFloatx80(1, 0x3FCD, LIT64(0xC0219DC1DA994FD2));
        !          2025:                fp2 = floatx80_mul(fp2, fp3, status); // N*(LOG2/64LOG10)_TRAIL
        !          2026:                fp0 = floatx80_sub(fp0, fp1, status); // X - N L_LEAD
        !          2027:                fp0 = floatx80_sub(fp0, fp2, status); // X - N L_TRAIL
        !          2028:                fp2 = packFloatx80(0, 0x4000, LIT64(0x935D8DDDAAA8AC17)); // LOG10
        !          2029:                fp0 = floatx80_mul(fp0, fp2, status); // R
        !          2030:                
        !          2031:                // EXPR
        !          2032:                fp1 = floatx80_mul(fp0, fp0, status); // S = R*R
        !          2033:                fp2 = float64_to_floatx80(LIT64(0x3F56C16D6F7BD0B2), status); // A5
        !          2034:                fp3 = float64_to_floatx80(LIT64(0x3F811112302C712C), status); // A4
        !          2035:                fp2 = floatx80_mul(fp2, fp1, status); // S*A5
        !          2036:                fp3 = floatx80_mul(fp3, fp1, status); // S*A4
        !          2037:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FA5555555554CC1), status), status); // A3+S*A5
        !          2038:                fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0x3FC5555555554A54), status), status); // A2+S*A4
        !          2039:                fp2 = floatx80_mul(fp2, fp1, status); // S*(A3+S*A5)
        !          2040:                fp3 = floatx80_mul(fp3, fp1, status); // S*(A2+S*A4)
        !          2041:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FE0000000000000), status), status); // A1+S*(A3+S*A5)
        !          2042:                fp3 = floatx80_mul(fp3, fp0, status); // R*S*(A2+S*A4)
        !          2043:                
        !          2044:                fp2 = floatx80_mul(fp2, fp1, status); // S*(A1+S*(A3+S*A5))
        !          2045:                fp0 = floatx80_add(fp0, fp3, status); // R+R*S*(A2+S*A4)
        !          2046:                fp0 = floatx80_add(fp0, fp2, status); // EXP(R) - 1
        !          2047:                
        !          2048:                fp0 = floatx80_mul(fp0, fact1, status);
        !          2049:                fp0 = floatx80_add(fp0, fact2, status);
        !          2050:                fp0 = floatx80_add(fp0, fact1, status);
        !          2051:                
        !          2052:                RESET_PREC;
        !          2053: 
        !          2054:                a = floatx80_mul(fp0, adjfact, status);
        !          2055:                
        !          2056:                float_raise(float_flag_inexact, status);
        !          2057:                
        !          2058:                return a;
        !          2059:        }
        !          2060: }
        !          2061: 
        !          2062: /*----------------------------------------------------------------------------
        !          2063:  | 2 to x
        !          2064:  *----------------------------------------------------------------------------*/
        !          2065: 
        !          2066: floatx80 floatx80_twotox(floatx80 a, float_status *status)
        !          2067: {
        !          2068:        flag aSign;
        !          2069:        int32_t aExp;
        !          2070:        uint64_t aSig;
        !          2071:        
        !          2072:        int32_t compact, n, j, l, m, m1;
        !          2073:        floatx80 fp0, fp1, fp2, fp3, adjfact, fact1, fact2;
        !          2074:        
        !          2075:        aSig = extractFloatx80Frac(a);
        !          2076:        aExp = extractFloatx80Exp(a);
        !          2077:        aSign = extractFloatx80Sign(a);
        !          2078:        
        !          2079:        if (aExp == 0x7FFF) {
        !          2080:                if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status);
        !          2081:                if (aSign) return packFloatx80(0, 0, 0);
        !          2082:                return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
        !          2083:        }
        !          2084:        
        !          2085:        if (aExp == 0 && aSig == 0) {
        !          2086:                return packFloatx80(0, one_exp, one_sig);
        !          2087:        }
        !          2088:        
        !          2089:        SET_PREC;
        !          2090:        
        !          2091:        fp0 = a;
        !          2092:        
        !          2093:        compact = floatx80_make_compact(aExp, aSig);
        !          2094:        
        !          2095:        if (compact < 0x3FB98000 || compact > 0x400D80C0) { // |X| > 16480 or |X| < 2^(-70)
        !          2096:                if (compact > 0x3FFF8000) { // |X| > 16480
        !          2097:                        RESET_PREC;;
        !          2098:                        
        !          2099:                        if (aSign) {
        !          2100:                                return roundAndPackFloatx80(status->floatx80_rounding_precision, 0, -0x1000, aSig, 0, status);
        !          2101:                        } else {
        !          2102:                                return roundAndPackFloatx80(status->floatx80_rounding_precision, 0, 0x8000, aSig, 0, status);
        !          2103:                        }
        !          2104:                } else { // |X| < 2^(-70)
        !          2105:                        RESET_PREC;;
        !          2106:                        
        !          2107:                        a = floatx80_add(fp0, float32_to_floatx80(0x3F800000, status), status); // 1 + X
        !          2108:                        
        !          2109:                        float_raise(float_flag_inexact, status);
        !          2110:                        
        !          2111:                        return a;
        !          2112:                }
        !          2113:        } else { // 2^(-70) <= |X| <= 16480
        !          2114:                fp1 = fp0; // X
        !          2115:                fp1 = floatx80_mul(fp1, float32_to_floatx80(0x42800000, status), status); // X * 64
        !          2116:                n = floatx80_to_int32(fp1, status);
        !          2117:                fp1 = int32_to_floatx80(n);
        !          2118:                j = n & 0x3F;
        !          2119:                l = n / 64; // NOTE: this is really arithmetic right shift by 6
        !          2120:                if (n < 0 && j) { // arithmetic right shift is division and round towards minus infinity
        !          2121:                        l--;
        !          2122:                }
        !          2123:                m = l / 2; // NOTE: this is really arithmetic right shift by 1
        !          2124:                if (l < 0 && (l & 1)) { // arithmetic right shift is division and round towards minus infinity
        !          2125:                        m--;
        !          2126:                }
        !          2127:                m1 = l - m;
        !          2128:                m1 += 0x3FFF; // ADJFACT IS 2^(M')
        !          2129:                
        !          2130:                adjfact = packFloatx80(0, m1, one_sig);
        !          2131:                fact1 = exp2_tbl[j];
        !          2132:                fact1.high += m;
        !          2133:                fact2.high = exp2_tbl2[j]>>16;
        !          2134:                fact2.high += m;
        !          2135:                fact2.low = (uint64_t)(exp2_tbl2[j] & 0xFFFF);
        !          2136:                fact2.low <<= 48;
        !          2137:                
        !          2138:                fp1 = floatx80_mul(fp1, float32_to_floatx80(0x3C800000, status), status); // (1/64)*N
        !          2139:                fp0 = floatx80_sub(fp0, fp1, status); // X - (1/64)*INT(64 X)
        !          2140:                fp2 = packFloatx80(0, 0x3FFE, LIT64(0xB17217F7D1CF79AC)); // LOG2
        !          2141:                fp0 = floatx80_mul(fp0, fp2, status); // R
        !          2142:                
        !          2143:                // EXPR
        !          2144:                fp1 = floatx80_mul(fp0, fp0, status); // S = R*R
        !          2145:                fp2 = float64_to_floatx80(LIT64(0x3F56C16D6F7BD0B2), status); // A5
        !          2146:                fp3 = float64_to_floatx80(LIT64(0x3F811112302C712C), status); // A4
        !          2147:                fp2 = floatx80_mul(fp2, fp1, status); // S*A5
        !          2148:                fp3 = floatx80_mul(fp3, fp1, status); // S*A4
        !          2149:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FA5555555554CC1), status), status); // A3+S*A5
        !          2150:                fp3 = floatx80_add(fp3, float64_to_floatx80(LIT64(0x3FC5555555554A54), status), status); // A2+S*A4
        !          2151:                fp2 = floatx80_mul(fp2, fp1, status); // S*(A3+S*A5)
        !          2152:                fp3 = floatx80_mul(fp3, fp1, status); // S*(A2+S*A4)
        !          2153:                fp2 = floatx80_add(fp2, float64_to_floatx80(LIT64(0x3FE0000000000000), status), status); // A1+S*(A3+S*A5)
        !          2154:                fp3 = floatx80_mul(fp3, fp0, status); // R*S*(A2+S*A4)
        !          2155:                
        !          2156:                fp2 = floatx80_mul(fp2, fp1, status); // S*(A1+S*(A3+S*A5))
        !          2157:                fp0 = floatx80_add(fp0, fp3, status); // R+R*S*(A2+S*A4)
        !          2158:                fp0 = floatx80_add(fp0, fp2, status); // EXP(R) - 1
        !          2159:                
        !          2160:                fp0 = floatx80_mul(fp0, fact1, status);
        !          2161:                fp0 = floatx80_add(fp0, fact2, status);
        !          2162:                fp0 = floatx80_add(fp0, fact1, status);
        !          2163:                
        !          2164:                RESET_PREC;
        !          2165:                
        !          2166:                a = floatx80_mul(fp0, adjfact, status);
        !          2167:                
        !          2168:                float_raise(float_flag_inexact, status);
        !          2169:                
        !          2170:                return a;
        !          2171:        }
        !          2172: }

unix.superglobalmegacorp.com

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