1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
page ,132
title 87triga - inverse trigonometric functions - ASIN, ACOS, ATAN
;***
;87triga.asm - inverse trigonometric functions - ASIN, ACOS, ATAN
;
; Copyright (c) 1984-88, Microsoft Corporation
;
;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
;
;
;*******************************************************************************
.xlist
include cruntime.inc
include mrt386.inc
include elem87.inc
.list
.data
extrn _indefinite:tbyte
extrn _piby2:tbyte
jmptab OP_ASIN,4,<'asin',0,0>,<0,0,0,0,0,0>,1
DNCPTR codeoffset fFASN ; 0000 TOS Valid non-0
DNCPTR codeoffset _rttosnpop ; 0001 TOS 0
DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
DNCPTR codeoffset _rtindfnpop ; 0011 TOS Inf
jmptab OP_ACOS,4,<'acos',0,0>,<0,0,0,0,0,0>,1
DNCPTR codeoffset fFACS ; 0000 TOS Valid non-0
DNCPTR codeoffset _rtpiby2 ; 0001 TOS 0
DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
DNCPTR codeoffset _rtindfnpop ; 0011 TOS Inf
jmptab OP_ATAN,4,<'atan',0,0>,<0,0,0,0,0,0>,1
DNCPTR codeoffset fFATN ; 0000 TOS Valid non-0
DNCPTR codeoffset _rttosnpop ; 0001 TOS 0
DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
DNCPTR codeoffset _rtforatninf ; 0011 TOS Inf
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 _rtforatn200 ; 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
jmp _rtzeronpop ; return 0.0
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
|