fplsp.s revision 1.1 1 1.1 is #
2 1.1 is # $NetBSD: fplsp.s,v 1.1 2000/04/14 20:24:37 is Exp $
3 1.1 is #
4 1.1 is
5 1.1 is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 1.1 is # MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
7 1.1 is # M68000 Hi-Performance Microprocessor Division
8 1.1 is # M68060 Software Package Production Release
9 1.1 is #
10 1.1 is # M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc.
11 1.1 is # All rights reserved.
12 1.1 is #
13 1.1 is # THE SOFTWARE is provided on an "AS IS" basis and without warranty.
14 1.1 is # To the maximum extent permitted by applicable law,
15 1.1 is # MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
16 1.1 is # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
17 1.1 is # FOR A PARTICULAR PURPOSE and any warranty against infringement with
18 1.1 is # regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
19 1.1 is # and any accompanying written materials.
20 1.1 is #
21 1.1 is # To the maximum extent permitted by applicable law,
22 1.1 is # IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
23 1.1 is # (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
24 1.1 is # BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
25 1.1 is # ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
26 1.1 is #
27 1.1 is # Motorola assumes no responsibility for the maintenance and support
28 1.1 is # of the SOFTWARE.
29 1.1 is #
30 1.1 is # You are hereby granted a copyright license to use, modify, and distribute the
31 1.1 is # SOFTWARE so long as this entire notice is retained without alteration
32 1.1 is # in any modified and/or redistributed versions, and that such modified
33 1.1 is # versions are clearly identified as such.
34 1.1 is # No licenses are granted by implication, estoppel or otherwise under any
35 1.1 is # patents or trademarks of Motorola, Inc.
36 1.1 is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 1.1 is
38 1.1 is #
39 1.1 is # lfptop.s:
40 1.1 is # This file is appended to the top of the 060ILSP package
41 1.1 is # and contains the entry points into the package. The user, in
42 1.1 is # effect, branches to one of the branch table entries located here.
43 1.1 is #
44 1.1 is
45 1.1 is bra.l _facoss_
46 1.1 is short 0x0000
47 1.1 is bra.l _facosd_
48 1.1 is short 0x0000
49 1.1 is bra.l _facosx_
50 1.1 is short 0x0000
51 1.1 is
52 1.1 is bra.l _fasins_
53 1.1 is short 0x0000
54 1.1 is bra.l _fasind_
55 1.1 is short 0x0000
56 1.1 is bra.l _fasinx_
57 1.1 is short 0x0000
58 1.1 is
59 1.1 is bra.l _fatans_
60 1.1 is short 0x0000
61 1.1 is bra.l _fatand_
62 1.1 is short 0x0000
63 1.1 is bra.l _fatanx_
64 1.1 is short 0x0000
65 1.1 is
66 1.1 is bra.l _fatanhs_
67 1.1 is short 0x0000
68 1.1 is bra.l _fatanhd_
69 1.1 is short 0x0000
70 1.1 is bra.l _fatanhx_
71 1.1 is short 0x0000
72 1.1 is
73 1.1 is bra.l _fcoss_
74 1.1 is short 0x0000
75 1.1 is bra.l _fcosd_
76 1.1 is short 0x0000
77 1.1 is bra.l _fcosx_
78 1.1 is short 0x0000
79 1.1 is
80 1.1 is bra.l _fcoshs_
81 1.1 is short 0x0000
82 1.1 is bra.l _fcoshd_
83 1.1 is short 0x0000
84 1.1 is bra.l _fcoshx_
85 1.1 is short 0x0000
86 1.1 is
87 1.1 is bra.l _fetoxs_
88 1.1 is short 0x0000
89 1.1 is bra.l _fetoxd_
90 1.1 is short 0x0000
91 1.1 is bra.l _fetoxx_
92 1.1 is short 0x0000
93 1.1 is
94 1.1 is bra.l _fetoxm1s_
95 1.1 is short 0x0000
96 1.1 is bra.l _fetoxm1d_
97 1.1 is short 0x0000
98 1.1 is bra.l _fetoxm1x_
99 1.1 is short 0x0000
100 1.1 is
101 1.1 is bra.l _fgetexps_
102 1.1 is short 0x0000
103 1.1 is bra.l _fgetexpd_
104 1.1 is short 0x0000
105 1.1 is bra.l _fgetexpx_
106 1.1 is short 0x0000
107 1.1 is
108 1.1 is bra.l _fgetmans_
109 1.1 is short 0x0000
110 1.1 is bra.l _fgetmand_
111 1.1 is short 0x0000
112 1.1 is bra.l _fgetmanx_
113 1.1 is short 0x0000
114 1.1 is
115 1.1 is bra.l _flog10s_
116 1.1 is short 0x0000
117 1.1 is bra.l _flog10d_
118 1.1 is short 0x0000
119 1.1 is bra.l _flog10x_
120 1.1 is short 0x0000
121 1.1 is
122 1.1 is bra.l _flog2s_
123 1.1 is short 0x0000
124 1.1 is bra.l _flog2d_
125 1.1 is short 0x0000
126 1.1 is bra.l _flog2x_
127 1.1 is short 0x0000
128 1.1 is
129 1.1 is bra.l _flogns_
130 1.1 is short 0x0000
131 1.1 is bra.l _flognd_
132 1.1 is short 0x0000
133 1.1 is bra.l _flognx_
134 1.1 is short 0x0000
135 1.1 is
136 1.1 is bra.l _flognp1s_
137 1.1 is short 0x0000
138 1.1 is bra.l _flognp1d_
139 1.1 is short 0x0000
140 1.1 is bra.l _flognp1x_
141 1.1 is short 0x0000
142 1.1 is
143 1.1 is bra.l _fmods_
144 1.1 is short 0x0000
145 1.1 is bra.l _fmodd_
146 1.1 is short 0x0000
147 1.1 is bra.l _fmodx_
148 1.1 is short 0x0000
149 1.1 is
150 1.1 is bra.l _frems_
151 1.1 is short 0x0000
152 1.1 is bra.l _fremd_
153 1.1 is short 0x0000
154 1.1 is bra.l _fremx_
155 1.1 is short 0x0000
156 1.1 is
157 1.1 is bra.l _fscales_
158 1.1 is short 0x0000
159 1.1 is bra.l _fscaled_
160 1.1 is short 0x0000
161 1.1 is bra.l _fscalex_
162 1.1 is short 0x0000
163 1.1 is
164 1.1 is bra.l _fsins_
165 1.1 is short 0x0000
166 1.1 is bra.l _fsind_
167 1.1 is short 0x0000
168 1.1 is bra.l _fsinx_
169 1.1 is short 0x0000
170 1.1 is
171 1.1 is bra.l _fsincoss_
172 1.1 is short 0x0000
173 1.1 is bra.l _fsincosd_
174 1.1 is short 0x0000
175 1.1 is bra.l _fsincosx_
176 1.1 is short 0x0000
177 1.1 is
178 1.1 is bra.l _fsinhs_
179 1.1 is short 0x0000
180 1.1 is bra.l _fsinhd_
181 1.1 is short 0x0000
182 1.1 is bra.l _fsinhx_
183 1.1 is short 0x0000
184 1.1 is
185 1.1 is bra.l _ftans_
186 1.1 is short 0x0000
187 1.1 is bra.l _ftand_
188 1.1 is short 0x0000
189 1.1 is bra.l _ftanx_
190 1.1 is short 0x0000
191 1.1 is
192 1.1 is bra.l _ftanhs_
193 1.1 is short 0x0000
194 1.1 is bra.l _ftanhd_
195 1.1 is short 0x0000
196 1.1 is bra.l _ftanhx_
197 1.1 is short 0x0000
198 1.1 is
199 1.1 is bra.l _ftentoxs_
200 1.1 is short 0x0000
201 1.1 is bra.l _ftentoxd_
202 1.1 is short 0x0000
203 1.1 is bra.l _ftentoxx_
204 1.1 is short 0x0000
205 1.1 is
206 1.1 is bra.l _ftwotoxs_
207 1.1 is short 0x0000
208 1.1 is bra.l _ftwotoxd_
209 1.1 is short 0x0000
210 1.1 is bra.l _ftwotoxx_
211 1.1 is short 0x0000
212 1.1 is
213 1.1 is bra.l _fabss_
214 1.1 is short 0x0000
215 1.1 is bra.l _fabsd_
216 1.1 is short 0x0000
217 1.1 is bra.l _fabsx_
218 1.1 is short 0x0000
219 1.1 is
220 1.1 is bra.l _fadds_
221 1.1 is short 0x0000
222 1.1 is bra.l _faddd_
223 1.1 is short 0x0000
224 1.1 is bra.l _faddx_
225 1.1 is short 0x0000
226 1.1 is
227 1.1 is bra.l _fdivs_
228 1.1 is short 0x0000
229 1.1 is bra.l _fdivd_
230 1.1 is short 0x0000
231 1.1 is bra.l _fdivx_
232 1.1 is short 0x0000
233 1.1 is
234 1.1 is bra.l _fints_
235 1.1 is short 0x0000
236 1.1 is bra.l _fintd_
237 1.1 is short 0x0000
238 1.1 is bra.l _fintx_
239 1.1 is short 0x0000
240 1.1 is
241 1.1 is bra.l _fintrzs_
242 1.1 is short 0x0000
243 1.1 is bra.l _fintrzd_
244 1.1 is short 0x0000
245 1.1 is bra.l _fintrzx_
246 1.1 is short 0x0000
247 1.1 is
248 1.1 is bra.l _fmuls_
249 1.1 is short 0x0000
250 1.1 is bra.l _fmuld_
251 1.1 is short 0x0000
252 1.1 is bra.l _fmulx_
253 1.1 is short 0x0000
254 1.1 is
255 1.1 is bra.l _fnegs_
256 1.1 is short 0x0000
257 1.1 is bra.l _fnegd_
258 1.1 is short 0x0000
259 1.1 is bra.l _fnegx_
260 1.1 is short 0x0000
261 1.1 is
262 1.1 is bra.l _fsqrts_
263 1.1 is short 0x0000
264 1.1 is bra.l _fsqrtd_
265 1.1 is short 0x0000
266 1.1 is bra.l _fsqrtx_
267 1.1 is short 0x0000
268 1.1 is
269 1.1 is bra.l _fsubs_
270 1.1 is short 0x0000
271 1.1 is bra.l _fsubd_
272 1.1 is short 0x0000
273 1.1 is bra.l _fsubx_
274 1.1 is short 0x0000
275 1.1 is
276 1.1 is # leave room for future possible additions
277 1.1 is align 0x400
278 1.1 is
279 1.1 is #
280 1.1 is # This file contains a set of define statements for constants
281 1.1 is # in order to promote readability within the corecode itself.
282 1.1 is #
283 1.1 is
284 1.1 is set LOCAL_SIZE, 192 # stack frame size(bytes)
285 1.1 is set LV, -LOCAL_SIZE # stack offset
286 1.1 is
287 1.1 is set EXC_SR, 0x4 # stack status register
288 1.1 is set EXC_PC, 0x6 # stack pc
289 1.1 is set EXC_VOFF, 0xa # stacked vector offset
290 1.1 is set EXC_EA, 0xc # stacked <ea>
291 1.1 is
292 1.1 is set EXC_FP, 0x0 # frame pointer
293 1.1 is
294 1.1 is set EXC_AREGS, -68 # offset of all address regs
295 1.1 is set EXC_DREGS, -100 # offset of all data regs
296 1.1 is set EXC_FPREGS, -36 # offset of all fp regs
297 1.1 is
298 1.1 is set EXC_A7, EXC_AREGS+(7*4) # offset of saved a7
299 1.1 is set OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7
300 1.1 is set EXC_A6, EXC_AREGS+(6*4) # offset of saved a6
301 1.1 is set EXC_A5, EXC_AREGS+(5*4)
302 1.1 is set EXC_A4, EXC_AREGS+(4*4)
303 1.1 is set EXC_A3, EXC_AREGS+(3*4)
304 1.1 is set EXC_A2, EXC_AREGS+(2*4)
305 1.1 is set EXC_A1, EXC_AREGS+(1*4)
306 1.1 is set EXC_A0, EXC_AREGS+(0*4)
307 1.1 is set EXC_D7, EXC_DREGS+(7*4)
308 1.1 is set EXC_D6, EXC_DREGS+(6*4)
309 1.1 is set EXC_D5, EXC_DREGS+(5*4)
310 1.1 is set EXC_D4, EXC_DREGS+(4*4)
311 1.1 is set EXC_D3, EXC_DREGS+(3*4)
312 1.1 is set EXC_D2, EXC_DREGS+(2*4)
313 1.1 is set EXC_D1, EXC_DREGS+(1*4)
314 1.1 is set EXC_D0, EXC_DREGS+(0*4)
315 1.1 is
316 1.1 is set EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0
317 1.1 is set EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1
318 1.1 is set EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used)
319 1.1 is
320 1.1 is set FP_SCR1, LV+80 # fp scratch 1
321 1.1 is set FP_SCR1_EX, FP_SCR1+0
322 1.1 is set FP_SCR1_SGN, FP_SCR1+2
323 1.1 is set FP_SCR1_HI, FP_SCR1+4
324 1.1 is set FP_SCR1_LO, FP_SCR1+8
325 1.1 is
326 1.1 is set FP_SCR0, LV+68 # fp scratch 0
327 1.1 is set FP_SCR0_EX, FP_SCR0+0
328 1.1 is set FP_SCR0_SGN, FP_SCR0+2
329 1.1 is set FP_SCR0_HI, FP_SCR0+4
330 1.1 is set FP_SCR0_LO, FP_SCR0+8
331 1.1 is
332 1.1 is set FP_DST, LV+56 # fp destination operand
333 1.1 is set FP_DST_EX, FP_DST+0
334 1.1 is set FP_DST_SGN, FP_DST+2
335 1.1 is set FP_DST_HI, FP_DST+4
336 1.1 is set FP_DST_LO, FP_DST+8
337 1.1 is
338 1.1 is set FP_SRC, LV+44 # fp source operand
339 1.1 is set FP_SRC_EX, FP_SRC+0
340 1.1 is set FP_SRC_SGN, FP_SRC+2
341 1.1 is set FP_SRC_HI, FP_SRC+4
342 1.1 is set FP_SRC_LO, FP_SRC+8
343 1.1 is
344 1.1 is set USER_FPIAR, LV+40 # FP instr address register
345 1.1 is
346 1.1 is set USER_FPSR, LV+36 # FP status register
347 1.1 is set FPSR_CC, USER_FPSR+0 # FPSR condition codes
348 1.1 is set FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte
349 1.1 is set FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte
350 1.1 is set FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte
351 1.1 is
352 1.1 is set USER_FPCR, LV+32 # FP control register
353 1.1 is set FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable
354 1.1 is set FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control
355 1.1 is
356 1.1 is set L_SCR3, LV+28 # integer scratch 3
357 1.1 is set L_SCR2, LV+24 # integer scratch 2
358 1.1 is set L_SCR1, LV+20 # integer scratch 1
359 1.1 is
360 1.1 is set STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst)
361 1.1 is
362 1.1 is set EXC_TEMP2, LV+24 # temporary space
363 1.1 is set EXC_TEMP, LV+16 # temporary space
364 1.1 is
365 1.1 is set DTAG, LV+15 # destination operand type
366 1.1 is set STAG, LV+14 # source operand type
367 1.1 is
368 1.1 is set SPCOND_FLG, LV+10 # flag: special case (see below)
369 1.1 is
370 1.1 is set EXC_CC, LV+8 # saved condition codes
371 1.1 is set EXC_EXTWPTR, LV+4 # saved current PC (active)
372 1.1 is set EXC_EXTWORD, LV+2 # saved extension word
373 1.1 is set EXC_CMDREG, LV+2 # saved extension word
374 1.1 is set EXC_OPWORD, LV+0 # saved operation word
375 1.1 is
376 1.1 is ################################
377 1.1 is
378 1.1 is # Helpful macros
379 1.1 is
380 1.1 is set FTEMP, 0 # offsets within an
381 1.1 is set FTEMP_EX, 0 # extended precision
382 1.1 is set FTEMP_SGN, 2 # value saved in memory.
383 1.1 is set FTEMP_HI, 4
384 1.1 is set FTEMP_LO, 8
385 1.1 is set FTEMP_GRS, 12
386 1.1 is
387 1.1 is set LOCAL, 0 # offsets within an
388 1.1 is set LOCAL_EX, 0 # extended precision
389 1.1 is set LOCAL_SGN, 2 # value saved in memory.
390 1.1 is set LOCAL_HI, 4
391 1.1 is set LOCAL_LO, 8
392 1.1 is set LOCAL_GRS, 12
393 1.1 is
394 1.1 is set DST, 0 # offsets within an
395 1.1 is set DST_EX, 0 # extended precision
396 1.1 is set DST_HI, 4 # value saved in memory.
397 1.1 is set DST_LO, 8
398 1.1 is
399 1.1 is set SRC, 0 # offsets within an
400 1.1 is set SRC_EX, 0 # extended precision
401 1.1 is set SRC_HI, 4 # value saved in memory.
402 1.1 is set SRC_LO, 8
403 1.1 is
404 1.1 is set SGL_LO, 0x3f81 # min sgl prec exponent
405 1.1 is set SGL_HI, 0x407e # max sgl prec exponent
406 1.1 is set DBL_LO, 0x3c01 # min dbl prec exponent
407 1.1 is set DBL_HI, 0x43fe # max dbl prec exponent
408 1.1 is set EXT_LO, 0x0 # min ext prec exponent
409 1.1 is set EXT_HI, 0x7ffe # max ext prec exponent
410 1.1 is
411 1.1 is set EXT_BIAS, 0x3fff # extended precision bias
412 1.1 is set SGL_BIAS, 0x007f # single precision bias
413 1.1 is set DBL_BIAS, 0x03ff # double precision bias
414 1.1 is
415 1.1 is set NORM, 0x00 # operand type for STAG/DTAG
416 1.1 is set ZERO, 0x01 # operand type for STAG/DTAG
417 1.1 is set INF, 0x02 # operand type for STAG/DTAG
418 1.1 is set QNAN, 0x03 # operand type for STAG/DTAG
419 1.1 is set DENORM, 0x04 # operand type for STAG/DTAG
420 1.1 is set SNAN, 0x05 # operand type for STAG/DTAG
421 1.1 is set UNNORM, 0x06 # operand type for STAG/DTAG
422 1.1 is
423 1.1 is ##################
424 1.1 is # FPSR/FPCR bits #
425 1.1 is ##################
426 1.1 is set neg_bit, 0x3 # negative result
427 1.1 is set z_bit, 0x2 # zero result
428 1.1 is set inf_bit, 0x1 # infinite result
429 1.1 is set nan_bit, 0x0 # NAN result
430 1.1 is
431 1.1 is set q_sn_bit, 0x7 # sign bit of quotient byte
432 1.1 is
433 1.1 is set bsun_bit, 7 # branch on unordered
434 1.1 is set snan_bit, 6 # signalling NAN
435 1.1 is set operr_bit, 5 # operand error
436 1.1 is set ovfl_bit, 4 # overflow
437 1.1 is set unfl_bit, 3 # underflow
438 1.1 is set dz_bit, 2 # divide by zero
439 1.1 is set inex2_bit, 1 # inexact result 2
440 1.1 is set inex1_bit, 0 # inexact result 1
441 1.1 is
442 1.1 is set aiop_bit, 7 # accrued inexact operation bit
443 1.1 is set aovfl_bit, 6 # accrued overflow bit
444 1.1 is set aunfl_bit, 5 # accrued underflow bit
445 1.1 is set adz_bit, 4 # accrued dz bit
446 1.1 is set ainex_bit, 3 # accrued inexact bit
447 1.1 is
448 1.1 is #############################
449 1.1 is # FPSR individual bit masks #
450 1.1 is #############################
451 1.1 is set neg_mask, 0x08000000 # negative bit mask (lw)
452 1.1 is set inf_mask, 0x02000000 # infinity bit mask (lw)
453 1.1 is set z_mask, 0x04000000 # zero bit mask (lw)
454 1.1 is set nan_mask, 0x01000000 # nan bit mask (lw)
455 1.1 is
456 1.1 is set neg_bmask, 0x08 # negative bit mask (byte)
457 1.1 is set inf_bmask, 0x02 # infinity bit mask (byte)
458 1.1 is set z_bmask, 0x04 # zero bit mask (byte)
459 1.1 is set nan_bmask, 0x01 # nan bit mask (byte)
460 1.1 is
461 1.1 is set bsun_mask, 0x00008000 # bsun exception mask
462 1.1 is set snan_mask, 0x00004000 # snan exception mask
463 1.1 is set operr_mask, 0x00002000 # operr exception mask
464 1.1 is set ovfl_mask, 0x00001000 # overflow exception mask
465 1.1 is set unfl_mask, 0x00000800 # underflow exception mask
466 1.1 is set dz_mask, 0x00000400 # dz exception mask
467 1.1 is set inex2_mask, 0x00000200 # inex2 exception mask
468 1.1 is set inex1_mask, 0x00000100 # inex1 exception mask
469 1.1 is
470 1.1 is set aiop_mask, 0x00000080 # accrued illegal operation
471 1.1 is set aovfl_mask, 0x00000040 # accrued overflow
472 1.1 is set aunfl_mask, 0x00000020 # accrued underflow
473 1.1 is set adz_mask, 0x00000010 # accrued divide by zero
474 1.1 is set ainex_mask, 0x00000008 # accrued inexact
475 1.1 is
476 1.1 is ######################################
477 1.1 is # FPSR combinations used in the FPSP #
478 1.1 is ######################################
479 1.1 is set dzinf_mask, inf_mask+dz_mask+adz_mask
480 1.1 is set opnan_mask, nan_mask+operr_mask+aiop_mask
481 1.1 is set nzi_mask, 0x01ffffff #clears N, Z, and I
482 1.1 is set unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask
483 1.1 is set unf2inx_mask, unfl_mask+inex2_mask+ainex_mask
484 1.1 is set ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
485 1.1 is set inx1a_mask, inex1_mask+ainex_mask
486 1.1 is set inx2a_mask, inex2_mask+ainex_mask
487 1.1 is set snaniop_mask, nan_mask+snan_mask+aiop_mask
488 1.1 is set snaniop2_mask, snan_mask+aiop_mask
489 1.1 is set naniop_mask, nan_mask+aiop_mask
490 1.1 is set neginf_mask, neg_mask+inf_mask
491 1.1 is set infaiop_mask, inf_mask+aiop_mask
492 1.1 is set negz_mask, neg_mask+z_mask
493 1.1 is set opaop_mask, operr_mask+aiop_mask
494 1.1 is set unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask
495 1.1 is set ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask
496 1.1 is
497 1.1 is #########
498 1.1 is # misc. #
499 1.1 is #########
500 1.1 is set rnd_stky_bit, 29 # stky bit pos in longword
501 1.1 is
502 1.1 is set sign_bit, 0x7 # sign bit
503 1.1 is set signan_bit, 0x6 # signalling nan bit
504 1.1 is
505 1.1 is set sgl_thresh, 0x3f81 # minimum sgl exponent
506 1.1 is set dbl_thresh, 0x3c01 # minimum dbl exponent
507 1.1 is
508 1.1 is set x_mode, 0x0 # extended precision
509 1.1 is set s_mode, 0x4 # single precision
510 1.1 is set d_mode, 0x8 # double precision
511 1.1 is
512 1.1 is set rn_mode, 0x0 # round-to-nearest
513 1.1 is set rz_mode, 0x1 # round-to-zero
514 1.1 is set rm_mode, 0x2 # round-tp-minus-infinity
515 1.1 is set rp_mode, 0x3 # round-to-plus-infinity
516 1.1 is
517 1.1 is set mantissalen, 64 # length of mantissa in bits
518 1.1 is
519 1.1 is set BYTE, 1 # len(byte) == 1 byte
520 1.1 is set WORD, 2 # len(word) == 2 bytes
521 1.1 is set LONG, 4 # len(longword) == 2 bytes
522 1.1 is
523 1.1 is set BSUN_VEC, 0xc0 # bsun vector offset
524 1.1 is set INEX_VEC, 0xc4 # inexact vector offset
525 1.1 is set DZ_VEC, 0xc8 # dz vector offset
526 1.1 is set UNFL_VEC, 0xcc # unfl vector offset
527 1.1 is set OPERR_VEC, 0xd0 # operr vector offset
528 1.1 is set OVFL_VEC, 0xd4 # ovfl vector offset
529 1.1 is set SNAN_VEC, 0xd8 # snan vector offset
530 1.1 is
531 1.1 is ###########################
532 1.1 is # SPecial CONDition FLaGs #
533 1.1 is ###########################
534 1.1 is set ftrapcc_flg, 0x01 # flag bit: ftrapcc exception
535 1.1 is set fbsun_flg, 0x02 # flag bit: bsun exception
536 1.1 is set mia7_flg, 0x04 # flag bit: (a7)+ <ea>
537 1.1 is set mda7_flg, 0x08 # flag bit: -(a7) <ea>
538 1.1 is set fmovm_flg, 0x40 # flag bit: fmovm instruction
539 1.1 is set immed_flg, 0x80 # flag bit: &<data> <ea>
540 1.1 is
541 1.1 is set ftrapcc_bit, 0x0
542 1.1 is set fbsun_bit, 0x1
543 1.1 is set mia7_bit, 0x2
544 1.1 is set mda7_bit, 0x3
545 1.1 is set immed_bit, 0x7
546 1.1 is
547 1.1 is ##################################
548 1.1 is # TRANSCENDENTAL "LAST-OP" FLAGS #
549 1.1 is ##################################
550 1.1 is set FMUL_OP, 0x0 # fmul instr performed last
551 1.1 is set FDIV_OP, 0x1 # fdiv performed last
552 1.1 is set FADD_OP, 0x2 # fadd performed last
553 1.1 is set FMOV_OP, 0x3 # fmov performed last
554 1.1 is
555 1.1 is #############
556 1.1 is # CONSTANTS #
557 1.1 is #############
558 1.1 is T1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD
559 1.1 is T2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL
560 1.1 is
561 1.1 is PI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000
562 1.1 is PIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
563 1.1 is
564 1.1 is TWOBYPI:
565 1.1 is long 0x3FE45F30,0x6DC9C883
566 1.1 is
567 1.1 is #########################################################################
568 1.1 is # MONADIC TEMPLATE #
569 1.1 is #########################################################################
570 1.1 is global _fsins_
571 1.1 is _fsins_:
572 1.1 is link %a6,&-LOCAL_SIZE
573 1.1 is
574 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
575 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
576 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
577 1.1 is
578 1.1 is fmov.l &0x0,%fpcr # zero FPCR
579 1.1 is
580 1.1 is #
581 1.1 is # copy, convert, and tag input argument
582 1.1 is #
583 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
584 1.1 is fmov.x %fp0,FP_SRC(%a6)
585 1.1 is lea FP_SRC(%a6),%a0
586 1.1 is bsr.l tag # fetch operand type
587 1.1 is mov.b %d0,STAG(%a6)
588 1.1 is mov.b %d0,%d1
589 1.1 is
590 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
591 1.1 is
592 1.1 is clr.l %d0
593 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
594 1.1 is
595 1.1 is tst.b %d1
596 1.1 is bne.b _L0_2s
597 1.1 is bsr.l ssin # operand is a NORM
598 1.1 is bra.b _L0_6s
599 1.1 is _L0_2s:
600 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
601 1.1 is bne.b _L0_3s # no
602 1.1 is bsr.l src_zero # yes
603 1.1 is bra.b _L0_6s
604 1.1 is _L0_3s:
605 1.1 is cmpi.b %d1,&INF # is operand an INF?
606 1.1 is bne.b _L0_4s # no
607 1.1 is bsr.l t_operr # yes
608 1.1 is bra.b _L0_6s
609 1.1 is _L0_4s:
610 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
611 1.1 is bne.b _L0_5s # no
612 1.1 is bsr.l src_qnan # yes
613 1.1 is bra.b _L0_6s
614 1.1 is _L0_5s:
615 1.1 is bsr.l ssind # operand is a DENORM
616 1.1 is _L0_6s:
617 1.1 is
618 1.1 is #
619 1.1 is # Result is now in FP0
620 1.1 is #
621 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
622 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
623 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
624 1.1 is unlk %a6
625 1.1 is rts
626 1.1 is
627 1.1 is global _fsind_
628 1.1 is _fsind_:
629 1.1 is link %a6,&-LOCAL_SIZE
630 1.1 is
631 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
632 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
633 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
634 1.1 is
635 1.1 is fmov.l &0x0,%fpcr # zero FPCR
636 1.1 is
637 1.1 is #
638 1.1 is # copy, convert, and tag input argument
639 1.1 is #
640 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
641 1.1 is fmov.x %fp0,FP_SRC(%a6)
642 1.1 is lea FP_SRC(%a6),%a0
643 1.1 is bsr.l tag # fetch operand type
644 1.1 is mov.b %d0,STAG(%a6)
645 1.1 is mov.b %d0,%d1
646 1.1 is
647 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
648 1.1 is
649 1.1 is clr.l %d0
650 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
651 1.1 is
652 1.1 is mov.b %d1,STAG(%a6)
653 1.1 is tst.b %d1
654 1.1 is bne.b _L0_2d
655 1.1 is bsr.l ssin # operand is a NORM
656 1.1 is bra.b _L0_6d
657 1.1 is _L0_2d:
658 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
659 1.1 is bne.b _L0_3d # no
660 1.1 is bsr.l src_zero # yes
661 1.1 is bra.b _L0_6d
662 1.1 is _L0_3d:
663 1.1 is cmpi.b %d1,&INF # is operand an INF?
664 1.1 is bne.b _L0_4d # no
665 1.1 is bsr.l t_operr # yes
666 1.1 is bra.b _L0_6d
667 1.1 is _L0_4d:
668 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
669 1.1 is bne.b _L0_5d # no
670 1.1 is bsr.l src_qnan # yes
671 1.1 is bra.b _L0_6d
672 1.1 is _L0_5d:
673 1.1 is bsr.l ssind # operand is a DENORM
674 1.1 is _L0_6d:
675 1.1 is
676 1.1 is #
677 1.1 is # Result is now in FP0
678 1.1 is #
679 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
680 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
681 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
682 1.1 is unlk %a6
683 1.1 is rts
684 1.1 is
685 1.1 is global _fsinx_
686 1.1 is _fsinx_:
687 1.1 is link %a6,&-LOCAL_SIZE
688 1.1 is
689 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
690 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
691 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
692 1.1 is
693 1.1 is fmov.l &0x0,%fpcr # zero FPCR
694 1.1 is
695 1.1 is #
696 1.1 is # copy, convert, and tag input argument
697 1.1 is #
698 1.1 is lea FP_SRC(%a6),%a0
699 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
700 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
701 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
702 1.1 is bsr.l tag # fetch operand type
703 1.1 is mov.b %d0,STAG(%a6)
704 1.1 is mov.b %d0,%d1
705 1.1 is
706 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
707 1.1 is
708 1.1 is clr.l %d0
709 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
710 1.1 is
711 1.1 is tst.b %d1
712 1.1 is bne.b _L0_2x
713 1.1 is bsr.l ssin # operand is a NORM
714 1.1 is bra.b _L0_6x
715 1.1 is _L0_2x:
716 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
717 1.1 is bne.b _L0_3x # no
718 1.1 is bsr.l src_zero # yes
719 1.1 is bra.b _L0_6x
720 1.1 is _L0_3x:
721 1.1 is cmpi.b %d1,&INF # is operand an INF?
722 1.1 is bne.b _L0_4x # no
723 1.1 is bsr.l t_operr # yes
724 1.1 is bra.b _L0_6x
725 1.1 is _L0_4x:
726 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
727 1.1 is bne.b _L0_5x # no
728 1.1 is bsr.l src_qnan # yes
729 1.1 is bra.b _L0_6x
730 1.1 is _L0_5x:
731 1.1 is bsr.l ssind # operand is a DENORM
732 1.1 is _L0_6x:
733 1.1 is
734 1.1 is #
735 1.1 is # Result is now in FP0
736 1.1 is #
737 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
738 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
739 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
740 1.1 is unlk %a6
741 1.1 is rts
742 1.1 is
743 1.1 is
744 1.1 is #########################################################################
745 1.1 is # MONADIC TEMPLATE #
746 1.1 is #########################################################################
747 1.1 is global _fcoss_
748 1.1 is _fcoss_:
749 1.1 is link %a6,&-LOCAL_SIZE
750 1.1 is
751 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
752 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
753 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
754 1.1 is
755 1.1 is fmov.l &0x0,%fpcr # zero FPCR
756 1.1 is
757 1.1 is #
758 1.1 is # copy, convert, and tag input argument
759 1.1 is #
760 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
761 1.1 is fmov.x %fp0,FP_SRC(%a6)
762 1.1 is lea FP_SRC(%a6),%a0
763 1.1 is bsr.l tag # fetch operand type
764 1.1 is mov.b %d0,STAG(%a6)
765 1.1 is mov.b %d0,%d1
766 1.1 is
767 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
768 1.1 is
769 1.1 is clr.l %d0
770 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
771 1.1 is
772 1.1 is tst.b %d1
773 1.1 is bne.b _L1_2s
774 1.1 is bsr.l scos # operand is a NORM
775 1.1 is bra.b _L1_6s
776 1.1 is _L1_2s:
777 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
778 1.1 is bne.b _L1_3s # no
779 1.1 is bsr.l ld_pone # yes
780 1.1 is bra.b _L1_6s
781 1.1 is _L1_3s:
782 1.1 is cmpi.b %d1,&INF # is operand an INF?
783 1.1 is bne.b _L1_4s # no
784 1.1 is bsr.l t_operr # yes
785 1.1 is bra.b _L1_6s
786 1.1 is _L1_4s:
787 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
788 1.1 is bne.b _L1_5s # no
789 1.1 is bsr.l src_qnan # yes
790 1.1 is bra.b _L1_6s
791 1.1 is _L1_5s:
792 1.1 is bsr.l scosd # operand is a DENORM
793 1.1 is _L1_6s:
794 1.1 is
795 1.1 is #
796 1.1 is # Result is now in FP0
797 1.1 is #
798 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
799 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
800 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
801 1.1 is unlk %a6
802 1.1 is rts
803 1.1 is
804 1.1 is global _fcosd_
805 1.1 is _fcosd_:
806 1.1 is link %a6,&-LOCAL_SIZE
807 1.1 is
808 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
809 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
810 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
811 1.1 is
812 1.1 is fmov.l &0x0,%fpcr # zero FPCR
813 1.1 is
814 1.1 is #
815 1.1 is # copy, convert, and tag input argument
816 1.1 is #
817 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
818 1.1 is fmov.x %fp0,FP_SRC(%a6)
819 1.1 is lea FP_SRC(%a6),%a0
820 1.1 is bsr.l tag # fetch operand type
821 1.1 is mov.b %d0,STAG(%a6)
822 1.1 is mov.b %d0,%d1
823 1.1 is
824 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
825 1.1 is
826 1.1 is clr.l %d0
827 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
828 1.1 is
829 1.1 is mov.b %d1,STAG(%a6)
830 1.1 is tst.b %d1
831 1.1 is bne.b _L1_2d
832 1.1 is bsr.l scos # operand is a NORM
833 1.1 is bra.b _L1_6d
834 1.1 is _L1_2d:
835 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
836 1.1 is bne.b _L1_3d # no
837 1.1 is bsr.l ld_pone # yes
838 1.1 is bra.b _L1_6d
839 1.1 is _L1_3d:
840 1.1 is cmpi.b %d1,&INF # is operand an INF?
841 1.1 is bne.b _L1_4d # no
842 1.1 is bsr.l t_operr # yes
843 1.1 is bra.b _L1_6d
844 1.1 is _L1_4d:
845 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
846 1.1 is bne.b _L1_5d # no
847 1.1 is bsr.l src_qnan # yes
848 1.1 is bra.b _L1_6d
849 1.1 is _L1_5d:
850 1.1 is bsr.l scosd # operand is a DENORM
851 1.1 is _L1_6d:
852 1.1 is
853 1.1 is #
854 1.1 is # Result is now in FP0
855 1.1 is #
856 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
857 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
858 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
859 1.1 is unlk %a6
860 1.1 is rts
861 1.1 is
862 1.1 is global _fcosx_
863 1.1 is _fcosx_:
864 1.1 is link %a6,&-LOCAL_SIZE
865 1.1 is
866 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
867 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
868 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
869 1.1 is
870 1.1 is fmov.l &0x0,%fpcr # zero FPCR
871 1.1 is
872 1.1 is #
873 1.1 is # copy, convert, and tag input argument
874 1.1 is #
875 1.1 is lea FP_SRC(%a6),%a0
876 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
877 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
878 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
879 1.1 is bsr.l tag # fetch operand type
880 1.1 is mov.b %d0,STAG(%a6)
881 1.1 is mov.b %d0,%d1
882 1.1 is
883 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
884 1.1 is
885 1.1 is clr.l %d0
886 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
887 1.1 is
888 1.1 is tst.b %d1
889 1.1 is bne.b _L1_2x
890 1.1 is bsr.l scos # operand is a NORM
891 1.1 is bra.b _L1_6x
892 1.1 is _L1_2x:
893 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
894 1.1 is bne.b _L1_3x # no
895 1.1 is bsr.l ld_pone # yes
896 1.1 is bra.b _L1_6x
897 1.1 is _L1_3x:
898 1.1 is cmpi.b %d1,&INF # is operand an INF?
899 1.1 is bne.b _L1_4x # no
900 1.1 is bsr.l t_operr # yes
901 1.1 is bra.b _L1_6x
902 1.1 is _L1_4x:
903 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
904 1.1 is bne.b _L1_5x # no
905 1.1 is bsr.l src_qnan # yes
906 1.1 is bra.b _L1_6x
907 1.1 is _L1_5x:
908 1.1 is bsr.l scosd # operand is a DENORM
909 1.1 is _L1_6x:
910 1.1 is
911 1.1 is #
912 1.1 is # Result is now in FP0
913 1.1 is #
914 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
915 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
916 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
917 1.1 is unlk %a6
918 1.1 is rts
919 1.1 is
920 1.1 is
921 1.1 is #########################################################################
922 1.1 is # MONADIC TEMPLATE #
923 1.1 is #########################################################################
924 1.1 is global _fsinhs_
925 1.1 is _fsinhs_:
926 1.1 is link %a6,&-LOCAL_SIZE
927 1.1 is
928 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
929 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
930 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
931 1.1 is
932 1.1 is fmov.l &0x0,%fpcr # zero FPCR
933 1.1 is
934 1.1 is #
935 1.1 is # copy, convert, and tag input argument
936 1.1 is #
937 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
938 1.1 is fmov.x %fp0,FP_SRC(%a6)
939 1.1 is lea FP_SRC(%a6),%a0
940 1.1 is bsr.l tag # fetch operand type
941 1.1 is mov.b %d0,STAG(%a6)
942 1.1 is mov.b %d0,%d1
943 1.1 is
944 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
945 1.1 is
946 1.1 is clr.l %d0
947 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
948 1.1 is
949 1.1 is tst.b %d1
950 1.1 is bne.b _L2_2s
951 1.1 is bsr.l ssinh # operand is a NORM
952 1.1 is bra.b _L2_6s
953 1.1 is _L2_2s:
954 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
955 1.1 is bne.b _L2_3s # no
956 1.1 is bsr.l src_zero # yes
957 1.1 is bra.b _L2_6s
958 1.1 is _L2_3s:
959 1.1 is cmpi.b %d1,&INF # is operand an INF?
960 1.1 is bne.b _L2_4s # no
961 1.1 is bsr.l src_inf # yes
962 1.1 is bra.b _L2_6s
963 1.1 is _L2_4s:
964 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
965 1.1 is bne.b _L2_5s # no
966 1.1 is bsr.l src_qnan # yes
967 1.1 is bra.b _L2_6s
968 1.1 is _L2_5s:
969 1.1 is bsr.l ssinhd # operand is a DENORM
970 1.1 is _L2_6s:
971 1.1 is
972 1.1 is #
973 1.1 is # Result is now in FP0
974 1.1 is #
975 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
976 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
977 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
978 1.1 is unlk %a6
979 1.1 is rts
980 1.1 is
981 1.1 is global _fsinhd_
982 1.1 is _fsinhd_:
983 1.1 is link %a6,&-LOCAL_SIZE
984 1.1 is
985 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
986 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
987 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
988 1.1 is
989 1.1 is fmov.l &0x0,%fpcr # zero FPCR
990 1.1 is
991 1.1 is #
992 1.1 is # copy, convert, and tag input argument
993 1.1 is #
994 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
995 1.1 is fmov.x %fp0,FP_SRC(%a6)
996 1.1 is lea FP_SRC(%a6),%a0
997 1.1 is bsr.l tag # fetch operand type
998 1.1 is mov.b %d0,STAG(%a6)
999 1.1 is mov.b %d0,%d1
1000 1.1 is
1001 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1002 1.1 is
1003 1.1 is clr.l %d0
1004 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1005 1.1 is
1006 1.1 is mov.b %d1,STAG(%a6)
1007 1.1 is tst.b %d1
1008 1.1 is bne.b _L2_2d
1009 1.1 is bsr.l ssinh # operand is a NORM
1010 1.1 is bra.b _L2_6d
1011 1.1 is _L2_2d:
1012 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1013 1.1 is bne.b _L2_3d # no
1014 1.1 is bsr.l src_zero # yes
1015 1.1 is bra.b _L2_6d
1016 1.1 is _L2_3d:
1017 1.1 is cmpi.b %d1,&INF # is operand an INF?
1018 1.1 is bne.b _L2_4d # no
1019 1.1 is bsr.l src_inf # yes
1020 1.1 is bra.b _L2_6d
1021 1.1 is _L2_4d:
1022 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1023 1.1 is bne.b _L2_5d # no
1024 1.1 is bsr.l src_qnan # yes
1025 1.1 is bra.b _L2_6d
1026 1.1 is _L2_5d:
1027 1.1 is bsr.l ssinhd # operand is a DENORM
1028 1.1 is _L2_6d:
1029 1.1 is
1030 1.1 is #
1031 1.1 is # Result is now in FP0
1032 1.1 is #
1033 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1034 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1035 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1036 1.1 is unlk %a6
1037 1.1 is rts
1038 1.1 is
1039 1.1 is global _fsinhx_
1040 1.1 is _fsinhx_:
1041 1.1 is link %a6,&-LOCAL_SIZE
1042 1.1 is
1043 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1044 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1045 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1046 1.1 is
1047 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1048 1.1 is
1049 1.1 is #
1050 1.1 is # copy, convert, and tag input argument
1051 1.1 is #
1052 1.1 is lea FP_SRC(%a6),%a0
1053 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
1054 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
1055 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
1056 1.1 is bsr.l tag # fetch operand type
1057 1.1 is mov.b %d0,STAG(%a6)
1058 1.1 is mov.b %d0,%d1
1059 1.1 is
1060 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1061 1.1 is
1062 1.1 is clr.l %d0
1063 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1064 1.1 is
1065 1.1 is tst.b %d1
1066 1.1 is bne.b _L2_2x
1067 1.1 is bsr.l ssinh # operand is a NORM
1068 1.1 is bra.b _L2_6x
1069 1.1 is _L2_2x:
1070 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1071 1.1 is bne.b _L2_3x # no
1072 1.1 is bsr.l src_zero # yes
1073 1.1 is bra.b _L2_6x
1074 1.1 is _L2_3x:
1075 1.1 is cmpi.b %d1,&INF # is operand an INF?
1076 1.1 is bne.b _L2_4x # no
1077 1.1 is bsr.l src_inf # yes
1078 1.1 is bra.b _L2_6x
1079 1.1 is _L2_4x:
1080 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1081 1.1 is bne.b _L2_5x # no
1082 1.1 is bsr.l src_qnan # yes
1083 1.1 is bra.b _L2_6x
1084 1.1 is _L2_5x:
1085 1.1 is bsr.l ssinhd # operand is a DENORM
1086 1.1 is _L2_6x:
1087 1.1 is
1088 1.1 is #
1089 1.1 is # Result is now in FP0
1090 1.1 is #
1091 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1092 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1093 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1094 1.1 is unlk %a6
1095 1.1 is rts
1096 1.1 is
1097 1.1 is
1098 1.1 is #########################################################################
1099 1.1 is # MONADIC TEMPLATE #
1100 1.1 is #########################################################################
1101 1.1 is global _flognp1s_
1102 1.1 is _flognp1s_:
1103 1.1 is link %a6,&-LOCAL_SIZE
1104 1.1 is
1105 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1106 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1107 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1108 1.1 is
1109 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1110 1.1 is
1111 1.1 is #
1112 1.1 is # copy, convert, and tag input argument
1113 1.1 is #
1114 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
1115 1.1 is fmov.x %fp0,FP_SRC(%a6)
1116 1.1 is lea FP_SRC(%a6),%a0
1117 1.1 is bsr.l tag # fetch operand type
1118 1.1 is mov.b %d0,STAG(%a6)
1119 1.1 is mov.b %d0,%d1
1120 1.1 is
1121 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1122 1.1 is
1123 1.1 is clr.l %d0
1124 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1125 1.1 is
1126 1.1 is tst.b %d1
1127 1.1 is bne.b _L3_2s
1128 1.1 is bsr.l slognp1 # operand is a NORM
1129 1.1 is bra.b _L3_6s
1130 1.1 is _L3_2s:
1131 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1132 1.1 is bne.b _L3_3s # no
1133 1.1 is bsr.l src_zero # yes
1134 1.1 is bra.b _L3_6s
1135 1.1 is _L3_3s:
1136 1.1 is cmpi.b %d1,&INF # is operand an INF?
1137 1.1 is bne.b _L3_4s # no
1138 1.1 is bsr.l sopr_inf # yes
1139 1.1 is bra.b _L3_6s
1140 1.1 is _L3_4s:
1141 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1142 1.1 is bne.b _L3_5s # no
1143 1.1 is bsr.l src_qnan # yes
1144 1.1 is bra.b _L3_6s
1145 1.1 is _L3_5s:
1146 1.1 is bsr.l slognp1d # operand is a DENORM
1147 1.1 is _L3_6s:
1148 1.1 is
1149 1.1 is #
1150 1.1 is # Result is now in FP0
1151 1.1 is #
1152 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1153 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1154 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1155 1.1 is unlk %a6
1156 1.1 is rts
1157 1.1 is
1158 1.1 is global _flognp1d_
1159 1.1 is _flognp1d_:
1160 1.1 is link %a6,&-LOCAL_SIZE
1161 1.1 is
1162 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1163 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1164 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1165 1.1 is
1166 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1167 1.1 is
1168 1.1 is #
1169 1.1 is # copy, convert, and tag input argument
1170 1.1 is #
1171 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
1172 1.1 is fmov.x %fp0,FP_SRC(%a6)
1173 1.1 is lea FP_SRC(%a6),%a0
1174 1.1 is bsr.l tag # fetch operand type
1175 1.1 is mov.b %d0,STAG(%a6)
1176 1.1 is mov.b %d0,%d1
1177 1.1 is
1178 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1179 1.1 is
1180 1.1 is clr.l %d0
1181 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1182 1.1 is
1183 1.1 is mov.b %d1,STAG(%a6)
1184 1.1 is tst.b %d1
1185 1.1 is bne.b _L3_2d
1186 1.1 is bsr.l slognp1 # operand is a NORM
1187 1.1 is bra.b _L3_6d
1188 1.1 is _L3_2d:
1189 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1190 1.1 is bne.b _L3_3d # no
1191 1.1 is bsr.l src_zero # yes
1192 1.1 is bra.b _L3_6d
1193 1.1 is _L3_3d:
1194 1.1 is cmpi.b %d1,&INF # is operand an INF?
1195 1.1 is bne.b _L3_4d # no
1196 1.1 is bsr.l sopr_inf # yes
1197 1.1 is bra.b _L3_6d
1198 1.1 is _L3_4d:
1199 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1200 1.1 is bne.b _L3_5d # no
1201 1.1 is bsr.l src_qnan # yes
1202 1.1 is bra.b _L3_6d
1203 1.1 is _L3_5d:
1204 1.1 is bsr.l slognp1d # operand is a DENORM
1205 1.1 is _L3_6d:
1206 1.1 is
1207 1.1 is #
1208 1.1 is # Result is now in FP0
1209 1.1 is #
1210 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1211 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1212 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1213 1.1 is unlk %a6
1214 1.1 is rts
1215 1.1 is
1216 1.1 is global _flognp1x_
1217 1.1 is _flognp1x_:
1218 1.1 is link %a6,&-LOCAL_SIZE
1219 1.1 is
1220 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1221 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1222 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1223 1.1 is
1224 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1225 1.1 is
1226 1.1 is #
1227 1.1 is # copy, convert, and tag input argument
1228 1.1 is #
1229 1.1 is lea FP_SRC(%a6),%a0
1230 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
1231 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
1232 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
1233 1.1 is bsr.l tag # fetch operand type
1234 1.1 is mov.b %d0,STAG(%a6)
1235 1.1 is mov.b %d0,%d1
1236 1.1 is
1237 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1238 1.1 is
1239 1.1 is clr.l %d0
1240 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1241 1.1 is
1242 1.1 is tst.b %d1
1243 1.1 is bne.b _L3_2x
1244 1.1 is bsr.l slognp1 # operand is a NORM
1245 1.1 is bra.b _L3_6x
1246 1.1 is _L3_2x:
1247 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1248 1.1 is bne.b _L3_3x # no
1249 1.1 is bsr.l src_zero # yes
1250 1.1 is bra.b _L3_6x
1251 1.1 is _L3_3x:
1252 1.1 is cmpi.b %d1,&INF # is operand an INF?
1253 1.1 is bne.b _L3_4x # no
1254 1.1 is bsr.l sopr_inf # yes
1255 1.1 is bra.b _L3_6x
1256 1.1 is _L3_4x:
1257 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1258 1.1 is bne.b _L3_5x # no
1259 1.1 is bsr.l src_qnan # yes
1260 1.1 is bra.b _L3_6x
1261 1.1 is _L3_5x:
1262 1.1 is bsr.l slognp1d # operand is a DENORM
1263 1.1 is _L3_6x:
1264 1.1 is
1265 1.1 is #
1266 1.1 is # Result is now in FP0
1267 1.1 is #
1268 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1269 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1270 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1271 1.1 is unlk %a6
1272 1.1 is rts
1273 1.1 is
1274 1.1 is
1275 1.1 is #########################################################################
1276 1.1 is # MONADIC TEMPLATE #
1277 1.1 is #########################################################################
1278 1.1 is global _fetoxm1s_
1279 1.1 is _fetoxm1s_:
1280 1.1 is link %a6,&-LOCAL_SIZE
1281 1.1 is
1282 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1283 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1284 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1285 1.1 is
1286 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1287 1.1 is
1288 1.1 is #
1289 1.1 is # copy, convert, and tag input argument
1290 1.1 is #
1291 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
1292 1.1 is fmov.x %fp0,FP_SRC(%a6)
1293 1.1 is lea FP_SRC(%a6),%a0
1294 1.1 is bsr.l tag # fetch operand type
1295 1.1 is mov.b %d0,STAG(%a6)
1296 1.1 is mov.b %d0,%d1
1297 1.1 is
1298 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1299 1.1 is
1300 1.1 is clr.l %d0
1301 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1302 1.1 is
1303 1.1 is tst.b %d1
1304 1.1 is bne.b _L4_2s
1305 1.1 is bsr.l setoxm1 # operand is a NORM
1306 1.1 is bra.b _L4_6s
1307 1.1 is _L4_2s:
1308 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1309 1.1 is bne.b _L4_3s # no
1310 1.1 is bsr.l src_zero # yes
1311 1.1 is bra.b _L4_6s
1312 1.1 is _L4_3s:
1313 1.1 is cmpi.b %d1,&INF # is operand an INF?
1314 1.1 is bne.b _L4_4s # no
1315 1.1 is bsr.l setoxm1i # yes
1316 1.1 is bra.b _L4_6s
1317 1.1 is _L4_4s:
1318 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1319 1.1 is bne.b _L4_5s # no
1320 1.1 is bsr.l src_qnan # yes
1321 1.1 is bra.b _L4_6s
1322 1.1 is _L4_5s:
1323 1.1 is bsr.l setoxm1d # operand is a DENORM
1324 1.1 is _L4_6s:
1325 1.1 is
1326 1.1 is #
1327 1.1 is # Result is now in FP0
1328 1.1 is #
1329 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1330 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1331 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1332 1.1 is unlk %a6
1333 1.1 is rts
1334 1.1 is
1335 1.1 is global _fetoxm1d_
1336 1.1 is _fetoxm1d_:
1337 1.1 is link %a6,&-LOCAL_SIZE
1338 1.1 is
1339 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1340 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1341 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1342 1.1 is
1343 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1344 1.1 is
1345 1.1 is #
1346 1.1 is # copy, convert, and tag input argument
1347 1.1 is #
1348 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
1349 1.1 is fmov.x %fp0,FP_SRC(%a6)
1350 1.1 is lea FP_SRC(%a6),%a0
1351 1.1 is bsr.l tag # fetch operand type
1352 1.1 is mov.b %d0,STAG(%a6)
1353 1.1 is mov.b %d0,%d1
1354 1.1 is
1355 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1356 1.1 is
1357 1.1 is clr.l %d0
1358 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1359 1.1 is
1360 1.1 is mov.b %d1,STAG(%a6)
1361 1.1 is tst.b %d1
1362 1.1 is bne.b _L4_2d
1363 1.1 is bsr.l setoxm1 # operand is a NORM
1364 1.1 is bra.b _L4_6d
1365 1.1 is _L4_2d:
1366 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1367 1.1 is bne.b _L4_3d # no
1368 1.1 is bsr.l src_zero # yes
1369 1.1 is bra.b _L4_6d
1370 1.1 is _L4_3d:
1371 1.1 is cmpi.b %d1,&INF # is operand an INF?
1372 1.1 is bne.b _L4_4d # no
1373 1.1 is bsr.l setoxm1i # yes
1374 1.1 is bra.b _L4_6d
1375 1.1 is _L4_4d:
1376 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1377 1.1 is bne.b _L4_5d # no
1378 1.1 is bsr.l src_qnan # yes
1379 1.1 is bra.b _L4_6d
1380 1.1 is _L4_5d:
1381 1.1 is bsr.l setoxm1d # operand is a DENORM
1382 1.1 is _L4_6d:
1383 1.1 is
1384 1.1 is #
1385 1.1 is # Result is now in FP0
1386 1.1 is #
1387 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1388 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1389 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1390 1.1 is unlk %a6
1391 1.1 is rts
1392 1.1 is
1393 1.1 is global _fetoxm1x_
1394 1.1 is _fetoxm1x_:
1395 1.1 is link %a6,&-LOCAL_SIZE
1396 1.1 is
1397 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1398 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1399 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1400 1.1 is
1401 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1402 1.1 is
1403 1.1 is #
1404 1.1 is # copy, convert, and tag input argument
1405 1.1 is #
1406 1.1 is lea FP_SRC(%a6),%a0
1407 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
1408 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
1409 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
1410 1.1 is bsr.l tag # fetch operand type
1411 1.1 is mov.b %d0,STAG(%a6)
1412 1.1 is mov.b %d0,%d1
1413 1.1 is
1414 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1415 1.1 is
1416 1.1 is clr.l %d0
1417 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1418 1.1 is
1419 1.1 is tst.b %d1
1420 1.1 is bne.b _L4_2x
1421 1.1 is bsr.l setoxm1 # operand is a NORM
1422 1.1 is bra.b _L4_6x
1423 1.1 is _L4_2x:
1424 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1425 1.1 is bne.b _L4_3x # no
1426 1.1 is bsr.l src_zero # yes
1427 1.1 is bra.b _L4_6x
1428 1.1 is _L4_3x:
1429 1.1 is cmpi.b %d1,&INF # is operand an INF?
1430 1.1 is bne.b _L4_4x # no
1431 1.1 is bsr.l setoxm1i # yes
1432 1.1 is bra.b _L4_6x
1433 1.1 is _L4_4x:
1434 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1435 1.1 is bne.b _L4_5x # no
1436 1.1 is bsr.l src_qnan # yes
1437 1.1 is bra.b _L4_6x
1438 1.1 is _L4_5x:
1439 1.1 is bsr.l setoxm1d # operand is a DENORM
1440 1.1 is _L4_6x:
1441 1.1 is
1442 1.1 is #
1443 1.1 is # Result is now in FP0
1444 1.1 is #
1445 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1446 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1447 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1448 1.1 is unlk %a6
1449 1.1 is rts
1450 1.1 is
1451 1.1 is
1452 1.1 is #########################################################################
1453 1.1 is # MONADIC TEMPLATE #
1454 1.1 is #########################################################################
1455 1.1 is global _ftanhs_
1456 1.1 is _ftanhs_:
1457 1.1 is link %a6,&-LOCAL_SIZE
1458 1.1 is
1459 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1460 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1461 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1462 1.1 is
1463 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1464 1.1 is
1465 1.1 is #
1466 1.1 is # copy, convert, and tag input argument
1467 1.1 is #
1468 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
1469 1.1 is fmov.x %fp0,FP_SRC(%a6)
1470 1.1 is lea FP_SRC(%a6),%a0
1471 1.1 is bsr.l tag # fetch operand type
1472 1.1 is mov.b %d0,STAG(%a6)
1473 1.1 is mov.b %d0,%d1
1474 1.1 is
1475 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1476 1.1 is
1477 1.1 is clr.l %d0
1478 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1479 1.1 is
1480 1.1 is tst.b %d1
1481 1.1 is bne.b _L5_2s
1482 1.1 is bsr.l stanh # operand is a NORM
1483 1.1 is bra.b _L5_6s
1484 1.1 is _L5_2s:
1485 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1486 1.1 is bne.b _L5_3s # no
1487 1.1 is bsr.l src_zero # yes
1488 1.1 is bra.b _L5_6s
1489 1.1 is _L5_3s:
1490 1.1 is cmpi.b %d1,&INF # is operand an INF?
1491 1.1 is bne.b _L5_4s # no
1492 1.1 is bsr.l src_one # yes
1493 1.1 is bra.b _L5_6s
1494 1.1 is _L5_4s:
1495 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1496 1.1 is bne.b _L5_5s # no
1497 1.1 is bsr.l src_qnan # yes
1498 1.1 is bra.b _L5_6s
1499 1.1 is _L5_5s:
1500 1.1 is bsr.l stanhd # operand is a DENORM
1501 1.1 is _L5_6s:
1502 1.1 is
1503 1.1 is #
1504 1.1 is # Result is now in FP0
1505 1.1 is #
1506 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1507 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1508 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1509 1.1 is unlk %a6
1510 1.1 is rts
1511 1.1 is
1512 1.1 is global _ftanhd_
1513 1.1 is _ftanhd_:
1514 1.1 is link %a6,&-LOCAL_SIZE
1515 1.1 is
1516 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1517 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1518 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1519 1.1 is
1520 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1521 1.1 is
1522 1.1 is #
1523 1.1 is # copy, convert, and tag input argument
1524 1.1 is #
1525 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
1526 1.1 is fmov.x %fp0,FP_SRC(%a6)
1527 1.1 is lea FP_SRC(%a6),%a0
1528 1.1 is bsr.l tag # fetch operand type
1529 1.1 is mov.b %d0,STAG(%a6)
1530 1.1 is mov.b %d0,%d1
1531 1.1 is
1532 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1533 1.1 is
1534 1.1 is clr.l %d0
1535 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1536 1.1 is
1537 1.1 is mov.b %d1,STAG(%a6)
1538 1.1 is tst.b %d1
1539 1.1 is bne.b _L5_2d
1540 1.1 is bsr.l stanh # operand is a NORM
1541 1.1 is bra.b _L5_6d
1542 1.1 is _L5_2d:
1543 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1544 1.1 is bne.b _L5_3d # no
1545 1.1 is bsr.l src_zero # yes
1546 1.1 is bra.b _L5_6d
1547 1.1 is _L5_3d:
1548 1.1 is cmpi.b %d1,&INF # is operand an INF?
1549 1.1 is bne.b _L5_4d # no
1550 1.1 is bsr.l src_one # yes
1551 1.1 is bra.b _L5_6d
1552 1.1 is _L5_4d:
1553 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1554 1.1 is bne.b _L5_5d # no
1555 1.1 is bsr.l src_qnan # yes
1556 1.1 is bra.b _L5_6d
1557 1.1 is _L5_5d:
1558 1.1 is bsr.l stanhd # operand is a DENORM
1559 1.1 is _L5_6d:
1560 1.1 is
1561 1.1 is #
1562 1.1 is # Result is now in FP0
1563 1.1 is #
1564 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1565 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1566 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1567 1.1 is unlk %a6
1568 1.1 is rts
1569 1.1 is
1570 1.1 is global _ftanhx_
1571 1.1 is _ftanhx_:
1572 1.1 is link %a6,&-LOCAL_SIZE
1573 1.1 is
1574 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1575 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1576 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1577 1.1 is
1578 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1579 1.1 is
1580 1.1 is #
1581 1.1 is # copy, convert, and tag input argument
1582 1.1 is #
1583 1.1 is lea FP_SRC(%a6),%a0
1584 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
1585 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
1586 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
1587 1.1 is bsr.l tag # fetch operand type
1588 1.1 is mov.b %d0,STAG(%a6)
1589 1.1 is mov.b %d0,%d1
1590 1.1 is
1591 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1592 1.1 is
1593 1.1 is clr.l %d0
1594 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1595 1.1 is
1596 1.1 is tst.b %d1
1597 1.1 is bne.b _L5_2x
1598 1.1 is bsr.l stanh # operand is a NORM
1599 1.1 is bra.b _L5_6x
1600 1.1 is _L5_2x:
1601 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1602 1.1 is bne.b _L5_3x # no
1603 1.1 is bsr.l src_zero # yes
1604 1.1 is bra.b _L5_6x
1605 1.1 is _L5_3x:
1606 1.1 is cmpi.b %d1,&INF # is operand an INF?
1607 1.1 is bne.b _L5_4x # no
1608 1.1 is bsr.l src_one # yes
1609 1.1 is bra.b _L5_6x
1610 1.1 is _L5_4x:
1611 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1612 1.1 is bne.b _L5_5x # no
1613 1.1 is bsr.l src_qnan # yes
1614 1.1 is bra.b _L5_6x
1615 1.1 is _L5_5x:
1616 1.1 is bsr.l stanhd # operand is a DENORM
1617 1.1 is _L5_6x:
1618 1.1 is
1619 1.1 is #
1620 1.1 is # Result is now in FP0
1621 1.1 is #
1622 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1623 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1624 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1625 1.1 is unlk %a6
1626 1.1 is rts
1627 1.1 is
1628 1.1 is
1629 1.1 is #########################################################################
1630 1.1 is # MONADIC TEMPLATE #
1631 1.1 is #########################################################################
1632 1.1 is global _fatans_
1633 1.1 is _fatans_:
1634 1.1 is link %a6,&-LOCAL_SIZE
1635 1.1 is
1636 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1637 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1638 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1639 1.1 is
1640 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1641 1.1 is
1642 1.1 is #
1643 1.1 is # copy, convert, and tag input argument
1644 1.1 is #
1645 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
1646 1.1 is fmov.x %fp0,FP_SRC(%a6)
1647 1.1 is lea FP_SRC(%a6),%a0
1648 1.1 is bsr.l tag # fetch operand type
1649 1.1 is mov.b %d0,STAG(%a6)
1650 1.1 is mov.b %d0,%d1
1651 1.1 is
1652 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1653 1.1 is
1654 1.1 is clr.l %d0
1655 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1656 1.1 is
1657 1.1 is tst.b %d1
1658 1.1 is bne.b _L6_2s
1659 1.1 is bsr.l satan # operand is a NORM
1660 1.1 is bra.b _L6_6s
1661 1.1 is _L6_2s:
1662 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1663 1.1 is bne.b _L6_3s # no
1664 1.1 is bsr.l src_zero # yes
1665 1.1 is bra.b _L6_6s
1666 1.1 is _L6_3s:
1667 1.1 is cmpi.b %d1,&INF # is operand an INF?
1668 1.1 is bne.b _L6_4s # no
1669 1.1 is bsr.l spi_2 # yes
1670 1.1 is bra.b _L6_6s
1671 1.1 is _L6_4s:
1672 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1673 1.1 is bne.b _L6_5s # no
1674 1.1 is bsr.l src_qnan # yes
1675 1.1 is bra.b _L6_6s
1676 1.1 is _L6_5s:
1677 1.1 is bsr.l satand # operand is a DENORM
1678 1.1 is _L6_6s:
1679 1.1 is
1680 1.1 is #
1681 1.1 is # Result is now in FP0
1682 1.1 is #
1683 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1684 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1685 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1686 1.1 is unlk %a6
1687 1.1 is rts
1688 1.1 is
1689 1.1 is global _fatand_
1690 1.1 is _fatand_:
1691 1.1 is link %a6,&-LOCAL_SIZE
1692 1.1 is
1693 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1694 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1695 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1696 1.1 is
1697 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1698 1.1 is
1699 1.1 is #
1700 1.1 is # copy, convert, and tag input argument
1701 1.1 is #
1702 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
1703 1.1 is fmov.x %fp0,FP_SRC(%a6)
1704 1.1 is lea FP_SRC(%a6),%a0
1705 1.1 is bsr.l tag # fetch operand type
1706 1.1 is mov.b %d0,STAG(%a6)
1707 1.1 is mov.b %d0,%d1
1708 1.1 is
1709 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1710 1.1 is
1711 1.1 is clr.l %d0
1712 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1713 1.1 is
1714 1.1 is mov.b %d1,STAG(%a6)
1715 1.1 is tst.b %d1
1716 1.1 is bne.b _L6_2d
1717 1.1 is bsr.l satan # operand is a NORM
1718 1.1 is bra.b _L6_6d
1719 1.1 is _L6_2d:
1720 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1721 1.1 is bne.b _L6_3d # no
1722 1.1 is bsr.l src_zero # yes
1723 1.1 is bra.b _L6_6d
1724 1.1 is _L6_3d:
1725 1.1 is cmpi.b %d1,&INF # is operand an INF?
1726 1.1 is bne.b _L6_4d # no
1727 1.1 is bsr.l spi_2 # yes
1728 1.1 is bra.b _L6_6d
1729 1.1 is _L6_4d:
1730 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1731 1.1 is bne.b _L6_5d # no
1732 1.1 is bsr.l src_qnan # yes
1733 1.1 is bra.b _L6_6d
1734 1.1 is _L6_5d:
1735 1.1 is bsr.l satand # operand is a DENORM
1736 1.1 is _L6_6d:
1737 1.1 is
1738 1.1 is #
1739 1.1 is # Result is now in FP0
1740 1.1 is #
1741 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1742 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1743 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1744 1.1 is unlk %a6
1745 1.1 is rts
1746 1.1 is
1747 1.1 is global _fatanx_
1748 1.1 is _fatanx_:
1749 1.1 is link %a6,&-LOCAL_SIZE
1750 1.1 is
1751 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1752 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1753 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1754 1.1 is
1755 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1756 1.1 is
1757 1.1 is #
1758 1.1 is # copy, convert, and tag input argument
1759 1.1 is #
1760 1.1 is lea FP_SRC(%a6),%a0
1761 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
1762 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
1763 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
1764 1.1 is bsr.l tag # fetch operand type
1765 1.1 is mov.b %d0,STAG(%a6)
1766 1.1 is mov.b %d0,%d1
1767 1.1 is
1768 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1769 1.1 is
1770 1.1 is clr.l %d0
1771 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1772 1.1 is
1773 1.1 is tst.b %d1
1774 1.1 is bne.b _L6_2x
1775 1.1 is bsr.l satan # operand is a NORM
1776 1.1 is bra.b _L6_6x
1777 1.1 is _L6_2x:
1778 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1779 1.1 is bne.b _L6_3x # no
1780 1.1 is bsr.l src_zero # yes
1781 1.1 is bra.b _L6_6x
1782 1.1 is _L6_3x:
1783 1.1 is cmpi.b %d1,&INF # is operand an INF?
1784 1.1 is bne.b _L6_4x # no
1785 1.1 is bsr.l spi_2 # yes
1786 1.1 is bra.b _L6_6x
1787 1.1 is _L6_4x:
1788 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1789 1.1 is bne.b _L6_5x # no
1790 1.1 is bsr.l src_qnan # yes
1791 1.1 is bra.b _L6_6x
1792 1.1 is _L6_5x:
1793 1.1 is bsr.l satand # operand is a DENORM
1794 1.1 is _L6_6x:
1795 1.1 is
1796 1.1 is #
1797 1.1 is # Result is now in FP0
1798 1.1 is #
1799 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1800 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1801 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1802 1.1 is unlk %a6
1803 1.1 is rts
1804 1.1 is
1805 1.1 is
1806 1.1 is #########################################################################
1807 1.1 is # MONADIC TEMPLATE #
1808 1.1 is #########################################################################
1809 1.1 is global _fasins_
1810 1.1 is _fasins_:
1811 1.1 is link %a6,&-LOCAL_SIZE
1812 1.1 is
1813 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1814 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1815 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1816 1.1 is
1817 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1818 1.1 is
1819 1.1 is #
1820 1.1 is # copy, convert, and tag input argument
1821 1.1 is #
1822 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
1823 1.1 is fmov.x %fp0,FP_SRC(%a6)
1824 1.1 is lea FP_SRC(%a6),%a0
1825 1.1 is bsr.l tag # fetch operand type
1826 1.1 is mov.b %d0,STAG(%a6)
1827 1.1 is mov.b %d0,%d1
1828 1.1 is
1829 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1830 1.1 is
1831 1.1 is clr.l %d0
1832 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1833 1.1 is
1834 1.1 is tst.b %d1
1835 1.1 is bne.b _L7_2s
1836 1.1 is bsr.l sasin # operand is a NORM
1837 1.1 is bra.b _L7_6s
1838 1.1 is _L7_2s:
1839 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1840 1.1 is bne.b _L7_3s # no
1841 1.1 is bsr.l src_zero # yes
1842 1.1 is bra.b _L7_6s
1843 1.1 is _L7_3s:
1844 1.1 is cmpi.b %d1,&INF # is operand an INF?
1845 1.1 is bne.b _L7_4s # no
1846 1.1 is bsr.l t_operr # yes
1847 1.1 is bra.b _L7_6s
1848 1.1 is _L7_4s:
1849 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1850 1.1 is bne.b _L7_5s # no
1851 1.1 is bsr.l src_qnan # yes
1852 1.1 is bra.b _L7_6s
1853 1.1 is _L7_5s:
1854 1.1 is bsr.l sasind # operand is a DENORM
1855 1.1 is _L7_6s:
1856 1.1 is
1857 1.1 is #
1858 1.1 is # Result is now in FP0
1859 1.1 is #
1860 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1861 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1862 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1863 1.1 is unlk %a6
1864 1.1 is rts
1865 1.1 is
1866 1.1 is global _fasind_
1867 1.1 is _fasind_:
1868 1.1 is link %a6,&-LOCAL_SIZE
1869 1.1 is
1870 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1871 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1872 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1873 1.1 is
1874 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1875 1.1 is
1876 1.1 is #
1877 1.1 is # copy, convert, and tag input argument
1878 1.1 is #
1879 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
1880 1.1 is fmov.x %fp0,FP_SRC(%a6)
1881 1.1 is lea FP_SRC(%a6),%a0
1882 1.1 is bsr.l tag # fetch operand type
1883 1.1 is mov.b %d0,STAG(%a6)
1884 1.1 is mov.b %d0,%d1
1885 1.1 is
1886 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1887 1.1 is
1888 1.1 is clr.l %d0
1889 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1890 1.1 is
1891 1.1 is mov.b %d1,STAG(%a6)
1892 1.1 is tst.b %d1
1893 1.1 is bne.b _L7_2d
1894 1.1 is bsr.l sasin # operand is a NORM
1895 1.1 is bra.b _L7_6d
1896 1.1 is _L7_2d:
1897 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1898 1.1 is bne.b _L7_3d # no
1899 1.1 is bsr.l src_zero # yes
1900 1.1 is bra.b _L7_6d
1901 1.1 is _L7_3d:
1902 1.1 is cmpi.b %d1,&INF # is operand an INF?
1903 1.1 is bne.b _L7_4d # no
1904 1.1 is bsr.l t_operr # yes
1905 1.1 is bra.b _L7_6d
1906 1.1 is _L7_4d:
1907 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1908 1.1 is bne.b _L7_5d # no
1909 1.1 is bsr.l src_qnan # yes
1910 1.1 is bra.b _L7_6d
1911 1.1 is _L7_5d:
1912 1.1 is bsr.l sasind # operand is a DENORM
1913 1.1 is _L7_6d:
1914 1.1 is
1915 1.1 is #
1916 1.1 is # Result is now in FP0
1917 1.1 is #
1918 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1919 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1920 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1921 1.1 is unlk %a6
1922 1.1 is rts
1923 1.1 is
1924 1.1 is global _fasinx_
1925 1.1 is _fasinx_:
1926 1.1 is link %a6,&-LOCAL_SIZE
1927 1.1 is
1928 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1929 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1930 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1931 1.1 is
1932 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1933 1.1 is
1934 1.1 is #
1935 1.1 is # copy, convert, and tag input argument
1936 1.1 is #
1937 1.1 is lea FP_SRC(%a6),%a0
1938 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
1939 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
1940 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
1941 1.1 is bsr.l tag # fetch operand type
1942 1.1 is mov.b %d0,STAG(%a6)
1943 1.1 is mov.b %d0,%d1
1944 1.1 is
1945 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
1946 1.1 is
1947 1.1 is clr.l %d0
1948 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
1949 1.1 is
1950 1.1 is tst.b %d1
1951 1.1 is bne.b _L7_2x
1952 1.1 is bsr.l sasin # operand is a NORM
1953 1.1 is bra.b _L7_6x
1954 1.1 is _L7_2x:
1955 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
1956 1.1 is bne.b _L7_3x # no
1957 1.1 is bsr.l src_zero # yes
1958 1.1 is bra.b _L7_6x
1959 1.1 is _L7_3x:
1960 1.1 is cmpi.b %d1,&INF # is operand an INF?
1961 1.1 is bne.b _L7_4x # no
1962 1.1 is bsr.l t_operr # yes
1963 1.1 is bra.b _L7_6x
1964 1.1 is _L7_4x:
1965 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
1966 1.1 is bne.b _L7_5x # no
1967 1.1 is bsr.l src_qnan # yes
1968 1.1 is bra.b _L7_6x
1969 1.1 is _L7_5x:
1970 1.1 is bsr.l sasind # operand is a DENORM
1971 1.1 is _L7_6x:
1972 1.1 is
1973 1.1 is #
1974 1.1 is # Result is now in FP0
1975 1.1 is #
1976 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
1977 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1978 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
1979 1.1 is unlk %a6
1980 1.1 is rts
1981 1.1 is
1982 1.1 is
1983 1.1 is #########################################################################
1984 1.1 is # MONADIC TEMPLATE #
1985 1.1 is #########################################################################
1986 1.1 is global _fatanhs_
1987 1.1 is _fatanhs_:
1988 1.1 is link %a6,&-LOCAL_SIZE
1989 1.1 is
1990 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
1991 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1992 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
1993 1.1 is
1994 1.1 is fmov.l &0x0,%fpcr # zero FPCR
1995 1.1 is
1996 1.1 is #
1997 1.1 is # copy, convert, and tag input argument
1998 1.1 is #
1999 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
2000 1.1 is fmov.x %fp0,FP_SRC(%a6)
2001 1.1 is lea FP_SRC(%a6),%a0
2002 1.1 is bsr.l tag # fetch operand type
2003 1.1 is mov.b %d0,STAG(%a6)
2004 1.1 is mov.b %d0,%d1
2005 1.1 is
2006 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2007 1.1 is
2008 1.1 is clr.l %d0
2009 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2010 1.1 is
2011 1.1 is tst.b %d1
2012 1.1 is bne.b _L8_2s
2013 1.1 is bsr.l satanh # operand is a NORM
2014 1.1 is bra.b _L8_6s
2015 1.1 is _L8_2s:
2016 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2017 1.1 is bne.b _L8_3s # no
2018 1.1 is bsr.l src_zero # yes
2019 1.1 is bra.b _L8_6s
2020 1.1 is _L8_3s:
2021 1.1 is cmpi.b %d1,&INF # is operand an INF?
2022 1.1 is bne.b _L8_4s # no
2023 1.1 is bsr.l t_operr # yes
2024 1.1 is bra.b _L8_6s
2025 1.1 is _L8_4s:
2026 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2027 1.1 is bne.b _L8_5s # no
2028 1.1 is bsr.l src_qnan # yes
2029 1.1 is bra.b _L8_6s
2030 1.1 is _L8_5s:
2031 1.1 is bsr.l satanhd # operand is a DENORM
2032 1.1 is _L8_6s:
2033 1.1 is
2034 1.1 is #
2035 1.1 is # Result is now in FP0
2036 1.1 is #
2037 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2038 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2039 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2040 1.1 is unlk %a6
2041 1.1 is rts
2042 1.1 is
2043 1.1 is global _fatanhd_
2044 1.1 is _fatanhd_:
2045 1.1 is link %a6,&-LOCAL_SIZE
2046 1.1 is
2047 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2048 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2049 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2050 1.1 is
2051 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2052 1.1 is
2053 1.1 is #
2054 1.1 is # copy, convert, and tag input argument
2055 1.1 is #
2056 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
2057 1.1 is fmov.x %fp0,FP_SRC(%a6)
2058 1.1 is lea FP_SRC(%a6),%a0
2059 1.1 is bsr.l tag # fetch operand type
2060 1.1 is mov.b %d0,STAG(%a6)
2061 1.1 is mov.b %d0,%d1
2062 1.1 is
2063 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2064 1.1 is
2065 1.1 is clr.l %d0
2066 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2067 1.1 is
2068 1.1 is mov.b %d1,STAG(%a6)
2069 1.1 is tst.b %d1
2070 1.1 is bne.b _L8_2d
2071 1.1 is bsr.l satanh # operand is a NORM
2072 1.1 is bra.b _L8_6d
2073 1.1 is _L8_2d:
2074 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2075 1.1 is bne.b _L8_3d # no
2076 1.1 is bsr.l src_zero # yes
2077 1.1 is bra.b _L8_6d
2078 1.1 is _L8_3d:
2079 1.1 is cmpi.b %d1,&INF # is operand an INF?
2080 1.1 is bne.b _L8_4d # no
2081 1.1 is bsr.l t_operr # yes
2082 1.1 is bra.b _L8_6d
2083 1.1 is _L8_4d:
2084 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2085 1.1 is bne.b _L8_5d # no
2086 1.1 is bsr.l src_qnan # yes
2087 1.1 is bra.b _L8_6d
2088 1.1 is _L8_5d:
2089 1.1 is bsr.l satanhd # operand is a DENORM
2090 1.1 is _L8_6d:
2091 1.1 is
2092 1.1 is #
2093 1.1 is # Result is now in FP0
2094 1.1 is #
2095 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2096 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2097 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2098 1.1 is unlk %a6
2099 1.1 is rts
2100 1.1 is
2101 1.1 is global _fatanhx_
2102 1.1 is _fatanhx_:
2103 1.1 is link %a6,&-LOCAL_SIZE
2104 1.1 is
2105 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2106 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2107 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2108 1.1 is
2109 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2110 1.1 is
2111 1.1 is #
2112 1.1 is # copy, convert, and tag input argument
2113 1.1 is #
2114 1.1 is lea FP_SRC(%a6),%a0
2115 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
2116 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
2117 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
2118 1.1 is bsr.l tag # fetch operand type
2119 1.1 is mov.b %d0,STAG(%a6)
2120 1.1 is mov.b %d0,%d1
2121 1.1 is
2122 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2123 1.1 is
2124 1.1 is clr.l %d0
2125 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2126 1.1 is
2127 1.1 is tst.b %d1
2128 1.1 is bne.b _L8_2x
2129 1.1 is bsr.l satanh # operand is a NORM
2130 1.1 is bra.b _L8_6x
2131 1.1 is _L8_2x:
2132 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2133 1.1 is bne.b _L8_3x # no
2134 1.1 is bsr.l src_zero # yes
2135 1.1 is bra.b _L8_6x
2136 1.1 is _L8_3x:
2137 1.1 is cmpi.b %d1,&INF # is operand an INF?
2138 1.1 is bne.b _L8_4x # no
2139 1.1 is bsr.l t_operr # yes
2140 1.1 is bra.b _L8_6x
2141 1.1 is _L8_4x:
2142 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2143 1.1 is bne.b _L8_5x # no
2144 1.1 is bsr.l src_qnan # yes
2145 1.1 is bra.b _L8_6x
2146 1.1 is _L8_5x:
2147 1.1 is bsr.l satanhd # operand is a DENORM
2148 1.1 is _L8_6x:
2149 1.1 is
2150 1.1 is #
2151 1.1 is # Result is now in FP0
2152 1.1 is #
2153 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2154 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2155 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2156 1.1 is unlk %a6
2157 1.1 is rts
2158 1.1 is
2159 1.1 is
2160 1.1 is #########################################################################
2161 1.1 is # MONADIC TEMPLATE #
2162 1.1 is #########################################################################
2163 1.1 is global _ftans_
2164 1.1 is _ftans_:
2165 1.1 is link %a6,&-LOCAL_SIZE
2166 1.1 is
2167 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2168 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2169 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2170 1.1 is
2171 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2172 1.1 is
2173 1.1 is #
2174 1.1 is # copy, convert, and tag input argument
2175 1.1 is #
2176 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
2177 1.1 is fmov.x %fp0,FP_SRC(%a6)
2178 1.1 is lea FP_SRC(%a6),%a0
2179 1.1 is bsr.l tag # fetch operand type
2180 1.1 is mov.b %d0,STAG(%a6)
2181 1.1 is mov.b %d0,%d1
2182 1.1 is
2183 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2184 1.1 is
2185 1.1 is clr.l %d0
2186 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2187 1.1 is
2188 1.1 is tst.b %d1
2189 1.1 is bne.b _L9_2s
2190 1.1 is bsr.l stan # operand is a NORM
2191 1.1 is bra.b _L9_6s
2192 1.1 is _L9_2s:
2193 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2194 1.1 is bne.b _L9_3s # no
2195 1.1 is bsr.l src_zero # yes
2196 1.1 is bra.b _L9_6s
2197 1.1 is _L9_3s:
2198 1.1 is cmpi.b %d1,&INF # is operand an INF?
2199 1.1 is bne.b _L9_4s # no
2200 1.1 is bsr.l t_operr # yes
2201 1.1 is bra.b _L9_6s
2202 1.1 is _L9_4s:
2203 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2204 1.1 is bne.b _L9_5s # no
2205 1.1 is bsr.l src_qnan # yes
2206 1.1 is bra.b _L9_6s
2207 1.1 is _L9_5s:
2208 1.1 is bsr.l stand # operand is a DENORM
2209 1.1 is _L9_6s:
2210 1.1 is
2211 1.1 is #
2212 1.1 is # Result is now in FP0
2213 1.1 is #
2214 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2215 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2216 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2217 1.1 is unlk %a6
2218 1.1 is rts
2219 1.1 is
2220 1.1 is global _ftand_
2221 1.1 is _ftand_:
2222 1.1 is link %a6,&-LOCAL_SIZE
2223 1.1 is
2224 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2225 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2226 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2227 1.1 is
2228 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2229 1.1 is
2230 1.1 is #
2231 1.1 is # copy, convert, and tag input argument
2232 1.1 is #
2233 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
2234 1.1 is fmov.x %fp0,FP_SRC(%a6)
2235 1.1 is lea FP_SRC(%a6),%a0
2236 1.1 is bsr.l tag # fetch operand type
2237 1.1 is mov.b %d0,STAG(%a6)
2238 1.1 is mov.b %d0,%d1
2239 1.1 is
2240 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2241 1.1 is
2242 1.1 is clr.l %d0
2243 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2244 1.1 is
2245 1.1 is mov.b %d1,STAG(%a6)
2246 1.1 is tst.b %d1
2247 1.1 is bne.b _L9_2d
2248 1.1 is bsr.l stan # operand is a NORM
2249 1.1 is bra.b _L9_6d
2250 1.1 is _L9_2d:
2251 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2252 1.1 is bne.b _L9_3d # no
2253 1.1 is bsr.l src_zero # yes
2254 1.1 is bra.b _L9_6d
2255 1.1 is _L9_3d:
2256 1.1 is cmpi.b %d1,&INF # is operand an INF?
2257 1.1 is bne.b _L9_4d # no
2258 1.1 is bsr.l t_operr # yes
2259 1.1 is bra.b _L9_6d
2260 1.1 is _L9_4d:
2261 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2262 1.1 is bne.b _L9_5d # no
2263 1.1 is bsr.l src_qnan # yes
2264 1.1 is bra.b _L9_6d
2265 1.1 is _L9_5d:
2266 1.1 is bsr.l stand # operand is a DENORM
2267 1.1 is _L9_6d:
2268 1.1 is
2269 1.1 is #
2270 1.1 is # Result is now in FP0
2271 1.1 is #
2272 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2273 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2274 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2275 1.1 is unlk %a6
2276 1.1 is rts
2277 1.1 is
2278 1.1 is global _ftanx_
2279 1.1 is _ftanx_:
2280 1.1 is link %a6,&-LOCAL_SIZE
2281 1.1 is
2282 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2283 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2284 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2285 1.1 is
2286 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2287 1.1 is
2288 1.1 is #
2289 1.1 is # copy, convert, and tag input argument
2290 1.1 is #
2291 1.1 is lea FP_SRC(%a6),%a0
2292 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
2293 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
2294 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
2295 1.1 is bsr.l tag # fetch operand type
2296 1.1 is mov.b %d0,STAG(%a6)
2297 1.1 is mov.b %d0,%d1
2298 1.1 is
2299 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2300 1.1 is
2301 1.1 is clr.l %d0
2302 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2303 1.1 is
2304 1.1 is tst.b %d1
2305 1.1 is bne.b _L9_2x
2306 1.1 is bsr.l stan # operand is a NORM
2307 1.1 is bra.b _L9_6x
2308 1.1 is _L9_2x:
2309 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2310 1.1 is bne.b _L9_3x # no
2311 1.1 is bsr.l src_zero # yes
2312 1.1 is bra.b _L9_6x
2313 1.1 is _L9_3x:
2314 1.1 is cmpi.b %d1,&INF # is operand an INF?
2315 1.1 is bne.b _L9_4x # no
2316 1.1 is bsr.l t_operr # yes
2317 1.1 is bra.b _L9_6x
2318 1.1 is _L9_4x:
2319 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2320 1.1 is bne.b _L9_5x # no
2321 1.1 is bsr.l src_qnan # yes
2322 1.1 is bra.b _L9_6x
2323 1.1 is _L9_5x:
2324 1.1 is bsr.l stand # operand is a DENORM
2325 1.1 is _L9_6x:
2326 1.1 is
2327 1.1 is #
2328 1.1 is # Result is now in FP0
2329 1.1 is #
2330 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2331 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2332 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2333 1.1 is unlk %a6
2334 1.1 is rts
2335 1.1 is
2336 1.1 is
2337 1.1 is #########################################################################
2338 1.1 is # MONADIC TEMPLATE #
2339 1.1 is #########################################################################
2340 1.1 is global _fetoxs_
2341 1.1 is _fetoxs_:
2342 1.1 is link %a6,&-LOCAL_SIZE
2343 1.1 is
2344 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2345 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2346 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2347 1.1 is
2348 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2349 1.1 is
2350 1.1 is #
2351 1.1 is # copy, convert, and tag input argument
2352 1.1 is #
2353 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
2354 1.1 is fmov.x %fp0,FP_SRC(%a6)
2355 1.1 is lea FP_SRC(%a6),%a0
2356 1.1 is bsr.l tag # fetch operand type
2357 1.1 is mov.b %d0,STAG(%a6)
2358 1.1 is mov.b %d0,%d1
2359 1.1 is
2360 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2361 1.1 is
2362 1.1 is clr.l %d0
2363 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2364 1.1 is
2365 1.1 is tst.b %d1
2366 1.1 is bne.b _L10_2s
2367 1.1 is bsr.l setox # operand is a NORM
2368 1.1 is bra.b _L10_6s
2369 1.1 is _L10_2s:
2370 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2371 1.1 is bne.b _L10_3s # no
2372 1.1 is bsr.l ld_pone # yes
2373 1.1 is bra.b _L10_6s
2374 1.1 is _L10_3s:
2375 1.1 is cmpi.b %d1,&INF # is operand an INF?
2376 1.1 is bne.b _L10_4s # no
2377 1.1 is bsr.l szr_inf # yes
2378 1.1 is bra.b _L10_6s
2379 1.1 is _L10_4s:
2380 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2381 1.1 is bne.b _L10_5s # no
2382 1.1 is bsr.l src_qnan # yes
2383 1.1 is bra.b _L10_6s
2384 1.1 is _L10_5s:
2385 1.1 is bsr.l setoxd # operand is a DENORM
2386 1.1 is _L10_6s:
2387 1.1 is
2388 1.1 is #
2389 1.1 is # Result is now in FP0
2390 1.1 is #
2391 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2392 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2393 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2394 1.1 is unlk %a6
2395 1.1 is rts
2396 1.1 is
2397 1.1 is global _fetoxd_
2398 1.1 is _fetoxd_:
2399 1.1 is link %a6,&-LOCAL_SIZE
2400 1.1 is
2401 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2402 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2403 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2404 1.1 is
2405 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2406 1.1 is
2407 1.1 is #
2408 1.1 is # copy, convert, and tag input argument
2409 1.1 is #
2410 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
2411 1.1 is fmov.x %fp0,FP_SRC(%a6)
2412 1.1 is lea FP_SRC(%a6),%a0
2413 1.1 is bsr.l tag # fetch operand type
2414 1.1 is mov.b %d0,STAG(%a6)
2415 1.1 is mov.b %d0,%d1
2416 1.1 is
2417 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2418 1.1 is
2419 1.1 is clr.l %d0
2420 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2421 1.1 is
2422 1.1 is mov.b %d1,STAG(%a6)
2423 1.1 is tst.b %d1
2424 1.1 is bne.b _L10_2d
2425 1.1 is bsr.l setox # operand is a NORM
2426 1.1 is bra.b _L10_6d
2427 1.1 is _L10_2d:
2428 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2429 1.1 is bne.b _L10_3d # no
2430 1.1 is bsr.l ld_pone # yes
2431 1.1 is bra.b _L10_6d
2432 1.1 is _L10_3d:
2433 1.1 is cmpi.b %d1,&INF # is operand an INF?
2434 1.1 is bne.b _L10_4d # no
2435 1.1 is bsr.l szr_inf # yes
2436 1.1 is bra.b _L10_6d
2437 1.1 is _L10_4d:
2438 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2439 1.1 is bne.b _L10_5d # no
2440 1.1 is bsr.l src_qnan # yes
2441 1.1 is bra.b _L10_6d
2442 1.1 is _L10_5d:
2443 1.1 is bsr.l setoxd # operand is a DENORM
2444 1.1 is _L10_6d:
2445 1.1 is
2446 1.1 is #
2447 1.1 is # Result is now in FP0
2448 1.1 is #
2449 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2450 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2451 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2452 1.1 is unlk %a6
2453 1.1 is rts
2454 1.1 is
2455 1.1 is global _fetoxx_
2456 1.1 is _fetoxx_:
2457 1.1 is link %a6,&-LOCAL_SIZE
2458 1.1 is
2459 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2460 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2461 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2462 1.1 is
2463 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2464 1.1 is
2465 1.1 is #
2466 1.1 is # copy, convert, and tag input argument
2467 1.1 is #
2468 1.1 is lea FP_SRC(%a6),%a0
2469 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
2470 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
2471 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
2472 1.1 is bsr.l tag # fetch operand type
2473 1.1 is mov.b %d0,STAG(%a6)
2474 1.1 is mov.b %d0,%d1
2475 1.1 is
2476 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2477 1.1 is
2478 1.1 is clr.l %d0
2479 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2480 1.1 is
2481 1.1 is tst.b %d1
2482 1.1 is bne.b _L10_2x
2483 1.1 is bsr.l setox # operand is a NORM
2484 1.1 is bra.b _L10_6x
2485 1.1 is _L10_2x:
2486 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2487 1.1 is bne.b _L10_3x # no
2488 1.1 is bsr.l ld_pone # yes
2489 1.1 is bra.b _L10_6x
2490 1.1 is _L10_3x:
2491 1.1 is cmpi.b %d1,&INF # is operand an INF?
2492 1.1 is bne.b _L10_4x # no
2493 1.1 is bsr.l szr_inf # yes
2494 1.1 is bra.b _L10_6x
2495 1.1 is _L10_4x:
2496 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2497 1.1 is bne.b _L10_5x # no
2498 1.1 is bsr.l src_qnan # yes
2499 1.1 is bra.b _L10_6x
2500 1.1 is _L10_5x:
2501 1.1 is bsr.l setoxd # operand is a DENORM
2502 1.1 is _L10_6x:
2503 1.1 is
2504 1.1 is #
2505 1.1 is # Result is now in FP0
2506 1.1 is #
2507 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2508 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2509 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2510 1.1 is unlk %a6
2511 1.1 is rts
2512 1.1 is
2513 1.1 is
2514 1.1 is #########################################################################
2515 1.1 is # MONADIC TEMPLATE #
2516 1.1 is #########################################################################
2517 1.1 is global _ftwotoxs_
2518 1.1 is _ftwotoxs_:
2519 1.1 is link %a6,&-LOCAL_SIZE
2520 1.1 is
2521 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2522 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2523 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2524 1.1 is
2525 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2526 1.1 is
2527 1.1 is #
2528 1.1 is # copy, convert, and tag input argument
2529 1.1 is #
2530 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
2531 1.1 is fmov.x %fp0,FP_SRC(%a6)
2532 1.1 is lea FP_SRC(%a6),%a0
2533 1.1 is bsr.l tag # fetch operand type
2534 1.1 is mov.b %d0,STAG(%a6)
2535 1.1 is mov.b %d0,%d1
2536 1.1 is
2537 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2538 1.1 is
2539 1.1 is clr.l %d0
2540 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2541 1.1 is
2542 1.1 is tst.b %d1
2543 1.1 is bne.b _L11_2s
2544 1.1 is bsr.l stwotox # operand is a NORM
2545 1.1 is bra.b _L11_6s
2546 1.1 is _L11_2s:
2547 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2548 1.1 is bne.b _L11_3s # no
2549 1.1 is bsr.l ld_pone # yes
2550 1.1 is bra.b _L11_6s
2551 1.1 is _L11_3s:
2552 1.1 is cmpi.b %d1,&INF # is operand an INF?
2553 1.1 is bne.b _L11_4s # no
2554 1.1 is bsr.l szr_inf # yes
2555 1.1 is bra.b _L11_6s
2556 1.1 is _L11_4s:
2557 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2558 1.1 is bne.b _L11_5s # no
2559 1.1 is bsr.l src_qnan # yes
2560 1.1 is bra.b _L11_6s
2561 1.1 is _L11_5s:
2562 1.1 is bsr.l stwotoxd # operand is a DENORM
2563 1.1 is _L11_6s:
2564 1.1 is
2565 1.1 is #
2566 1.1 is # Result is now in FP0
2567 1.1 is #
2568 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2569 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2570 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2571 1.1 is unlk %a6
2572 1.1 is rts
2573 1.1 is
2574 1.1 is global _ftwotoxd_
2575 1.1 is _ftwotoxd_:
2576 1.1 is link %a6,&-LOCAL_SIZE
2577 1.1 is
2578 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2579 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2580 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2581 1.1 is
2582 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2583 1.1 is
2584 1.1 is #
2585 1.1 is # copy, convert, and tag input argument
2586 1.1 is #
2587 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
2588 1.1 is fmov.x %fp0,FP_SRC(%a6)
2589 1.1 is lea FP_SRC(%a6),%a0
2590 1.1 is bsr.l tag # fetch operand type
2591 1.1 is mov.b %d0,STAG(%a6)
2592 1.1 is mov.b %d0,%d1
2593 1.1 is
2594 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2595 1.1 is
2596 1.1 is clr.l %d0
2597 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2598 1.1 is
2599 1.1 is mov.b %d1,STAG(%a6)
2600 1.1 is tst.b %d1
2601 1.1 is bne.b _L11_2d
2602 1.1 is bsr.l stwotox # operand is a NORM
2603 1.1 is bra.b _L11_6d
2604 1.1 is _L11_2d:
2605 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2606 1.1 is bne.b _L11_3d # no
2607 1.1 is bsr.l ld_pone # yes
2608 1.1 is bra.b _L11_6d
2609 1.1 is _L11_3d:
2610 1.1 is cmpi.b %d1,&INF # is operand an INF?
2611 1.1 is bne.b _L11_4d # no
2612 1.1 is bsr.l szr_inf # yes
2613 1.1 is bra.b _L11_6d
2614 1.1 is _L11_4d:
2615 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2616 1.1 is bne.b _L11_5d # no
2617 1.1 is bsr.l src_qnan # yes
2618 1.1 is bra.b _L11_6d
2619 1.1 is _L11_5d:
2620 1.1 is bsr.l stwotoxd # operand is a DENORM
2621 1.1 is _L11_6d:
2622 1.1 is
2623 1.1 is #
2624 1.1 is # Result is now in FP0
2625 1.1 is #
2626 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2627 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2628 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2629 1.1 is unlk %a6
2630 1.1 is rts
2631 1.1 is
2632 1.1 is global _ftwotoxx_
2633 1.1 is _ftwotoxx_:
2634 1.1 is link %a6,&-LOCAL_SIZE
2635 1.1 is
2636 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2637 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2638 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2639 1.1 is
2640 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2641 1.1 is
2642 1.1 is #
2643 1.1 is # copy, convert, and tag input argument
2644 1.1 is #
2645 1.1 is lea FP_SRC(%a6),%a0
2646 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
2647 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
2648 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
2649 1.1 is bsr.l tag # fetch operand type
2650 1.1 is mov.b %d0,STAG(%a6)
2651 1.1 is mov.b %d0,%d1
2652 1.1 is
2653 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2654 1.1 is
2655 1.1 is clr.l %d0
2656 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2657 1.1 is
2658 1.1 is tst.b %d1
2659 1.1 is bne.b _L11_2x
2660 1.1 is bsr.l stwotox # operand is a NORM
2661 1.1 is bra.b _L11_6x
2662 1.1 is _L11_2x:
2663 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2664 1.1 is bne.b _L11_3x # no
2665 1.1 is bsr.l ld_pone # yes
2666 1.1 is bra.b _L11_6x
2667 1.1 is _L11_3x:
2668 1.1 is cmpi.b %d1,&INF # is operand an INF?
2669 1.1 is bne.b _L11_4x # no
2670 1.1 is bsr.l szr_inf # yes
2671 1.1 is bra.b _L11_6x
2672 1.1 is _L11_4x:
2673 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2674 1.1 is bne.b _L11_5x # no
2675 1.1 is bsr.l src_qnan # yes
2676 1.1 is bra.b _L11_6x
2677 1.1 is _L11_5x:
2678 1.1 is bsr.l stwotoxd # operand is a DENORM
2679 1.1 is _L11_6x:
2680 1.1 is
2681 1.1 is #
2682 1.1 is # Result is now in FP0
2683 1.1 is #
2684 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2685 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2686 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2687 1.1 is unlk %a6
2688 1.1 is rts
2689 1.1 is
2690 1.1 is
2691 1.1 is #########################################################################
2692 1.1 is # MONADIC TEMPLATE #
2693 1.1 is #########################################################################
2694 1.1 is global _ftentoxs_
2695 1.1 is _ftentoxs_:
2696 1.1 is link %a6,&-LOCAL_SIZE
2697 1.1 is
2698 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2699 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2700 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2701 1.1 is
2702 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2703 1.1 is
2704 1.1 is #
2705 1.1 is # copy, convert, and tag input argument
2706 1.1 is #
2707 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
2708 1.1 is fmov.x %fp0,FP_SRC(%a6)
2709 1.1 is lea FP_SRC(%a6),%a0
2710 1.1 is bsr.l tag # fetch operand type
2711 1.1 is mov.b %d0,STAG(%a6)
2712 1.1 is mov.b %d0,%d1
2713 1.1 is
2714 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2715 1.1 is
2716 1.1 is clr.l %d0
2717 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2718 1.1 is
2719 1.1 is tst.b %d1
2720 1.1 is bne.b _L12_2s
2721 1.1 is bsr.l stentox # operand is a NORM
2722 1.1 is bra.b _L12_6s
2723 1.1 is _L12_2s:
2724 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2725 1.1 is bne.b _L12_3s # no
2726 1.1 is bsr.l ld_pone # yes
2727 1.1 is bra.b _L12_6s
2728 1.1 is _L12_3s:
2729 1.1 is cmpi.b %d1,&INF # is operand an INF?
2730 1.1 is bne.b _L12_4s # no
2731 1.1 is bsr.l szr_inf # yes
2732 1.1 is bra.b _L12_6s
2733 1.1 is _L12_4s:
2734 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2735 1.1 is bne.b _L12_5s # no
2736 1.1 is bsr.l src_qnan # yes
2737 1.1 is bra.b _L12_6s
2738 1.1 is _L12_5s:
2739 1.1 is bsr.l stentoxd # operand is a DENORM
2740 1.1 is _L12_6s:
2741 1.1 is
2742 1.1 is #
2743 1.1 is # Result is now in FP0
2744 1.1 is #
2745 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2746 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2747 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2748 1.1 is unlk %a6
2749 1.1 is rts
2750 1.1 is
2751 1.1 is global _ftentoxd_
2752 1.1 is _ftentoxd_:
2753 1.1 is link %a6,&-LOCAL_SIZE
2754 1.1 is
2755 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2756 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2757 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2758 1.1 is
2759 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2760 1.1 is
2761 1.1 is #
2762 1.1 is # copy, convert, and tag input argument
2763 1.1 is #
2764 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
2765 1.1 is fmov.x %fp0,FP_SRC(%a6)
2766 1.1 is lea FP_SRC(%a6),%a0
2767 1.1 is bsr.l tag # fetch operand type
2768 1.1 is mov.b %d0,STAG(%a6)
2769 1.1 is mov.b %d0,%d1
2770 1.1 is
2771 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2772 1.1 is
2773 1.1 is clr.l %d0
2774 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2775 1.1 is
2776 1.1 is mov.b %d1,STAG(%a6)
2777 1.1 is tst.b %d1
2778 1.1 is bne.b _L12_2d
2779 1.1 is bsr.l stentox # operand is a NORM
2780 1.1 is bra.b _L12_6d
2781 1.1 is _L12_2d:
2782 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2783 1.1 is bne.b _L12_3d # no
2784 1.1 is bsr.l ld_pone # yes
2785 1.1 is bra.b _L12_6d
2786 1.1 is _L12_3d:
2787 1.1 is cmpi.b %d1,&INF # is operand an INF?
2788 1.1 is bne.b _L12_4d # no
2789 1.1 is bsr.l szr_inf # yes
2790 1.1 is bra.b _L12_6d
2791 1.1 is _L12_4d:
2792 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2793 1.1 is bne.b _L12_5d # no
2794 1.1 is bsr.l src_qnan # yes
2795 1.1 is bra.b _L12_6d
2796 1.1 is _L12_5d:
2797 1.1 is bsr.l stentoxd # operand is a DENORM
2798 1.1 is _L12_6d:
2799 1.1 is
2800 1.1 is #
2801 1.1 is # Result is now in FP0
2802 1.1 is #
2803 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2804 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2805 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2806 1.1 is unlk %a6
2807 1.1 is rts
2808 1.1 is
2809 1.1 is global _ftentoxx_
2810 1.1 is _ftentoxx_:
2811 1.1 is link %a6,&-LOCAL_SIZE
2812 1.1 is
2813 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2814 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2815 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2816 1.1 is
2817 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2818 1.1 is
2819 1.1 is #
2820 1.1 is # copy, convert, and tag input argument
2821 1.1 is #
2822 1.1 is lea FP_SRC(%a6),%a0
2823 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
2824 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
2825 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
2826 1.1 is bsr.l tag # fetch operand type
2827 1.1 is mov.b %d0,STAG(%a6)
2828 1.1 is mov.b %d0,%d1
2829 1.1 is
2830 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2831 1.1 is
2832 1.1 is clr.l %d0
2833 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2834 1.1 is
2835 1.1 is tst.b %d1
2836 1.1 is bne.b _L12_2x
2837 1.1 is bsr.l stentox # operand is a NORM
2838 1.1 is bra.b _L12_6x
2839 1.1 is _L12_2x:
2840 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2841 1.1 is bne.b _L12_3x # no
2842 1.1 is bsr.l ld_pone # yes
2843 1.1 is bra.b _L12_6x
2844 1.1 is _L12_3x:
2845 1.1 is cmpi.b %d1,&INF # is operand an INF?
2846 1.1 is bne.b _L12_4x # no
2847 1.1 is bsr.l szr_inf # yes
2848 1.1 is bra.b _L12_6x
2849 1.1 is _L12_4x:
2850 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2851 1.1 is bne.b _L12_5x # no
2852 1.1 is bsr.l src_qnan # yes
2853 1.1 is bra.b _L12_6x
2854 1.1 is _L12_5x:
2855 1.1 is bsr.l stentoxd # operand is a DENORM
2856 1.1 is _L12_6x:
2857 1.1 is
2858 1.1 is #
2859 1.1 is # Result is now in FP0
2860 1.1 is #
2861 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2862 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2863 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2864 1.1 is unlk %a6
2865 1.1 is rts
2866 1.1 is
2867 1.1 is
2868 1.1 is #########################################################################
2869 1.1 is # MONADIC TEMPLATE #
2870 1.1 is #########################################################################
2871 1.1 is global _flogns_
2872 1.1 is _flogns_:
2873 1.1 is link %a6,&-LOCAL_SIZE
2874 1.1 is
2875 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2876 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2877 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2878 1.1 is
2879 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2880 1.1 is
2881 1.1 is #
2882 1.1 is # copy, convert, and tag input argument
2883 1.1 is #
2884 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
2885 1.1 is fmov.x %fp0,FP_SRC(%a6)
2886 1.1 is lea FP_SRC(%a6),%a0
2887 1.1 is bsr.l tag # fetch operand type
2888 1.1 is mov.b %d0,STAG(%a6)
2889 1.1 is mov.b %d0,%d1
2890 1.1 is
2891 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2892 1.1 is
2893 1.1 is clr.l %d0
2894 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2895 1.1 is
2896 1.1 is tst.b %d1
2897 1.1 is bne.b _L13_2s
2898 1.1 is bsr.l slogn # operand is a NORM
2899 1.1 is bra.b _L13_6s
2900 1.1 is _L13_2s:
2901 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2902 1.1 is bne.b _L13_3s # no
2903 1.1 is bsr.l t_dz2 # yes
2904 1.1 is bra.b _L13_6s
2905 1.1 is _L13_3s:
2906 1.1 is cmpi.b %d1,&INF # is operand an INF?
2907 1.1 is bne.b _L13_4s # no
2908 1.1 is bsr.l sopr_inf # yes
2909 1.1 is bra.b _L13_6s
2910 1.1 is _L13_4s:
2911 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2912 1.1 is bne.b _L13_5s # no
2913 1.1 is bsr.l src_qnan # yes
2914 1.1 is bra.b _L13_6s
2915 1.1 is _L13_5s:
2916 1.1 is bsr.l slognd # operand is a DENORM
2917 1.1 is _L13_6s:
2918 1.1 is
2919 1.1 is #
2920 1.1 is # Result is now in FP0
2921 1.1 is #
2922 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2923 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2924 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2925 1.1 is unlk %a6
2926 1.1 is rts
2927 1.1 is
2928 1.1 is global _flognd_
2929 1.1 is _flognd_:
2930 1.1 is link %a6,&-LOCAL_SIZE
2931 1.1 is
2932 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2933 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2934 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2935 1.1 is
2936 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2937 1.1 is
2938 1.1 is #
2939 1.1 is # copy, convert, and tag input argument
2940 1.1 is #
2941 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
2942 1.1 is fmov.x %fp0,FP_SRC(%a6)
2943 1.1 is lea FP_SRC(%a6),%a0
2944 1.1 is bsr.l tag # fetch operand type
2945 1.1 is mov.b %d0,STAG(%a6)
2946 1.1 is mov.b %d0,%d1
2947 1.1 is
2948 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
2949 1.1 is
2950 1.1 is clr.l %d0
2951 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
2952 1.1 is
2953 1.1 is mov.b %d1,STAG(%a6)
2954 1.1 is tst.b %d1
2955 1.1 is bne.b _L13_2d
2956 1.1 is bsr.l slogn # operand is a NORM
2957 1.1 is bra.b _L13_6d
2958 1.1 is _L13_2d:
2959 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
2960 1.1 is bne.b _L13_3d # no
2961 1.1 is bsr.l t_dz2 # yes
2962 1.1 is bra.b _L13_6d
2963 1.1 is _L13_3d:
2964 1.1 is cmpi.b %d1,&INF # is operand an INF?
2965 1.1 is bne.b _L13_4d # no
2966 1.1 is bsr.l sopr_inf # yes
2967 1.1 is bra.b _L13_6d
2968 1.1 is _L13_4d:
2969 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
2970 1.1 is bne.b _L13_5d # no
2971 1.1 is bsr.l src_qnan # yes
2972 1.1 is bra.b _L13_6d
2973 1.1 is _L13_5d:
2974 1.1 is bsr.l slognd # operand is a DENORM
2975 1.1 is _L13_6d:
2976 1.1 is
2977 1.1 is #
2978 1.1 is # Result is now in FP0
2979 1.1 is #
2980 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
2981 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2982 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
2983 1.1 is unlk %a6
2984 1.1 is rts
2985 1.1 is
2986 1.1 is global _flognx_
2987 1.1 is _flognx_:
2988 1.1 is link %a6,&-LOCAL_SIZE
2989 1.1 is
2990 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
2991 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2992 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
2993 1.1 is
2994 1.1 is fmov.l &0x0,%fpcr # zero FPCR
2995 1.1 is
2996 1.1 is #
2997 1.1 is # copy, convert, and tag input argument
2998 1.1 is #
2999 1.1 is lea FP_SRC(%a6),%a0
3000 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
3001 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
3002 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
3003 1.1 is bsr.l tag # fetch operand type
3004 1.1 is mov.b %d0,STAG(%a6)
3005 1.1 is mov.b %d0,%d1
3006 1.1 is
3007 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3008 1.1 is
3009 1.1 is clr.l %d0
3010 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3011 1.1 is
3012 1.1 is tst.b %d1
3013 1.1 is bne.b _L13_2x
3014 1.1 is bsr.l slogn # operand is a NORM
3015 1.1 is bra.b _L13_6x
3016 1.1 is _L13_2x:
3017 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3018 1.1 is bne.b _L13_3x # no
3019 1.1 is bsr.l t_dz2 # yes
3020 1.1 is bra.b _L13_6x
3021 1.1 is _L13_3x:
3022 1.1 is cmpi.b %d1,&INF # is operand an INF?
3023 1.1 is bne.b _L13_4x # no
3024 1.1 is bsr.l sopr_inf # yes
3025 1.1 is bra.b _L13_6x
3026 1.1 is _L13_4x:
3027 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3028 1.1 is bne.b _L13_5x # no
3029 1.1 is bsr.l src_qnan # yes
3030 1.1 is bra.b _L13_6x
3031 1.1 is _L13_5x:
3032 1.1 is bsr.l slognd # operand is a DENORM
3033 1.1 is _L13_6x:
3034 1.1 is
3035 1.1 is #
3036 1.1 is # Result is now in FP0
3037 1.1 is #
3038 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3039 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3040 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3041 1.1 is unlk %a6
3042 1.1 is rts
3043 1.1 is
3044 1.1 is
3045 1.1 is #########################################################################
3046 1.1 is # MONADIC TEMPLATE #
3047 1.1 is #########################################################################
3048 1.1 is global _flog10s_
3049 1.1 is _flog10s_:
3050 1.1 is link %a6,&-LOCAL_SIZE
3051 1.1 is
3052 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3053 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3054 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3055 1.1 is
3056 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3057 1.1 is
3058 1.1 is #
3059 1.1 is # copy, convert, and tag input argument
3060 1.1 is #
3061 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
3062 1.1 is fmov.x %fp0,FP_SRC(%a6)
3063 1.1 is lea FP_SRC(%a6),%a0
3064 1.1 is bsr.l tag # fetch operand type
3065 1.1 is mov.b %d0,STAG(%a6)
3066 1.1 is mov.b %d0,%d1
3067 1.1 is
3068 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3069 1.1 is
3070 1.1 is clr.l %d0
3071 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3072 1.1 is
3073 1.1 is tst.b %d1
3074 1.1 is bne.b _L14_2s
3075 1.1 is bsr.l slog10 # operand is a NORM
3076 1.1 is bra.b _L14_6s
3077 1.1 is _L14_2s:
3078 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3079 1.1 is bne.b _L14_3s # no
3080 1.1 is bsr.l t_dz2 # yes
3081 1.1 is bra.b _L14_6s
3082 1.1 is _L14_3s:
3083 1.1 is cmpi.b %d1,&INF # is operand an INF?
3084 1.1 is bne.b _L14_4s # no
3085 1.1 is bsr.l sopr_inf # yes
3086 1.1 is bra.b _L14_6s
3087 1.1 is _L14_4s:
3088 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3089 1.1 is bne.b _L14_5s # no
3090 1.1 is bsr.l src_qnan # yes
3091 1.1 is bra.b _L14_6s
3092 1.1 is _L14_5s:
3093 1.1 is bsr.l slog10d # operand is a DENORM
3094 1.1 is _L14_6s:
3095 1.1 is
3096 1.1 is #
3097 1.1 is # Result is now in FP0
3098 1.1 is #
3099 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3100 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3101 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3102 1.1 is unlk %a6
3103 1.1 is rts
3104 1.1 is
3105 1.1 is global _flog10d_
3106 1.1 is _flog10d_:
3107 1.1 is link %a6,&-LOCAL_SIZE
3108 1.1 is
3109 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3110 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3111 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3112 1.1 is
3113 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3114 1.1 is
3115 1.1 is #
3116 1.1 is # copy, convert, and tag input argument
3117 1.1 is #
3118 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
3119 1.1 is fmov.x %fp0,FP_SRC(%a6)
3120 1.1 is lea FP_SRC(%a6),%a0
3121 1.1 is bsr.l tag # fetch operand type
3122 1.1 is mov.b %d0,STAG(%a6)
3123 1.1 is mov.b %d0,%d1
3124 1.1 is
3125 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3126 1.1 is
3127 1.1 is clr.l %d0
3128 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3129 1.1 is
3130 1.1 is mov.b %d1,STAG(%a6)
3131 1.1 is tst.b %d1
3132 1.1 is bne.b _L14_2d
3133 1.1 is bsr.l slog10 # operand is a NORM
3134 1.1 is bra.b _L14_6d
3135 1.1 is _L14_2d:
3136 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3137 1.1 is bne.b _L14_3d # no
3138 1.1 is bsr.l t_dz2 # yes
3139 1.1 is bra.b _L14_6d
3140 1.1 is _L14_3d:
3141 1.1 is cmpi.b %d1,&INF # is operand an INF?
3142 1.1 is bne.b _L14_4d # no
3143 1.1 is bsr.l sopr_inf # yes
3144 1.1 is bra.b _L14_6d
3145 1.1 is _L14_4d:
3146 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3147 1.1 is bne.b _L14_5d # no
3148 1.1 is bsr.l src_qnan # yes
3149 1.1 is bra.b _L14_6d
3150 1.1 is _L14_5d:
3151 1.1 is bsr.l slog10d # operand is a DENORM
3152 1.1 is _L14_6d:
3153 1.1 is
3154 1.1 is #
3155 1.1 is # Result is now in FP0
3156 1.1 is #
3157 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3158 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3159 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3160 1.1 is unlk %a6
3161 1.1 is rts
3162 1.1 is
3163 1.1 is global _flog10x_
3164 1.1 is _flog10x_:
3165 1.1 is link %a6,&-LOCAL_SIZE
3166 1.1 is
3167 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3168 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3169 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3170 1.1 is
3171 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3172 1.1 is
3173 1.1 is #
3174 1.1 is # copy, convert, and tag input argument
3175 1.1 is #
3176 1.1 is lea FP_SRC(%a6),%a0
3177 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
3178 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
3179 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
3180 1.1 is bsr.l tag # fetch operand type
3181 1.1 is mov.b %d0,STAG(%a6)
3182 1.1 is mov.b %d0,%d1
3183 1.1 is
3184 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3185 1.1 is
3186 1.1 is clr.l %d0
3187 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3188 1.1 is
3189 1.1 is tst.b %d1
3190 1.1 is bne.b _L14_2x
3191 1.1 is bsr.l slog10 # operand is a NORM
3192 1.1 is bra.b _L14_6x
3193 1.1 is _L14_2x:
3194 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3195 1.1 is bne.b _L14_3x # no
3196 1.1 is bsr.l t_dz2 # yes
3197 1.1 is bra.b _L14_6x
3198 1.1 is _L14_3x:
3199 1.1 is cmpi.b %d1,&INF # is operand an INF?
3200 1.1 is bne.b _L14_4x # no
3201 1.1 is bsr.l sopr_inf # yes
3202 1.1 is bra.b _L14_6x
3203 1.1 is _L14_4x:
3204 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3205 1.1 is bne.b _L14_5x # no
3206 1.1 is bsr.l src_qnan # yes
3207 1.1 is bra.b _L14_6x
3208 1.1 is _L14_5x:
3209 1.1 is bsr.l slog10d # operand is a DENORM
3210 1.1 is _L14_6x:
3211 1.1 is
3212 1.1 is #
3213 1.1 is # Result is now in FP0
3214 1.1 is #
3215 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3216 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3217 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3218 1.1 is unlk %a6
3219 1.1 is rts
3220 1.1 is
3221 1.1 is
3222 1.1 is #########################################################################
3223 1.1 is # MONADIC TEMPLATE #
3224 1.1 is #########################################################################
3225 1.1 is global _flog2s_
3226 1.1 is _flog2s_:
3227 1.1 is link %a6,&-LOCAL_SIZE
3228 1.1 is
3229 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3230 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3231 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3232 1.1 is
3233 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3234 1.1 is
3235 1.1 is #
3236 1.1 is # copy, convert, and tag input argument
3237 1.1 is #
3238 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
3239 1.1 is fmov.x %fp0,FP_SRC(%a6)
3240 1.1 is lea FP_SRC(%a6),%a0
3241 1.1 is bsr.l tag # fetch operand type
3242 1.1 is mov.b %d0,STAG(%a6)
3243 1.1 is mov.b %d0,%d1
3244 1.1 is
3245 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3246 1.1 is
3247 1.1 is clr.l %d0
3248 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3249 1.1 is
3250 1.1 is tst.b %d1
3251 1.1 is bne.b _L15_2s
3252 1.1 is bsr.l slog2 # operand is a NORM
3253 1.1 is bra.b _L15_6s
3254 1.1 is _L15_2s:
3255 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3256 1.1 is bne.b _L15_3s # no
3257 1.1 is bsr.l t_dz2 # yes
3258 1.1 is bra.b _L15_6s
3259 1.1 is _L15_3s:
3260 1.1 is cmpi.b %d1,&INF # is operand an INF?
3261 1.1 is bne.b _L15_4s # no
3262 1.1 is bsr.l sopr_inf # yes
3263 1.1 is bra.b _L15_6s
3264 1.1 is _L15_4s:
3265 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3266 1.1 is bne.b _L15_5s # no
3267 1.1 is bsr.l src_qnan # yes
3268 1.1 is bra.b _L15_6s
3269 1.1 is _L15_5s:
3270 1.1 is bsr.l slog2d # operand is a DENORM
3271 1.1 is _L15_6s:
3272 1.1 is
3273 1.1 is #
3274 1.1 is # Result is now in FP0
3275 1.1 is #
3276 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3277 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3278 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3279 1.1 is unlk %a6
3280 1.1 is rts
3281 1.1 is
3282 1.1 is global _flog2d_
3283 1.1 is _flog2d_:
3284 1.1 is link %a6,&-LOCAL_SIZE
3285 1.1 is
3286 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3287 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3288 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3289 1.1 is
3290 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3291 1.1 is
3292 1.1 is #
3293 1.1 is # copy, convert, and tag input argument
3294 1.1 is #
3295 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
3296 1.1 is fmov.x %fp0,FP_SRC(%a6)
3297 1.1 is lea FP_SRC(%a6),%a0
3298 1.1 is bsr.l tag # fetch operand type
3299 1.1 is mov.b %d0,STAG(%a6)
3300 1.1 is mov.b %d0,%d1
3301 1.1 is
3302 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3303 1.1 is
3304 1.1 is clr.l %d0
3305 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3306 1.1 is
3307 1.1 is mov.b %d1,STAG(%a6)
3308 1.1 is tst.b %d1
3309 1.1 is bne.b _L15_2d
3310 1.1 is bsr.l slog2 # operand is a NORM
3311 1.1 is bra.b _L15_6d
3312 1.1 is _L15_2d:
3313 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3314 1.1 is bne.b _L15_3d # no
3315 1.1 is bsr.l t_dz2 # yes
3316 1.1 is bra.b _L15_6d
3317 1.1 is _L15_3d:
3318 1.1 is cmpi.b %d1,&INF # is operand an INF?
3319 1.1 is bne.b _L15_4d # no
3320 1.1 is bsr.l sopr_inf # yes
3321 1.1 is bra.b _L15_6d
3322 1.1 is _L15_4d:
3323 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3324 1.1 is bne.b _L15_5d # no
3325 1.1 is bsr.l src_qnan # yes
3326 1.1 is bra.b _L15_6d
3327 1.1 is _L15_5d:
3328 1.1 is bsr.l slog2d # operand is a DENORM
3329 1.1 is _L15_6d:
3330 1.1 is
3331 1.1 is #
3332 1.1 is # Result is now in FP0
3333 1.1 is #
3334 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3335 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3336 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3337 1.1 is unlk %a6
3338 1.1 is rts
3339 1.1 is
3340 1.1 is global _flog2x_
3341 1.1 is _flog2x_:
3342 1.1 is link %a6,&-LOCAL_SIZE
3343 1.1 is
3344 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3345 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3346 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3347 1.1 is
3348 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3349 1.1 is
3350 1.1 is #
3351 1.1 is # copy, convert, and tag input argument
3352 1.1 is #
3353 1.1 is lea FP_SRC(%a6),%a0
3354 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
3355 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
3356 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
3357 1.1 is bsr.l tag # fetch operand type
3358 1.1 is mov.b %d0,STAG(%a6)
3359 1.1 is mov.b %d0,%d1
3360 1.1 is
3361 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3362 1.1 is
3363 1.1 is clr.l %d0
3364 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3365 1.1 is
3366 1.1 is tst.b %d1
3367 1.1 is bne.b _L15_2x
3368 1.1 is bsr.l slog2 # operand is a NORM
3369 1.1 is bra.b _L15_6x
3370 1.1 is _L15_2x:
3371 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3372 1.1 is bne.b _L15_3x # no
3373 1.1 is bsr.l t_dz2 # yes
3374 1.1 is bra.b _L15_6x
3375 1.1 is _L15_3x:
3376 1.1 is cmpi.b %d1,&INF # is operand an INF?
3377 1.1 is bne.b _L15_4x # no
3378 1.1 is bsr.l sopr_inf # yes
3379 1.1 is bra.b _L15_6x
3380 1.1 is _L15_4x:
3381 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3382 1.1 is bne.b _L15_5x # no
3383 1.1 is bsr.l src_qnan # yes
3384 1.1 is bra.b _L15_6x
3385 1.1 is _L15_5x:
3386 1.1 is bsr.l slog2d # operand is a DENORM
3387 1.1 is _L15_6x:
3388 1.1 is
3389 1.1 is #
3390 1.1 is # Result is now in FP0
3391 1.1 is #
3392 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3393 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3394 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3395 1.1 is unlk %a6
3396 1.1 is rts
3397 1.1 is
3398 1.1 is
3399 1.1 is #########################################################################
3400 1.1 is # MONADIC TEMPLATE #
3401 1.1 is #########################################################################
3402 1.1 is global _fcoshs_
3403 1.1 is _fcoshs_:
3404 1.1 is link %a6,&-LOCAL_SIZE
3405 1.1 is
3406 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3407 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3408 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3409 1.1 is
3410 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3411 1.1 is
3412 1.1 is #
3413 1.1 is # copy, convert, and tag input argument
3414 1.1 is #
3415 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
3416 1.1 is fmov.x %fp0,FP_SRC(%a6)
3417 1.1 is lea FP_SRC(%a6),%a0
3418 1.1 is bsr.l tag # fetch operand type
3419 1.1 is mov.b %d0,STAG(%a6)
3420 1.1 is mov.b %d0,%d1
3421 1.1 is
3422 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3423 1.1 is
3424 1.1 is clr.l %d0
3425 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3426 1.1 is
3427 1.1 is tst.b %d1
3428 1.1 is bne.b _L16_2s
3429 1.1 is bsr.l scosh # operand is a NORM
3430 1.1 is bra.b _L16_6s
3431 1.1 is _L16_2s:
3432 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3433 1.1 is bne.b _L16_3s # no
3434 1.1 is bsr.l ld_pone # yes
3435 1.1 is bra.b _L16_6s
3436 1.1 is _L16_3s:
3437 1.1 is cmpi.b %d1,&INF # is operand an INF?
3438 1.1 is bne.b _L16_4s # no
3439 1.1 is bsr.l ld_pinf # yes
3440 1.1 is bra.b _L16_6s
3441 1.1 is _L16_4s:
3442 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3443 1.1 is bne.b _L16_5s # no
3444 1.1 is bsr.l src_qnan # yes
3445 1.1 is bra.b _L16_6s
3446 1.1 is _L16_5s:
3447 1.1 is bsr.l scoshd # operand is a DENORM
3448 1.1 is _L16_6s:
3449 1.1 is
3450 1.1 is #
3451 1.1 is # Result is now in FP0
3452 1.1 is #
3453 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3454 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3455 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3456 1.1 is unlk %a6
3457 1.1 is rts
3458 1.1 is
3459 1.1 is global _fcoshd_
3460 1.1 is _fcoshd_:
3461 1.1 is link %a6,&-LOCAL_SIZE
3462 1.1 is
3463 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3464 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3465 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3466 1.1 is
3467 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3468 1.1 is
3469 1.1 is #
3470 1.1 is # copy, convert, and tag input argument
3471 1.1 is #
3472 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
3473 1.1 is fmov.x %fp0,FP_SRC(%a6)
3474 1.1 is lea FP_SRC(%a6),%a0
3475 1.1 is bsr.l tag # fetch operand type
3476 1.1 is mov.b %d0,STAG(%a6)
3477 1.1 is mov.b %d0,%d1
3478 1.1 is
3479 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3480 1.1 is
3481 1.1 is clr.l %d0
3482 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3483 1.1 is
3484 1.1 is mov.b %d1,STAG(%a6)
3485 1.1 is tst.b %d1
3486 1.1 is bne.b _L16_2d
3487 1.1 is bsr.l scosh # operand is a NORM
3488 1.1 is bra.b _L16_6d
3489 1.1 is _L16_2d:
3490 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3491 1.1 is bne.b _L16_3d # no
3492 1.1 is bsr.l ld_pone # yes
3493 1.1 is bra.b _L16_6d
3494 1.1 is _L16_3d:
3495 1.1 is cmpi.b %d1,&INF # is operand an INF?
3496 1.1 is bne.b _L16_4d # no
3497 1.1 is bsr.l ld_pinf # yes
3498 1.1 is bra.b _L16_6d
3499 1.1 is _L16_4d:
3500 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3501 1.1 is bne.b _L16_5d # no
3502 1.1 is bsr.l src_qnan # yes
3503 1.1 is bra.b _L16_6d
3504 1.1 is _L16_5d:
3505 1.1 is bsr.l scoshd # operand is a DENORM
3506 1.1 is _L16_6d:
3507 1.1 is
3508 1.1 is #
3509 1.1 is # Result is now in FP0
3510 1.1 is #
3511 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3512 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3513 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3514 1.1 is unlk %a6
3515 1.1 is rts
3516 1.1 is
3517 1.1 is global _fcoshx_
3518 1.1 is _fcoshx_:
3519 1.1 is link %a6,&-LOCAL_SIZE
3520 1.1 is
3521 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3522 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3523 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3524 1.1 is
3525 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3526 1.1 is
3527 1.1 is #
3528 1.1 is # copy, convert, and tag input argument
3529 1.1 is #
3530 1.1 is lea FP_SRC(%a6),%a0
3531 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
3532 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
3533 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
3534 1.1 is bsr.l tag # fetch operand type
3535 1.1 is mov.b %d0,STAG(%a6)
3536 1.1 is mov.b %d0,%d1
3537 1.1 is
3538 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3539 1.1 is
3540 1.1 is clr.l %d0
3541 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3542 1.1 is
3543 1.1 is tst.b %d1
3544 1.1 is bne.b _L16_2x
3545 1.1 is bsr.l scosh # operand is a NORM
3546 1.1 is bra.b _L16_6x
3547 1.1 is _L16_2x:
3548 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3549 1.1 is bne.b _L16_3x # no
3550 1.1 is bsr.l ld_pone # yes
3551 1.1 is bra.b _L16_6x
3552 1.1 is _L16_3x:
3553 1.1 is cmpi.b %d1,&INF # is operand an INF?
3554 1.1 is bne.b _L16_4x # no
3555 1.1 is bsr.l ld_pinf # yes
3556 1.1 is bra.b _L16_6x
3557 1.1 is _L16_4x:
3558 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3559 1.1 is bne.b _L16_5x # no
3560 1.1 is bsr.l src_qnan # yes
3561 1.1 is bra.b _L16_6x
3562 1.1 is _L16_5x:
3563 1.1 is bsr.l scoshd # operand is a DENORM
3564 1.1 is _L16_6x:
3565 1.1 is
3566 1.1 is #
3567 1.1 is # Result is now in FP0
3568 1.1 is #
3569 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3570 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3571 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3572 1.1 is unlk %a6
3573 1.1 is rts
3574 1.1 is
3575 1.1 is
3576 1.1 is #########################################################################
3577 1.1 is # MONADIC TEMPLATE #
3578 1.1 is #########################################################################
3579 1.1 is global _facoss_
3580 1.1 is _facoss_:
3581 1.1 is link %a6,&-LOCAL_SIZE
3582 1.1 is
3583 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3584 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3585 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3586 1.1 is
3587 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3588 1.1 is
3589 1.1 is #
3590 1.1 is # copy, convert, and tag input argument
3591 1.1 is #
3592 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
3593 1.1 is fmov.x %fp0,FP_SRC(%a6)
3594 1.1 is lea FP_SRC(%a6),%a0
3595 1.1 is bsr.l tag # fetch operand type
3596 1.1 is mov.b %d0,STAG(%a6)
3597 1.1 is mov.b %d0,%d1
3598 1.1 is
3599 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3600 1.1 is
3601 1.1 is clr.l %d0
3602 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3603 1.1 is
3604 1.1 is tst.b %d1
3605 1.1 is bne.b _L17_2s
3606 1.1 is bsr.l sacos # operand is a NORM
3607 1.1 is bra.b _L17_6s
3608 1.1 is _L17_2s:
3609 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3610 1.1 is bne.b _L17_3s # no
3611 1.1 is bsr.l ld_ppi2 # yes
3612 1.1 is bra.b _L17_6s
3613 1.1 is _L17_3s:
3614 1.1 is cmpi.b %d1,&INF # is operand an INF?
3615 1.1 is bne.b _L17_4s # no
3616 1.1 is bsr.l t_operr # yes
3617 1.1 is bra.b _L17_6s
3618 1.1 is _L17_4s:
3619 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3620 1.1 is bne.b _L17_5s # no
3621 1.1 is bsr.l src_qnan # yes
3622 1.1 is bra.b _L17_6s
3623 1.1 is _L17_5s:
3624 1.1 is bsr.l sacosd # operand is a DENORM
3625 1.1 is _L17_6s:
3626 1.1 is
3627 1.1 is #
3628 1.1 is # Result is now in FP0
3629 1.1 is #
3630 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3631 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3632 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3633 1.1 is unlk %a6
3634 1.1 is rts
3635 1.1 is
3636 1.1 is global _facosd_
3637 1.1 is _facosd_:
3638 1.1 is link %a6,&-LOCAL_SIZE
3639 1.1 is
3640 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3641 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3642 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3643 1.1 is
3644 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3645 1.1 is
3646 1.1 is #
3647 1.1 is # copy, convert, and tag input argument
3648 1.1 is #
3649 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
3650 1.1 is fmov.x %fp0,FP_SRC(%a6)
3651 1.1 is lea FP_SRC(%a6),%a0
3652 1.1 is bsr.l tag # fetch operand type
3653 1.1 is mov.b %d0,STAG(%a6)
3654 1.1 is mov.b %d0,%d1
3655 1.1 is
3656 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3657 1.1 is
3658 1.1 is clr.l %d0
3659 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3660 1.1 is
3661 1.1 is mov.b %d1,STAG(%a6)
3662 1.1 is tst.b %d1
3663 1.1 is bne.b _L17_2d
3664 1.1 is bsr.l sacos # operand is a NORM
3665 1.1 is bra.b _L17_6d
3666 1.1 is _L17_2d:
3667 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3668 1.1 is bne.b _L17_3d # no
3669 1.1 is bsr.l ld_ppi2 # yes
3670 1.1 is bra.b _L17_6d
3671 1.1 is _L17_3d:
3672 1.1 is cmpi.b %d1,&INF # is operand an INF?
3673 1.1 is bne.b _L17_4d # no
3674 1.1 is bsr.l t_operr # yes
3675 1.1 is bra.b _L17_6d
3676 1.1 is _L17_4d:
3677 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3678 1.1 is bne.b _L17_5d # no
3679 1.1 is bsr.l src_qnan # yes
3680 1.1 is bra.b _L17_6d
3681 1.1 is _L17_5d:
3682 1.1 is bsr.l sacosd # operand is a DENORM
3683 1.1 is _L17_6d:
3684 1.1 is
3685 1.1 is #
3686 1.1 is # Result is now in FP0
3687 1.1 is #
3688 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3689 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3690 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3691 1.1 is unlk %a6
3692 1.1 is rts
3693 1.1 is
3694 1.1 is global _facosx_
3695 1.1 is _facosx_:
3696 1.1 is link %a6,&-LOCAL_SIZE
3697 1.1 is
3698 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3699 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3700 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3701 1.1 is
3702 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3703 1.1 is
3704 1.1 is #
3705 1.1 is # copy, convert, and tag input argument
3706 1.1 is #
3707 1.1 is lea FP_SRC(%a6),%a0
3708 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
3709 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
3710 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
3711 1.1 is bsr.l tag # fetch operand type
3712 1.1 is mov.b %d0,STAG(%a6)
3713 1.1 is mov.b %d0,%d1
3714 1.1 is
3715 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3716 1.1 is
3717 1.1 is clr.l %d0
3718 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3719 1.1 is
3720 1.1 is tst.b %d1
3721 1.1 is bne.b _L17_2x
3722 1.1 is bsr.l sacos # operand is a NORM
3723 1.1 is bra.b _L17_6x
3724 1.1 is _L17_2x:
3725 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3726 1.1 is bne.b _L17_3x # no
3727 1.1 is bsr.l ld_ppi2 # yes
3728 1.1 is bra.b _L17_6x
3729 1.1 is _L17_3x:
3730 1.1 is cmpi.b %d1,&INF # is operand an INF?
3731 1.1 is bne.b _L17_4x # no
3732 1.1 is bsr.l t_operr # yes
3733 1.1 is bra.b _L17_6x
3734 1.1 is _L17_4x:
3735 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3736 1.1 is bne.b _L17_5x # no
3737 1.1 is bsr.l src_qnan # yes
3738 1.1 is bra.b _L17_6x
3739 1.1 is _L17_5x:
3740 1.1 is bsr.l sacosd # operand is a DENORM
3741 1.1 is _L17_6x:
3742 1.1 is
3743 1.1 is #
3744 1.1 is # Result is now in FP0
3745 1.1 is #
3746 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3747 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3748 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3749 1.1 is unlk %a6
3750 1.1 is rts
3751 1.1 is
3752 1.1 is
3753 1.1 is #########################################################################
3754 1.1 is # MONADIC TEMPLATE #
3755 1.1 is #########################################################################
3756 1.1 is global _fgetexps_
3757 1.1 is _fgetexps_:
3758 1.1 is link %a6,&-LOCAL_SIZE
3759 1.1 is
3760 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3761 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3762 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3763 1.1 is
3764 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3765 1.1 is
3766 1.1 is #
3767 1.1 is # copy, convert, and tag input argument
3768 1.1 is #
3769 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
3770 1.1 is fmov.x %fp0,FP_SRC(%a6)
3771 1.1 is lea FP_SRC(%a6),%a0
3772 1.1 is bsr.l tag # fetch operand type
3773 1.1 is mov.b %d0,STAG(%a6)
3774 1.1 is mov.b %d0,%d1
3775 1.1 is
3776 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3777 1.1 is
3778 1.1 is clr.l %d0
3779 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3780 1.1 is
3781 1.1 is tst.b %d1
3782 1.1 is bne.b _L18_2s
3783 1.1 is bsr.l sgetexp # operand is a NORM
3784 1.1 is bra.b _L18_6s
3785 1.1 is _L18_2s:
3786 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3787 1.1 is bne.b _L18_3s # no
3788 1.1 is bsr.l src_zero # yes
3789 1.1 is bra.b _L18_6s
3790 1.1 is _L18_3s:
3791 1.1 is cmpi.b %d1,&INF # is operand an INF?
3792 1.1 is bne.b _L18_4s # no
3793 1.1 is bsr.l t_operr # yes
3794 1.1 is bra.b _L18_6s
3795 1.1 is _L18_4s:
3796 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3797 1.1 is bne.b _L18_5s # no
3798 1.1 is bsr.l src_qnan # yes
3799 1.1 is bra.b _L18_6s
3800 1.1 is _L18_5s:
3801 1.1 is bsr.l sgetexpd # operand is a DENORM
3802 1.1 is _L18_6s:
3803 1.1 is
3804 1.1 is #
3805 1.1 is # Result is now in FP0
3806 1.1 is #
3807 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3808 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3809 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3810 1.1 is unlk %a6
3811 1.1 is rts
3812 1.1 is
3813 1.1 is global _fgetexpd_
3814 1.1 is _fgetexpd_:
3815 1.1 is link %a6,&-LOCAL_SIZE
3816 1.1 is
3817 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3818 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3819 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3820 1.1 is
3821 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3822 1.1 is
3823 1.1 is #
3824 1.1 is # copy, convert, and tag input argument
3825 1.1 is #
3826 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
3827 1.1 is fmov.x %fp0,FP_SRC(%a6)
3828 1.1 is lea FP_SRC(%a6),%a0
3829 1.1 is bsr.l tag # fetch operand type
3830 1.1 is mov.b %d0,STAG(%a6)
3831 1.1 is mov.b %d0,%d1
3832 1.1 is
3833 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3834 1.1 is
3835 1.1 is clr.l %d0
3836 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3837 1.1 is
3838 1.1 is mov.b %d1,STAG(%a6)
3839 1.1 is tst.b %d1
3840 1.1 is bne.b _L18_2d
3841 1.1 is bsr.l sgetexp # operand is a NORM
3842 1.1 is bra.b _L18_6d
3843 1.1 is _L18_2d:
3844 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3845 1.1 is bne.b _L18_3d # no
3846 1.1 is bsr.l src_zero # yes
3847 1.1 is bra.b _L18_6d
3848 1.1 is _L18_3d:
3849 1.1 is cmpi.b %d1,&INF # is operand an INF?
3850 1.1 is bne.b _L18_4d # no
3851 1.1 is bsr.l t_operr # yes
3852 1.1 is bra.b _L18_6d
3853 1.1 is _L18_4d:
3854 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3855 1.1 is bne.b _L18_5d # no
3856 1.1 is bsr.l src_qnan # yes
3857 1.1 is bra.b _L18_6d
3858 1.1 is _L18_5d:
3859 1.1 is bsr.l sgetexpd # operand is a DENORM
3860 1.1 is _L18_6d:
3861 1.1 is
3862 1.1 is #
3863 1.1 is # Result is now in FP0
3864 1.1 is #
3865 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3866 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3867 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3868 1.1 is unlk %a6
3869 1.1 is rts
3870 1.1 is
3871 1.1 is global _fgetexpx_
3872 1.1 is _fgetexpx_:
3873 1.1 is link %a6,&-LOCAL_SIZE
3874 1.1 is
3875 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3876 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3877 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3878 1.1 is
3879 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3880 1.1 is
3881 1.1 is #
3882 1.1 is # copy, convert, and tag input argument
3883 1.1 is #
3884 1.1 is lea FP_SRC(%a6),%a0
3885 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
3886 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
3887 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
3888 1.1 is bsr.l tag # fetch operand type
3889 1.1 is mov.b %d0,STAG(%a6)
3890 1.1 is mov.b %d0,%d1
3891 1.1 is
3892 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3893 1.1 is
3894 1.1 is clr.l %d0
3895 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3896 1.1 is
3897 1.1 is tst.b %d1
3898 1.1 is bne.b _L18_2x
3899 1.1 is bsr.l sgetexp # operand is a NORM
3900 1.1 is bra.b _L18_6x
3901 1.1 is _L18_2x:
3902 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3903 1.1 is bne.b _L18_3x # no
3904 1.1 is bsr.l src_zero # yes
3905 1.1 is bra.b _L18_6x
3906 1.1 is _L18_3x:
3907 1.1 is cmpi.b %d1,&INF # is operand an INF?
3908 1.1 is bne.b _L18_4x # no
3909 1.1 is bsr.l t_operr # yes
3910 1.1 is bra.b _L18_6x
3911 1.1 is _L18_4x:
3912 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3913 1.1 is bne.b _L18_5x # no
3914 1.1 is bsr.l src_qnan # yes
3915 1.1 is bra.b _L18_6x
3916 1.1 is _L18_5x:
3917 1.1 is bsr.l sgetexpd # operand is a DENORM
3918 1.1 is _L18_6x:
3919 1.1 is
3920 1.1 is #
3921 1.1 is # Result is now in FP0
3922 1.1 is #
3923 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3924 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3925 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3926 1.1 is unlk %a6
3927 1.1 is rts
3928 1.1 is
3929 1.1 is
3930 1.1 is #########################################################################
3931 1.1 is # MONADIC TEMPLATE #
3932 1.1 is #########################################################################
3933 1.1 is global _fgetmans_
3934 1.1 is _fgetmans_:
3935 1.1 is link %a6,&-LOCAL_SIZE
3936 1.1 is
3937 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3938 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3939 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3940 1.1 is
3941 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3942 1.1 is
3943 1.1 is #
3944 1.1 is # copy, convert, and tag input argument
3945 1.1 is #
3946 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
3947 1.1 is fmov.x %fp0,FP_SRC(%a6)
3948 1.1 is lea FP_SRC(%a6),%a0
3949 1.1 is bsr.l tag # fetch operand type
3950 1.1 is mov.b %d0,STAG(%a6)
3951 1.1 is mov.b %d0,%d1
3952 1.1 is
3953 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
3954 1.1 is
3955 1.1 is clr.l %d0
3956 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
3957 1.1 is
3958 1.1 is tst.b %d1
3959 1.1 is bne.b _L19_2s
3960 1.1 is bsr.l sgetman # operand is a NORM
3961 1.1 is bra.b _L19_6s
3962 1.1 is _L19_2s:
3963 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
3964 1.1 is bne.b _L19_3s # no
3965 1.1 is bsr.l src_zero # yes
3966 1.1 is bra.b _L19_6s
3967 1.1 is _L19_3s:
3968 1.1 is cmpi.b %d1,&INF # is operand an INF?
3969 1.1 is bne.b _L19_4s # no
3970 1.1 is bsr.l t_operr # yes
3971 1.1 is bra.b _L19_6s
3972 1.1 is _L19_4s:
3973 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
3974 1.1 is bne.b _L19_5s # no
3975 1.1 is bsr.l src_qnan # yes
3976 1.1 is bra.b _L19_6s
3977 1.1 is _L19_5s:
3978 1.1 is bsr.l sgetmand # operand is a DENORM
3979 1.1 is _L19_6s:
3980 1.1 is
3981 1.1 is #
3982 1.1 is # Result is now in FP0
3983 1.1 is #
3984 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
3985 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3986 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
3987 1.1 is unlk %a6
3988 1.1 is rts
3989 1.1 is
3990 1.1 is global _fgetmand_
3991 1.1 is _fgetmand_:
3992 1.1 is link %a6,&-LOCAL_SIZE
3993 1.1 is
3994 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
3995 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3996 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
3997 1.1 is
3998 1.1 is fmov.l &0x0,%fpcr # zero FPCR
3999 1.1 is
4000 1.1 is #
4001 1.1 is # copy, convert, and tag input argument
4002 1.1 is #
4003 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
4004 1.1 is fmov.x %fp0,FP_SRC(%a6)
4005 1.1 is lea FP_SRC(%a6),%a0
4006 1.1 is bsr.l tag # fetch operand type
4007 1.1 is mov.b %d0,STAG(%a6)
4008 1.1 is mov.b %d0,%d1
4009 1.1 is
4010 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4011 1.1 is
4012 1.1 is clr.l %d0
4013 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4014 1.1 is
4015 1.1 is mov.b %d1,STAG(%a6)
4016 1.1 is tst.b %d1
4017 1.1 is bne.b _L19_2d
4018 1.1 is bsr.l sgetman # operand is a NORM
4019 1.1 is bra.b _L19_6d
4020 1.1 is _L19_2d:
4021 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4022 1.1 is bne.b _L19_3d # no
4023 1.1 is bsr.l src_zero # yes
4024 1.1 is bra.b _L19_6d
4025 1.1 is _L19_3d:
4026 1.1 is cmpi.b %d1,&INF # is operand an INF?
4027 1.1 is bne.b _L19_4d # no
4028 1.1 is bsr.l t_operr # yes
4029 1.1 is bra.b _L19_6d
4030 1.1 is _L19_4d:
4031 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4032 1.1 is bne.b _L19_5d # no
4033 1.1 is bsr.l src_qnan # yes
4034 1.1 is bra.b _L19_6d
4035 1.1 is _L19_5d:
4036 1.1 is bsr.l sgetmand # operand is a DENORM
4037 1.1 is _L19_6d:
4038 1.1 is
4039 1.1 is #
4040 1.1 is # Result is now in FP0
4041 1.1 is #
4042 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4043 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4044 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4045 1.1 is unlk %a6
4046 1.1 is rts
4047 1.1 is
4048 1.1 is global _fgetmanx_
4049 1.1 is _fgetmanx_:
4050 1.1 is link %a6,&-LOCAL_SIZE
4051 1.1 is
4052 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4053 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4054 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4055 1.1 is
4056 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4057 1.1 is
4058 1.1 is #
4059 1.1 is # copy, convert, and tag input argument
4060 1.1 is #
4061 1.1 is lea FP_SRC(%a6),%a0
4062 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
4063 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
4064 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
4065 1.1 is bsr.l tag # fetch operand type
4066 1.1 is mov.b %d0,STAG(%a6)
4067 1.1 is mov.b %d0,%d1
4068 1.1 is
4069 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4070 1.1 is
4071 1.1 is clr.l %d0
4072 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4073 1.1 is
4074 1.1 is tst.b %d1
4075 1.1 is bne.b _L19_2x
4076 1.1 is bsr.l sgetman # operand is a NORM
4077 1.1 is bra.b _L19_6x
4078 1.1 is _L19_2x:
4079 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4080 1.1 is bne.b _L19_3x # no
4081 1.1 is bsr.l src_zero # yes
4082 1.1 is bra.b _L19_6x
4083 1.1 is _L19_3x:
4084 1.1 is cmpi.b %d1,&INF # is operand an INF?
4085 1.1 is bne.b _L19_4x # no
4086 1.1 is bsr.l t_operr # yes
4087 1.1 is bra.b _L19_6x
4088 1.1 is _L19_4x:
4089 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4090 1.1 is bne.b _L19_5x # no
4091 1.1 is bsr.l src_qnan # yes
4092 1.1 is bra.b _L19_6x
4093 1.1 is _L19_5x:
4094 1.1 is bsr.l sgetmand # operand is a DENORM
4095 1.1 is _L19_6x:
4096 1.1 is
4097 1.1 is #
4098 1.1 is # Result is now in FP0
4099 1.1 is #
4100 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4101 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4102 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4103 1.1 is unlk %a6
4104 1.1 is rts
4105 1.1 is
4106 1.1 is
4107 1.1 is #########################################################################
4108 1.1 is # MONADIC TEMPLATE #
4109 1.1 is #########################################################################
4110 1.1 is global _fsincoss_
4111 1.1 is _fsincoss_:
4112 1.1 is link %a6,&-LOCAL_SIZE
4113 1.1 is
4114 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4115 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4116 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4117 1.1 is
4118 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4119 1.1 is
4120 1.1 is #
4121 1.1 is # copy, convert, and tag input argument
4122 1.1 is #
4123 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input
4124 1.1 is fmov.x %fp0,FP_SRC(%a6)
4125 1.1 is lea FP_SRC(%a6),%a0
4126 1.1 is bsr.l tag # fetch operand type
4127 1.1 is mov.b %d0,STAG(%a6)
4128 1.1 is mov.b %d0,%d1
4129 1.1 is
4130 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4131 1.1 is
4132 1.1 is clr.l %d0
4133 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4134 1.1 is
4135 1.1 is tst.b %d1
4136 1.1 is bne.b _L20_2s
4137 1.1 is bsr.l ssincos # operand is a NORM
4138 1.1 is bra.b _L20_6s
4139 1.1 is _L20_2s:
4140 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4141 1.1 is bne.b _L20_3s # no
4142 1.1 is bsr.l ssincosz # yes
4143 1.1 is bra.b _L20_6s
4144 1.1 is _L20_3s:
4145 1.1 is cmpi.b %d1,&INF # is operand an INF?
4146 1.1 is bne.b _L20_4s # no
4147 1.1 is bsr.l ssincosi # yes
4148 1.1 is bra.b _L20_6s
4149 1.1 is _L20_4s:
4150 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4151 1.1 is bne.b _L20_5s # no
4152 1.1 is bsr.l ssincosqnan # yes
4153 1.1 is bra.b _L20_6s
4154 1.1 is _L20_5s:
4155 1.1 is bsr.l ssincosd # operand is a DENORM
4156 1.1 is _L20_6s:
4157 1.1 is
4158 1.1 is #
4159 1.1 is # Result is now in FP0
4160 1.1 is #
4161 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4162 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4163 1.1 is fmovm.x &0x03,-(%sp) # store off fp0/fp1
4164 1.1 is fmovm.x (%sp)+,&0x40 # fp0 now in fp1
4165 1.1 is fmovm.x (%sp)+,&0x80 # fp1 now in fp0
4166 1.1 is unlk %a6
4167 1.1 is rts
4168 1.1 is
4169 1.1 is global _fsincosd_
4170 1.1 is _fsincosd_:
4171 1.1 is link %a6,&-LOCAL_SIZE
4172 1.1 is
4173 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4174 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4175 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4176 1.1 is
4177 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4178 1.1 is
4179 1.1 is #
4180 1.1 is # copy, convert, and tag input argument
4181 1.1 is #
4182 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input
4183 1.1 is fmov.x %fp0,FP_SRC(%a6)
4184 1.1 is lea FP_SRC(%a6),%a0
4185 1.1 is bsr.l tag # fetch operand type
4186 1.1 is mov.b %d0,STAG(%a6)
4187 1.1 is mov.b %d0,%d1
4188 1.1 is
4189 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4190 1.1 is
4191 1.1 is clr.l %d0
4192 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4193 1.1 is
4194 1.1 is mov.b %d1,STAG(%a6)
4195 1.1 is tst.b %d1
4196 1.1 is bne.b _L20_2d
4197 1.1 is bsr.l ssincos # operand is a NORM
4198 1.1 is bra.b _L20_6d
4199 1.1 is _L20_2d:
4200 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4201 1.1 is bne.b _L20_3d # no
4202 1.1 is bsr.l ssincosz # yes
4203 1.1 is bra.b _L20_6d
4204 1.1 is _L20_3d:
4205 1.1 is cmpi.b %d1,&INF # is operand an INF?
4206 1.1 is bne.b _L20_4d # no
4207 1.1 is bsr.l ssincosi # yes
4208 1.1 is bra.b _L20_6d
4209 1.1 is _L20_4d:
4210 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4211 1.1 is bne.b _L20_5d # no
4212 1.1 is bsr.l ssincosqnan # yes
4213 1.1 is bra.b _L20_6d
4214 1.1 is _L20_5d:
4215 1.1 is bsr.l ssincosd # operand is a DENORM
4216 1.1 is _L20_6d:
4217 1.1 is
4218 1.1 is #
4219 1.1 is # Result is now in FP0
4220 1.1 is #
4221 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4222 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4223 1.1 is fmovm.x &0x03,-(%sp) # store off fp0/fp1
4224 1.1 is fmovm.x (%sp)+,&0x40 # fp0 now in fp1
4225 1.1 is fmovm.x (%sp)+,&0x80 # fp1 now in fp0
4226 1.1 is unlk %a6
4227 1.1 is rts
4228 1.1 is
4229 1.1 is global _fsincosx_
4230 1.1 is _fsincosx_:
4231 1.1 is link %a6,&-LOCAL_SIZE
4232 1.1 is
4233 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4234 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4235 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4236 1.1 is
4237 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4238 1.1 is
4239 1.1 is #
4240 1.1 is # copy, convert, and tag input argument
4241 1.1 is #
4242 1.1 is lea FP_SRC(%a6),%a0
4243 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
4244 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
4245 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
4246 1.1 is bsr.l tag # fetch operand type
4247 1.1 is mov.b %d0,STAG(%a6)
4248 1.1 is mov.b %d0,%d1
4249 1.1 is
4250 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4251 1.1 is
4252 1.1 is clr.l %d0
4253 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4254 1.1 is
4255 1.1 is tst.b %d1
4256 1.1 is bne.b _L20_2x
4257 1.1 is bsr.l ssincos # operand is a NORM
4258 1.1 is bra.b _L20_6x
4259 1.1 is _L20_2x:
4260 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4261 1.1 is bne.b _L20_3x # no
4262 1.1 is bsr.l ssincosz # yes
4263 1.1 is bra.b _L20_6x
4264 1.1 is _L20_3x:
4265 1.1 is cmpi.b %d1,&INF # is operand an INF?
4266 1.1 is bne.b _L20_4x # no
4267 1.1 is bsr.l ssincosi # yes
4268 1.1 is bra.b _L20_6x
4269 1.1 is _L20_4x:
4270 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4271 1.1 is bne.b _L20_5x # no
4272 1.1 is bsr.l ssincosqnan # yes
4273 1.1 is bra.b _L20_6x
4274 1.1 is _L20_5x:
4275 1.1 is bsr.l ssincosd # operand is a DENORM
4276 1.1 is _L20_6x:
4277 1.1 is
4278 1.1 is #
4279 1.1 is # Result is now in FP0
4280 1.1 is #
4281 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4282 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4283 1.1 is fmovm.x &0x03,-(%sp) # store off fp0/fp1
4284 1.1 is fmovm.x (%sp)+,&0x40 # fp0 now in fp1
4285 1.1 is fmovm.x (%sp)+,&0x80 # fp1 now in fp0
4286 1.1 is unlk %a6
4287 1.1 is rts
4288 1.1 is
4289 1.1 is
4290 1.1 is #########################################################################
4291 1.1 is # DYADIC TEMPLATE #
4292 1.1 is #########################################################################
4293 1.1 is global _frems_
4294 1.1 is _frems_:
4295 1.1 is link %a6,&-LOCAL_SIZE
4296 1.1 is
4297 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4298 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4299 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4300 1.1 is
4301 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4302 1.1 is
4303 1.1 is #
4304 1.1 is # copy, convert, and tag input argument
4305 1.1 is #
4306 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl dst
4307 1.1 is fmov.x %fp0,FP_DST(%a6)
4308 1.1 is lea FP_DST(%a6),%a0
4309 1.1 is bsr.l tag # fetch operand type
4310 1.1 is mov.b %d0,DTAG(%a6)
4311 1.1 is
4312 1.1 is fmov.s 0xc(%a6),%fp0 # load sgl src
4313 1.1 is fmov.x %fp0,FP_SRC(%a6)
4314 1.1 is lea FP_SRC(%a6),%a0
4315 1.1 is bsr.l tag # fetch operand type
4316 1.1 is mov.b %d0,STAG(%a6)
4317 1.1 is mov.l %d0,%d1
4318 1.1 is
4319 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4320 1.1 is
4321 1.1 is clr.l %d0
4322 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4323 1.1 is
4324 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4325 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4326 1.1 is
4327 1.1 is tst.b %d1
4328 1.1 is bne.b _L21_2s
4329 1.1 is bsr.l srem_snorm # operand is a NORM
4330 1.1 is bra.b _L21_6s
4331 1.1 is _L21_2s:
4332 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4333 1.1 is bne.b _L21_3s # no
4334 1.1 is bsr.l srem_szero # yes
4335 1.1 is bra.b _L21_6s
4336 1.1 is _L21_3s:
4337 1.1 is cmpi.b %d1,&INF # is operand an INF?
4338 1.1 is bne.b _L21_4s # no
4339 1.1 is bsr.l srem_sinf # yes
4340 1.1 is bra.b _L21_6s
4341 1.1 is _L21_4s:
4342 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4343 1.1 is bne.b _L21_5s # no
4344 1.1 is bsr.l sop_sqnan # yes
4345 1.1 is bra.b _L21_6s
4346 1.1 is _L21_5s:
4347 1.1 is bsr.l srem_sdnrm # operand is a DENORM
4348 1.1 is _L21_6s:
4349 1.1 is
4350 1.1 is #
4351 1.1 is # Result is now in FP0
4352 1.1 is #
4353 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4354 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4355 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4356 1.1 is unlk %a6
4357 1.1 is rts
4358 1.1 is
4359 1.1 is global _fremd_
4360 1.1 is _fremd_:
4361 1.1 is link %a6,&-LOCAL_SIZE
4362 1.1 is
4363 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4364 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4365 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4366 1.1 is
4367 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4368 1.1 is
4369 1.1 is #
4370 1.1 is # copy, convert, and tag input argument
4371 1.1 is #
4372 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl dst
4373 1.1 is fmov.x %fp0,FP_DST(%a6)
4374 1.1 is lea FP_DST(%a6),%a0
4375 1.1 is bsr.l tag # fetch operand type
4376 1.1 is mov.b %d0,DTAG(%a6)
4377 1.1 is
4378 1.1 is fmov.d 0x10(%a6),%fp0 # load dbl src
4379 1.1 is fmov.x %fp0,FP_SRC(%a6)
4380 1.1 is lea FP_SRC(%a6),%a0
4381 1.1 is bsr.l tag # fetch operand type
4382 1.1 is mov.b %d0,STAG(%a6)
4383 1.1 is mov.l %d0,%d1
4384 1.1 is
4385 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4386 1.1 is
4387 1.1 is clr.l %d0
4388 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4389 1.1 is
4390 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4391 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4392 1.1 is
4393 1.1 is tst.b %d1
4394 1.1 is bne.b _L21_2d
4395 1.1 is bsr.l srem_snorm # operand is a NORM
4396 1.1 is bra.b _L21_6d
4397 1.1 is _L21_2d:
4398 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4399 1.1 is bne.b _L21_3d # no
4400 1.1 is bsr.l srem_szero # yes
4401 1.1 is bra.b _L21_6d
4402 1.1 is _L21_3d:
4403 1.1 is cmpi.b %d1,&INF # is operand an INF?
4404 1.1 is bne.b _L21_4d # no
4405 1.1 is bsr.l srem_sinf # yes
4406 1.1 is bra.b _L21_6d
4407 1.1 is _L21_4d:
4408 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4409 1.1 is bne.b _L21_5d # no
4410 1.1 is bsr.l sop_sqnan # yes
4411 1.1 is bra.b _L21_6d
4412 1.1 is _L21_5d:
4413 1.1 is bsr.l srem_sdnrm # operand is a DENORM
4414 1.1 is _L21_6d:
4415 1.1 is
4416 1.1 is #
4417 1.1 is # Result is now in FP0
4418 1.1 is #
4419 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4420 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4421 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4422 1.1 is unlk %a6
4423 1.1 is rts
4424 1.1 is
4425 1.1 is global _fremx_
4426 1.1 is _fremx_:
4427 1.1 is link %a6,&-LOCAL_SIZE
4428 1.1 is
4429 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4430 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4431 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4432 1.1 is
4433 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4434 1.1 is
4435 1.1 is #
4436 1.1 is # copy, convert, and tag input argument
4437 1.1 is #
4438 1.1 is lea FP_DST(%a6),%a0
4439 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst
4440 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
4441 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
4442 1.1 is bsr.l tag # fetch operand type
4443 1.1 is mov.b %d0,DTAG(%a6)
4444 1.1 is
4445 1.1 is lea FP_SRC(%a6),%a0
4446 1.1 is mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src
4447 1.1 is mov.l 0x14+0x4(%a6),0x4(%a0)
4448 1.1 is mov.l 0x14+0x8(%a6),0x8(%a0)
4449 1.1 is bsr.l tag # fetch operand type
4450 1.1 is mov.b %d0,STAG(%a6)
4451 1.1 is mov.l %d0,%d1
4452 1.1 is
4453 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4454 1.1 is
4455 1.1 is clr.l %d0
4456 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4457 1.1 is
4458 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4459 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4460 1.1 is
4461 1.1 is tst.b %d1
4462 1.1 is bne.b _L21_2x
4463 1.1 is bsr.l srem_snorm # operand is a NORM
4464 1.1 is bra.b _L21_6x
4465 1.1 is _L21_2x:
4466 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4467 1.1 is bne.b _L21_3x # no
4468 1.1 is bsr.l srem_szero # yes
4469 1.1 is bra.b _L21_6x
4470 1.1 is _L21_3x:
4471 1.1 is cmpi.b %d1,&INF # is operand an INF?
4472 1.1 is bne.b _L21_4x # no
4473 1.1 is bsr.l srem_sinf # yes
4474 1.1 is bra.b _L21_6x
4475 1.1 is _L21_4x:
4476 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4477 1.1 is bne.b _L21_5x # no
4478 1.1 is bsr.l sop_sqnan # yes
4479 1.1 is bra.b _L21_6x
4480 1.1 is _L21_5x:
4481 1.1 is bsr.l srem_sdnrm # operand is a DENORM
4482 1.1 is _L21_6x:
4483 1.1 is
4484 1.1 is #
4485 1.1 is # Result is now in FP0
4486 1.1 is #
4487 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4488 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4489 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4490 1.1 is unlk %a6
4491 1.1 is rts
4492 1.1 is
4493 1.1 is
4494 1.1 is #########################################################################
4495 1.1 is # DYADIC TEMPLATE #
4496 1.1 is #########################################################################
4497 1.1 is global _fmods_
4498 1.1 is _fmods_:
4499 1.1 is link %a6,&-LOCAL_SIZE
4500 1.1 is
4501 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4502 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4503 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4504 1.1 is
4505 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4506 1.1 is
4507 1.1 is #
4508 1.1 is # copy, convert, and tag input argument
4509 1.1 is #
4510 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl dst
4511 1.1 is fmov.x %fp0,FP_DST(%a6)
4512 1.1 is lea FP_DST(%a6),%a0
4513 1.1 is bsr.l tag # fetch operand type
4514 1.1 is mov.b %d0,DTAG(%a6)
4515 1.1 is
4516 1.1 is fmov.s 0xc(%a6),%fp0 # load sgl src
4517 1.1 is fmov.x %fp0,FP_SRC(%a6)
4518 1.1 is lea FP_SRC(%a6),%a0
4519 1.1 is bsr.l tag # fetch operand type
4520 1.1 is mov.b %d0,STAG(%a6)
4521 1.1 is mov.l %d0,%d1
4522 1.1 is
4523 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4524 1.1 is
4525 1.1 is clr.l %d0
4526 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4527 1.1 is
4528 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4529 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4530 1.1 is
4531 1.1 is tst.b %d1
4532 1.1 is bne.b _L22_2s
4533 1.1 is bsr.l smod_snorm # operand is a NORM
4534 1.1 is bra.b _L22_6s
4535 1.1 is _L22_2s:
4536 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4537 1.1 is bne.b _L22_3s # no
4538 1.1 is bsr.l smod_szero # yes
4539 1.1 is bra.b _L22_6s
4540 1.1 is _L22_3s:
4541 1.1 is cmpi.b %d1,&INF # is operand an INF?
4542 1.1 is bne.b _L22_4s # no
4543 1.1 is bsr.l smod_sinf # yes
4544 1.1 is bra.b _L22_6s
4545 1.1 is _L22_4s:
4546 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4547 1.1 is bne.b _L22_5s # no
4548 1.1 is bsr.l sop_sqnan # yes
4549 1.1 is bra.b _L22_6s
4550 1.1 is _L22_5s:
4551 1.1 is bsr.l smod_sdnrm # operand is a DENORM
4552 1.1 is _L22_6s:
4553 1.1 is
4554 1.1 is #
4555 1.1 is # Result is now in FP0
4556 1.1 is #
4557 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4558 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4559 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4560 1.1 is unlk %a6
4561 1.1 is rts
4562 1.1 is
4563 1.1 is global _fmodd_
4564 1.1 is _fmodd_:
4565 1.1 is link %a6,&-LOCAL_SIZE
4566 1.1 is
4567 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4568 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4569 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4570 1.1 is
4571 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4572 1.1 is
4573 1.1 is #
4574 1.1 is # copy, convert, and tag input argument
4575 1.1 is #
4576 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl dst
4577 1.1 is fmov.x %fp0,FP_DST(%a6)
4578 1.1 is lea FP_DST(%a6),%a0
4579 1.1 is bsr.l tag # fetch operand type
4580 1.1 is mov.b %d0,DTAG(%a6)
4581 1.1 is
4582 1.1 is fmov.d 0x10(%a6),%fp0 # load dbl src
4583 1.1 is fmov.x %fp0,FP_SRC(%a6)
4584 1.1 is lea FP_SRC(%a6),%a0
4585 1.1 is bsr.l tag # fetch operand type
4586 1.1 is mov.b %d0,STAG(%a6)
4587 1.1 is mov.l %d0,%d1
4588 1.1 is
4589 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4590 1.1 is
4591 1.1 is clr.l %d0
4592 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4593 1.1 is
4594 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4595 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4596 1.1 is
4597 1.1 is tst.b %d1
4598 1.1 is bne.b _L22_2d
4599 1.1 is bsr.l smod_snorm # operand is a NORM
4600 1.1 is bra.b _L22_6d
4601 1.1 is _L22_2d:
4602 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4603 1.1 is bne.b _L22_3d # no
4604 1.1 is bsr.l smod_szero # yes
4605 1.1 is bra.b _L22_6d
4606 1.1 is _L22_3d:
4607 1.1 is cmpi.b %d1,&INF # is operand an INF?
4608 1.1 is bne.b _L22_4d # no
4609 1.1 is bsr.l smod_sinf # yes
4610 1.1 is bra.b _L22_6d
4611 1.1 is _L22_4d:
4612 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4613 1.1 is bne.b _L22_5d # no
4614 1.1 is bsr.l sop_sqnan # yes
4615 1.1 is bra.b _L22_6d
4616 1.1 is _L22_5d:
4617 1.1 is bsr.l smod_sdnrm # operand is a DENORM
4618 1.1 is _L22_6d:
4619 1.1 is
4620 1.1 is #
4621 1.1 is # Result is now in FP0
4622 1.1 is #
4623 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4624 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4625 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4626 1.1 is unlk %a6
4627 1.1 is rts
4628 1.1 is
4629 1.1 is global _fmodx_
4630 1.1 is _fmodx_:
4631 1.1 is link %a6,&-LOCAL_SIZE
4632 1.1 is
4633 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4634 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4635 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4636 1.1 is
4637 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4638 1.1 is
4639 1.1 is #
4640 1.1 is # copy, convert, and tag input argument
4641 1.1 is #
4642 1.1 is lea FP_DST(%a6),%a0
4643 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst
4644 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
4645 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
4646 1.1 is bsr.l tag # fetch operand type
4647 1.1 is mov.b %d0,DTAG(%a6)
4648 1.1 is
4649 1.1 is lea FP_SRC(%a6),%a0
4650 1.1 is mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src
4651 1.1 is mov.l 0x14+0x4(%a6),0x4(%a0)
4652 1.1 is mov.l 0x14+0x8(%a6),0x8(%a0)
4653 1.1 is bsr.l tag # fetch operand type
4654 1.1 is mov.b %d0,STAG(%a6)
4655 1.1 is mov.l %d0,%d1
4656 1.1 is
4657 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4658 1.1 is
4659 1.1 is clr.l %d0
4660 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4661 1.1 is
4662 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4663 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4664 1.1 is
4665 1.1 is tst.b %d1
4666 1.1 is bne.b _L22_2x
4667 1.1 is bsr.l smod_snorm # operand is a NORM
4668 1.1 is bra.b _L22_6x
4669 1.1 is _L22_2x:
4670 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4671 1.1 is bne.b _L22_3x # no
4672 1.1 is bsr.l smod_szero # yes
4673 1.1 is bra.b _L22_6x
4674 1.1 is _L22_3x:
4675 1.1 is cmpi.b %d1,&INF # is operand an INF?
4676 1.1 is bne.b _L22_4x # no
4677 1.1 is bsr.l smod_sinf # yes
4678 1.1 is bra.b _L22_6x
4679 1.1 is _L22_4x:
4680 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4681 1.1 is bne.b _L22_5x # no
4682 1.1 is bsr.l sop_sqnan # yes
4683 1.1 is bra.b _L22_6x
4684 1.1 is _L22_5x:
4685 1.1 is bsr.l smod_sdnrm # operand is a DENORM
4686 1.1 is _L22_6x:
4687 1.1 is
4688 1.1 is #
4689 1.1 is # Result is now in FP0
4690 1.1 is #
4691 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4692 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4693 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4694 1.1 is unlk %a6
4695 1.1 is rts
4696 1.1 is
4697 1.1 is
4698 1.1 is #########################################################################
4699 1.1 is # DYADIC TEMPLATE #
4700 1.1 is #########################################################################
4701 1.1 is global _fscales_
4702 1.1 is _fscales_:
4703 1.1 is link %a6,&-LOCAL_SIZE
4704 1.1 is
4705 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4706 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4707 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4708 1.1 is
4709 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4710 1.1 is
4711 1.1 is #
4712 1.1 is # copy, convert, and tag input argument
4713 1.1 is #
4714 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl dst
4715 1.1 is fmov.x %fp0,FP_DST(%a6)
4716 1.1 is lea FP_DST(%a6),%a0
4717 1.1 is bsr.l tag # fetch operand type
4718 1.1 is mov.b %d0,DTAG(%a6)
4719 1.1 is
4720 1.1 is fmov.s 0xc(%a6),%fp0 # load sgl src
4721 1.1 is fmov.x %fp0,FP_SRC(%a6)
4722 1.1 is lea FP_SRC(%a6),%a0
4723 1.1 is bsr.l tag # fetch operand type
4724 1.1 is mov.b %d0,STAG(%a6)
4725 1.1 is mov.l %d0,%d1
4726 1.1 is
4727 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4728 1.1 is
4729 1.1 is clr.l %d0
4730 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4731 1.1 is
4732 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4733 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4734 1.1 is
4735 1.1 is tst.b %d1
4736 1.1 is bne.b _L23_2s
4737 1.1 is bsr.l sscale_snorm # operand is a NORM
4738 1.1 is bra.b _L23_6s
4739 1.1 is _L23_2s:
4740 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4741 1.1 is bne.b _L23_3s # no
4742 1.1 is bsr.l sscale_szero # yes
4743 1.1 is bra.b _L23_6s
4744 1.1 is _L23_3s:
4745 1.1 is cmpi.b %d1,&INF # is operand an INF?
4746 1.1 is bne.b _L23_4s # no
4747 1.1 is bsr.l sscale_sinf # yes
4748 1.1 is bra.b _L23_6s
4749 1.1 is _L23_4s:
4750 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4751 1.1 is bne.b _L23_5s # no
4752 1.1 is bsr.l sop_sqnan # yes
4753 1.1 is bra.b _L23_6s
4754 1.1 is _L23_5s:
4755 1.1 is bsr.l sscale_sdnrm # operand is a DENORM
4756 1.1 is _L23_6s:
4757 1.1 is
4758 1.1 is #
4759 1.1 is # Result is now in FP0
4760 1.1 is #
4761 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4762 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4763 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4764 1.1 is unlk %a6
4765 1.1 is rts
4766 1.1 is
4767 1.1 is global _fscaled_
4768 1.1 is _fscaled_:
4769 1.1 is link %a6,&-LOCAL_SIZE
4770 1.1 is
4771 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4772 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4773 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4774 1.1 is
4775 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4776 1.1 is
4777 1.1 is #
4778 1.1 is # copy, convert, and tag input argument
4779 1.1 is #
4780 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl dst
4781 1.1 is fmov.x %fp0,FP_DST(%a6)
4782 1.1 is lea FP_DST(%a6),%a0
4783 1.1 is bsr.l tag # fetch operand type
4784 1.1 is mov.b %d0,DTAG(%a6)
4785 1.1 is
4786 1.1 is fmov.d 0x10(%a6),%fp0 # load dbl src
4787 1.1 is fmov.x %fp0,FP_SRC(%a6)
4788 1.1 is lea FP_SRC(%a6),%a0
4789 1.1 is bsr.l tag # fetch operand type
4790 1.1 is mov.b %d0,STAG(%a6)
4791 1.1 is mov.l %d0,%d1
4792 1.1 is
4793 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4794 1.1 is
4795 1.1 is clr.l %d0
4796 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4797 1.1 is
4798 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4799 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4800 1.1 is
4801 1.1 is tst.b %d1
4802 1.1 is bne.b _L23_2d
4803 1.1 is bsr.l sscale_snorm # operand is a NORM
4804 1.1 is bra.b _L23_6d
4805 1.1 is _L23_2d:
4806 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4807 1.1 is bne.b _L23_3d # no
4808 1.1 is bsr.l sscale_szero # yes
4809 1.1 is bra.b _L23_6d
4810 1.1 is _L23_3d:
4811 1.1 is cmpi.b %d1,&INF # is operand an INF?
4812 1.1 is bne.b _L23_4d # no
4813 1.1 is bsr.l sscale_sinf # yes
4814 1.1 is bra.b _L23_6d
4815 1.1 is _L23_4d:
4816 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4817 1.1 is bne.b _L23_5d # no
4818 1.1 is bsr.l sop_sqnan # yes
4819 1.1 is bra.b _L23_6d
4820 1.1 is _L23_5d:
4821 1.1 is bsr.l sscale_sdnrm # operand is a DENORM
4822 1.1 is _L23_6d:
4823 1.1 is
4824 1.1 is #
4825 1.1 is # Result is now in FP0
4826 1.1 is #
4827 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4828 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4829 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4830 1.1 is unlk %a6
4831 1.1 is rts
4832 1.1 is
4833 1.1 is global _fscalex_
4834 1.1 is _fscalex_:
4835 1.1 is link %a6,&-LOCAL_SIZE
4836 1.1 is
4837 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
4838 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4839 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
4840 1.1 is
4841 1.1 is fmov.l &0x0,%fpcr # zero FPCR
4842 1.1 is
4843 1.1 is #
4844 1.1 is # copy, convert, and tag input argument
4845 1.1 is #
4846 1.1 is lea FP_DST(%a6),%a0
4847 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst
4848 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0)
4849 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0)
4850 1.1 is bsr.l tag # fetch operand type
4851 1.1 is mov.b %d0,DTAG(%a6)
4852 1.1 is
4853 1.1 is lea FP_SRC(%a6),%a0
4854 1.1 is mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src
4855 1.1 is mov.l 0x14+0x4(%a6),0x4(%a0)
4856 1.1 is mov.l 0x14+0x8(%a6),0x8(%a0)
4857 1.1 is bsr.l tag # fetch operand type
4858 1.1 is mov.b %d0,STAG(%a6)
4859 1.1 is mov.l %d0,%d1
4860 1.1 is
4861 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6)
4862 1.1 is
4863 1.1 is clr.l %d0
4864 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
4865 1.1 is
4866 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src
4867 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst
4868 1.1 is
4869 1.1 is tst.b %d1
4870 1.1 is bne.b _L23_2x
4871 1.1 is bsr.l sscale_snorm # operand is a NORM
4872 1.1 is bra.b _L23_6x
4873 1.1 is _L23_2x:
4874 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO?
4875 1.1 is bne.b _L23_3x # no
4876 1.1 is bsr.l sscale_szero # yes
4877 1.1 is bra.b _L23_6x
4878 1.1 is _L23_3x:
4879 1.1 is cmpi.b %d1,&INF # is operand an INF?
4880 1.1 is bne.b _L23_4x # no
4881 1.1 is bsr.l sscale_sinf # yes
4882 1.1 is bra.b _L23_6x
4883 1.1 is _L23_4x:
4884 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN?
4885 1.1 is bne.b _L23_5x # no
4886 1.1 is bsr.l sop_sqnan # yes
4887 1.1 is bra.b _L23_6x
4888 1.1 is _L23_5x:
4889 1.1 is bsr.l sscale_sdnrm # operand is a DENORM
4890 1.1 is _L23_6x:
4891 1.1 is
4892 1.1 is #
4893 1.1 is # Result is now in FP0
4894 1.1 is #
4895 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
4896 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4897 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
4898 1.1 is unlk %a6
4899 1.1 is rts
4900 1.1 is
4901 1.1 is
4902 1.1 is #########################################################################
4903 1.1 is # ssin(): computes the sine of a normalized input #
4904 1.1 is # ssind(): computes the sine of a denormalized input #
4905 1.1 is # scos(): computes the cosine of a normalized input #
4906 1.1 is # scosd(): computes the cosine of a denormalized input #
4907 1.1 is # ssincos(): computes the sine and cosine of a normalized input #
4908 1.1 is # ssincosd(): computes the sine and cosine of a denormalized input #
4909 1.1 is # #
4910 1.1 is # INPUT *************************************************************** #
4911 1.1 is # a0 = pointer to extended precision input #
4912 1.1 is # d0 = round precision,mode #
4913 1.1 is # #
4914 1.1 is # OUTPUT ************************************************************** #
4915 1.1 is # fp0 = sin(X) or cos(X) #
4916 1.1 is # #
4917 1.1 is # For ssincos(X): #
4918 1.1 is # fp0 = sin(X) #
4919 1.1 is # fp1 = cos(X) #
4920 1.1 is # #
4921 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
4922 1.1 is # The returned result is within 1 ulp in 64 significant bit, i.e. #
4923 1.1 is # within 0.5001 ulp to 53 bits if the result is subsequently #
4924 1.1 is # rounded to double precision. The result is provably monotonic #
4925 1.1 is # in double precision. #
4926 1.1 is # #
4927 1.1 is # ALGORITHM *********************************************************** #
4928 1.1 is # #
4929 1.1 is # SIN and COS: #
4930 1.1 is # 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. #
4931 1.1 is # #
4932 1.1 is # 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. #
4933 1.1 is # #
4934 1.1 is # 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
4935 1.1 is # k = N mod 4, so in particular, k = 0,1,2,or 3. #
4936 1.1 is # Overwrite k by k := k + AdjN. #
4937 1.1 is # #
4938 1.1 is # 4. If k is even, go to 6. #
4939 1.1 is # #
4940 1.1 is # 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. #
4941 1.1 is # Return sgn*cos(r) where cos(r) is approximated by an #
4942 1.1 is # even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), #
4943 1.1 is # s = r*r. #
4944 1.1 is # Exit. #
4945 1.1 is # #
4946 1.1 is # 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) #
4947 1.1 is # where sin(r) is approximated by an odd polynomial in r #
4948 1.1 is # r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. #
4949 1.1 is # Exit. #
4950 1.1 is # #
4951 1.1 is # 7. If |X| > 1, go to 9. #
4952 1.1 is # #
4953 1.1 is # 8. (|X|<2**(-40)) If SIN is invoked, return X; #
4954 1.1 is # otherwise return 1. #
4955 1.1 is # #
4956 1.1 is # 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, #
4957 1.1 is # go back to 3. #
4958 1.1 is # #
4959 1.1 is # SINCOS: #
4960 1.1 is # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. #
4961 1.1 is # #
4962 1.1 is # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
4963 1.1 is # k = N mod 4, so in particular, k = 0,1,2,or 3. #
4964 1.1 is # #
4965 1.1 is # 3. If k is even, go to 5. #
4966 1.1 is # #
4967 1.1 is # 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie. #
4968 1.1 is # j1 exclusive or with the l.s.b. of k. #
4969 1.1 is # sgn1 := (-1)**j1, sgn2 := (-1)**j2. #
4970 1.1 is # SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where #
4971 1.1 is # sin(r) and cos(r) are computed as odd and even #
4972 1.1 is # polynomials in r, respectively. Exit #
4973 1.1 is # #
4974 1.1 is # 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. #
4975 1.1 is # SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where #
4976 1.1 is # sin(r) and cos(r) are computed as odd and even #
4977 1.1 is # polynomials in r, respectively. Exit #
4978 1.1 is # #
4979 1.1 is # 6. If |X| > 1, go to 8. #
4980 1.1 is # #
4981 1.1 is # 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. #
4982 1.1 is # #
4983 1.1 is # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, #
4984 1.1 is # go back to 2. #
4985 1.1 is # #
4986 1.1 is #########################################################################
4987 1.1 is
4988 1.1 is SINA7: long 0xBD6AAA77,0xCCC994F5
4989 1.1 is SINA6: long 0x3DE61209,0x7AAE8DA1
4990 1.1 is SINA5: long 0xBE5AE645,0x2A118AE4
4991 1.1 is SINA4: long 0x3EC71DE3,0xA5341531
4992 1.1 is SINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
4993 1.1 is SINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000
4994 1.1 is SINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
4995 1.1 is
4996 1.1 is COSB8: long 0x3D2AC4D0,0xD6011EE3
4997 1.1 is COSB7: long 0xBDA9396F,0x9F45AC19
4998 1.1 is COSB6: long 0x3E21EED9,0x0612C972
4999 1.1 is COSB5: long 0xBE927E4F,0xB79D9FCF
5000 1.1 is COSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
5001 1.1 is COSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
5002 1.1 is COSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
5003 1.1 is COSB1: long 0xBF000000
5004 1.1 is
5005 1.1 is set INARG,FP_SCR0
5006 1.1 is
5007 1.1 is set X,FP_SCR0
5008 1.1 is # set XDCARE,X+2
5009 1.1 is set XFRAC,X+4
5010 1.1 is
5011 1.1 is set RPRIME,FP_SCR0
5012 1.1 is set SPRIME,FP_SCR1
5013 1.1 is
5014 1.1 is set POSNEG1,L_SCR1
5015 1.1 is set TWOTO63,L_SCR1
5016 1.1 is
5017 1.1 is set ENDFLAG,L_SCR2
5018 1.1 is set INT,L_SCR2
5019 1.1 is
5020 1.1 is set ADJN,L_SCR3
5021 1.1 is
5022 1.1 is ############################################
5023 1.1 is global ssin
5024 1.1 is ssin:
5025 1.1 is mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0
5026 1.1 is bra.b SINBGN
5027 1.1 is
5028 1.1 is ############################################
5029 1.1 is global scos
5030 1.1 is scos:
5031 1.1 is mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1
5032 1.1 is
5033 1.1 is ############################################
5034 1.1 is SINBGN:
5035 1.1 is #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
5036 1.1 is
5037 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
5038 1.1 is fmov.x %fp0,X(%a6) # save input at X
5039 1.1 is
5040 1.1 is # "COMPACTIFY" X
5041 1.1 is mov.l (%a0),%d1 # put exp in hi word
5042 1.1 is mov.w 4(%a0),%d1 # fetch hi(man)
5043 1.1 is and.l &0x7FFFFFFF,%d1 # strip sign
5044 1.1 is
5045 1.1 is cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)?
5046 1.1 is bge.b SOK1 # no
5047 1.1 is bra.w SINSM # yes; input is very small
5048 1.1 is
5049 1.1 is SOK1:
5050 1.1 is cmp.l %d1,&0x4004BC7E # is |X| < 15 PI?
5051 1.1 is blt.b SINMAIN # no
5052 1.1 is bra.w SREDUCEX # yes; input is very large
5053 1.1 is
5054 1.1 is #--THIS IS THE USUAL CASE, |X| <= 15 PI.
5055 1.1 is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
5056 1.1 is SINMAIN:
5057 1.1 is fmov.x %fp0,%fp1
5058 1.1 is fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
5059 1.1 is
5060 1.1 is lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
5061 1.1 is
5062 1.1 is fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER
5063 1.1 is
5064 1.1 is mov.l INT(%a6),%d1 # make a copy of N
5065 1.1 is asl.l &4,%d1 # N *= 16
5066 1.1 is add.l %d1,%a1 # tbl_addr = a1 + (N*16)
5067 1.1 is
5068 1.1 is # A1 IS THE ADDRESS OF N*PIBY2
5069 1.1 is # ...WHICH IS IN TWO PIECES Y1 & Y2
5070 1.1 is fsub.x (%a1)+,%fp0 # X-Y1
5071 1.1 is fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2
5072 1.1 is
5073 1.1 is SINCONT:
5074 1.1 is #--continuation from REDUCEX
5075 1.1 is
5076 1.1 is #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
5077 1.1 is mov.l INT(%a6),%d1
5078 1.1 is add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN
5079 1.1 is ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE
5080 1.1 is cmp.l %d1,&0
5081 1.1 is blt.w COSPOLY
5082 1.1 is
5083 1.1 is #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
5084 1.1 is #--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
5085 1.1 is #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
5086 1.1 is #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
5087 1.1 is #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
5088 1.1 is #--WHERE T=S*S.
5089 1.1 is #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
5090 1.1 is #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
5091 1.1 is SINPOLY:
5092 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3
5093 1.1 is
5094 1.1 is fmov.x %fp0,X(%a6) # X IS R
5095 1.1 is fmul.x %fp0,%fp0 # FP0 IS S
5096 1.1 is
5097 1.1 is fmov.d SINA7(%pc),%fp3
5098 1.1 is fmov.d SINA6(%pc),%fp2
5099 1.1 is
5100 1.1 is fmov.x %fp0,%fp1
5101 1.1 is fmul.x %fp1,%fp1 # FP1 IS T
5102 1.1 is
5103 1.1 is ror.l &1,%d1
5104 1.1 is and.l &0x80000000,%d1
5105 1.1 is # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
5106 1.1 is eor.l %d1,X(%a6) # X IS NOW R'= SGN*R
5107 1.1 is
5108 1.1 is fmul.x %fp1,%fp3 # TA7
5109 1.1 is fmul.x %fp1,%fp2 # TA6
5110 1.1 is
5111 1.1 is fadd.d SINA5(%pc),%fp3 # A5+TA7
5112 1.1 is fadd.d SINA4(%pc),%fp2 # A4+TA6
5113 1.1 is
5114 1.1 is fmul.x %fp1,%fp3 # T(A5+TA7)
5115 1.1 is fmul.x %fp1,%fp2 # T(A4+TA6)
5116 1.1 is
5117 1.1 is fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7)
5118 1.1 is fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6)
5119 1.1 is
5120 1.1 is fmul.x %fp3,%fp1 # T(A3+T(A5+TA7))
5121 1.1 is
5122 1.1 is fmul.x %fp0,%fp2 # S(A2+T(A4+TA6))
5123 1.1 is fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7))
5124 1.1 is fmul.x X(%a6),%fp0 # R'*S
5125 1.1 is
5126 1.1 is fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
5127 1.1 is
5128 1.1 is fmul.x %fp1,%fp0 # SIN(R')-R'
5129 1.1 is
5130 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3
5131 1.1 is
5132 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5133 1.1 is fadd.x X(%a6),%fp0 # last inst - possible exception set
5134 1.1 is bra t_inx2
5135 1.1 is
5136 1.1 is #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
5137 1.1 is #--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY
5138 1.1 is #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
5139 1.1 is #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
5140 1.1 is #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
5141 1.1 is #--WHERE T=S*S.
5142 1.1 is #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
5143 1.1 is #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
5144 1.1 is #--AND IS THEREFORE STORED AS SINGLE PRECISION.
5145 1.1 is COSPOLY:
5146 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3
5147 1.1 is
5148 1.1 is fmul.x %fp0,%fp0 # FP0 IS S
5149 1.1 is
5150 1.1 is fmov.d COSB8(%pc),%fp2
5151 1.1 is fmov.d COSB7(%pc),%fp3
5152 1.1 is
5153 1.1 is fmov.x %fp0,%fp1
5154 1.1 is fmul.x %fp1,%fp1 # FP1 IS T
5155 1.1 is
5156 1.1 is fmov.x %fp0,X(%a6) # X IS S
5157 1.1 is ror.l &1,%d1
5158 1.1 is and.l &0x80000000,%d1
5159 1.1 is # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
5160 1.1 is
5161 1.1 is fmul.x %fp1,%fp2 # TB8
5162 1.1 is
5163 1.1 is eor.l %d1,X(%a6) # X IS NOW S'= SGN*S
5164 1.1 is and.l &0x80000000,%d1
5165 1.1 is
5166 1.1 is fmul.x %fp1,%fp3 # TB7
5167 1.1 is
5168 1.1 is or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE
5169 1.1 is mov.l %d1,POSNEG1(%a6)
5170 1.1 is
5171 1.1 is fadd.d COSB6(%pc),%fp2 # B6+TB8
5172 1.1 is fadd.d COSB5(%pc),%fp3 # B5+TB7
5173 1.1 is
5174 1.1 is fmul.x %fp1,%fp2 # T(B6+TB8)
5175 1.1 is fmul.x %fp1,%fp3 # T(B5+TB7)
5176 1.1 is
5177 1.1 is fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8)
5178 1.1 is fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7)
5179 1.1 is
5180 1.1 is fmul.x %fp1,%fp2 # T(B4+T(B6+TB8))
5181 1.1 is fmul.x %fp3,%fp1 # T(B3+T(B5+TB7))
5182 1.1 is
5183 1.1 is fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8))
5184 1.1 is fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7))
5185 1.1 is
5186 1.1 is fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8)))
5187 1.1 is
5188 1.1 is fadd.x %fp1,%fp0
5189 1.1 is
5190 1.1 is fmul.x X(%a6),%fp0
5191 1.1 is
5192 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3
5193 1.1 is
5194 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5195 1.1 is fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set
5196 1.1 is bra t_inx2
5197 1.1 is
5198 1.1 is ##############################################
5199 1.1 is
5200 1.1 is # SINe: Big OR Small?
5201 1.1 is #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
5202 1.1 is #--IF |X| < 2**(-40), RETURN X OR 1.
5203 1.1 is SINBORS:
5204 1.1 is cmp.l %d1,&0x3FFF8000
5205 1.1 is bgt.l SREDUCEX
5206 1.1 is
5207 1.1 is SINSM:
5208 1.1 is mov.l ADJN(%a6),%d1
5209 1.1 is cmp.l %d1,&0
5210 1.1 is bgt.b COSTINY
5211 1.1 is
5212 1.1 is # here, the operation may underflow iff the precision is sgl or dbl.
5213 1.1 is # extended denorms are handled through another entry point.
5214 1.1 is SINTINY:
5215 1.1 is # mov.w &0x0000,XDCARE(%a6) # JUST IN CASE
5216 1.1 is
5217 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5218 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
5219 1.1 is fmov.x X(%a6),%fp0 # last inst - possible exception set
5220 1.1 is bra t_catch
5221 1.1 is
5222 1.1 is COSTINY:
5223 1.1 is fmov.s &0x3F800000,%fp0 # fp0 = 1.0
5224 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5225 1.1 is fadd.s &0x80800000,%fp0 # last inst - possible exception set
5226 1.1 is bra t_pinx2
5227 1.1 is
5228 1.1 is ################################################
5229 1.1 is global ssind
5230 1.1 is #--SIN(X) = X FOR DENORMALIZED X
5231 1.1 is ssind:
5232 1.1 is bra t_extdnrm
5233 1.1 is
5234 1.1 is ############################################
5235 1.1 is global scosd
5236 1.1 is #--COS(X) = 1 FOR DENORMALIZED X
5237 1.1 is scosd:
5238 1.1 is fmov.s &0x3F800000,%fp0 # fp0 = 1.0
5239 1.1 is bra t_pinx2
5240 1.1 is
5241 1.1 is ##################################################
5242 1.1 is
5243 1.1 is global ssincos
5244 1.1 is ssincos:
5245 1.1 is #--SET ADJN TO 4
5246 1.1 is mov.l &4,ADJN(%a6)
5247 1.1 is
5248 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
5249 1.1 is fmov.x %fp0,X(%a6)
5250 1.1 is
5251 1.1 is mov.l (%a0),%d1
5252 1.1 is mov.w 4(%a0),%d1
5253 1.1 is and.l &0x7FFFFFFF,%d1 # COMPACTIFY X
5254 1.1 is
5255 1.1 is cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)?
5256 1.1 is bge.b SCOK1
5257 1.1 is bra.w SCSM
5258 1.1 is
5259 1.1 is SCOK1:
5260 1.1 is cmp.l %d1,&0x4004BC7E # |X| < 15 PI?
5261 1.1 is blt.b SCMAIN
5262 1.1 is bra.w SREDUCEX
5263 1.1 is
5264 1.1 is
5265 1.1 is #--THIS IS THE USUAL CASE, |X| <= 15 PI.
5266 1.1 is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
5267 1.1 is SCMAIN:
5268 1.1 is fmov.x %fp0,%fp1
5269 1.1 is
5270 1.1 is fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
5271 1.1 is
5272 1.1 is lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
5273 1.1 is
5274 1.1 is fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER
5275 1.1 is
5276 1.1 is mov.l INT(%a6),%d1
5277 1.1 is asl.l &4,%d1
5278 1.1 is add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2
5279 1.1 is
5280 1.1 is fsub.x (%a1)+,%fp0 # X-Y1
5281 1.1 is fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2
5282 1.1 is
5283 1.1 is SCCONT:
5284 1.1 is #--continuation point from REDUCEX
5285 1.1 is
5286 1.1 is mov.l INT(%a6),%d1
5287 1.1 is ror.l &1,%d1
5288 1.1 is cmp.l %d1,&0 # D0 < 0 IFF N IS ODD
5289 1.1 is bge.w NEVEN
5290 1.1 is
5291 1.1 is SNODD:
5292 1.1 is #--REGISTERS SAVED SO FAR: D0, A0, FP2.
5293 1.1 is fmovm.x &0x04,-(%sp) # save fp2
5294 1.1 is
5295 1.1 is fmov.x %fp0,RPRIME(%a6)
5296 1.1 is fmul.x %fp0,%fp0 # FP0 IS S = R*R
5297 1.1 is fmov.d SINA7(%pc),%fp1 # A7
5298 1.1 is fmov.d COSB8(%pc),%fp2 # B8
5299 1.1 is fmul.x %fp0,%fp1 # SA7
5300 1.1 is fmul.x %fp0,%fp2 # SB8
5301 1.1 is
5302 1.1 is mov.l %d2,-(%sp)
5303 1.1 is mov.l %d1,%d2
5304 1.1 is ror.l &1,%d2
5305 1.1 is and.l &0x80000000,%d2
5306 1.1 is eor.l %d1,%d2
5307 1.1 is and.l &0x80000000,%d2
5308 1.1 is
5309 1.1 is fadd.d SINA6(%pc),%fp1 # A6+SA7
5310 1.1 is fadd.d COSB7(%pc),%fp2 # B7+SB8
5311 1.1 is
5312 1.1 is fmul.x %fp0,%fp1 # S(A6+SA7)
5313 1.1 is eor.l %d2,RPRIME(%a6)
5314 1.1 is mov.l (%sp)+,%d2
5315 1.1 is fmul.x %fp0,%fp2 # S(B7+SB8)
5316 1.1 is ror.l &1,%d1
5317 1.1 is and.l &0x80000000,%d1
5318 1.1 is mov.l &0x3F800000,POSNEG1(%a6)
5319 1.1 is eor.l %d1,POSNEG1(%a6)
5320 1.1 is
5321 1.1 is fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7)
5322 1.1 is fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8)
5323 1.1 is
5324 1.1 is fmul.x %fp0,%fp1 # S(A5+S(A6+SA7))
5325 1.1 is fmul.x %fp0,%fp2 # S(B6+S(B7+SB8))
5326 1.1 is fmov.x %fp0,SPRIME(%a6)
5327 1.1 is
5328 1.1 is fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7))
5329 1.1 is eor.l %d1,SPRIME(%a6)
5330 1.1 is fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8))
5331 1.1 is
5332 1.1 is fmul.x %fp0,%fp1 # S(A4+...)
5333 1.1 is fmul.x %fp0,%fp2 # S(B5+...)
5334 1.1 is
5335 1.1 is fadd.d SINA3(%pc),%fp1 # A3+S(A4+...)
5336 1.1 is fadd.d COSB4(%pc),%fp2 # B4+S(B5+...)
5337 1.1 is
5338 1.1 is fmul.x %fp0,%fp1 # S(A3+...)
5339 1.1 is fmul.x %fp0,%fp2 # S(B4+...)
5340 1.1 is
5341 1.1 is fadd.x SINA2(%pc),%fp1 # A2+S(A3+...)
5342 1.1 is fadd.x COSB3(%pc),%fp2 # B3+S(B4+...)
5343 1.1 is
5344 1.1 is fmul.x %fp0,%fp1 # S(A2+...)
5345 1.1 is fmul.x %fp0,%fp2 # S(B3+...)
5346 1.1 is
5347 1.1 is fadd.x SINA1(%pc),%fp1 # A1+S(A2+...)
5348 1.1 is fadd.x COSB2(%pc),%fp2 # B2+S(B3+...)
5349 1.1 is
5350 1.1 is fmul.x %fp0,%fp1 # S(A1+...)
5351 1.1 is fmul.x %fp2,%fp0 # S(B2+...)
5352 1.1 is
5353 1.1 is fmul.x RPRIME(%a6),%fp1 # R'S(A1+...)
5354 1.1 is fadd.s COSB1(%pc),%fp0 # B1+S(B2...)
5355 1.1 is fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...))
5356 1.1 is
5357 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2
5358 1.1 is
5359 1.1 is fmov.l %d0,%fpcr
5360 1.1 is fadd.x RPRIME(%a6),%fp1 # COS(X)
5361 1.1 is bsr sto_cos # store cosine result
5362 1.1 is fadd.s POSNEG1(%a6),%fp0 # SIN(X)
5363 1.1 is bra t_inx2
5364 1.1 is
5365 1.1 is NEVEN:
5366 1.1 is #--REGISTERS SAVED SO FAR: FP2.
5367 1.1 is fmovm.x &0x04,-(%sp) # save fp2
5368 1.1 is
5369 1.1 is fmov.x %fp0,RPRIME(%a6)
5370 1.1 is fmul.x %fp0,%fp0 # FP0 IS S = R*R
5371 1.1 is
5372 1.1 is fmov.d COSB8(%pc),%fp1 # B8
5373 1.1 is fmov.d SINA7(%pc),%fp2 # A7
5374 1.1 is
5375 1.1 is fmul.x %fp0,%fp1 # SB8
5376 1.1 is fmov.x %fp0,SPRIME(%a6)
5377 1.1 is fmul.x %fp0,%fp2 # SA7
5378 1.1 is
5379 1.1 is ror.l &1,%d1
5380 1.1 is and.l &0x80000000,%d1
5381 1.1 is
5382 1.1 is fadd.d COSB7(%pc),%fp1 # B7+SB8
5383 1.1 is fadd.d SINA6(%pc),%fp2 # A6+SA7
5384 1.1 is
5385 1.1 is eor.l %d1,RPRIME(%a6)
5386 1.1 is eor.l %d1,SPRIME(%a6)
5387 1.1 is
5388 1.1 is fmul.x %fp0,%fp1 # S(B7+SB8)
5389 1.1 is
5390 1.1 is or.l &0x3F800000,%d1
5391 1.1 is mov.l %d1,POSNEG1(%a6)
5392 1.1 is
5393 1.1 is fmul.x %fp0,%fp2 # S(A6+SA7)
5394 1.1 is
5395 1.1 is fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8)
5396 1.1 is fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7)
5397 1.1 is
5398 1.1 is fmul.x %fp0,%fp1 # S(B6+S(B7+SB8))
5399 1.1 is fmul.x %fp0,%fp2 # S(A5+S(A6+SA7))
5400 1.1 is
5401 1.1 is fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8))
5402 1.1 is fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7))
5403 1.1 is
5404 1.1 is fmul.x %fp0,%fp1 # S(B5+...)
5405 1.1 is fmul.x %fp0,%fp2 # S(A4+...)
5406 1.1 is
5407 1.1 is fadd.d COSB4(%pc),%fp1 # B4+S(B5+...)
5408 1.1 is fadd.d SINA3(%pc),%fp2 # A3+S(A4+...)
5409 1.1 is
5410 1.1 is fmul.x %fp0,%fp1 # S(B4+...)
5411 1.1 is fmul.x %fp0,%fp2 # S(A3+...)
5412 1.1 is
5413 1.1 is fadd.x COSB3(%pc),%fp1 # B3+S(B4+...)
5414 1.1 is fadd.x SINA2(%pc),%fp2 # A2+S(A3+...)
5415 1.1 is
5416 1.1 is fmul.x %fp0,%fp1 # S(B3+...)
5417 1.1 is fmul.x %fp0,%fp2 # S(A2+...)
5418 1.1 is
5419 1.1 is fadd.x COSB2(%pc),%fp1 # B2+S(B3+...)
5420 1.1 is fadd.x SINA1(%pc),%fp2 # A1+S(A2+...)
5421 1.1 is
5422 1.1 is fmul.x %fp0,%fp1 # S(B2+...)
5423 1.1 is fmul.x %fp2,%fp0 # s(a1+...)
5424 1.1 is
5425 1.1 is
5426 1.1 is fadd.s COSB1(%pc),%fp1 # B1+S(B2...)
5427 1.1 is fmul.x RPRIME(%a6),%fp0 # R'S(A1+...)
5428 1.1 is fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...))
5429 1.1 is
5430 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2
5431 1.1 is
5432 1.1 is fmov.l %d0,%fpcr
5433 1.1 is fadd.s POSNEG1(%a6),%fp1 # COS(X)
5434 1.1 is bsr sto_cos # store cosine result
5435 1.1 is fadd.x RPRIME(%a6),%fp0 # SIN(X)
5436 1.1 is bra t_inx2
5437 1.1 is
5438 1.1 is ################################################
5439 1.1 is
5440 1.1 is SCBORS:
5441 1.1 is cmp.l %d1,&0x3FFF8000
5442 1.1 is bgt.w SREDUCEX
5443 1.1 is
5444 1.1 is ################################################
5445 1.1 is
5446 1.1 is SCSM:
5447 1.1 is # mov.w &0x0000,XDCARE(%a6)
5448 1.1 is fmov.s &0x3F800000,%fp1
5449 1.1 is
5450 1.1 is fmov.l %d0,%fpcr
5451 1.1 is fsub.s &0x00800000,%fp1
5452 1.1 is bsr sto_cos # store cosine result
5453 1.1 is fmov.l %fpcr,%d0 # d0 must have fpcr,too
5454 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
5455 1.1 is fmov.x X(%a6),%fp0
5456 1.1 is bra t_catch
5457 1.1 is
5458 1.1 is ##############################################
5459 1.1 is
5460 1.1 is global ssincosd
5461 1.1 is #--SIN AND COS OF X FOR DENORMALIZED X
5462 1.1 is ssincosd:
5463 1.1 is mov.l %d0,-(%sp) # save d0
5464 1.1 is fmov.s &0x3F800000,%fp1
5465 1.1 is bsr sto_cos # store cosine result
5466 1.1 is mov.l (%sp)+,%d0 # restore d0
5467 1.1 is bra t_extdnrm
5468 1.1 is
5469 1.1 is ############################################
5470 1.1 is
5471 1.1 is #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
5472 1.1 is #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
5473 1.1 is #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
5474 1.1 is SREDUCEX:
5475 1.1 is fmovm.x &0x3c,-(%sp) # save {fp2-fp5}
5476 1.1 is mov.l %d2,-(%sp) # save d2
5477 1.1 is fmov.s &0x00000000,%fp1 # fp1 = 0
5478 1.1 is
5479 1.1 is #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
5480 1.1 is #--there is a danger of unwanted overflow in first LOOP iteration. In this
5481 1.1 is #--case, reduce argument by one remainder step to make subsequent reduction
5482 1.1 is #--safe.
5483 1.1 is cmp.l %d1,&0x7ffeffff # is arg dangerously large?
5484 1.1 is bne.b SLOOP # no
5485 1.1 is
5486 1.1 is # yes; create 2**16383*PI/2
5487 1.1 is mov.w &0x7ffe,FP_SCR0_EX(%a6)
5488 1.1 is mov.l &0xc90fdaa2,FP_SCR0_HI(%a6)
5489 1.1 is clr.l FP_SCR0_LO(%a6)
5490 1.1 is
5491 1.1 is # create low half of 2**16383*PI/2 at FP_SCR1
5492 1.1 is mov.w &0x7fdc,FP_SCR1_EX(%a6)
5493 1.1 is mov.l &0x85a308d3,FP_SCR1_HI(%a6)
5494 1.1 is clr.l FP_SCR1_LO(%a6)
5495 1.1 is
5496 1.1 is ftest.x %fp0 # test sign of argument
5497 1.1 is fblt.w sred_neg
5498 1.1 is
5499 1.1 is or.b &0x80,FP_SCR0_EX(%a6) # positive arg
5500 1.1 is or.b &0x80,FP_SCR1_EX(%a6)
5501 1.1 is sred_neg:
5502 1.1 is fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact
5503 1.1 is fmov.x %fp0,%fp1 # save high result in fp1
5504 1.1 is fadd.x FP_SCR1(%a6),%fp0 # low part of reduction
5505 1.1 is fsub.x %fp0,%fp1 # determine low component of result
5506 1.1 is fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument.
5507 1.1 is
5508 1.1 is #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
5509 1.1 is #--integer quotient will be stored in N
5510 1.1 is #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
5511 1.1 is SLOOP:
5512 1.1 is fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2
5513 1.1 is mov.w INARG(%a6),%d1
5514 1.1 is mov.l %d1,%a1 # save a copy of D0
5515 1.1 is and.l &0x00007FFF,%d1
5516 1.1 is sub.l &0x00003FFF,%d1 # d0 = K
5517 1.1 is cmp.l %d1,&28
5518 1.1 is ble.b SLASTLOOP
5519 1.1 is SCONTLOOP:
5520 1.1 is sub.l &27,%d1 # d0 = L := K-27
5521 1.1 is mov.b &0,ENDFLAG(%a6)
5522 1.1 is bra.b SWORK
5523 1.1 is SLASTLOOP:
5524 1.1 is clr.l %d1 # d0 = L := 0
5525 1.1 is mov.b &1,ENDFLAG(%a6)
5526 1.1 is
5527 1.1 is SWORK:
5528 1.1 is #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN
5529 1.1 is #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
5530 1.1 is
5531 1.1 is #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
5532 1.1 is #--2**L * (PIby2_1), 2**L * (PIby2_2)
5533 1.1 is
5534 1.1 is mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI
5535 1.1 is sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI)
5536 1.1 is
5537 1.1 is mov.l &0xA2F9836E,FP_SCR0_HI(%a6)
5538 1.1 is mov.l &0x4E44152A,FP_SCR0_LO(%a6)
5539 1.1 is mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI)
5540 1.1 is
5541 1.1 is fmov.x %fp0,%fp2
5542 1.1 is fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI)
5543 1.1 is
5544 1.1 is #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
5545 1.1 is #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N
5546 1.1 is #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
5547 1.1 is #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
5548 1.1 is #--US THE DESIRED VALUE IN FLOATING POINT.
5549 1.1 is mov.l %a1,%d2
5550 1.1 is swap %d2
5551 1.1 is and.l &0x80000000,%d2
5552 1.1 is or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL
5553 1.1 is mov.l %d2,TWOTO63(%a6)
5554 1.1 is fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED
5555 1.1 is fsub.s TWOTO63(%a6),%fp2 # fp2 = N
5556 1.1 is # fint.x %fp2
5557 1.1 is
5558 1.1 is #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
5559 1.1 is mov.l %d1,%d2 # d2 = L
5560 1.1 is
5561 1.1 is add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2)
5562 1.1 is mov.w %d2,FP_SCR0_EX(%a6)
5563 1.1 is mov.l &0xC90FDAA2,FP_SCR0_HI(%a6)
5564 1.1 is clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1
5565 1.1 is
5566 1.1 is add.l &0x00003FDD,%d1
5567 1.1 is mov.w %d1,FP_SCR1_EX(%a6)
5568 1.1 is mov.l &0x85A308D3,FP_SCR1_HI(%a6)
5569 1.1 is clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2
5570 1.1 is
5571 1.1 is mov.b ENDFLAG(%a6),%d1
5572 1.1 is
5573 1.1 is #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
5574 1.1 is #--P2 = 2**(L) * Piby2_2
5575 1.1 is fmov.x %fp2,%fp4 # fp4 = N
5576 1.1 is fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1
5577 1.1 is fmov.x %fp2,%fp5 # fp5 = N
5578 1.1 is fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2
5579 1.1 is fmov.x %fp4,%fp3 # fp3 = W = N*P1
5580 1.1 is
5581 1.1 is #--we want P+p = W+w but |p| <= half ulp of P
5582 1.1 is #--Then, we need to compute A := R-P and a := r-p
5583 1.1 is fadd.x %fp5,%fp3 # fp3 = P
5584 1.1 is fsub.x %fp3,%fp4 # fp4 = W-P
5585 1.1 is
5586 1.1 is fsub.x %fp3,%fp0 # fp0 = A := R - P
5587 1.1 is fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w
5588 1.1 is
5589 1.1 is fmov.x %fp0,%fp3 # fp3 = A
5590 1.1 is fsub.x %fp4,%fp1 # fp1 = a := r - p
5591 1.1 is
5592 1.1 is #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but
5593 1.1 is #--|r| <= half ulp of R.
5594 1.1 is fadd.x %fp1,%fp0 # fp0 = R := A+a
5595 1.1 is #--No need to calculate r if this is the last loop
5596 1.1 is cmp.b %d1,&0
5597 1.1 is bgt.w SRESTORE
5598 1.1 is
5599 1.1 is #--Need to calculate r
5600 1.1 is fsub.x %fp0,%fp3 # fp3 = A-R
5601 1.1 is fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a
5602 1.1 is bra.w SLOOP
5603 1.1 is
5604 1.1 is SRESTORE:
5605 1.1 is fmov.l %fp2,INT(%a6)
5606 1.1 is mov.l (%sp)+,%d2 # restore d2
5607 1.1 is fmovm.x (%sp)+,&0x3c # restore {fp2-fp5}
5608 1.1 is
5609 1.1 is mov.l ADJN(%a6),%d1
5610 1.1 is cmp.l %d1,&4
5611 1.1 is
5612 1.1 is blt.w SINCONT
5613 1.1 is bra.w SCCONT
5614 1.1 is
5615 1.1 is #########################################################################
5616 1.1 is # stan(): computes the tangent of a normalized input #
5617 1.1 is # stand(): computes the tangent of a denormalized input #
5618 1.1 is # #
5619 1.1 is # INPUT *************************************************************** #
5620 1.1 is # a0 = pointer to extended precision input #
5621 1.1 is # d0 = round precision,mode #
5622 1.1 is # #
5623 1.1 is # OUTPUT ************************************************************** #
5624 1.1 is # fp0 = tan(X) #
5625 1.1 is # #
5626 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
5627 1.1 is # The returned result is within 3 ulp in 64 significant bit, i.e. #
5628 1.1 is # within 0.5001 ulp to 53 bits if the result is subsequently #
5629 1.1 is # rounded to double precision. The result is provably monotonic #
5630 1.1 is # in double precision. #
5631 1.1 is # #
5632 1.1 is # ALGORITHM *********************************************************** #
5633 1.1 is # #
5634 1.1 is # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. #
5635 1.1 is # #
5636 1.1 is # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
5637 1.1 is # k = N mod 2, so in particular, k = 0 or 1. #
5638 1.1 is # #
5639 1.1 is # 3. If k is odd, go to 5. #
5640 1.1 is # #
5641 1.1 is # 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a #
5642 1.1 is # rational function U/V where #
5643 1.1 is # U = r + r*s*(P1 + s*(P2 + s*P3)), and #
5644 1.1 is # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. #
5645 1.1 is # Exit. #
5646 1.1 is # #
5647 1.1 is # 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
5648 1.1 is # a rational function U/V where #
5649 1.1 is # U = r + r*s*(P1 + s*(P2 + s*P3)), and #
5650 1.1 is # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, #
5651 1.1 is # -Cot(r) = -V/U. Exit. #
5652 1.1 is # #
5653 1.1 is # 6. If |X| > 1, go to 8. #
5654 1.1 is # #
5655 1.1 is # 7. (|X|<2**(-40)) Tan(X) = X. Exit. #
5656 1.1 is # #
5657 1.1 is # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back #
5658 1.1 is # to 2. #
5659 1.1 is # #
5660 1.1 is #########################################################################
5661 1.1 is
5662 1.1 is TANQ4:
5663 1.1 is long 0x3EA0B759,0xF50F8688
5664 1.1 is TANP3:
5665 1.1 is long 0xBEF2BAA5,0xA8924F04
5666 1.1 is
5667 1.1 is TANQ3:
5668 1.1 is long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000
5669 1.1 is
5670 1.1 is TANP2:
5671 1.1 is long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
5672 1.1 is
5673 1.1 is TANQ2:
5674 1.1 is long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
5675 1.1 is
5676 1.1 is TANP1:
5677 1.1 is long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
5678 1.1 is
5679 1.1 is TANQ1:
5680 1.1 is long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
5681 1.1 is
5682 1.1 is INVTWOPI:
5683 1.1 is long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
5684 1.1 is
5685 1.1 is TWOPI1:
5686 1.1 is long 0x40010000,0xC90FDAA2,0x00000000,0x00000000
5687 1.1 is TWOPI2:
5688 1.1 is long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000
5689 1.1 is
5690 1.1 is #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
5691 1.1 is #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
5692 1.1 is #--MOST 69 BITS LONG.
5693 1.1 is # global PITBL
5694 1.1 is PITBL:
5695 1.1 is long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
5696 1.1 is long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
5697 1.1 is long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
5698 1.1 is long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000
5699 1.1 is long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
5700 1.1 is long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
5701 1.1 is long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
5702 1.1 is long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
5703 1.1 is long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
5704 1.1 is long 0xC0040000,0x90836524,0x88034B96,0x20B00000
5705 1.1 is long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
5706 1.1 is long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
5707 1.1 is long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
5708 1.1 is long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
5709 1.1 is long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
5710 1.1 is long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
5711 1.1 is long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
5712 1.1 is long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
5713 1.1 is long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
5714 1.1 is long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
5715 1.1 is long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
5716 1.1 is long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
5717 1.1 is long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
5718 1.1 is long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
5719 1.1 is long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
5720 1.1 is long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
5721 1.1 is long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
5722 1.1 is long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
5723 1.1 is long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
5724 1.1 is long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
5725 1.1 is long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
5726 1.1 is long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
5727 1.1 is long 0x00000000,0x00000000,0x00000000,0x00000000
5728 1.1 is long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
5729 1.1 is long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
5730 1.1 is long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
5731 1.1 is long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
5732 1.1 is long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
5733 1.1 is long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
5734 1.1 is long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
5735 1.1 is long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
5736 1.1 is long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
5737 1.1 is long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
5738 1.1 is long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000
5739 1.1 is long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
5740 1.1 is long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
5741 1.1 is long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
5742 1.1 is long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
5743 1.1 is long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
5744 1.1 is long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
5745 1.1 is long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
5746 1.1 is long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
5747 1.1 is long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
5748 1.1 is long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
5749 1.1 is long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000
5750 1.1 is long 0x40040000,0x90836524,0x88034B96,0xA0B00000
5751 1.1 is long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
5752 1.1 is long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
5753 1.1 is long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
5754 1.1 is long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
5755 1.1 is long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
5756 1.1 is long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000
5757 1.1 is long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
5758 1.1 is long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
5759 1.1 is long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
5760 1.1 is
5761 1.1 is set INARG,FP_SCR0
5762 1.1 is
5763 1.1 is set TWOTO63,L_SCR1
5764 1.1 is set INT,L_SCR1
5765 1.1 is set ENDFLAG,L_SCR2
5766 1.1 is
5767 1.1 is global stan
5768 1.1 is stan:
5769 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
5770 1.1 is
5771 1.1 is mov.l (%a0),%d1
5772 1.1 is mov.w 4(%a0),%d1
5773 1.1 is and.l &0x7FFFFFFF,%d1
5774 1.1 is
5775 1.1 is cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)?
5776 1.1 is bge.b TANOK1
5777 1.1 is bra.w TANSM
5778 1.1 is TANOK1:
5779 1.1 is cmp.l %d1,&0x4004BC7E # |X| < 15 PI?
5780 1.1 is blt.b TANMAIN
5781 1.1 is bra.w REDUCEX
5782 1.1 is
5783 1.1 is TANMAIN:
5784 1.1 is #--THIS IS THE USUAL CASE, |X| <= 15 PI.
5785 1.1 is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
5786 1.1 is fmov.x %fp0,%fp1
5787 1.1 is fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
5788 1.1 is
5789 1.1 is lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
5790 1.1 is
5791 1.1 is fmov.l %fp1,%d1 # CONVERT TO INTEGER
5792 1.1 is
5793 1.1 is asl.l &4,%d1
5794 1.1 is add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2
5795 1.1 is
5796 1.1 is fsub.x (%a1)+,%fp0 # X-Y1
5797 1.1 is
5798 1.1 is fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2
5799 1.1 is
5800 1.1 is ror.l &5,%d1
5801 1.1 is and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0
5802 1.1 is
5803 1.1 is TANCONT:
5804 1.1 is fmovm.x &0x0c,-(%sp) # save fp2,fp3
5805 1.1 is
5806 1.1 is cmp.l %d1,&0
5807 1.1 is blt.w NODD
5808 1.1 is
5809 1.1 is fmov.x %fp0,%fp1
5810 1.1 is fmul.x %fp1,%fp1 # S = R*R
5811 1.1 is
5812 1.1 is fmov.d TANQ4(%pc),%fp3
5813 1.1 is fmov.d TANP3(%pc),%fp2
5814 1.1 is
5815 1.1 is fmul.x %fp1,%fp3 # SQ4
5816 1.1 is fmul.x %fp1,%fp2 # SP3
5817 1.1 is
5818 1.1 is fadd.d TANQ3(%pc),%fp3 # Q3+SQ4
5819 1.1 is fadd.x TANP2(%pc),%fp2 # P2+SP3
5820 1.1 is
5821 1.1 is fmul.x %fp1,%fp3 # S(Q3+SQ4)
5822 1.1 is fmul.x %fp1,%fp2 # S(P2+SP3)
5823 1.1 is
5824 1.1 is fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4)
5825 1.1 is fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3)
5826 1.1 is
5827 1.1 is fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4))
5828 1.1 is fmul.x %fp1,%fp2 # S(P1+S(P2+SP3))
5829 1.1 is
5830 1.1 is fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4))
5831 1.1 is fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3))
5832 1.1 is
5833 1.1 is fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4)))
5834 1.1 is
5835 1.1 is fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3))
5836 1.1 is
5837 1.1 is fadd.s &0x3F800000,%fp1 # 1+S(Q1+...)
5838 1.1 is
5839 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2,fp3
5840 1.1 is
5841 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5842 1.1 is fdiv.x %fp1,%fp0 # last inst - possible exception set
5843 1.1 is bra t_inx2
5844 1.1 is
5845 1.1 is NODD:
5846 1.1 is fmov.x %fp0,%fp1
5847 1.1 is fmul.x %fp0,%fp0 # S = R*R
5848 1.1 is
5849 1.1 is fmov.d TANQ4(%pc),%fp3
5850 1.1 is fmov.d TANP3(%pc),%fp2
5851 1.1 is
5852 1.1 is fmul.x %fp0,%fp3 # SQ4
5853 1.1 is fmul.x %fp0,%fp2 # SP3
5854 1.1 is
5855 1.1 is fadd.d TANQ3(%pc),%fp3 # Q3+SQ4
5856 1.1 is fadd.x TANP2(%pc),%fp2 # P2+SP3
5857 1.1 is
5858 1.1 is fmul.x %fp0,%fp3 # S(Q3+SQ4)
5859 1.1 is fmul.x %fp0,%fp2 # S(P2+SP3)
5860 1.1 is
5861 1.1 is fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4)
5862 1.1 is fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3)
5863 1.1 is
5864 1.1 is fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4))
5865 1.1 is fmul.x %fp0,%fp2 # S(P1+S(P2+SP3))
5866 1.1 is
5867 1.1 is fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4))
5868 1.1 is fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3))
5869 1.1 is
5870 1.1 is fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4)))
5871 1.1 is
5872 1.1 is fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3))
5873 1.1 is fadd.s &0x3F800000,%fp0 # 1+S(Q1+...)
5874 1.1 is
5875 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2,fp3
5876 1.1 is
5877 1.1 is fmov.x %fp1,-(%sp)
5878 1.1 is eor.l &0x80000000,(%sp)
5879 1.1 is
5880 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5881 1.1 is fdiv.x (%sp)+,%fp0 # last inst - possible exception set
5882 1.1 is bra t_inx2
5883 1.1 is
5884 1.1 is TANBORS:
5885 1.1 is #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
5886 1.1 is #--IF |X| < 2**(-40), RETURN X OR 1.
5887 1.1 is cmp.l %d1,&0x3FFF8000
5888 1.1 is bgt.b REDUCEX
5889 1.1 is
5890 1.1 is TANSM:
5891 1.1 is fmov.x %fp0,-(%sp)
5892 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec
5893 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
5894 1.1 is fmov.x (%sp)+,%fp0 # last inst - posibble exception set
5895 1.1 is bra t_catch
5896 1.1 is
5897 1.1 is global stand
5898 1.1 is #--TAN(X) = X FOR DENORMALIZED X
5899 1.1 is stand:
5900 1.1 is bra t_extdnrm
5901 1.1 is
5902 1.1 is #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
5903 1.1 is #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
5904 1.1 is #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
5905 1.1 is REDUCEX:
5906 1.1 is fmovm.x &0x3c,-(%sp) # save {fp2-fp5}
5907 1.1 is mov.l %d2,-(%sp) # save d2
5908 1.1 is fmov.s &0x00000000,%fp1 # fp1 = 0
5909 1.1 is
5910 1.1 is #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
5911 1.1 is #--there is a danger of unwanted overflow in first LOOP iteration. In this
5912 1.1 is #--case, reduce argument by one remainder step to make subsequent reduction
5913 1.1 is #--safe.
5914 1.1 is cmp.l %d1,&0x7ffeffff # is arg dangerously large?
5915 1.1 is bne.b LOOP # no
5916 1.1 is
5917 1.1 is # yes; create 2**16383*PI/2
5918 1.1 is mov.w &0x7ffe,FP_SCR0_EX(%a6)
5919 1.1 is mov.l &0xc90fdaa2,FP_SCR0_HI(%a6)
5920 1.1 is clr.l FP_SCR0_LO(%a6)
5921 1.1 is
5922 1.1 is # create low half of 2**16383*PI/2 at FP_SCR1
5923 1.1 is mov.w &0x7fdc,FP_SCR1_EX(%a6)
5924 1.1 is mov.l &0x85a308d3,FP_SCR1_HI(%a6)
5925 1.1 is clr.l FP_SCR1_LO(%a6)
5926 1.1 is
5927 1.1 is ftest.x %fp0 # test sign of argument
5928 1.1 is fblt.w red_neg
5929 1.1 is
5930 1.1 is or.b &0x80,FP_SCR0_EX(%a6) # positive arg
5931 1.1 is or.b &0x80,FP_SCR1_EX(%a6)
5932 1.1 is red_neg:
5933 1.1 is fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact
5934 1.1 is fmov.x %fp0,%fp1 # save high result in fp1
5935 1.1 is fadd.x FP_SCR1(%a6),%fp0 # low part of reduction
5936 1.1 is fsub.x %fp0,%fp1 # determine low component of result
5937 1.1 is fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument.
5938 1.1 is
5939 1.1 is #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
5940 1.1 is #--integer quotient will be stored in N
5941 1.1 is #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
5942 1.1 is LOOP:
5943 1.1 is fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2
5944 1.1 is mov.w INARG(%a6),%d1
5945 1.1 is mov.l %d1,%a1 # save a copy of D0
5946 1.1 is and.l &0x00007FFF,%d1
5947 1.1 is sub.l &0x00003FFF,%d1 # d0 = K
5948 1.1 is cmp.l %d1,&28
5949 1.1 is ble.b LASTLOOP
5950 1.1 is CONTLOOP:
5951 1.1 is sub.l &27,%d1 # d0 = L := K-27
5952 1.1 is mov.b &0,ENDFLAG(%a6)
5953 1.1 is bra.b WORK
5954 1.1 is LASTLOOP:
5955 1.1 is clr.l %d1 # d0 = L := 0
5956 1.1 is mov.b &1,ENDFLAG(%a6)
5957 1.1 is
5958 1.1 is WORK:
5959 1.1 is #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN
5960 1.1 is #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
5961 1.1 is
5962 1.1 is #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
5963 1.1 is #--2**L * (PIby2_1), 2**L * (PIby2_2)
5964 1.1 is
5965 1.1 is mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI
5966 1.1 is sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI)
5967 1.1 is
5968 1.1 is mov.l &0xA2F9836E,FP_SCR0_HI(%a6)
5969 1.1 is mov.l &0x4E44152A,FP_SCR0_LO(%a6)
5970 1.1 is mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI)
5971 1.1 is
5972 1.1 is fmov.x %fp0,%fp2
5973 1.1 is fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI)
5974 1.1 is
5975 1.1 is #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
5976 1.1 is #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N
5977 1.1 is #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
5978 1.1 is #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
5979 1.1 is #--US THE DESIRED VALUE IN FLOATING POINT.
5980 1.1 is mov.l %a1,%d2
5981 1.1 is swap %d2
5982 1.1 is and.l &0x80000000,%d2
5983 1.1 is or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL
5984 1.1 is mov.l %d2,TWOTO63(%a6)
5985 1.1 is fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED
5986 1.1 is fsub.s TWOTO63(%a6),%fp2 # fp2 = N
5987 1.1 is # fintrz.x %fp2,%fp2
5988 1.1 is
5989 1.1 is #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
5990 1.1 is mov.l %d1,%d2 # d2 = L
5991 1.1 is
5992 1.1 is add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2)
5993 1.1 is mov.w %d2,FP_SCR0_EX(%a6)
5994 1.1 is mov.l &0xC90FDAA2,FP_SCR0_HI(%a6)
5995 1.1 is clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1
5996 1.1 is
5997 1.1 is add.l &0x00003FDD,%d1
5998 1.1 is mov.w %d1,FP_SCR1_EX(%a6)
5999 1.1 is mov.l &0x85A308D3,FP_SCR1_HI(%a6)
6000 1.1 is clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2
6001 1.1 is
6002 1.1 is mov.b ENDFLAG(%a6),%d1
6003 1.1 is
6004 1.1 is #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
6005 1.1 is #--P2 = 2**(L) * Piby2_2
6006 1.1 is fmov.x %fp2,%fp4 # fp4 = N
6007 1.1 is fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1
6008 1.1 is fmov.x %fp2,%fp5 # fp5 = N
6009 1.1 is fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2
6010 1.1 is fmov.x %fp4,%fp3 # fp3 = W = N*P1
6011 1.1 is
6012 1.1 is #--we want P+p = W+w but |p| <= half ulp of P
6013 1.1 is #--Then, we need to compute A := R-P and a := r-p
6014 1.1 is fadd.x %fp5,%fp3 # fp3 = P
6015 1.1 is fsub.x %fp3,%fp4 # fp4 = W-P
6016 1.1 is
6017 1.1 is fsub.x %fp3,%fp0 # fp0 = A := R - P
6018 1.1 is fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w
6019 1.1 is
6020 1.1 is fmov.x %fp0,%fp3 # fp3 = A
6021 1.1 is fsub.x %fp4,%fp1 # fp1 = a := r - p
6022 1.1 is
6023 1.1 is #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but
6024 1.1 is #--|r| <= half ulp of R.
6025 1.1 is fadd.x %fp1,%fp0 # fp0 = R := A+a
6026 1.1 is #--No need to calculate r if this is the last loop
6027 1.1 is cmp.b %d1,&0
6028 1.1 is bgt.w RESTORE
6029 1.1 is
6030 1.1 is #--Need to calculate r
6031 1.1 is fsub.x %fp0,%fp3 # fp3 = A-R
6032 1.1 is fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a
6033 1.1 is bra.w LOOP
6034 1.1 is
6035 1.1 is RESTORE:
6036 1.1 is fmov.l %fp2,INT(%a6)
6037 1.1 is mov.l (%sp)+,%d2 # restore d2
6038 1.1 is fmovm.x (%sp)+,&0x3c # restore {fp2-fp5}
6039 1.1 is
6040 1.1 is mov.l INT(%a6),%d1
6041 1.1 is ror.l &1,%d1
6042 1.1 is
6043 1.1 is bra.w TANCONT
6044 1.1 is
6045 1.1 is #########################################################################
6046 1.1 is # satan(): computes the arctangent of a normalized number #
6047 1.1 is # satand(): computes the arctangent of a denormalized number #
6048 1.1 is # #
6049 1.1 is # INPUT *************************************************************** #
6050 1.1 is # a0 = pointer to extended precision input #
6051 1.1 is # d0 = round precision,mode #
6052 1.1 is # #
6053 1.1 is # OUTPUT ************************************************************** #
6054 1.1 is # fp0 = arctan(X) #
6055 1.1 is # #
6056 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
6057 1.1 is # The returned result is within 2 ulps in 64 significant bit, #
6058 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
6059 1.1 is # rounded to double precision. The result is provably monotonic #
6060 1.1 is # in double precision. #
6061 1.1 is # #
6062 1.1 is # ALGORITHM *********************************************************** #
6063 1.1 is # Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. #
6064 1.1 is # #
6065 1.1 is # Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. #
6066 1.1 is # Note that k = -4, -3,..., or 3. #
6067 1.1 is # Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 #
6068 1.1 is # significant bits of X with a bit-1 attached at the 6-th #
6069 1.1 is # bit position. Define u to be u = (X-F) / (1 + X*F). #
6070 1.1 is # #
6071 1.1 is # Step 3. Approximate arctan(u) by a polynomial poly. #
6072 1.1 is # #
6073 1.1 is # Step 4. Return arctan(F) + poly, arctan(F) is fetched from a #
6074 1.1 is # table of values calculated beforehand. Exit. #
6075 1.1 is # #
6076 1.1 is # Step 5. If |X| >= 16, go to Step 7. #
6077 1.1 is # #
6078 1.1 is # Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. #
6079 1.1 is # #
6080 1.1 is # Step 7. Define X' = -1/X. Approximate arctan(X') by an odd #
6081 1.1 is # polynomial in X'. #
6082 1.1 is # Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. #
6083 1.1 is # #
6084 1.1 is #########################################################################
6085 1.1 is
6086 1.1 is ATANA3: long 0xBFF6687E,0x314987D8
6087 1.1 is ATANA2: long 0x4002AC69,0x34A26DB3
6088 1.1 is ATANA1: long 0xBFC2476F,0x4E1DA28E
6089 1.1 is
6090 1.1 is ATANB6: long 0x3FB34444,0x7F876989
6091 1.1 is ATANB5: long 0xBFB744EE,0x7FAF45DB
6092 1.1 is ATANB4: long 0x3FBC71C6,0x46940220
6093 1.1 is ATANB3: long 0xBFC24924,0x921872F9
6094 1.1 is ATANB2: long 0x3FC99999,0x99998FA9
6095 1.1 is ATANB1: long 0xBFD55555,0x55555555
6096 1.1 is
6097 1.1 is ATANC5: long 0xBFB70BF3,0x98539E6A
6098 1.1 is ATANC4: long 0x3FBC7187,0x962D1D7D
6099 1.1 is ATANC3: long 0xBFC24924,0x827107B8
6100 1.1 is ATANC2: long 0x3FC99999,0x9996263E
6101 1.1 is ATANC1: long 0xBFD55555,0x55555536
6102 1.1 is
6103 1.1 is PPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
6104 1.1 is NPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
6105 1.1 is
6106 1.1 is PTINY: long 0x00010000,0x80000000,0x00000000,0x00000000
6107 1.1 is NTINY: long 0x80010000,0x80000000,0x00000000,0x00000000
6108 1.1 is
6109 1.1 is ATANTBL:
6110 1.1 is long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
6111 1.1 is long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
6112 1.1 is long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
6113 1.1 is long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
6114 1.1 is long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
6115 1.1 is long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000
6116 1.1 is long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
6117 1.1 is long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
6118 1.1 is long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
6119 1.1 is long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
6120 1.1 is long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
6121 1.1 is long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
6122 1.1 is long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
6123 1.1 is long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
6124 1.1 is long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
6125 1.1 is long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
6126 1.1 is long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
6127 1.1 is long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
6128 1.1 is long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
6129 1.1 is long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
6130 1.1 is long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
6131 1.1 is long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
6132 1.1 is long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
6133 1.1 is long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
6134 1.1 is long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
6135 1.1 is long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
6136 1.1 is long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
6137 1.1 is long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
6138 1.1 is long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
6139 1.1 is long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
6140 1.1 is long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
6141 1.1 is long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
6142 1.1 is long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
6143 1.1 is long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
6144 1.1 is long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
6145 1.1 is long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
6146 1.1 is long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
6147 1.1 is long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
6148 1.1 is long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
6149 1.1 is long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
6150 1.1 is long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
6151 1.1 is long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
6152 1.1 is long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
6153 1.1 is long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
6154 1.1 is long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
6155 1.1 is long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
6156 1.1 is long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
6157 1.1 is long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
6158 1.1 is long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
6159 1.1 is long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
6160 1.1 is long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
6161 1.1 is long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
6162 1.1 is long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
6163 1.1 is long 0x3FFE0000,0x97731420,0x365E538C,0x00000000
6164 1.1 is long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
6165 1.1 is long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
6166 1.1 is long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
6167 1.1 is long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
6168 1.1 is long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
6169 1.1 is long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
6170 1.1 is long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
6171 1.1 is long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
6172 1.1 is long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
6173 1.1 is long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
6174 1.1 is long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
6175 1.1 is long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
6176 1.1 is long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
6177 1.1 is long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
6178 1.1 is long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000
6179 1.1 is long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
6180 1.1 is long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
6181 1.1 is long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
6182 1.1 is long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
6183 1.1 is long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
6184 1.1 is long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
6185 1.1 is long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
6186 1.1 is long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
6187 1.1 is long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
6188 1.1 is long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
6189 1.1 is long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
6190 1.1 is long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
6191 1.1 is long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
6192 1.1 is long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
6193 1.1 is long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
6194 1.1 is long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
6195 1.1 is long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
6196 1.1 is long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
6197 1.1 is long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000
6198 1.1 is long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
6199 1.1 is long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
6200 1.1 is long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
6201 1.1 is long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
6202 1.1 is long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
6203 1.1 is long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
6204 1.1 is long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
6205 1.1 is long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
6206 1.1 is long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
6207 1.1 is long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
6208 1.1 is long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
6209 1.1 is long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
6210 1.1 is long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
6211 1.1 is long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
6212 1.1 is long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
6213 1.1 is long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
6214 1.1 is long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
6215 1.1 is long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000
6216 1.1 is long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
6217 1.1 is long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
6218 1.1 is long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
6219 1.1 is long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
6220 1.1 is long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
6221 1.1 is long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
6222 1.1 is long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
6223 1.1 is long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
6224 1.1 is long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
6225 1.1 is long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
6226 1.1 is long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
6227 1.1 is long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
6228 1.1 is long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
6229 1.1 is long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
6230 1.1 is long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
6231 1.1 is long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
6232 1.1 is long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
6233 1.1 is long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
6234 1.1 is long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
6235 1.1 is long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
6236 1.1 is long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
6237 1.1 is long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
6238 1.1 is
6239 1.1 is set X,FP_SCR0
6240 1.1 is set XDCARE,X+2
6241 1.1 is set XFRAC,X+4
6242 1.1 is set XFRACLO,X+8
6243 1.1 is
6244 1.1 is set ATANF,FP_SCR1
6245 1.1 is set ATANFHI,ATANF+4
6246 1.1 is set ATANFLO,ATANF+8
6247 1.1 is
6248 1.1 is global satan
6249 1.1 is #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
6250 1.1 is satan:
6251 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
6252 1.1 is
6253 1.1 is mov.l (%a0),%d1
6254 1.1 is mov.w 4(%a0),%d1
6255 1.1 is fmov.x %fp0,X(%a6)
6256 1.1 is and.l &0x7FFFFFFF,%d1
6257 1.1 is
6258 1.1 is cmp.l %d1,&0x3FFB8000 # |X| >= 1/16?
6259 1.1 is bge.b ATANOK1
6260 1.1 is bra.w ATANSM
6261 1.1 is
6262 1.1 is ATANOK1:
6263 1.1 is cmp.l %d1,&0x4002FFFF # |X| < 16 ?
6264 1.1 is ble.b ATANMAIN
6265 1.1 is bra.w ATANBIG
6266 1.1 is
6267 1.1 is #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
6268 1.1 is #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
6269 1.1 is #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
6270 1.1 is #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
6271 1.1 is #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
6272 1.1 is #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
6273 1.1 is #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
6274 1.1 is #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
6275 1.1 is #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
6276 1.1 is #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
6277 1.1 is #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
6278 1.1 is #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
6279 1.1 is #--WILL INVOLVE A VERY LONG POLYNOMIAL.
6280 1.1 is
6281 1.1 is #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
6282 1.1 is #--WE CHOSE F TO BE +-2^K * 1.BBBB1
6283 1.1 is #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
6284 1.1 is #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
6285 1.1 is #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
6286 1.1 is #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
6287 1.1 is
6288 1.1 is ATANMAIN:
6289 1.1 is
6290 1.1 is and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS
6291 1.1 is or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1
6292 1.1 is mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
6293 1.1 is
6294 1.1 is fmov.x %fp0,%fp1 # FP1 IS X
6295 1.1 is fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0
6296 1.1 is fsub.x X(%a6),%fp0 # FP0 IS X-F
6297 1.1 is fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F
6298 1.1 is fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F)
6299 1.1 is
6300 1.1 is #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
6301 1.1 is #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
6302 1.1 is #--SAVE REGISTERS FP2.
6303 1.1 is
6304 1.1 is mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY
6305 1.1 is mov.l %d1,%d2 # THE EXP AND 16 BITS OF X
6306 1.1 is and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION
6307 1.1 is and.l &0x7FFF0000,%d2 # EXPONENT OF F
6308 1.1 is sub.l &0x3FFB0000,%d2 # K+4
6309 1.1 is asr.l &1,%d2
6310 1.1 is add.l %d2,%d1 # THE 7 BITS IDENTIFYING F
6311 1.1 is asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|)
6312 1.1 is lea ATANTBL(%pc),%a1
6313 1.1 is add.l %d1,%a1 # ADDRESS OF ATAN(|F|)
6314 1.1 is mov.l (%a1)+,ATANF(%a6)
6315 1.1 is mov.l (%a1)+,ATANFHI(%a6)
6316 1.1 is mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|)
6317 1.1 is mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN
6318 1.1 is and.l &0x80000000,%d1 # SIGN(F)
6319 1.1 is or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|)
6320 1.1 is mov.l (%sp)+,%d2 # RESTORE d2
6321 1.1 is
6322 1.1 is #--THAT'S ALL I HAVE TO DO FOR NOW,
6323 1.1 is #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
6324 1.1 is
6325 1.1 is #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
6326 1.1 is #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
6327 1.1 is #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
6328 1.1 is #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
6329 1.1 is #--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3.
6330 1.1 is #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
6331 1.1 is #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
6332 1.1 is
6333 1.1 is fmovm.x &0x04,-(%sp) # save fp2
6334 1.1 is
6335 1.1 is fmov.x %fp0,%fp1
6336 1.1 is fmul.x %fp1,%fp1
6337 1.1 is fmov.d ATANA3(%pc),%fp2
6338 1.1 is fadd.x %fp1,%fp2 # A3+V
6339 1.1 is fmul.x %fp1,%fp2 # V*(A3+V)
6340 1.1 is fmul.x %fp0,%fp1 # U*V
6341 1.1 is fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V)
6342 1.1 is fmul.d ATANA1(%pc),%fp1 # A1*U*V
6343 1.1 is fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V))
6344 1.1 is fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED
6345 1.1 is
6346 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2
6347 1.1 is
6348 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec
6349 1.1 is fadd.x ATANF(%a6),%fp0 # ATAN(X)
6350 1.1 is bra t_inx2
6351 1.1 is
6352 1.1 is ATANBORS:
6353 1.1 is #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
6354 1.1 is #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
6355 1.1 is cmp.l %d1,&0x3FFF8000
6356 1.1 is bgt.w ATANBIG # I.E. |X| >= 16
6357 1.1 is
6358 1.1 is ATANSM:
6359 1.1 is #--|X| <= 1/16
6360 1.1 is #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
6361 1.1 is #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
6362 1.1 is #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
6363 1.1 is #--WHERE Y = X*X, AND Z = Y*Y.
6364 1.1 is
6365 1.1 is cmp.l %d1,&0x3FD78000
6366 1.1 is blt.w ATANTINY
6367 1.1 is
6368 1.1 is #--COMPUTE POLYNOMIAL
6369 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3
6370 1.1 is
6371 1.1 is fmul.x %fp0,%fp0 # FPO IS Y = X*X
6372 1.1 is
6373 1.1 is fmov.x %fp0,%fp1
6374 1.1 is fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y
6375 1.1 is
6376 1.1 is fmov.d ATANB6(%pc),%fp2
6377 1.1 is fmov.d ATANB5(%pc),%fp3
6378 1.1 is
6379 1.1 is fmul.x %fp1,%fp2 # Z*B6
6380 1.1 is fmul.x %fp1,%fp3 # Z*B5
6381 1.1 is
6382 1.1 is fadd.d ATANB4(%pc),%fp2 # B4+Z*B6
6383 1.1 is fadd.d ATANB3(%pc),%fp3 # B3+Z*B5
6384 1.1 is
6385 1.1 is fmul.x %fp1,%fp2 # Z*(B4+Z*B6)
6386 1.1 is fmul.x %fp3,%fp1 # Z*(B3+Z*B5)
6387 1.1 is
6388 1.1 is fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6)
6389 1.1 is fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5)
6390 1.1 is
6391 1.1 is fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6))
6392 1.1 is fmul.x X(%a6),%fp0 # X*Y
6393 1.1 is
6394 1.1 is fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
6395 1.1 is
6396 1.1 is fmul.x %fp1,%fp0 # X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
6397 1.1 is
6398 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3
6399 1.1 is
6400 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec
6401 1.1 is fadd.x X(%a6),%fp0
6402 1.1 is bra t_inx2
6403 1.1 is
6404 1.1 is ATANTINY:
6405 1.1 is #--|X| < 2^(-40), ATAN(X) = X
6406 1.1 is
6407 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec
6408 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
6409 1.1 is fmov.x X(%a6),%fp0 # last inst - possible exception set
6410 1.1 is
6411 1.1 is bra t_catch
6412 1.1 is
6413 1.1 is ATANBIG:
6414 1.1 is #--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE,
6415 1.1 is #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
6416 1.1 is cmp.l %d1,&0x40638000
6417 1.1 is bgt.w ATANHUGE
6418 1.1 is
6419 1.1 is #--APPROXIMATE ATAN(-1/X) BY
6420 1.1 is #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
6421 1.1 is #--THIS CAN BE RE-WRITTEN AS
6422 1.1 is #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
6423 1.1 is
6424 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3
6425 1.1 is
6426 1.1 is fmov.s &0xBF800000,%fp1 # LOAD -1
6427 1.1 is fdiv.x %fp0,%fp1 # FP1 IS -1/X
6428 1.1 is
6429 1.1 is #--DIVIDE IS STILL CRANKING
6430 1.1 is
6431 1.1 is fmov.x %fp1,%fp0 # FP0 IS X'
6432 1.1 is fmul.x %fp0,%fp0 # FP0 IS Y = X'*X'
6433 1.1 is fmov.x %fp1,X(%a6) # X IS REALLY X'
6434 1.1 is
6435 1.1 is fmov.x %fp0,%fp1
6436 1.1 is fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y
6437 1.1 is
6438 1.1 is fmov.d ATANC5(%pc),%fp3
6439 1.1 is fmov.d ATANC4(%pc),%fp2
6440 1.1 is
6441 1.1 is fmul.x %fp1,%fp3 # Z*C5
6442 1.1 is fmul.x %fp1,%fp2 # Z*B4
6443 1.1 is
6444 1.1 is fadd.d ATANC3(%pc),%fp3 # C3+Z*C5
6445 1.1 is fadd.d ATANC2(%pc),%fp2 # C2+Z*C4
6446 1.1 is
6447 1.1 is fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED
6448 1.1 is fmul.x %fp0,%fp2 # Y*(C2+Z*C4)
6449 1.1 is
6450 1.1 is fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5)
6451 1.1 is fmul.x X(%a6),%fp0 # X'*Y
6452 1.1 is
6453 1.1 is fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
6454 1.1 is
6455 1.1 is fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)]
6456 1.1 is # ... +[Y*(B2+Z*(B4+Z*B6))])
6457 1.1 is fadd.x X(%a6),%fp0
6458 1.1 is
6459 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3
6460 1.1 is
6461 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec
6462 1.1 is tst.b (%a0)
6463 1.1 is bpl.b pos_big
6464 1.1 is
6465 1.1 is neg_big:
6466 1.1 is fadd.x NPIBY2(%pc),%fp0
6467 1.1 is bra t_minx2
6468 1.1 is
6469 1.1 is pos_big:
6470 1.1 is fadd.x PPIBY2(%pc),%fp0
6471 1.1 is bra t_pinx2
6472 1.1 is
6473 1.1 is ATANHUGE:
6474 1.1 is #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
6475 1.1 is tst.b (%a0)
6476 1.1 is bpl.b pos_huge
6477 1.1 is
6478 1.1 is neg_huge:
6479 1.1 is fmov.x NPIBY2(%pc),%fp0
6480 1.1 is fmov.l %d0,%fpcr
6481 1.1 is fadd.x PTINY(%pc),%fp0
6482 1.1 is bra t_minx2
6483 1.1 is
6484 1.1 is pos_huge:
6485 1.1 is fmov.x PPIBY2(%pc),%fp0
6486 1.1 is fmov.l %d0,%fpcr
6487 1.1 is fadd.x NTINY(%pc),%fp0
6488 1.1 is bra t_pinx2
6489 1.1 is
6490 1.1 is global satand
6491 1.1 is #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
6492 1.1 is satand:
6493 1.1 is bra t_extdnrm
6494 1.1 is
6495 1.1 is #########################################################################
6496 1.1 is # sasin(): computes the inverse sine of a normalized input #
6497 1.1 is # sasind(): computes the inverse sine of a denormalized input #
6498 1.1 is # #
6499 1.1 is # INPUT *************************************************************** #
6500 1.1 is # a0 = pointer to extended precision input #
6501 1.1 is # d0 = round precision,mode #
6502 1.1 is # #
6503 1.1 is # OUTPUT ************************************************************** #
6504 1.1 is # fp0 = arcsin(X) #
6505 1.1 is # #
6506 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
6507 1.1 is # The returned result is within 3 ulps in 64 significant bit, #
6508 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
6509 1.1 is # rounded to double precision. The result is provably monotonic #
6510 1.1 is # in double precision. #
6511 1.1 is # #
6512 1.1 is # ALGORITHM *********************************************************** #
6513 1.1 is # #
6514 1.1 is # ASIN #
6515 1.1 is # 1. If |X| >= 1, go to 3. #
6516 1.1 is # #
6517 1.1 is # 2. (|X| < 1) Calculate asin(X) by #
6518 1.1 is # z := sqrt( [1-X][1+X] ) #
6519 1.1 is # asin(X) = atan( x / z ). #
6520 1.1 is # Exit. #
6521 1.1 is # #
6522 1.1 is # 3. If |X| > 1, go to 5. #
6523 1.1 is # #
6524 1.1 is # 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
6525 1.1 is # #
6526 1.1 is # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
6527 1.1 is # Exit. #
6528 1.1 is # #
6529 1.1 is #########################################################################
6530 1.1 is
6531 1.1 is global sasin
6532 1.1 is sasin:
6533 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
6534 1.1 is
6535 1.1 is mov.l (%a0),%d1
6536 1.1 is mov.w 4(%a0),%d1
6537 1.1 is and.l &0x7FFFFFFF,%d1
6538 1.1 is cmp.l %d1,&0x3FFF8000
6539 1.1 is bge.b ASINBIG
6540 1.1 is
6541 1.1 is # This catch is added here for the '060 QSP. Originally, the call to
6542 1.1 is # satan() would handle this case by causing the exception which would
6543 1.1 is # not be caught until gen_except(). Now, with the exceptions being
6544 1.1 is # detected inside of satan(), the exception would have been handled there
6545 1.1 is # instead of inside sasin() as expected.
6546 1.1 is cmp.l %d1,&0x3FD78000
6547 1.1 is blt.w ASINTINY
6548 1.1 is
6549 1.1 is #--THIS IS THE USUAL CASE, |X| < 1
6550 1.1 is #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
6551 1.1 is
6552 1.1 is ASINMAIN:
6553 1.1 is fmov.s &0x3F800000,%fp1
6554 1.1 is fsub.x %fp0,%fp1 # 1-X
6555 1.1 is fmovm.x &0x4,-(%sp) # {fp2}
6556 1.1 is fmov.s &0x3F800000,%fp2
6557 1.1 is fadd.x %fp0,%fp2 # 1+X
6558 1.1 is fmul.x %fp2,%fp1 # (1+X)(1-X)
6559 1.1 is fmovm.x (%sp)+,&0x20 # {fp2}
6560 1.1 is fsqrt.x %fp1 # SQRT([1-X][1+X])
6561 1.1 is fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X])
6562 1.1 is fmovm.x &0x01,-(%sp) # save X/SQRT(...)
6563 1.1 is lea (%sp),%a0 # pass ptr to X/SQRT(...)
6564 1.1 is bsr satan
6565 1.1 is add.l &0xc,%sp # clear X/SQRT(...) from stack
6566 1.1 is bra t_inx2
6567 1.1 is
6568 1.1 is ASINBIG:
6569 1.1 is fabs.x %fp0 # |X|
6570 1.1 is fcmp.s %fp0,&0x3F800000
6571 1.1 is fbgt t_operr # cause an operr exception
6572 1.1 is
6573 1.1 is #--|X| = 1, ASIN(X) = +- PI/2.
6574 1.1 is ASINONE:
6575 1.1 is fmov.x PIBY2(%pc),%fp0
6576 1.1 is mov.l (%a0),%d1
6577 1.1 is and.l &0x80000000,%d1 # SIGN BIT OF X
6578 1.1 is or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT
6579 1.1 is mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT
6580 1.1 is fmov.l %d0,%fpcr
6581 1.1 is fmul.s (%sp)+,%fp0
6582 1.1 is bra t_inx2
6583 1.1 is
6584 1.1 is #--|X| < 2^(-40), ATAN(X) = X
6585 1.1 is ASINTINY:
6586 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec
6587 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
6588 1.1 is fmov.x (%a0),%fp0 # last inst - possible exception
6589 1.1 is bra t_catch
6590 1.1 is
6591 1.1 is global sasind
6592 1.1 is #--ASIN(X) = X FOR DENORMALIZED X
6593 1.1 is sasind:
6594 1.1 is bra t_extdnrm
6595 1.1 is
6596 1.1 is #########################################################################
6597 1.1 is # sacos(): computes the inverse cosine of a normalized input #
6598 1.1 is # sacosd(): computes the inverse cosine of a denormalized input #
6599 1.1 is # #
6600 1.1 is # INPUT *************************************************************** #
6601 1.1 is # a0 = pointer to extended precision input #
6602 1.1 is # d0 = round precision,mode #
6603 1.1 is # #
6604 1.1 is # OUTPUT ************************************************************** #
6605 1.1 is # fp0 = arccos(X) #
6606 1.1 is # #
6607 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
6608 1.1 is # The returned result is within 3 ulps in 64 significant bit, #
6609 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
6610 1.1 is # rounded to double precision. The result is provably monotonic #
6611 1.1 is # in double precision. #
6612 1.1 is # #
6613 1.1 is # ALGORITHM *********************************************************** #
6614 1.1 is # #
6615 1.1 is # ACOS #
6616 1.1 is # 1. If |X| >= 1, go to 3. #
6617 1.1 is # #
6618 1.1 is # 2. (|X| < 1) Calculate acos(X) by #
6619 1.1 is # z := (1-X) / (1+X) #
6620 1.1 is # acos(X) = 2 * atan( sqrt(z) ). #
6621 1.1 is # Exit. #
6622 1.1 is # #
6623 1.1 is # 3. If |X| > 1, go to 5. #
6624 1.1 is # #
6625 1.1 is # 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. #
6626 1.1 is # #
6627 1.1 is # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
6628 1.1 is # Exit. #
6629 1.1 is # #
6630 1.1 is #########################################################################
6631 1.1 is
6632 1.1 is global sacos
6633 1.1 is sacos:
6634 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
6635 1.1 is
6636 1.1 is mov.l (%a0),%d1 # pack exp w/ upper 16 fraction
6637 1.1 is mov.w 4(%a0),%d1
6638 1.1 is and.l &0x7FFFFFFF,%d1
6639 1.1 is cmp.l %d1,&0x3FFF8000
6640 1.1 is bge.b ACOSBIG
6641 1.1 is
6642 1.1 is #--THIS IS THE USUAL CASE, |X| < 1
6643 1.1 is #--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) )
6644 1.1 is
6645 1.1 is ACOSMAIN:
6646 1.1 is fmov.s &0x3F800000,%fp1
6647 1.1 is fadd.x %fp0,%fp1 # 1+X
6648 1.1 is fneg.x %fp0 # -X
6649 1.1 is fadd.s &0x3F800000,%fp0 # 1-X
6650 1.1 is fdiv.x %fp1,%fp0 # (1-X)/(1+X)
6651 1.1 is fsqrt.x %fp0 # SQRT((1-X)/(1+X))
6652 1.1 is mov.l %d0,-(%sp) # save original users fpcr
6653 1.1 is clr.l %d0
6654 1.1 is fmovm.x &0x01,-(%sp) # save SQRT(...) to stack
6655 1.1 is lea (%sp),%a0 # pass ptr to sqrt
6656 1.1 is bsr satan # ATAN(SQRT([1-X]/[1+X]))
6657 1.1 is add.l &0xc,%sp # clear SQRT(...) from stack
6658 1.1 is
6659 1.1 is fmov.l (%sp)+,%fpcr # restore users round prec,mode
6660 1.1 is fadd.x %fp0,%fp0 # 2 * ATAN( STUFF )
6661 1.1 is bra t_pinx2
6662 1.1 is
6663 1.1 is ACOSBIG:
6664 1.1 is fabs.x %fp0
6665 1.1 is fcmp.s %fp0,&0x3F800000
6666 1.1 is fbgt t_operr # cause an operr exception
6667 1.1 is
6668 1.1 is #--|X| = 1, ACOS(X) = 0 OR PI
6669 1.1 is tst.b (%a0) # is X positive or negative?
6670 1.1 is bpl.b ACOSP1
6671 1.1 is
6672 1.1 is #--X = -1
6673 1.1 is #Returns PI and inexact exception
6674 1.1 is ACOSM1:
6675 1.1 is fmov.x PI(%pc),%fp0 # load PI
6676 1.1 is fmov.l %d0,%fpcr # load round mode,prec
6677 1.1 is fadd.s &0x00800000,%fp0 # add a small value
6678 1.1 is bra t_pinx2
6679 1.1 is
6680 1.1 is ACOSP1:
6681 1.1 is bra ld_pzero # answer is positive zero
6682 1.1 is
6683 1.1 is global sacosd
6684 1.1 is #--ACOS(X) = PI/2 FOR DENORMALIZED X
6685 1.1 is sacosd:
6686 1.1 is fmov.l %d0,%fpcr # load user's rnd mode/prec
6687 1.1 is fmov.x PIBY2(%pc),%fp0
6688 1.1 is bra t_pinx2
6689 1.1 is
6690 1.1 is #########################################################################
6691 1.1 is # setox(): computes the exponential for a normalized input #
6692 1.1 is # setoxd(): computes the exponential for a denormalized input #
6693 1.1 is # setoxm1(): computes the exponential minus 1 for a normalized input #
6694 1.1 is # setoxm1d(): computes the exponential minus 1 for a denormalized input #
6695 1.1 is # #
6696 1.1 is # INPUT *************************************************************** #
6697 1.1 is # a0 = pointer to extended precision input #
6698 1.1 is # d0 = round precision,mode #
6699 1.1 is # #
6700 1.1 is # OUTPUT ************************************************************** #
6701 1.1 is # fp0 = exp(X) or exp(X)-1 #
6702 1.1 is # #
6703 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
6704 1.1 is # The returned result is within 0.85 ulps in 64 significant bit, #
6705 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
6706 1.1 is # rounded to double precision. The result is provably monotonic #
6707 1.1 is # in double precision. #
6708 1.1 is # #
6709 1.1 is # ALGORITHM and IMPLEMENTATION **************************************** #
6710 1.1 is # #
6711 1.1 is # setoxd #
6712 1.1 is # ------ #
6713 1.1 is # Step 1. Set ans := 1.0 #
6714 1.1 is # #
6715 1.1 is # Step 2. Return ans := ans + sign(X)*2^(-126). Exit. #
6716 1.1 is # Notes: This will always generate one exception -- inexact. #
6717 1.1 is # #
6718 1.1 is # #
6719 1.1 is # setox #
6720 1.1 is # ----- #
6721 1.1 is # #
6722 1.1 is # Step 1. Filter out extreme cases of input argument. #
6723 1.1 is # 1.1 If |X| >= 2^(-65), go to Step 1.3. #
6724 1.1 is # 1.2 Go to Step 7. #
6725 1.1 is # 1.3 If |X| < 16380 log(2), go to Step 2. #
6726 1.1 is # 1.4 Go to Step 8. #
6727 1.1 is # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.#
6728 1.1 is # To avoid the use of floating-point comparisons, a #
6729 1.1 is # compact representation of |X| is used. This format is a #
6730 1.1 is # 32-bit integer, the upper (more significant) 16 bits #
6731 1.1 is # are the sign and biased exponent field of |X|; the #
6732 1.1 is # lower 16 bits are the 16 most significant fraction #
6733 1.1 is # (including the explicit bit) bits of |X|. Consequently, #
6734 1.1 is # the comparisons in Steps 1.1 and 1.3 can be performed #
6735 1.1 is # by integer comparison. Note also that the constant #
6736 1.1 is # 16380 log(2) used in Step 1.3 is also in the compact #
6737 1.1 is # form. Thus taking the branch to Step 2 guarantees #
6738 1.1 is # |X| < 16380 log(2). There is no harm to have a small #
6739 1.1 is # number of cases where |X| is less than, but close to, #
6740 1.1 is # 16380 log(2) and the branch to Step 9 is taken. #
6741 1.1 is # #
6742 1.1 is # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). #
6743 1.1 is # 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
6744 1.1 is # was taken) #
6745 1.1 is # 2.2 N := round-to-nearest-integer( X * 64/log2 ). #
6746 1.1 is # 2.3 Calculate J = N mod 64; so J = 0,1,2,..., #
6747 1.1 is # or 63. #
6748 1.1 is # 2.4 Calculate M = (N - J)/64; so N = 64M + J. #
6749 1.1 is # 2.5 Calculate the address of the stored value of #
6750 1.1 is # 2^(J/64). #
6751 1.1 is # 2.6 Create the value Scale = 2^M. #
6752 1.1 is # Notes: The calculation in 2.2 is really performed by #
6753 1.1 is # Z := X * constant #
6754 1.1 is # N := round-to-nearest-integer(Z) #
6755 1.1 is # where #
6756 1.1 is # constant := single-precision( 64/log 2 ). #
6757 1.1 is # #
6758 1.1 is # Using a single-precision constant avoids memory #
6759 1.1 is # access. Another effect of using a single-precision #
6760 1.1 is # "constant" is that the calculated value Z is #
6761 1.1 is # #
6762 1.1 is # Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). #
6763 1.1 is # #
6764 1.1 is # This error has to be considered later in Steps 3 and 4. #
6765 1.1 is # #
6766 1.1 is # Step 3. Calculate X - N*log2/64. #
6767 1.1 is # 3.1 R := X + N*L1, #
6768 1.1 is # where L1 := single-precision(-log2/64). #
6769 1.1 is # 3.2 R := R + N*L2, #
6770 1.1 is # L2 := extended-precision(-log2/64 - L1).#
6771 1.1 is # Notes: a) The way L1 and L2 are chosen ensures L1+L2 #
6772 1.1 is # approximate the value -log2/64 to 88 bits of accuracy. #
6773 1.1 is # b) N*L1 is exact because N is no longer than 22 bits #
6774 1.1 is # and L1 is no longer than 24 bits. #
6775 1.1 is # c) The calculation X+N*L1 is also exact due to #
6776 1.1 is # cancellation. Thus, R is practically X+N(L1+L2) to full #
6777 1.1 is # 64 bits. #
6778 1.1 is # d) It is important to estimate how large can |R| be #
6779 1.1 is # after Step 3.2. #
6780 1.1 is # #
6781 1.1 is # N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) #
6782 1.1 is # X*64/log2 (1+eps) = N + f, |f| <= 0.5 #
6783 1.1 is # X*64/log2 - N = f - eps*X 64/log2 #
6784 1.1 is # X - N*log2/64 = f*log2/64 - eps*X #
6785 1.1 is # #
6786 1.1 is # #
6787 1.1 is # Now |X| <= 16446 log2, thus #
6788 1.1 is # #
6789 1.1 is # |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 #
6790 1.1 is # <= 0.57 log2/64. #
6791 1.1 is # This bound will be used in Step 4. #
6792 1.1 is # #
6793 1.1 is # Step 4. Approximate exp(R)-1 by a polynomial #
6794 1.1 is # p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) #
6795 1.1 is # Notes: a) In order to reduce memory access, the coefficients #
6796 1.1 is # are made as "short" as possible: A1 (which is 1/2), A4 #
6797 1.1 is # and A5 are single precision; A2 and A3 are double #
6798 1.1 is # precision. #
6799 1.1 is # b) Even with the restrictions above, #
6800 1.1 is # |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. #
6801 1.1 is # Note that 0.0062 is slightly bigger than 0.57 log2/64. #
6802 1.1 is # c) To fully utilize the pipeline, p is separated into #
6803 1.1 is # two independent pieces of roughly equal complexities #
6804 1.1 is # p = [ R + R*S*(A2 + S*A4) ] + #
6805 1.1 is # [ S*(A1 + S*(A3 + S*A5)) ] #
6806 1.1 is # where S = R*R. #
6807 1.1 is # #
6808 1.1 is # Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by #
6809 1.1 is # ans := T + ( T*p + t) #
6810 1.1 is # where T and t are the stored values for 2^(J/64). #
6811 1.1 is # Notes: 2^(J/64) is stored as T and t where T+t approximates #
6812 1.1 is # 2^(J/64) to roughly 85 bits; T is in extended precision #
6813 1.1 is # and t is in single precision. Note also that T is #
6814 1.1 is # rounded to 62 bits so that the last two bits of T are #
6815 1.1 is # zero. The reason for such a special form is that T-1, #
6816 1.1 is # T-2, and T-8 will all be exact --- a property that will #
6817 1.1 is # give much more accurate computation of the function #
6818 1.1 is # EXPM1. #
6819 1.1 is # #
6820 1.1 is # Step 6. Reconstruction of exp(X) #
6821 1.1 is # exp(X) = 2^M * 2^(J/64) * exp(R). #
6822 1.1 is # 6.1 If AdjFlag = 0, go to 6.3 #
6823 1.1 is # 6.2 ans := ans * AdjScale #
6824 1.1 is # 6.3 Restore the user FPCR #
6825 1.1 is # 6.4 Return ans := ans * Scale. Exit. #
6826 1.1 is # Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, #
6827 1.1 is # |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will #
6828 1.1 is # neither overflow nor underflow. If AdjFlag = 1, that #
6829 1.1 is # means that #
6830 1.1 is # X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. #
6831 1.1 is # Hence, exp(X) may overflow or underflow or neither. #
6832 1.1 is # When that is the case, AdjScale = 2^(M1) where M1 is #
6833 1.1 is # approximately M. Thus 6.2 will never cause #
6834 1.1 is # over/underflow. Possible exception in 6.4 is overflow #
6835 1.1 is # or underflow. The inexact exception is not generated in #
6836 1.1 is # 6.4. Although one can argue that the inexact flag #
6837 1.1 is # should always be raised, to simulate that exception #
6838 1.1 is # cost to much than the flag is worth in practical uses. #
6839 1.1 is # #
6840 1.1 is # Step 7. Return 1 + X. #
6841 1.1 is # 7.1 ans := X #
6842 1.1 is # 7.2 Restore user FPCR. #
6843 1.1 is # 7.3 Return ans := 1 + ans. Exit #
6844 1.1 is # Notes: For non-zero X, the inexact exception will always be #
6845 1.1 is # raised by 7.3. That is the only exception raised by 7.3.#
6846 1.1 is # Note also that we use the FMOVEM instruction to move X #
6847 1.1 is # in Step 7.1 to avoid unnecessary trapping. (Although #
6848 1.1 is # the FMOVEM may not seem relevant since X is normalized, #
6849 1.1 is # the precaution will be useful in the library version of #
6850 1.1 is # this code where the separate entry for denormalized #
6851 1.1 is # inputs will be done away with.) #
6852 1.1 is # #
6853 1.1 is # Step 8. Handle exp(X) where |X| >= 16380log2. #
6854 1.1 is # 8.1 If |X| > 16480 log2, go to Step 9. #
6855 1.1 is # (mimic 2.2 - 2.6) #
6856 1.1 is # 8.2 N := round-to-integer( X * 64/log2 ) #
6857 1.1 is # 8.3 Calculate J = N mod 64, J = 0,1,...,63 #
6858 1.1 is # 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, #
6859 1.1 is # AdjFlag := 1. #
6860 1.1 is # 8.5 Calculate the address of the stored value #
6861 1.1 is # 2^(J/64). #
6862 1.1 is # 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. #
6863 1.1 is # 8.7 Go to Step 3. #
6864 1.1 is # Notes: Refer to notes for 2.2 - 2.6. #
6865 1.1 is # #
6866 1.1 is # Step 9. Handle exp(X), |X| > 16480 log2. #
6867 1.1 is # 9.1 If X < 0, go to 9.3 #
6868 1.1 is # 9.2 ans := Huge, go to 9.4 #
6869 1.1 is # 9.3 ans := Tiny. #
6870 1.1 is # 9.4 Restore user FPCR. #
6871 1.1 is # 9.5 Return ans := ans * ans. Exit. #
6872 1.1 is # Notes: Exp(X) will surely overflow or underflow, depending on #
6873 1.1 is # X's sign. "Huge" and "Tiny" are respectively large/tiny #
6874 1.1 is # extended-precision numbers whose square over/underflow #
6875 1.1 is # with an inexact result. Thus, 9.5 always raises the #
6876 1.1 is # inexact together with either overflow or underflow. #
6877 1.1 is # #
6878 1.1 is # setoxm1d #
6879 1.1 is # -------- #
6880 1.1 is # #
6881 1.1 is # Step 1. Set ans := 0 #
6882 1.1 is # #
6883 1.1 is # Step 2. Return ans := X + ans. Exit. #
6884 1.1 is # Notes: This will return X with the appropriate rounding #
6885 1.1 is # precision prescribed by the user FPCR. #
6886 1.1 is # #
6887 1.1 is # setoxm1 #
6888 1.1 is # ------- #
6889 1.1 is # #
6890 1.1 is # Step 1. Check |X| #
6891 1.1 is # 1.1 If |X| >= 1/4, go to Step 1.3. #
6892 1.1 is # 1.2 Go to Step 7. #
6893 1.1 is # 1.3 If |X| < 70 log(2), go to Step 2. #
6894 1.1 is # 1.4 Go to Step 10. #
6895 1.1 is # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.#
6896 1.1 is # However, it is conceivable |X| can be small very often #
6897 1.1 is # because EXPM1 is intended to evaluate exp(X)-1 #
6898 1.1 is # accurately when |X| is small. For further details on #
6899 1.1 is # the comparisons, see the notes on Step 1 of setox. #
6900 1.1 is # #
6901 1.1 is # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). #
6902 1.1 is # 2.1 N := round-to-nearest-integer( X * 64/log2 ). #
6903 1.1 is # 2.2 Calculate J = N mod 64; so J = 0,1,2,..., #
6904 1.1 is # or 63. #
6905 1.1 is # 2.3 Calculate M = (N - J)/64; so N = 64M + J. #
6906 1.1 is # 2.4 Calculate the address of the stored value of #
6907 1.1 is # 2^(J/64). #
6908 1.1 is # 2.5 Create the values Sc = 2^M and #
6909 1.1 is # OnebySc := -2^(-M). #
6910 1.1 is # Notes: See the notes on Step 2 of setox. #
6911 1.1 is # #
6912 1.1 is # Step 3. Calculate X - N*log2/64. #
6913 1.1 is # 3.1 R := X + N*L1, #
6914 1.1 is # where L1 := single-precision(-log2/64). #
6915 1.1 is # 3.2 R := R + N*L2, #
6916 1.1 is # L2 := extended-precision(-log2/64 - L1).#
6917 1.1 is # Notes: Applying the analysis of Step 3 of setox in this case #
6918 1.1 is # shows that |R| <= 0.0055 (note that |X| <= 70 log2 in #
6919 1.1 is # this case). #
6920 1.1 is # #
6921 1.1 is # Step 4. Approximate exp(R)-1 by a polynomial #
6922 1.1 is # p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) #
6923 1.1 is # Notes: a) In order to reduce memory access, the coefficients #
6924 1.1 is # are made as "short" as possible: A1 (which is 1/2), A5 #
6925 1.1 is # and A6 are single precision; A2, A3 and A4 are double #
6926 1.1 is # precision. #
6927 1.1 is # b) Even with the restriction above, #
6928 1.1 is # |p - (exp(R)-1)| < |R| * 2^(-72.7) #
6929 1.1 is # for all |R| <= 0.0055. #
6930 1.1 is # c) To fully utilize the pipeline, p is separated into #
6931 1.1 is # two independent pieces of roughly equal complexity #
6932 1.1 is # p = [ R*S*(A2 + S*(A4 + S*A6)) ] + #
6933 1.1 is # [ R + S*(A1 + S*(A3 + S*A5)) ] #
6934 1.1 is # where S = R*R. #
6935 1.1 is # #
6936 1.1 is # Step 5. Compute 2^(J/64)*p by #
6937 1.1 is # p := T*p #
6938 1.1 is # where T and t are the stored values for 2^(J/64). #
6939 1.1 is # Notes: 2^(J/64) is stored as T and t where T+t approximates #
6940 1.1 is # 2^(J/64) to roughly 85 bits; T is in extended precision #
6941 1.1 is # and t is in single precision. Note also that T is #
6942 1.1 is # rounded to 62 bits so that the last two bits of T are #
6943 1.1 is # zero. The reason for such a special form is that T-1, #
6944 1.1 is # T-2, and T-8 will all be exact --- a property that will #
6945 1.1 is # be exploited in Step 6 below. The total relative error #
6946 1.1 is # in p is no bigger than 2^(-67.7) compared to the final #
6947 1.1 is # result. #
6948 1.1 is # #
6949 1.1 is # Step 6. Reconstruction of exp(X)-1 #
6950 1.1 is # exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). #
6951 1.1 is # 6.1 If M <= 63, go to Step 6.3. #
6952 1.1 is # 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 #
6953 1.1 is # 6.3 If M >= -3, go to 6.5. #
6954 1.1 is # 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 #
6955 1.1 is # 6.5 ans := (T + OnebySc) + (p + t). #
6956 1.1 is # 6.6 Restore user FPCR. #
6957 1.1 is # 6.7 Return ans := Sc * ans. Exit. #
6958 1.1 is # Notes: The various arrangements of the expressions give #
6959 1.1 is # accurate evaluations. #
6960 1.1 is # #
6961 1.1 is # Step 7. exp(X)-1 for |X| < 1/4. #
6962 1.1 is # 7.1 If |X| >= 2^(-65), go to Step 9. #
6963 1.1 is # 7.2 Go to Step 8. #
6964 1.1 is # #
6965 1.1 is # Step 8. Calculate exp(X)-1, |X| < 2^(-65). #
6966 1.1 is # 8.1 If |X| < 2^(-16312), goto 8.3 #
6967 1.1 is # 8.2 Restore FPCR; return ans := X - 2^(-16382). #
6968 1.1 is # Exit. #
6969 1.1 is # 8.3 X := X * 2^(140). #
6970 1.1 is # 8.4 Restore FPCR; ans := ans - 2^(-16382). #
6971 1.1 is # Return ans := ans*2^(140). Exit #
6972 1.1 is # Notes: The idea is to return "X - tiny" under the user #
6973 1.1 is # precision and rounding modes. To avoid unnecessary #
6974 1.1 is # inefficiency, we stay away from denormalized numbers #
6975 1.1 is # the best we can. For |X| >= 2^(-16312), the #
6976 1.1 is # straightforward 8.2 generates the inexact exception as #
6977 1.1 is # the case warrants. #
6978 1.1 is # #
6979 1.1 is # Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial #
6980 1.1 is # p = X + X*X*(B1 + X*(B2 + ... + X*B12)) #
6981 1.1 is # Notes: a) In order to reduce memory access, the coefficients #
6982 1.1 is # are made as "short" as possible: B1 (which is 1/2), B9 #
6983 1.1 is # to B12 are single precision; B3 to B8 are double #
6984 1.1 is # precision; and B2 is double extended. #
6985 1.1 is # b) Even with the restriction above, #
6986 1.1 is # |p - (exp(X)-1)| < |X| 2^(-70.6) #
6987 1.1 is # for all |X| <= 0.251. #
6988 1.1 is # Note that 0.251 is slightly bigger than 1/4. #
6989 1.1 is # c) To fully preserve accuracy, the polynomial is #
6990 1.1 is # computed as #
6991 1.1 is # X + ( S*B1 + Q ) where S = X*X and #
6992 1.1 is # Q = X*S*(B2 + X*(B3 + ... + X*B12)) #
6993 1.1 is # d) To fully utilize the pipeline, Q is separated into #
6994 1.1 is # two independent pieces of roughly equal complexity #
6995 1.1 is # Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + #
6996 1.1 is # [ S*S*(B3 + S*(B5 + ... + S*B11)) ] #
6997 1.1 is # #
6998 1.1 is # Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. #
6999 1.1 is # 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all #
7000 1.1 is # practical purposes. Therefore, go to Step 1 of setox. #
7001 1.1 is # 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical #
7002 1.1 is # purposes. #
7003 1.1 is # ans := -1 #
7004 1.1 is # Restore user FPCR #
7005 1.1 is # Return ans := ans + 2^(-126). Exit. #
7006 1.1 is # Notes: 10.2 will always create an inexact and return -1 + tiny #
7007 1.1 is # in the user rounding precision and mode. #
7008 1.1 is # #
7009 1.1 is #########################################################################
7010 1.1 is
7011 1.1 is L2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
7012 1.1 is
7013 1.1 is EEXPA3: long 0x3FA55555,0x55554CC1
7014 1.1 is EEXPA2: long 0x3FC55555,0x55554A54
7015 1.1 is
7016 1.1 is EM1A4: long 0x3F811111,0x11174385
7017 1.1 is EM1A3: long 0x3FA55555,0x55554F5A
7018 1.1 is
7019 1.1 is EM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000
7020 1.1 is
7021 1.1 is EM1B8: long 0x3EC71DE3,0xA5774682
7022 1.1 is EM1B7: long 0x3EFA01A0,0x19D7CB68
7023 1.1 is
7024 1.1 is EM1B6: long 0x3F2A01A0,0x1A019DF3
7025 1.1 is EM1B5: long 0x3F56C16C,0x16C170E2
7026 1.1 is
7027 1.1 is EM1B4: long 0x3F811111,0x11111111
7028 1.1 is EM1B3: long 0x3FA55555,0x55555555
7029 1.1 is
7030 1.1 is EM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
7031 1.1 is long 0x00000000
7032 1.1 is
7033 1.1 is TWO140: long 0x48B00000,0x00000000
7034 1.1 is TWON140:
7035 1.1 is long 0x37300000,0x00000000
7036 1.1 is
7037 1.1 is EEXPTBL:
7038 1.1 is long 0x3FFF0000,0x80000000,0x00000000,0x00000000
7039 1.1 is long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
7040 1.1 is long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
7041 1.1 is long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
7042 1.1 is long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
7043 1.1 is long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
7044 1.1 is long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
7045 1.1 is long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
7046 1.1 is long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
7047 1.1 is long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
7048 1.1 is long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
7049 1.1 is long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
7050 1.1 is long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
7051 1.1 is long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
7052 1.1 is long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
7053 1.1 is long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
7054 1.1 is long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
7055 1.1 is long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
7056 1.1 is long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
7057 1.1 is long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
7058 1.1 is long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
7059 1.1 is long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
7060 1.1 is long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
7061 1.1 is long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
7062 1.1 is long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
7063 1.1 is long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
7064 1.1 is long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
7065 1.1 is long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
7066 1.1 is long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
7067 1.1 is long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
7068 1.1 is long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
7069 1.1 is long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
7070 1.1 is long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
7071 1.1 is long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
7072 1.1 is long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
7073 1.1 is long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
7074 1.1 is long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
7075 1.1 is long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
7076 1.1 is long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
7077 1.1 is long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
7078 1.1 is long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
7079 1.1 is long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
7080 1.1 is long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
7081 1.1 is long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
7082 1.1 is long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
7083 1.1 is long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
7084 1.1 is long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
7085 1.1 is long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
7086 1.1 is long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
7087 1.1 is long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
7088 1.1 is long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
7089 1.1 is long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
7090 1.1 is long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
7091 1.1 is long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
7092 1.1 is long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
7093 1.1 is long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
7094 1.1 is long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
7095 1.1 is long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
7096 1.1 is long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
7097 1.1 is long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
7098 1.1 is long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
7099 1.1 is long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
7100 1.1 is long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
7101 1.1 is long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
7102 1.1 is
7103 1.1 is set ADJFLAG,L_SCR2
7104 1.1 is set SCALE,FP_SCR0
7105 1.1 is set ADJSCALE,FP_SCR1
7106 1.1 is set SC,FP_SCR0
7107 1.1 is set ONEBYSC,FP_SCR1
7108 1.1 is
7109 1.1 is global setox
7110 1.1 is setox:
7111 1.1 is #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
7112 1.1 is
7113 1.1 is #--Step 1.
7114 1.1 is mov.l (%a0),%d1 # load part of input X
7115 1.1 is and.l &0x7FFF0000,%d1 # biased expo. of X
7116 1.1 is cmp.l %d1,&0x3FBE0000 # 2^(-65)
7117 1.1 is bge.b EXPC1 # normal case
7118 1.1 is bra EXPSM
7119 1.1 is
7120 1.1 is EXPC1:
7121 1.1 is #--The case |X| >= 2^(-65)
7122 1.1 is mov.w 4(%a0),%d1 # expo. and partial sig. of |X|
7123 1.1 is cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits
7124 1.1 is blt.b EXPMAIN # normal case
7125 1.1 is bra EEXPBIG
7126 1.1 is
7127 1.1 is EXPMAIN:
7128 1.1 is #--Step 2.
7129 1.1 is #--This is the normal branch: 2^(-65) <= |X| < 16380 log2.
7130 1.1 is fmov.x (%a0),%fp0 # load input from (a0)
7131 1.1 is
7132 1.1 is fmov.x %fp0,%fp1
7133 1.1 is fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
7134 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
7135 1.1 is mov.l &0,ADJFLAG(%a6)
7136 1.1 is fmov.l %fp0,%d1 # N = int( X * 64/log2 )
7137 1.1 is lea EEXPTBL(%pc),%a1
7138 1.1 is fmov.l %d1,%fp0 # convert to floating-format
7139 1.1 is
7140 1.1 is mov.l %d1,L_SCR1(%a6) # save N temporarily
7141 1.1 is and.l &0x3F,%d1 # D0 is J = N mod 64
7142 1.1 is lsl.l &4,%d1
7143 1.1 is add.l %d1,%a1 # address of 2^(J/64)
7144 1.1 is mov.l L_SCR1(%a6),%d1
7145 1.1 is asr.l &6,%d1 # D0 is M
7146 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(M)
7147 1.1 is mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB
7148 1.1 is
7149 1.1 is EXPCONT1:
7150 1.1 is #--Step 3.
7151 1.1 is #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
7152 1.1 is #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
7153 1.1 is fmov.x %fp0,%fp2
7154 1.1 is fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64)
7155 1.1 is fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64
7156 1.1 is fadd.x %fp1,%fp0 # X + N*L1
7157 1.1 is fadd.x %fp2,%fp0 # fp0 is R, reduced arg.
7158 1.1 is
7159 1.1 is #--Step 4.
7160 1.1 is #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
7161 1.1 is #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
7162 1.1 is #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
7163 1.1 is #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
7164 1.1 is
7165 1.1 is fmov.x %fp0,%fp1
7166 1.1 is fmul.x %fp1,%fp1 # fp1 IS S = R*R
7167 1.1 is
7168 1.1 is fmov.s &0x3AB60B70,%fp2 # fp2 IS A5
7169 1.1 is
7170 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*A5
7171 1.1 is fmov.x %fp1,%fp3
7172 1.1 is fmul.s &0x3C088895,%fp3 # fp3 IS S*A4
7173 1.1 is
7174 1.1 is fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5
7175 1.1 is fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4
7176 1.1 is
7177 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5)
7178 1.1 is mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended
7179 1.1 is mov.l &0x80000000,SCALE+4(%a6)
7180 1.1 is clr.l SCALE+8(%a6)
7181 1.1 is
7182 1.1 is fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4)
7183 1.1 is
7184 1.1 is fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5)
7185 1.1 is fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4)
7186 1.1 is
7187 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5))
7188 1.1 is fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4),
7189 1.1 is
7190 1.1 is fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64)
7191 1.1 is fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1
7192 1.1 is
7193 1.1 is #--Step 5
7194 1.1 is #--final reconstruction process
7195 1.1 is #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
7196 1.1 is
7197 1.1 is fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1)
7198 1.1 is fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
7199 1.1 is fadd.s (%a1),%fp0 # accurate 2^(J/64)
7200 1.1 is
7201 1.1 is fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*...
7202 1.1 is mov.l ADJFLAG(%a6),%d1
7203 1.1 is
7204 1.1 is #--Step 6
7205 1.1 is tst.l %d1
7206 1.1 is beq.b NORMAL
7207 1.1 is ADJUST:
7208 1.1 is fmul.x ADJSCALE(%a6),%fp0
7209 1.1 is NORMAL:
7210 1.1 is fmov.l %d0,%fpcr # restore user FPCR
7211 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
7212 1.1 is fmul.x SCALE(%a6),%fp0 # multiply 2^(M)
7213 1.1 is bra t_catch
7214 1.1 is
7215 1.1 is EXPSM:
7216 1.1 is #--Step 7
7217 1.1 is fmovm.x (%a0),&0x80 # load X
7218 1.1 is fmov.l %d0,%fpcr
7219 1.1 is fadd.s &0x3F800000,%fp0 # 1+X in user mode
7220 1.1 is bra t_pinx2
7221 1.1 is
7222 1.1 is EEXPBIG:
7223 1.1 is #--Step 8
7224 1.1 is cmp.l %d1,&0x400CB27C # 16480 log2
7225 1.1 is bgt.b EXP2BIG
7226 1.1 is #--Steps 8.2 -- 8.6
7227 1.1 is fmov.x (%a0),%fp0 # load input from (a0)
7228 1.1 is
7229 1.1 is fmov.x %fp0,%fp1
7230 1.1 is fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
7231 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
7232 1.1 is mov.l &1,ADJFLAG(%a6)
7233 1.1 is fmov.l %fp0,%d1 # N = int( X * 64/log2 )
7234 1.1 is lea EEXPTBL(%pc),%a1
7235 1.1 is fmov.l %d1,%fp0 # convert to floating-format
7236 1.1 is mov.l %d1,L_SCR1(%a6) # save N temporarily
7237 1.1 is and.l &0x3F,%d1 # D0 is J = N mod 64
7238 1.1 is lsl.l &4,%d1
7239 1.1 is add.l %d1,%a1 # address of 2^(J/64)
7240 1.1 is mov.l L_SCR1(%a6),%d1
7241 1.1 is asr.l &6,%d1 # D0 is K
7242 1.1 is mov.l %d1,L_SCR1(%a6) # save K temporarily
7243 1.1 is asr.l &1,%d1 # D0 is M1
7244 1.1 is sub.l %d1,L_SCR1(%a6) # a1 is M
7245 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(M1)
7246 1.1 is mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1)
7247 1.1 is mov.l &0x80000000,ADJSCALE+4(%a6)
7248 1.1 is clr.l ADJSCALE+8(%a6)
7249 1.1 is mov.l L_SCR1(%a6),%d1 # D0 is M
7250 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(M)
7251 1.1 is bra.w EXPCONT1 # go back to Step 3
7252 1.1 is
7253 1.1 is EXP2BIG:
7254 1.1 is #--Step 9
7255 1.1 is tst.b (%a0) # is X positive or negative?
7256 1.1 is bmi t_unfl2
7257 1.1 is bra t_ovfl2
7258 1.1 is
7259 1.1 is global setoxd
7260 1.1 is setoxd:
7261 1.1 is #--entry point for EXP(X), X is denormalized
7262 1.1 is mov.l (%a0),-(%sp)
7263 1.1 is andi.l &0x80000000,(%sp)
7264 1.1 is ori.l &0x00800000,(%sp) # sign(X)*2^(-126)
7265 1.1 is
7266 1.1 is fmov.s &0x3F800000,%fp0
7267 1.1 is
7268 1.1 is fmov.l %d0,%fpcr
7269 1.1 is fadd.s (%sp)+,%fp0
7270 1.1 is bra t_pinx2
7271 1.1 is
7272 1.1 is global setoxm1
7273 1.1 is setoxm1:
7274 1.1 is #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
7275 1.1 is
7276 1.1 is #--Step 1.
7277 1.1 is #--Step 1.1
7278 1.1 is mov.l (%a0),%d1 # load part of input X
7279 1.1 is and.l &0x7FFF0000,%d1 # biased expo. of X
7280 1.1 is cmp.l %d1,&0x3FFD0000 # 1/4
7281 1.1 is bge.b EM1CON1 # |X| >= 1/4
7282 1.1 is bra EM1SM
7283 1.1 is
7284 1.1 is EM1CON1:
7285 1.1 is #--Step 1.3
7286 1.1 is #--The case |X| >= 1/4
7287 1.1 is mov.w 4(%a0),%d1 # expo. and partial sig. of |X|
7288 1.1 is cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits
7289 1.1 is ble.b EM1MAIN # 1/4 <= |X| <= 70log2
7290 1.1 is bra EM1BIG
7291 1.1 is
7292 1.1 is EM1MAIN:
7293 1.1 is #--Step 2.
7294 1.1 is #--This is the case: 1/4 <= |X| <= 70 log2.
7295 1.1 is fmov.x (%a0),%fp0 # load input from (a0)
7296 1.1 is
7297 1.1 is fmov.x %fp0,%fp1
7298 1.1 is fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
7299 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
7300 1.1 is fmov.l %fp0,%d1 # N = int( X * 64/log2 )
7301 1.1 is lea EEXPTBL(%pc),%a1
7302 1.1 is fmov.l %d1,%fp0 # convert to floating-format
7303 1.1 is
7304 1.1 is mov.l %d1,L_SCR1(%a6) # save N temporarily
7305 1.1 is and.l &0x3F,%d1 # D0 is J = N mod 64
7306 1.1 is lsl.l &4,%d1
7307 1.1 is add.l %d1,%a1 # address of 2^(J/64)
7308 1.1 is mov.l L_SCR1(%a6),%d1
7309 1.1 is asr.l &6,%d1 # D0 is M
7310 1.1 is mov.l %d1,L_SCR1(%a6) # save a copy of M
7311 1.1 is
7312 1.1 is #--Step 3.
7313 1.1 is #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
7314 1.1 is #--a0 points to 2^(J/64), D0 and a1 both contain M
7315 1.1 is fmov.x %fp0,%fp2
7316 1.1 is fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64)
7317 1.1 is fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64
7318 1.1 is fadd.x %fp1,%fp0 # X + N*L1
7319 1.1 is fadd.x %fp2,%fp0 # fp0 is R, reduced arg.
7320 1.1 is add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M
7321 1.1 is
7322 1.1 is #--Step 4.
7323 1.1 is #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
7324 1.1 is #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
7325 1.1 is #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
7326 1.1 is #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
7327 1.1 is
7328 1.1 is fmov.x %fp0,%fp1
7329 1.1 is fmul.x %fp1,%fp1 # fp1 IS S = R*R
7330 1.1 is
7331 1.1 is fmov.s &0x3950097B,%fp2 # fp2 IS a6
7332 1.1 is
7333 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*A6
7334 1.1 is fmov.x %fp1,%fp3
7335 1.1 is fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5
7336 1.1 is
7337 1.1 is fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6
7338 1.1 is fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5
7339 1.1 is mov.w %d1,SC(%a6) # SC is 2^(M) in extended
7340 1.1 is mov.l &0x80000000,SC+4(%a6)
7341 1.1 is clr.l SC+8(%a6)
7342 1.1 is
7343 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6)
7344 1.1 is mov.l L_SCR1(%a6),%d1 # D0 is M
7345 1.1 is neg.w %d1 # D0 is -M
7346 1.1 is fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5)
7347 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(-M)
7348 1.1 is fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6)
7349 1.1 is fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5)
7350 1.1 is
7351 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6))
7352 1.1 is or.w &0x8000,%d1 # signed/expo. of -2^(-M)
7353 1.1 is mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M)
7354 1.1 is mov.l &0x80000000,ONEBYSC+4(%a6)
7355 1.1 is clr.l ONEBYSC+8(%a6)
7356 1.1 is fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5))
7357 1.1 is
7358 1.1 is fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6))
7359 1.1 is fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5))
7360 1.1 is
7361 1.1 is fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1
7362 1.1 is
7363 1.1 is fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
7364 1.1 is
7365 1.1 is #--Step 5
7366 1.1 is #--Compute 2^(J/64)*p
7367 1.1 is
7368 1.1 is fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1)
7369 1.1 is
7370 1.1 is #--Step 6
7371 1.1 is #--Step 6.1
7372 1.1 is mov.l L_SCR1(%a6),%d1 # retrieve M
7373 1.1 is cmp.l %d1,&63
7374 1.1 is ble.b MLE63
7375 1.1 is #--Step 6.2 M >= 64
7376 1.1 is fmov.s 12(%a1),%fp1 # fp1 is t
7377 1.1 is fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc
7378 1.1 is fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released
7379 1.1 is fadd.x (%a1),%fp0 # T+(p+(t+OnebySc))
7380 1.1 is bra EM1SCALE
7381 1.1 is MLE63:
7382 1.1 is #--Step 6.3 M <= 63
7383 1.1 is cmp.l %d1,&-3
7384 1.1 is bge.b MGEN3
7385 1.1 is MLTN3:
7386 1.1 is #--Step 6.4 M <= -4
7387 1.1 is fadd.s 12(%a1),%fp0 # p+t
7388 1.1 is fadd.x (%a1),%fp0 # T+(p+t)
7389 1.1 is fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t))
7390 1.1 is bra EM1SCALE
7391 1.1 is MGEN3:
7392 1.1 is #--Step 6.5 -3 <= M <= 63
7393 1.1 is fmov.x (%a1)+,%fp1 # fp1 is T
7394 1.1 is fadd.s (%a1),%fp0 # fp0 is p+t
7395 1.1 is fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc
7396 1.1 is fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t)
7397 1.1 is
7398 1.1 is EM1SCALE:
7399 1.1 is #--Step 6.6
7400 1.1 is fmov.l %d0,%fpcr
7401 1.1 is fmul.x SC(%a6),%fp0
7402 1.1 is bra t_inx2
7403 1.1 is
7404 1.1 is EM1SM:
7405 1.1 is #--Step 7 |X| < 1/4.
7406 1.1 is cmp.l %d1,&0x3FBE0000 # 2^(-65)
7407 1.1 is bge.b EM1POLY
7408 1.1 is
7409 1.1 is EM1TINY:
7410 1.1 is #--Step 8 |X| < 2^(-65)
7411 1.1 is cmp.l %d1,&0x00330000 # 2^(-16312)
7412 1.1 is blt.b EM12TINY
7413 1.1 is #--Step 8.2
7414 1.1 is mov.l &0x80010000,SC(%a6) # SC is -2^(-16382)
7415 1.1 is mov.l &0x80000000,SC+4(%a6)
7416 1.1 is clr.l SC+8(%a6)
7417 1.1 is fmov.x (%a0),%fp0
7418 1.1 is fmov.l %d0,%fpcr
7419 1.1 is mov.b &FADD_OP,%d1 # last inst is ADD
7420 1.1 is fadd.x SC(%a6),%fp0
7421 1.1 is bra t_catch
7422 1.1 is
7423 1.1 is EM12TINY:
7424 1.1 is #--Step 8.3
7425 1.1 is fmov.x (%a0),%fp0
7426 1.1 is fmul.d TWO140(%pc),%fp0
7427 1.1 is mov.l &0x80010000,SC(%a6)
7428 1.1 is mov.l &0x80000000,SC+4(%a6)
7429 1.1 is clr.l SC+8(%a6)
7430 1.1 is fadd.x SC(%a6),%fp0
7431 1.1 is fmov.l %d0,%fpcr
7432 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
7433 1.1 is fmul.d TWON140(%pc),%fp0
7434 1.1 is bra t_catch
7435 1.1 is
7436 1.1 is EM1POLY:
7437 1.1 is #--Step 9 exp(X)-1 by a simple polynomial
7438 1.1 is fmov.x (%a0),%fp0 # fp0 is X
7439 1.1 is fmul.x %fp0,%fp0 # fp0 is S := X*X
7440 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
7441 1.1 is fmov.s &0x2F30CAA8,%fp1 # fp1 is B12
7442 1.1 is fmul.x %fp0,%fp1 # fp1 is S*B12
7443 1.1 is fmov.s &0x310F8290,%fp2 # fp2 is B11
7444 1.1 is fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12
7445 1.1 is
7446 1.1 is fmul.x %fp0,%fp2 # fp2 is S*B11
7447 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B10 + ...
7448 1.1 is
7449 1.1 is fadd.s &0x3493F281,%fp2 # fp2 is B9+S*...
7450 1.1 is fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*...
7451 1.1 is
7452 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B9+...
7453 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B8+...
7454 1.1 is
7455 1.1 is fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*...
7456 1.1 is fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*...
7457 1.1 is
7458 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B7+...
7459 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B6+...
7460 1.1 is
7461 1.1 is fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*...
7462 1.1 is fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*...
7463 1.1 is
7464 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B5+...
7465 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B4+...
7466 1.1 is
7467 1.1 is fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*...
7468 1.1 is fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*...
7469 1.1 is
7470 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B3+...
7471 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B2+...
7472 1.1 is
7473 1.1 is fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...)
7474 1.1 is fmul.x (%a0),%fp1 # fp1 is X*S*(B2...
7475 1.1 is
7476 1.1 is fmul.s &0x3F000000,%fp0 # fp0 is S*B1
7477 1.1 is fadd.x %fp2,%fp1 # fp1 is Q
7478 1.1 is
7479 1.1 is fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
7480 1.1 is
7481 1.1 is fadd.x %fp1,%fp0 # fp0 is S*B1+Q
7482 1.1 is
7483 1.1 is fmov.l %d0,%fpcr
7484 1.1 is fadd.x (%a0),%fp0
7485 1.1 is bra t_inx2
7486 1.1 is
7487 1.1 is EM1BIG:
7488 1.1 is #--Step 10 |X| > 70 log2
7489 1.1 is mov.l (%a0),%d1
7490 1.1 is cmp.l %d1,&0
7491 1.1 is bgt.w EXPC1
7492 1.1 is #--Step 10.2
7493 1.1 is fmov.s &0xBF800000,%fp0 # fp0 is -1
7494 1.1 is fmov.l %d0,%fpcr
7495 1.1 is fadd.s &0x00800000,%fp0 # -1 + 2^(-126)
7496 1.1 is bra t_minx2
7497 1.1 is
7498 1.1 is global setoxm1d
7499 1.1 is setoxm1d:
7500 1.1 is #--entry point for EXPM1(X), here X is denormalized
7501 1.1 is #--Step 0.
7502 1.1 is bra t_extdnrm
7503 1.1 is
7504 1.1 is #########################################################################
7505 1.1 is # sgetexp(): returns the exponent portion of the input argument. #
7506 1.1 is # The exponent bias is removed and the exponent value is #
7507 1.1 is # returned as an extended precision number in fp0. #
7508 1.1 is # sgetexpd(): handles denormalized numbers. #
7509 1.1 is # #
7510 1.1 is # sgetman(): extracts the mantissa of the input argument. The #
7511 1.1 is # mantissa is converted to an extended precision number w/ #
7512 1.1 is # an exponent of $3fff and is returned in fp0. The range of #
7513 1.1 is # the result is [1.0 - 2.0). #
7514 1.1 is # sgetmand(): handles denormalized numbers. #
7515 1.1 is # #
7516 1.1 is # INPUT *************************************************************** #
7517 1.1 is # a0 = pointer to extended precision input #
7518 1.1 is # #
7519 1.1 is # OUTPUT ************************************************************** #
7520 1.1 is # fp0 = exponent(X) or mantissa(X) #
7521 1.1 is # #
7522 1.1 is #########################################################################
7523 1.1 is
7524 1.1 is global sgetexp
7525 1.1 is sgetexp:
7526 1.1 is mov.w SRC_EX(%a0),%d0 # get the exponent
7527 1.1 is bclr &0xf,%d0 # clear the sign bit
7528 1.1 is subi.w &0x3fff,%d0 # subtract off the bias
7529 1.1 is fmov.w %d0,%fp0 # return exp in fp0
7530 1.1 is blt.b sgetexpn # it's negative
7531 1.1 is rts
7532 1.1 is
7533 1.1 is sgetexpn:
7534 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
7535 1.1 is rts
7536 1.1 is
7537 1.1 is global sgetexpd
7538 1.1 is sgetexpd:
7539 1.1 is bsr.l norm # normalize
7540 1.1 is neg.w %d0 # new exp = -(shft amt)
7541 1.1 is subi.w &0x3fff,%d0 # subtract off the bias
7542 1.1 is fmov.w %d0,%fp0 # return exp in fp0
7543 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
7544 1.1 is rts
7545 1.1 is
7546 1.1 is global sgetman
7547 1.1 is sgetman:
7548 1.1 is mov.w SRC_EX(%a0),%d0 # get the exp
7549 1.1 is ori.w &0x7fff,%d0 # clear old exp
7550 1.1 is bclr &0xe,%d0 # make it the new exp +-3fff
7551 1.1 is
7552 1.1 is # here, we build the result in a tmp location so as not to disturb the input
7553 1.1 is mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
7554 1.1 is mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
7555 1.1 is mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent
7556 1.1 is fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0
7557 1.1 is bmi.b sgetmann # it's negative
7558 1.1 is rts
7559 1.1 is
7560 1.1 is sgetmann:
7561 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
7562 1.1 is rts
7563 1.1 is
7564 1.1 is #
7565 1.1 is # For denormalized numbers, shift the mantissa until the j-bit = 1,
7566 1.1 is # then load the exponent with +/1 $3fff.
7567 1.1 is #
7568 1.1 is global sgetmand
7569 1.1 is sgetmand:
7570 1.1 is bsr.l norm # normalize exponent
7571 1.1 is bra.b sgetman
7572 1.1 is
7573 1.1 is #########################################################################
7574 1.1 is # scosh(): computes the hyperbolic cosine of a normalized input #
7575 1.1 is # scoshd(): computes the hyperbolic cosine of a denormalized input #
7576 1.1 is # #
7577 1.1 is # INPUT *************************************************************** #
7578 1.1 is # a0 = pointer to extended precision input #
7579 1.1 is # d0 = round precision,mode #
7580 1.1 is # #
7581 1.1 is # OUTPUT ************************************************************** #
7582 1.1 is # fp0 = cosh(X) #
7583 1.1 is # #
7584 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
7585 1.1 is # The returned result is within 3 ulps in 64 significant bit, #
7586 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
7587 1.1 is # rounded to double precision. The result is provably monotonic #
7588 1.1 is # in double precision. #
7589 1.1 is # #
7590 1.1 is # ALGORITHM *********************************************************** #
7591 1.1 is # #
7592 1.1 is # COSH #
7593 1.1 is # 1. If |X| > 16380 log2, go to 3. #
7594 1.1 is # #
7595 1.1 is # 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae #
7596 1.1 is # y = |X|, z = exp(Y), and #
7597 1.1 is # cosh(X) = (1/2)*( z + 1/z ). #
7598 1.1 is # Exit. #
7599 1.1 is # #
7600 1.1 is # 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. #
7601 1.1 is # #
7602 1.1 is # 4. (16380 log2 < |X| <= 16480 log2) #
7603 1.1 is # cosh(X) = sign(X) * exp(|X|)/2. #
7604 1.1 is # However, invoking exp(|X|) may cause premature #
7605 1.1 is # overflow. Thus, we calculate sinh(X) as follows: #
7606 1.1 is # Y := |X| #
7607 1.1 is # Fact := 2**(16380) #
7608 1.1 is # Y' := Y - 16381 log2 #
7609 1.1 is # cosh(X) := Fact * exp(Y'). #
7610 1.1 is # Exit. #
7611 1.1 is # #
7612 1.1 is # 5. (|X| > 16480 log2) sinh(X) must overflow. Return #
7613 1.1 is # Huge*Huge to generate overflow and an infinity with #
7614 1.1 is # the appropriate sign. Huge is the largest finite number #
7615 1.1 is # in extended format. Exit. #
7616 1.1 is # #
7617 1.1 is #########################################################################
7618 1.1 is
7619 1.1 is TWO16380:
7620 1.1 is long 0x7FFB0000,0x80000000,0x00000000,0x00000000
7621 1.1 is
7622 1.1 is global scosh
7623 1.1 is scosh:
7624 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
7625 1.1 is
7626 1.1 is mov.l (%a0),%d1
7627 1.1 is mov.w 4(%a0),%d1
7628 1.1 is and.l &0x7FFFFFFF,%d1
7629 1.1 is cmp.l %d1,&0x400CB167
7630 1.1 is bgt.b COSHBIG
7631 1.1 is
7632 1.1 is #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
7633 1.1 is #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
7634 1.1 is
7635 1.1 is fabs.x %fp0 # |X|
7636 1.1 is
7637 1.1 is mov.l %d0,-(%sp)
7638 1.1 is clr.l %d0
7639 1.1 is fmovm.x &0x01,-(%sp) # save |X| to stack
7640 1.1 is lea (%sp),%a0 # pass ptr to |X|
7641 1.1 is bsr setox # FP0 IS EXP(|X|)
7642 1.1 is add.l &0xc,%sp # erase |X| from stack
7643 1.1 is fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|)
7644 1.1 is mov.l (%sp)+,%d0
7645 1.1 is
7646 1.1 is fmov.s &0x3E800000,%fp1 # (1/4)
7647 1.1 is fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|))
7648 1.1 is
7649 1.1 is fmov.l %d0,%fpcr
7650 1.1 is mov.b &FADD_OP,%d1 # last inst is ADD
7651 1.1 is fadd.x %fp1,%fp0
7652 1.1 is bra t_catch
7653 1.1 is
7654 1.1 is COSHBIG:
7655 1.1 is cmp.l %d1,&0x400CB2B3
7656 1.1 is bgt.b COSHHUGE
7657 1.1 is
7658 1.1 is fabs.x %fp0
7659 1.1 is fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD)
7660 1.1 is fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE
7661 1.1 is
7662 1.1 is mov.l %d0,-(%sp)
7663 1.1 is clr.l %d0
7664 1.1 is fmovm.x &0x01,-(%sp) # save fp0 to stack
7665 1.1 is lea (%sp),%a0 # pass ptr to fp0
7666 1.1 is bsr setox
7667 1.1 is add.l &0xc,%sp # clear fp0 from stack
7668 1.1 is mov.l (%sp)+,%d0
7669 1.1 is
7670 1.1 is fmov.l %d0,%fpcr
7671 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
7672 1.1 is fmul.x TWO16380(%pc),%fp0
7673 1.1 is bra t_catch
7674 1.1 is
7675 1.1 is COSHHUGE:
7676 1.1 is bra t_ovfl2
7677 1.1 is
7678 1.1 is global scoshd
7679 1.1 is #--COSH(X) = 1 FOR DENORMALIZED X
7680 1.1 is scoshd:
7681 1.1 is fmov.s &0x3F800000,%fp0
7682 1.1 is
7683 1.1 is fmov.l %d0,%fpcr
7684 1.1 is fadd.s &0x00800000,%fp0
7685 1.1 is bra t_pinx2
7686 1.1 is
7687 1.1 is #########################################################################
7688 1.1 is # ssinh(): computes the hyperbolic sine of a normalized input #
7689 1.1 is # ssinhd(): computes the hyperbolic sine of a denormalized input #
7690 1.1 is # #
7691 1.1 is # INPUT *************************************************************** #
7692 1.1 is # a0 = pointer to extended precision input #
7693 1.1 is # d0 = round precision,mode #
7694 1.1 is # #
7695 1.1 is # OUTPUT ************************************************************** #
7696 1.1 is # fp0 = sinh(X) #
7697 1.1 is # #
7698 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
7699 1.1 is # The returned result is within 3 ulps in 64 significant bit, #
7700 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
7701 1.1 is # rounded to double precision. The result is provably monotonic #
7702 1.1 is # in double precision. #
7703 1.1 is # #
7704 1.1 is # ALGORITHM *********************************************************** #
7705 1.1 is # #
7706 1.1 is # SINH #
7707 1.1 is # 1. If |X| > 16380 log2, go to 3. #
7708 1.1 is # #
7709 1.1 is # 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula #
7710 1.1 is # y = |X|, sgn = sign(X), and z = expm1(Y), #
7711 1.1 is # sinh(X) = sgn*(1/2)*( z + z/(1+z) ). #
7712 1.1 is # Exit. #
7713 1.1 is # #
7714 1.1 is # 3. If |X| > 16480 log2, go to 5. #
7715 1.1 is # #
7716 1.1 is # 4. (16380 log2 < |X| <= 16480 log2) #
7717 1.1 is # sinh(X) = sign(X) * exp(|X|)/2. #
7718 1.1 is # However, invoking exp(|X|) may cause premature overflow. #
7719 1.1 is # Thus, we calculate sinh(X) as follows: #
7720 1.1 is # Y := |X| #
7721 1.1 is # sgn := sign(X) #
7722 1.1 is # sgnFact := sgn * 2**(16380) #
7723 1.1 is # Y' := Y - 16381 log2 #
7724 1.1 is # sinh(X) := sgnFact * exp(Y'). #
7725 1.1 is # Exit. #
7726 1.1 is # #
7727 1.1 is # 5. (|X| > 16480 log2) sinh(X) must overflow. Return #
7728 1.1 is # sign(X)*Huge*Huge to generate overflow and an infinity with #
7729 1.1 is # the appropriate sign. Huge is the largest finite number in #
7730 1.1 is # extended format. Exit. #
7731 1.1 is # #
7732 1.1 is #########################################################################
7733 1.1 is
7734 1.1 is global ssinh
7735 1.1 is ssinh:
7736 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
7737 1.1 is
7738 1.1 is mov.l (%a0),%d1
7739 1.1 is mov.w 4(%a0),%d1
7740 1.1 is mov.l %d1,%a1 # save (compacted) operand
7741 1.1 is and.l &0x7FFFFFFF,%d1
7742 1.1 is cmp.l %d1,&0x400CB167
7743 1.1 is bgt.b SINHBIG
7744 1.1 is
7745 1.1 is #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
7746 1.1 is #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
7747 1.1 is
7748 1.1 is fabs.x %fp0 # Y = |X|
7749 1.1 is
7750 1.1 is movm.l &0x8040,-(%sp) # {a1/d0}
7751 1.1 is fmovm.x &0x01,-(%sp) # save Y on stack
7752 1.1 is lea (%sp),%a0 # pass ptr to Y
7753 1.1 is clr.l %d0
7754 1.1 is bsr setoxm1 # FP0 IS Z = EXPM1(Y)
7755 1.1 is add.l &0xc,%sp # clear Y from stack
7756 1.1 is fmov.l &0,%fpcr
7757 1.1 is movm.l (%sp)+,&0x0201 # {a1/d0}
7758 1.1 is
7759 1.1 is fmov.x %fp0,%fp1
7760 1.1 is fadd.s &0x3F800000,%fp1 # 1+Z
7761 1.1 is fmov.x %fp0,-(%sp)
7762 1.1 is fdiv.x %fp1,%fp0 # Z/(1+Z)
7763 1.1 is mov.l %a1,%d1
7764 1.1 is and.l &0x80000000,%d1
7765 1.1 is or.l &0x3F000000,%d1
7766 1.1 is fadd.x (%sp)+,%fp0
7767 1.1 is mov.l %d1,-(%sp)
7768 1.1 is
7769 1.1 is fmov.l %d0,%fpcr
7770 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
7771 1.1 is fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set
7772 1.1 is bra t_catch
7773 1.1 is
7774 1.1 is SINHBIG:
7775 1.1 is cmp.l %d1,&0x400CB2B3
7776 1.1 is bgt t_ovfl
7777 1.1 is fabs.x %fp0
7778 1.1 is fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD)
7779 1.1 is mov.l &0,-(%sp)
7780 1.1 is mov.l &0x80000000,-(%sp)
7781 1.1 is mov.l %a1,%d1
7782 1.1 is and.l &0x80000000,%d1
7783 1.1 is or.l &0x7FFB0000,%d1
7784 1.1 is mov.l %d1,-(%sp) # EXTENDED FMT
7785 1.1 is fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE
7786 1.1 is
7787 1.1 is mov.l %d0,-(%sp)
7788 1.1 is clr.l %d0
7789 1.1 is fmovm.x &0x01,-(%sp) # save fp0 on stack
7790 1.1 is lea (%sp),%a0 # pass ptr to fp0
7791 1.1 is bsr setox
7792 1.1 is add.l &0xc,%sp # clear fp0 from stack
7793 1.1 is
7794 1.1 is mov.l (%sp)+,%d0
7795 1.1 is fmov.l %d0,%fpcr
7796 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
7797 1.1 is fmul.x (%sp)+,%fp0 # possible exception
7798 1.1 is bra t_catch
7799 1.1 is
7800 1.1 is global ssinhd
7801 1.1 is #--SINH(X) = X FOR DENORMALIZED X
7802 1.1 is ssinhd:
7803 1.1 is bra t_extdnrm
7804 1.1 is
7805 1.1 is #########################################################################
7806 1.1 is # stanh(): computes the hyperbolic tangent of a normalized input #
7807 1.1 is # stanhd(): computes the hyperbolic tangent of a denormalized input #
7808 1.1 is # #
7809 1.1 is # INPUT *************************************************************** #
7810 1.1 is # a0 = pointer to extended precision input #
7811 1.1 is # d0 = round precision,mode #
7812 1.1 is # #
7813 1.1 is # OUTPUT ************************************************************** #
7814 1.1 is # fp0 = tanh(X) #
7815 1.1 is # #
7816 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
7817 1.1 is # The returned result is within 3 ulps in 64 significant bit, #
7818 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
7819 1.1 is # rounded to double precision. The result is provably monotonic #
7820 1.1 is # in double precision. #
7821 1.1 is # #
7822 1.1 is # ALGORITHM *********************************************************** #
7823 1.1 is # #
7824 1.1 is # TANH #
7825 1.1 is # 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. #
7826 1.1 is # #
7827 1.1 is # 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by #
7828 1.1 is # sgn := sign(X), y := 2|X|, z := expm1(Y), and #
7829 1.1 is # tanh(X) = sgn*( z/(2+z) ). #
7830 1.1 is # Exit. #
7831 1.1 is # #
7832 1.1 is # 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, #
7833 1.1 is # go to 7. #
7834 1.1 is # #
7835 1.1 is # 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. #
7836 1.1 is # #
7837 1.1 is # 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by #
7838 1.1 is # sgn := sign(X), y := 2|X|, z := exp(Y), #
7839 1.1 is # tanh(X) = sgn - [ sgn*2/(1+z) ]. #
7840 1.1 is # Exit. #
7841 1.1 is # #
7842 1.1 is # 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we #
7843 1.1 is # calculate Tanh(X) by #
7844 1.1 is # sgn := sign(X), Tiny := 2**(-126), #
7845 1.1 is # tanh(X) := sgn - sgn*Tiny. #
7846 1.1 is # Exit. #
7847 1.1 is # #
7848 1.1 is # 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. #
7849 1.1 is # #
7850 1.1 is #########################################################################
7851 1.1 is
7852 1.1 is set X,FP_SCR0
7853 1.1 is set XFRAC,X+4
7854 1.1 is
7855 1.1 is set SGN,L_SCR3
7856 1.1 is
7857 1.1 is set V,FP_SCR0
7858 1.1 is
7859 1.1 is global stanh
7860 1.1 is stanh:
7861 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
7862 1.1 is
7863 1.1 is fmov.x %fp0,X(%a6)
7864 1.1 is mov.l (%a0),%d1
7865 1.1 is mov.w 4(%a0),%d1
7866 1.1 is mov.l %d1,X(%a6)
7867 1.1 is and.l &0x7FFFFFFF,%d1
7868 1.1 is cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)?
7869 1.1 is blt.w TANHBORS # yes
7870 1.1 is cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2?
7871 1.1 is bgt.w TANHBORS # yes
7872 1.1 is
7873 1.1 is #--THIS IS THE USUAL CASE
7874 1.1 is #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
7875 1.1 is
7876 1.1 is mov.l X(%a6),%d1
7877 1.1 is mov.l %d1,SGN(%a6)
7878 1.1 is and.l &0x7FFF0000,%d1
7879 1.1 is add.l &0x00010000,%d1 # EXPONENT OF 2|X|
7880 1.1 is mov.l %d1,X(%a6)
7881 1.1 is and.l &0x80000000,SGN(%a6)
7882 1.1 is fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X|
7883 1.1 is
7884 1.1 is mov.l %d0,-(%sp)
7885 1.1 is clr.l %d0
7886 1.1 is fmovm.x &0x1,-(%sp) # save Y on stack
7887 1.1 is lea (%sp),%a0 # pass ptr to Y
7888 1.1 is bsr setoxm1 # FP0 IS Z = EXPM1(Y)
7889 1.1 is add.l &0xc,%sp # clear Y from stack
7890 1.1 is mov.l (%sp)+,%d0
7891 1.1 is
7892 1.1 is fmov.x %fp0,%fp1
7893 1.1 is fadd.s &0x40000000,%fp1 # Z+2
7894 1.1 is mov.l SGN(%a6),%d1
7895 1.1 is fmov.x %fp1,V(%a6)
7896 1.1 is eor.l %d1,V(%a6)
7897 1.1 is
7898 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode
7899 1.1 is fdiv.x V(%a6),%fp0
7900 1.1 is bra t_inx2
7901 1.1 is
7902 1.1 is TANHBORS:
7903 1.1 is cmp.l %d1,&0x3FFF8000
7904 1.1 is blt.w TANHSM
7905 1.1 is
7906 1.1 is cmp.l %d1,&0x40048AA1
7907 1.1 is bgt.w TANHHUGE
7908 1.1 is
7909 1.1 is #-- (5/2) LOG2 < |X| < 50 LOG2,
7910 1.1 is #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
7911 1.1 is #--TANH(X) = SGN - SGN*2/[EXP(Y)+1].
7912 1.1 is
7913 1.1 is mov.l X(%a6),%d1
7914 1.1 is mov.l %d1,SGN(%a6)
7915 1.1 is and.l &0x7FFF0000,%d1
7916 1.1 is add.l &0x00010000,%d1 # EXPO OF 2|X|
7917 1.1 is mov.l %d1,X(%a6) # Y = 2|X|
7918 1.1 is and.l &0x80000000,SGN(%a6)
7919 1.1 is mov.l SGN(%a6),%d1
7920 1.1 is fmov.x X(%a6),%fp0 # Y = 2|X|
7921 1.1 is
7922 1.1 is mov.l %d0,-(%sp)
7923 1.1 is clr.l %d0
7924 1.1 is fmovm.x &0x01,-(%sp) # save Y on stack
7925 1.1 is lea (%sp),%a0 # pass ptr to Y
7926 1.1 is bsr setox # FP0 IS EXP(Y)
7927 1.1 is add.l &0xc,%sp # clear Y from stack
7928 1.1 is mov.l (%sp)+,%d0
7929 1.1 is mov.l SGN(%a6),%d1
7930 1.1 is fadd.s &0x3F800000,%fp0 # EXP(Y)+1
7931 1.1 is
7932 1.1 is eor.l &0xC0000000,%d1 # -SIGN(X)*2
7933 1.1 is fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT
7934 1.1 is fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ]
7935 1.1 is
7936 1.1 is mov.l SGN(%a6),%d1
7937 1.1 is or.l &0x3F800000,%d1 # SGN
7938 1.1 is fmov.s %d1,%fp0 # SGN IN SGL FMT
7939 1.1 is
7940 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode
7941 1.1 is mov.b &FADD_OP,%d1 # last inst is ADD
7942 1.1 is fadd.x %fp1,%fp0
7943 1.1 is bra t_inx2
7944 1.1 is
7945 1.1 is TANHSM:
7946 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode
7947 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
7948 1.1 is fmov.x X(%a6),%fp0 # last inst - possible exception set
7949 1.1 is bra t_catch
7950 1.1 is
7951 1.1 is #---RETURN SGN(X) - SGN(X)EPS
7952 1.1 is TANHHUGE:
7953 1.1 is mov.l X(%a6),%d1
7954 1.1 is and.l &0x80000000,%d1
7955 1.1 is or.l &0x3F800000,%d1
7956 1.1 is fmov.s %d1,%fp0
7957 1.1 is and.l &0x80000000,%d1
7958 1.1 is eor.l &0x80800000,%d1 # -SIGN(X)*EPS
7959 1.1 is
7960 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode
7961 1.1 is fadd.s %d1,%fp0
7962 1.1 is bra t_inx2
7963 1.1 is
7964 1.1 is global stanhd
7965 1.1 is #--TANH(X) = X FOR DENORMALIZED X
7966 1.1 is stanhd:
7967 1.1 is bra t_extdnrm
7968 1.1 is
7969 1.1 is #########################################################################
7970 1.1 is # slogn(): computes the natural logarithm of a normalized input #
7971 1.1 is # slognd(): computes the natural logarithm of a denormalized input #
7972 1.1 is # slognp1(): computes the log(1+X) of a normalized input #
7973 1.1 is # slognp1d(): computes the log(1+X) of a denormalized input #
7974 1.1 is # #
7975 1.1 is # INPUT *************************************************************** #
7976 1.1 is # a0 = pointer to extended precision input #
7977 1.1 is # d0 = round precision,mode #
7978 1.1 is # #
7979 1.1 is # OUTPUT ************************************************************** #
7980 1.1 is # fp0 = log(X) or log(1+X) #
7981 1.1 is # #
7982 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
7983 1.1 is # The returned result is within 2 ulps in 64 significant bit, #
7984 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
7985 1.1 is # rounded to double precision. The result is provably monotonic #
7986 1.1 is # in double precision. #
7987 1.1 is # #
7988 1.1 is # ALGORITHM *********************************************************** #
7989 1.1 is # LOGN: #
7990 1.1 is # Step 1. If |X-1| < 1/16, approximate log(X) by an odd #
7991 1.1 is # polynomial in u, where u = 2(X-1)/(X+1). Otherwise, #
7992 1.1 is # move on to Step 2. #
7993 1.1 is # #
7994 1.1 is # Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first #
7995 1.1 is # seven significant bits of Y plus 2**(-7), i.e. #
7996 1.1 is # F = 1.xxxxxx1 in base 2 where the six "x" match those #
7997 1.1 is # of Y. Note that |Y-F| <= 2**(-7). #
7998 1.1 is # #
7999 1.1 is # Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a #
8000 1.1 is # polynomial in u, log(1+u) = poly. #
8001 1.1 is # #
8002 1.1 is # Step 4. Reconstruct #
8003 1.1 is # log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) #
8004 1.1 is # by k*log(2) + (log(F) + poly). The values of log(F) are #
8005 1.1 is # calculated beforehand and stored in the program. #
8006 1.1 is # #
8007 1.1 is # lognp1: #
8008 1.1 is # Step 1: If |X| < 1/16, approximate log(1+X) by an odd #
8009 1.1 is # polynomial in u where u = 2X/(2+X). Otherwise, move on #
8010 1.1 is # to Step 2. #
8011 1.1 is # #
8012 1.1 is # Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done #
8013 1.1 is # in Step 2 of the algorithm for LOGN and compute #
8014 1.1 is # log(1+X) as k*log(2) + log(F) + poly where poly #
8015 1.1 is # approximates log(1+u), u = (Y-F)/F. #
8016 1.1 is # #
8017 1.1 is # Implementation Notes: #
8018 1.1 is # Note 1. There are 64 different possible values for F, thus 64 #
8019 1.1 is # log(F)'s need to be tabulated. Moreover, the values of #
8020 1.1 is # 1/F are also tabulated so that the division in (Y-F)/F #
8021 1.1 is # can be performed by a multiplication. #
8022 1.1 is # #
8023 1.1 is # Note 2. In Step 2 of lognp1, in order to preserved accuracy, #
8024 1.1 is # the value Y-F has to be calculated carefully when #
8025 1.1 is # 1/2 <= X < 3/2. #
8026 1.1 is # #
8027 1.1 is # Note 3. To fully exploit the pipeline, polynomials are usually #
8028 1.1 is # separated into two parts evaluated independently before #
8029 1.1 is # being added up. #
8030 1.1 is # #
8031 1.1 is #########################################################################
8032 1.1 is LOGOF2:
8033 1.1 is long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
8034 1.1 is
8035 1.1 is one:
8036 1.1 is long 0x3F800000
8037 1.1 is zero:
8038 1.1 is long 0x00000000
8039 1.1 is infty:
8040 1.1 is long 0x7F800000
8041 1.1 is negone:
8042 1.1 is long 0xBF800000
8043 1.1 is
8044 1.1 is LOGA6:
8045 1.1 is long 0x3FC2499A,0xB5E4040B
8046 1.1 is LOGA5:
8047 1.1 is long 0xBFC555B5,0x848CB7DB
8048 1.1 is
8049 1.1 is LOGA4:
8050 1.1 is long 0x3FC99999,0x987D8730
8051 1.1 is LOGA3:
8052 1.1 is long 0xBFCFFFFF,0xFF6F7E97
8053 1.1 is
8054 1.1 is LOGA2:
8055 1.1 is long 0x3FD55555,0x555555A4
8056 1.1 is LOGA1:
8057 1.1 is long 0xBFE00000,0x00000008
8058 1.1 is
8059 1.1 is LOGB5:
8060 1.1 is long 0x3F175496,0xADD7DAD6
8061 1.1 is LOGB4:
8062 1.1 is long 0x3F3C71C2,0xFE80C7E0
8063 1.1 is
8064 1.1 is LOGB3:
8065 1.1 is long 0x3F624924,0x928BCCFF
8066 1.1 is LOGB2:
8067 1.1 is long 0x3F899999,0x999995EC
8068 1.1 is
8069 1.1 is LOGB1:
8070 1.1 is long 0x3FB55555,0x55555555
8071 1.1 is TWO:
8072 1.1 is long 0x40000000,0x00000000
8073 1.1 is
8074 1.1 is LTHOLD:
8075 1.1 is long 0x3f990000,0x80000000,0x00000000,0x00000000
8076 1.1 is
8077 1.1 is LOGTBL:
8078 1.1 is long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
8079 1.1 is long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000
8080 1.1 is long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
8081 1.1 is long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
8082 1.1 is long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
8083 1.1 is long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
8084 1.1 is long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
8085 1.1 is long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
8086 1.1 is long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
8087 1.1 is long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
8088 1.1 is long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
8089 1.1 is long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
8090 1.1 is long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
8091 1.1 is long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
8092 1.1 is long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
8093 1.1 is long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
8094 1.1 is long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
8095 1.1 is long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
8096 1.1 is long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
8097 1.1 is long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
8098 1.1 is long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
8099 1.1 is long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
8100 1.1 is long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
8101 1.1 is long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
8102 1.1 is long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
8103 1.1 is long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
8104 1.1 is long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
8105 1.1 is long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
8106 1.1 is long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
8107 1.1 is long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
8108 1.1 is long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
8109 1.1 is long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
8110 1.1 is long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
8111 1.1 is long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
8112 1.1 is long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
8113 1.1 is long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
8114 1.1 is long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
8115 1.1 is long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
8116 1.1 is long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
8117 1.1 is long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
8118 1.1 is long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
8119 1.1 is long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
8120 1.1 is long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
8121 1.1 is long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
8122 1.1 is long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
8123 1.1 is long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
8124 1.1 is long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
8125 1.1 is long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
8126 1.1 is long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
8127 1.1 is long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
8128 1.1 is long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
8129 1.1 is long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
8130 1.1 is long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
8131 1.1 is long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
8132 1.1 is long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
8133 1.1 is long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
8134 1.1 is long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
8135 1.1 is long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
8136 1.1 is long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
8137 1.1 is long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
8138 1.1 is long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
8139 1.1 is long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
8140 1.1 is long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
8141 1.1 is long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
8142 1.1 is long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
8143 1.1 is long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
8144 1.1 is long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
8145 1.1 is long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
8146 1.1 is long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
8147 1.1 is long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
8148 1.1 is long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
8149 1.1 is long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
8150 1.1 is long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
8151 1.1 is long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
8152 1.1 is long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
8153 1.1 is long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
8154 1.1 is long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
8155 1.1 is long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
8156 1.1 is long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
8157 1.1 is long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
8158 1.1 is long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
8159 1.1 is long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
8160 1.1 is long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
8161 1.1 is long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
8162 1.1 is long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
8163 1.1 is long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000
8164 1.1 is long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000
8165 1.1 is long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
8166 1.1 is long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
8167 1.1 is long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
8168 1.1 is long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000
8169 1.1 is long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
8170 1.1 is long 0x3FFE0000,0x94458094,0x45809446,0x00000000
8171 1.1 is long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
8172 1.1 is long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000
8173 1.1 is long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
8174 1.1 is long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
8175 1.1 is long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
8176 1.1 is long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
8177 1.1 is long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
8178 1.1 is long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
8179 1.1 is long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
8180 1.1 is long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
8181 1.1 is long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
8182 1.1 is long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
8183 1.1 is long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
8184 1.1 is long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
8185 1.1 is long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
8186 1.1 is long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
8187 1.1 is long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
8188 1.1 is long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
8189 1.1 is long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
8190 1.1 is long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
8191 1.1 is long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
8192 1.1 is long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
8193 1.1 is long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
8194 1.1 is long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
8195 1.1 is long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
8196 1.1 is long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
8197 1.1 is long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
8198 1.1 is long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
8199 1.1 is long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
8200 1.1 is long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
8201 1.1 is long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
8202 1.1 is long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
8203 1.1 is long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
8204 1.1 is long 0x3FFE0000,0x80808080,0x80808081,0x00000000
8205 1.1 is long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
8206 1.1 is
8207 1.1 is set ADJK,L_SCR1
8208 1.1 is
8209 1.1 is set X,FP_SCR0
8210 1.1 is set XDCARE,X+2
8211 1.1 is set XFRAC,X+4
8212 1.1 is
8213 1.1 is set F,FP_SCR1
8214 1.1 is set FFRAC,F+4
8215 1.1 is
8216 1.1 is set KLOG2,FP_SCR0
8217 1.1 is
8218 1.1 is set SAVEU,FP_SCR0
8219 1.1 is
8220 1.1 is global slogn
8221 1.1 is #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
8222 1.1 is slogn:
8223 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
8224 1.1 is mov.l &0x00000000,ADJK(%a6)
8225 1.1 is
8226 1.1 is LOGBGN:
8227 1.1 is #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
8228 1.1 is #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
8229 1.1 is
8230 1.1 is mov.l (%a0),%d1
8231 1.1 is mov.w 4(%a0),%d1
8232 1.1 is
8233 1.1 is mov.l (%a0),X(%a6)
8234 1.1 is mov.l 4(%a0),X+4(%a6)
8235 1.1 is mov.l 8(%a0),X+8(%a6)
8236 1.1 is
8237 1.1 is cmp.l %d1,&0 # CHECK IF X IS NEGATIVE
8238 1.1 is blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID
8239 1.1 is # X IS POSITIVE, CHECK IF X IS NEAR 1
8240 1.1 is cmp.l %d1,&0x3ffef07d # IS X < 15/16?
8241 1.1 is blt.b LOGMAIN # YES
8242 1.1 is cmp.l %d1,&0x3fff8841 # IS X > 17/16?
8243 1.1 is ble.w LOGNEAR1 # NO
8244 1.1 is
8245 1.1 is LOGMAIN:
8246 1.1 is #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
8247 1.1 is
8248 1.1 is #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
8249 1.1 is #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
8250 1.1 is #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
8251 1.1 is #-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
8252 1.1 is #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
8253 1.1 is #--LOG(1+U) CAN BE VERY EFFICIENT.
8254 1.1 is #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
8255 1.1 is #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
8256 1.1 is
8257 1.1 is #--GET K, Y, F, AND ADDRESS OF 1/F.
8258 1.1 is asr.l &8,%d1
8259 1.1 is asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X
8260 1.1 is sub.l &0x3FFF,%d1 # THIS IS K
8261 1.1 is add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM.
8262 1.1 is lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F)
8263 1.1 is fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT
8264 1.1 is
8265 1.1 is #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
8266 1.1 is mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X
8267 1.1 is mov.l XFRAC(%a6),FFRAC(%a6)
8268 1.1 is and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y
8269 1.1 is or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT
8270 1.1 is mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F
8271 1.1 is and.l &0x7E000000,%d1
8272 1.1 is asr.l &8,%d1
8273 1.1 is asr.l &8,%d1
8274 1.1 is asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT
8275 1.1 is add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F
8276 1.1 is
8277 1.1 is fmov.x X(%a6),%fp0
8278 1.1 is mov.l &0x3fff0000,F(%a6)
8279 1.1 is clr.l F+8(%a6)
8280 1.1 is fsub.x F(%a6),%fp0 # Y-F
8281 1.1 is fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY
8282 1.1 is #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
8283 1.1 is #--REGISTERS SAVED: FPCR, FP1, FP2
8284 1.1 is
8285 1.1 is LP1CONT1:
8286 1.1 is #--AN RE-ENTRY POINT FOR LOGNP1
8287 1.1 is fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F
8288 1.1 is fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY
8289 1.1 is fmov.x %fp0,%fp2
8290 1.1 is fmul.x %fp2,%fp2 # FP2 IS V=U*U
8291 1.1 is fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMEORY, FREE FP1
8292 1.1 is
8293 1.1 is #--LOG(1+U) IS APPROXIMATED BY
8294 1.1 is #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
8295 1.1 is #--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))]
8296 1.1 is
8297 1.1 is fmov.x %fp2,%fp3
8298 1.1 is fmov.x %fp2,%fp1
8299 1.1 is
8300 1.1 is fmul.d LOGA6(%pc),%fp1 # V*A6
8301 1.1 is fmul.d LOGA5(%pc),%fp2 # V*A5
8302 1.1 is
8303 1.1 is fadd.d LOGA4(%pc),%fp1 # A4+V*A6
8304 1.1 is fadd.d LOGA3(%pc),%fp2 # A3+V*A5
8305 1.1 is
8306 1.1 is fmul.x %fp3,%fp1 # V*(A4+V*A6)
8307 1.1 is fmul.x %fp3,%fp2 # V*(A3+V*A5)
8308 1.1 is
8309 1.1 is fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6)
8310 1.1 is fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5)
8311 1.1 is
8312 1.1 is fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6))
8313 1.1 is add.l &16,%a0 # ADDRESS OF LOG(F)
8314 1.1 is fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5))
8315 1.1 is
8316 1.1 is fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6))
8317 1.1 is fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5))
8318 1.1 is
8319 1.1 is fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6))
8320 1.1 is fmovm.x (%sp)+,&0x30 # RESTORE FP2-3
8321 1.1 is fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U)
8322 1.1 is
8323 1.1 is fmov.l %d0,%fpcr
8324 1.1 is fadd.x KLOG2(%a6),%fp0 # FINAL ADD
8325 1.1 is bra t_inx2
8326 1.1 is
8327 1.1 is
8328 1.1 is LOGNEAR1:
8329 1.1 is
8330 1.1 is # if the input is exactly equal to one, then exit through ld_pzero.
8331 1.1 is # if these 2 lines weren't here, the correct answer would be returned
8332 1.1 is # but the INEX2 bit would be set.
8333 1.1 is fcmp.b %fp0,&0x1 # is it equal to one?
8334 1.1 is fbeq.l ld_pzero # yes
8335 1.1 is
8336 1.1 is #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
8337 1.1 is fmov.x %fp0,%fp1
8338 1.1 is fsub.s one(%pc),%fp1 # FP1 IS X-1
8339 1.1 is fadd.s one(%pc),%fp0 # FP0 IS X+1
8340 1.1 is fadd.x %fp1,%fp1 # FP1 IS 2(X-1)
8341 1.1 is #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
8342 1.1 is #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
8343 1.1 is
8344 1.1 is LP1CONT2:
8345 1.1 is #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
8346 1.1 is fdiv.x %fp0,%fp1 # FP1 IS U
8347 1.1 is fmovm.x &0xc,-(%sp) # SAVE FP2-3
8348 1.1 is #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
8349 1.1 is #--LET V=U*U, W=V*V, CALCULATE
8350 1.1 is #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
8351 1.1 is #--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] )
8352 1.1 is fmov.x %fp1,%fp0
8353 1.1 is fmul.x %fp0,%fp0 # FP0 IS V
8354 1.1 is fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1
8355 1.1 is fmov.x %fp0,%fp1
8356 1.1 is fmul.x %fp1,%fp1 # FP1 IS W
8357 1.1 is
8358 1.1 is fmov.d LOGB5(%pc),%fp3
8359 1.1 is fmov.d LOGB4(%pc),%fp2
8360 1.1 is
8361 1.1 is fmul.x %fp1,%fp3 # W*B5
8362 1.1 is fmul.x %fp1,%fp2 # W*B4
8363 1.1 is
8364 1.1 is fadd.d LOGB3(%pc),%fp3 # B3+W*B5
8365 1.1 is fadd.d LOGB2(%pc),%fp2 # B2+W*B4
8366 1.1 is
8367 1.1 is fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED
8368 1.1 is
8369 1.1 is fmul.x %fp0,%fp2 # V*(B2+W*B4)
8370 1.1 is
8371 1.1 is fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5)
8372 1.1 is fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V
8373 1.1 is
8374 1.1 is fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
8375 1.1 is fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED
8376 1.1 is
8377 1.1 is fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
8378 1.1 is
8379 1.1 is fmov.l %d0,%fpcr
8380 1.1 is fadd.x SAVEU(%a6),%fp0
8381 1.1 is bra t_inx2
8382 1.1 is
8383 1.1 is #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
8384 1.1 is LOGNEG:
8385 1.1 is bra t_operr
8386 1.1 is
8387 1.1 is global slognd
8388 1.1 is slognd:
8389 1.1 is #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
8390 1.1 is
8391 1.1 is mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0
8392 1.1 is
8393 1.1 is #----normalize the input value by left shifting k bits (k to be determined
8394 1.1 is #----below), adjusting exponent and storing -k to ADJK
8395 1.1 is #----the value TWOTO100 is no longer needed.
8396 1.1 is #----Note that this code assumes the denormalized input is NON-ZERO.
8397 1.1 is
8398 1.1 is movm.l &0x3f00,-(%sp) # save some registers {d2-d7}
8399 1.1 is mov.l (%a0),%d3 # D3 is exponent of smallest norm. #
8400 1.1 is mov.l 4(%a0),%d4
8401 1.1 is mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X)
8402 1.1 is clr.l %d2 # D2 used for holding K
8403 1.1 is
8404 1.1 is tst.l %d4
8405 1.1 is bne.b Hi_not0
8406 1.1 is
8407 1.1 is Hi_0:
8408 1.1 is mov.l %d5,%d4
8409 1.1 is clr.l %d5
8410 1.1 is mov.l &32,%d2
8411 1.1 is clr.l %d6
8412 1.1 is bfffo %d4{&0:&32},%d6
8413 1.1 is lsl.l %d6,%d4
8414 1.1 is add.l %d6,%d2 # (D3,D4,D5) is normalized
8415 1.1 is
8416 1.1 is mov.l %d3,X(%a6)
8417 1.1 is mov.l %d4,XFRAC(%a6)
8418 1.1 is mov.l %d5,XFRAC+4(%a6)
8419 1.1 is neg.l %d2
8420 1.1 is mov.l %d2,ADJK(%a6)
8421 1.1 is fmov.x X(%a6),%fp0
8422 1.1 is movm.l (%sp)+,&0xfc # restore registers {d2-d7}
8423 1.1 is lea X(%a6),%a0
8424 1.1 is bra.w LOGBGN # begin regular log(X)
8425 1.1 is
8426 1.1 is Hi_not0:
8427 1.1 is clr.l %d6
8428 1.1 is bfffo %d4{&0:&32},%d6 # find first 1
8429 1.1 is mov.l %d6,%d2 # get k
8430 1.1 is lsl.l %d6,%d4
8431 1.1 is mov.l %d5,%d7 # a copy of D5
8432 1.1 is lsl.l %d6,%d5
8433 1.1 is neg.l %d6
8434 1.1 is add.l &32,%d6
8435 1.1 is lsr.l %d6,%d7
8436 1.1 is or.l %d7,%d4 # (D3,D4,D5) normalized
8437 1.1 is
8438 1.1 is mov.l %d3,X(%a6)
8439 1.1 is mov.l %d4,XFRAC(%a6)
8440 1.1 is mov.l %d5,XFRAC+4(%a6)
8441 1.1 is neg.l %d2
8442 1.1 is mov.l %d2,ADJK(%a6)
8443 1.1 is fmov.x X(%a6),%fp0
8444 1.1 is movm.l (%sp)+,&0xfc # restore registers {d2-d7}
8445 1.1 is lea X(%a6),%a0
8446 1.1 is bra.w LOGBGN # begin regular log(X)
8447 1.1 is
8448 1.1 is global slognp1
8449 1.1 is #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
8450 1.1 is slognp1:
8451 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
8452 1.1 is fabs.x %fp0 # test magnitude
8453 1.1 is fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold
8454 1.1 is fbgt.w LP1REAL # if greater, continue
8455 1.1 is fmov.l %d0,%fpcr
8456 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
8457 1.1 is fmov.x (%a0),%fp0 # return signed argument
8458 1.1 is bra t_catch
8459 1.1 is
8460 1.1 is LP1REAL:
8461 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT
8462 1.1 is mov.l &0x00000000,ADJK(%a6)
8463 1.1 is fmov.x %fp0,%fp1 # FP1 IS INPUT Z
8464 1.1 is fadd.s one(%pc),%fp0 # X := ROUND(1+Z)
8465 1.1 is fmov.x %fp0,X(%a6)
8466 1.1 is mov.w XFRAC(%a6),XDCARE(%a6)
8467 1.1 is mov.l X(%a6),%d1
8468 1.1 is cmp.l %d1,&0
8469 1.1 is ble.w LP1NEG0 # LOG OF ZERO OR -VE
8470 1.1 is cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]?
8471 1.1 is blt.w LOGMAIN
8472 1.1 is cmp.l %d1,&0x3fffc000
8473 1.1 is bgt.w LOGMAIN
8474 1.1 is #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
8475 1.1 is #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
8476 1.1 is #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
8477 1.1 is
8478 1.1 is LP1NEAR1:
8479 1.1 is #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
8480 1.1 is cmp.l %d1,&0x3ffef07d
8481 1.1 is blt.w LP1CARE
8482 1.1 is cmp.l %d1,&0x3fff8841
8483 1.1 is bgt.w LP1CARE
8484 1.1 is
8485 1.1 is LP1ONE16:
8486 1.1 is #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
8487 1.1 is #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
8488 1.1 is fadd.x %fp1,%fp1 # FP1 IS 2Z
8489 1.1 is fadd.s one(%pc),%fp0 # FP0 IS 1+X
8490 1.1 is #--U = FP1/FP0
8491 1.1 is bra.w LP1CONT2
8492 1.1 is
8493 1.1 is LP1CARE:
8494 1.1 is #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
8495 1.1 is #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
8496 1.1 is #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
8497 1.1 is #--THERE ARE ONLY TWO CASES.
8498 1.1 is #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
8499 1.1 is #--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z
8500 1.1 is #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
8501 1.1 is #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
8502 1.1 is
8503 1.1 is mov.l XFRAC(%a6),FFRAC(%a6)
8504 1.1 is and.l &0xFE000000,FFRAC(%a6)
8505 1.1 is or.l &0x01000000,FFRAC(%a6) # F OBTAINED
8506 1.1 is cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1
8507 1.1 is bge.b KISZERO
8508 1.1 is
8509 1.1 is KISNEG1:
8510 1.1 is fmov.s TWO(%pc),%fp0
8511 1.1 is mov.l &0x3fff0000,F(%a6)
8512 1.1 is clr.l F+8(%a6)
8513 1.1 is fsub.x F(%a6),%fp0 # 2-F
8514 1.1 is mov.l FFRAC(%a6),%d1
8515 1.1 is and.l &0x7E000000,%d1
8516 1.1 is asr.l &8,%d1
8517 1.1 is asr.l &8,%d1
8518 1.1 is asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F
8519 1.1 is fadd.x %fp1,%fp1 # GET 2Z
8520 1.1 is fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3}
8521 1.1 is fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z
8522 1.1 is lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F
8523 1.1 is add.l %d1,%a0
8524 1.1 is fmov.s negone(%pc),%fp1 # FP1 IS K = -1
8525 1.1 is bra.w LP1CONT1
8526 1.1 is
8527 1.1 is KISZERO:
8528 1.1 is fmov.s one(%pc),%fp0
8529 1.1 is mov.l &0x3fff0000,F(%a6)
8530 1.1 is clr.l F+8(%a6)
8531 1.1 is fsub.x F(%a6),%fp0 # 1-F
8532 1.1 is mov.l FFRAC(%a6),%d1
8533 1.1 is and.l &0x7E000000,%d1
8534 1.1 is asr.l &8,%d1
8535 1.1 is asr.l &8,%d1
8536 1.1 is asr.l &4,%d1
8537 1.1 is fadd.x %fp1,%fp0 # FP0 IS Y-F
8538 1.1 is fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3}
8539 1.1 is lea LOGTBL(%pc),%a0
8540 1.1 is add.l %d1,%a0 # A0 IS ADDRESS OF 1/F
8541 1.1 is fmov.s zero(%pc),%fp1 # FP1 IS K = 0
8542 1.1 is bra.w LP1CONT1
8543 1.1 is
8544 1.1 is LP1NEG0:
8545 1.1 is #--FPCR SAVED. D0 IS X IN COMPACT FORM.
8546 1.1 is cmp.l %d1,&0
8547 1.1 is blt.b LP1NEG
8548 1.1 is LP1ZERO:
8549 1.1 is fmov.s negone(%pc),%fp0
8550 1.1 is
8551 1.1 is fmov.l %d0,%fpcr
8552 1.1 is bra t_dz
8553 1.1 is
8554 1.1 is LP1NEG:
8555 1.1 is fmov.s zero(%pc),%fp0
8556 1.1 is
8557 1.1 is fmov.l %d0,%fpcr
8558 1.1 is bra t_operr
8559 1.1 is
8560 1.1 is global slognp1d
8561 1.1 is #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
8562 1.1 is # Simply return the denorm
8563 1.1 is slognp1d:
8564 1.1 is bra t_extdnrm
8565 1.1 is
8566 1.1 is #########################################################################
8567 1.1 is # satanh(): computes the inverse hyperbolic tangent of a norm input #
8568 1.1 is # satanhd(): computes the inverse hyperbolic tangent of a denorm input #
8569 1.1 is # #
8570 1.1 is # INPUT *************************************************************** #
8571 1.1 is # a0 = pointer to extended precision input #
8572 1.1 is # d0 = round precision,mode #
8573 1.1 is # #
8574 1.1 is # OUTPUT ************************************************************** #
8575 1.1 is # fp0 = arctanh(X) #
8576 1.1 is # #
8577 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
8578 1.1 is # The returned result is within 3 ulps in 64 significant bit, #
8579 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
8580 1.1 is # rounded to double precision. The result is provably monotonic #
8581 1.1 is # in double precision. #
8582 1.1 is # #
8583 1.1 is # ALGORITHM *********************************************************** #
8584 1.1 is # #
8585 1.1 is # ATANH #
8586 1.1 is # 1. If |X| >= 1, go to 3. #
8587 1.1 is # #
8588 1.1 is # 2. (|X| < 1) Calculate atanh(X) by #
8589 1.1 is # sgn := sign(X) #
8590 1.1 is # y := |X| #
8591 1.1 is # z := 2y/(1-y) #
8592 1.1 is # atanh(X) := sgn * (1/2) * logp1(z) #
8593 1.1 is # Exit. #
8594 1.1 is # #
8595 1.1 is # 3. If |X| > 1, go to 5. #
8596 1.1 is # #
8597 1.1 is # 4. (|X| = 1) Generate infinity with an appropriate sign and #
8598 1.1 is # divide-by-zero by #
8599 1.1 is # sgn := sign(X) #
8600 1.1 is # atan(X) := sgn / (+0). #
8601 1.1 is # Exit. #
8602 1.1 is # #
8603 1.1 is # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
8604 1.1 is # Exit. #
8605 1.1 is # #
8606 1.1 is #########################################################################
8607 1.1 is
8608 1.1 is global satanh
8609 1.1 is satanh:
8610 1.1 is mov.l (%a0),%d1
8611 1.1 is mov.w 4(%a0),%d1
8612 1.1 is and.l &0x7FFFFFFF,%d1
8613 1.1 is cmp.l %d1,&0x3FFF8000
8614 1.1 is bge.b ATANHBIG
8615 1.1 is
8616 1.1 is #--THIS IS THE USUAL CASE, |X| < 1
8617 1.1 is #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
8618 1.1 is
8619 1.1 is fabs.x (%a0),%fp0 # Y = |X|
8620 1.1 is fmov.x %fp0,%fp1
8621 1.1 is fneg.x %fp1 # -Y
8622 1.1 is fadd.x %fp0,%fp0 # 2Y
8623 1.1 is fadd.s &0x3F800000,%fp1 # 1-Y
8624 1.1 is fdiv.x %fp1,%fp0 # 2Y/(1-Y)
8625 1.1 is mov.l (%a0),%d1
8626 1.1 is and.l &0x80000000,%d1
8627 1.1 is or.l &0x3F000000,%d1 # SIGN(X)*HALF
8628 1.1 is mov.l %d1,-(%sp)
8629 1.1 is
8630 1.1 is mov.l %d0,-(%sp) # save rnd prec,mode
8631 1.1 is clr.l %d0 # pass ext prec,RN
8632 1.1 is fmovm.x &0x01,-(%sp) # save Z on stack
8633 1.1 is lea (%sp),%a0 # pass ptr to Z
8634 1.1 is bsr slognp1 # LOG1P(Z)
8635 1.1 is add.l &0xc,%sp # clear Z from stack
8636 1.1 is
8637 1.1 is mov.l (%sp)+,%d0 # fetch old prec,mode
8638 1.1 is fmov.l %d0,%fpcr # load it
8639 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
8640 1.1 is fmul.s (%sp)+,%fp0
8641 1.1 is bra t_catch
8642 1.1 is
8643 1.1 is ATANHBIG:
8644 1.1 is fabs.x (%a0),%fp0 # |X|
8645 1.1 is fcmp.s %fp0,&0x3F800000
8646 1.1 is fbgt t_operr
8647 1.1 is bra t_dz
8648 1.1 is
8649 1.1 is global satanhd
8650 1.1 is #--ATANH(X) = X FOR DENORMALIZED X
8651 1.1 is satanhd:
8652 1.1 is bra t_extdnrm
8653 1.1 is
8654 1.1 is #########################################################################
8655 1.1 is # slog10(): computes the base-10 logarithm of a normalized input #
8656 1.1 is # slog10d(): computes the base-10 logarithm of a denormalized input #
8657 1.1 is # slog2(): computes the base-2 logarithm of a normalized input #
8658 1.1 is # slog2d(): computes the base-2 logarithm of a denormalized input #
8659 1.1 is # #
8660 1.1 is # INPUT *************************************************************** #
8661 1.1 is # a0 = pointer to extended precision input #
8662 1.1 is # d0 = round precision,mode #
8663 1.1 is # #
8664 1.1 is # OUTPUT ************************************************************** #
8665 1.1 is # fp0 = log_10(X) or log_2(X) #
8666 1.1 is # #
8667 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
8668 1.1 is # The returned result is within 1.7 ulps in 64 significant bit, #
8669 1.1 is # i.e. within 0.5003 ulp to 53 bits if the result is subsequently #
8670 1.1 is # rounded to double precision. The result is provably monotonic #
8671 1.1 is # in double precision. #
8672 1.1 is # #
8673 1.1 is # ALGORITHM *********************************************************** #
8674 1.1 is # #
8675 1.1 is # slog10d: #
8676 1.1 is # #
8677 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation #
8678 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. #
8679 1.1 is # Notes: Default means round-to-nearest mode, no floating-point #
8680 1.1 is # traps, and precision control = double extended. #
8681 1.1 is # #
8682 1.1 is # Step 1. Call slognd to obtain Y = log(X), the natural log of X. #
8683 1.1 is # Notes: Even if X is denormalized, log(X) is always normalized. #
8684 1.1 is # #
8685 1.1 is # Step 2. Compute log_10(X) = log(X) * (1/log(10)). #
8686 1.1 is # 2.1 Restore the user FPCR #
8687 1.1 is # 2.2 Return ans := Y * INV_L10. #
8688 1.1 is # #
8689 1.1 is # slog10: #
8690 1.1 is # #
8691 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation #
8692 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. #
8693 1.1 is # Notes: Default means round-to-nearest mode, no floating-point #
8694 1.1 is # traps, and precision control = double extended. #
8695 1.1 is # #
8696 1.1 is # Step 1. Call sLogN to obtain Y = log(X), the natural log of X. #
8697 1.1 is # #
8698 1.1 is # Step 2. Compute log_10(X) = log(X) * (1/log(10)). #
8699 1.1 is # 2.1 Restore the user FPCR #
8700 1.1 is # 2.2 Return ans := Y * INV_L10. #
8701 1.1 is # #
8702 1.1 is # sLog2d: #
8703 1.1 is # #
8704 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation #
8705 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. #
8706 1.1 is # Notes: Default means round-to-nearest mode, no floating-point #
8707 1.1 is # traps, and precision control = double extended. #
8708 1.1 is # #
8709 1.1 is # Step 1. Call slognd to obtain Y = log(X), the natural log of X. #
8710 1.1 is # Notes: Even if X is denormalized, log(X) is always normalized. #
8711 1.1 is # #
8712 1.1 is # Step 2. Compute log_10(X) = log(X) * (1/log(2)). #
8713 1.1 is # 2.1 Restore the user FPCR #
8714 1.1 is # 2.2 Return ans := Y * INV_L2. #
8715 1.1 is # #
8716 1.1 is # sLog2: #
8717 1.1 is # #
8718 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation #
8719 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. #
8720 1.1 is # Notes: Default means round-to-nearest mode, no floating-point #
8721 1.1 is # traps, and precision control = double extended. #
8722 1.1 is # #
8723 1.1 is # Step 1. If X is not an integer power of two, i.e., X != 2^k, #
8724 1.1 is # go to Step 3. #
8725 1.1 is # #
8726 1.1 is # Step 2. Return k. #
8727 1.1 is # 2.1 Get integer k, X = 2^k. #
8728 1.1 is # 2.2 Restore the user FPCR. #
8729 1.1 is # 2.3 Return ans := convert-to-double-extended(k). #
8730 1.1 is # #
8731 1.1 is # Step 3. Call sLogN to obtain Y = log(X), the natural log of X. #
8732 1.1 is # #
8733 1.1 is # Step 4. Compute log_2(X) = log(X) * (1/log(2)). #
8734 1.1 is # 4.1 Restore the user FPCR #
8735 1.1 is # 4.2 Return ans := Y * INV_L2. #
8736 1.1 is # #
8737 1.1 is #########################################################################
8738 1.1 is
8739 1.1 is INV_L10:
8740 1.1 is long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
8741 1.1 is
8742 1.1 is INV_L2:
8743 1.1 is long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
8744 1.1 is
8745 1.1 is global slog10
8746 1.1 is #--entry point for Log10(X), X is normalized
8747 1.1 is slog10:
8748 1.1 is fmov.b &0x1,%fp0
8749 1.1 is fcmp.x %fp0,(%a0) # if operand == 1,
8750 1.1 is fbeq.l ld_pzero # return an EXACT zero
8751 1.1 is
8752 1.1 is mov.l (%a0),%d1
8753 1.1 is blt.w invalid
8754 1.1 is mov.l %d0,-(%sp)
8755 1.1 is clr.l %d0
8756 1.1 is bsr slogn # log(X), X normal.
8757 1.1 is fmov.l (%sp)+,%fpcr
8758 1.1 is fmul.x INV_L10(%pc),%fp0
8759 1.1 is bra t_inx2
8760 1.1 is
8761 1.1 is global slog10d
8762 1.1 is #--entry point for Log10(X), X is denormalized
8763 1.1 is slog10d:
8764 1.1 is mov.l (%a0),%d1
8765 1.1 is blt.w invalid
8766 1.1 is mov.l %d0,-(%sp)
8767 1.1 is clr.l %d0
8768 1.1 is bsr slognd # log(X), X denorm.
8769 1.1 is fmov.l (%sp)+,%fpcr
8770 1.1 is fmul.x INV_L10(%pc),%fp0
8771 1.1 is bra t_minx2
8772 1.1 is
8773 1.1 is global slog2
8774 1.1 is #--entry point for Log2(X), X is normalized
8775 1.1 is slog2:
8776 1.1 is mov.l (%a0),%d1
8777 1.1 is blt.w invalid
8778 1.1 is
8779 1.1 is mov.l 8(%a0),%d1
8780 1.1 is bne.b continue # X is not 2^k
8781 1.1 is
8782 1.1 is mov.l 4(%a0),%d1
8783 1.1 is and.l &0x7FFFFFFF,%d1
8784 1.1 is bne.b continue
8785 1.1 is
8786 1.1 is #--X = 2^k.
8787 1.1 is mov.w (%a0),%d1
8788 1.1 is and.l &0x00007FFF,%d1
8789 1.1 is sub.l &0x3FFF,%d1
8790 1.1 is beq.l ld_pzero
8791 1.1 is fmov.l %d0,%fpcr
8792 1.1 is fmov.l %d1,%fp0
8793 1.1 is bra t_inx2
8794 1.1 is
8795 1.1 is continue:
8796 1.1 is mov.l %d0,-(%sp)
8797 1.1 is clr.l %d0
8798 1.1 is bsr slogn # log(X), X normal.
8799 1.1 is fmov.l (%sp)+,%fpcr
8800 1.1 is fmul.x INV_L2(%pc),%fp0
8801 1.1 is bra t_inx2
8802 1.1 is
8803 1.1 is invalid:
8804 1.1 is bra t_operr
8805 1.1 is
8806 1.1 is global slog2d
8807 1.1 is #--entry point for Log2(X), X is denormalized
8808 1.1 is slog2d:
8809 1.1 is mov.l (%a0),%d1
8810 1.1 is blt.w invalid
8811 1.1 is mov.l %d0,-(%sp)
8812 1.1 is clr.l %d0
8813 1.1 is bsr slognd # log(X), X denorm.
8814 1.1 is fmov.l (%sp)+,%fpcr
8815 1.1 is fmul.x INV_L2(%pc),%fp0
8816 1.1 is bra t_minx2
8817 1.1 is
8818 1.1 is #########################################################################
8819 1.1 is # stwotox(): computes 2**X for a normalized input #
8820 1.1 is # stwotoxd(): computes 2**X for a denormalized input #
8821 1.1 is # stentox(): computes 10**X for a normalized input #
8822 1.1 is # stentoxd(): computes 10**X for a denormalized input #
8823 1.1 is # #
8824 1.1 is # INPUT *************************************************************** #
8825 1.1 is # a0 = pointer to extended precision input #
8826 1.1 is # d0 = round precision,mode #
8827 1.1 is # #
8828 1.1 is # OUTPUT ************************************************************** #
8829 1.1 is # fp0 = 2**X or 10**X #
8830 1.1 is # #
8831 1.1 is # ACCURACY and MONOTONICITY ******************************************* #
8832 1.1 is # The returned result is within 2 ulps in 64 significant bit, #
8833 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
8834 1.1 is # rounded to double precision. The result is provably monotonic #
8835 1.1 is # in double precision. #
8836 1.1 is # #
8837 1.1 is # ALGORITHM *********************************************************** #
8838 1.1 is # #
8839 1.1 is # twotox #
8840 1.1 is # 1. If |X| > 16480, go to ExpBig. #
8841 1.1 is # #
8842 1.1 is # 2. If |X| < 2**(-70), go to ExpSm. #
8843 1.1 is # #
8844 1.1 is # 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore #
8845 1.1 is # decompose N as #
8846 1.1 is # N = 64(M + M') + j, j = 0,1,2,...,63. #
8847 1.1 is # #
8848 1.1 is # 4. Overwrite r := r * log2. Then #
8849 1.1 is # 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). #
8850 1.1 is # Go to expr to compute that expression. #
8851 1.1 is # #
8852 1.1 is # tentox #
8853 1.1 is # 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. #
8854 1.1 is # #
8855 1.1 is # 2. If |X| < 2**(-70), go to ExpSm. #
8856 1.1 is # #
8857 1.1 is # 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set #
8858 1.1 is # N := round-to-int(y). Decompose N as #
8859 1.1 is # N = 64(M + M') + j, j = 0,1,2,...,63. #
8860 1.1 is # #
8861 1.1 is # 4. Define r as #
8862 1.1 is # r := ((X - N*L1)-N*L2) * L10 #
8863 1.1 is # where L1, L2 are the leading and trailing parts of #
8864 1.1 is # log_10(2)/64 and L10 is the natural log of 10. Then #
8865 1.1 is # 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). #
8866 1.1 is # Go to expr to compute that expression. #
8867 1.1 is # #
8868 1.1 is # expr #
8869 1.1 is # 1. Fetch 2**(j/64) from table as Fact1 and Fact2. #
8870 1.1 is # #
8871 1.1 is # 2. Overwrite Fact1 and Fact2 by #
8872 1.1 is # Fact1 := 2**(M) * Fact1 #
8873 1.1 is # Fact2 := 2**(M) * Fact2 #
8874 1.1 is # Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). #
8875 1.1 is # #
8876 1.1 is # 3. Calculate P where 1 + P approximates exp(r): #
8877 1.1 is # P = r + r*r*(A1+r*(A2+...+r*A5)). #
8878 1.1 is # #
8879 1.1 is # 4. Let AdjFact := 2**(M'). Return #
8880 1.1 is # AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). #
8881 1.1 is # Exit. #
8882 1.1 is # #
8883 1.1 is # ExpBig #
8884 1.1 is # 1. Generate overflow by Huge * Huge if X > 0; otherwise, #
8885 1.1 is # generate underflow by Tiny * Tiny. #
8886 1.1 is # #
8887 1.1 is # ExpSm #
8888 1.1 is # 1. Return 1 + X. #
8889 1.1 is # #
8890 1.1 is #########################################################################
8891 1.1 is
8892 1.1 is L2TEN64:
8893 1.1 is long 0x406A934F,0x0979A371 # 64LOG10/LOG2
8894 1.1 is L10TWO1:
8895 1.1 is long 0x3F734413,0x509F8000 # LOG2/64LOG10
8896 1.1 is
8897 1.1 is L10TWO2:
8898 1.1 is long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
8899 1.1 is
8900 1.1 is LOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
8901 1.1 is
8902 1.1 is LOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
8903 1.1 is
8904 1.1 is EXPA5: long 0x3F56C16D,0x6F7BD0B2
8905 1.1 is EXPA4: long 0x3F811112,0x302C712C
8906 1.1 is EXPA3: long 0x3FA55555,0x55554CC1
8907 1.1 is EXPA2: long 0x3FC55555,0x55554A54
8908 1.1 is EXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000
8909 1.1 is
8910 1.1 is TEXPTBL:
8911 1.1 is long 0x3FFF0000,0x80000000,0x00000000,0x3F738000
8912 1.1 is long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
8913 1.1 is long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
8914 1.1 is long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
8915 1.1 is long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
8916 1.1 is long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
8917 1.1 is long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
8918 1.1 is long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
8919 1.1 is long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
8920 1.1 is long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
8921 1.1 is long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
8922 1.1 is long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
8923 1.1 is long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
8924 1.1 is long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
8925 1.1 is long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
8926 1.1 is long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
8927 1.1 is long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
8928 1.1 is long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
8929 1.1 is long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
8930 1.1 is long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
8931 1.1 is long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
8932 1.1 is long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
8933 1.1 is long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
8934 1.1 is long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
8935 1.1 is long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
8936 1.1 is long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
8937 1.1 is long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
8938 1.1 is long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
8939 1.1 is long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
8940 1.1 is long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
8941 1.1 is long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
8942 1.1 is long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
8943 1.1 is long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
8944 1.1 is long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
8945 1.1 is long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
8946 1.1 is long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
8947 1.1 is long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
8948 1.1 is long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
8949 1.1 is long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
8950 1.1 is long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
8951 1.1 is long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
8952 1.1 is long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
8953 1.1 is long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
8954 1.1 is long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
8955 1.1 is long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
8956 1.1 is long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
8957 1.1 is long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
8958 1.1 is long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
8959 1.1 is long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
8960 1.1 is long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
8961 1.1 is long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
8962 1.1 is long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
8963 1.1 is long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
8964 1.1 is long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
8965 1.1 is long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
8966 1.1 is long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
8967 1.1 is long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
8968 1.1 is long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
8969 1.1 is long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
8970 1.1 is long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
8971 1.1 is long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
8972 1.1 is long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
8973 1.1 is long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
8974 1.1 is long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
8975 1.1 is
8976 1.1 is set INT,L_SCR1
8977 1.1 is
8978 1.1 is set X,FP_SCR0
8979 1.1 is set XDCARE,X+2
8980 1.1 is set XFRAC,X+4
8981 1.1 is
8982 1.1 is set ADJFACT,FP_SCR0
8983 1.1 is
8984 1.1 is set FACT1,FP_SCR0
8985 1.1 is set FACT1HI,FACT1+4
8986 1.1 is set FACT1LOW,FACT1+8
8987 1.1 is
8988 1.1 is set FACT2,FP_SCR1
8989 1.1 is set FACT2HI,FACT2+4
8990 1.1 is set FACT2LOW,FACT2+8
8991 1.1 is
8992 1.1 is global stwotox
8993 1.1 is #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
8994 1.1 is stwotox:
8995 1.1 is fmovm.x (%a0),&0x80 # LOAD INPUT
8996 1.1 is
8997 1.1 is mov.l (%a0),%d1
8998 1.1 is mov.w 4(%a0),%d1
8999 1.1 is fmov.x %fp0,X(%a6)
9000 1.1 is and.l &0x7FFFFFFF,%d1
9001 1.1 is
9002 1.1 is cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)?
9003 1.1 is bge.b TWOOK1
9004 1.1 is bra.w EXPBORS
9005 1.1 is
9006 1.1 is TWOOK1:
9007 1.1 is cmp.l %d1,&0x400D80C0 # |X| > 16480?
9008 1.1 is ble.b TWOMAIN
9009 1.1 is bra.w EXPBORS
9010 1.1 is
9011 1.1 is TWOMAIN:
9012 1.1 is #--USUAL CASE, 2^(-70) <= |X| <= 16480
9013 1.1 is
9014 1.1 is fmov.x %fp0,%fp1
9015 1.1 is fmul.s &0x42800000,%fp1 # 64 * X
9016 1.1 is fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X)
9017 1.1 is mov.l %d2,-(%sp)
9018 1.1 is lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64)
9019 1.1 is fmov.l INT(%a6),%fp1 # N --> FLOATING FMT
9020 1.1 is mov.l INT(%a6),%d1
9021 1.1 is mov.l %d1,%d2
9022 1.1 is and.l &0x3F,%d1 # D0 IS J
9023 1.1 is asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64)
9024 1.1 is add.l %d1,%a1 # ADDRESS FOR 2^(J/64)
9025 1.1 is asr.l &6,%d2 # d2 IS L, N = 64L + J
9026 1.1 is mov.l %d2,%d1
9027 1.1 is asr.l &1,%d1 # D0 IS M
9028 1.1 is sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J
9029 1.1 is add.l &0x3FFF,%d2
9030 1.1 is
9031 1.1 is #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
9032 1.1 is #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
9033 1.1 is #--ADJFACT = 2^(M').
9034 1.1 is #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
9035 1.1 is
9036 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3
9037 1.1 is
9038 1.1 is fmul.s &0x3C800000,%fp1 # (1/64)*N
9039 1.1 is mov.l (%a1)+,FACT1(%a6)
9040 1.1 is mov.l (%a1)+,FACT1HI(%a6)
9041 1.1 is mov.l (%a1)+,FACT1LOW(%a6)
9042 1.1 is mov.w (%a1)+,FACT2(%a6)
9043 1.1 is
9044 1.1 is fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X)
9045 1.1 is
9046 1.1 is mov.w (%a1)+,FACT2HI(%a6)
9047 1.1 is clr.w FACT2HI+2(%a6)
9048 1.1 is clr.l FACT2LOW(%a6)
9049 1.1 is add.w %d1,FACT1(%a6)
9050 1.1 is fmul.x LOG2(%pc),%fp0 # FP0 IS R
9051 1.1 is add.w %d1,FACT2(%a6)
9052 1.1 is
9053 1.1 is bra.w expr
9054 1.1 is
9055 1.1 is EXPBORS:
9056 1.1 is #--FPCR, D0 SAVED
9057 1.1 is cmp.l %d1,&0x3FFF8000
9058 1.1 is bgt.b TEXPBIG
9059 1.1 is
9060 1.1 is #--|X| IS SMALL, RETURN 1 + X
9061 1.1 is
9062 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode
9063 1.1 is fadd.s &0x3F800000,%fp0 # RETURN 1 + X
9064 1.1 is bra t_pinx2
9065 1.1 is
9066 1.1 is TEXPBIG:
9067 1.1 is #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
9068 1.1 is #--REGISTERS SAVE SO FAR ARE FPCR AND D0
9069 1.1 is mov.l X(%a6),%d1
9070 1.1 is cmp.l %d1,&0
9071 1.1 is blt.b EXPNEG
9072 1.1 is
9073 1.1 is bra t_ovfl2 # t_ovfl expects positive value
9074 1.1 is
9075 1.1 is EXPNEG:
9076 1.1 is bra t_unfl2 # t_unfl expects positive value
9077 1.1 is
9078 1.1 is global stwotoxd
9079 1.1 is stwotoxd:
9080 1.1 is #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
9081 1.1 is
9082 1.1 is fmov.l %d0,%fpcr # set user's rounding mode/precision
9083 1.1 is fmov.s &0x3F800000,%fp0 # RETURN 1 + X
9084 1.1 is mov.l (%a0),%d1
9085 1.1 is or.l &0x00800001,%d1
9086 1.1 is fadd.s %d1,%fp0
9087 1.1 is bra t_pinx2
9088 1.1 is
9089 1.1 is global stentox
9090 1.1 is #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
9091 1.1 is stentox:
9092 1.1 is fmovm.x (%a0),&0x80 # LOAD INPUT
9093 1.1 is
9094 1.1 is mov.l (%a0),%d1
9095 1.1 is mov.w 4(%a0),%d1
9096 1.1 is fmov.x %fp0,X(%a6)
9097 1.1 is and.l &0x7FFFFFFF,%d1
9098 1.1 is
9099 1.1 is cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)?
9100 1.1 is bge.b TENOK1
9101 1.1 is bra.w EXPBORS
9102 1.1 is
9103 1.1 is TENOK1:
9104 1.1 is cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ?
9105 1.1 is ble.b TENMAIN
9106 1.1 is bra.w EXPBORS
9107 1.1 is
9108 1.1 is TENMAIN:
9109 1.1 is #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
9110 1.1 is
9111 1.1 is fmov.x %fp0,%fp1
9112 1.1 is fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2
9113 1.1 is fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2)
9114 1.1 is mov.l %d2,-(%sp)
9115 1.1 is lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64)
9116 1.1 is fmov.l INT(%a6),%fp1 # N --> FLOATING FMT
9117 1.1 is mov.l INT(%a6),%d1
9118 1.1 is mov.l %d1,%d2
9119 1.1 is and.l &0x3F,%d1 # D0 IS J
9120 1.1 is asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64)
9121 1.1 is add.l %d1,%a1 # ADDRESS FOR 2^(J/64)
9122 1.1 is asr.l &6,%d2 # d2 IS L, N = 64L + J
9123 1.1 is mov.l %d2,%d1
9124 1.1 is asr.l &1,%d1 # D0 IS M
9125 1.1 is sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J
9126 1.1 is add.l &0x3FFF,%d2
9127 1.1 is
9128 1.1 is #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
9129 1.1 is #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
9130 1.1 is #--ADJFACT = 2^(M').
9131 1.1 is #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
9132 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3
9133 1.1 is
9134 1.1 is fmov.x %fp1,%fp2
9135 1.1 is
9136 1.1 is fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD
9137 1.1 is mov.l (%a1)+,FACT1(%a6)
9138 1.1 is
9139 1.1 is fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL
9140 1.1 is
9141 1.1 is mov.l (%a1)+,FACT1HI(%a6)
9142 1.1 is mov.l (%a1)+,FACT1LOW(%a6)
9143 1.1 is fsub.x %fp1,%fp0 # X - N L_LEAD
9144 1.1 is mov.w (%a1)+,FACT2(%a6)
9145 1.1 is
9146 1.1 is fsub.x %fp2,%fp0 # X - N L_TRAIL
9147 1.1 is
9148 1.1 is mov.w (%a1)+,FACT2HI(%a6)
9149 1.1 is clr.w FACT2HI+2(%a6)
9150 1.1 is clr.l FACT2LOW(%a6)
9151 1.1 is
9152 1.1 is fmul.x LOG10(%pc),%fp0 # FP0 IS R
9153 1.1 is add.w %d1,FACT1(%a6)
9154 1.1 is add.w %d1,FACT2(%a6)
9155 1.1 is
9156 1.1 is expr:
9157 1.1 is #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
9158 1.1 is #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
9159 1.1 is #--FP0 IS R. THE FOLLOWING CODE COMPUTES
9160 1.1 is #-- 2**(M'+M) * 2**(J/64) * EXP(R)
9161 1.1 is
9162 1.1 is fmov.x %fp0,%fp1
9163 1.1 is fmul.x %fp1,%fp1 # FP1 IS S = R*R
9164 1.1 is
9165 1.1 is fmov.d EXPA5(%pc),%fp2 # FP2 IS A5
9166 1.1 is fmov.d EXPA4(%pc),%fp3 # FP3 IS A4
9167 1.1 is
9168 1.1 is fmul.x %fp1,%fp2 # FP2 IS S*A5
9169 1.1 is fmul.x %fp1,%fp3 # FP3 IS S*A4
9170 1.1 is
9171 1.1 is fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5
9172 1.1 is fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4
9173 1.1 is
9174 1.1 is fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5)
9175 1.1 is fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4)
9176 1.1 is
9177 1.1 is fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5)
9178 1.1 is fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4)
9179 1.1 is
9180 1.1 is fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5))
9181 1.1 is fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4)
9182 1.1 is fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1
9183 1.1 is
9184 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3
9185 1.1 is
9186 1.1 is #--FINAL RECONSTRUCTION PROCESS
9187 1.1 is #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1) - (1 OR 0)
9188 1.1 is
9189 1.1 is fmul.x FACT1(%a6),%fp0
9190 1.1 is fadd.x FACT2(%a6),%fp0
9191 1.1 is fadd.x FACT1(%a6),%fp0
9192 1.1 is
9193 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode
9194 1.1 is mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT
9195 1.1 is mov.l (%sp)+,%d2
9196 1.1 is mov.l &0x80000000,ADJFACT+4(%a6)
9197 1.1 is clr.l ADJFACT+8(%a6)
9198 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
9199 1.1 is fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT
9200 1.1 is bra t_catch
9201 1.1 is
9202 1.1 is global stentoxd
9203 1.1 is stentoxd:
9204 1.1 is #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
9205 1.1 is
9206 1.1 is fmov.l %d0,%fpcr # set user's rounding mode/precision
9207 1.1 is fmov.s &0x3F800000,%fp0 # RETURN 1 + X
9208 1.1 is mov.l (%a0),%d1
9209 1.1 is or.l &0x00800001,%d1
9210 1.1 is fadd.s %d1,%fp0
9211 1.1 is bra t_pinx2
9212 1.1 is
9213 1.1 is #########################################################################
9214 1.1 is # sscale(): computes the destination operand scaled by the source #
9215 1.1 is # operand. If the absoulute value of the source operand is #
9216 1.1 is # >= 2^14, an overflow or underflow is returned. #
9217 1.1 is # #
9218 1.1 is # INPUT *************************************************************** #
9219 1.1 is # a0 = pointer to double-extended source operand X #
9220 1.1 is # a1 = pointer to double-extended destination operand Y #
9221 1.1 is # #
9222 1.1 is # OUTPUT ************************************************************** #
9223 1.1 is # fp0 = scale(X,Y) #
9224 1.1 is # #
9225 1.1 is #########################################################################
9226 1.1 is
9227 1.1 is set SIGN, L_SCR1
9228 1.1 is
9229 1.1 is global sscale
9230 1.1 is sscale:
9231 1.1 is mov.l %d0,-(%sp) # store off ctrl bits for now
9232 1.1 is
9233 1.1 is mov.w DST_EX(%a1),%d1 # get dst exponent
9234 1.1 is smi.b SIGN(%a6) # use SIGN to hold dst sign
9235 1.1 is andi.l &0x00007fff,%d1 # strip sign from dst exp
9236 1.1 is
9237 1.1 is mov.w SRC_EX(%a0),%d0 # check src bounds
9238 1.1 is andi.w &0x7fff,%d0 # clr src sign bit
9239 1.1 is cmpi.w %d0,&0x3fff # is src ~ ZERO?
9240 1.1 is blt.w src_small # yes
9241 1.1 is cmpi.w %d0,&0x400c # no; is src too big?
9242 1.1 is bgt.w src_out # yes
9243 1.1 is
9244 1.1 is #
9245 1.1 is # Source is within 2^14 range.
9246 1.1 is #
9247 1.1 is src_ok:
9248 1.1 is fintrz.x SRC(%a0),%fp0 # calc int of src
9249 1.1 is fmov.l %fp0,%d0 # int src to d0
9250 1.1 is # don't want any accrued bits from the fintrz showing up later since
9251 1.1 is # we may need to read the fpsr for the last fp op in t_catch2().
9252 1.1 is fmov.l &0x0,%fpsr
9253 1.1 is
9254 1.1 is tst.b DST_HI(%a1) # is dst denormalized?
9255 1.1 is bmi.b sok_norm
9256 1.1 is
9257 1.1 is # the dst is a DENORM. normalize the DENORM and add the adjustment to
9258 1.1 is # the src value. then, jump to the norm part of the routine.
9259 1.1 is sok_dnrm:
9260 1.1 is mov.l %d0,-(%sp) # save src for now
9261 1.1 is
9262 1.1 is mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
9263 1.1 is mov.l DST_HI(%a1),FP_SCR0_HI(%a6)
9264 1.1 is mov.l DST_LO(%a1),FP_SCR0_LO(%a6)
9265 1.1 is
9266 1.1 is lea FP_SCR0(%a6),%a0 # pass ptr to DENORM
9267 1.1 is bsr.l norm # normalize the DENORM
9268 1.1 is neg.l %d0
9269 1.1 is add.l (%sp)+,%d0 # add adjustment to src
9270 1.1 is
9271 1.1 is fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM
9272 1.1 is
9273 1.1 is cmpi.w %d0,&-0x3fff # is the shft amt really low?
9274 1.1 is bge.b sok_norm2 # thank goodness no
9275 1.1 is
9276 1.1 is # the multiply factor that we're trying to create should be a denorm
9277 1.1 is # for the multiply to work. therefore, we're going to actually do a
9278 1.1 is # multiply with a denorm which will cause an unimplemented data type
9279 1.1 is # exception to be put into the machine which will be caught and corrected
9280 1.1 is # later. we don't do this with the DENORMs above because this method
9281 1.1 is # is slower. but, don't fret, I don't see it being used much either.
9282 1.1 is fmov.l (%sp)+,%fpcr # restore user fpcr
9283 1.1 is mov.l &0x80000000,%d1 # load normalized mantissa
9284 1.1 is subi.l &-0x3fff,%d0 # how many should we shift?
9285 1.1 is neg.l %d0 # make it positive
9286 1.1 is cmpi.b %d0,&0x20 # is it > 32?
9287 1.1 is bge.b sok_dnrm_32 # yes
9288 1.1 is lsr.l %d0,%d1 # no; bit stays in upper lw
9289 1.1 is clr.l -(%sp) # insert zero low mantissa
9290 1.1 is mov.l %d1,-(%sp) # insert new high mantissa
9291 1.1 is clr.l -(%sp) # make zero exponent
9292 1.1 is bra.b sok_norm_cont
9293 1.1 is sok_dnrm_32:
9294 1.1 is subi.b &0x20,%d0 # get shift count
9295 1.1 is lsr.l %d0,%d1 # make low mantissa longword
9296 1.1 is mov.l %d1,-(%sp) # insert new low mantissa
9297 1.1 is clr.l -(%sp) # insert zero high mantissa
9298 1.1 is clr.l -(%sp) # make zero exponent
9299 1.1 is bra.b sok_norm_cont
9300 1.1 is
9301 1.1 is # the src will force the dst to a DENORM value or worse. so, let's
9302 1.1 is # create an fp multiply that will create the result.
9303 1.1 is sok_norm:
9304 1.1 is fmovm.x DST(%a1),&0x80 # load fp0 with normalized src
9305 1.1 is sok_norm2:
9306 1.1 is fmov.l (%sp)+,%fpcr # restore user fpcr
9307 1.1 is
9308 1.1 is addi.w &0x3fff,%d0 # turn src amt into exp value
9309 1.1 is swap %d0 # put exponent in high word
9310 1.1 is clr.l -(%sp) # insert new exponent
9311 1.1 is mov.l &0x80000000,-(%sp) # insert new high mantissa
9312 1.1 is mov.l %d0,-(%sp) # insert new lo mantissa
9313 1.1 is
9314 1.1 is sok_norm_cont:
9315 1.1 is fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2
9316 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
9317 1.1 is fmul.x (%sp)+,%fp0 # do the multiply
9318 1.1 is bra t_catch2 # catch any exceptions
9319 1.1 is
9320 1.1 is #
9321 1.1 is # Source is outside of 2^14 range. Test the sign and branch
9322 1.1 is # to the appropriate exception handler.
9323 1.1 is #
9324 1.1 is src_out:
9325 1.1 is mov.l (%sp)+,%d0 # restore ctrl bits
9326 1.1 is exg %a0,%a1 # swap src,dst ptrs
9327 1.1 is tst.b SRC_EX(%a1) # is src negative?
9328 1.1 is bmi t_unfl # yes; underflow
9329 1.1 is bra t_ovfl_sc # no; overflow
9330 1.1 is
9331 1.1 is #
9332 1.1 is # The source input is below 1, so we check for denormalized numbers
9333 1.1 is # and set unfl.
9334 1.1 is #
9335 1.1 is src_small:
9336 1.1 is tst.b DST_HI(%a1) # is dst denormalized?
9337 1.1 is bpl.b ssmall_done # yes
9338 1.1 is
9339 1.1 is mov.l (%sp)+,%d0
9340 1.1 is fmov.l %d0,%fpcr # no; load control bits
9341 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
9342 1.1 is fmov.x DST(%a1),%fp0 # simply return dest
9343 1.1 is bra t_catch2
9344 1.1 is ssmall_done:
9345 1.1 is mov.l (%sp)+,%d0 # load control bits into d1
9346 1.1 is mov.l %a1,%a0 # pass ptr to dst
9347 1.1 is bra t_resdnrm
9348 1.1 is
9349 1.1 is #########################################################################
9350 1.1 is # smod(): computes the fp MOD of the input values X,Y. #
9351 1.1 is # srem(): computes the fp (IEEE) REM of the input values X,Y. #
9352 1.1 is # #
9353 1.1 is # INPUT *************************************************************** #
9354 1.1 is # a0 = pointer to extended precision input X #
9355 1.1 is # a1 = pointer to extended precision input Y #
9356 1.1 is # d0 = round precision,mode #
9357 1.1 is # #
9358 1.1 is # The input operands X and Y can be either normalized or #
9359 1.1 is # denormalized. #
9360 1.1 is # #
9361 1.1 is # OUTPUT ************************************************************** #
9362 1.1 is # fp0 = FREM(X,Y) or FMOD(X,Y) #
9363 1.1 is # #
9364 1.1 is # ALGORITHM *********************************************************** #
9365 1.1 is # #
9366 1.1 is # Step 1. Save and strip signs of X and Y: signX := sign(X), #
9367 1.1 is # signY := sign(Y), X := |X|, Y := |Y|, #
9368 1.1 is # signQ := signX EOR signY. Record whether MOD or REM #
9369 1.1 is # is requested. #
9370 1.1 is # #
9371 1.1 is # Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. #
9372 1.1 is # If (L < 0) then #
9373 1.1 is # R := X, go to Step 4. #
9374 1.1 is # else #
9375 1.1 is # R := 2^(-L)X, j := L. #
9376 1.1 is # endif #
9377 1.1 is # #
9378 1.1 is # Step 3. Perform MOD(X,Y) #
9379 1.1 is # 3.1 If R = Y, go to Step 9. #
9380 1.1 is # 3.2 If R > Y, then { R := R - Y, Q := Q + 1} #
9381 1.1 is # 3.3 If j = 0, go to Step 4. #
9382 1.1 is # 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to #
9383 1.1 is # Step 3.1. #
9384 1.1 is # #
9385 1.1 is # Step 4. At this point, R = X - QY = MOD(X,Y). Set #
9386 1.1 is # Last_Subtract := false (used in Step 7 below). If #
9387 1.1 is # MOD is requested, go to Step 6. #
9388 1.1 is # #
9389 1.1 is # Step 5. R = MOD(X,Y), but REM(X,Y) is requested. #
9390 1.1 is # 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to #
9391 1.1 is # Step 6. #
9392 1.1 is # 5.2 If R > Y/2, then { set Last_Subtract := true, #
9393 1.1 is # Q := Q + 1, Y := signY*Y }. Go to Step 6. #
9394 1.1 is # 5.3 This is the tricky case of R = Y/2. If Q is odd, #
9395 1.1 is # then { Q := Q + 1, signX := -signX }. #
9396 1.1 is # #
9397 1.1 is # Step 6. R := signX*R. #
9398 1.1 is # #
9399 1.1 is # Step 7. If Last_Subtract = true, R := R - Y. #
9400 1.1 is # #
9401 1.1 is # Step 8. Return signQ, last 7 bits of Q, and R as required. #
9402 1.1 is # #
9403 1.1 is # Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, #
9404 1.1 is # X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), #
9405 1.1 is # R := 0. Return signQ, last 7 bits of Q, and R. #
9406 1.1 is # #
9407 1.1 is #########################################################################
9408 1.1 is
9409 1.1 is set Mod_Flag,L_SCR3
9410 1.1 is set Sc_Flag,L_SCR3+1
9411 1.1 is
9412 1.1 is set SignY,L_SCR2
9413 1.1 is set SignX,L_SCR2+2
9414 1.1 is set SignQ,L_SCR3+2
9415 1.1 is
9416 1.1 is set Y,FP_SCR0
9417 1.1 is set Y_Hi,Y+4
9418 1.1 is set Y_Lo,Y+8
9419 1.1 is
9420 1.1 is set R,FP_SCR1
9421 1.1 is set R_Hi,R+4
9422 1.1 is set R_Lo,R+8
9423 1.1 is
9424 1.1 is Scale:
9425 1.1 is long 0x00010000,0x80000000,0x00000000,0x00000000
9426 1.1 is
9427 1.1 is global smod
9428 1.1 is smod:
9429 1.1 is clr.b FPSR_QBYTE(%a6)
9430 1.1 is mov.l %d0,-(%sp) # save ctrl bits
9431 1.1 is clr.b Mod_Flag(%a6)
9432 1.1 is bra.b Mod_Rem
9433 1.1 is
9434 1.1 is global srem
9435 1.1 is srem:
9436 1.1 is clr.b FPSR_QBYTE(%a6)
9437 1.1 is mov.l %d0,-(%sp) # save ctrl bits
9438 1.1 is mov.b &0x1,Mod_Flag(%a6)
9439 1.1 is
9440 1.1 is Mod_Rem:
9441 1.1 is #..Save sign of X and Y
9442 1.1 is movm.l &0x3f00,-(%sp) # save data registers
9443 1.1 is mov.w SRC_EX(%a0),%d3
9444 1.1 is mov.w %d3,SignY(%a6)
9445 1.1 is and.l &0x00007FFF,%d3 # Y := |Y|
9446 1.1 is
9447 1.1 is #
9448 1.1 is mov.l SRC_HI(%a0),%d4
9449 1.1 is mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y|
9450 1.1 is
9451 1.1 is tst.l %d3
9452 1.1 is bne.b Y_Normal
9453 1.1 is
9454 1.1 is mov.l &0x00003FFE,%d3 # $3FFD + 1
9455 1.1 is tst.l %d4
9456 1.1 is bne.b HiY_not0
9457 1.1 is
9458 1.1 is HiY_0:
9459 1.1 is mov.l %d5,%d4
9460 1.1 is clr.l %d5
9461 1.1 is sub.l &32,%d3
9462 1.1 is clr.l %d6
9463 1.1 is bfffo %d4{&0:&32},%d6
9464 1.1 is lsl.l %d6,%d4
9465 1.1 is sub.l %d6,%d3 # (D3,D4,D5) is normalized
9466 1.1 is # ...with bias $7FFD
9467 1.1 is bra.b Chk_X
9468 1.1 is
9469 1.1 is HiY_not0:
9470 1.1 is clr.l %d6
9471 1.1 is bfffo %d4{&0:&32},%d6
9472 1.1 is sub.l %d6,%d3
9473 1.1 is lsl.l %d6,%d4
9474 1.1 is mov.l %d5,%d7 # a copy of D5
9475 1.1 is lsl.l %d6,%d5
9476 1.1 is neg.l %d6
9477 1.1 is add.l &32,%d6
9478 1.1 is lsr.l %d6,%d7
9479 1.1 is or.l %d7,%d4 # (D3,D4,D5) normalized
9480 1.1 is # ...with bias $7FFD
9481 1.1 is bra.b Chk_X
9482 1.1 is
9483 1.1 is Y_Normal:
9484 1.1 is add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized
9485 1.1 is # ...with bias $7FFD
9486 1.1 is
9487 1.1 is Chk_X:
9488 1.1 is mov.w DST_EX(%a1),%d0
9489 1.1 is mov.w %d0,SignX(%a6)
9490 1.1 is mov.w SignY(%a6),%d1
9491 1.1 is eor.l %d0,%d1
9492 1.1 is and.l &0x00008000,%d1
9493 1.1 is mov.w %d1,SignQ(%a6) # sign(Q) obtained
9494 1.1 is and.l &0x00007FFF,%d0
9495 1.1 is mov.l DST_HI(%a1),%d1
9496 1.1 is mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X|
9497 1.1 is tst.l %d0
9498 1.1 is bne.b X_Normal
9499 1.1 is mov.l &0x00003FFE,%d0
9500 1.1 is tst.l %d1
9501 1.1 is bne.b HiX_not0
9502 1.1 is
9503 1.1 is HiX_0:
9504 1.1 is mov.l %d2,%d1
9505 1.1 is clr.l %d2
9506 1.1 is sub.l &32,%d0
9507 1.1 is clr.l %d6
9508 1.1 is bfffo %d1{&0:&32},%d6
9509 1.1 is lsl.l %d6,%d1
9510 1.1 is sub.l %d6,%d0 # (D0,D1,D2) is normalized
9511 1.1 is # ...with bias $7FFD
9512 1.1 is bra.b Init
9513 1.1 is
9514 1.1 is HiX_not0:
9515 1.1 is clr.l %d6
9516 1.1 is bfffo %d1{&0:&32},%d6
9517 1.1 is sub.l %d6,%d0
9518 1.1 is lsl.l %d6,%d1
9519 1.1 is mov.l %d2,%d7 # a copy of D2
9520 1.1 is lsl.l %d6,%d2
9521 1.1 is neg.l %d6
9522 1.1 is add.l &32,%d6
9523 1.1 is lsr.l %d6,%d7
9524 1.1 is or.l %d7,%d1 # (D0,D1,D2) normalized
9525 1.1 is # ...with bias $7FFD
9526 1.1 is bra.b Init
9527 1.1 is
9528 1.1 is X_Normal:
9529 1.1 is add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized
9530 1.1 is # ...with bias $7FFD
9531 1.1 is
9532 1.1 is Init:
9533 1.1 is #
9534 1.1 is mov.l %d3,L_SCR1(%a6) # save biased exp(Y)
9535 1.1 is mov.l %d0,-(%sp) # save biased exp(X)
9536 1.1 is sub.l %d3,%d0 # L := expo(X)-expo(Y)
9537 1.1 is
9538 1.1 is clr.l %d6 # D6 := carry <- 0
9539 1.1 is clr.l %d3 # D3 is Q
9540 1.1 is mov.l &0,%a1 # A1 is k; j+k=L, Q=0
9541 1.1 is
9542 1.1 is #..(Carry,D1,D2) is R
9543 1.1 is tst.l %d0
9544 1.1 is bge.b Mod_Loop_pre
9545 1.1 is
9546 1.1 is #..expo(X) < expo(Y). Thus X = mod(X,Y)
9547 1.1 is #
9548 1.1 is mov.l (%sp)+,%d0 # restore d0
9549 1.1 is bra.w Get_Mod
9550 1.1 is
9551 1.1 is Mod_Loop_pre:
9552 1.1 is addq.l &0x4,%sp # erase exp(X)
9553 1.1 is #..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L
9554 1.1 is Mod_Loop:
9555 1.1 is tst.l %d6 # test carry bit
9556 1.1 is bgt.b R_GT_Y
9557 1.1 is
9558 1.1 is #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
9559 1.1 is cmp.l %d1,%d4 # compare hi(R) and hi(Y)
9560 1.1 is bne.b R_NE_Y
9561 1.1 is cmp.l %d2,%d5 # compare lo(R) and lo(Y)
9562 1.1 is bne.b R_NE_Y
9563 1.1 is
9564 1.1 is #..At this point, R = Y
9565 1.1 is bra.w Rem_is_0
9566 1.1 is
9567 1.1 is R_NE_Y:
9568 1.1 is #..use the borrow of the previous compare
9569 1.1 is bcs.b R_LT_Y # borrow is set iff R < Y
9570 1.1 is
9571 1.1 is R_GT_Y:
9572 1.1 is #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
9573 1.1 is #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
9574 1.1 is sub.l %d5,%d2 # lo(R) - lo(Y)
9575 1.1 is subx.l %d4,%d1 # hi(R) - hi(Y)
9576 1.1 is clr.l %d6 # clear carry
9577 1.1 is addq.l &1,%d3 # Q := Q + 1
9578 1.1 is
9579 1.1 is R_LT_Y:
9580 1.1 is #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
9581 1.1 is tst.l %d0 # see if j = 0.
9582 1.1 is beq.b PostLoop
9583 1.1 is
9584 1.1 is add.l %d3,%d3 # Q := 2Q
9585 1.1 is add.l %d2,%d2 # lo(R) = 2lo(R)
9586 1.1 is roxl.l &1,%d1 # hi(R) = 2hi(R) + carry
9587 1.1 is scs %d6 # set Carry if 2(R) overflows
9588 1.1 is addq.l &1,%a1 # k := k+1
9589 1.1 is subq.l &1,%d0 # j := j - 1
9590 1.1 is #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
9591 1.1 is
9592 1.1 is bra.b Mod_Loop
9593 1.1 is
9594 1.1 is PostLoop:
9595 1.1 is #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
9596 1.1 is
9597 1.1 is #..normalize R.
9598 1.1 is mov.l L_SCR1(%a6),%d0 # new biased expo of R
9599 1.1 is tst.l %d1
9600 1.1 is bne.b HiR_not0
9601 1.1 is
9602 1.1 is HiR_0:
9603 1.1 is mov.l %d2,%d1
9604 1.1 is clr.l %d2
9605 1.1 is sub.l &32,%d0
9606 1.1 is clr.l %d6
9607 1.1 is bfffo %d1{&0:&32},%d6
9608 1.1 is lsl.l %d6,%d1
9609 1.1 is sub.l %d6,%d0 # (D0,D1,D2) is normalized
9610 1.1 is # ...with bias $7FFD
9611 1.1 is bra.b Get_Mod
9612 1.1 is
9613 1.1 is HiR_not0:
9614 1.1 is clr.l %d6
9615 1.1 is bfffo %d1{&0:&32},%d6
9616 1.1 is bmi.b Get_Mod # already normalized
9617 1.1 is sub.l %d6,%d0
9618 1.1 is lsl.l %d6,%d1
9619 1.1 is mov.l %d2,%d7 # a copy of D2
9620 1.1 is lsl.l %d6,%d2
9621 1.1 is neg.l %d6
9622 1.1 is add.l &32,%d6
9623 1.1 is lsr.l %d6,%d7
9624 1.1 is or.l %d7,%d1 # (D0,D1,D2) normalized
9625 1.1 is
9626 1.1 is #
9627 1.1 is Get_Mod:
9628 1.1 is cmp.l %d0,&0x000041FE
9629 1.1 is bge.b No_Scale
9630 1.1 is Do_Scale:
9631 1.1 is mov.w %d0,R(%a6)
9632 1.1 is mov.l %d1,R_Hi(%a6)
9633 1.1 is mov.l %d2,R_Lo(%a6)
9634 1.1 is mov.l L_SCR1(%a6),%d6
9635 1.1 is mov.w %d6,Y(%a6)
9636 1.1 is mov.l %d4,Y_Hi(%a6)
9637 1.1 is mov.l %d5,Y_Lo(%a6)
9638 1.1 is fmov.x R(%a6),%fp0 # no exception
9639 1.1 is mov.b &1,Sc_Flag(%a6)
9640 1.1 is bra.b ModOrRem
9641 1.1 is No_Scale:
9642 1.1 is mov.l %d1,R_Hi(%a6)
9643 1.1 is mov.l %d2,R_Lo(%a6)
9644 1.1 is sub.l &0x3FFE,%d0
9645 1.1 is mov.w %d0,R(%a6)
9646 1.1 is mov.l L_SCR1(%a6),%d6
9647 1.1 is sub.l &0x3FFE,%d6
9648 1.1 is mov.l %d6,L_SCR1(%a6)
9649 1.1 is fmov.x R(%a6),%fp0
9650 1.1 is mov.w %d6,Y(%a6)
9651 1.1 is mov.l %d4,Y_Hi(%a6)
9652 1.1 is mov.l %d5,Y_Lo(%a6)
9653 1.1 is clr.b Sc_Flag(%a6)
9654 1.1 is
9655 1.1 is #
9656 1.1 is ModOrRem:
9657 1.1 is tst.b Mod_Flag(%a6)
9658 1.1 is beq.b Fix_Sign
9659 1.1 is
9660 1.1 is mov.l L_SCR1(%a6),%d6 # new biased expo(Y)
9661 1.1 is subq.l &1,%d6 # biased expo(Y/2)
9662 1.1 is cmp.l %d0,%d6
9663 1.1 is blt.b Fix_Sign
9664 1.1 is bgt.b Last_Sub
9665 1.1 is
9666 1.1 is cmp.l %d1,%d4
9667 1.1 is bne.b Not_EQ
9668 1.1 is cmp.l %d2,%d5
9669 1.1 is bne.b Not_EQ
9670 1.1 is bra.w Tie_Case
9671 1.1 is
9672 1.1 is Not_EQ:
9673 1.1 is bcs.b Fix_Sign
9674 1.1 is
9675 1.1 is Last_Sub:
9676 1.1 is #
9677 1.1 is fsub.x Y(%a6),%fp0 # no exceptions
9678 1.1 is addq.l &1,%d3 # Q := Q + 1
9679 1.1 is
9680 1.1 is #
9681 1.1 is Fix_Sign:
9682 1.1 is #..Get sign of X
9683 1.1 is mov.w SignX(%a6),%d6
9684 1.1 is bge.b Get_Q
9685 1.1 is fneg.x %fp0
9686 1.1 is
9687 1.1 is #..Get Q
9688 1.1 is #
9689 1.1 is Get_Q:
9690 1.1 is clr.l %d6
9691 1.1 is mov.w SignQ(%a6),%d6 # D6 is sign(Q)
9692 1.1 is mov.l &8,%d7
9693 1.1 is lsr.l %d7,%d6
9694 1.1 is and.l &0x0000007F,%d3 # 7 bits of Q
9695 1.1 is or.l %d6,%d3 # sign and bits of Q
9696 1.1 is # swap %d3
9697 1.1 is # fmov.l %fpsr,%d6
9698 1.1 is # and.l &0xFF00FFFF,%d6
9699 1.1 is # or.l %d3,%d6
9700 1.1 is # fmov.l %d6,%fpsr # put Q in fpsr
9701 1.1 is mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr
9702 1.1 is
9703 1.1 is #
9704 1.1 is Restore:
9705 1.1 is movm.l (%sp)+,&0xfc # {%d2-%d7}
9706 1.1 is mov.l (%sp)+,%d0
9707 1.1 is fmov.l %d0,%fpcr
9708 1.1 is tst.b Sc_Flag(%a6)
9709 1.1 is beq.b Finish
9710 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL
9711 1.1 is fmul.x Scale(%pc),%fp0 # may cause underflow
9712 1.1 is bra t_catch2
9713 1.1 is # the '040 package did this apparently to see if the dst operand for the
9714 1.1 is # preceding fmul was a denorm. but, it better not have been since the
9715 1.1 is # algorithm just got done playing with fp0 and expected no exceptions
9716 1.1 is # as a result. trust me...
9717 1.1 is # bra t_avoid_unsupp # check for denorm as a
9718 1.1 is # ;result of the scaling
9719 1.1 is
9720 1.1 is Finish:
9721 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE
9722 1.1 is fmov.x %fp0,%fp0 # capture exceptions & round
9723 1.1 is bra t_catch2
9724 1.1 is
9725 1.1 is Rem_is_0:
9726 1.1 is #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
9727 1.1 is addq.l &1,%d3
9728 1.1 is cmp.l %d0,&8 # D0 is j
9729 1.1 is bge.b Q_Big
9730 1.1 is
9731 1.1 is lsl.l %d0,%d3
9732 1.1 is bra.b Set_R_0
9733 1.1 is
9734 1.1 is Q_Big:
9735 1.1 is clr.l %d3
9736 1.1 is
9737 1.1 is Set_R_0:
9738 1.1 is fmov.s &0x00000000,%fp0
9739 1.1 is clr.b Sc_Flag(%a6)
9740 1.1 is bra.w Fix_Sign
9741 1.1 is
9742 1.1 is Tie_Case:
9743 1.1 is #..Check parity of Q
9744 1.1 is mov.l %d3,%d6
9745 1.1 is and.l &0x00000001,%d6
9746 1.1 is tst.l %d6
9747 1.1 is beq.w Fix_Sign # Q is even
9748 1.1 is
9749 1.1 is #..Q is odd, Q := Q + 1, signX := -signX
9750 1.1 is addq.l &1,%d3
9751 1.1 is mov.w SignX(%a6),%d6
9752 1.1 is eor.l &0x00008000,%d6
9753 1.1 is mov.w %d6,SignX(%a6)
9754 1.1 is bra.w Fix_Sign
9755 1.1 is
9756 1.1 is #########################################################################
9757 1.1 is # XDEF **************************************************************** #
9758 1.1 is # tag(): return the optype of the input ext fp number #
9759 1.1 is # #
9760 1.1 is # This routine is used by the 060FPLSP. #
9761 1.1 is # #
9762 1.1 is # XREF **************************************************************** #
9763 1.1 is # None #
9764 1.1 is # #
9765 1.1 is # INPUT *************************************************************** #
9766 1.1 is # a0 = pointer to extended precision operand #
9767 1.1 is # #
9768 1.1 is # OUTPUT ************************************************************** #
9769 1.1 is # d0 = value of type tag #
9770 1.1 is # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO #
9771 1.1 is # #
9772 1.1 is # ALGORITHM *********************************************************** #
9773 1.1 is # Simply test the exponent, j-bit, and mantissa values to #
9774 1.1 is # determine the type of operand. #
9775 1.1 is # If it's an unnormalized zero, alter the operand and force it #
9776 1.1 is # to be a normal zero. #
9777 1.1 is # #
9778 1.1 is #########################################################################
9779 1.1 is
9780 1.1 is global tag
9781 1.1 is tag:
9782 1.1 is mov.w FTEMP_EX(%a0), %d0 # extract exponent
9783 1.1 is andi.w &0x7fff, %d0 # strip off sign
9784 1.1 is cmpi.w %d0, &0x7fff # is (EXP == MAX)?
9785 1.1 is beq.b inf_or_nan_x
9786 1.1 is not_inf_or_nan_x:
9787 1.1 is btst &0x7,FTEMP_HI(%a0)
9788 1.1 is beq.b not_norm_x
9789 1.1 is is_norm_x:
9790 1.1 is mov.b &NORM, %d0
9791 1.1 is rts
9792 1.1 is not_norm_x:
9793 1.1 is tst.w %d0 # is exponent = 0?
9794 1.1 is bne.b is_unnorm_x
9795 1.1 is not_unnorm_x:
9796 1.1 is tst.l FTEMP_HI(%a0)
9797 1.1 is bne.b is_denorm_x
9798 1.1 is tst.l FTEMP_LO(%a0)
9799 1.1 is bne.b is_denorm_x
9800 1.1 is is_zero_x:
9801 1.1 is mov.b &ZERO, %d0
9802 1.1 is rts
9803 1.1 is is_denorm_x:
9804 1.1 is mov.b &DENORM, %d0
9805 1.1 is rts
9806 1.1 is is_unnorm_x:
9807 1.1 is bsr.l unnorm_fix # convert to norm,denorm,or zero
9808 1.1 is rts
9809 1.1 is is_unnorm_reg_x:
9810 1.1 is mov.b &UNNORM, %d0
9811 1.1 is rts
9812 1.1 is inf_or_nan_x:
9813 1.1 is tst.l FTEMP_LO(%a0)
9814 1.1 is bne.b is_nan_x
9815 1.1 is mov.l FTEMP_HI(%a0), %d0
9816 1.1 is and.l &0x7fffffff, %d0 # msb is a don't care!
9817 1.1 is bne.b is_nan_x
9818 1.1 is is_inf_x:
9819 1.1 is mov.b &INF, %d0
9820 1.1 is rts
9821 1.1 is is_nan_x:
9822 1.1 is mov.b &QNAN, %d0
9823 1.1 is rts
9824 1.1 is
9825 1.1 is #############################################################
9826 1.1 is
9827 1.1 is qnan: long 0x7fff0000, 0xffffffff, 0xffffffff
9828 1.1 is
9829 1.1 is #########################################################################
9830 1.1 is # XDEF **************************************************************** #
9831 1.1 is # t_dz(): Handle 060FPLSP dz exception for "flogn" emulation. #
9832 1.1 is # t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation. #
9833 1.1 is # #
9834 1.1 is # These rouitnes are used by the 060FPLSP package. #
9835 1.1 is # #
9836 1.1 is # XREF **************************************************************** #
9837 1.1 is # None #
9838 1.1 is # #
9839 1.1 is # INPUT *************************************************************** #
9840 1.1 is # a0 = pointer to extended precision source operand. #
9841 1.1 is # #
9842 1.1 is # OUTPUT ************************************************************** #
9843 1.1 is # fp0 = default DZ result. #
9844 1.1 is # #
9845 1.1 is # ALGORITHM *********************************************************** #
9846 1.1 is # Transcendental emulation for the 060FPLSP has detected that #
9847 1.1 is # a DZ exception should occur for the instruction. If DZ is disabled, #
9848 1.1 is # return the default result. #
9849 1.1 is # If DZ is enabled, the dst operand should be returned unscathed #
9850 1.1 is # in fp0 while fp1 is used to create a DZ exception so that the #
9851 1.1 is # operating system can log that such an event occurred. #
9852 1.1 is # #
9853 1.1 is #########################################################################
9854 1.1 is
9855 1.1 is global t_dz
9856 1.1 is t_dz:
9857 1.1 is tst.b SRC_EX(%a0) # check sign for neg or pos
9858 1.1 is bpl.b dz_pinf # branch if pos sign
9859 1.1 is
9860 1.1 is global t_dz2
9861 1.1 is t_dz2:
9862 1.1 is ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
9863 1.1 is
9864 1.1 is btst &dz_bit,FPCR_ENABLE(%a6)
9865 1.1 is bne.b dz_minf_ena
9866 1.1 is
9867 1.1 is # dz is disabled. return a -INF.
9868 1.1 is fmov.s &0xff800000,%fp0 # return -INF
9869 1.1 is rts
9870 1.1 is
9871 1.1 is # dz is enabled. create a dz exception so the user can record it
9872 1.1 is # but use fp1 instead. return the dst operand unscathed in fp0.
9873 1.1 is dz_minf_ena:
9874 1.1 is fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed
9875 1.1 is fmov.l USER_FPCR(%a6),%fpcr
9876 1.1 is fmov.s &0xbf800000,%fp1 # load -1
9877 1.1 is fdiv.s &0x00000000,%fp1 # -1 / 0
9878 1.1 is rts
9879 1.1 is
9880 1.1 is dz_pinf:
9881 1.1 is ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
9882 1.1 is
9883 1.1 is btst &dz_bit,FPCR_ENABLE(%a6)
9884 1.1 is bne.b dz_pinf_ena
9885 1.1 is
9886 1.1 is # dz is disabled. return a +INF.
9887 1.1 is fmov.s &0x7f800000,%fp0 # return +INF
9888 1.1 is rts
9889 1.1 is
9890 1.1 is # dz is enabled. create a dz exception so the user can record it
9891 1.1 is # but use fp1 instead. return the dst operand unscathed in fp0.
9892 1.1 is dz_pinf_ena:
9893 1.1 is fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed
9894 1.1 is fmov.l USER_FPCR(%a6),%fpcr
9895 1.1 is fmov.s &0x3f800000,%fp1 # load +1
9896 1.1 is fdiv.s &0x00000000,%fp1 # +1 / 0
9897 1.1 is rts
9898 1.1 is
9899 1.1 is #########################################################################
9900 1.1 is # XDEF **************************************************************** #
9901 1.1 is # t_operr(): Handle 060FPLSP OPERR exception during emulation. #
9902 1.1 is # #
9903 1.1 is # This routine is used by the 060FPLSP package. #
9904 1.1 is # #
9905 1.1 is # XREF **************************************************************** #
9906 1.1 is # None. #
9907 1.1 is # #
9908 1.1 is # INPUT *************************************************************** #
9909 1.1 is # fp1 = source operand #
9910 1.1 is # #
9911 1.1 is # OUTPUT ************************************************************** #
9912 1.1 is # fp0 = default result #
9913 1.1 is # fp1 = unchanged #
9914 1.1 is # #
9915 1.1 is # ALGORITHM *********************************************************** #
9916 1.1 is # An operand error should occur as the result of transcendental #
9917 1.1 is # emulation in the 060FPLSP. If OPERR is disabled, just return a NAN #
9918 1.1 is # in fp0. If OPERR is enabled, return the dst operand unscathed in fp0 #
9919 1.1 is # and the source operand in fp1. Use fp2 to create an OPERR exception #
9920 1.1 is # so that the operating system can log the event. #
9921 1.1 is # #
9922 1.1 is #########################################################################
9923 1.1 is
9924 1.1 is global t_operr
9925 1.1 is t_operr:
9926 1.1 is ori.l &opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
9927 1.1 is
9928 1.1 is btst &operr_bit,FPCR_ENABLE(%a6)
9929 1.1 is bne.b operr_ena
9930 1.1 is
9931 1.1 is # operr is disabled. return a QNAN in fp0
9932 1.1 is fmovm.x qnan(%pc),&0x80 # return QNAN
9933 1.1 is rts
9934 1.1 is
9935 1.1 is # operr is enabled. create an operr exception so the user can record it
9936 1.1 is # but use fp2 instead. return the dst operand unscathed in fp0.
9937 1.1 is operr_ena:
9938 1.1 is fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed
9939 1.1 is fmov.l USER_FPCR(%a6),%fpcr
9940 1.1 is fmovm.x &0x04,-(%sp) # save fp2
9941 1.1 is fmov.s &0x7f800000,%fp2 # load +INF
9942 1.1 is fmul.s &0x00000000,%fp2 # +INF x 0
9943 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2
9944 1.1 is rts
9945 1.1 is
9946 1.1 is pls_huge:
9947 1.1 is long 0x7ffe0000,0xffffffff,0xffffffff
9948 1.1 is mns_huge:
9949 1.1 is long 0xfffe0000,0xffffffff,0xffffffff
9950 1.1 is pls_tiny:
9951 1.1 is long 0x00000000,0x80000000,0x00000000
9952 1.1 is mns_tiny:
9953 1.1 is long 0x80000000,0x80000000,0x00000000
9954 1.1 is
9955 1.1 is #########################################################################
9956 1.1 is # XDEF **************************************************************** #
9957 1.1 is # t_unfl(): Handle 060FPLSP underflow exception during emulation. #
9958 1.1 is # t_unfl2(): Handle 060FPLSP underflow exception during #
9959 1.1 is # emulation. result always positive. #
9960 1.1 is # #
9961 1.1 is # This routine is used by the 060FPLSP package. #
9962 1.1 is # #
9963 1.1 is # XREF **************************************************************** #
9964 1.1 is # None. #
9965 1.1 is # #
9966 1.1 is # INPUT *************************************************************** #
9967 1.1 is # a0 = pointer to extended precision source operand #
9968 1.1 is # #
9969 1.1 is # OUTPUT ************************************************************** #
9970 1.1 is # fp0 = default underflow result #
9971 1.1 is # #
9972 1.1 is # ALGORITHM *********************************************************** #
9973 1.1 is # An underflow should occur as the result of transcendental #
9974 1.1 is # emulation in the 060FPLSP. Create an underflow by using "fmul" #
9975 1.1 is # and two very small numbers of appropriate sign so that the operating #
9976 1.1 is # system can log the event. #
9977 1.1 is # #
9978 1.1 is #########################################################################
9979 1.1 is
9980 1.1 is global t_unfl
9981 1.1 is t_unfl:
9982 1.1 is tst.b SRC_EX(%a0)
9983 1.1 is bpl.b unf_pos
9984 1.1 is
9985 1.1 is global t_unfl2
9986 1.1 is t_unfl2:
9987 1.1 is ori.l &unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
9988 1.1 is
9989 1.1 is fmov.l USER_FPCR(%a6),%fpcr
9990 1.1 is fmovm.x mns_tiny(%pc),&0x80
9991 1.1 is fmul.x pls_tiny(%pc),%fp0
9992 1.1 is
9993 1.1 is fmov.l %fpsr,%d0
9994 1.1 is rol.l &0x8,%d0
9995 1.1 is mov.b %d0,FPSR_CC(%a6)
9996 1.1 is rts
9997 1.1 is unf_pos:
9998 1.1 is ori.w &unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
9999 1.1 is
10000 1.1 is fmov.l USER_FPCR(%a6),%fpcr
10001 1.1 is fmovm.x pls_tiny(%pc),&0x80
10002 1.1 is fmul.x %fp0,%fp0
10003 1.1 is
10004 1.1 is fmov.l %fpsr,%d0
10005 1.1 is rol.l &0x8,%d0
10006 1.1 is mov.b %d0,FPSR_CC(%a6)
10007 1.1 is rts
10008 1.1 is
10009 1.1 is #########################################################################
10010 1.1 is # XDEF **************************************************************** #
10011 1.1 is # t_ovfl(): Handle 060FPLSP overflow exception during emulation. #
10012 1.1 is # (monadic) #
10013 1.1 is # t_ovfl2(): Handle 060FPLSP overflow exception during #
10014 1.1 is # emulation. result always positive. (dyadic) #
10015 1.1 is # t_ovfl_sc(): Handle 060FPLSP overflow exception during #
10016 1.1 is # emulation for "fscale". #
10017 1.1 is # #
10018 1.1 is # This routine is used by the 060FPLSP package. #
10019 1.1 is # #
10020 1.1 is # XREF **************************************************************** #
10021 1.1 is # None. #
10022 1.1 is # #
10023 1.1 is # INPUT *************************************************************** #
10024 1.1 is # a0 = pointer to extended precision source operand #
10025 1.1 is # #
10026 1.1 is # OUTPUT ************************************************************** #
10027 1.1 is # fp0 = default underflow result #
10028 1.1 is # #
10029 1.1 is # ALGORITHM *********************************************************** #
10030 1.1 is # An overflow should occur as the result of transcendental #
10031 1.1 is # emulation in the 060FPLSP. Create an overflow by using "fmul" #
10032 1.1 is # and two very lareg numbers of appropriate sign so that the operating #
10033 1.1 is # system can log the event. #
10034 1.1 is # For t_ovfl_sc() we take special care not to lose the INEX2 bit. #
10035 1.1 is # #
10036 1.1 is #########################################################################
10037 1.1 is
10038 1.1 is global t_ovfl_sc
10039 1.1 is t_ovfl_sc:
10040 1.1 is ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
10041 1.1 is
10042 1.1 is mov.b %d0,%d1 # fetch rnd prec,mode
10043 1.1 is andi.b &0xc0,%d1 # extract prec
10044 1.1 is beq.w ovfl_work
10045 1.1 is
10046 1.1 is # dst op is a DENORM. we have to normalize the mantissa to see if the
10047 1.1 is # result would be inexact for the given precision. make a copy of the
10048 1.1 is # dst so we don't screw up the version passed to us.
10049 1.1 is mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6)
10050 1.1 is mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6)
10051 1.1 is mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6)
10052 1.1 is lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0
10053 1.1 is movm.l &0xc080,-(%sp) # save d0-d1/a0
10054 1.1 is bsr.l norm # normalize mantissa
10055 1.1 is movm.l (%sp)+,&0x0103 # restore d0-d1/a0
10056 1.1 is
10057 1.1 is cmpi.b %d1,&0x40 # is precision sgl?
10058 1.1 is bne.b ovfl_sc_dbl # no; dbl
10059 1.1 is ovfl_sc_sgl:
10060 1.1 is tst.l LOCAL_LO(%a0) # is lo lw of sgl set?
10061 1.1 is bne.b ovfl_sc_inx # yes
10062 1.1 is tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set?
10063 1.1 is bne.b ovfl_sc_inx # yes
10064 1.1 is bra.w ovfl_work # don't set INEX2
10065 1.1 is ovfl_sc_dbl:
10066 1.1 is mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of
10067 1.1 is andi.l &0x7ff,%d1 # dbl mantissa set?
10068 1.1 is beq.w ovfl_work # no; don't set INEX2
10069 1.1 is ovfl_sc_inx:
10070 1.1 is ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2
10071 1.1 is bra.b ovfl_work # continue
10072 1.1 is
10073 1.1 is global t_ovfl
10074 1.1 is t_ovfl:
10075 1.1 is ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
10076 1.1 is ovfl_work:
10077 1.1 is tst.b SRC_EX(%a0)
10078 1.1 is bpl.b ovfl_p
10079 1.1 is ovfl_m:
10080 1.1 is fmov.l USER_FPCR(%a6),%fpcr
10081 1.1 is fmovm.x mns_huge(%pc),&0x80
10082 1.1 is fmul.x pls_huge(%pc),%fp0
10083 1.1 is
10084 1.1 is fmov.l %fpsr,%d0
10085 1.1 is rol.l &0x8,%d0
10086 1.1 is ori.b &neg_mask,%d0
10087 1.1 is mov.b %d0,FPSR_CC(%a6)
10088 1.1 is rts
10089 1.1 is ovfl_p:
10090 1.1 is fmov.l USER_FPCR(%a6),%fpcr
10091 1.1 is fmovm.x pls_huge(%pc),&0x80
10092 1.1 is fmul.x pls_huge(%pc),%fp0
10093 1.1 is
10094 1.1 is fmov.l %fpsr,%d0
10095 1.1 is rol.l &0x8,%d0
10096 1.1 is mov.b %d0,FPSR_CC(%a6)
10097 1.1 is rts
10098 1.1 is
10099 1.1 is global t_ovfl2
10100 1.1 is t_ovfl2:
10101 1.1 is ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
10102 1.1 is fmov.l USER_FPCR(%a6),%fpcr
10103 1.1 is fmovm.x pls_huge(%pc),&0x80
10104 1.1 is fmul.x pls_huge(%pc),%fp0
10105 1.1 is
10106 1.1 is fmov.l %fpsr,%d0
10107 1.1 is rol.l &0x8,%d0
10108 1.1 is mov.b %d0,FPSR_CC(%a6)
10109 1.1 is rts
10110 1.1 is
10111 1.1 is #########################################################################
10112 1.1 is # XDEF **************************************************************** #
10113 1.1 is # t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during #
10114 1.1 is # emulation. #
10115 1.1 is # t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during #
10116 1.1 is # emulation. #
10117 1.1 is # #
10118 1.1 is # These routines are used by the 060FPLSP package. #
10119 1.1 is # #
10120 1.1 is # XREF **************************************************************** #
10121 1.1 is # None. #
10122 1.1 is # #
10123 1.1 is # INPUT *************************************************************** #
10124 1.1 is # fp0 = default underflow or overflow result #
10125 1.1 is # #
10126 1.1 is # OUTPUT ************************************************************** #
10127 1.1 is # fp0 = default result #
10128 1.1 is # #
10129 1.1 is # ALGORITHM *********************************************************** #
10130 1.1 is # If an overflow or underflow occurred during the last #
10131 1.1 is # instruction of transcendental 060FPLSP emulation, then it has already #
10132 1.1 is # occurred and has been logged. Now we need to see if an inexact #
10133 1.1 is # exception should occur. #
10134 1.1 is # #
10135 1.1 is #########################################################################
10136 1.1 is
10137 1.1 is global t_catch2
10138 1.1 is t_catch2:
10139 1.1 is fmov.l %fpsr,%d0
10140 1.1 is or.l %d0,USER_FPSR(%a6)
10141 1.1 is bra.b inx2_work
10142 1.1 is
10143 1.1 is global t_catch
10144 1.1 is t_catch:
10145 1.1 is fmov.l %fpsr,%d0
10146 1.1 is or.l %d0,USER_FPSR(%a6)
10147 1.1 is
10148 1.1 is #########################################################################
10149 1.1 is # XDEF **************************************************************** #
10150 1.1 is # t_inx2(): Handle inexact 060FPLSP exception during emulation. #
10151 1.1 is # t_pinx2(): Handle inexact 060FPLSP exception for "+" results. #
10152 1.1 is # t_minx2(): Handle inexact 060FPLSP exception for "-" results. #
10153 1.1 is # #
10154 1.1 is # XREF **************************************************************** #
10155 1.1 is # None. #
10156 1.1 is # #
10157 1.1 is # INPUT *************************************************************** #
10158 1.1 is # fp0 = default result #
10159 1.1 is # #
10160 1.1 is # OUTPUT ************************************************************** #
10161 1.1 is # fp0 = default result #
10162 1.1 is # #
10163 1.1 is # ALGORITHM *********************************************************** #
10164 1.1 is # The last instruction of transcendental emulation for the #
10165 1.1 is # 060FPLSP should be inexact. So, if inexact is enabled, then we create #
10166 1.1 is # the event here by adding a large and very small number together #
10167 1.1 is # so that the operating system can log the event. #
10168 1.1 is # Must check, too, if the result was zero, in which case we just #
10169 1.1 is # set the FPSR bits and return. #
10170 1.1 is # #
10171 1.1 is #########################################################################
10172 1.1 is
10173 1.1 is global t_inx2
10174 1.1 is t_inx2:
10175 1.1 is fblt.w t_minx2
10176 1.1 is fbeq.w inx2_zero
10177 1.1 is
10178 1.1 is global t_pinx2
10179 1.1 is t_pinx2:
10180 1.1 is ori.w &inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
10181 1.1 is bra.b inx2_work
10182 1.1 is
10183 1.1 is global t_minx2
10184 1.1 is t_minx2:
10185 1.1 is ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6)
10186 1.1 is
10187 1.1 is inx2_work:
10188 1.1 is btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
10189 1.1 is bne.b inx2_work_ena # yes
10190 1.1 is rts
10191 1.1 is inx2_work_ena:
10192 1.1 is fmov.l USER_FPCR(%a6),%fpcr # insert user's exceptions
10193 1.1 is fmov.s &0x3f800000,%fp1 # load +1
10194 1.1 is fadd.x pls_tiny(%pc),%fp1 # cause exception
10195 1.1 is rts
10196 1.1 is
10197 1.1 is inx2_zero:
10198 1.1 is mov.b &z_bmask,FPSR_CC(%a6)
10199 1.1 is ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
10200 1.1 is rts
10201 1.1 is
10202 1.1 is #########################################################################
10203 1.1 is # XDEF **************************************************************** #
10204 1.1 is # t_extdnrm(): Handle DENORM inputs in 060FPLSP. #
10205 1.1 is # t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale". #
10206 1.1 is # #
10207 1.1 is # This routine is used by the 060FPLSP package. #
10208 1.1 is # #
10209 1.1 is # XREF **************************************************************** #
10210 1.1 is # None. #
10211 1.1 is # #
10212 1.1 is # INPUT *************************************************************** #
10213 1.1 is # a0 = pointer to extended precision input operand #
10214 1.1 is # #
10215 1.1 is # OUTPUT ************************************************************** #
10216 1.1 is # fp0 = default result #
10217 1.1 is # #
10218 1.1 is # ALGORITHM *********************************************************** #
10219 1.1 is # For all functions that have a denormalized input and that #
10220 1.1 is # f(x)=x, this is the entry point. #
10221 1.1 is # DENORM value is moved using "fmove" which triggers an exception #
10222 1.1 is # if enabled so the operating system can log the event. #
10223 1.1 is # #
10224 1.1 is #########################################################################
10225 1.1 is
10226 1.1 is global t_extdnrm
10227 1.1 is t_extdnrm:
10228 1.1 is fmov.l USER_FPCR(%a6),%fpcr
10229 1.1 is fmov.x SRC_EX(%a0),%fp0
10230 1.1 is fmov.l %fpsr,%d0
10231 1.1 is ori.l &unfinx_mask,%d0
10232 1.1 is or.l %d0,USER_FPSR(%a6)
10233 1.1 is rts
10234 1.1 is
10235 1.1 is global t_resdnrm
10236 1.1 is t_resdnrm:
10237 1.1 is fmov.l USER_FPCR(%a6),%fpcr
10238 1.1 is fmov.x SRC_EX(%a0),%fp0
10239 1.1 is fmov.l %fpsr,%d0
10240 1.1 is or.l %d0,USER_FPSR(%a6)
10241 1.1 is rts
10242 1.1 is
10243 1.1 is ##########################################
10244 1.1 is
10245 1.1 is #
10246 1.1 is # sto_cos:
10247 1.1 is # This is used by fsincos library emulation. The correct
10248 1.1 is # values are already in fp0 and fp1 so we do nothing here.
10249 1.1 is #
10250 1.1 is global sto_cos
10251 1.1 is sto_cos:
10252 1.1 is rts
10253 1.1 is
10254 1.1 is ##########################################
10255 1.1 is
10256 1.1 is #
10257 1.1 is # dst_qnan --- force result when destination is a NaN
10258 1.1 is #
10259 1.1 is global dst_qnan
10260 1.1 is dst_qnan:
10261 1.1 is fmov.x DST(%a1),%fp0
10262 1.1 is tst.b DST_EX(%a1)
10263 1.1 is bmi.b dst_qnan_m
10264 1.1 is dst_qnan_p:
10265 1.1 is mov.b &nan_bmask,FPSR_CC(%a6)
10266 1.1 is rts
10267 1.1 is dst_qnan_m:
10268 1.1 is mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6)
10269 1.1 is rts
10270 1.1 is
10271 1.1 is #
10272 1.1 is # src_qnan --- force result when source is a NaN
10273 1.1 is #
10274 1.1 is global src_qnan
10275 1.1 is src_qnan:
10276 1.1 is fmov.x SRC(%a0),%fp0
10277 1.1 is tst.b SRC_EX(%a0)
10278 1.1 is bmi.b src_qnan_m
10279 1.1 is src_qnan_p:
10280 1.1 is mov.b &nan_bmask,FPSR_CC(%a6)
10281 1.1 is rts
10282 1.1 is src_qnan_m:
10283 1.1 is mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6)
10284 1.1 is rts
10285 1.1 is
10286 1.1 is ##########################################
10287 1.1 is
10288 1.1 is #
10289 1.1 is # Native instruction support
10290 1.1 is #
10291 1.1 is # Some systems may need entry points even for 68060 native
10292 1.1 is # instructions. These routines are provided for
10293 1.1 is # convenience.
10294 1.1 is #
10295 1.1 is global _fadds_
10296 1.1 is _fadds_:
10297 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10298 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10299 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst
10300 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10301 1.1 is fadd.s 0x8(%sp),%fp0 # fadd w/ sgl src
10302 1.1 is rts
10303 1.1 is
10304 1.1 is global _faddd_
10305 1.1 is _faddd_:
10306 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10307 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10308 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst
10309 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10310 1.1 is fadd.d 0xc(%sp),%fp0 # fadd w/ dbl src
10311 1.1 is rts
10312 1.1 is
10313 1.1 is global _faddx_
10314 1.1 is _faddx_:
10315 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst
10316 1.1 is fadd.x 0x10(%sp),%fp0 # fadd w/ ext src
10317 1.1 is rts
10318 1.1 is
10319 1.1 is global _fsubs_
10320 1.1 is _fsubs_:
10321 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10322 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10323 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst
10324 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10325 1.1 is fsub.s 0x8(%sp),%fp0 # fsub w/ sgl src
10326 1.1 is rts
10327 1.1 is
10328 1.1 is global _fsubd_
10329 1.1 is _fsubd_:
10330 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10331 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10332 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst
10333 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10334 1.1 is fsub.d 0xc(%sp),%fp0 # fsub w/ dbl src
10335 1.1 is rts
10336 1.1 is
10337 1.1 is global _fsubx_
10338 1.1 is _fsubx_:
10339 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst
10340 1.1 is fsub.x 0x10(%sp),%fp0 # fsub w/ ext src
10341 1.1 is rts
10342 1.1 is
10343 1.1 is global _fmuls_
10344 1.1 is _fmuls_:
10345 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10346 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10347 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst
10348 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10349 1.1 is fmul.s 0x8(%sp),%fp0 # fmul w/ sgl src
10350 1.1 is rts
10351 1.1 is
10352 1.1 is global _fmuld_
10353 1.1 is _fmuld_:
10354 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10355 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10356 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst
10357 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10358 1.1 is fmul.d 0xc(%sp),%fp0 # fmul w/ dbl src
10359 1.1 is rts
10360 1.1 is
10361 1.1 is global _fmulx_
10362 1.1 is _fmulx_:
10363 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst
10364 1.1 is fmul.x 0x10(%sp),%fp0 # fmul w/ ext src
10365 1.1 is rts
10366 1.1 is
10367 1.1 is global _fdivs_
10368 1.1 is _fdivs_:
10369 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10370 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10371 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst
10372 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10373 1.1 is fdiv.s 0x8(%sp),%fp0 # fdiv w/ sgl src
10374 1.1 is rts
10375 1.1 is
10376 1.1 is global _fdivd_
10377 1.1 is _fdivd_:
10378 1.1 is fmov.l %fpcr,-(%sp) # save fpcr
10379 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load
10380 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst
10381 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr
10382 1.1 is fdiv.d 0xc(%sp),%fp0 # fdiv w/ dbl src
10383 1.1 is rts
10384 1.1 is
10385 1.1 is global _fdivx_
10386 1.1 is _fdivx_:
10387 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst
10388 1.1 is fdiv.x 0x10(%sp),%fp0 # fdiv w/ ext src
10389 1.1 is rts
10390 1.1 is
10391 1.1 is global _fabss_
10392 1.1 is _fabss_:
10393 1.1 is fabs.s 0x4(%sp),%fp0 # fabs w/ sgl src
10394 1.1 is rts
10395 1.1 is
10396 1.1 is global _fabsd_
10397 1.1 is _fabsd_:
10398 1.1 is fabs.d 0x4(%sp),%fp0 # fabs w/ dbl src
10399 1.1 is rts
10400 1.1 is
10401 1.1 is global _fabsx_
10402 1.1 is _fabsx_:
10403 1.1 is fabs.x 0x4(%sp),%fp0 # fabs w/ ext src
10404 1.1 is rts
10405 1.1 is
10406 1.1 is global _fnegs_
10407 1.1 is _fnegs_:
10408 1.1 is fneg.s 0x4(%sp),%fp0 # fneg w/ sgl src
10409 1.1 is rts
10410 1.1 is
10411 1.1 is global _fnegd_
10412 1.1 is _fnegd_:
10413 1.1 is fneg.d 0x4(%sp),%fp0 # fneg w/ dbl src
10414 1.1 is rts
10415 1.1 is
10416 1.1 is global _fnegx_
10417 1.1 is _fnegx_:
10418 1.1 is fneg.x 0x4(%sp),%fp0 # fneg w/ ext src
10419 1.1 is rts
10420 1.1 is
10421 1.1 is global _fsqrts_
10422 1.1 is _fsqrts_:
10423 1.1 is fsqrt.s 0x4(%sp),%fp0 # fsqrt w/ sgl src
10424 1.1 is rts
10425 1.1 is
10426 1.1 is global _fsqrtd_
10427 1.1 is _fsqrtd_:
10428 1.1 is fsqrt.d 0x4(%sp),%fp0 # fsqrt w/ dbl src
10429 1.1 is rts
10430 1.1 is
10431 1.1 is global _fsqrtx_
10432 1.1 is _fsqrtx_:
10433 1.1 is fsqrt.x 0x4(%sp),%fp0 # fsqrt w/ ext src
10434 1.1 is rts
10435 1.1 is
10436 1.1 is global _fints_
10437 1.1 is _fints_:
10438 1.1 is fint.s 0x4(%sp),%fp0 # fint w/ sgl src
10439 1.1 is rts
10440 1.1 is
10441 1.1 is global _fintd_
10442 1.1 is _fintd_:
10443 1.1 is fint.d 0x4(%sp),%fp0 # fint w/ dbl src
10444 1.1 is rts
10445 1.1 is
10446 1.1 is global _fintx_
10447 1.1 is _fintx_:
10448 1.1 is fint.x 0x4(%sp),%fp0 # fint w/ ext src
10449 1.1 is rts
10450 1.1 is
10451 1.1 is global _fintrzs_
10452 1.1 is _fintrzs_:
10453 1.1 is fintrz.s 0x4(%sp),%fp0 # fintrz w/ sgl src
10454 1.1 is rts
10455 1.1 is
10456 1.1 is global _fintrzd_
10457 1.1 is _fintrzd_:
10458 1.1 is fintrz.d 0x4(%sp),%fp0 # fintrx w/ dbl src
10459 1.1 is rts
10460 1.1 is
10461 1.1 is global _fintrzx_
10462 1.1 is _fintrzx_:
10463 1.1 is fintrz.x 0x4(%sp),%fp0 # fintrz w/ ext src
10464 1.1 is rts
10465 1.1 is
10466 1.1 is ########################################################################
10467 1.1 is
10468 1.1 is #########################################################################
10469 1.1 is # src_zero(): Return signed zero according to sign of src operand. #
10470 1.1 is #########################################################################
10471 1.1 is global src_zero
10472 1.1 is src_zero:
10473 1.1 is tst.b SRC_EX(%a0) # get sign of src operand
10474 1.1 is bmi.b ld_mzero # if neg, load neg zero
10475 1.1 is
10476 1.1 is #
10477 1.1 is # ld_pzero(): return a positive zero.
10478 1.1 is #
10479 1.1 is global ld_pzero
10480 1.1 is ld_pzero:
10481 1.1 is fmov.s &0x00000000,%fp0 # load +0
10482 1.1 is mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
10483 1.1 is rts
10484 1.1 is
10485 1.1 is # ld_mzero(): return a negative zero.
10486 1.1 is global ld_mzero
10487 1.1 is ld_mzero:
10488 1.1 is fmov.s &0x80000000,%fp0 # load -0
10489 1.1 is mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
10490 1.1 is rts
10491 1.1 is
10492 1.1 is #########################################################################
10493 1.1 is # dst_zero(): Return signed zero according to sign of dst operand. #
10494 1.1 is #########################################################################
10495 1.1 is global dst_zero
10496 1.1 is dst_zero:
10497 1.1 is tst.b DST_EX(%a1) # get sign of dst operand
10498 1.1 is bmi.b ld_mzero # if neg, load neg zero
10499 1.1 is bra.b ld_pzero # load positive zero
10500 1.1 is
10501 1.1 is #########################################################################
10502 1.1 is # src_inf(): Return signed inf according to sign of src operand. #
10503 1.1 is #########################################################################
10504 1.1 is global src_inf
10505 1.1 is src_inf:
10506 1.1 is tst.b SRC_EX(%a0) # get sign of src operand
10507 1.1 is bmi.b ld_minf # if negative branch
10508 1.1 is
10509 1.1 is #
10510 1.1 is # ld_pinf(): return a positive infinity.
10511 1.1 is #
10512 1.1 is global ld_pinf
10513 1.1 is ld_pinf:
10514 1.1 is fmov.s &0x7f800000,%fp0 # load +INF
10515 1.1 is mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit
10516 1.1 is rts
10517 1.1 is
10518 1.1 is #
10519 1.1 is # ld_minf():return a negative infinity.
10520 1.1 is #
10521 1.1 is global ld_minf
10522 1.1 is ld_minf:
10523 1.1 is fmov.s &0xff800000,%fp0 # load -INF
10524 1.1 is mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
10525 1.1 is rts
10526 1.1 is
10527 1.1 is #########################################################################
10528 1.1 is # dst_inf(): Return signed inf according to sign of dst operand. #
10529 1.1 is #########################################################################
10530 1.1 is global dst_inf
10531 1.1 is dst_inf:
10532 1.1 is tst.b DST_EX(%a1) # get sign of dst operand
10533 1.1 is bmi.b ld_minf # if negative branch
10534 1.1 is bra.b ld_pinf
10535 1.1 is
10536 1.1 is global szr_inf
10537 1.1 is #################################################################
10538 1.1 is # szr_inf(): Return +ZERO for a negative src operand or #
10539 1.1 is # +INF for a positive src operand. #
10540 1.1 is # Routine used for fetox, ftwotox, and ftentox. #
10541 1.1 is #################################################################
10542 1.1 is szr_inf:
10543 1.1 is tst.b SRC_EX(%a0) # check sign of source
10544 1.1 is bmi.b ld_pzero
10545 1.1 is bra.b ld_pinf
10546 1.1 is
10547 1.1 is #########################################################################
10548 1.1 is # sopr_inf(): Return +INF for a positive src operand or #
10549 1.1 is # jump to operand error routine for a negative src operand. #
10550 1.1 is # Routine used for flogn, flognp1, flog10, and flog2. #
10551 1.1 is #########################################################################
10552 1.1 is global sopr_inf
10553 1.1 is sopr_inf:
10554 1.1 is tst.b SRC_EX(%a0) # check sign of source
10555 1.1 is bmi.w t_operr
10556 1.1 is bra.b ld_pinf
10557 1.1 is
10558 1.1 is #################################################################
10559 1.1 is # setoxm1i(): Return minus one for a negative src operand or #
10560 1.1 is # positive infinity for a positive src operand. #
10561 1.1 is # Routine used for fetoxm1. #
10562 1.1 is #################################################################
10563 1.1 is global setoxm1i
10564 1.1 is setoxm1i:
10565 1.1 is tst.b SRC_EX(%a0) # check sign of source
10566 1.1 is bmi.b ld_mone
10567 1.1 is bra.b ld_pinf
10568 1.1 is
10569 1.1 is #########################################################################
10570 1.1 is # src_one(): Return signed one according to sign of src operand. #
10571 1.1 is #########################################################################
10572 1.1 is global src_one
10573 1.1 is src_one:
10574 1.1 is tst.b SRC_EX(%a0) # check sign of source
10575 1.1 is bmi.b ld_mone
10576 1.1 is
10577 1.1 is #
10578 1.1 is # ld_pone(): return positive one.
10579 1.1 is #
10580 1.1 is global ld_pone
10581 1.1 is ld_pone:
10582 1.1 is fmov.s &0x3f800000,%fp0 # load +1
10583 1.1 is clr.b FPSR_CC(%a6)
10584 1.1 is rts
10585 1.1 is
10586 1.1 is #
10587 1.1 is # ld_mone(): return negative one.
10588 1.1 is #
10589 1.1 is global ld_mone
10590 1.1 is ld_mone:
10591 1.1 is fmov.s &0xbf800000,%fp0 # load -1
10592 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
10593 1.1 is rts
10594 1.1 is
10595 1.1 is ppiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235
10596 1.1 is mpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235
10597 1.1 is
10598 1.1 is #################################################################
10599 1.1 is # spi_2(): Return signed PI/2 according to sign of src operand. #
10600 1.1 is #################################################################
10601 1.1 is global spi_2
10602 1.1 is spi_2:
10603 1.1 is tst.b SRC_EX(%a0) # check sign of source
10604 1.1 is bmi.b ld_mpi2
10605 1.1 is
10606 1.1 is #
10607 1.1 is # ld_ppi2(): return positive PI/2.
10608 1.1 is #
10609 1.1 is global ld_ppi2
10610 1.1 is ld_ppi2:
10611 1.1 is fmov.l %d0,%fpcr
10612 1.1 is fmov.x ppiby2(%pc),%fp0 # load +pi/2
10613 1.1 is bra.w t_pinx2 # set INEX2
10614 1.1 is
10615 1.1 is #
10616 1.1 is # ld_mpi2(): return negative PI/2.
10617 1.1 is #
10618 1.1 is global ld_mpi2
10619 1.1 is ld_mpi2:
10620 1.1 is fmov.l %d0,%fpcr
10621 1.1 is fmov.x mpiby2(%pc),%fp0 # load -pi/2
10622 1.1 is bra.w t_minx2 # set INEX2
10623 1.1 is
10624 1.1 is ####################################################
10625 1.1 is # The following routines give support for fsincos. #
10626 1.1 is ####################################################
10627 1.1 is
10628 1.1 is #
10629 1.1 is # ssincosz(): When the src operand is ZERO, store a one in the
10630 1.1 is # cosine register and return a ZERO in fp0 w/ the same sign
10631 1.1 is # as the src operand.
10632 1.1 is #
10633 1.1 is global ssincosz
10634 1.1 is ssincosz:
10635 1.1 is fmov.s &0x3f800000,%fp1
10636 1.1 is tst.b SRC_EX(%a0) # test sign
10637 1.1 is bpl.b sincoszp
10638 1.1 is fmov.s &0x80000000,%fp0 # return sin result in fp0
10639 1.1 is mov.b &z_bmask+neg_bmask,FPSR_CC(%a6)
10640 1.1 is rts
10641 1.1 is sincoszp:
10642 1.1 is fmov.s &0x00000000,%fp0 # return sin result in fp0
10643 1.1 is mov.b &z_bmask,FPSR_CC(%a6)
10644 1.1 is rts
10645 1.1 is
10646 1.1 is #
10647 1.1 is # ssincosi(): When the src operand is INF, store a QNAN in the cosine
10648 1.1 is # register and jump to the operand error routine for negative
10649 1.1 is # src operands.
10650 1.1 is #
10651 1.1 is global ssincosi
10652 1.1 is ssincosi:
10653 1.1 is fmov.x qnan(%pc),%fp1 # load NAN
10654 1.1 is bra.w t_operr
10655 1.1 is
10656 1.1 is #
10657 1.1 is # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
10658 1.1 is # register and branch to the src QNAN routine.
10659 1.1 is #
10660 1.1 is global ssincosqnan
10661 1.1 is ssincosqnan:
10662 1.1 is fmov.x LOCAL_EX(%a0),%fp1
10663 1.1 is bra.w src_qnan
10664 1.1 is
10665 1.1 is ########################################################################
10666 1.1 is
10667 1.1 is global smod_sdnrm
10668 1.1 is global smod_snorm
10669 1.1 is smod_sdnrm:
10670 1.1 is smod_snorm:
10671 1.1 is mov.b DTAG(%a6),%d1
10672 1.1 is beq.l smod
10673 1.1 is cmpi.b %d1,&ZERO
10674 1.1 is beq.w smod_zro
10675 1.1 is cmpi.b %d1,&INF
10676 1.1 is beq.l t_operr
10677 1.1 is cmpi.b %d1,&DENORM
10678 1.1 is beq.l smod
10679 1.1 is bra.l dst_qnan
10680 1.1 is
10681 1.1 is global smod_szero
10682 1.1 is smod_szero:
10683 1.1 is mov.b DTAG(%a6),%d1
10684 1.1 is beq.l t_operr
10685 1.1 is cmpi.b %d1,&ZERO
10686 1.1 is beq.l t_operr
10687 1.1 is cmpi.b %d1,&INF
10688 1.1 is beq.l t_operr
10689 1.1 is cmpi.b %d1,&DENORM
10690 1.1 is beq.l t_operr
10691 1.1 is bra.l dst_qnan
10692 1.1 is
10693 1.1 is global smod_sinf
10694 1.1 is smod_sinf:
10695 1.1 is mov.b DTAG(%a6),%d1
10696 1.1 is beq.l smod_fpn
10697 1.1 is cmpi.b %d1,&ZERO
10698 1.1 is beq.l smod_zro
10699 1.1 is cmpi.b %d1,&INF
10700 1.1 is beq.l t_operr
10701 1.1 is cmpi.b %d1,&DENORM
10702 1.1 is beq.l smod_fpn
10703 1.1 is bra.l dst_qnan
10704 1.1 is
10705 1.1 is smod_zro:
10706 1.1 is srem_zro:
10707 1.1 is mov.b SRC_EX(%a0),%d1 # get src sign
10708 1.1 is mov.b DST_EX(%a1),%d0 # get dst sign
10709 1.1 is eor.b %d0,%d1 # get qbyte sign
10710 1.1 is andi.b &0x80,%d1
10711 1.1 is mov.b %d1,FPSR_QBYTE(%a6)
10712 1.1 is tst.b %d0
10713 1.1 is bpl.w ld_pzero
10714 1.1 is bra.w ld_mzero
10715 1.1 is
10716 1.1 is smod_fpn:
10717 1.1 is srem_fpn:
10718 1.1 is clr.b FPSR_QBYTE(%a6)
10719 1.1 is mov.l %d0,-(%sp)
10720 1.1 is mov.b SRC_EX(%a0),%d1 # get src sign
10721 1.1 is mov.b DST_EX(%a1),%d0 # get dst sign
10722 1.1 is eor.b %d0,%d1 # get qbyte sign
10723 1.1 is andi.b &0x80,%d1
10724 1.1 is mov.b %d1,FPSR_QBYTE(%a6)
10725 1.1 is cmpi.b DTAG(%a6),&DENORM
10726 1.1 is bne.b smod_nrm
10727 1.1 is lea DST(%a1),%a0
10728 1.1 is mov.l (%sp)+,%d0
10729 1.1 is bra t_resdnrm
10730 1.1 is smod_nrm:
10731 1.1 is fmov.l (%sp)+,%fpcr
10732 1.1 is fmov.x DST(%a1),%fp0
10733 1.1 is tst.b DST_EX(%a1)
10734 1.1 is bmi.b smod_nrm_neg
10735 1.1 is rts
10736 1.1 is
10737 1.1 is smod_nrm_neg:
10738 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' code
10739 1.1 is rts
10740 1.1 is
10741 1.1 is #########################################################################
10742 1.1 is global srem_snorm
10743 1.1 is global srem_sdnrm
10744 1.1 is srem_sdnrm:
10745 1.1 is srem_snorm:
10746 1.1 is mov.b DTAG(%a6),%d1
10747 1.1 is beq.l srem
10748 1.1 is cmpi.b %d1,&ZERO
10749 1.1 is beq.w srem_zro
10750 1.1 is cmpi.b %d1,&INF
10751 1.1 is beq.l t_operr
10752 1.1 is cmpi.b %d1,&DENORM
10753 1.1 is beq.l srem
10754 1.1 is bra.l dst_qnan
10755 1.1 is
10756 1.1 is global srem_szero
10757 1.1 is srem_szero:
10758 1.1 is mov.b DTAG(%a6),%d1
10759 1.1 is beq.l t_operr
10760 1.1 is cmpi.b %d1,&ZERO
10761 1.1 is beq.l t_operr
10762 1.1 is cmpi.b %d1,&INF
10763 1.1 is beq.l t_operr
10764 1.1 is cmpi.b %d1,&DENORM
10765 1.1 is beq.l t_operr
10766 1.1 is bra.l dst_qnan
10767 1.1 is
10768 1.1 is global srem_sinf
10769 1.1 is srem_sinf:
10770 1.1 is mov.b DTAG(%a6),%d1
10771 1.1 is beq.w srem_fpn
10772 1.1 is cmpi.b %d1,&ZERO
10773 1.1 is beq.w srem_zro
10774 1.1 is cmpi.b %d1,&INF
10775 1.1 is beq.l t_operr
10776 1.1 is cmpi.b %d1,&DENORM
10777 1.1 is beq.l srem_fpn
10778 1.1 is bra.l dst_qnan
10779 1.1 is
10780 1.1 is #########################################################################
10781 1.1 is
10782 1.1 is global sscale_snorm
10783 1.1 is global sscale_sdnrm
10784 1.1 is sscale_snorm:
10785 1.1 is sscale_sdnrm:
10786 1.1 is mov.b DTAG(%a6),%d1
10787 1.1 is beq.l sscale
10788 1.1 is cmpi.b %d1,&ZERO
10789 1.1 is beq.l dst_zero
10790 1.1 is cmpi.b %d1,&INF
10791 1.1 is beq.l dst_inf
10792 1.1 is cmpi.b %d1,&DENORM
10793 1.1 is beq.l sscale
10794 1.1 is bra.l dst_qnan
10795 1.1 is
10796 1.1 is global sscale_szero
10797 1.1 is sscale_szero:
10798 1.1 is mov.b DTAG(%a6),%d1
10799 1.1 is beq.l sscale
10800 1.1 is cmpi.b %d1,&ZERO
10801 1.1 is beq.l dst_zero
10802 1.1 is cmpi.b %d1,&INF
10803 1.1 is beq.l dst_inf
10804 1.1 is cmpi.b %d1,&DENORM
10805 1.1 is beq.l sscale
10806 1.1 is bra.l dst_qnan
10807 1.1 is
10808 1.1 is global sscale_sinf
10809 1.1 is sscale_sinf:
10810 1.1 is mov.b DTAG(%a6),%d1
10811 1.1 is beq.l t_operr
10812 1.1 is cmpi.b %d1,&QNAN
10813 1.1 is beq.l dst_qnan
10814 1.1 is bra.l t_operr
10815 1.1 is
10816 1.1 is ########################################################################
10817 1.1 is
10818 1.1 is global sop_sqnan
10819 1.1 is sop_sqnan:
10820 1.1 is mov.b DTAG(%a6),%d1
10821 1.1 is cmpi.b %d1,&QNAN
10822 1.1 is beq.l dst_qnan
10823 1.1 is bra.l src_qnan
10824 1.1 is
10825 1.1 is #########################################################################
10826 1.1 is # norm(): normalize the mantissa of an extended precision input. the #
10827 1.1 is # input operand should not be normalized already. #
10828 1.1 is # #
10829 1.1 is # XDEF **************************************************************** #
10830 1.1 is # norm() #
10831 1.1 is # #
10832 1.1 is # XREF **************************************************************** #
10833 1.1 is # none #
10834 1.1 is # #
10835 1.1 is # INPUT *************************************************************** #
10836 1.1 is # a0 = pointer fp extended precision operand to normalize #
10837 1.1 is # #
10838 1.1 is # OUTPUT ************************************************************** #
10839 1.1 is # d0 = number of bit positions the mantissa was shifted #
10840 1.1 is # a0 = the input operand's mantissa is normalized; the exponent #
10841 1.1 is # is unchanged. #
10842 1.1 is # #
10843 1.1 is #########################################################################
10844 1.1 is global norm
10845 1.1 is norm:
10846 1.1 is mov.l %d2, -(%sp) # create some temp regs
10847 1.1 is mov.l %d3, -(%sp)
10848 1.1 is
10849 1.1 is mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa)
10850 1.1 is mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa)
10851 1.1 is
10852 1.1 is bfffo %d0{&0:&32}, %d2 # how many places to shift?
10853 1.1 is beq.b norm_lo # hi(man) is all zeroes!
10854 1.1 is
10855 1.1 is norm_hi:
10856 1.1 is lsl.l %d2, %d0 # left shift hi(man)
10857 1.1 is bfextu %d1{&0:%d2}, %d3 # extract lo bits
10858 1.1 is
10859 1.1 is or.l %d3, %d0 # create hi(man)
10860 1.1 is lsl.l %d2, %d1 # create lo(man)
10861 1.1 is
10862 1.1 is mov.l %d0, FTEMP_HI(%a0) # store new hi(man)
10863 1.1 is mov.l %d1, FTEMP_LO(%a0) # store new lo(man)
10864 1.1 is
10865 1.1 is mov.l %d2, %d0 # return shift amount
10866 1.1 is
10867 1.1 is mov.l (%sp)+, %d3 # restore temp regs
10868 1.1 is mov.l (%sp)+, %d2
10869 1.1 is
10870 1.1 is rts
10871 1.1 is
10872 1.1 is norm_lo:
10873 1.1 is bfffo %d1{&0:&32}, %d2 # how many places to shift?
10874 1.1 is lsl.l %d2, %d1 # shift lo(man)
10875 1.1 is add.l &32, %d2 # add 32 to shft amount
10876 1.1 is
10877 1.1 is mov.l %d1, FTEMP_HI(%a0) # store hi(man)
10878 1.1 is clr.l FTEMP_LO(%a0) # lo(man) is now zero
10879 1.1 is
10880 1.1 is mov.l %d2, %d0 # return shift amount
10881 1.1 is
10882 1.1 is mov.l (%sp)+, %d3 # restore temp regs
10883 1.1 is mov.l (%sp)+, %d2
10884 1.1 is
10885 1.1 is rts
10886 1.1 is
10887 1.1 is #########################################################################
10888 1.1 is # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO #
10889 1.1 is # - returns corresponding optype tag #
10890 1.1 is # #
10891 1.1 is # XDEF **************************************************************** #
10892 1.1 is # unnorm_fix() #
10893 1.1 is # #
10894 1.1 is # XREF **************************************************************** #
10895 1.1 is # norm() - normalize the mantissa #
10896 1.1 is # #
10897 1.1 is # INPUT *************************************************************** #
10898 1.1 is # a0 = pointer to unnormalized extended precision number #
10899 1.1 is # #
10900 1.1 is # OUTPUT ************************************************************** #
10901 1.1 is # d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO #
10902 1.1 is # a0 = input operand has been converted to a norm, denorm, or #
10903 1.1 is # zero; both the exponent and mantissa are changed. #
10904 1.1 is # #
10905 1.1 is #########################################################################
10906 1.1 is
10907 1.1 is global unnorm_fix
10908 1.1 is unnorm_fix:
10909 1.1 is bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
10910 1.1 is bne.b unnorm_shift # hi(man) is not all zeroes
10911 1.1 is
10912 1.1 is #
10913 1.1 is # hi(man) is all zeroes so see if any bits in lo(man) are set
10914 1.1 is #
10915 1.1 is unnorm_chk_lo:
10916 1.1 is bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
10917 1.1 is beq.w unnorm_zero # yes
10918 1.1 is
10919 1.1 is add.w &32, %d0 # no; fix shift distance
10920 1.1 is
10921 1.1 is #
10922 1.1 is # d0 = # shifts needed for complete normalization
10923 1.1 is #
10924 1.1 is unnorm_shift:
10925 1.1 is clr.l %d1 # clear top word
10926 1.1 is mov.w FTEMP_EX(%a0), %d1 # extract exponent
10927 1.1 is and.w &0x7fff, %d1 # strip off sgn
10928 1.1 is
10929 1.1 is cmp.w %d0, %d1 # will denorm push exp < 0?
10930 1.1 is bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0
10931 1.1 is
10932 1.1 is #
10933 1.1 is # exponent would not go < 0. therefore, number stays normalized
10934 1.1 is #
10935 1.1 is sub.w %d0, %d1 # shift exponent value
10936 1.1 is mov.w FTEMP_EX(%a0), %d0 # load old exponent
10937 1.1 is and.w &0x8000, %d0 # save old sign
10938 1.1 is or.w %d0, %d1 # {sgn,new exp}
10939 1.1 is mov.w %d1, FTEMP_EX(%a0) # insert new exponent
10940 1.1 is
10941 1.1 is bsr.l norm # normalize UNNORM
10942 1.1 is
10943 1.1 is mov.b &NORM, %d0 # return new optype tag
10944 1.1 is rts
10945 1.1 is
10946 1.1 is #
10947 1.1 is # exponent would go < 0, so only denormalize until exp = 0
10948 1.1 is #
10949 1.1 is unnorm_nrm_zero:
10950 1.1 is cmp.b %d1, &32 # is exp <= 32?
10951 1.1 is bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent
10952 1.1 is
10953 1.1 is bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
10954 1.1 is mov.l %d0, FTEMP_HI(%a0) # save new hi(man)
10955 1.1 is
10956 1.1 is mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man)
10957 1.1 is lsl.l %d1, %d0 # extract new lo(man)
10958 1.1 is mov.l %d0, FTEMP_LO(%a0) # save new lo(man)
10959 1.1 is
10960 1.1 is and.w &0x8000, FTEMP_EX(%a0) # set exp = 0
10961 1.1 is
10962 1.1 is mov.b &DENORM, %d0 # return new optype tag
10963 1.1 is rts
10964 1.1 is
10965 1.1 is #
10966 1.1 is # only mantissa bits set are in lo(man)
10967 1.1 is #
10968 1.1 is unnorm_nrm_zero_lrg:
10969 1.1 is sub.w &32, %d1 # adjust shft amt by 32
10970 1.1 is
10971 1.1 is mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man)
10972 1.1 is lsl.l %d1, %d0 # left shift lo(man)
10973 1.1 is
10974 1.1 is mov.l %d0, FTEMP_HI(%a0) # store new hi(man)
10975 1.1 is clr.l FTEMP_LO(%a0) # lo(man) = 0
10976 1.1 is
10977 1.1 is and.w &0x8000, FTEMP_EX(%a0) # set exp = 0
10978 1.1 is
10979 1.1 is mov.b &DENORM, %d0 # return new optype tag
10980 1.1 is rts
10981 1.1 is
10982 1.1 is #
10983 1.1 is # whole mantissa is zero so this UNNORM is actually a zero
10984 1.1 is #
10985 1.1 is unnorm_zero:
10986 1.1 is and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero
10987 1.1 is
10988 1.1 is mov.b &ZERO, %d0 # fix optype tag
10989 1.1 is rts
10990