windows-nt/Source/XPSP1/NT/base/crts/fpw32/tran/i386/87trigh.asm

218 lines
5.3 KiB
NASM
Raw Normal View History

2020-09-26 03:20:57 -05:00
page ,132
title 87trigh - hyperbolic trigonometric functions - SINH, COSH, TANH
;***
;87trigh.asm - hyperbolic trigonometric functions - SINH, COSH, TANH
;
; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
;
;Purpose:
; Routines for SINH, COSH, TANH
;
;Revision History:
;
; 07/04/84 Greg Whitten
; initial version
;
; 10/31/85 Jamie Bariteau
; made _fFSINH and _fFCOSH public labels
;
; 10/30/87 Bill Johnston
; Minor changes for new cmacros.
;
; 08/25/88 Bill Johnston
; 386 version.
;
; 02/10/92 Georgios Papagiannakopoulos
; NT port --used CHECKOVER for detection of overflow
;
;*******************************************************************************
.xlist
include cruntime.inc
include mrt386.inc
include elem87.inc
.list
.data
extrn _logemax:tbyte
extrn _infinity:tbyte
staticT _tanhmaxarg, 04003987E0C9996699000R
jmptab OP_SINH,4,<'sinh',0,0>,<0,0,0,0,0,0>,1
DNCPTR codeoffset fFSINH ; 0000 TOS Valid non-0
DNCPTR codeoffset _rttosnpop ; 0001 TOS 0
DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
DNCPTR codeoffset _rtforsnhinf ; 0011 TOS Inf
jmptab OP_COSH,4,<'cosh',0,0>,<0,0,0,0,0,0>,1
DNCPTR codeoffset fFCOSH ; 0000 TOS Valid non-0
DNCPTR codeoffset _rtonenpop ; 0001 TOS 0
DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
DNCPTR codeoffset _rtforcshinf ; 0011 TOS Inf
jmptab OP_TANH,4,<'tanh',0,0>,<0,0,0,0,0,0>,1
DNCPTR codeoffset fFTANH ; 0000 TOS Valid non-0
DNCPTR codeoffset _rttosnpop ; 0001 TOS 0
DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
DNCPTR codeoffset _rtfortnhinf ; 0011 TOS Inf
page
CODESEG
extrn _ffexpm1:near
extrn _rtchsifneg:near
extrn _rtindfnpop:near
extrn _rtinfnpop:near
extrn _rtonenpop:near
extrn _rttospop:near
extrn _rttosnpop:near
extrn _rttosnpopde:near
extrn _tosnan1:near
;----------------------------------------------------------
;
; HYPERBOLIC FUNCTIONS
;
;----------------------------------------------------------
;
; INPUTS - The argument is the stack top.
; The sign of the argument is bit 2 of CL.
;
; OUTPUT - The result is the stack top
;
;----------------------------------------------------------
labelNP _fFSINH, PUBLIC
lab fFSINH
mov DSF.ErrorType, CHECKOVER ; indicate possible overflow on exit
call fFEXPH ; compute e^x for hyperbolics
or bl, bl ; if e^x is infinite
JSZ _rtforsnhlarge ; return as if x = affine infinity
call ExpHypCopyInv ; TOS = e^(-x), NOS = e^x
fsubp st(1), st(0) ; compute e^x - e^(-x) for hyperbolics
jmp short SinhCoshReturn
lab fFTANH
fld st(0) ; copy TOS
fabs ; make TOS +ve
fld [_tanhmaxarg] ; get largest arg, roughly ln(2)(55)/2
fcompp
fstsw DSF.StatusWord
fwait
test CondCode, 041h ; if abs(arg) > XBIG (see tanh.h)
JSNZ _rtfortnhlarge ; return as if x = affine infinity
call fFEXPH ; compute e^x for hyperbolics
or bl, bl ; if e^x is infinite
JSZ _rtfortnhlarge ; return as if x = affine infinity
fld st(0) ; copy TOS
call ExpHypSum ; compute e^x + e^(-x) for hyperbolics
fxch ; get copy of e^x
call ExpHypCopyInv ; TOS = e^(-x), NOS = e^x
fsubp st(1), st(0) ; compute e^x - e^(-x) for hyperbolics
fdivrp st(1), st(0) ; now TOS = tanh(x)
ret
labelNP _fFCOSH, PUBLIC
lab fFCOSH
mov DSF.ErrorType, CHECKOVER ; indicate possible overflow on exit
call fFEXPH ; compute e^x for hyperbolics
or bl, bl ; if e^x is infinite
JSZ _rtforcnhlarge ; return as if x = affine infinity
call ExpHypSum ; compute e^x + e^(-x) for hyperbolics
lab SinhCoshReturn
fld1
fchs
fxch
fscale ; divide result by 2
jmp _rttospop
page
lab _rtforsnhinf
fstp st(0)
fld [_infinity]
jmp _rtchsifneg ; change sign if argument -ve
lab _rtforcshinf
fstp st(0)
fld [_infinity]
ret
lab infpositive
ret
lab _rtforsnhlarge
call _rtinfnpop ; TOS = infinity
lab chsifneg
jmp _rtchsifneg ; change sign if argument -ve
lab _rtforcnhlarge
jmp _rtinfnpop ; TOS = infinity
lab _rtfortnhlarge
mov DSF.ErrorType, INEXACT
lab _rtfortnhinf
call _rtonenpop ; TOS = one
jmp chsifneg ; change sign if argument -ve
page
lab fFEXPH
fldl2e
fmul ; convert log base e to log base 2
xor rbx, rbx ; clear e^x, finite result flags
call _ffexpm1 ; TOS = e^|x|-1 unscaled, NOS = scale
not bl ; set finite result flag
test CondCode, 1 ; if fraction > 0 (TOS > 0)
JSZ ExpHypNoInvert ; bypass e^x-1 invert
call ExpHypCopyInv ; TOS = e^(-x)-1, NOS = e^x-1
fxch
fstp st(0) ; remove NOS
lab ExpHypNoInvert
test dl, 040h ; if integer part was zero
JSNZ ExpHypScaled ; bypass scaling to avoid bug
not bh ; set e^x flag
fld1
fadd ; TOS = e^x unscaled
fscale ; now TOS = e^x
lab ExpHypScaled
jmp _rttospop ; TOS = e^x-1 or e^x scaled
lab ExpHypSum
call ExpHypCopyInv ; TOS = e^(-x), NOS = e^x
fadd ; TOS = e^x + e^(-x)
or bh, bh ; if e^x flag set
JSNZ ExpHypSumReturn ; bypass e^x-1 adjust
fld1
fadd st(1),st
fadd ; add 2 to result
lab ExpHypSumReturn
ret
lab ExpHypCopyInv
fld st(0) ; TOS = e^x (or e^x-1)
fld1 ; TOS = 1, NOS = e^x (or e^x-1)
or bh, bh ; if e^x flag set
JSNZ ExpHypCopyInvReturn ; bypass e^x-1 adjust
fadd st, st(1) ; TOS = e^x, NOS = e^x-1
fchs ; TOS = -e^x, NOS = e^x-1
fxch ; TOS = e^x-1, NOS = -e^x
lab ExpHypCopyInvReturn
fdivrp st(1), st(0) ; TOS = e^(-x) (or e^(-x)-1)
ret
end