1*4882a593Smuzhiyun| 2*4882a593Smuzhiyun| ssinh.sa 3.1 12/10/90 3*4882a593Smuzhiyun| 4*4882a593Smuzhiyun| The entry point sSinh computes the hyperbolic sine of 5*4882a593Smuzhiyun| an input argument; sSinhd does the same except for denormalized 6*4882a593Smuzhiyun| input. 7*4882a593Smuzhiyun| 8*4882a593Smuzhiyun| Input: Double-extended number X in location pointed to 9*4882a593Smuzhiyun| by address register a0. 10*4882a593Smuzhiyun| 11*4882a593Smuzhiyun| Output: The value sinh(X) returned in floating-point register Fp0. 12*4882a593Smuzhiyun| 13*4882a593Smuzhiyun| Accuracy and Monotonicity: The returned result is within 3 ulps in 14*4882a593Smuzhiyun| 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the 15*4882a593Smuzhiyun| result is subsequently rounded to double precision. The 16*4882a593Smuzhiyun| result is provably monotonic in double precision. 17*4882a593Smuzhiyun| 18*4882a593Smuzhiyun| Speed: The program sSINH takes approximately 280 cycles. 19*4882a593Smuzhiyun| 20*4882a593Smuzhiyun| Algorithm: 21*4882a593Smuzhiyun| 22*4882a593Smuzhiyun| SINH 23*4882a593Smuzhiyun| 1. If |X| > 16380 log2, go to 3. 24*4882a593Smuzhiyun| 25*4882a593Smuzhiyun| 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formulae 26*4882a593Smuzhiyun| y = |X|, sgn = sign(X), and z = expm1(Y), 27*4882a593Smuzhiyun| sinh(X) = sgn*(1/2)*( z + z/(1+z) ). 28*4882a593Smuzhiyun| Exit. 29*4882a593Smuzhiyun| 30*4882a593Smuzhiyun| 3. If |X| > 16480 log2, go to 5. 31*4882a593Smuzhiyun| 32*4882a593Smuzhiyun| 4. (16380 log2 < |X| <= 16480 log2) 33*4882a593Smuzhiyun| sinh(X) = sign(X) * exp(|X|)/2. 34*4882a593Smuzhiyun| However, invoking exp(|X|) may cause premature overflow. 35*4882a593Smuzhiyun| Thus, we calculate sinh(X) as follows: 36*4882a593Smuzhiyun| Y := |X| 37*4882a593Smuzhiyun| sgn := sign(X) 38*4882a593Smuzhiyun| sgnFact := sgn * 2**(16380) 39*4882a593Smuzhiyun| Y' := Y - 16381 log2 40*4882a593Smuzhiyun| sinh(X) := sgnFact * exp(Y'). 41*4882a593Smuzhiyun| Exit. 42*4882a593Smuzhiyun| 43*4882a593Smuzhiyun| 5. (|X| > 16480 log2) sinh(X) must overflow. Return 44*4882a593Smuzhiyun| sign(X)*Huge*Huge to generate overflow and an infinity with 45*4882a593Smuzhiyun| the appropriate sign. Huge is the largest finite number in 46*4882a593Smuzhiyun| extended format. Exit. 47*4882a593Smuzhiyun| 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun| Copyright (C) Motorola, Inc. 1990 50*4882a593Smuzhiyun| All Rights Reserved 51*4882a593Smuzhiyun| 52*4882a593Smuzhiyun| For details on the license for this file, please see the 53*4882a593Smuzhiyun| file, README, in this same directory. 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun|SSINH idnt 2,1 | Motorola 040 Floating Point Software Package 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun |section 8 58*4882a593Smuzhiyun 59*4882a593SmuzhiyunT1: .long 0x40C62D38,0xD3D64634 | ... 16381 LOG2 LEAD 60*4882a593SmuzhiyunT2: .long 0x3D6F90AE,0xB1E75CC7 | ... 16381 LOG2 TRAIL 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun |xref t_frcinx 63*4882a593Smuzhiyun |xref t_ovfl 64*4882a593Smuzhiyun |xref t_extdnrm 65*4882a593Smuzhiyun |xref setox 66*4882a593Smuzhiyun |xref setoxm1 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun .global ssinhd 69*4882a593Smuzhiyunssinhd: 70*4882a593Smuzhiyun|--SINH(X) = X FOR DENORMALIZED X 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun bra t_extdnrm 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun .global ssinh 75*4882a593Smuzhiyunssinh: 76*4882a593Smuzhiyun fmovex (%a0),%fp0 | ...LOAD INPUT 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun movel (%a0),%d0 79*4882a593Smuzhiyun movew 4(%a0),%d0 80*4882a593Smuzhiyun movel %d0,%a1 | save a copy of original (compacted) operand 81*4882a593Smuzhiyun andl #0x7FFFFFFF,%d0 82*4882a593Smuzhiyun cmpl #0x400CB167,%d0 83*4882a593Smuzhiyun bgts SINHBIG 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun|--THIS IS THE USUAL CASE, |X| < 16380 LOG2 86*4882a593Smuzhiyun|--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) ) 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun fabsx %fp0 | ...Y = |X| 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun moveml %a1/%d1,-(%sp) 91*4882a593Smuzhiyun fmovemx %fp0-%fp0,(%a0) 92*4882a593Smuzhiyun clrl %d1 93*4882a593Smuzhiyun bsr setoxm1 | ...FP0 IS Z = EXPM1(Y) 94*4882a593Smuzhiyun fmovel #0,%fpcr 95*4882a593Smuzhiyun moveml (%sp)+,%a1/%d1 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun fmovex %fp0,%fp1 98*4882a593Smuzhiyun fadds #0x3F800000,%fp1 | ...1+Z 99*4882a593Smuzhiyun fmovex %fp0,-(%sp) 100*4882a593Smuzhiyun fdivx %fp1,%fp0 | ...Z/(1+Z) 101*4882a593Smuzhiyun movel %a1,%d0 102*4882a593Smuzhiyun andl #0x80000000,%d0 103*4882a593Smuzhiyun orl #0x3F000000,%d0 104*4882a593Smuzhiyun faddx (%sp)+,%fp0 105*4882a593Smuzhiyun movel %d0,-(%sp) 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun fmovel %d1,%fpcr 108*4882a593Smuzhiyun fmuls (%sp)+,%fp0 |last fp inst - possible exceptions set 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun bra t_frcinx 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunSINHBIG: 113*4882a593Smuzhiyun cmpl #0x400CB2B3,%d0 114*4882a593Smuzhiyun bgt t_ovfl 115*4882a593Smuzhiyun fabsx %fp0 116*4882a593Smuzhiyun fsubd T1(%pc),%fp0 | ...(|X|-16381LOG2_LEAD) 117*4882a593Smuzhiyun movel #0,-(%sp) 118*4882a593Smuzhiyun movel #0x80000000,-(%sp) 119*4882a593Smuzhiyun movel %a1,%d0 120*4882a593Smuzhiyun andl #0x80000000,%d0 121*4882a593Smuzhiyun orl #0x7FFB0000,%d0 122*4882a593Smuzhiyun movel %d0,-(%sp) | ...EXTENDED FMT 123*4882a593Smuzhiyun fsubd T2(%pc),%fp0 | ...|X| - 16381 LOG2, ACCURATE 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun movel %d1,-(%sp) 126*4882a593Smuzhiyun clrl %d1 127*4882a593Smuzhiyun fmovemx %fp0-%fp0,(%a0) 128*4882a593Smuzhiyun bsr setox 129*4882a593Smuzhiyun fmovel (%sp)+,%fpcr 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun fmulx (%sp)+,%fp0 |possible exception 132*4882a593Smuzhiyun bra t_frcinx 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun |end 135