Annotation of hatari/src/cpu/softfloat/softfloat_fpsp.c, revision 1.1.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.