245 lines
6 KiB
NASM
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
|