windows-nt/Source/XPSP1/NT/base/crts/fpw32/tran/i386/87triga.asm
2020-09-26 16:20:57 +08:00

245 lines
6 KiB
NASM

page ,132
title 87triga - inverse trigonometric functions - ASIN, ACOS, ATAN
;***
;87triga.asm - inverse trigonometric functions - ASIN, ACOS, ATAN
;
; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
;
;Purpose:
; Routines for ASIN, ACOS, ATAN
;
;Revision History:
;
; 07/04/84 Greg Whitten
; initial version
;
; 10/01/84 Brad Verheiden
; Fixed bug in _rtforatnby0 which did not remove an
; element from the floating stack
;
; 10/28/85 Jamie Bariteau
; Added comment about inputs to fFATN2, made fFATN2
; public
; made _fFATN2 and _rtpiby2 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 -- Bug fix for atan(-INF)
;
; 03/27/92 GDP support underflow
;
; 01/03/96 JWM Modify return value of atan2(0,0)
;
; 05/10/00 GB Modify return value for atan2(-0.0, 1.0)
;
;*******************************************************************************
.xlist
include cruntime.inc
include mrt386.inc
include elem87.inc
.list
.data
extrn _indefinite:tbyte
extrn _piby2:tbyte
jmptab OP_ATAN2,5,<'atan2',0>,<0,0,0,0,0,0>,2
DNCPTR codeoffset fFATN2 ; 0000 NOS Valid non-0, TOS Valid non-0
DNCPTR codeoffset _rtforatnby0 ; 0001 NOS Valid non-0, TOS 0
DNCPTR codeoffset _tosnan2 ; 0010 NOS Valid non-0, TOS NAN
DNCPTR codeoffset _rtforatn20 ; 0011 NOS Valid non-0, TOS Inf
DNCPTR codeoffset _rtforatn20 ; 0100 NOS 0, TOS Valid non-0
DNCPTR codeoffset _rtforatn20 ; 0101 NOS 0, TOS 0
DNCPTR codeoffset _tosnan2 ; 0110 NOS 0, TOS NAN
DNCPTR codeoffset _rtforatn20 ; 0111 NOS 0, TOS Inf
DNCPTR codeoffset _nosnan2 ; 1000 NOS NAN, TOS Valid non-0
DNCPTR codeoffset _nosnan2 ; 1001 NOS NAN, TOS 0
DNCPTR codeoffset _nan2 ; 1010 NOS NAN, TOS NAN
DNCPTR codeoffset _nosnan2 ; 1011 NOS NAN, TOS Inf
DNCPTR codeoffset _rtforatnby0 ; 1100 NOS Inf, TOS Valid non-0
DNCPTR codeoffset _rtforatnby0 ; 1101 NOS Inf, TOS 0
DNCPTR codeoffset _tosnan2 ; 1110 NOS Inf, TOS NAN
DNCPTR codeoffset _rtindfpop ; 1111 NOS Inf, TOS Inf
page
CODESEG
extrn _rtchsifneg:near
extrn _rtindfpop:near
extrn _rtindfnpop:near
extrn _rtnospop:near
extrn _rtonenpop:near
extrn _rttospop:near
extrn _rttosnpop:near
extrn _rttosnpopde:near
extrn _rtzeronpop:near
extrn _tosnan1:near
extrn _tosnan2:near
extrn _nosnan2:near
extrn _nan2:near
;----------------------------------------------------------
;
; INVERSE TRIGONOMETRIC FUNCTIONS
;
;----------------------------------------------------------
;
; INPUTS - For single argument functions the argument
; is the stack top. For fFATN2 the numerator
; is next to stack top, the denominator is
; the stack top.
; For single argument functions the sign is
; in bit 2 of CL. For fFATN2 the numerator
; sign is bit 2 of CH, the denominator
; sign is bit 2 of CL.
;
; Note:
; _clog calls fFATN2 with the signs of the arguments
; in bit 0 of CL and CH respectively. This should
; work since fFATN2 tests for sign of numerator and
; denominator by using "or CL,CL" and "or CH,CH"
;
; OUTPUT - The result is the stack top
;
;----------------------------------------------------------
lab fFASN
call AugmentSinCos ; num.=arg, den.=sqrt(1-arg^2)
xchg ch, cl ; sign(num.)=sign(arg)
jmp short fFPATAN
lab fFACS
call AugmentSinCos ; num.=arg, den.=sqrt(1-arg^2)
fxch ; num.=sqrt(1-arg^2), den.=arg
jmp short fFPATAN
lab fFATN
fabs
fld1 ; denominator is 1
mov ch, cl
xor cl, cl ; sign of denominator is +ve
jmp short fFPATAN
labelNP _fFATN2, PUBLIC
lab fFATN2
mov DSF.ErrorType, CHECKRANGE ; indicate possible over/under flow on exit
fabs
fxch
fabs
fxch
lab fFPATAN
fpatan ; compute partial arctangent
or cl, cl ; if denominator was +ve
JSZ PatanNumeratorTest ; bypass -ve denominator adjust
fldpi
fsubrp st(1), st(0) ; change Patan to pi - Patan
lab PatanNumeratorTest
or ch, ch ; if numerator was +ve
JSZ PatanDone ; bypass -ve numerator adjust
fchs ; change Patan to -Patan
lab PatanDone
ret
page
lab AugmentSinCos
fabs ; NOS=x = |input|
fld st(0) ; NOS=x, TOS=x
fld st(0) ; NNOS=x, NOS=x, TOS=x
fld1 ; NNNOS=x, NNOS=x, NOS=x, TOS=1
fsubrp st(1),st(0) ; NNOS=x, NOS=x, TOS=1-x
fxch ; NNOS=x, NOS=1-x, TOS=x
fld1 ; NNNOS=x, NNOS=1-x, NOS=x, TOS=1
fadd ; NNOS=x, NOS=1-x, TOS=1+x
fmul ; NOS=x, TOS=1-x^2
ftst
fstsw DSF.StatusWord
fwait
test CondCode, 1 ; if 1-x^2 < 0
JSNZ DescriminantNeg ; return a NAN
xor ch, ch ; sign of TOS is +ve
fsqrt ; NOS=x, TOS=sqrt(1-x^2)
ret
lab DescriminantNeg
pop rax ; remove return address from stack
jmp _rtindfpop ; replace top of stack with a NAN
page
;----------------------------------------------------------
;
; SPECIAL CASE RETURN FUNCTIONS
;
;----------------------------------------------------------
;
; INPUTS - The signs of the last, second to last
; arguments are in CH, CL respectively.
;
; OUTPUT - The result is the stack top.
;
;----------------------------------------------------------
labelNP _rtpiby2, PUBLIC
fstp st(0) ; remove ST(0)
fld [_piby2] ; push pi/2 onto stack
ret
lab _rtforatn20
fstp st(0) ; remove ST(0)
or cl ,cl ; if denominator is +ve
JSZ zeronpop ; return zero
fstp st(0)
fldpi ; push pi onto stack
or ch, ch ; if numerator was +ve
JSZ postv
fchs
lab postv
ret
lab zeronpop
fstp st(0)
fldz ; push 0.0 onto stack
or ch, ch ; if numerator was +ve
JSZ postv
fchs
ret
lab _rtforatn200
lab indfpop
fstp st(0) ; remove ST(0)
lab indfnpop
jmp _rtindfnpop ; return real indefinite
lab _rtforatnby0
fstp st(0) ; remove an argument before returning
mov cl, ch ; cl is sign(TOS)
jmp short _rtsignpiby2
lab _rtforatninf
lab _rtsignpiby2
call _rtpiby2 ; push pi/2 onto stack
jmp _rtchsifneg ; return with sign change if negative
end