File indexing completed on 2025-05-11 08:23:48
0001 #include "fpsp-namespace.h"
0002 //
0003 //
0004 // satanh.sa 3.3 12/19/90
0005 //
0006 // The entry point satanh computes the inverse
0007 // hyperbolic tangent of
0008 // an input argument; satanhd does the same except for denormalized
0009 // input.
0010 //
0011 // Input: Double-extended number X in location pointed to
0012 // by address register a0.
0013 //
0014 // Output: The value arctanh(X) returned in floating-point register Fp0.
0015 //
0016 // Accuracy and Monotonicity: The returned result is within 3 ulps in
0017 // 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
0018 // result is subsequently rounded to double precision. The
0019 // result is provably monotonic in double precision.
0020 //
0021 // Speed: The program satanh takes approximately 270 cycles.
0022 //
0023 // Algorithm:
0024 //
0025 // ATANH
0026 // 1. If |X| >= 1, go to 3.
0027 //
0028 // 2. (|X| < 1) Calculate atanh(X) by
0029 // sgn := sign(X)
0030 // y := |X|
0031 // z := 2y/(1-y)
0032 // atanh(X) := sgn * (1/2) * logp1(z)
0033 // Exit.
0034 //
0035 // 3. If |X| > 1, go to 5.
0036 //
0037 // 4. (|X| = 1) Generate infinity with an appropriate sign and
0038 // divide-by-zero by
0039 // sgn := sign(X)
0040 // atan(X) := sgn / (+0).
0041 // Exit.
0042 //
0043 // 5. (|X| > 1) Generate an invalid operation by 0 * infinity.
0044 // Exit.
0045 //
0046
0047 // Copyright (C) Motorola, Inc. 1990
0048 // All Rights Reserved
0049 //
0050 // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
0051 // The copyright notice above does not evidence any
0052 // actual or intended publication of such source code.
0053
0054 //satanh idnt 2,1 | Motorola 040 Floating Point Software Package
0055
0056 |section 8
0057
0058 |xref t_dz
0059 |xref t_operr
0060 |xref t_frcinx
0061 |xref t_extdnrm
0062 |xref slognp1
0063
0064 .global satanhd
0065 satanhd:
0066 //--ATANH(X) = X FOR DENORMALIZED X
0067
0068 bra t_extdnrm
0069
0070 .global satanh
0071 satanh:
0072 movel (%a0),%d0
0073 movew 4(%a0),%d0
0074 andil #0x7FFFFFFF,%d0
0075 cmpil #0x3FFF8000,%d0
0076 bges ATANHBIG
0077
0078 //--THIS IS THE USUAL CASE, |X| < 1
0079 //--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
0080
0081 fabsx (%a0),%fp0 // ...Y = |X|
0082 fmovex %fp0,%fp1
0083 fnegx %fp1 // ...-Y
0084 faddx %fp0,%fp0 // ...2Y
0085 fadds #0x3F800000,%fp1 // ...1-Y
0086 fdivx %fp1,%fp0 // ...2Y/(1-Y)
0087 movel (%a0),%d0
0088 andil #0x80000000,%d0
0089 oril #0x3F000000,%d0 // ...SIGN(X)*HALF
0090 movel %d0,-(%sp)
0091
0092 fmovemx %fp0-%fp0,(%a0) // ...overwrite input
0093 movel %d1,-(%sp)
0094 clrl %d1
0095 bsr slognp1 // ...LOG1P(Z)
0096 fmovel (%sp)+,%fpcr
0097 fmuls (%sp)+,%fp0
0098 bra t_frcinx
0099
0100 ATANHBIG:
0101 fabsx (%a0),%fp0 // ...|X|
0102 fcmps #0x3F800000,%fp0
0103 fbgt t_operr
0104 bra t_dz
0105
0106 |end