Bell 32V development
[unix-history] / usr / src / libnm / tanh.s
# double tanh(arg)
# double arg
# method: tanh(arg)=sinh(arg)/cosh(arg); if |arg|<0.5 sinh(9 is computed from
# a polynomial approx otherwise from exp().
# Only 1 call to exp(9 is made.
# J F Jarvis, August 17, 1978
.globl _tanh
.globl _exp
.text
.align 1
_tanh:
.word 0x7c0
clrl r10 # sign bit
movd 4(ap),r6
jgeq t1
movw $0x8000,r10
xorw2 r10,r6 # co|arg|
t1: cmpd r6,$0d2.0e+1
jleq t2
movd $0d1.0e+0,r0
xorw2 r10,r0
ret
t2: movd r6,-(sp)
calls $2,_exp
movd r0,r8
divd3 r8,$0d1.0e+0,-(sp) # exp(-|arg|)
cmpd r6,$0d0.5e+0
jgeq t3
muld3 r6,r6,r0 # |arg|<0.5, sinh() from poly approx
polyd r0,$5,pcoef
muld2 r6,r0
muld2 $0d2.0e+0,r0
jbr t4
t3: subd3 (sp),r8,r0
t4: # r0,1 = 2*sinh(|arg|)
addd3 (sp),r8,r2 # r2,3 = cosh(|arg|);
divd2 r2,r0 # r0,1 = tanh(|arg|)
xorw2 r10,r0 # r0,1 = tanh(arg)
ret
.data
.align 3
pcoef:
.double 0d0.251726188251e-7
.double 0d0.275569807356154e-5
.double 0d0.1984127027907999e-3
.double 0d0.833333333307759961e-2
.double 0d0.16666666666667212324e+0
.double 0d0.99999999999999998116e+0