summaryrefslogtreecommitdiff
path: root/arch/m68k/fpsp040/satanh.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/fpsp040/satanh.S')
-rw-r--r--arch/m68k/fpsp040/satanh.S104
1 files changed, 104 insertions, 0 deletions
diff --git a/arch/m68k/fpsp040/satanh.S b/arch/m68k/fpsp040/satanh.S
new file mode 100644
index 00000000000..20f07810bcd
--- /dev/null
+++ b/arch/m68k/fpsp040/satanh.S
@@ -0,0 +1,104 @@
+|
+| 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