diff options
Diffstat (limited to 'c/src/lib/libcpu/m68k/m68040/fpsp/satanh.S')
-rw-r--r-- | c/src/lib/libcpu/m68k/m68040/fpsp/satanh.S | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/m68k/m68040/fpsp/satanh.S b/c/src/lib/libcpu/m68k/m68040/fpsp/satanh.S new file mode 100644 index 0000000000..592dfe7d1d --- /dev/null +++ b/c/src/lib/libcpu/m68k/m68040/fpsp/satanh.S @@ -0,0 +1,106 @@ +// +// $Id$ +// +// satanh.sa 3.3 12/19/90 +// +// The entry point satanh computes the inverse +// hyperbolic tangent of +// an input argument; satanhd does the same except for denormalized +// input. +// +// Input: Double-extended number X in location pointed to +// by address register a0. +// +// Output: The value arctanh(X) returned in floating-point register Fp0. +// +// Accuracy and Monotonicity: The returned result is within 3 ulps in +// 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the +// result is subsequently rounded to double precision. The +// result is provably monotonic in double precision. +// +// Speed: The program satanh takes approximately 270 cycles. +// +// Algorithm: +// +// ATANH +// 1. If |X| >= 1, go to 3. +// +// 2. (|X| < 1) Calculate atanh(X) by +// sgn := sign(X) +// y := |X| +// z := 2y/(1-y) +// atanh(X) := sgn * (1/2) * logp1(z) +// Exit. +// +// 3. If |X| > 1, go to 5. +// +// 4. (|X| = 1) Generate infinity with an appropriate sign and +// divide-by-zero by +// sgn := sign(X) +// atan(X) := sgn / (+0). +// Exit. +// +// 5. (|X| > 1) Generate an invalid operation by 0 * infinity. +// Exit. +// + +// Copyright (C) Motorola, Inc. 1990 +// All Rights Reserved +// +// THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA +// The copyright notice above does not evidence any +// actual or intended publication of such source code. + +//satanh idnt 2,1 | Motorola 040 Floating Point Software Package + + |section 8 + + |xref t_dz + |xref t_operr + |xref t_frcinx + |xref t_extdnrm + |xref slognp1 + + .global satanhd +satanhd: +//--ATANH(X) = X FOR DENORMALIZED X + + bra t_extdnrm + + .global satanh +satanh: + movel (%a0),%d0 + movew 4(%a0),%d0 + andil #0x7FFFFFFF,%d0 + cmpil #0x3FFF8000,%d0 + bges ATANHBIG + +//--THIS IS THE USUAL CASE, |X| < 1 +//--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z). + + fabsx (%a0),%fp0 // ...Y = |X| + fmovex %fp0,%fp1 + fnegx %fp1 // ...-Y + faddx %fp0,%fp0 // ...2Y + fadds #0x3F800000,%fp1 // ...1-Y + fdivx %fp1,%fp0 // ...2Y/(1-Y) + movel (%a0),%d0 + andil #0x80000000,%d0 + oril #0x3F000000,%d0 // ...SIGN(X)*HALF + movel %d0,-(%sp) + + fmovemx %fp0-%fp0,(%a0) // ...overwrite input + movel %d1,-(%sp) + clrl %d1 + bsr slognp1 // ...LOG1P(Z) + fmovel (%sp)+,%fpcr + fmuls (%sp)+,%fp0 + bra t_frcinx + +ATANHBIG: + fabsx (%a0),%fp0 // ...|X| + fcmps #0x3F800000,%fp0 + fbgt t_operr + bra t_dz + + |end |