xref: /openbmc/linux/arch/m68k/ifpsp060/src/fplsp.S (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
3 M68000 Hi-Performance Microprocessor Division
4 M68060 Software Package
5 Production Release P1.00 -- October 10, 1994
6 
7 M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
8 
9 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
10 To the maximum extent permitted by applicable law,
11 MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
12 INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
13 and any warranty against infringement with regard to the SOFTWARE
14 (INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
15 
16 To the maximum extent permitted by applicable law,
17 IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
18 (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
19 BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
20 ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
21 Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
22 
23 You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
24 so long as this entire notice is retained without alteration in any modified and/or
25 redistributed versions, and that such modified versions are clearly identified as such.
26 No licenses are granted by implication, estoppel or otherwise under any patents
27 or trademarks of Motorola, Inc.
28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29 #
30 # lfptop.s:
31 #	This file is appended to the top of the 060ILSP package
32 # and contains the entry points into the package. The user, in
33 # effect, branches to one of the branch table entries located here.
34 #
35 
36 	bra.l	_facoss_
37 	short	0x0000
38 	bra.l	_facosd_
39 	short	0x0000
40 	bra.l	_facosx_
41 	short	0x0000
42 
43 	bra.l	_fasins_
44 	short	0x0000
45 	bra.l	_fasind_
46 	short	0x0000
47 	bra.l	_fasinx_
48 	short	0x0000
49 
50 	bra.l	_fatans_
51 	short	0x0000
52 	bra.l	_fatand_
53 	short	0x0000
54 	bra.l	_fatanx_
55 	short	0x0000
56 
57 	bra.l	_fatanhs_
58 	short	0x0000
59 	bra.l	_fatanhd_
60 	short	0x0000
61 	bra.l	_fatanhx_
62 	short	0x0000
63 
64 	bra.l	_fcoss_
65 	short	0x0000
66 	bra.l	_fcosd_
67 	short	0x0000
68 	bra.l	_fcosx_
69 	short	0x0000
70 
71 	bra.l	_fcoshs_
72 	short	0x0000
73 	bra.l	_fcoshd_
74 	short	0x0000
75 	bra.l	_fcoshx_
76 	short	0x0000
77 
78 	bra.l	_fetoxs_
79 	short	0x0000
80 	bra.l	_fetoxd_
81 	short	0x0000
82 	bra.l	_fetoxx_
83 	short	0x0000
84 
85 	bra.l	_fetoxm1s_
86 	short	0x0000
87 	bra.l	_fetoxm1d_
88 	short	0x0000
89 	bra.l	_fetoxm1x_
90 	short	0x0000
91 
92 	bra.l	_fgetexps_
93 	short	0x0000
94 	bra.l	_fgetexpd_
95 	short	0x0000
96 	bra.l	_fgetexpx_
97 	short	0x0000
98 
99 	bra.l	_fgetmans_
100 	short	0x0000
101 	bra.l	_fgetmand_
102 	short	0x0000
103 	bra.l	_fgetmanx_
104 	short	0x0000
105 
106 	bra.l	_flog10s_
107 	short	0x0000
108 	bra.l	_flog10d_
109 	short	0x0000
110 	bra.l	_flog10x_
111 	short	0x0000
112 
113 	bra.l	_flog2s_
114 	short	0x0000
115 	bra.l	_flog2d_
116 	short	0x0000
117 	bra.l	_flog2x_
118 	short	0x0000
119 
120 	bra.l	_flogns_
121 	short	0x0000
122 	bra.l	_flognd_
123 	short	0x0000
124 	bra.l	_flognx_
125 	short	0x0000
126 
127 	bra.l	_flognp1s_
128 	short	0x0000
129 	bra.l	_flognp1d_
130 	short	0x0000
131 	bra.l	_flognp1x_
132 	short	0x0000
133 
134 	bra.l	_fmods_
135 	short	0x0000
136 	bra.l	_fmodd_
137 	short	0x0000
138 	bra.l	_fmodx_
139 	short	0x0000
140 
141 	bra.l	_frems_
142 	short	0x0000
143 	bra.l	_fremd_
144 	short	0x0000
145 	bra.l	_fremx_
146 	short	0x0000
147 
148 	bra.l	_fscales_
149 	short	0x0000
150 	bra.l	_fscaled_
151 	short	0x0000
152 	bra.l	_fscalex_
153 	short	0x0000
154 
155 	bra.l	_fsins_
156 	short	0x0000
157 	bra.l	_fsind_
158 	short	0x0000
159 	bra.l	_fsinx_
160 	short	0x0000
161 
162 	bra.l	_fsincoss_
163 	short	0x0000
164 	bra.l	_fsincosd_
165 	short	0x0000
166 	bra.l	_fsincosx_
167 	short	0x0000
168 
169 	bra.l	_fsinhs_
170 	short	0x0000
171 	bra.l	_fsinhd_
172 	short	0x0000
173 	bra.l	_fsinhx_
174 	short	0x0000
175 
176 	bra.l	_ftans_
177 	short	0x0000
178 	bra.l	_ftand_
179 	short	0x0000
180 	bra.l	_ftanx_
181 	short	0x0000
182 
183 	bra.l	_ftanhs_
184 	short	0x0000
185 	bra.l	_ftanhd_
186 	short	0x0000
187 	bra.l	_ftanhx_
188 	short	0x0000
189 
190 	bra.l	_ftentoxs_
191 	short	0x0000
192 	bra.l	_ftentoxd_
193 	short	0x0000
194 	bra.l	_ftentoxx_
195 	short	0x0000
196 
197 	bra.l	_ftwotoxs_
198 	short	0x0000
199 	bra.l	_ftwotoxd_
200 	short	0x0000
201 	bra.l	_ftwotoxx_
202 	short	0x0000
203 
204 	bra.l	_fabss_
205 	short	0x0000
206 	bra.l	_fabsd_
207 	short	0x0000
208 	bra.l	_fabsx_
209 	short	0x0000
210 
211 	bra.l	_fadds_
212 	short	0x0000
213 	bra.l	_faddd_
214 	short	0x0000
215 	bra.l	_faddx_
216 	short	0x0000
217 
218 	bra.l	_fdivs_
219 	short	0x0000
220 	bra.l	_fdivd_
221 	short	0x0000
222 	bra.l	_fdivx_
223 	short	0x0000
224 
225 	bra.l	_fints_
226 	short	0x0000
227 	bra.l	_fintd_
228 	short	0x0000
229 	bra.l	_fintx_
230 	short	0x0000
231 
232 	bra.l	_fintrzs_
233 	short	0x0000
234 	bra.l	_fintrzd_
235 	short	0x0000
236 	bra.l	_fintrzx_
237 	short	0x0000
238 
239 	bra.l	_fmuls_
240 	short	0x0000
241 	bra.l	_fmuld_
242 	short	0x0000
243 	bra.l	_fmulx_
244 	short	0x0000
245 
246 	bra.l	_fnegs_
247 	short	0x0000
248 	bra.l	_fnegd_
249 	short	0x0000
250 	bra.l	_fnegx_
251 	short	0x0000
252 
253 	bra.l	_fsqrts_
254 	short	0x0000
255 	bra.l	_fsqrtd_
256 	short	0x0000
257 	bra.l	_fsqrtx_
258 	short	0x0000
259 
260 	bra.l	_fsubs_
261 	short	0x0000
262 	bra.l	_fsubd_
263 	short	0x0000
264 	bra.l	_fsubx_
265 	short	0x0000
266 
267 # leave room for future possible additions
268 	align	0x400
269 
270 #
271 # This file contains a set of define statements for constants
272 # in order to promote readability within the corecode itself.
273 #
274 
275 set LOCAL_SIZE,		192			# stack frame size(bytes)
276 set LV,			-LOCAL_SIZE		# stack offset
277 
278 set EXC_SR,		0x4			# stack status register
279 set EXC_PC,		0x6			# stack pc
280 set EXC_VOFF,		0xa			# stacked vector offset
281 set EXC_EA,		0xc			# stacked <ea>
282 
283 set EXC_FP,		0x0			# frame pointer
284 
285 set EXC_AREGS,		-68			# offset of all address regs
286 set EXC_DREGS,		-100			# offset of all data regs
287 set EXC_FPREGS,		-36			# offset of all fp regs
288 
289 set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
290 set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
291 set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
292 set EXC_A5,		EXC_AREGS+(5*4)
293 set EXC_A4,		EXC_AREGS+(4*4)
294 set EXC_A3,		EXC_AREGS+(3*4)
295 set EXC_A2,		EXC_AREGS+(2*4)
296 set EXC_A1,		EXC_AREGS+(1*4)
297 set EXC_A0,		EXC_AREGS+(0*4)
298 set EXC_D7,		EXC_DREGS+(7*4)
299 set EXC_D6,		EXC_DREGS+(6*4)
300 set EXC_D5,		EXC_DREGS+(5*4)
301 set EXC_D4,		EXC_DREGS+(4*4)
302 set EXC_D3,		EXC_DREGS+(3*4)
303 set EXC_D2,		EXC_DREGS+(2*4)
304 set EXC_D1,		EXC_DREGS+(1*4)
305 set EXC_D0,		EXC_DREGS+(0*4)
306 
307 set EXC_FP0,		EXC_FPREGS+(0*12)	# offset of saved fp0
308 set EXC_FP1,		EXC_FPREGS+(1*12)	# offset of saved fp1
309 set EXC_FP2,		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
310 
311 set FP_SCR1,		LV+80			# fp scratch 1
312 set FP_SCR1_EX,		FP_SCR1+0
313 set FP_SCR1_SGN,	FP_SCR1+2
314 set FP_SCR1_HI,		FP_SCR1+4
315 set FP_SCR1_LO,		FP_SCR1+8
316 
317 set FP_SCR0,		LV+68			# fp scratch 0
318 set FP_SCR0_EX,		FP_SCR0+0
319 set FP_SCR0_SGN,	FP_SCR0+2
320 set FP_SCR0_HI,		FP_SCR0+4
321 set FP_SCR0_LO,		FP_SCR0+8
322 
323 set FP_DST,		LV+56			# fp destination operand
324 set FP_DST_EX,		FP_DST+0
325 set FP_DST_SGN,		FP_DST+2
326 set FP_DST_HI,		FP_DST+4
327 set FP_DST_LO,		FP_DST+8
328 
329 set FP_SRC,		LV+44			# fp source operand
330 set FP_SRC_EX,		FP_SRC+0
331 set FP_SRC_SGN,		FP_SRC+2
332 set FP_SRC_HI,		FP_SRC+4
333 set FP_SRC_LO,		FP_SRC+8
334 
335 set USER_FPIAR,		LV+40			# FP instr address register
336 
337 set USER_FPSR,		LV+36			# FP status register
338 set FPSR_CC,		USER_FPSR+0		# FPSR condition codes
339 set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
340 set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
341 set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
342 
343 set USER_FPCR,		LV+32			# FP control register
344 set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
345 set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
346 
347 set L_SCR3,		LV+28			# integer scratch 3
348 set L_SCR2,		LV+24			# integer scratch 2
349 set L_SCR1,		LV+20			# integer scratch 1
350 
351 set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
352 
353 set EXC_TEMP2,		LV+24			# temporary space
354 set EXC_TEMP,		LV+16			# temporary space
355 
356 set DTAG,		LV+15			# destination operand type
357 set STAG,		LV+14			# source operand type
358 
359 set SPCOND_FLG,		LV+10			# flag: special case (see below)
360 
361 set EXC_CC,		LV+8			# saved condition codes
362 set EXC_EXTWPTR,	LV+4			# saved current PC (active)
363 set EXC_EXTWORD,	LV+2			# saved extension word
364 set EXC_CMDREG,		LV+2			# saved extension word
365 set EXC_OPWORD,		LV+0			# saved operation word
366 
367 ################################
368 
369 # Helpful macros
370 
371 set FTEMP,		0			# offsets within an
372 set FTEMP_EX,		0			# extended precision
373 set FTEMP_SGN,		2			# value saved in memory.
374 set FTEMP_HI,		4
375 set FTEMP_LO,		8
376 set FTEMP_GRS,		12
377 
378 set LOCAL,		0			# offsets within an
379 set LOCAL_EX,		0			# extended precision
380 set LOCAL_SGN,		2			# value saved in memory.
381 set LOCAL_HI,		4
382 set LOCAL_LO,		8
383 set LOCAL_GRS,		12
384 
385 set DST,		0			# offsets within an
386 set DST_EX,		0			# extended precision
387 set DST_HI,		4			# value saved in memory.
388 set DST_LO,		8
389 
390 set SRC,		0			# offsets within an
391 set SRC_EX,		0			# extended precision
392 set SRC_HI,		4			# value saved in memory.
393 set SRC_LO,		8
394 
395 set SGL_LO,		0x3f81			# min sgl prec exponent
396 set SGL_HI,		0x407e			# max sgl prec exponent
397 set DBL_LO,		0x3c01			# min dbl prec exponent
398 set DBL_HI,		0x43fe			# max dbl prec exponent
399 set EXT_LO,		0x0			# min ext prec exponent
400 set EXT_HI,		0x7ffe			# max ext prec exponent
401 
402 set EXT_BIAS,		0x3fff			# extended precision bias
403 set SGL_BIAS,		0x007f			# single precision bias
404 set DBL_BIAS,		0x03ff			# double precision bias
405 
406 set NORM,		0x00			# operand type for STAG/DTAG
407 set ZERO,		0x01			# operand type for STAG/DTAG
408 set INF,		0x02			# operand type for STAG/DTAG
409 set QNAN,		0x03			# operand type for STAG/DTAG
410 set DENORM,		0x04			# operand type for STAG/DTAG
411 set SNAN,		0x05			# operand type for STAG/DTAG
412 set UNNORM,		0x06			# operand type for STAG/DTAG
413 
414 ##################
415 # FPSR/FPCR bits #
416 ##################
417 set neg_bit,		0x3			# negative result
418 set z_bit,		0x2			# zero result
419 set inf_bit,		0x1			# infinite result
420 set nan_bit,		0x0			# NAN result
421 
422 set q_sn_bit,		0x7			# sign bit of quotient byte
423 
424 set bsun_bit,		7			# branch on unordered
425 set snan_bit,		6			# signalling NAN
426 set operr_bit,		5			# operand error
427 set ovfl_bit,		4			# overflow
428 set unfl_bit,		3			# underflow
429 set dz_bit,		2			# divide by zero
430 set inex2_bit,		1			# inexact result 2
431 set inex1_bit,		0			# inexact result 1
432 
433 set aiop_bit,		7			# accrued inexact operation bit
434 set aovfl_bit,		6			# accrued overflow bit
435 set aunfl_bit,		5			# accrued underflow bit
436 set adz_bit,		4			# accrued dz bit
437 set ainex_bit,		3			# accrued inexact bit
438 
439 #############################
440 # FPSR individual bit masks #
441 #############################
442 set neg_mask,		0x08000000		# negative bit mask (lw)
443 set inf_mask,		0x02000000		# infinity bit mask (lw)
444 set z_mask,		0x04000000		# zero bit mask (lw)
445 set nan_mask,		0x01000000		# nan bit mask (lw)
446 
447 set neg_bmask,		0x08			# negative bit mask (byte)
448 set inf_bmask,		0x02			# infinity bit mask (byte)
449 set z_bmask,		0x04			# zero bit mask (byte)
450 set nan_bmask,		0x01			# nan bit mask (byte)
451 
452 set bsun_mask,		0x00008000		# bsun exception mask
453 set snan_mask,		0x00004000		# snan exception mask
454 set operr_mask,		0x00002000		# operr exception mask
455 set ovfl_mask,		0x00001000		# overflow exception mask
456 set unfl_mask,		0x00000800		# underflow exception mask
457 set dz_mask,		0x00000400		# dz exception mask
458 set inex2_mask,		0x00000200		# inex2 exception mask
459 set inex1_mask,		0x00000100		# inex1 exception mask
460 
461 set aiop_mask,		0x00000080		# accrued illegal operation
462 set aovfl_mask,		0x00000040		# accrued overflow
463 set aunfl_mask,		0x00000020		# accrued underflow
464 set adz_mask,		0x00000010		# accrued divide by zero
465 set ainex_mask,		0x00000008		# accrued inexact
466 
467 ######################################
468 # FPSR combinations used in the FPSP #
469 ######################################
470 set dzinf_mask,		inf_mask+dz_mask+adz_mask
471 set opnan_mask,		nan_mask+operr_mask+aiop_mask
472 set nzi_mask,		0x01ffffff		#clears N, Z, and I
473 set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
474 set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
475 set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
476 set inx1a_mask,		inex1_mask+ainex_mask
477 set inx2a_mask,		inex2_mask+ainex_mask
478 set snaniop_mask,	nan_mask+snan_mask+aiop_mask
479 set snaniop2_mask,	snan_mask+aiop_mask
480 set naniop_mask,	nan_mask+aiop_mask
481 set neginf_mask,	neg_mask+inf_mask
482 set infaiop_mask,	inf_mask+aiop_mask
483 set negz_mask,		neg_mask+z_mask
484 set opaop_mask,		operr_mask+aiop_mask
485 set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
486 set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
487 
488 #########
489 # misc. #
490 #########
491 set rnd_stky_bit,	29			# stky bit pos in longword
492 
493 set sign_bit,		0x7			# sign bit
494 set signan_bit,		0x6			# signalling nan bit
495 
496 set sgl_thresh,		0x3f81			# minimum sgl exponent
497 set dbl_thresh,		0x3c01			# minimum dbl exponent
498 
499 set x_mode,		0x0			# extended precision
500 set s_mode,		0x4			# single precision
501 set d_mode,		0x8			# double precision
502 
503 set rn_mode,		0x0			# round-to-nearest
504 set rz_mode,		0x1			# round-to-zero
505 set rm_mode,		0x2			# round-tp-minus-infinity
506 set rp_mode,		0x3			# round-to-plus-infinity
507 
508 set mantissalen,	64			# length of mantissa in bits
509 
510 set BYTE,		1			# len(byte) == 1 byte
511 set WORD,		2			# len(word) == 2 bytes
512 set LONG,		4			# len(longword) == 2 bytes
513 
514 set BSUN_VEC,		0xc0			# bsun    vector offset
515 set INEX_VEC,		0xc4			# inexact vector offset
516 set DZ_VEC,		0xc8			# dz      vector offset
517 set UNFL_VEC,		0xcc			# unfl    vector offset
518 set OPERR_VEC,		0xd0			# operr   vector offset
519 set OVFL_VEC,		0xd4			# ovfl    vector offset
520 set SNAN_VEC,		0xd8			# snan    vector offset
521 
522 ###########################
523 # SPecial CONDition FLaGs #
524 ###########################
525 set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
526 set fbsun_flg,		0x02			# flag bit: bsun exception
527 set mia7_flg,		0x04			# flag bit: (a7)+ <ea>
528 set mda7_flg,		0x08			# flag bit: -(a7) <ea>
529 set fmovm_flg,		0x40			# flag bit: fmovm instruction
530 set immed_flg,		0x80			# flag bit: &<data> <ea>
531 
532 set ftrapcc_bit,	0x0
533 set fbsun_bit,		0x1
534 set mia7_bit,		0x2
535 set mda7_bit,		0x3
536 set immed_bit,		0x7
537 
538 ##################################
539 # TRANSCENDENTAL "LAST-OP" FLAGS #
540 ##################################
541 set FMUL_OP,		0x0			# fmul instr performed last
542 set FDIV_OP,		0x1			# fdiv performed last
543 set FADD_OP,		0x2			# fadd performed last
544 set FMOV_OP,		0x3			# fmov performed last
545 
546 #############
547 # CONSTANTS #
548 #############
549 T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
550 T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
551 
552 PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
553 PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
554 
555 TWOBYPI:
556 	long		0x3FE45F30,0x6DC9C883
557 
558 #########################################################################
559 # MONADIC TEMPLATE							#
560 #########################################################################
561 	global		_fsins_
562 _fsins_:
563 	link		%a6,&-LOCAL_SIZE
564 
565 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
566 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
567 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
568 
569 	fmov.l		&0x0,%fpcr		# zero FPCR
570 
571 #
572 #	copy, convert, and tag input argument
573 #
574 	fmov.s		0x8(%a6),%fp0		# load sgl input
575 	fmov.x		%fp0,FP_SRC(%a6)
576 	lea		FP_SRC(%a6),%a0
577 	bsr.l		tag			# fetch operand type
578 	mov.b		%d0,STAG(%a6)
579 	mov.b		%d0,%d1
580 
581 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
582 
583 	clr.l		%d0
584 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
585 
586 	tst.b		%d1
587 	bne.b		_L0_2s
588 	bsr.l		ssin			# operand is a NORM
589 	bra.b		_L0_6s
590 _L0_2s:
591 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
592 	bne.b		_L0_3s			# no
593 	bsr.l		src_zero			# yes
594 	bra.b		_L0_6s
595 _L0_3s:
596 	cmpi.b		%d1,&INF		# is operand an INF?
597 	bne.b		_L0_4s			# no
598 	bsr.l		t_operr			# yes
599 	bra.b		_L0_6s
600 _L0_4s:
601 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
602 	bne.b		_L0_5s			# no
603 	bsr.l		src_qnan			# yes
604 	bra.b		_L0_6s
605 _L0_5s:
606 	bsr.l		ssind			# operand is a DENORM
607 _L0_6s:
608 
609 #
610 #	Result is now in FP0
611 #
612 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
613 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
614 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
615 	unlk		%a6
616 	rts
617 
618 	global		_fsind_
619 _fsind_:
620 	link		%a6,&-LOCAL_SIZE
621 
622 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
623 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
624 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
625 
626 	fmov.l		&0x0,%fpcr		# zero FPCR
627 
628 #
629 #	copy, convert, and tag input argument
630 #
631 	fmov.d		0x8(%a6),%fp0		# load dbl input
632 	fmov.x		%fp0,FP_SRC(%a6)
633 	lea		FP_SRC(%a6),%a0
634 	bsr.l		tag			# fetch operand type
635 	mov.b		%d0,STAG(%a6)
636 	mov.b		%d0,%d1
637 
638 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
639 
640 	clr.l		%d0
641 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
642 
643 	mov.b		%d1,STAG(%a6)
644 	tst.b		%d1
645 	bne.b		_L0_2d
646 	bsr.l		ssin			# operand is a NORM
647 	bra.b		_L0_6d
648 _L0_2d:
649 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
650 	bne.b		_L0_3d			# no
651 	bsr.l		src_zero			# yes
652 	bra.b		_L0_6d
653 _L0_3d:
654 	cmpi.b		%d1,&INF		# is operand an INF?
655 	bne.b		_L0_4d			# no
656 	bsr.l		t_operr			# yes
657 	bra.b		_L0_6d
658 _L0_4d:
659 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
660 	bne.b		_L0_5d			# no
661 	bsr.l		src_qnan			# yes
662 	bra.b		_L0_6d
663 _L0_5d:
664 	bsr.l		ssind			# operand is a DENORM
665 _L0_6d:
666 
667 #
668 #	Result is now in FP0
669 #
670 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
671 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
672 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
673 	unlk		%a6
674 	rts
675 
676 	global		_fsinx_
677 _fsinx_:
678 	link		%a6,&-LOCAL_SIZE
679 
680 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
681 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
682 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
683 
684 	fmov.l		&0x0,%fpcr		# zero FPCR
685 
686 #
687 #	copy, convert, and tag input argument
688 #
689 	lea		FP_SRC(%a6),%a0
690 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
691 	mov.l		0x8+0x4(%a6),0x4(%a0)
692 	mov.l		0x8+0x8(%a6),0x8(%a0)
693 	bsr.l		tag			# fetch operand type
694 	mov.b		%d0,STAG(%a6)
695 	mov.b		%d0,%d1
696 
697 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
698 
699 	clr.l		%d0
700 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
701 
702 	tst.b		%d1
703 	bne.b		_L0_2x
704 	bsr.l		ssin			# operand is a NORM
705 	bra.b		_L0_6x
706 _L0_2x:
707 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
708 	bne.b		_L0_3x			# no
709 	bsr.l		src_zero			# yes
710 	bra.b		_L0_6x
711 _L0_3x:
712 	cmpi.b		%d1,&INF		# is operand an INF?
713 	bne.b		_L0_4x			# no
714 	bsr.l		t_operr			# yes
715 	bra.b		_L0_6x
716 _L0_4x:
717 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
718 	bne.b		_L0_5x			# no
719 	bsr.l		src_qnan			# yes
720 	bra.b		_L0_6x
721 _L0_5x:
722 	bsr.l		ssind			# operand is a DENORM
723 _L0_6x:
724 
725 #
726 #	Result is now in FP0
727 #
728 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
729 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
730 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
731 	unlk		%a6
732 	rts
733 
734 
735 #########################################################################
736 # MONADIC TEMPLATE							#
737 #########################################################################
738 	global		_fcoss_
739 _fcoss_:
740 	link		%a6,&-LOCAL_SIZE
741 
742 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
743 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
744 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
745 
746 	fmov.l		&0x0,%fpcr		# zero FPCR
747 
748 #
749 #	copy, convert, and tag input argument
750 #
751 	fmov.s		0x8(%a6),%fp0		# load sgl input
752 	fmov.x		%fp0,FP_SRC(%a6)
753 	lea		FP_SRC(%a6),%a0
754 	bsr.l		tag			# fetch operand type
755 	mov.b		%d0,STAG(%a6)
756 	mov.b		%d0,%d1
757 
758 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
759 
760 	clr.l		%d0
761 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
762 
763 	tst.b		%d1
764 	bne.b		_L1_2s
765 	bsr.l		scos			# operand is a NORM
766 	bra.b		_L1_6s
767 _L1_2s:
768 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
769 	bne.b		_L1_3s			# no
770 	bsr.l		ld_pone			# yes
771 	bra.b		_L1_6s
772 _L1_3s:
773 	cmpi.b		%d1,&INF		# is operand an INF?
774 	bne.b		_L1_4s			# no
775 	bsr.l		t_operr			# yes
776 	bra.b		_L1_6s
777 _L1_4s:
778 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
779 	bne.b		_L1_5s			# no
780 	bsr.l		src_qnan			# yes
781 	bra.b		_L1_6s
782 _L1_5s:
783 	bsr.l		scosd			# operand is a DENORM
784 _L1_6s:
785 
786 #
787 #	Result is now in FP0
788 #
789 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
790 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
791 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
792 	unlk		%a6
793 	rts
794 
795 	global		_fcosd_
796 _fcosd_:
797 	link		%a6,&-LOCAL_SIZE
798 
799 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
800 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
801 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
802 
803 	fmov.l		&0x0,%fpcr		# zero FPCR
804 
805 #
806 #	copy, convert, and tag input argument
807 #
808 	fmov.d		0x8(%a6),%fp0		# load dbl input
809 	fmov.x		%fp0,FP_SRC(%a6)
810 	lea		FP_SRC(%a6),%a0
811 	bsr.l		tag			# fetch operand type
812 	mov.b		%d0,STAG(%a6)
813 	mov.b		%d0,%d1
814 
815 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
816 
817 	clr.l		%d0
818 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
819 
820 	mov.b		%d1,STAG(%a6)
821 	tst.b		%d1
822 	bne.b		_L1_2d
823 	bsr.l		scos			# operand is a NORM
824 	bra.b		_L1_6d
825 _L1_2d:
826 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
827 	bne.b		_L1_3d			# no
828 	bsr.l		ld_pone			# yes
829 	bra.b		_L1_6d
830 _L1_3d:
831 	cmpi.b		%d1,&INF		# is operand an INF?
832 	bne.b		_L1_4d			# no
833 	bsr.l		t_operr			# yes
834 	bra.b		_L1_6d
835 _L1_4d:
836 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
837 	bne.b		_L1_5d			# no
838 	bsr.l		src_qnan			# yes
839 	bra.b		_L1_6d
840 _L1_5d:
841 	bsr.l		scosd			# operand is a DENORM
842 _L1_6d:
843 
844 #
845 #	Result is now in FP0
846 #
847 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
848 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
849 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
850 	unlk		%a6
851 	rts
852 
853 	global		_fcosx_
854 _fcosx_:
855 	link		%a6,&-LOCAL_SIZE
856 
857 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
858 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
859 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
860 
861 	fmov.l		&0x0,%fpcr		# zero FPCR
862 
863 #
864 #	copy, convert, and tag input argument
865 #
866 	lea		FP_SRC(%a6),%a0
867 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
868 	mov.l		0x8+0x4(%a6),0x4(%a0)
869 	mov.l		0x8+0x8(%a6),0x8(%a0)
870 	bsr.l		tag			# fetch operand type
871 	mov.b		%d0,STAG(%a6)
872 	mov.b		%d0,%d1
873 
874 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
875 
876 	clr.l		%d0
877 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
878 
879 	tst.b		%d1
880 	bne.b		_L1_2x
881 	bsr.l		scos			# operand is a NORM
882 	bra.b		_L1_6x
883 _L1_2x:
884 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
885 	bne.b		_L1_3x			# no
886 	bsr.l		ld_pone			# yes
887 	bra.b		_L1_6x
888 _L1_3x:
889 	cmpi.b		%d1,&INF		# is operand an INF?
890 	bne.b		_L1_4x			# no
891 	bsr.l		t_operr			# yes
892 	bra.b		_L1_6x
893 _L1_4x:
894 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
895 	bne.b		_L1_5x			# no
896 	bsr.l		src_qnan			# yes
897 	bra.b		_L1_6x
898 _L1_5x:
899 	bsr.l		scosd			# operand is a DENORM
900 _L1_6x:
901 
902 #
903 #	Result is now in FP0
904 #
905 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
906 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
907 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
908 	unlk		%a6
909 	rts
910 
911 
912 #########################################################################
913 # MONADIC TEMPLATE							#
914 #########################################################################
915 	global		_fsinhs_
916 _fsinhs_:
917 	link		%a6,&-LOCAL_SIZE
918 
919 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
920 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
921 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
922 
923 	fmov.l		&0x0,%fpcr		# zero FPCR
924 
925 #
926 #	copy, convert, and tag input argument
927 #
928 	fmov.s		0x8(%a6),%fp0		# load sgl input
929 	fmov.x		%fp0,FP_SRC(%a6)
930 	lea		FP_SRC(%a6),%a0
931 	bsr.l		tag			# fetch operand type
932 	mov.b		%d0,STAG(%a6)
933 	mov.b		%d0,%d1
934 
935 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
936 
937 	clr.l		%d0
938 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
939 
940 	tst.b		%d1
941 	bne.b		_L2_2s
942 	bsr.l		ssinh			# operand is a NORM
943 	bra.b		_L2_6s
944 _L2_2s:
945 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
946 	bne.b		_L2_3s			# no
947 	bsr.l		src_zero			# yes
948 	bra.b		_L2_6s
949 _L2_3s:
950 	cmpi.b		%d1,&INF		# is operand an INF?
951 	bne.b		_L2_4s			# no
952 	bsr.l		src_inf			# yes
953 	bra.b		_L2_6s
954 _L2_4s:
955 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
956 	bne.b		_L2_5s			# no
957 	bsr.l		src_qnan			# yes
958 	bra.b		_L2_6s
959 _L2_5s:
960 	bsr.l		ssinhd			# operand is a DENORM
961 _L2_6s:
962 
963 #
964 #	Result is now in FP0
965 #
966 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
967 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
968 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
969 	unlk		%a6
970 	rts
971 
972 	global		_fsinhd_
973 _fsinhd_:
974 	link		%a6,&-LOCAL_SIZE
975 
976 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
977 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
978 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
979 
980 	fmov.l		&0x0,%fpcr		# zero FPCR
981 
982 #
983 #	copy, convert, and tag input argument
984 #
985 	fmov.d		0x8(%a6),%fp0		# load dbl input
986 	fmov.x		%fp0,FP_SRC(%a6)
987 	lea		FP_SRC(%a6),%a0
988 	bsr.l		tag			# fetch operand type
989 	mov.b		%d0,STAG(%a6)
990 	mov.b		%d0,%d1
991 
992 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
993 
994 	clr.l		%d0
995 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
996 
997 	mov.b		%d1,STAG(%a6)
998 	tst.b		%d1
999 	bne.b		_L2_2d
1000 	bsr.l		ssinh			# operand is a NORM
1001 	bra.b		_L2_6d
1002 _L2_2d:
1003 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1004 	bne.b		_L2_3d			# no
1005 	bsr.l		src_zero			# yes
1006 	bra.b		_L2_6d
1007 _L2_3d:
1008 	cmpi.b		%d1,&INF		# is operand an INF?
1009 	bne.b		_L2_4d			# no
1010 	bsr.l		src_inf			# yes
1011 	bra.b		_L2_6d
1012 _L2_4d:
1013 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1014 	bne.b		_L2_5d			# no
1015 	bsr.l		src_qnan			# yes
1016 	bra.b		_L2_6d
1017 _L2_5d:
1018 	bsr.l		ssinhd			# operand is a DENORM
1019 _L2_6d:
1020 
1021 #
1022 #	Result is now in FP0
1023 #
1024 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1025 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1026 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1027 	unlk		%a6
1028 	rts
1029 
1030 	global		_fsinhx_
1031 _fsinhx_:
1032 	link		%a6,&-LOCAL_SIZE
1033 
1034 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1035 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1036 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1037 
1038 	fmov.l		&0x0,%fpcr		# zero FPCR
1039 
1040 #
1041 #	copy, convert, and tag input argument
1042 #
1043 	lea		FP_SRC(%a6),%a0
1044 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
1045 	mov.l		0x8+0x4(%a6),0x4(%a0)
1046 	mov.l		0x8+0x8(%a6),0x8(%a0)
1047 	bsr.l		tag			# fetch operand type
1048 	mov.b		%d0,STAG(%a6)
1049 	mov.b		%d0,%d1
1050 
1051 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1052 
1053 	clr.l		%d0
1054 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1055 
1056 	tst.b		%d1
1057 	bne.b		_L2_2x
1058 	bsr.l		ssinh			# operand is a NORM
1059 	bra.b		_L2_6x
1060 _L2_2x:
1061 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1062 	bne.b		_L2_3x			# no
1063 	bsr.l		src_zero			# yes
1064 	bra.b		_L2_6x
1065 _L2_3x:
1066 	cmpi.b		%d1,&INF		# is operand an INF?
1067 	bne.b		_L2_4x			# no
1068 	bsr.l		src_inf			# yes
1069 	bra.b		_L2_6x
1070 _L2_4x:
1071 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1072 	bne.b		_L2_5x			# no
1073 	bsr.l		src_qnan			# yes
1074 	bra.b		_L2_6x
1075 _L2_5x:
1076 	bsr.l		ssinhd			# operand is a DENORM
1077 _L2_6x:
1078 
1079 #
1080 #	Result is now in FP0
1081 #
1082 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1083 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1084 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1085 	unlk		%a6
1086 	rts
1087 
1088 
1089 #########################################################################
1090 # MONADIC TEMPLATE							#
1091 #########################################################################
1092 	global		_flognp1s_
1093 _flognp1s_:
1094 	link		%a6,&-LOCAL_SIZE
1095 
1096 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1097 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1098 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1099 
1100 	fmov.l		&0x0,%fpcr		# zero FPCR
1101 
1102 #
1103 #	copy, convert, and tag input argument
1104 #
1105 	fmov.s		0x8(%a6),%fp0		# load sgl input
1106 	fmov.x		%fp0,FP_SRC(%a6)
1107 	lea		FP_SRC(%a6),%a0
1108 	bsr.l		tag			# fetch operand type
1109 	mov.b		%d0,STAG(%a6)
1110 	mov.b		%d0,%d1
1111 
1112 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1113 
1114 	clr.l		%d0
1115 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1116 
1117 	tst.b		%d1
1118 	bne.b		_L3_2s
1119 	bsr.l		slognp1			# operand is a NORM
1120 	bra.b		_L3_6s
1121 _L3_2s:
1122 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1123 	bne.b		_L3_3s			# no
1124 	bsr.l		src_zero			# yes
1125 	bra.b		_L3_6s
1126 _L3_3s:
1127 	cmpi.b		%d1,&INF		# is operand an INF?
1128 	bne.b		_L3_4s			# no
1129 	bsr.l		sopr_inf			# yes
1130 	bra.b		_L3_6s
1131 _L3_4s:
1132 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1133 	bne.b		_L3_5s			# no
1134 	bsr.l		src_qnan			# yes
1135 	bra.b		_L3_6s
1136 _L3_5s:
1137 	bsr.l		slognp1d			# operand is a DENORM
1138 _L3_6s:
1139 
1140 #
1141 #	Result is now in FP0
1142 #
1143 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1144 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1145 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1146 	unlk		%a6
1147 	rts
1148 
1149 	global		_flognp1d_
1150 _flognp1d_:
1151 	link		%a6,&-LOCAL_SIZE
1152 
1153 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1154 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1155 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1156 
1157 	fmov.l		&0x0,%fpcr		# zero FPCR
1158 
1159 #
1160 #	copy, convert, and tag input argument
1161 #
1162 	fmov.d		0x8(%a6),%fp0		# load dbl input
1163 	fmov.x		%fp0,FP_SRC(%a6)
1164 	lea		FP_SRC(%a6),%a0
1165 	bsr.l		tag			# fetch operand type
1166 	mov.b		%d0,STAG(%a6)
1167 	mov.b		%d0,%d1
1168 
1169 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1170 
1171 	clr.l		%d0
1172 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1173 
1174 	mov.b		%d1,STAG(%a6)
1175 	tst.b		%d1
1176 	bne.b		_L3_2d
1177 	bsr.l		slognp1			# operand is a NORM
1178 	bra.b		_L3_6d
1179 _L3_2d:
1180 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1181 	bne.b		_L3_3d			# no
1182 	bsr.l		src_zero			# yes
1183 	bra.b		_L3_6d
1184 _L3_3d:
1185 	cmpi.b		%d1,&INF		# is operand an INF?
1186 	bne.b		_L3_4d			# no
1187 	bsr.l		sopr_inf			# yes
1188 	bra.b		_L3_6d
1189 _L3_4d:
1190 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1191 	bne.b		_L3_5d			# no
1192 	bsr.l		src_qnan			# yes
1193 	bra.b		_L3_6d
1194 _L3_5d:
1195 	bsr.l		slognp1d			# operand is a DENORM
1196 _L3_6d:
1197 
1198 #
1199 #	Result is now in FP0
1200 #
1201 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1202 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1203 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1204 	unlk		%a6
1205 	rts
1206 
1207 	global		_flognp1x_
1208 _flognp1x_:
1209 	link		%a6,&-LOCAL_SIZE
1210 
1211 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1212 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1213 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1214 
1215 	fmov.l		&0x0,%fpcr		# zero FPCR
1216 
1217 #
1218 #	copy, convert, and tag input argument
1219 #
1220 	lea		FP_SRC(%a6),%a0
1221 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
1222 	mov.l		0x8+0x4(%a6),0x4(%a0)
1223 	mov.l		0x8+0x8(%a6),0x8(%a0)
1224 	bsr.l		tag			# fetch operand type
1225 	mov.b		%d0,STAG(%a6)
1226 	mov.b		%d0,%d1
1227 
1228 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1229 
1230 	clr.l		%d0
1231 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1232 
1233 	tst.b		%d1
1234 	bne.b		_L3_2x
1235 	bsr.l		slognp1			# operand is a NORM
1236 	bra.b		_L3_6x
1237 _L3_2x:
1238 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1239 	bne.b		_L3_3x			# no
1240 	bsr.l		src_zero			# yes
1241 	bra.b		_L3_6x
1242 _L3_3x:
1243 	cmpi.b		%d1,&INF		# is operand an INF?
1244 	bne.b		_L3_4x			# no
1245 	bsr.l		sopr_inf			# yes
1246 	bra.b		_L3_6x
1247 _L3_4x:
1248 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1249 	bne.b		_L3_5x			# no
1250 	bsr.l		src_qnan			# yes
1251 	bra.b		_L3_6x
1252 _L3_5x:
1253 	bsr.l		slognp1d			# operand is a DENORM
1254 _L3_6x:
1255 
1256 #
1257 #	Result is now in FP0
1258 #
1259 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1260 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1261 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1262 	unlk		%a6
1263 	rts
1264 
1265 
1266 #########################################################################
1267 # MONADIC TEMPLATE							#
1268 #########################################################################
1269 	global		_fetoxm1s_
1270 _fetoxm1s_:
1271 	link		%a6,&-LOCAL_SIZE
1272 
1273 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1274 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1275 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1276 
1277 	fmov.l		&0x0,%fpcr		# zero FPCR
1278 
1279 #
1280 #	copy, convert, and tag input argument
1281 #
1282 	fmov.s		0x8(%a6),%fp0		# load sgl input
1283 	fmov.x		%fp0,FP_SRC(%a6)
1284 	lea		FP_SRC(%a6),%a0
1285 	bsr.l		tag			# fetch operand type
1286 	mov.b		%d0,STAG(%a6)
1287 	mov.b		%d0,%d1
1288 
1289 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1290 
1291 	clr.l		%d0
1292 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1293 
1294 	tst.b		%d1
1295 	bne.b		_L4_2s
1296 	bsr.l		setoxm1			# operand is a NORM
1297 	bra.b		_L4_6s
1298 _L4_2s:
1299 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1300 	bne.b		_L4_3s			# no
1301 	bsr.l		src_zero			# yes
1302 	bra.b		_L4_6s
1303 _L4_3s:
1304 	cmpi.b		%d1,&INF		# is operand an INF?
1305 	bne.b		_L4_4s			# no
1306 	bsr.l		setoxm1i			# yes
1307 	bra.b		_L4_6s
1308 _L4_4s:
1309 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1310 	bne.b		_L4_5s			# no
1311 	bsr.l		src_qnan			# yes
1312 	bra.b		_L4_6s
1313 _L4_5s:
1314 	bsr.l		setoxm1d			# operand is a DENORM
1315 _L4_6s:
1316 
1317 #
1318 #	Result is now in FP0
1319 #
1320 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1321 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1322 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1323 	unlk		%a6
1324 	rts
1325 
1326 	global		_fetoxm1d_
1327 _fetoxm1d_:
1328 	link		%a6,&-LOCAL_SIZE
1329 
1330 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1331 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1332 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1333 
1334 	fmov.l		&0x0,%fpcr		# zero FPCR
1335 
1336 #
1337 #	copy, convert, and tag input argument
1338 #
1339 	fmov.d		0x8(%a6),%fp0		# load dbl input
1340 	fmov.x		%fp0,FP_SRC(%a6)
1341 	lea		FP_SRC(%a6),%a0
1342 	bsr.l		tag			# fetch operand type
1343 	mov.b		%d0,STAG(%a6)
1344 	mov.b		%d0,%d1
1345 
1346 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1347 
1348 	clr.l		%d0
1349 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1350 
1351 	mov.b		%d1,STAG(%a6)
1352 	tst.b		%d1
1353 	bne.b		_L4_2d
1354 	bsr.l		setoxm1			# operand is a NORM
1355 	bra.b		_L4_6d
1356 _L4_2d:
1357 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1358 	bne.b		_L4_3d			# no
1359 	bsr.l		src_zero			# yes
1360 	bra.b		_L4_6d
1361 _L4_3d:
1362 	cmpi.b		%d1,&INF		# is operand an INF?
1363 	bne.b		_L4_4d			# no
1364 	bsr.l		setoxm1i			# yes
1365 	bra.b		_L4_6d
1366 _L4_4d:
1367 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1368 	bne.b		_L4_5d			# no
1369 	bsr.l		src_qnan			# yes
1370 	bra.b		_L4_6d
1371 _L4_5d:
1372 	bsr.l		setoxm1d			# operand is a DENORM
1373 _L4_6d:
1374 
1375 #
1376 #	Result is now in FP0
1377 #
1378 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1379 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1380 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1381 	unlk		%a6
1382 	rts
1383 
1384 	global		_fetoxm1x_
1385 _fetoxm1x_:
1386 	link		%a6,&-LOCAL_SIZE
1387 
1388 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1389 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1390 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1391 
1392 	fmov.l		&0x0,%fpcr		# zero FPCR
1393 
1394 #
1395 #	copy, convert, and tag input argument
1396 #
1397 	lea		FP_SRC(%a6),%a0
1398 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
1399 	mov.l		0x8+0x4(%a6),0x4(%a0)
1400 	mov.l		0x8+0x8(%a6),0x8(%a0)
1401 	bsr.l		tag			# fetch operand type
1402 	mov.b		%d0,STAG(%a6)
1403 	mov.b		%d0,%d1
1404 
1405 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1406 
1407 	clr.l		%d0
1408 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1409 
1410 	tst.b		%d1
1411 	bne.b		_L4_2x
1412 	bsr.l		setoxm1			# operand is a NORM
1413 	bra.b		_L4_6x
1414 _L4_2x:
1415 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1416 	bne.b		_L4_3x			# no
1417 	bsr.l		src_zero			# yes
1418 	bra.b		_L4_6x
1419 _L4_3x:
1420 	cmpi.b		%d1,&INF		# is operand an INF?
1421 	bne.b		_L4_4x			# no
1422 	bsr.l		setoxm1i			# yes
1423 	bra.b		_L4_6x
1424 _L4_4x:
1425 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1426 	bne.b		_L4_5x			# no
1427 	bsr.l		src_qnan			# yes
1428 	bra.b		_L4_6x
1429 _L4_5x:
1430 	bsr.l		setoxm1d			# operand is a DENORM
1431 _L4_6x:
1432 
1433 #
1434 #	Result is now in FP0
1435 #
1436 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1437 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1438 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1439 	unlk		%a6
1440 	rts
1441 
1442 
1443 #########################################################################
1444 # MONADIC TEMPLATE							#
1445 #########################################################################
1446 	global		_ftanhs_
1447 _ftanhs_:
1448 	link		%a6,&-LOCAL_SIZE
1449 
1450 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1451 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1452 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1453 
1454 	fmov.l		&0x0,%fpcr		# zero FPCR
1455 
1456 #
1457 #	copy, convert, and tag input argument
1458 #
1459 	fmov.s		0x8(%a6),%fp0		# load sgl input
1460 	fmov.x		%fp0,FP_SRC(%a6)
1461 	lea		FP_SRC(%a6),%a0
1462 	bsr.l		tag			# fetch operand type
1463 	mov.b		%d0,STAG(%a6)
1464 	mov.b		%d0,%d1
1465 
1466 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1467 
1468 	clr.l		%d0
1469 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1470 
1471 	tst.b		%d1
1472 	bne.b		_L5_2s
1473 	bsr.l		stanh			# operand is a NORM
1474 	bra.b		_L5_6s
1475 _L5_2s:
1476 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1477 	bne.b		_L5_3s			# no
1478 	bsr.l		src_zero			# yes
1479 	bra.b		_L5_6s
1480 _L5_3s:
1481 	cmpi.b		%d1,&INF		# is operand an INF?
1482 	bne.b		_L5_4s			# no
1483 	bsr.l		src_one			# yes
1484 	bra.b		_L5_6s
1485 _L5_4s:
1486 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1487 	bne.b		_L5_5s			# no
1488 	bsr.l		src_qnan			# yes
1489 	bra.b		_L5_6s
1490 _L5_5s:
1491 	bsr.l		stanhd			# operand is a DENORM
1492 _L5_6s:
1493 
1494 #
1495 #	Result is now in FP0
1496 #
1497 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1498 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1499 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1500 	unlk		%a6
1501 	rts
1502 
1503 	global		_ftanhd_
1504 _ftanhd_:
1505 	link		%a6,&-LOCAL_SIZE
1506 
1507 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1508 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1509 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1510 
1511 	fmov.l		&0x0,%fpcr		# zero FPCR
1512 
1513 #
1514 #	copy, convert, and tag input argument
1515 #
1516 	fmov.d		0x8(%a6),%fp0		# load dbl input
1517 	fmov.x		%fp0,FP_SRC(%a6)
1518 	lea		FP_SRC(%a6),%a0
1519 	bsr.l		tag			# fetch operand type
1520 	mov.b		%d0,STAG(%a6)
1521 	mov.b		%d0,%d1
1522 
1523 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1524 
1525 	clr.l		%d0
1526 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1527 
1528 	mov.b		%d1,STAG(%a6)
1529 	tst.b		%d1
1530 	bne.b		_L5_2d
1531 	bsr.l		stanh			# operand is a NORM
1532 	bra.b		_L5_6d
1533 _L5_2d:
1534 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1535 	bne.b		_L5_3d			# no
1536 	bsr.l		src_zero			# yes
1537 	bra.b		_L5_6d
1538 _L5_3d:
1539 	cmpi.b		%d1,&INF		# is operand an INF?
1540 	bne.b		_L5_4d			# no
1541 	bsr.l		src_one			# yes
1542 	bra.b		_L5_6d
1543 _L5_4d:
1544 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1545 	bne.b		_L5_5d			# no
1546 	bsr.l		src_qnan			# yes
1547 	bra.b		_L5_6d
1548 _L5_5d:
1549 	bsr.l		stanhd			# operand is a DENORM
1550 _L5_6d:
1551 
1552 #
1553 #	Result is now in FP0
1554 #
1555 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1556 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1557 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1558 	unlk		%a6
1559 	rts
1560 
1561 	global		_ftanhx_
1562 _ftanhx_:
1563 	link		%a6,&-LOCAL_SIZE
1564 
1565 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1566 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1567 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1568 
1569 	fmov.l		&0x0,%fpcr		# zero FPCR
1570 
1571 #
1572 #	copy, convert, and tag input argument
1573 #
1574 	lea		FP_SRC(%a6),%a0
1575 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
1576 	mov.l		0x8+0x4(%a6),0x4(%a0)
1577 	mov.l		0x8+0x8(%a6),0x8(%a0)
1578 	bsr.l		tag			# fetch operand type
1579 	mov.b		%d0,STAG(%a6)
1580 	mov.b		%d0,%d1
1581 
1582 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1583 
1584 	clr.l		%d0
1585 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1586 
1587 	tst.b		%d1
1588 	bne.b		_L5_2x
1589 	bsr.l		stanh			# operand is a NORM
1590 	bra.b		_L5_6x
1591 _L5_2x:
1592 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1593 	bne.b		_L5_3x			# no
1594 	bsr.l		src_zero			# yes
1595 	bra.b		_L5_6x
1596 _L5_3x:
1597 	cmpi.b		%d1,&INF		# is operand an INF?
1598 	bne.b		_L5_4x			# no
1599 	bsr.l		src_one			# yes
1600 	bra.b		_L5_6x
1601 _L5_4x:
1602 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1603 	bne.b		_L5_5x			# no
1604 	bsr.l		src_qnan			# yes
1605 	bra.b		_L5_6x
1606 _L5_5x:
1607 	bsr.l		stanhd			# operand is a DENORM
1608 _L5_6x:
1609 
1610 #
1611 #	Result is now in FP0
1612 #
1613 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1614 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1615 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1616 	unlk		%a6
1617 	rts
1618 
1619 
1620 #########################################################################
1621 # MONADIC TEMPLATE							#
1622 #########################################################################
1623 	global		_fatans_
1624 _fatans_:
1625 	link		%a6,&-LOCAL_SIZE
1626 
1627 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1628 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1629 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1630 
1631 	fmov.l		&0x0,%fpcr		# zero FPCR
1632 
1633 #
1634 #	copy, convert, and tag input argument
1635 #
1636 	fmov.s		0x8(%a6),%fp0		# load sgl input
1637 	fmov.x		%fp0,FP_SRC(%a6)
1638 	lea		FP_SRC(%a6),%a0
1639 	bsr.l		tag			# fetch operand type
1640 	mov.b		%d0,STAG(%a6)
1641 	mov.b		%d0,%d1
1642 
1643 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1644 
1645 	clr.l		%d0
1646 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1647 
1648 	tst.b		%d1
1649 	bne.b		_L6_2s
1650 	bsr.l		satan			# operand is a NORM
1651 	bra.b		_L6_6s
1652 _L6_2s:
1653 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1654 	bne.b		_L6_3s			# no
1655 	bsr.l		src_zero			# yes
1656 	bra.b		_L6_6s
1657 _L6_3s:
1658 	cmpi.b		%d1,&INF		# is operand an INF?
1659 	bne.b		_L6_4s			# no
1660 	bsr.l		spi_2			# yes
1661 	bra.b		_L6_6s
1662 _L6_4s:
1663 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1664 	bne.b		_L6_5s			# no
1665 	bsr.l		src_qnan			# yes
1666 	bra.b		_L6_6s
1667 _L6_5s:
1668 	bsr.l		satand			# operand is a DENORM
1669 _L6_6s:
1670 
1671 #
1672 #	Result is now in FP0
1673 #
1674 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1675 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1676 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1677 	unlk		%a6
1678 	rts
1679 
1680 	global		_fatand_
1681 _fatand_:
1682 	link		%a6,&-LOCAL_SIZE
1683 
1684 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1685 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1686 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1687 
1688 	fmov.l		&0x0,%fpcr		# zero FPCR
1689 
1690 #
1691 #	copy, convert, and tag input argument
1692 #
1693 	fmov.d		0x8(%a6),%fp0		# load dbl input
1694 	fmov.x		%fp0,FP_SRC(%a6)
1695 	lea		FP_SRC(%a6),%a0
1696 	bsr.l		tag			# fetch operand type
1697 	mov.b		%d0,STAG(%a6)
1698 	mov.b		%d0,%d1
1699 
1700 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1701 
1702 	clr.l		%d0
1703 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1704 
1705 	mov.b		%d1,STAG(%a6)
1706 	tst.b		%d1
1707 	bne.b		_L6_2d
1708 	bsr.l		satan			# operand is a NORM
1709 	bra.b		_L6_6d
1710 _L6_2d:
1711 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1712 	bne.b		_L6_3d			# no
1713 	bsr.l		src_zero			# yes
1714 	bra.b		_L6_6d
1715 _L6_3d:
1716 	cmpi.b		%d1,&INF		# is operand an INF?
1717 	bne.b		_L6_4d			# no
1718 	bsr.l		spi_2			# yes
1719 	bra.b		_L6_6d
1720 _L6_4d:
1721 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1722 	bne.b		_L6_5d			# no
1723 	bsr.l		src_qnan			# yes
1724 	bra.b		_L6_6d
1725 _L6_5d:
1726 	bsr.l		satand			# operand is a DENORM
1727 _L6_6d:
1728 
1729 #
1730 #	Result is now in FP0
1731 #
1732 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1733 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1734 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1735 	unlk		%a6
1736 	rts
1737 
1738 	global		_fatanx_
1739 _fatanx_:
1740 	link		%a6,&-LOCAL_SIZE
1741 
1742 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1743 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1744 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1745 
1746 	fmov.l		&0x0,%fpcr		# zero FPCR
1747 
1748 #
1749 #	copy, convert, and tag input argument
1750 #
1751 	lea		FP_SRC(%a6),%a0
1752 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
1753 	mov.l		0x8+0x4(%a6),0x4(%a0)
1754 	mov.l		0x8+0x8(%a6),0x8(%a0)
1755 	bsr.l		tag			# fetch operand type
1756 	mov.b		%d0,STAG(%a6)
1757 	mov.b		%d0,%d1
1758 
1759 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1760 
1761 	clr.l		%d0
1762 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1763 
1764 	tst.b		%d1
1765 	bne.b		_L6_2x
1766 	bsr.l		satan			# operand is a NORM
1767 	bra.b		_L6_6x
1768 _L6_2x:
1769 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1770 	bne.b		_L6_3x			# no
1771 	bsr.l		src_zero			# yes
1772 	bra.b		_L6_6x
1773 _L6_3x:
1774 	cmpi.b		%d1,&INF		# is operand an INF?
1775 	bne.b		_L6_4x			# no
1776 	bsr.l		spi_2			# yes
1777 	bra.b		_L6_6x
1778 _L6_4x:
1779 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1780 	bne.b		_L6_5x			# no
1781 	bsr.l		src_qnan			# yes
1782 	bra.b		_L6_6x
1783 _L6_5x:
1784 	bsr.l		satand			# operand is a DENORM
1785 _L6_6x:
1786 
1787 #
1788 #	Result is now in FP0
1789 #
1790 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1791 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1792 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1793 	unlk		%a6
1794 	rts
1795 
1796 
1797 #########################################################################
1798 # MONADIC TEMPLATE							#
1799 #########################################################################
1800 	global		_fasins_
1801 _fasins_:
1802 	link		%a6,&-LOCAL_SIZE
1803 
1804 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1805 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1806 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1807 
1808 	fmov.l		&0x0,%fpcr		# zero FPCR
1809 
1810 #
1811 #	copy, convert, and tag input argument
1812 #
1813 	fmov.s		0x8(%a6),%fp0		# load sgl input
1814 	fmov.x		%fp0,FP_SRC(%a6)
1815 	lea		FP_SRC(%a6),%a0
1816 	bsr.l		tag			# fetch operand type
1817 	mov.b		%d0,STAG(%a6)
1818 	mov.b		%d0,%d1
1819 
1820 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1821 
1822 	clr.l		%d0
1823 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1824 
1825 	tst.b		%d1
1826 	bne.b		_L7_2s
1827 	bsr.l		sasin			# operand is a NORM
1828 	bra.b		_L7_6s
1829 _L7_2s:
1830 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1831 	bne.b		_L7_3s			# no
1832 	bsr.l		src_zero			# yes
1833 	bra.b		_L7_6s
1834 _L7_3s:
1835 	cmpi.b		%d1,&INF		# is operand an INF?
1836 	bne.b		_L7_4s			# no
1837 	bsr.l		t_operr			# yes
1838 	bra.b		_L7_6s
1839 _L7_4s:
1840 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1841 	bne.b		_L7_5s			# no
1842 	bsr.l		src_qnan			# yes
1843 	bra.b		_L7_6s
1844 _L7_5s:
1845 	bsr.l		sasind			# operand is a DENORM
1846 _L7_6s:
1847 
1848 #
1849 #	Result is now in FP0
1850 #
1851 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1852 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1853 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1854 	unlk		%a6
1855 	rts
1856 
1857 	global		_fasind_
1858 _fasind_:
1859 	link		%a6,&-LOCAL_SIZE
1860 
1861 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1862 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1863 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1864 
1865 	fmov.l		&0x0,%fpcr		# zero FPCR
1866 
1867 #
1868 #	copy, convert, and tag input argument
1869 #
1870 	fmov.d		0x8(%a6),%fp0		# load dbl input
1871 	fmov.x		%fp0,FP_SRC(%a6)
1872 	lea		FP_SRC(%a6),%a0
1873 	bsr.l		tag			# fetch operand type
1874 	mov.b		%d0,STAG(%a6)
1875 	mov.b		%d0,%d1
1876 
1877 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1878 
1879 	clr.l		%d0
1880 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1881 
1882 	mov.b		%d1,STAG(%a6)
1883 	tst.b		%d1
1884 	bne.b		_L7_2d
1885 	bsr.l		sasin			# operand is a NORM
1886 	bra.b		_L7_6d
1887 _L7_2d:
1888 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1889 	bne.b		_L7_3d			# no
1890 	bsr.l		src_zero			# yes
1891 	bra.b		_L7_6d
1892 _L7_3d:
1893 	cmpi.b		%d1,&INF		# is operand an INF?
1894 	bne.b		_L7_4d			# no
1895 	bsr.l		t_operr			# yes
1896 	bra.b		_L7_6d
1897 _L7_4d:
1898 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1899 	bne.b		_L7_5d			# no
1900 	bsr.l		src_qnan			# yes
1901 	bra.b		_L7_6d
1902 _L7_5d:
1903 	bsr.l		sasind			# operand is a DENORM
1904 _L7_6d:
1905 
1906 #
1907 #	Result is now in FP0
1908 #
1909 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1910 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1911 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1912 	unlk		%a6
1913 	rts
1914 
1915 	global		_fasinx_
1916 _fasinx_:
1917 	link		%a6,&-LOCAL_SIZE
1918 
1919 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1920 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1921 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1922 
1923 	fmov.l		&0x0,%fpcr		# zero FPCR
1924 
1925 #
1926 #	copy, convert, and tag input argument
1927 #
1928 	lea		FP_SRC(%a6),%a0
1929 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
1930 	mov.l		0x8+0x4(%a6),0x4(%a0)
1931 	mov.l		0x8+0x8(%a6),0x8(%a0)
1932 	bsr.l		tag			# fetch operand type
1933 	mov.b		%d0,STAG(%a6)
1934 	mov.b		%d0,%d1
1935 
1936 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1937 
1938 	clr.l		%d0
1939 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
1940 
1941 	tst.b		%d1
1942 	bne.b		_L7_2x
1943 	bsr.l		sasin			# operand is a NORM
1944 	bra.b		_L7_6x
1945 _L7_2x:
1946 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
1947 	bne.b		_L7_3x			# no
1948 	bsr.l		src_zero			# yes
1949 	bra.b		_L7_6x
1950 _L7_3x:
1951 	cmpi.b		%d1,&INF		# is operand an INF?
1952 	bne.b		_L7_4x			# no
1953 	bsr.l		t_operr			# yes
1954 	bra.b		_L7_6x
1955 _L7_4x:
1956 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
1957 	bne.b		_L7_5x			# no
1958 	bsr.l		src_qnan			# yes
1959 	bra.b		_L7_6x
1960 _L7_5x:
1961 	bsr.l		sasind			# operand is a DENORM
1962 _L7_6x:
1963 
1964 #
1965 #	Result is now in FP0
1966 #
1967 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
1968 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
1969 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
1970 	unlk		%a6
1971 	rts
1972 
1973 
1974 #########################################################################
1975 # MONADIC TEMPLATE							#
1976 #########################################################################
1977 	global		_fatanhs_
1978 _fatanhs_:
1979 	link		%a6,&-LOCAL_SIZE
1980 
1981 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
1982 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
1983 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
1984 
1985 	fmov.l		&0x0,%fpcr		# zero FPCR
1986 
1987 #
1988 #	copy, convert, and tag input argument
1989 #
1990 	fmov.s		0x8(%a6),%fp0		# load sgl input
1991 	fmov.x		%fp0,FP_SRC(%a6)
1992 	lea		FP_SRC(%a6),%a0
1993 	bsr.l		tag			# fetch operand type
1994 	mov.b		%d0,STAG(%a6)
1995 	mov.b		%d0,%d1
1996 
1997 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
1998 
1999 	clr.l		%d0
2000 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2001 
2002 	tst.b		%d1
2003 	bne.b		_L8_2s
2004 	bsr.l		satanh			# operand is a NORM
2005 	bra.b		_L8_6s
2006 _L8_2s:
2007 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2008 	bne.b		_L8_3s			# no
2009 	bsr.l		src_zero			# yes
2010 	bra.b		_L8_6s
2011 _L8_3s:
2012 	cmpi.b		%d1,&INF		# is operand an INF?
2013 	bne.b		_L8_4s			# no
2014 	bsr.l		t_operr			# yes
2015 	bra.b		_L8_6s
2016 _L8_4s:
2017 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2018 	bne.b		_L8_5s			# no
2019 	bsr.l		src_qnan			# yes
2020 	bra.b		_L8_6s
2021 _L8_5s:
2022 	bsr.l		satanhd			# operand is a DENORM
2023 _L8_6s:
2024 
2025 #
2026 #	Result is now in FP0
2027 #
2028 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2029 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2030 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2031 	unlk		%a6
2032 	rts
2033 
2034 	global		_fatanhd_
2035 _fatanhd_:
2036 	link		%a6,&-LOCAL_SIZE
2037 
2038 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2039 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2040 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2041 
2042 	fmov.l		&0x0,%fpcr		# zero FPCR
2043 
2044 #
2045 #	copy, convert, and tag input argument
2046 #
2047 	fmov.d		0x8(%a6),%fp0		# load dbl input
2048 	fmov.x		%fp0,FP_SRC(%a6)
2049 	lea		FP_SRC(%a6),%a0
2050 	bsr.l		tag			# fetch operand type
2051 	mov.b		%d0,STAG(%a6)
2052 	mov.b		%d0,%d1
2053 
2054 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2055 
2056 	clr.l		%d0
2057 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2058 
2059 	mov.b		%d1,STAG(%a6)
2060 	tst.b		%d1
2061 	bne.b		_L8_2d
2062 	bsr.l		satanh			# operand is a NORM
2063 	bra.b		_L8_6d
2064 _L8_2d:
2065 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2066 	bne.b		_L8_3d			# no
2067 	bsr.l		src_zero			# yes
2068 	bra.b		_L8_6d
2069 _L8_3d:
2070 	cmpi.b		%d1,&INF		# is operand an INF?
2071 	bne.b		_L8_4d			# no
2072 	bsr.l		t_operr			# yes
2073 	bra.b		_L8_6d
2074 _L8_4d:
2075 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2076 	bne.b		_L8_5d			# no
2077 	bsr.l		src_qnan			# yes
2078 	bra.b		_L8_6d
2079 _L8_5d:
2080 	bsr.l		satanhd			# operand is a DENORM
2081 _L8_6d:
2082 
2083 #
2084 #	Result is now in FP0
2085 #
2086 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2087 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2088 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2089 	unlk		%a6
2090 	rts
2091 
2092 	global		_fatanhx_
2093 _fatanhx_:
2094 	link		%a6,&-LOCAL_SIZE
2095 
2096 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2097 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2098 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2099 
2100 	fmov.l		&0x0,%fpcr		# zero FPCR
2101 
2102 #
2103 #	copy, convert, and tag input argument
2104 #
2105 	lea		FP_SRC(%a6),%a0
2106 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
2107 	mov.l		0x8+0x4(%a6),0x4(%a0)
2108 	mov.l		0x8+0x8(%a6),0x8(%a0)
2109 	bsr.l		tag			# fetch operand type
2110 	mov.b		%d0,STAG(%a6)
2111 	mov.b		%d0,%d1
2112 
2113 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2114 
2115 	clr.l		%d0
2116 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2117 
2118 	tst.b		%d1
2119 	bne.b		_L8_2x
2120 	bsr.l		satanh			# operand is a NORM
2121 	bra.b		_L8_6x
2122 _L8_2x:
2123 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2124 	bne.b		_L8_3x			# no
2125 	bsr.l		src_zero			# yes
2126 	bra.b		_L8_6x
2127 _L8_3x:
2128 	cmpi.b		%d1,&INF		# is operand an INF?
2129 	bne.b		_L8_4x			# no
2130 	bsr.l		t_operr			# yes
2131 	bra.b		_L8_6x
2132 _L8_4x:
2133 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2134 	bne.b		_L8_5x			# no
2135 	bsr.l		src_qnan			# yes
2136 	bra.b		_L8_6x
2137 _L8_5x:
2138 	bsr.l		satanhd			# operand is a DENORM
2139 _L8_6x:
2140 
2141 #
2142 #	Result is now in FP0
2143 #
2144 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2145 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2146 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2147 	unlk		%a6
2148 	rts
2149 
2150 
2151 #########################################################################
2152 # MONADIC TEMPLATE							#
2153 #########################################################################
2154 	global		_ftans_
2155 _ftans_:
2156 	link		%a6,&-LOCAL_SIZE
2157 
2158 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2159 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2160 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2161 
2162 	fmov.l		&0x0,%fpcr		# zero FPCR
2163 
2164 #
2165 #	copy, convert, and tag input argument
2166 #
2167 	fmov.s		0x8(%a6),%fp0		# load sgl input
2168 	fmov.x		%fp0,FP_SRC(%a6)
2169 	lea		FP_SRC(%a6),%a0
2170 	bsr.l		tag			# fetch operand type
2171 	mov.b		%d0,STAG(%a6)
2172 	mov.b		%d0,%d1
2173 
2174 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2175 
2176 	clr.l		%d0
2177 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2178 
2179 	tst.b		%d1
2180 	bne.b		_L9_2s
2181 	bsr.l		stan			# operand is a NORM
2182 	bra.b		_L9_6s
2183 _L9_2s:
2184 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2185 	bne.b		_L9_3s			# no
2186 	bsr.l		src_zero			# yes
2187 	bra.b		_L9_6s
2188 _L9_3s:
2189 	cmpi.b		%d1,&INF		# is operand an INF?
2190 	bne.b		_L9_4s			# no
2191 	bsr.l		t_operr			# yes
2192 	bra.b		_L9_6s
2193 _L9_4s:
2194 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2195 	bne.b		_L9_5s			# no
2196 	bsr.l		src_qnan			# yes
2197 	bra.b		_L9_6s
2198 _L9_5s:
2199 	bsr.l		stand			# operand is a DENORM
2200 _L9_6s:
2201 
2202 #
2203 #	Result is now in FP0
2204 #
2205 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2206 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2207 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2208 	unlk		%a6
2209 	rts
2210 
2211 	global		_ftand_
2212 _ftand_:
2213 	link		%a6,&-LOCAL_SIZE
2214 
2215 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2216 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2217 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2218 
2219 	fmov.l		&0x0,%fpcr		# zero FPCR
2220 
2221 #
2222 #	copy, convert, and tag input argument
2223 #
2224 	fmov.d		0x8(%a6),%fp0		# load dbl input
2225 	fmov.x		%fp0,FP_SRC(%a6)
2226 	lea		FP_SRC(%a6),%a0
2227 	bsr.l		tag			# fetch operand type
2228 	mov.b		%d0,STAG(%a6)
2229 	mov.b		%d0,%d1
2230 
2231 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2232 
2233 	clr.l		%d0
2234 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2235 
2236 	mov.b		%d1,STAG(%a6)
2237 	tst.b		%d1
2238 	bne.b		_L9_2d
2239 	bsr.l		stan			# operand is a NORM
2240 	bra.b		_L9_6d
2241 _L9_2d:
2242 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2243 	bne.b		_L9_3d			# no
2244 	bsr.l		src_zero			# yes
2245 	bra.b		_L9_6d
2246 _L9_3d:
2247 	cmpi.b		%d1,&INF		# is operand an INF?
2248 	bne.b		_L9_4d			# no
2249 	bsr.l		t_operr			# yes
2250 	bra.b		_L9_6d
2251 _L9_4d:
2252 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2253 	bne.b		_L9_5d			# no
2254 	bsr.l		src_qnan			# yes
2255 	bra.b		_L9_6d
2256 _L9_5d:
2257 	bsr.l		stand			# operand is a DENORM
2258 _L9_6d:
2259 
2260 #
2261 #	Result is now in FP0
2262 #
2263 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2264 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2265 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2266 	unlk		%a6
2267 	rts
2268 
2269 	global		_ftanx_
2270 _ftanx_:
2271 	link		%a6,&-LOCAL_SIZE
2272 
2273 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2274 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2275 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2276 
2277 	fmov.l		&0x0,%fpcr		# zero FPCR
2278 
2279 #
2280 #	copy, convert, and tag input argument
2281 #
2282 	lea		FP_SRC(%a6),%a0
2283 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
2284 	mov.l		0x8+0x4(%a6),0x4(%a0)
2285 	mov.l		0x8+0x8(%a6),0x8(%a0)
2286 	bsr.l		tag			# fetch operand type
2287 	mov.b		%d0,STAG(%a6)
2288 	mov.b		%d0,%d1
2289 
2290 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2291 
2292 	clr.l		%d0
2293 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2294 
2295 	tst.b		%d1
2296 	bne.b		_L9_2x
2297 	bsr.l		stan			# operand is a NORM
2298 	bra.b		_L9_6x
2299 _L9_2x:
2300 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2301 	bne.b		_L9_3x			# no
2302 	bsr.l		src_zero			# yes
2303 	bra.b		_L9_6x
2304 _L9_3x:
2305 	cmpi.b		%d1,&INF		# is operand an INF?
2306 	bne.b		_L9_4x			# no
2307 	bsr.l		t_operr			# yes
2308 	bra.b		_L9_6x
2309 _L9_4x:
2310 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2311 	bne.b		_L9_5x			# no
2312 	bsr.l		src_qnan			# yes
2313 	bra.b		_L9_6x
2314 _L9_5x:
2315 	bsr.l		stand			# operand is a DENORM
2316 _L9_6x:
2317 
2318 #
2319 #	Result is now in FP0
2320 #
2321 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2322 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2323 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2324 	unlk		%a6
2325 	rts
2326 
2327 
2328 #########################################################################
2329 # MONADIC TEMPLATE							#
2330 #########################################################################
2331 	global		_fetoxs_
2332 _fetoxs_:
2333 	link		%a6,&-LOCAL_SIZE
2334 
2335 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2336 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2337 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2338 
2339 	fmov.l		&0x0,%fpcr		# zero FPCR
2340 
2341 #
2342 #	copy, convert, and tag input argument
2343 #
2344 	fmov.s		0x8(%a6),%fp0		# load sgl input
2345 	fmov.x		%fp0,FP_SRC(%a6)
2346 	lea		FP_SRC(%a6),%a0
2347 	bsr.l		tag			# fetch operand type
2348 	mov.b		%d0,STAG(%a6)
2349 	mov.b		%d0,%d1
2350 
2351 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2352 
2353 	clr.l		%d0
2354 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2355 
2356 	tst.b		%d1
2357 	bne.b		_L10_2s
2358 	bsr.l		setox			# operand is a NORM
2359 	bra.b		_L10_6s
2360 _L10_2s:
2361 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2362 	bne.b		_L10_3s			# no
2363 	bsr.l		ld_pone			# yes
2364 	bra.b		_L10_6s
2365 _L10_3s:
2366 	cmpi.b		%d1,&INF		# is operand an INF?
2367 	bne.b		_L10_4s			# no
2368 	bsr.l		szr_inf			# yes
2369 	bra.b		_L10_6s
2370 _L10_4s:
2371 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2372 	bne.b		_L10_5s			# no
2373 	bsr.l		src_qnan			# yes
2374 	bra.b		_L10_6s
2375 _L10_5s:
2376 	bsr.l		setoxd			# operand is a DENORM
2377 _L10_6s:
2378 
2379 #
2380 #	Result is now in FP0
2381 #
2382 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2383 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2384 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2385 	unlk		%a6
2386 	rts
2387 
2388 	global		_fetoxd_
2389 _fetoxd_:
2390 	link		%a6,&-LOCAL_SIZE
2391 
2392 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2393 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2394 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2395 
2396 	fmov.l		&0x0,%fpcr		# zero FPCR
2397 
2398 #
2399 #	copy, convert, and tag input argument
2400 #
2401 	fmov.d		0x8(%a6),%fp0		# load dbl input
2402 	fmov.x		%fp0,FP_SRC(%a6)
2403 	lea		FP_SRC(%a6),%a0
2404 	bsr.l		tag			# fetch operand type
2405 	mov.b		%d0,STAG(%a6)
2406 	mov.b		%d0,%d1
2407 
2408 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2409 
2410 	clr.l		%d0
2411 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2412 
2413 	mov.b		%d1,STAG(%a6)
2414 	tst.b		%d1
2415 	bne.b		_L10_2d
2416 	bsr.l		setox			# operand is a NORM
2417 	bra.b		_L10_6d
2418 _L10_2d:
2419 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2420 	bne.b		_L10_3d			# no
2421 	bsr.l		ld_pone			# yes
2422 	bra.b		_L10_6d
2423 _L10_3d:
2424 	cmpi.b		%d1,&INF		# is operand an INF?
2425 	bne.b		_L10_4d			# no
2426 	bsr.l		szr_inf			# yes
2427 	bra.b		_L10_6d
2428 _L10_4d:
2429 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2430 	bne.b		_L10_5d			# no
2431 	bsr.l		src_qnan			# yes
2432 	bra.b		_L10_6d
2433 _L10_5d:
2434 	bsr.l		setoxd			# operand is a DENORM
2435 _L10_6d:
2436 
2437 #
2438 #	Result is now in FP0
2439 #
2440 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2441 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2442 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2443 	unlk		%a6
2444 	rts
2445 
2446 	global		_fetoxx_
2447 _fetoxx_:
2448 	link		%a6,&-LOCAL_SIZE
2449 
2450 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2451 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2452 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2453 
2454 	fmov.l		&0x0,%fpcr		# zero FPCR
2455 
2456 #
2457 #	copy, convert, and tag input argument
2458 #
2459 	lea		FP_SRC(%a6),%a0
2460 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
2461 	mov.l		0x8+0x4(%a6),0x4(%a0)
2462 	mov.l		0x8+0x8(%a6),0x8(%a0)
2463 	bsr.l		tag			# fetch operand type
2464 	mov.b		%d0,STAG(%a6)
2465 	mov.b		%d0,%d1
2466 
2467 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2468 
2469 	clr.l		%d0
2470 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2471 
2472 	tst.b		%d1
2473 	bne.b		_L10_2x
2474 	bsr.l		setox			# operand is a NORM
2475 	bra.b		_L10_6x
2476 _L10_2x:
2477 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2478 	bne.b		_L10_3x			# no
2479 	bsr.l		ld_pone			# yes
2480 	bra.b		_L10_6x
2481 _L10_3x:
2482 	cmpi.b		%d1,&INF		# is operand an INF?
2483 	bne.b		_L10_4x			# no
2484 	bsr.l		szr_inf			# yes
2485 	bra.b		_L10_6x
2486 _L10_4x:
2487 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2488 	bne.b		_L10_5x			# no
2489 	bsr.l		src_qnan			# yes
2490 	bra.b		_L10_6x
2491 _L10_5x:
2492 	bsr.l		setoxd			# operand is a DENORM
2493 _L10_6x:
2494 
2495 #
2496 #	Result is now in FP0
2497 #
2498 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2499 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2500 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2501 	unlk		%a6
2502 	rts
2503 
2504 
2505 #########################################################################
2506 # MONADIC TEMPLATE							#
2507 #########################################################################
2508 	global		_ftwotoxs_
2509 _ftwotoxs_:
2510 	link		%a6,&-LOCAL_SIZE
2511 
2512 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2513 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2514 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2515 
2516 	fmov.l		&0x0,%fpcr		# zero FPCR
2517 
2518 #
2519 #	copy, convert, and tag input argument
2520 #
2521 	fmov.s		0x8(%a6),%fp0		# load sgl input
2522 	fmov.x		%fp0,FP_SRC(%a6)
2523 	lea		FP_SRC(%a6),%a0
2524 	bsr.l		tag			# fetch operand type
2525 	mov.b		%d0,STAG(%a6)
2526 	mov.b		%d0,%d1
2527 
2528 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2529 
2530 	clr.l		%d0
2531 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2532 
2533 	tst.b		%d1
2534 	bne.b		_L11_2s
2535 	bsr.l		stwotox			# operand is a NORM
2536 	bra.b		_L11_6s
2537 _L11_2s:
2538 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2539 	bne.b		_L11_3s			# no
2540 	bsr.l		ld_pone			# yes
2541 	bra.b		_L11_6s
2542 _L11_3s:
2543 	cmpi.b		%d1,&INF		# is operand an INF?
2544 	bne.b		_L11_4s			# no
2545 	bsr.l		szr_inf			# yes
2546 	bra.b		_L11_6s
2547 _L11_4s:
2548 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2549 	bne.b		_L11_5s			# no
2550 	bsr.l		src_qnan			# yes
2551 	bra.b		_L11_6s
2552 _L11_5s:
2553 	bsr.l		stwotoxd			# operand is a DENORM
2554 _L11_6s:
2555 
2556 #
2557 #	Result is now in FP0
2558 #
2559 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2560 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2561 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2562 	unlk		%a6
2563 	rts
2564 
2565 	global		_ftwotoxd_
2566 _ftwotoxd_:
2567 	link		%a6,&-LOCAL_SIZE
2568 
2569 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2570 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2571 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2572 
2573 	fmov.l		&0x0,%fpcr		# zero FPCR
2574 
2575 #
2576 #	copy, convert, and tag input argument
2577 #
2578 	fmov.d		0x8(%a6),%fp0		# load dbl input
2579 	fmov.x		%fp0,FP_SRC(%a6)
2580 	lea		FP_SRC(%a6),%a0
2581 	bsr.l		tag			# fetch operand type
2582 	mov.b		%d0,STAG(%a6)
2583 	mov.b		%d0,%d1
2584 
2585 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2586 
2587 	clr.l		%d0
2588 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2589 
2590 	mov.b		%d1,STAG(%a6)
2591 	tst.b		%d1
2592 	bne.b		_L11_2d
2593 	bsr.l		stwotox			# operand is a NORM
2594 	bra.b		_L11_6d
2595 _L11_2d:
2596 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2597 	bne.b		_L11_3d			# no
2598 	bsr.l		ld_pone			# yes
2599 	bra.b		_L11_6d
2600 _L11_3d:
2601 	cmpi.b		%d1,&INF		# is operand an INF?
2602 	bne.b		_L11_4d			# no
2603 	bsr.l		szr_inf			# yes
2604 	bra.b		_L11_6d
2605 _L11_4d:
2606 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2607 	bne.b		_L11_5d			# no
2608 	bsr.l		src_qnan			# yes
2609 	bra.b		_L11_6d
2610 _L11_5d:
2611 	bsr.l		stwotoxd			# operand is a DENORM
2612 _L11_6d:
2613 
2614 #
2615 #	Result is now in FP0
2616 #
2617 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2618 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2619 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2620 	unlk		%a6
2621 	rts
2622 
2623 	global		_ftwotoxx_
2624 _ftwotoxx_:
2625 	link		%a6,&-LOCAL_SIZE
2626 
2627 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2628 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2629 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2630 
2631 	fmov.l		&0x0,%fpcr		# zero FPCR
2632 
2633 #
2634 #	copy, convert, and tag input argument
2635 #
2636 	lea		FP_SRC(%a6),%a0
2637 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
2638 	mov.l		0x8+0x4(%a6),0x4(%a0)
2639 	mov.l		0x8+0x8(%a6),0x8(%a0)
2640 	bsr.l		tag			# fetch operand type
2641 	mov.b		%d0,STAG(%a6)
2642 	mov.b		%d0,%d1
2643 
2644 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2645 
2646 	clr.l		%d0
2647 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2648 
2649 	tst.b		%d1
2650 	bne.b		_L11_2x
2651 	bsr.l		stwotox			# operand is a NORM
2652 	bra.b		_L11_6x
2653 _L11_2x:
2654 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2655 	bne.b		_L11_3x			# no
2656 	bsr.l		ld_pone			# yes
2657 	bra.b		_L11_6x
2658 _L11_3x:
2659 	cmpi.b		%d1,&INF		# is operand an INF?
2660 	bne.b		_L11_4x			# no
2661 	bsr.l		szr_inf			# yes
2662 	bra.b		_L11_6x
2663 _L11_4x:
2664 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2665 	bne.b		_L11_5x			# no
2666 	bsr.l		src_qnan			# yes
2667 	bra.b		_L11_6x
2668 _L11_5x:
2669 	bsr.l		stwotoxd			# operand is a DENORM
2670 _L11_6x:
2671 
2672 #
2673 #	Result is now in FP0
2674 #
2675 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2676 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2677 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2678 	unlk		%a6
2679 	rts
2680 
2681 
2682 #########################################################################
2683 # MONADIC TEMPLATE							#
2684 #########################################################################
2685 	global		_ftentoxs_
2686 _ftentoxs_:
2687 	link		%a6,&-LOCAL_SIZE
2688 
2689 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2690 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2691 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2692 
2693 	fmov.l		&0x0,%fpcr		# zero FPCR
2694 
2695 #
2696 #	copy, convert, and tag input argument
2697 #
2698 	fmov.s		0x8(%a6),%fp0		# load sgl input
2699 	fmov.x		%fp0,FP_SRC(%a6)
2700 	lea		FP_SRC(%a6),%a0
2701 	bsr.l		tag			# fetch operand type
2702 	mov.b		%d0,STAG(%a6)
2703 	mov.b		%d0,%d1
2704 
2705 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2706 
2707 	clr.l		%d0
2708 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2709 
2710 	tst.b		%d1
2711 	bne.b		_L12_2s
2712 	bsr.l		stentox			# operand is a NORM
2713 	bra.b		_L12_6s
2714 _L12_2s:
2715 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2716 	bne.b		_L12_3s			# no
2717 	bsr.l		ld_pone			# yes
2718 	bra.b		_L12_6s
2719 _L12_3s:
2720 	cmpi.b		%d1,&INF		# is operand an INF?
2721 	bne.b		_L12_4s			# no
2722 	bsr.l		szr_inf			# yes
2723 	bra.b		_L12_6s
2724 _L12_4s:
2725 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2726 	bne.b		_L12_5s			# no
2727 	bsr.l		src_qnan			# yes
2728 	bra.b		_L12_6s
2729 _L12_5s:
2730 	bsr.l		stentoxd			# operand is a DENORM
2731 _L12_6s:
2732 
2733 #
2734 #	Result is now in FP0
2735 #
2736 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2737 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2738 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2739 	unlk		%a6
2740 	rts
2741 
2742 	global		_ftentoxd_
2743 _ftentoxd_:
2744 	link		%a6,&-LOCAL_SIZE
2745 
2746 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2747 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2748 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2749 
2750 	fmov.l		&0x0,%fpcr		# zero FPCR
2751 
2752 #
2753 #	copy, convert, and tag input argument
2754 #
2755 	fmov.d		0x8(%a6),%fp0		# load dbl input
2756 	fmov.x		%fp0,FP_SRC(%a6)
2757 	lea		FP_SRC(%a6),%a0
2758 	bsr.l		tag			# fetch operand type
2759 	mov.b		%d0,STAG(%a6)
2760 	mov.b		%d0,%d1
2761 
2762 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2763 
2764 	clr.l		%d0
2765 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2766 
2767 	mov.b		%d1,STAG(%a6)
2768 	tst.b		%d1
2769 	bne.b		_L12_2d
2770 	bsr.l		stentox			# operand is a NORM
2771 	bra.b		_L12_6d
2772 _L12_2d:
2773 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2774 	bne.b		_L12_3d			# no
2775 	bsr.l		ld_pone			# yes
2776 	bra.b		_L12_6d
2777 _L12_3d:
2778 	cmpi.b		%d1,&INF		# is operand an INF?
2779 	bne.b		_L12_4d			# no
2780 	bsr.l		szr_inf			# yes
2781 	bra.b		_L12_6d
2782 _L12_4d:
2783 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2784 	bne.b		_L12_5d			# no
2785 	bsr.l		src_qnan			# yes
2786 	bra.b		_L12_6d
2787 _L12_5d:
2788 	bsr.l		stentoxd			# operand is a DENORM
2789 _L12_6d:
2790 
2791 #
2792 #	Result is now in FP0
2793 #
2794 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2795 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2796 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2797 	unlk		%a6
2798 	rts
2799 
2800 	global		_ftentoxx_
2801 _ftentoxx_:
2802 	link		%a6,&-LOCAL_SIZE
2803 
2804 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2805 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2806 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2807 
2808 	fmov.l		&0x0,%fpcr		# zero FPCR
2809 
2810 #
2811 #	copy, convert, and tag input argument
2812 #
2813 	lea		FP_SRC(%a6),%a0
2814 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
2815 	mov.l		0x8+0x4(%a6),0x4(%a0)
2816 	mov.l		0x8+0x8(%a6),0x8(%a0)
2817 	bsr.l		tag			# fetch operand type
2818 	mov.b		%d0,STAG(%a6)
2819 	mov.b		%d0,%d1
2820 
2821 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2822 
2823 	clr.l		%d0
2824 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2825 
2826 	tst.b		%d1
2827 	bne.b		_L12_2x
2828 	bsr.l		stentox			# operand is a NORM
2829 	bra.b		_L12_6x
2830 _L12_2x:
2831 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2832 	bne.b		_L12_3x			# no
2833 	bsr.l		ld_pone			# yes
2834 	bra.b		_L12_6x
2835 _L12_3x:
2836 	cmpi.b		%d1,&INF		# is operand an INF?
2837 	bne.b		_L12_4x			# no
2838 	bsr.l		szr_inf			# yes
2839 	bra.b		_L12_6x
2840 _L12_4x:
2841 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2842 	bne.b		_L12_5x			# no
2843 	bsr.l		src_qnan			# yes
2844 	bra.b		_L12_6x
2845 _L12_5x:
2846 	bsr.l		stentoxd			# operand is a DENORM
2847 _L12_6x:
2848 
2849 #
2850 #	Result is now in FP0
2851 #
2852 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2853 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2854 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2855 	unlk		%a6
2856 	rts
2857 
2858 
2859 #########################################################################
2860 # MONADIC TEMPLATE							#
2861 #########################################################################
2862 	global		_flogns_
2863 _flogns_:
2864 	link		%a6,&-LOCAL_SIZE
2865 
2866 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2867 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2868 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2869 
2870 	fmov.l		&0x0,%fpcr		# zero FPCR
2871 
2872 #
2873 #	copy, convert, and tag input argument
2874 #
2875 	fmov.s		0x8(%a6),%fp0		# load sgl input
2876 	fmov.x		%fp0,FP_SRC(%a6)
2877 	lea		FP_SRC(%a6),%a0
2878 	bsr.l		tag			# fetch operand type
2879 	mov.b		%d0,STAG(%a6)
2880 	mov.b		%d0,%d1
2881 
2882 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2883 
2884 	clr.l		%d0
2885 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2886 
2887 	tst.b		%d1
2888 	bne.b		_L13_2s
2889 	bsr.l		slogn			# operand is a NORM
2890 	bra.b		_L13_6s
2891 _L13_2s:
2892 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2893 	bne.b		_L13_3s			# no
2894 	bsr.l		t_dz2			# yes
2895 	bra.b		_L13_6s
2896 _L13_3s:
2897 	cmpi.b		%d1,&INF		# is operand an INF?
2898 	bne.b		_L13_4s			# no
2899 	bsr.l		sopr_inf			# yes
2900 	bra.b		_L13_6s
2901 _L13_4s:
2902 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2903 	bne.b		_L13_5s			# no
2904 	bsr.l		src_qnan			# yes
2905 	bra.b		_L13_6s
2906 _L13_5s:
2907 	bsr.l		slognd			# operand is a DENORM
2908 _L13_6s:
2909 
2910 #
2911 #	Result is now in FP0
2912 #
2913 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2914 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2915 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2916 	unlk		%a6
2917 	rts
2918 
2919 	global		_flognd_
2920 _flognd_:
2921 	link		%a6,&-LOCAL_SIZE
2922 
2923 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2924 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2925 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2926 
2927 	fmov.l		&0x0,%fpcr		# zero FPCR
2928 
2929 #
2930 #	copy, convert, and tag input argument
2931 #
2932 	fmov.d		0x8(%a6),%fp0		# load dbl input
2933 	fmov.x		%fp0,FP_SRC(%a6)
2934 	lea		FP_SRC(%a6),%a0
2935 	bsr.l		tag			# fetch operand type
2936 	mov.b		%d0,STAG(%a6)
2937 	mov.b		%d0,%d1
2938 
2939 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2940 
2941 	clr.l		%d0
2942 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
2943 
2944 	mov.b		%d1,STAG(%a6)
2945 	tst.b		%d1
2946 	bne.b		_L13_2d
2947 	bsr.l		slogn			# operand is a NORM
2948 	bra.b		_L13_6d
2949 _L13_2d:
2950 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
2951 	bne.b		_L13_3d			# no
2952 	bsr.l		t_dz2			# yes
2953 	bra.b		_L13_6d
2954 _L13_3d:
2955 	cmpi.b		%d1,&INF		# is operand an INF?
2956 	bne.b		_L13_4d			# no
2957 	bsr.l		sopr_inf			# yes
2958 	bra.b		_L13_6d
2959 _L13_4d:
2960 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
2961 	bne.b		_L13_5d			# no
2962 	bsr.l		src_qnan			# yes
2963 	bra.b		_L13_6d
2964 _L13_5d:
2965 	bsr.l		slognd			# operand is a DENORM
2966 _L13_6d:
2967 
2968 #
2969 #	Result is now in FP0
2970 #
2971 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
2972 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
2973 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
2974 	unlk		%a6
2975 	rts
2976 
2977 	global		_flognx_
2978 _flognx_:
2979 	link		%a6,&-LOCAL_SIZE
2980 
2981 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
2982 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
2983 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
2984 
2985 	fmov.l		&0x0,%fpcr		# zero FPCR
2986 
2987 #
2988 #	copy, convert, and tag input argument
2989 #
2990 	lea		FP_SRC(%a6),%a0
2991 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
2992 	mov.l		0x8+0x4(%a6),0x4(%a0)
2993 	mov.l		0x8+0x8(%a6),0x8(%a0)
2994 	bsr.l		tag			# fetch operand type
2995 	mov.b		%d0,STAG(%a6)
2996 	mov.b		%d0,%d1
2997 
2998 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
2999 
3000 	clr.l		%d0
3001 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3002 
3003 	tst.b		%d1
3004 	bne.b		_L13_2x
3005 	bsr.l		slogn			# operand is a NORM
3006 	bra.b		_L13_6x
3007 _L13_2x:
3008 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3009 	bne.b		_L13_3x			# no
3010 	bsr.l		t_dz2			# yes
3011 	bra.b		_L13_6x
3012 _L13_3x:
3013 	cmpi.b		%d1,&INF		# is operand an INF?
3014 	bne.b		_L13_4x			# no
3015 	bsr.l		sopr_inf			# yes
3016 	bra.b		_L13_6x
3017 _L13_4x:
3018 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3019 	bne.b		_L13_5x			# no
3020 	bsr.l		src_qnan			# yes
3021 	bra.b		_L13_6x
3022 _L13_5x:
3023 	bsr.l		slognd			# operand is a DENORM
3024 _L13_6x:
3025 
3026 #
3027 #	Result is now in FP0
3028 #
3029 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3030 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3031 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3032 	unlk		%a6
3033 	rts
3034 
3035 
3036 #########################################################################
3037 # MONADIC TEMPLATE							#
3038 #########################################################################
3039 	global		_flog10s_
3040 _flog10s_:
3041 	link		%a6,&-LOCAL_SIZE
3042 
3043 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3044 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3045 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3046 
3047 	fmov.l		&0x0,%fpcr		# zero FPCR
3048 
3049 #
3050 #	copy, convert, and tag input argument
3051 #
3052 	fmov.s		0x8(%a6),%fp0		# load sgl input
3053 	fmov.x		%fp0,FP_SRC(%a6)
3054 	lea		FP_SRC(%a6),%a0
3055 	bsr.l		tag			# fetch operand type
3056 	mov.b		%d0,STAG(%a6)
3057 	mov.b		%d0,%d1
3058 
3059 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3060 
3061 	clr.l		%d0
3062 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3063 
3064 	tst.b		%d1
3065 	bne.b		_L14_2s
3066 	bsr.l		slog10			# operand is a NORM
3067 	bra.b		_L14_6s
3068 _L14_2s:
3069 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3070 	bne.b		_L14_3s			# no
3071 	bsr.l		t_dz2			# yes
3072 	bra.b		_L14_6s
3073 _L14_3s:
3074 	cmpi.b		%d1,&INF		# is operand an INF?
3075 	bne.b		_L14_4s			# no
3076 	bsr.l		sopr_inf			# yes
3077 	bra.b		_L14_6s
3078 _L14_4s:
3079 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3080 	bne.b		_L14_5s			# no
3081 	bsr.l		src_qnan			# yes
3082 	bra.b		_L14_6s
3083 _L14_5s:
3084 	bsr.l		slog10d			# operand is a DENORM
3085 _L14_6s:
3086 
3087 #
3088 #	Result is now in FP0
3089 #
3090 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3091 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3092 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3093 	unlk		%a6
3094 	rts
3095 
3096 	global		_flog10d_
3097 _flog10d_:
3098 	link		%a6,&-LOCAL_SIZE
3099 
3100 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3101 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3102 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3103 
3104 	fmov.l		&0x0,%fpcr		# zero FPCR
3105 
3106 #
3107 #	copy, convert, and tag input argument
3108 #
3109 	fmov.d		0x8(%a6),%fp0		# load dbl input
3110 	fmov.x		%fp0,FP_SRC(%a6)
3111 	lea		FP_SRC(%a6),%a0
3112 	bsr.l		tag			# fetch operand type
3113 	mov.b		%d0,STAG(%a6)
3114 	mov.b		%d0,%d1
3115 
3116 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3117 
3118 	clr.l		%d0
3119 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3120 
3121 	mov.b		%d1,STAG(%a6)
3122 	tst.b		%d1
3123 	bne.b		_L14_2d
3124 	bsr.l		slog10			# operand is a NORM
3125 	bra.b		_L14_6d
3126 _L14_2d:
3127 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3128 	bne.b		_L14_3d			# no
3129 	bsr.l		t_dz2			# yes
3130 	bra.b		_L14_6d
3131 _L14_3d:
3132 	cmpi.b		%d1,&INF		# is operand an INF?
3133 	bne.b		_L14_4d			# no
3134 	bsr.l		sopr_inf			# yes
3135 	bra.b		_L14_6d
3136 _L14_4d:
3137 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3138 	bne.b		_L14_5d			# no
3139 	bsr.l		src_qnan			# yes
3140 	bra.b		_L14_6d
3141 _L14_5d:
3142 	bsr.l		slog10d			# operand is a DENORM
3143 _L14_6d:
3144 
3145 #
3146 #	Result is now in FP0
3147 #
3148 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3149 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3150 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3151 	unlk		%a6
3152 	rts
3153 
3154 	global		_flog10x_
3155 _flog10x_:
3156 	link		%a6,&-LOCAL_SIZE
3157 
3158 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3159 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3160 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3161 
3162 	fmov.l		&0x0,%fpcr		# zero FPCR
3163 
3164 #
3165 #	copy, convert, and tag input argument
3166 #
3167 	lea		FP_SRC(%a6),%a0
3168 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
3169 	mov.l		0x8+0x4(%a6),0x4(%a0)
3170 	mov.l		0x8+0x8(%a6),0x8(%a0)
3171 	bsr.l		tag			# fetch operand type
3172 	mov.b		%d0,STAG(%a6)
3173 	mov.b		%d0,%d1
3174 
3175 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3176 
3177 	clr.l		%d0
3178 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3179 
3180 	tst.b		%d1
3181 	bne.b		_L14_2x
3182 	bsr.l		slog10			# operand is a NORM
3183 	bra.b		_L14_6x
3184 _L14_2x:
3185 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3186 	bne.b		_L14_3x			# no
3187 	bsr.l		t_dz2			# yes
3188 	bra.b		_L14_6x
3189 _L14_3x:
3190 	cmpi.b		%d1,&INF		# is operand an INF?
3191 	bne.b		_L14_4x			# no
3192 	bsr.l		sopr_inf			# yes
3193 	bra.b		_L14_6x
3194 _L14_4x:
3195 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3196 	bne.b		_L14_5x			# no
3197 	bsr.l		src_qnan			# yes
3198 	bra.b		_L14_6x
3199 _L14_5x:
3200 	bsr.l		slog10d			# operand is a DENORM
3201 _L14_6x:
3202 
3203 #
3204 #	Result is now in FP0
3205 #
3206 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3207 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3208 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3209 	unlk		%a6
3210 	rts
3211 
3212 
3213 #########################################################################
3214 # MONADIC TEMPLATE							#
3215 #########################################################################
3216 	global		_flog2s_
3217 _flog2s_:
3218 	link		%a6,&-LOCAL_SIZE
3219 
3220 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3221 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3222 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3223 
3224 	fmov.l		&0x0,%fpcr		# zero FPCR
3225 
3226 #
3227 #	copy, convert, and tag input argument
3228 #
3229 	fmov.s		0x8(%a6),%fp0		# load sgl input
3230 	fmov.x		%fp0,FP_SRC(%a6)
3231 	lea		FP_SRC(%a6),%a0
3232 	bsr.l		tag			# fetch operand type
3233 	mov.b		%d0,STAG(%a6)
3234 	mov.b		%d0,%d1
3235 
3236 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3237 
3238 	clr.l		%d0
3239 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3240 
3241 	tst.b		%d1
3242 	bne.b		_L15_2s
3243 	bsr.l		slog2			# operand is a NORM
3244 	bra.b		_L15_6s
3245 _L15_2s:
3246 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3247 	bne.b		_L15_3s			# no
3248 	bsr.l		t_dz2			# yes
3249 	bra.b		_L15_6s
3250 _L15_3s:
3251 	cmpi.b		%d1,&INF		# is operand an INF?
3252 	bne.b		_L15_4s			# no
3253 	bsr.l		sopr_inf			# yes
3254 	bra.b		_L15_6s
3255 _L15_4s:
3256 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3257 	bne.b		_L15_5s			# no
3258 	bsr.l		src_qnan			# yes
3259 	bra.b		_L15_6s
3260 _L15_5s:
3261 	bsr.l		slog2d			# operand is a DENORM
3262 _L15_6s:
3263 
3264 #
3265 #	Result is now in FP0
3266 #
3267 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3268 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3269 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3270 	unlk		%a6
3271 	rts
3272 
3273 	global		_flog2d_
3274 _flog2d_:
3275 	link		%a6,&-LOCAL_SIZE
3276 
3277 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3278 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3279 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3280 
3281 	fmov.l		&0x0,%fpcr		# zero FPCR
3282 
3283 #
3284 #	copy, convert, and tag input argument
3285 #
3286 	fmov.d		0x8(%a6),%fp0		# load dbl input
3287 	fmov.x		%fp0,FP_SRC(%a6)
3288 	lea		FP_SRC(%a6),%a0
3289 	bsr.l		tag			# fetch operand type
3290 	mov.b		%d0,STAG(%a6)
3291 	mov.b		%d0,%d1
3292 
3293 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3294 
3295 	clr.l		%d0
3296 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3297 
3298 	mov.b		%d1,STAG(%a6)
3299 	tst.b		%d1
3300 	bne.b		_L15_2d
3301 	bsr.l		slog2			# operand is a NORM
3302 	bra.b		_L15_6d
3303 _L15_2d:
3304 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3305 	bne.b		_L15_3d			# no
3306 	bsr.l		t_dz2			# yes
3307 	bra.b		_L15_6d
3308 _L15_3d:
3309 	cmpi.b		%d1,&INF		# is operand an INF?
3310 	bne.b		_L15_4d			# no
3311 	bsr.l		sopr_inf			# yes
3312 	bra.b		_L15_6d
3313 _L15_4d:
3314 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3315 	bne.b		_L15_5d			# no
3316 	bsr.l		src_qnan			# yes
3317 	bra.b		_L15_6d
3318 _L15_5d:
3319 	bsr.l		slog2d			# operand is a DENORM
3320 _L15_6d:
3321 
3322 #
3323 #	Result is now in FP0
3324 #
3325 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3326 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3327 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3328 	unlk		%a6
3329 	rts
3330 
3331 	global		_flog2x_
3332 _flog2x_:
3333 	link		%a6,&-LOCAL_SIZE
3334 
3335 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3336 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3337 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3338 
3339 	fmov.l		&0x0,%fpcr		# zero FPCR
3340 
3341 #
3342 #	copy, convert, and tag input argument
3343 #
3344 	lea		FP_SRC(%a6),%a0
3345 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
3346 	mov.l		0x8+0x4(%a6),0x4(%a0)
3347 	mov.l		0x8+0x8(%a6),0x8(%a0)
3348 	bsr.l		tag			# fetch operand type
3349 	mov.b		%d0,STAG(%a6)
3350 	mov.b		%d0,%d1
3351 
3352 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3353 
3354 	clr.l		%d0
3355 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3356 
3357 	tst.b		%d1
3358 	bne.b		_L15_2x
3359 	bsr.l		slog2			# operand is a NORM
3360 	bra.b		_L15_6x
3361 _L15_2x:
3362 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3363 	bne.b		_L15_3x			# no
3364 	bsr.l		t_dz2			# yes
3365 	bra.b		_L15_6x
3366 _L15_3x:
3367 	cmpi.b		%d1,&INF		# is operand an INF?
3368 	bne.b		_L15_4x			# no
3369 	bsr.l		sopr_inf			# yes
3370 	bra.b		_L15_6x
3371 _L15_4x:
3372 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3373 	bne.b		_L15_5x			# no
3374 	bsr.l		src_qnan			# yes
3375 	bra.b		_L15_6x
3376 _L15_5x:
3377 	bsr.l		slog2d			# operand is a DENORM
3378 _L15_6x:
3379 
3380 #
3381 #	Result is now in FP0
3382 #
3383 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3384 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3385 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3386 	unlk		%a6
3387 	rts
3388 
3389 
3390 #########################################################################
3391 # MONADIC TEMPLATE							#
3392 #########################################################################
3393 	global		_fcoshs_
3394 _fcoshs_:
3395 	link		%a6,&-LOCAL_SIZE
3396 
3397 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3398 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3399 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3400 
3401 	fmov.l		&0x0,%fpcr		# zero FPCR
3402 
3403 #
3404 #	copy, convert, and tag input argument
3405 #
3406 	fmov.s		0x8(%a6),%fp0		# load sgl input
3407 	fmov.x		%fp0,FP_SRC(%a6)
3408 	lea		FP_SRC(%a6),%a0
3409 	bsr.l		tag			# fetch operand type
3410 	mov.b		%d0,STAG(%a6)
3411 	mov.b		%d0,%d1
3412 
3413 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3414 
3415 	clr.l		%d0
3416 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3417 
3418 	tst.b		%d1
3419 	bne.b		_L16_2s
3420 	bsr.l		scosh			# operand is a NORM
3421 	bra.b		_L16_6s
3422 _L16_2s:
3423 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3424 	bne.b		_L16_3s			# no
3425 	bsr.l		ld_pone			# yes
3426 	bra.b		_L16_6s
3427 _L16_3s:
3428 	cmpi.b		%d1,&INF		# is operand an INF?
3429 	bne.b		_L16_4s			# no
3430 	bsr.l		ld_pinf			# yes
3431 	bra.b		_L16_6s
3432 _L16_4s:
3433 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3434 	bne.b		_L16_5s			# no
3435 	bsr.l		src_qnan			# yes
3436 	bra.b		_L16_6s
3437 _L16_5s:
3438 	bsr.l		scoshd			# operand is a DENORM
3439 _L16_6s:
3440 
3441 #
3442 #	Result is now in FP0
3443 #
3444 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3445 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3446 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3447 	unlk		%a6
3448 	rts
3449 
3450 	global		_fcoshd_
3451 _fcoshd_:
3452 	link		%a6,&-LOCAL_SIZE
3453 
3454 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3455 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3456 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3457 
3458 	fmov.l		&0x0,%fpcr		# zero FPCR
3459 
3460 #
3461 #	copy, convert, and tag input argument
3462 #
3463 	fmov.d		0x8(%a6),%fp0		# load dbl input
3464 	fmov.x		%fp0,FP_SRC(%a6)
3465 	lea		FP_SRC(%a6),%a0
3466 	bsr.l		tag			# fetch operand type
3467 	mov.b		%d0,STAG(%a6)
3468 	mov.b		%d0,%d1
3469 
3470 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3471 
3472 	clr.l		%d0
3473 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3474 
3475 	mov.b		%d1,STAG(%a6)
3476 	tst.b		%d1
3477 	bne.b		_L16_2d
3478 	bsr.l		scosh			# operand is a NORM
3479 	bra.b		_L16_6d
3480 _L16_2d:
3481 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3482 	bne.b		_L16_3d			# no
3483 	bsr.l		ld_pone			# yes
3484 	bra.b		_L16_6d
3485 _L16_3d:
3486 	cmpi.b		%d1,&INF		# is operand an INF?
3487 	bne.b		_L16_4d			# no
3488 	bsr.l		ld_pinf			# yes
3489 	bra.b		_L16_6d
3490 _L16_4d:
3491 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3492 	bne.b		_L16_5d			# no
3493 	bsr.l		src_qnan			# yes
3494 	bra.b		_L16_6d
3495 _L16_5d:
3496 	bsr.l		scoshd			# operand is a DENORM
3497 _L16_6d:
3498 
3499 #
3500 #	Result is now in FP0
3501 #
3502 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3503 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3504 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3505 	unlk		%a6
3506 	rts
3507 
3508 	global		_fcoshx_
3509 _fcoshx_:
3510 	link		%a6,&-LOCAL_SIZE
3511 
3512 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3513 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3514 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3515 
3516 	fmov.l		&0x0,%fpcr		# zero FPCR
3517 
3518 #
3519 #	copy, convert, and tag input argument
3520 #
3521 	lea		FP_SRC(%a6),%a0
3522 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
3523 	mov.l		0x8+0x4(%a6),0x4(%a0)
3524 	mov.l		0x8+0x8(%a6),0x8(%a0)
3525 	bsr.l		tag			# fetch operand type
3526 	mov.b		%d0,STAG(%a6)
3527 	mov.b		%d0,%d1
3528 
3529 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3530 
3531 	clr.l		%d0
3532 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3533 
3534 	tst.b		%d1
3535 	bne.b		_L16_2x
3536 	bsr.l		scosh			# operand is a NORM
3537 	bra.b		_L16_6x
3538 _L16_2x:
3539 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3540 	bne.b		_L16_3x			# no
3541 	bsr.l		ld_pone			# yes
3542 	bra.b		_L16_6x
3543 _L16_3x:
3544 	cmpi.b		%d1,&INF		# is operand an INF?
3545 	bne.b		_L16_4x			# no
3546 	bsr.l		ld_pinf			# yes
3547 	bra.b		_L16_6x
3548 _L16_4x:
3549 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3550 	bne.b		_L16_5x			# no
3551 	bsr.l		src_qnan			# yes
3552 	bra.b		_L16_6x
3553 _L16_5x:
3554 	bsr.l		scoshd			# operand is a DENORM
3555 _L16_6x:
3556 
3557 #
3558 #	Result is now in FP0
3559 #
3560 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3561 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3562 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3563 	unlk		%a6
3564 	rts
3565 
3566 
3567 #########################################################################
3568 # MONADIC TEMPLATE							#
3569 #########################################################################
3570 	global		_facoss_
3571 _facoss_:
3572 	link		%a6,&-LOCAL_SIZE
3573 
3574 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3575 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3576 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3577 
3578 	fmov.l		&0x0,%fpcr		# zero FPCR
3579 
3580 #
3581 #	copy, convert, and tag input argument
3582 #
3583 	fmov.s		0x8(%a6),%fp0		# load sgl input
3584 	fmov.x		%fp0,FP_SRC(%a6)
3585 	lea		FP_SRC(%a6),%a0
3586 	bsr.l		tag			# fetch operand type
3587 	mov.b		%d0,STAG(%a6)
3588 	mov.b		%d0,%d1
3589 
3590 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3591 
3592 	clr.l		%d0
3593 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3594 
3595 	tst.b		%d1
3596 	bne.b		_L17_2s
3597 	bsr.l		sacos			# operand is a NORM
3598 	bra.b		_L17_6s
3599 _L17_2s:
3600 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3601 	bne.b		_L17_3s			# no
3602 	bsr.l		ld_ppi2			# yes
3603 	bra.b		_L17_6s
3604 _L17_3s:
3605 	cmpi.b		%d1,&INF		# is operand an INF?
3606 	bne.b		_L17_4s			# no
3607 	bsr.l		t_operr			# yes
3608 	bra.b		_L17_6s
3609 _L17_4s:
3610 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3611 	bne.b		_L17_5s			# no
3612 	bsr.l		src_qnan			# yes
3613 	bra.b		_L17_6s
3614 _L17_5s:
3615 	bsr.l		sacosd			# operand is a DENORM
3616 _L17_6s:
3617 
3618 #
3619 #	Result is now in FP0
3620 #
3621 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3622 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3623 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3624 	unlk		%a6
3625 	rts
3626 
3627 	global		_facosd_
3628 _facosd_:
3629 	link		%a6,&-LOCAL_SIZE
3630 
3631 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3632 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3633 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3634 
3635 	fmov.l		&0x0,%fpcr		# zero FPCR
3636 
3637 #
3638 #	copy, convert, and tag input argument
3639 #
3640 	fmov.d		0x8(%a6),%fp0		# load dbl input
3641 	fmov.x		%fp0,FP_SRC(%a6)
3642 	lea		FP_SRC(%a6),%a0
3643 	bsr.l		tag			# fetch operand type
3644 	mov.b		%d0,STAG(%a6)
3645 	mov.b		%d0,%d1
3646 
3647 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3648 
3649 	clr.l		%d0
3650 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3651 
3652 	mov.b		%d1,STAG(%a6)
3653 	tst.b		%d1
3654 	bne.b		_L17_2d
3655 	bsr.l		sacos			# operand is a NORM
3656 	bra.b		_L17_6d
3657 _L17_2d:
3658 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3659 	bne.b		_L17_3d			# no
3660 	bsr.l		ld_ppi2			# yes
3661 	bra.b		_L17_6d
3662 _L17_3d:
3663 	cmpi.b		%d1,&INF		# is operand an INF?
3664 	bne.b		_L17_4d			# no
3665 	bsr.l		t_operr			# yes
3666 	bra.b		_L17_6d
3667 _L17_4d:
3668 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3669 	bne.b		_L17_5d			# no
3670 	bsr.l		src_qnan			# yes
3671 	bra.b		_L17_6d
3672 _L17_5d:
3673 	bsr.l		sacosd			# operand is a DENORM
3674 _L17_6d:
3675 
3676 #
3677 #	Result is now in FP0
3678 #
3679 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3680 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3681 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3682 	unlk		%a6
3683 	rts
3684 
3685 	global		_facosx_
3686 _facosx_:
3687 	link		%a6,&-LOCAL_SIZE
3688 
3689 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3690 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3691 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3692 
3693 	fmov.l		&0x0,%fpcr		# zero FPCR
3694 
3695 #
3696 #	copy, convert, and tag input argument
3697 #
3698 	lea		FP_SRC(%a6),%a0
3699 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
3700 	mov.l		0x8+0x4(%a6),0x4(%a0)
3701 	mov.l		0x8+0x8(%a6),0x8(%a0)
3702 	bsr.l		tag			# fetch operand type
3703 	mov.b		%d0,STAG(%a6)
3704 	mov.b		%d0,%d1
3705 
3706 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3707 
3708 	clr.l		%d0
3709 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3710 
3711 	tst.b		%d1
3712 	bne.b		_L17_2x
3713 	bsr.l		sacos			# operand is a NORM
3714 	bra.b		_L17_6x
3715 _L17_2x:
3716 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3717 	bne.b		_L17_3x			# no
3718 	bsr.l		ld_ppi2			# yes
3719 	bra.b		_L17_6x
3720 _L17_3x:
3721 	cmpi.b		%d1,&INF		# is operand an INF?
3722 	bne.b		_L17_4x			# no
3723 	bsr.l		t_operr			# yes
3724 	bra.b		_L17_6x
3725 _L17_4x:
3726 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3727 	bne.b		_L17_5x			# no
3728 	bsr.l		src_qnan			# yes
3729 	bra.b		_L17_6x
3730 _L17_5x:
3731 	bsr.l		sacosd			# operand is a DENORM
3732 _L17_6x:
3733 
3734 #
3735 #	Result is now in FP0
3736 #
3737 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3738 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3739 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3740 	unlk		%a6
3741 	rts
3742 
3743 
3744 #########################################################################
3745 # MONADIC TEMPLATE							#
3746 #########################################################################
3747 	global		_fgetexps_
3748 _fgetexps_:
3749 	link		%a6,&-LOCAL_SIZE
3750 
3751 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3752 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3753 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3754 
3755 	fmov.l		&0x0,%fpcr		# zero FPCR
3756 
3757 #
3758 #	copy, convert, and tag input argument
3759 #
3760 	fmov.s		0x8(%a6),%fp0		# load sgl input
3761 	fmov.x		%fp0,FP_SRC(%a6)
3762 	lea		FP_SRC(%a6),%a0
3763 	bsr.l		tag			# fetch operand type
3764 	mov.b		%d0,STAG(%a6)
3765 	mov.b		%d0,%d1
3766 
3767 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3768 
3769 	clr.l		%d0
3770 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3771 
3772 	tst.b		%d1
3773 	bne.b		_L18_2s
3774 	bsr.l		sgetexp			# operand is a NORM
3775 	bra.b		_L18_6s
3776 _L18_2s:
3777 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3778 	bne.b		_L18_3s			# no
3779 	bsr.l		src_zero			# yes
3780 	bra.b		_L18_6s
3781 _L18_3s:
3782 	cmpi.b		%d1,&INF		# is operand an INF?
3783 	bne.b		_L18_4s			# no
3784 	bsr.l		t_operr			# yes
3785 	bra.b		_L18_6s
3786 _L18_4s:
3787 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3788 	bne.b		_L18_5s			# no
3789 	bsr.l		src_qnan			# yes
3790 	bra.b		_L18_6s
3791 _L18_5s:
3792 	bsr.l		sgetexpd			# operand is a DENORM
3793 _L18_6s:
3794 
3795 #
3796 #	Result is now in FP0
3797 #
3798 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3799 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3800 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3801 	unlk		%a6
3802 	rts
3803 
3804 	global		_fgetexpd_
3805 _fgetexpd_:
3806 	link		%a6,&-LOCAL_SIZE
3807 
3808 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3809 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3810 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3811 
3812 	fmov.l		&0x0,%fpcr		# zero FPCR
3813 
3814 #
3815 #	copy, convert, and tag input argument
3816 #
3817 	fmov.d		0x8(%a6),%fp0		# load dbl input
3818 	fmov.x		%fp0,FP_SRC(%a6)
3819 	lea		FP_SRC(%a6),%a0
3820 	bsr.l		tag			# fetch operand type
3821 	mov.b		%d0,STAG(%a6)
3822 	mov.b		%d0,%d1
3823 
3824 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3825 
3826 	clr.l		%d0
3827 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3828 
3829 	mov.b		%d1,STAG(%a6)
3830 	tst.b		%d1
3831 	bne.b		_L18_2d
3832 	bsr.l		sgetexp			# operand is a NORM
3833 	bra.b		_L18_6d
3834 _L18_2d:
3835 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3836 	bne.b		_L18_3d			# no
3837 	bsr.l		src_zero			# yes
3838 	bra.b		_L18_6d
3839 _L18_3d:
3840 	cmpi.b		%d1,&INF		# is operand an INF?
3841 	bne.b		_L18_4d			# no
3842 	bsr.l		t_operr			# yes
3843 	bra.b		_L18_6d
3844 _L18_4d:
3845 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3846 	bne.b		_L18_5d			# no
3847 	bsr.l		src_qnan			# yes
3848 	bra.b		_L18_6d
3849 _L18_5d:
3850 	bsr.l		sgetexpd			# operand is a DENORM
3851 _L18_6d:
3852 
3853 #
3854 #	Result is now in FP0
3855 #
3856 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3857 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3858 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3859 	unlk		%a6
3860 	rts
3861 
3862 	global		_fgetexpx_
3863 _fgetexpx_:
3864 	link		%a6,&-LOCAL_SIZE
3865 
3866 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3867 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3868 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3869 
3870 	fmov.l		&0x0,%fpcr		# zero FPCR
3871 
3872 #
3873 #	copy, convert, and tag input argument
3874 #
3875 	lea		FP_SRC(%a6),%a0
3876 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
3877 	mov.l		0x8+0x4(%a6),0x4(%a0)
3878 	mov.l		0x8+0x8(%a6),0x8(%a0)
3879 	bsr.l		tag			# fetch operand type
3880 	mov.b		%d0,STAG(%a6)
3881 	mov.b		%d0,%d1
3882 
3883 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3884 
3885 	clr.l		%d0
3886 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3887 
3888 	tst.b		%d1
3889 	bne.b		_L18_2x
3890 	bsr.l		sgetexp			# operand is a NORM
3891 	bra.b		_L18_6x
3892 _L18_2x:
3893 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3894 	bne.b		_L18_3x			# no
3895 	bsr.l		src_zero			# yes
3896 	bra.b		_L18_6x
3897 _L18_3x:
3898 	cmpi.b		%d1,&INF		# is operand an INF?
3899 	bne.b		_L18_4x			# no
3900 	bsr.l		t_operr			# yes
3901 	bra.b		_L18_6x
3902 _L18_4x:
3903 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3904 	bne.b		_L18_5x			# no
3905 	bsr.l		src_qnan			# yes
3906 	bra.b		_L18_6x
3907 _L18_5x:
3908 	bsr.l		sgetexpd			# operand is a DENORM
3909 _L18_6x:
3910 
3911 #
3912 #	Result is now in FP0
3913 #
3914 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3915 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3916 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3917 	unlk		%a6
3918 	rts
3919 
3920 
3921 #########################################################################
3922 # MONADIC TEMPLATE							#
3923 #########################################################################
3924 	global		_fgetmans_
3925 _fgetmans_:
3926 	link		%a6,&-LOCAL_SIZE
3927 
3928 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3929 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3930 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3931 
3932 	fmov.l		&0x0,%fpcr		# zero FPCR
3933 
3934 #
3935 #	copy, convert, and tag input argument
3936 #
3937 	fmov.s		0x8(%a6),%fp0		# load sgl input
3938 	fmov.x		%fp0,FP_SRC(%a6)
3939 	lea		FP_SRC(%a6),%a0
3940 	bsr.l		tag			# fetch operand type
3941 	mov.b		%d0,STAG(%a6)
3942 	mov.b		%d0,%d1
3943 
3944 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
3945 
3946 	clr.l		%d0
3947 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
3948 
3949 	tst.b		%d1
3950 	bne.b		_L19_2s
3951 	bsr.l		sgetman			# operand is a NORM
3952 	bra.b		_L19_6s
3953 _L19_2s:
3954 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
3955 	bne.b		_L19_3s			# no
3956 	bsr.l		src_zero			# yes
3957 	bra.b		_L19_6s
3958 _L19_3s:
3959 	cmpi.b		%d1,&INF		# is operand an INF?
3960 	bne.b		_L19_4s			# no
3961 	bsr.l		t_operr			# yes
3962 	bra.b		_L19_6s
3963 _L19_4s:
3964 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
3965 	bne.b		_L19_5s			# no
3966 	bsr.l		src_qnan			# yes
3967 	bra.b		_L19_6s
3968 _L19_5s:
3969 	bsr.l		sgetmand			# operand is a DENORM
3970 _L19_6s:
3971 
3972 #
3973 #	Result is now in FP0
3974 #
3975 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
3976 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
3977 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
3978 	unlk		%a6
3979 	rts
3980 
3981 	global		_fgetmand_
3982 _fgetmand_:
3983 	link		%a6,&-LOCAL_SIZE
3984 
3985 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
3986 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
3987 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
3988 
3989 	fmov.l		&0x0,%fpcr		# zero FPCR
3990 
3991 #
3992 #	copy, convert, and tag input argument
3993 #
3994 	fmov.d		0x8(%a6),%fp0		# load dbl input
3995 	fmov.x		%fp0,FP_SRC(%a6)
3996 	lea		FP_SRC(%a6),%a0
3997 	bsr.l		tag			# fetch operand type
3998 	mov.b		%d0,STAG(%a6)
3999 	mov.b		%d0,%d1
4000 
4001 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4002 
4003 	clr.l		%d0
4004 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4005 
4006 	mov.b		%d1,STAG(%a6)
4007 	tst.b		%d1
4008 	bne.b		_L19_2d
4009 	bsr.l		sgetman			# operand is a NORM
4010 	bra.b		_L19_6d
4011 _L19_2d:
4012 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4013 	bne.b		_L19_3d			# no
4014 	bsr.l		src_zero			# yes
4015 	bra.b		_L19_6d
4016 _L19_3d:
4017 	cmpi.b		%d1,&INF		# is operand an INF?
4018 	bne.b		_L19_4d			# no
4019 	bsr.l		t_operr			# yes
4020 	bra.b		_L19_6d
4021 _L19_4d:
4022 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4023 	bne.b		_L19_5d			# no
4024 	bsr.l		src_qnan			# yes
4025 	bra.b		_L19_6d
4026 _L19_5d:
4027 	bsr.l		sgetmand			# operand is a DENORM
4028 _L19_6d:
4029 
4030 #
4031 #	Result is now in FP0
4032 #
4033 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4034 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4035 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4036 	unlk		%a6
4037 	rts
4038 
4039 	global		_fgetmanx_
4040 _fgetmanx_:
4041 	link		%a6,&-LOCAL_SIZE
4042 
4043 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4044 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4045 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4046 
4047 	fmov.l		&0x0,%fpcr		# zero FPCR
4048 
4049 #
4050 #	copy, convert, and tag input argument
4051 #
4052 	lea		FP_SRC(%a6),%a0
4053 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
4054 	mov.l		0x8+0x4(%a6),0x4(%a0)
4055 	mov.l		0x8+0x8(%a6),0x8(%a0)
4056 	bsr.l		tag			# fetch operand type
4057 	mov.b		%d0,STAG(%a6)
4058 	mov.b		%d0,%d1
4059 
4060 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4061 
4062 	clr.l		%d0
4063 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4064 
4065 	tst.b		%d1
4066 	bne.b		_L19_2x
4067 	bsr.l		sgetman			# operand is a NORM
4068 	bra.b		_L19_6x
4069 _L19_2x:
4070 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4071 	bne.b		_L19_3x			# no
4072 	bsr.l		src_zero			# yes
4073 	bra.b		_L19_6x
4074 _L19_3x:
4075 	cmpi.b		%d1,&INF		# is operand an INF?
4076 	bne.b		_L19_4x			# no
4077 	bsr.l		t_operr			# yes
4078 	bra.b		_L19_6x
4079 _L19_4x:
4080 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4081 	bne.b		_L19_5x			# no
4082 	bsr.l		src_qnan			# yes
4083 	bra.b		_L19_6x
4084 _L19_5x:
4085 	bsr.l		sgetmand			# operand is a DENORM
4086 _L19_6x:
4087 
4088 #
4089 #	Result is now in FP0
4090 #
4091 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4092 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4093 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4094 	unlk		%a6
4095 	rts
4096 
4097 
4098 #########################################################################
4099 # MONADIC TEMPLATE							#
4100 #########################################################################
4101 	global		_fsincoss_
4102 _fsincoss_:
4103 	link		%a6,&-LOCAL_SIZE
4104 
4105 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4106 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4107 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4108 
4109 	fmov.l		&0x0,%fpcr		# zero FPCR
4110 
4111 #
4112 #	copy, convert, and tag input argument
4113 #
4114 	fmov.s		0x8(%a6),%fp0		# load sgl input
4115 	fmov.x		%fp0,FP_SRC(%a6)
4116 	lea		FP_SRC(%a6),%a0
4117 	bsr.l		tag			# fetch operand type
4118 	mov.b		%d0,STAG(%a6)
4119 	mov.b		%d0,%d1
4120 
4121 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4122 
4123 	clr.l		%d0
4124 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4125 
4126 	tst.b		%d1
4127 	bne.b		_L20_2s
4128 	bsr.l		ssincos			# operand is a NORM
4129 	bra.b		_L20_6s
4130 _L20_2s:
4131 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4132 	bne.b		_L20_3s			# no
4133 	bsr.l		ssincosz			# yes
4134 	bra.b		_L20_6s
4135 _L20_3s:
4136 	cmpi.b		%d1,&INF		# is operand an INF?
4137 	bne.b		_L20_4s			# no
4138 	bsr.l		ssincosi			# yes
4139 	bra.b		_L20_6s
4140 _L20_4s:
4141 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4142 	bne.b		_L20_5s			# no
4143 	bsr.l		ssincosqnan			# yes
4144 	bra.b		_L20_6s
4145 _L20_5s:
4146 	bsr.l		ssincosd			# operand is a DENORM
4147 _L20_6s:
4148 
4149 #
4150 #	Result is now in FP0
4151 #
4152 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4153 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4154 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
4155 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
4156 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
4157 	unlk		%a6
4158 	rts
4159 
4160 	global		_fsincosd_
4161 _fsincosd_:
4162 	link		%a6,&-LOCAL_SIZE
4163 
4164 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4165 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4166 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4167 
4168 	fmov.l		&0x0,%fpcr		# zero FPCR
4169 
4170 #
4171 #	copy, convert, and tag input argument
4172 #
4173 	fmov.d		0x8(%a6),%fp0		# load dbl input
4174 	fmov.x		%fp0,FP_SRC(%a6)
4175 	lea		FP_SRC(%a6),%a0
4176 	bsr.l		tag			# fetch operand type
4177 	mov.b		%d0,STAG(%a6)
4178 	mov.b		%d0,%d1
4179 
4180 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4181 
4182 	clr.l		%d0
4183 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4184 
4185 	mov.b		%d1,STAG(%a6)
4186 	tst.b		%d1
4187 	bne.b		_L20_2d
4188 	bsr.l		ssincos			# operand is a NORM
4189 	bra.b		_L20_6d
4190 _L20_2d:
4191 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4192 	bne.b		_L20_3d			# no
4193 	bsr.l		ssincosz			# yes
4194 	bra.b		_L20_6d
4195 _L20_3d:
4196 	cmpi.b		%d1,&INF		# is operand an INF?
4197 	bne.b		_L20_4d			# no
4198 	bsr.l		ssincosi			# yes
4199 	bra.b		_L20_6d
4200 _L20_4d:
4201 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4202 	bne.b		_L20_5d			# no
4203 	bsr.l		ssincosqnan			# yes
4204 	bra.b		_L20_6d
4205 _L20_5d:
4206 	bsr.l		ssincosd			# operand is a DENORM
4207 _L20_6d:
4208 
4209 #
4210 #	Result is now in FP0
4211 #
4212 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4213 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4214 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
4215 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
4216 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
4217 	unlk		%a6
4218 	rts
4219 
4220 	global		_fsincosx_
4221 _fsincosx_:
4222 	link		%a6,&-LOCAL_SIZE
4223 
4224 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4225 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4226 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4227 
4228 	fmov.l		&0x0,%fpcr		# zero FPCR
4229 
4230 #
4231 #	copy, convert, and tag input argument
4232 #
4233 	lea		FP_SRC(%a6),%a0
4234 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
4235 	mov.l		0x8+0x4(%a6),0x4(%a0)
4236 	mov.l		0x8+0x8(%a6),0x8(%a0)
4237 	bsr.l		tag			# fetch operand type
4238 	mov.b		%d0,STAG(%a6)
4239 	mov.b		%d0,%d1
4240 
4241 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4242 
4243 	clr.l		%d0
4244 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4245 
4246 	tst.b		%d1
4247 	bne.b		_L20_2x
4248 	bsr.l		ssincos			# operand is a NORM
4249 	bra.b		_L20_6x
4250 _L20_2x:
4251 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4252 	bne.b		_L20_3x			# no
4253 	bsr.l		ssincosz			# yes
4254 	bra.b		_L20_6x
4255 _L20_3x:
4256 	cmpi.b		%d1,&INF		# is operand an INF?
4257 	bne.b		_L20_4x			# no
4258 	bsr.l		ssincosi			# yes
4259 	bra.b		_L20_6x
4260 _L20_4x:
4261 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4262 	bne.b		_L20_5x			# no
4263 	bsr.l		ssincosqnan			# yes
4264 	bra.b		_L20_6x
4265 _L20_5x:
4266 	bsr.l		ssincosd			# operand is a DENORM
4267 _L20_6x:
4268 
4269 #
4270 #	Result is now in FP0
4271 #
4272 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4273 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4274 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
4275 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
4276 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
4277 	unlk		%a6
4278 	rts
4279 
4280 
4281 #########################################################################
4282 # DYADIC TEMPLATE							#
4283 #########################################################################
4284 	global		_frems_
4285 _frems_:
4286 	link		%a6,&-LOCAL_SIZE
4287 
4288 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4289 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4290 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4291 
4292 	fmov.l		&0x0,%fpcr		# zero FPCR
4293 
4294 #
4295 #	copy, convert, and tag input argument
4296 #
4297 	fmov.s		0x8(%a6),%fp0		# load sgl dst
4298 	fmov.x		%fp0,FP_DST(%a6)
4299 	lea		FP_DST(%a6),%a0
4300 	bsr.l		tag			# fetch operand type
4301 	mov.b		%d0,DTAG(%a6)
4302 
4303 	fmov.s		0xc(%a6),%fp0		# load sgl src
4304 	fmov.x		%fp0,FP_SRC(%a6)
4305 	lea		FP_SRC(%a6),%a0
4306 	bsr.l		tag			# fetch operand type
4307 	mov.b		%d0,STAG(%a6)
4308 	mov.l		%d0,%d1
4309 
4310 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4311 
4312 	clr.l		%d0
4313 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4314 
4315 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4316 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4317 
4318 	tst.b		%d1
4319 	bne.b		_L21_2s
4320 	bsr.l		srem_snorm			# operand is a NORM
4321 	bra.b		_L21_6s
4322 _L21_2s:
4323 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4324 	bne.b		_L21_3s			# no
4325 	bsr.l		srem_szero			# yes
4326 	bra.b		_L21_6s
4327 _L21_3s:
4328 	cmpi.b		%d1,&INF		# is operand an INF?
4329 	bne.b		_L21_4s			# no
4330 	bsr.l		srem_sinf			# yes
4331 	bra.b		_L21_6s
4332 _L21_4s:
4333 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4334 	bne.b		_L21_5s			# no
4335 	bsr.l		sop_sqnan			# yes
4336 	bra.b		_L21_6s
4337 _L21_5s:
4338 	bsr.l		srem_sdnrm			# operand is a DENORM
4339 _L21_6s:
4340 
4341 #
4342 #	Result is now in FP0
4343 #
4344 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4345 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4346 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4347 	unlk		%a6
4348 	rts
4349 
4350 	global		_fremd_
4351 _fremd_:
4352 	link		%a6,&-LOCAL_SIZE
4353 
4354 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4355 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4356 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4357 
4358 	fmov.l		&0x0,%fpcr		# zero FPCR
4359 
4360 #
4361 #	copy, convert, and tag input argument
4362 #
4363 	fmov.d		0x8(%a6),%fp0		# load dbl dst
4364 	fmov.x		%fp0,FP_DST(%a6)
4365 	lea		FP_DST(%a6),%a0
4366 	bsr.l		tag			# fetch operand type
4367 	mov.b		%d0,DTAG(%a6)
4368 
4369 	fmov.d		0x10(%a6),%fp0		# load dbl src
4370 	fmov.x		%fp0,FP_SRC(%a6)
4371 	lea		FP_SRC(%a6),%a0
4372 	bsr.l		tag			# fetch operand type
4373 	mov.b		%d0,STAG(%a6)
4374 	mov.l		%d0,%d1
4375 
4376 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4377 
4378 	clr.l		%d0
4379 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4380 
4381 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4382 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4383 
4384 	tst.b		%d1
4385 	bne.b		_L21_2d
4386 	bsr.l		srem_snorm			# operand is a NORM
4387 	bra.b		_L21_6d
4388 _L21_2d:
4389 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4390 	bne.b		_L21_3d			# no
4391 	bsr.l		srem_szero			# yes
4392 	bra.b		_L21_6d
4393 _L21_3d:
4394 	cmpi.b		%d1,&INF		# is operand an INF?
4395 	bne.b		_L21_4d			# no
4396 	bsr.l		srem_sinf			# yes
4397 	bra.b		_L21_6d
4398 _L21_4d:
4399 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4400 	bne.b		_L21_5d			# no
4401 	bsr.l		sop_sqnan			# yes
4402 	bra.b		_L21_6d
4403 _L21_5d:
4404 	bsr.l		srem_sdnrm			# operand is a DENORM
4405 _L21_6d:
4406 
4407 #
4408 #	Result is now in FP0
4409 #
4410 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4411 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4412 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4413 	unlk		%a6
4414 	rts
4415 
4416 	global		_fremx_
4417 _fremx_:
4418 	link		%a6,&-LOCAL_SIZE
4419 
4420 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4421 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4422 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4423 
4424 	fmov.l		&0x0,%fpcr		# zero FPCR
4425 
4426 #
4427 #	copy, convert, and tag input argument
4428 #
4429 	lea		FP_DST(%a6),%a0
4430 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
4431 	mov.l		0x8+0x4(%a6),0x4(%a0)
4432 	mov.l		0x8+0x8(%a6),0x8(%a0)
4433 	bsr.l		tag			# fetch operand type
4434 	mov.b		%d0,DTAG(%a6)
4435 
4436 	lea		FP_SRC(%a6),%a0
4437 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
4438 	mov.l		0x14+0x4(%a6),0x4(%a0)
4439 	mov.l		0x14+0x8(%a6),0x8(%a0)
4440 	bsr.l		tag			# fetch operand type
4441 	mov.b		%d0,STAG(%a6)
4442 	mov.l		%d0,%d1
4443 
4444 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4445 
4446 	clr.l		%d0
4447 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4448 
4449 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4450 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4451 
4452 	tst.b		%d1
4453 	bne.b		_L21_2x
4454 	bsr.l		srem_snorm			# operand is a NORM
4455 	bra.b		_L21_6x
4456 _L21_2x:
4457 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4458 	bne.b		_L21_3x			# no
4459 	bsr.l		srem_szero			# yes
4460 	bra.b		_L21_6x
4461 _L21_3x:
4462 	cmpi.b		%d1,&INF		# is operand an INF?
4463 	bne.b		_L21_4x			# no
4464 	bsr.l		srem_sinf			# yes
4465 	bra.b		_L21_6x
4466 _L21_4x:
4467 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4468 	bne.b		_L21_5x			# no
4469 	bsr.l		sop_sqnan			# yes
4470 	bra.b		_L21_6x
4471 _L21_5x:
4472 	bsr.l		srem_sdnrm			# operand is a DENORM
4473 _L21_6x:
4474 
4475 #
4476 #	Result is now in FP0
4477 #
4478 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4479 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4480 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4481 	unlk		%a6
4482 	rts
4483 
4484 
4485 #########################################################################
4486 # DYADIC TEMPLATE							#
4487 #########################################################################
4488 	global		_fmods_
4489 _fmods_:
4490 	link		%a6,&-LOCAL_SIZE
4491 
4492 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4493 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4494 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4495 
4496 	fmov.l		&0x0,%fpcr		# zero FPCR
4497 
4498 #
4499 #	copy, convert, and tag input argument
4500 #
4501 	fmov.s		0x8(%a6),%fp0		# load sgl dst
4502 	fmov.x		%fp0,FP_DST(%a6)
4503 	lea		FP_DST(%a6),%a0
4504 	bsr.l		tag			# fetch operand type
4505 	mov.b		%d0,DTAG(%a6)
4506 
4507 	fmov.s		0xc(%a6),%fp0		# load sgl src
4508 	fmov.x		%fp0,FP_SRC(%a6)
4509 	lea		FP_SRC(%a6),%a0
4510 	bsr.l		tag			# fetch operand type
4511 	mov.b		%d0,STAG(%a6)
4512 	mov.l		%d0,%d1
4513 
4514 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4515 
4516 	clr.l		%d0
4517 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4518 
4519 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4520 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4521 
4522 	tst.b		%d1
4523 	bne.b		_L22_2s
4524 	bsr.l		smod_snorm			# operand is a NORM
4525 	bra.b		_L22_6s
4526 _L22_2s:
4527 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4528 	bne.b		_L22_3s			# no
4529 	bsr.l		smod_szero			# yes
4530 	bra.b		_L22_6s
4531 _L22_3s:
4532 	cmpi.b		%d1,&INF		# is operand an INF?
4533 	bne.b		_L22_4s			# no
4534 	bsr.l		smod_sinf			# yes
4535 	bra.b		_L22_6s
4536 _L22_4s:
4537 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4538 	bne.b		_L22_5s			# no
4539 	bsr.l		sop_sqnan			# yes
4540 	bra.b		_L22_6s
4541 _L22_5s:
4542 	bsr.l		smod_sdnrm			# operand is a DENORM
4543 _L22_6s:
4544 
4545 #
4546 #	Result is now in FP0
4547 #
4548 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4549 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4550 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4551 	unlk		%a6
4552 	rts
4553 
4554 	global		_fmodd_
4555 _fmodd_:
4556 	link		%a6,&-LOCAL_SIZE
4557 
4558 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4559 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4560 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4561 
4562 	fmov.l		&0x0,%fpcr		# zero FPCR
4563 
4564 #
4565 #	copy, convert, and tag input argument
4566 #
4567 	fmov.d		0x8(%a6),%fp0		# load dbl dst
4568 	fmov.x		%fp0,FP_DST(%a6)
4569 	lea		FP_DST(%a6),%a0
4570 	bsr.l		tag			# fetch operand type
4571 	mov.b		%d0,DTAG(%a6)
4572 
4573 	fmov.d		0x10(%a6),%fp0		# load dbl src
4574 	fmov.x		%fp0,FP_SRC(%a6)
4575 	lea		FP_SRC(%a6),%a0
4576 	bsr.l		tag			# fetch operand type
4577 	mov.b		%d0,STAG(%a6)
4578 	mov.l		%d0,%d1
4579 
4580 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4581 
4582 	clr.l		%d0
4583 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4584 
4585 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4586 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4587 
4588 	tst.b		%d1
4589 	bne.b		_L22_2d
4590 	bsr.l		smod_snorm			# operand is a NORM
4591 	bra.b		_L22_6d
4592 _L22_2d:
4593 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4594 	bne.b		_L22_3d			# no
4595 	bsr.l		smod_szero			# yes
4596 	bra.b		_L22_6d
4597 _L22_3d:
4598 	cmpi.b		%d1,&INF		# is operand an INF?
4599 	bne.b		_L22_4d			# no
4600 	bsr.l		smod_sinf			# yes
4601 	bra.b		_L22_6d
4602 _L22_4d:
4603 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4604 	bne.b		_L22_5d			# no
4605 	bsr.l		sop_sqnan			# yes
4606 	bra.b		_L22_6d
4607 _L22_5d:
4608 	bsr.l		smod_sdnrm			# operand is a DENORM
4609 _L22_6d:
4610 
4611 #
4612 #	Result is now in FP0
4613 #
4614 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4615 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4616 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4617 	unlk		%a6
4618 	rts
4619 
4620 	global		_fmodx_
4621 _fmodx_:
4622 	link		%a6,&-LOCAL_SIZE
4623 
4624 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4625 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4626 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4627 
4628 	fmov.l		&0x0,%fpcr		# zero FPCR
4629 
4630 #
4631 #	copy, convert, and tag input argument
4632 #
4633 	lea		FP_DST(%a6),%a0
4634 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
4635 	mov.l		0x8+0x4(%a6),0x4(%a0)
4636 	mov.l		0x8+0x8(%a6),0x8(%a0)
4637 	bsr.l		tag			# fetch operand type
4638 	mov.b		%d0,DTAG(%a6)
4639 
4640 	lea		FP_SRC(%a6),%a0
4641 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
4642 	mov.l		0x14+0x4(%a6),0x4(%a0)
4643 	mov.l		0x14+0x8(%a6),0x8(%a0)
4644 	bsr.l		tag			# fetch operand type
4645 	mov.b		%d0,STAG(%a6)
4646 	mov.l		%d0,%d1
4647 
4648 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4649 
4650 	clr.l		%d0
4651 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4652 
4653 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4654 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4655 
4656 	tst.b		%d1
4657 	bne.b		_L22_2x
4658 	bsr.l		smod_snorm			# operand is a NORM
4659 	bra.b		_L22_6x
4660 _L22_2x:
4661 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4662 	bne.b		_L22_3x			# no
4663 	bsr.l		smod_szero			# yes
4664 	bra.b		_L22_6x
4665 _L22_3x:
4666 	cmpi.b		%d1,&INF		# is operand an INF?
4667 	bne.b		_L22_4x			# no
4668 	bsr.l		smod_sinf			# yes
4669 	bra.b		_L22_6x
4670 _L22_4x:
4671 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4672 	bne.b		_L22_5x			# no
4673 	bsr.l		sop_sqnan			# yes
4674 	bra.b		_L22_6x
4675 _L22_5x:
4676 	bsr.l		smod_sdnrm			# operand is a DENORM
4677 _L22_6x:
4678 
4679 #
4680 #	Result is now in FP0
4681 #
4682 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4683 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4684 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4685 	unlk		%a6
4686 	rts
4687 
4688 
4689 #########################################################################
4690 # DYADIC TEMPLATE							#
4691 #########################################################################
4692 	global		_fscales_
4693 _fscales_:
4694 	link		%a6,&-LOCAL_SIZE
4695 
4696 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4697 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4698 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4699 
4700 	fmov.l		&0x0,%fpcr		# zero FPCR
4701 
4702 #
4703 #	copy, convert, and tag input argument
4704 #
4705 	fmov.s		0x8(%a6),%fp0		# load sgl dst
4706 	fmov.x		%fp0,FP_DST(%a6)
4707 	lea		FP_DST(%a6),%a0
4708 	bsr.l		tag			# fetch operand type
4709 	mov.b		%d0,DTAG(%a6)
4710 
4711 	fmov.s		0xc(%a6),%fp0		# load sgl src
4712 	fmov.x		%fp0,FP_SRC(%a6)
4713 	lea		FP_SRC(%a6),%a0
4714 	bsr.l		tag			# fetch operand type
4715 	mov.b		%d0,STAG(%a6)
4716 	mov.l		%d0,%d1
4717 
4718 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4719 
4720 	clr.l		%d0
4721 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4722 
4723 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4724 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4725 
4726 	tst.b		%d1
4727 	bne.b		_L23_2s
4728 	bsr.l		sscale_snorm			# operand is a NORM
4729 	bra.b		_L23_6s
4730 _L23_2s:
4731 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4732 	bne.b		_L23_3s			# no
4733 	bsr.l		sscale_szero			# yes
4734 	bra.b		_L23_6s
4735 _L23_3s:
4736 	cmpi.b		%d1,&INF		# is operand an INF?
4737 	bne.b		_L23_4s			# no
4738 	bsr.l		sscale_sinf			# yes
4739 	bra.b		_L23_6s
4740 _L23_4s:
4741 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4742 	bne.b		_L23_5s			# no
4743 	bsr.l		sop_sqnan			# yes
4744 	bra.b		_L23_6s
4745 _L23_5s:
4746 	bsr.l		sscale_sdnrm			# operand is a DENORM
4747 _L23_6s:
4748 
4749 #
4750 #	Result is now in FP0
4751 #
4752 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4753 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4754 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4755 	unlk		%a6
4756 	rts
4757 
4758 	global		_fscaled_
4759 _fscaled_:
4760 	link		%a6,&-LOCAL_SIZE
4761 
4762 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4763 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4764 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4765 
4766 	fmov.l		&0x0,%fpcr		# zero FPCR
4767 
4768 #
4769 #	copy, convert, and tag input argument
4770 #
4771 	fmov.d		0x8(%a6),%fp0		# load dbl dst
4772 	fmov.x		%fp0,FP_DST(%a6)
4773 	lea		FP_DST(%a6),%a0
4774 	bsr.l		tag			# fetch operand type
4775 	mov.b		%d0,DTAG(%a6)
4776 
4777 	fmov.d		0x10(%a6),%fp0		# load dbl src
4778 	fmov.x		%fp0,FP_SRC(%a6)
4779 	lea		FP_SRC(%a6),%a0
4780 	bsr.l		tag			# fetch operand type
4781 	mov.b		%d0,STAG(%a6)
4782 	mov.l		%d0,%d1
4783 
4784 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4785 
4786 	clr.l		%d0
4787 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4788 
4789 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4790 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4791 
4792 	tst.b		%d1
4793 	bne.b		_L23_2d
4794 	bsr.l		sscale_snorm			# operand is a NORM
4795 	bra.b		_L23_6d
4796 _L23_2d:
4797 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4798 	bne.b		_L23_3d			# no
4799 	bsr.l		sscale_szero			# yes
4800 	bra.b		_L23_6d
4801 _L23_3d:
4802 	cmpi.b		%d1,&INF		# is operand an INF?
4803 	bne.b		_L23_4d			# no
4804 	bsr.l		sscale_sinf			# yes
4805 	bra.b		_L23_6d
4806 _L23_4d:
4807 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4808 	bne.b		_L23_5d			# no
4809 	bsr.l		sop_sqnan			# yes
4810 	bra.b		_L23_6d
4811 _L23_5d:
4812 	bsr.l		sscale_sdnrm			# operand is a DENORM
4813 _L23_6d:
4814 
4815 #
4816 #	Result is now in FP0
4817 #
4818 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4819 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4820 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4821 	unlk		%a6
4822 	rts
4823 
4824 	global		_fscalex_
4825 _fscalex_:
4826 	link		%a6,&-LOCAL_SIZE
4827 
4828 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
4829 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
4830 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
4831 
4832 	fmov.l		&0x0,%fpcr		# zero FPCR
4833 
4834 #
4835 #	copy, convert, and tag input argument
4836 #
4837 	lea		FP_DST(%a6),%a0
4838 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
4839 	mov.l		0x8+0x4(%a6),0x4(%a0)
4840 	mov.l		0x8+0x8(%a6),0x8(%a0)
4841 	bsr.l		tag			# fetch operand type
4842 	mov.b		%d0,DTAG(%a6)
4843 
4844 	lea		FP_SRC(%a6),%a0
4845 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
4846 	mov.l		0x14+0x4(%a6),0x4(%a0)
4847 	mov.l		0x14+0x8(%a6),0x8(%a0)
4848 	bsr.l		tag			# fetch operand type
4849 	mov.b		%d0,STAG(%a6)
4850 	mov.l		%d0,%d1
4851 
4852 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
4853 
4854 	clr.l		%d0
4855 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
4856 
4857 	lea		FP_SRC(%a6),%a0		# pass ptr to src
4858 	lea		FP_DST(%a6),%a1		# pass ptr to dst
4859 
4860 	tst.b		%d1
4861 	bne.b		_L23_2x
4862 	bsr.l		sscale_snorm			# operand is a NORM
4863 	bra.b		_L23_6x
4864 _L23_2x:
4865 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
4866 	bne.b		_L23_3x			# no
4867 	bsr.l		sscale_szero			# yes
4868 	bra.b		_L23_6x
4869 _L23_3x:
4870 	cmpi.b		%d1,&INF		# is operand an INF?
4871 	bne.b		_L23_4x			# no
4872 	bsr.l		sscale_sinf			# yes
4873 	bra.b		_L23_6x
4874 _L23_4x:
4875 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
4876 	bne.b		_L23_5x			# no
4877 	bsr.l		sop_sqnan			# yes
4878 	bra.b		_L23_6x
4879 _L23_5x:
4880 	bsr.l		sscale_sdnrm			# operand is a DENORM
4881 _L23_6x:
4882 
4883 #
4884 #	Result is now in FP0
4885 #
4886 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
4887 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
4888 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
4889 	unlk		%a6
4890 	rts
4891 
4892 
4893 #########################################################################
4894 # ssin():     computes the sine of a normalized input			#
4895 # ssind():    computes the sine of a denormalized input			#
4896 # scos():     computes the cosine of a normalized input			#
4897 # scosd():    computes the cosine of a denormalized input		#
4898 # ssincos():  computes the sine and cosine of a normalized input	#
4899 # ssincosd(): computes the sine and cosine of a denormalized input	#
4900 #									#
4901 # INPUT *************************************************************** #
4902 #	a0 = pointer to extended precision input			#
4903 #	d0 = round precision,mode					#
4904 #									#
4905 # OUTPUT ************************************************************** #
4906 #	fp0 = sin(X) or cos(X)						#
4907 #									#
4908 #    For ssincos(X):							#
4909 #	fp0 = sin(X)							#
4910 #	fp1 = cos(X)							#
4911 #									#
4912 # ACCURACY and MONOTONICITY ******************************************* #
4913 #	The returned result is within 1 ulp in 64 significant bit, i.e.	#
4914 #	within 0.5001 ulp to 53 bits if the result is subsequently	#
4915 #	rounded to double precision. The result is provably monotonic	#
4916 #	in double precision.						#
4917 #									#
4918 # ALGORITHM ***********************************************************	#
4919 #									#
4920 #	SIN and COS:							#
4921 #	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
4922 #									#
4923 #	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
4924 #									#
4925 #	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
4926 #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
4927 #		Overwrite k by k := k + AdjN.				#
4928 #									#
4929 #	4. If k is even, go to 6.					#
4930 #									#
4931 #	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j.			#
4932 #		Return sgn*cos(r) where cos(r) is approximated by an	#
4933 #		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
4934 #		s = r*r.						#
4935 #		Exit.							#
4936 #									#
4937 #	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
4938 #		where sin(r) is approximated by an odd polynomial in r	#
4939 #		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
4940 #		Exit.							#
4941 #									#
4942 #	7. If |X| > 1, go to 9.						#
4943 #									#
4944 #	8. (|X|<2**(-40)) If SIN is invoked, return X;			#
4945 #		otherwise return 1.					#
4946 #									#
4947 #	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
4948 #		go back to 3.						#
4949 #									#
4950 #	SINCOS:								#
4951 #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
4952 #									#
4953 #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
4954 #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
4955 #									#
4956 #	3. If k is even, go to 5.					#
4957 #									#
4958 #	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
4959 #		j1 exclusive or with the l.s.b. of k.			#
4960 #		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
4961 #		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
4962 #		sin(r) and cos(r) are computed as odd and even		#
4963 #		polynomials in r, respectively. Exit			#
4964 #									#
4965 #	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
4966 #		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
4967 #		sin(r) and cos(r) are computed as odd and even		#
4968 #		polynomials in r, respectively. Exit			#
4969 #									#
4970 #	6. If |X| > 1, go to 8.						#
4971 #									#
4972 #	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
4973 #									#
4974 #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
4975 #		go back to 2.						#
4976 #									#
4977 #########################################################################
4978 
4979 SINA7:	long		0xBD6AAA77,0xCCC994F5
4980 SINA6:	long		0x3DE61209,0x7AAE8DA1
4981 SINA5:	long		0xBE5AE645,0x2A118AE4
4982 SINA4:	long		0x3EC71DE3,0xA5341531
4983 SINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
4984 SINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
4985 SINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
4986 
4987 COSB8:	long		0x3D2AC4D0,0xD6011EE3
4988 COSB7:	long		0xBDA9396F,0x9F45AC19
4989 COSB6:	long		0x3E21EED9,0x0612C972
4990 COSB5:	long		0xBE927E4F,0xB79D9FCF
4991 COSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
4992 COSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
4993 COSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
4994 COSB1:	long		0xBF000000
4995 
4996 	set		INARG,FP_SCR0
4997 
4998 	set		X,FP_SCR0
4999 #	set		XDCARE,X+2
5000 	set		XFRAC,X+4
5001 
5002 	set		RPRIME,FP_SCR0
5003 	set		SPRIME,FP_SCR1
5004 
5005 	set		POSNEG1,L_SCR1
5006 	set		TWOTO63,L_SCR1
5007 
5008 	set		ENDFLAG,L_SCR2
5009 	set		INT,L_SCR2
5010 
5011 	set		ADJN,L_SCR3
5012 
5013 ############################################
5014 	global		ssin
5015 ssin:
5016 	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
5017 	bra.b		SINBGN
5018 
5019 ############################################
5020 	global		scos
5021 scos:
5022 	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
5023 
5024 ############################################
5025 SINBGN:
5026 #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
5027 
5028 	fmov.x		(%a0),%fp0		# LOAD INPUT
5029 	fmov.x		%fp0,X(%a6)		# save input at X
5030 
5031 # "COMPACTIFY" X
5032 	mov.l		(%a0),%d1		# put exp in hi word
5033 	mov.w		4(%a0),%d1		# fetch hi(man)
5034 	and.l		&0x7FFFFFFF,%d1		# strip sign
5035 
5036 	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
5037 	bge.b		SOK1			# no
5038 	bra.w		SINSM			# yes; input is very small
5039 
5040 SOK1:
5041 	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
5042 	blt.b		SINMAIN			# no
5043 	bra.w		SREDUCEX		# yes; input is very large
5044 
5045 #--THIS IS THE USUAL CASE, |X| <= 15 PI.
5046 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
5047 SINMAIN:
5048 	fmov.x		%fp0,%fp1
5049 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
5050 
5051 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
5052 
5053 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
5054 
5055 	mov.l		INT(%a6),%d1		# make a copy of N
5056 	asl.l		&4,%d1			# N *= 16
5057 	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
5058 
5059 # A1 IS THE ADDRESS OF N*PIBY2
5060 # ...WHICH IS IN TWO PIECES Y1 & Y2
5061 	fsub.x		(%a1)+,%fp0		# X-Y1
5062 	fsub.s		(%a1),%fp0		# fp0 = R = (X-Y1)-Y2
5063 
5064 SINCONT:
5065 #--continuation from REDUCEX
5066 
5067 #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
5068 	mov.l		INT(%a6),%d1
5069 	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
5070 	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
5071 	cmp.l		%d1,&0
5072 	blt.w		COSPOLY
5073 
5074 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
5075 #--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
5076 #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
5077 #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
5078 #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
5079 #--WHERE T=S*S.
5080 #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
5081 #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
5082 SINPOLY:
5083 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
5084 
5085 	fmov.x		%fp0,X(%a6)		# X IS R
5086 	fmul.x		%fp0,%fp0		# FP0 IS S
5087 
5088 	fmov.d		SINA7(%pc),%fp3
5089 	fmov.d		SINA6(%pc),%fp2
5090 
5091 	fmov.x		%fp0,%fp1
5092 	fmul.x		%fp1,%fp1		# FP1 IS T
5093 
5094 	ror.l		&1,%d1
5095 	and.l		&0x80000000,%d1
5096 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
5097 	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
5098 
5099 	fmul.x		%fp1,%fp3		# TA7
5100 	fmul.x		%fp1,%fp2		# TA6
5101 
5102 	fadd.d		SINA5(%pc),%fp3		# A5+TA7
5103 	fadd.d		SINA4(%pc),%fp2		# A4+TA6
5104 
5105 	fmul.x		%fp1,%fp3		# T(A5+TA7)
5106 	fmul.x		%fp1,%fp2		# T(A4+TA6)
5107 
5108 	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
5109 	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
5110 
5111 	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
5112 
5113 	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
5114 	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
5115 	fmul.x		X(%a6),%fp0		# R'*S
5116 
5117 	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
5118 
5119 	fmul.x		%fp1,%fp0		# SIN(R')-R'
5120 
5121 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
5122 
5123 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5124 	fadd.x		X(%a6),%fp0		# last inst - possible exception set
5125 	bra		t_inx2
5126 
5127 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
5128 #--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
5129 #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
5130 #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
5131 #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
5132 #--WHERE T=S*S.
5133 #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
5134 #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
5135 #--AND IS THEREFORE STORED AS SINGLE PRECISION.
5136 COSPOLY:
5137 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
5138 
5139 	fmul.x		%fp0,%fp0		# FP0 IS S
5140 
5141 	fmov.d		COSB8(%pc),%fp2
5142 	fmov.d		COSB7(%pc),%fp3
5143 
5144 	fmov.x		%fp0,%fp1
5145 	fmul.x		%fp1,%fp1		# FP1 IS T
5146 
5147 	fmov.x		%fp0,X(%a6)		# X IS S
5148 	ror.l		&1,%d1
5149 	and.l		&0x80000000,%d1
5150 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
5151 
5152 	fmul.x		%fp1,%fp2		# TB8
5153 
5154 	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
5155 	and.l		&0x80000000,%d1
5156 
5157 	fmul.x		%fp1,%fp3		# TB7
5158 
5159 	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
5160 	mov.l		%d1,POSNEG1(%a6)
5161 
5162 	fadd.d		COSB6(%pc),%fp2		# B6+TB8
5163 	fadd.d		COSB5(%pc),%fp3		# B5+TB7
5164 
5165 	fmul.x		%fp1,%fp2		# T(B6+TB8)
5166 	fmul.x		%fp1,%fp3		# T(B5+TB7)
5167 
5168 	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
5169 	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
5170 
5171 	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
5172 	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
5173 
5174 	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
5175 	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
5176 
5177 	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
5178 
5179 	fadd.x		%fp1,%fp0
5180 
5181 	fmul.x		X(%a6),%fp0
5182 
5183 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
5184 
5185 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5186 	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
5187 	bra		t_inx2
5188 
5189 ##############################################
5190 
5191 # SINe: Big OR Small?
5192 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
5193 #--IF |X| < 2**(-40), RETURN X OR 1.
5194 SINBORS:
5195 	cmp.l		%d1,&0x3FFF8000
5196 	bgt.l		SREDUCEX
5197 
5198 SINSM:
5199 	mov.l		ADJN(%a6),%d1
5200 	cmp.l		%d1,&0
5201 	bgt.b		COSTINY
5202 
5203 # here, the operation may underflow iff the precision is sgl or dbl.
5204 # extended denorms are handled through another entry point.
5205 SINTINY:
5206 #	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
5207 
5208 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5209 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
5210 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
5211 	bra		t_catch
5212 
5213 COSTINY:
5214 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
5215 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5216 	fadd.s		&0x80800000,%fp0	# last inst - possible exception set
5217 	bra		t_pinx2
5218 
5219 ################################################
5220 	global		ssind
5221 #--SIN(X) = X FOR DENORMALIZED X
5222 ssind:
5223 	bra		t_extdnrm
5224 
5225 ############################################
5226 	global		scosd
5227 #--COS(X) = 1 FOR DENORMALIZED X
5228 scosd:
5229 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
5230 	bra		t_pinx2
5231 
5232 ##################################################
5233 
5234 	global		ssincos
5235 ssincos:
5236 #--SET ADJN TO 4
5237 	mov.l		&4,ADJN(%a6)
5238 
5239 	fmov.x		(%a0),%fp0		# LOAD INPUT
5240 	fmov.x		%fp0,X(%a6)
5241 
5242 	mov.l		(%a0),%d1
5243 	mov.w		4(%a0),%d1
5244 	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
5245 
5246 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
5247 	bge.b		SCOK1
5248 	bra.w		SCSM
5249 
5250 SCOK1:
5251 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
5252 	blt.b		SCMAIN
5253 	bra.w		SREDUCEX
5254 
5255 
5256 #--THIS IS THE USUAL CASE, |X| <= 15 PI.
5257 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
5258 SCMAIN:
5259 	fmov.x		%fp0,%fp1
5260 
5261 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
5262 
5263 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
5264 
5265 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
5266 
5267 	mov.l		INT(%a6),%d1
5268 	asl.l		&4,%d1
5269 	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
5270 
5271 	fsub.x		(%a1)+,%fp0		# X-Y1
5272 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
5273 
5274 SCCONT:
5275 #--continuation point from REDUCEX
5276 
5277 	mov.l		INT(%a6),%d1
5278 	ror.l		&1,%d1
5279 	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
5280 	bge.w		NEVEN
5281 
5282 SNODD:
5283 #--REGISTERS SAVED SO FAR: D0, A0, FP2.
5284 	fmovm.x		&0x04,-(%sp)		# save fp2
5285 
5286 	fmov.x		%fp0,RPRIME(%a6)
5287 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
5288 	fmov.d		SINA7(%pc),%fp1		# A7
5289 	fmov.d		COSB8(%pc),%fp2		# B8
5290 	fmul.x		%fp0,%fp1		# SA7
5291 	fmul.x		%fp0,%fp2		# SB8
5292 
5293 	mov.l		%d2,-(%sp)
5294 	mov.l		%d1,%d2
5295 	ror.l		&1,%d2
5296 	and.l		&0x80000000,%d2
5297 	eor.l		%d1,%d2
5298 	and.l		&0x80000000,%d2
5299 
5300 	fadd.d		SINA6(%pc),%fp1		# A6+SA7
5301 	fadd.d		COSB7(%pc),%fp2		# B7+SB8
5302 
5303 	fmul.x		%fp0,%fp1		# S(A6+SA7)
5304 	eor.l		%d2,RPRIME(%a6)
5305 	mov.l		(%sp)+,%d2
5306 	fmul.x		%fp0,%fp2		# S(B7+SB8)
5307 	ror.l		&1,%d1
5308 	and.l		&0x80000000,%d1
5309 	mov.l		&0x3F800000,POSNEG1(%a6)
5310 	eor.l		%d1,POSNEG1(%a6)
5311 
5312 	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
5313 	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
5314 
5315 	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
5316 	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
5317 	fmov.x		%fp0,SPRIME(%a6)
5318 
5319 	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
5320 	eor.l		%d1,SPRIME(%a6)
5321 	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
5322 
5323 	fmul.x		%fp0,%fp1		# S(A4+...)
5324 	fmul.x		%fp0,%fp2		# S(B5+...)
5325 
5326 	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
5327 	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
5328 
5329 	fmul.x		%fp0,%fp1		# S(A3+...)
5330 	fmul.x		%fp0,%fp2		# S(B4+...)
5331 
5332 	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
5333 	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
5334 
5335 	fmul.x		%fp0,%fp1		# S(A2+...)
5336 	fmul.x		%fp0,%fp2		# S(B3+...)
5337 
5338 	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
5339 	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
5340 
5341 	fmul.x		%fp0,%fp1		# S(A1+...)
5342 	fmul.x		%fp2,%fp0		# S(B2+...)
5343 
5344 	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
5345 	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
5346 	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
5347 
5348 	fmovm.x		(%sp)+,&0x20		# restore fp2
5349 
5350 	fmov.l		%d0,%fpcr
5351 	fadd.x		RPRIME(%a6),%fp1	# COS(X)
5352 	bsr		sto_cos			# store cosine result
5353 	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
5354 	bra		t_inx2
5355 
5356 NEVEN:
5357 #--REGISTERS SAVED SO FAR: FP2.
5358 	fmovm.x		&0x04,-(%sp)		# save fp2
5359 
5360 	fmov.x		%fp0,RPRIME(%a6)
5361 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
5362 
5363 	fmov.d		COSB8(%pc),%fp1		# B8
5364 	fmov.d		SINA7(%pc),%fp2		# A7
5365 
5366 	fmul.x		%fp0,%fp1		# SB8
5367 	fmov.x		%fp0,SPRIME(%a6)
5368 	fmul.x		%fp0,%fp2		# SA7
5369 
5370 	ror.l		&1,%d1
5371 	and.l		&0x80000000,%d1
5372 
5373 	fadd.d		COSB7(%pc),%fp1		# B7+SB8
5374 	fadd.d		SINA6(%pc),%fp2		# A6+SA7
5375 
5376 	eor.l		%d1,RPRIME(%a6)
5377 	eor.l		%d1,SPRIME(%a6)
5378 
5379 	fmul.x		%fp0,%fp1		# S(B7+SB8)
5380 
5381 	or.l		&0x3F800000,%d1
5382 	mov.l		%d1,POSNEG1(%a6)
5383 
5384 	fmul.x		%fp0,%fp2		# S(A6+SA7)
5385 
5386 	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
5387 	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
5388 
5389 	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
5390 	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
5391 
5392 	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
5393 	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
5394 
5395 	fmul.x		%fp0,%fp1		# S(B5+...)
5396 	fmul.x		%fp0,%fp2		# S(A4+...)
5397 
5398 	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
5399 	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
5400 
5401 	fmul.x		%fp0,%fp1		# S(B4+...)
5402 	fmul.x		%fp0,%fp2		# S(A3+...)
5403 
5404 	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
5405 	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
5406 
5407 	fmul.x		%fp0,%fp1		# S(B3+...)
5408 	fmul.x		%fp0,%fp2		# S(A2+...)
5409 
5410 	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
5411 	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
5412 
5413 	fmul.x		%fp0,%fp1		# S(B2+...)
5414 	fmul.x		%fp2,%fp0		# s(a1+...)
5415 
5416 
5417 	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
5418 	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
5419 	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
5420 
5421 	fmovm.x		(%sp)+,&0x20		# restore fp2
5422 
5423 	fmov.l		%d0,%fpcr
5424 	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
5425 	bsr		sto_cos			# store cosine result
5426 	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
5427 	bra		t_inx2
5428 
5429 ################################################
5430 
5431 SCBORS:
5432 	cmp.l		%d1,&0x3FFF8000
5433 	bgt.w		SREDUCEX
5434 
5435 ################################################
5436 
5437 SCSM:
5438 #	mov.w		&0x0000,XDCARE(%a6)
5439 	fmov.s		&0x3F800000,%fp1
5440 
5441 	fmov.l		%d0,%fpcr
5442 	fsub.s		&0x00800000,%fp1
5443 	bsr		sto_cos			# store cosine result
5444 	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
5445 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
5446 	fmov.x		X(%a6),%fp0
5447 	bra		t_catch
5448 
5449 ##############################################
5450 
5451 	global		ssincosd
5452 #--SIN AND COS OF X FOR DENORMALIZED X
5453 ssincosd:
5454 	mov.l		%d0,-(%sp)		# save d0
5455 	fmov.s		&0x3F800000,%fp1
5456 	bsr		sto_cos			# store cosine result
5457 	mov.l		(%sp)+,%d0		# restore d0
5458 	bra		t_extdnrm
5459 
5460 ############################################
5461 
5462 #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
5463 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
5464 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
5465 SREDUCEX:
5466 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
5467 	mov.l		%d2,-(%sp)		# save d2
5468 	fmov.s		&0x00000000,%fp1	# fp1 = 0
5469 
5470 #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
5471 #--there is a danger of unwanted overflow in first LOOP iteration.  In this
5472 #--case, reduce argument by one remainder step to make subsequent reduction
5473 #--safe.
5474 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
5475 	bne.b		SLOOP			# no
5476 
5477 # yes; create 2**16383*PI/2
5478 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
5479 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
5480 	clr.l		FP_SCR0_LO(%a6)
5481 
5482 # create low half of 2**16383*PI/2 at FP_SCR1
5483 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
5484 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
5485 	clr.l		FP_SCR1_LO(%a6)
5486 
5487 	ftest.x		%fp0			# test sign of argument
5488 	fblt.w		sred_neg
5489 
5490 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
5491 	or.b		&0x80,FP_SCR1_EX(%a6)
5492 sred_neg:
5493 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
5494 	fmov.x		%fp0,%fp1		# save high result in fp1
5495 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
5496 	fsub.x		%fp0,%fp1		# determine low component of result
5497 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
5498 
5499 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
5500 #--integer quotient will be stored in N
5501 #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
5502 SLOOP:
5503 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
5504 	mov.w		INARG(%a6),%d1
5505 	mov.l		%d1,%a1			# save a copy of D0
5506 	and.l		&0x00007FFF,%d1
5507 	sub.l		&0x00003FFF,%d1		# d0 = K
5508 	cmp.l		%d1,&28
5509 	ble.b		SLASTLOOP
5510 SCONTLOOP:
5511 	sub.l		&27,%d1			# d0 = L := K-27
5512 	mov.b		&0,ENDFLAG(%a6)
5513 	bra.b		SWORK
5514 SLASTLOOP:
5515 	clr.l		%d1			# d0 = L := 0
5516 	mov.b		&1,ENDFLAG(%a6)
5517 
5518 SWORK:
5519 #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
5520 #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
5521 
5522 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
5523 #--2**L * (PIby2_1), 2**L * (PIby2_2)
5524 
5525 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
5526 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
5527 
5528 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
5529 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
5530 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
5531 
5532 	fmov.x		%fp0,%fp2
5533 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
5534 
5535 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
5536 #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
5537 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
5538 #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
5539 #--US THE DESIRED VALUE IN FLOATING POINT.
5540 	mov.l		%a1,%d2
5541 	swap		%d2
5542 	and.l		&0x80000000,%d2
5543 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
5544 	mov.l		%d2,TWOTO63(%a6)
5545 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
5546 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
5547 #	fint.x		%fp2
5548 
5549 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
5550 	mov.l		%d1,%d2			# d2 = L
5551 
5552 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
5553 	mov.w		%d2,FP_SCR0_EX(%a6)
5554 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
5555 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
5556 
5557 	add.l		&0x00003FDD,%d1
5558 	mov.w		%d1,FP_SCR1_EX(%a6)
5559 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
5560 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
5561 
5562 	mov.b		ENDFLAG(%a6),%d1
5563 
5564 #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
5565 #--P2 = 2**(L) * Piby2_2
5566 	fmov.x		%fp2,%fp4		# fp4 = N
5567 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
5568 	fmov.x		%fp2,%fp5		# fp5 = N
5569 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
5570 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
5571 
5572 #--we want P+p = W+w  but  |p| <= half ulp of P
5573 #--Then, we need to compute  A := R-P   and  a := r-p
5574 	fadd.x		%fp5,%fp3		# fp3 = P
5575 	fsub.x		%fp3,%fp4		# fp4 = W-P
5576 
5577 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
5578 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
5579 
5580 	fmov.x		%fp0,%fp3		# fp3 = A
5581 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
5582 
5583 #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
5584 #--|r| <= half ulp of R.
5585 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
5586 #--No need to calculate r if this is the last loop
5587 	cmp.b		%d1,&0
5588 	bgt.w		SRESTORE
5589 
5590 #--Need to calculate r
5591 	fsub.x		%fp0,%fp3		# fp3 = A-R
5592 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
5593 	bra.w		SLOOP
5594 
5595 SRESTORE:
5596 	fmov.l		%fp2,INT(%a6)
5597 	mov.l		(%sp)+,%d2		# restore d2
5598 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
5599 
5600 	mov.l		ADJN(%a6),%d1
5601 	cmp.l		%d1,&4
5602 
5603 	blt.w		SINCONT
5604 	bra.w		SCCONT
5605 
5606 #########################################################################
5607 # stan():  computes the tangent of a normalized input			#
5608 # stand(): computes the tangent of a denormalized input			#
5609 #									#
5610 # INPUT *************************************************************** #
5611 #	a0 = pointer to extended precision input			#
5612 #	d0 = round precision,mode					#
5613 #									#
5614 # OUTPUT ************************************************************** #
5615 #	fp0 = tan(X)							#
5616 #									#
5617 # ACCURACY and MONOTONICITY ******************************************* #
5618 #	The returned result is within 3 ulp in 64 significant bit, i.e. #
5619 #	within 0.5001 ulp to 53 bits if the result is subsequently	#
5620 #	rounded to double precision. The result is provably monotonic	#
5621 #	in double precision.						#
5622 #									#
5623 # ALGORITHM *********************************************************** #
5624 #									#
5625 #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
5626 #									#
5627 #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
5628 #		k = N mod 2, so in particular, k = 0 or 1.		#
5629 #									#
5630 #	3. If k is odd, go to 5.					#
5631 #									#
5632 #	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
5633 #		rational function U/V where				#
5634 #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
5635 #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
5636 #		Exit.							#
5637 #									#
5638 #	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
5639 #		a rational function U/V where				#
5640 #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
5641 #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
5642 #		-Cot(r) = -V/U. Exit.					#
5643 #									#
5644 #	6. If |X| > 1, go to 8.						#
5645 #									#
5646 #	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
5647 #									#
5648 #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back	#
5649 #		to 2.							#
5650 #									#
5651 #########################################################################
5652 
5653 TANQ4:
5654 	long		0x3EA0B759,0xF50F8688
5655 TANP3:
5656 	long		0xBEF2BAA5,0xA8924F04
5657 
5658 TANQ3:
5659 	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
5660 
5661 TANP2:
5662 	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
5663 
5664 TANQ2:
5665 	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
5666 
5667 TANP1:
5668 	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
5669 
5670 TANQ1:
5671 	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
5672 
5673 INVTWOPI:
5674 	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
5675 
5676 TWOPI1:
5677 	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
5678 TWOPI2:
5679 	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
5680 
5681 #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
5682 #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
5683 #--MOST 69 BITS LONG.
5684 #	global		PITBL
5685 PITBL:
5686 	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
5687 	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
5688 	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
5689 	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
5690 	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
5691 	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
5692 	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
5693 	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
5694 	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
5695 	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
5696 	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
5697 	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
5698 	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
5699 	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
5700 	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
5701 	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
5702 	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
5703 	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
5704 	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
5705 	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
5706 	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
5707 	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
5708 	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
5709 	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
5710 	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
5711 	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
5712 	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
5713 	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
5714 	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
5715 	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
5716 	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
5717 	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
5718 	long		0x00000000,0x00000000,0x00000000,0x00000000
5719 	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
5720 	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
5721 	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
5722 	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
5723 	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
5724 	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
5725 	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
5726 	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
5727 	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
5728 	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
5729 	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
5730 	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
5731 	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
5732 	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
5733 	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
5734 	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
5735 	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
5736 	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
5737 	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
5738 	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
5739 	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
5740 	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
5741 	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
5742 	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
5743 	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
5744 	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
5745 	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
5746 	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
5747 	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
5748 	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
5749 	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
5750 	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
5751 
5752 	set		INARG,FP_SCR0
5753 
5754 	set		TWOTO63,L_SCR1
5755 	set		INT,L_SCR1
5756 	set		ENDFLAG,L_SCR2
5757 
5758 	global		stan
5759 stan:
5760 	fmov.x		(%a0),%fp0		# LOAD INPUT
5761 
5762 	mov.l		(%a0),%d1
5763 	mov.w		4(%a0),%d1
5764 	and.l		&0x7FFFFFFF,%d1
5765 
5766 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
5767 	bge.b		TANOK1
5768 	bra.w		TANSM
5769 TANOK1:
5770 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
5771 	blt.b		TANMAIN
5772 	bra.w		REDUCEX
5773 
5774 TANMAIN:
5775 #--THIS IS THE USUAL CASE, |X| <= 15 PI.
5776 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
5777 	fmov.x		%fp0,%fp1
5778 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
5779 
5780 	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
5781 
5782 	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
5783 
5784 	asl.l		&4,%d1
5785 	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
5786 
5787 	fsub.x		(%a1)+,%fp0		# X-Y1
5788 
5789 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
5790 
5791 	ror.l		&5,%d1
5792 	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
5793 
5794 TANCONT:
5795 	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
5796 
5797 	cmp.l		%d1,&0
5798 	blt.w		NODD
5799 
5800 	fmov.x		%fp0,%fp1
5801 	fmul.x		%fp1,%fp1		# S = R*R
5802 
5803 	fmov.d		TANQ4(%pc),%fp3
5804 	fmov.d		TANP3(%pc),%fp2
5805 
5806 	fmul.x		%fp1,%fp3		# SQ4
5807 	fmul.x		%fp1,%fp2		# SP3
5808 
5809 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
5810 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
5811 
5812 	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
5813 	fmul.x		%fp1,%fp2		# S(P2+SP3)
5814 
5815 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
5816 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
5817 
5818 	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
5819 	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
5820 
5821 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
5822 	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
5823 
5824 	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
5825 
5826 	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
5827 
5828 	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
5829 
5830 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
5831 
5832 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5833 	fdiv.x		%fp1,%fp0		# last inst - possible exception set
5834 	bra		t_inx2
5835 
5836 NODD:
5837 	fmov.x		%fp0,%fp1
5838 	fmul.x		%fp0,%fp0		# S = R*R
5839 
5840 	fmov.d		TANQ4(%pc),%fp3
5841 	fmov.d		TANP3(%pc),%fp2
5842 
5843 	fmul.x		%fp0,%fp3		# SQ4
5844 	fmul.x		%fp0,%fp2		# SP3
5845 
5846 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
5847 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
5848 
5849 	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
5850 	fmul.x		%fp0,%fp2		# S(P2+SP3)
5851 
5852 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
5853 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
5854 
5855 	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
5856 	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
5857 
5858 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
5859 	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
5860 
5861 	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
5862 
5863 	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
5864 	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
5865 
5866 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
5867 
5868 	fmov.x		%fp1,-(%sp)
5869 	eor.l		&0x80000000,(%sp)
5870 
5871 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5872 	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
5873 	bra		t_inx2
5874 
5875 TANBORS:
5876 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
5877 #--IF |X| < 2**(-40), RETURN X OR 1.
5878 	cmp.l		%d1,&0x3FFF8000
5879 	bgt.b		REDUCEX
5880 
5881 TANSM:
5882 	fmov.x		%fp0,-(%sp)
5883 	fmov.l		%d0,%fpcr		# restore users round mode,prec
5884 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
5885 	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
5886 	bra		t_catch
5887 
5888 	global		stand
5889 #--TAN(X) = X FOR DENORMALIZED X
5890 stand:
5891 	bra		t_extdnrm
5892 
5893 #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
5894 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
5895 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
5896 REDUCEX:
5897 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
5898 	mov.l		%d2,-(%sp)		# save d2
5899 	fmov.s		&0x00000000,%fp1	# fp1 = 0
5900 
5901 #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
5902 #--there is a danger of unwanted overflow in first LOOP iteration.  In this
5903 #--case, reduce argument by one remainder step to make subsequent reduction
5904 #--safe.
5905 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
5906 	bne.b		LOOP			# no
5907 
5908 # yes; create 2**16383*PI/2
5909 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
5910 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
5911 	clr.l		FP_SCR0_LO(%a6)
5912 
5913 # create low half of 2**16383*PI/2 at FP_SCR1
5914 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
5915 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
5916 	clr.l		FP_SCR1_LO(%a6)
5917 
5918 	ftest.x		%fp0			# test sign of argument
5919 	fblt.w		red_neg
5920 
5921 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
5922 	or.b		&0x80,FP_SCR1_EX(%a6)
5923 red_neg:
5924 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
5925 	fmov.x		%fp0,%fp1		# save high result in fp1
5926 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
5927 	fsub.x		%fp0,%fp1		# determine low component of result
5928 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
5929 
5930 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
5931 #--integer quotient will be stored in N
5932 #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
5933 LOOP:
5934 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
5935 	mov.w		INARG(%a6),%d1
5936 	mov.l		%d1,%a1			# save a copy of D0
5937 	and.l		&0x00007FFF,%d1
5938 	sub.l		&0x00003FFF,%d1		# d0 = K
5939 	cmp.l		%d1,&28
5940 	ble.b		LASTLOOP
5941 CONTLOOP:
5942 	sub.l		&27,%d1			# d0 = L := K-27
5943 	mov.b		&0,ENDFLAG(%a6)
5944 	bra.b		WORK
5945 LASTLOOP:
5946 	clr.l		%d1			# d0 = L := 0
5947 	mov.b		&1,ENDFLAG(%a6)
5948 
5949 WORK:
5950 #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
5951 #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
5952 
5953 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
5954 #--2**L * (PIby2_1), 2**L * (PIby2_2)
5955 
5956 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
5957 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
5958 
5959 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
5960 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
5961 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
5962 
5963 	fmov.x		%fp0,%fp2
5964 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
5965 
5966 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
5967 #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
5968 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
5969 #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
5970 #--US THE DESIRED VALUE IN FLOATING POINT.
5971 	mov.l		%a1,%d2
5972 	swap		%d2
5973 	and.l		&0x80000000,%d2
5974 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
5975 	mov.l		%d2,TWOTO63(%a6)
5976 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
5977 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
5978 #	fintrz.x	%fp2,%fp2
5979 
5980 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
5981 	mov.l		%d1,%d2			# d2 = L
5982 
5983 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
5984 	mov.w		%d2,FP_SCR0_EX(%a6)
5985 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
5986 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
5987 
5988 	add.l		&0x00003FDD,%d1
5989 	mov.w		%d1,FP_SCR1_EX(%a6)
5990 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
5991 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
5992 
5993 	mov.b		ENDFLAG(%a6),%d1
5994 
5995 #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
5996 #--P2 = 2**(L) * Piby2_2
5997 	fmov.x		%fp2,%fp4		# fp4 = N
5998 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
5999 	fmov.x		%fp2,%fp5		# fp5 = N
6000 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
6001 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
6002 
6003 #--we want P+p = W+w  but  |p| <= half ulp of P
6004 #--Then, we need to compute  A := R-P   and  a := r-p
6005 	fadd.x		%fp5,%fp3		# fp3 = P
6006 	fsub.x		%fp3,%fp4		# fp4 = W-P
6007 
6008 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
6009 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
6010 
6011 	fmov.x		%fp0,%fp3		# fp3 = A
6012 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
6013 
6014 #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
6015 #--|r| <= half ulp of R.
6016 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
6017 #--No need to calculate r if this is the last loop
6018 	cmp.b		%d1,&0
6019 	bgt.w		RESTORE
6020 
6021 #--Need to calculate r
6022 	fsub.x		%fp0,%fp3		# fp3 = A-R
6023 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
6024 	bra.w		LOOP
6025 
6026 RESTORE:
6027 	fmov.l		%fp2,INT(%a6)
6028 	mov.l		(%sp)+,%d2		# restore d2
6029 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
6030 
6031 	mov.l		INT(%a6),%d1
6032 	ror.l		&1,%d1
6033 
6034 	bra.w		TANCONT
6035 
6036 #########################################################################
6037 # satan():  computes the arctangent of a normalized number		#
6038 # satand(): computes the arctangent of a denormalized number		#
6039 #									#
6040 # INPUT	*************************************************************** #
6041 #	a0 = pointer to extended precision input			#
6042 #	d0 = round precision,mode					#
6043 #									#
6044 # OUTPUT ************************************************************** #
6045 #	fp0 = arctan(X)							#
6046 #									#
6047 # ACCURACY and MONOTONICITY ******************************************* #
6048 #	The returned result is within 2 ulps in	64 significant bit,	#
6049 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
6050 #	rounded to double precision. The result is provably monotonic	#
6051 #	in double precision.						#
6052 #									#
6053 # ALGORITHM *********************************************************** #
6054 #	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
6055 #									#
6056 #	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x.			#
6057 #		Note that k = -4, -3,..., or 3.				#
6058 #		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5	#
6059 #		significant bits of X with a bit-1 attached at the 6-th	#
6060 #		bit position. Define u to be u = (X-F) / (1 + X*F).	#
6061 #									#
6062 #	Step 3. Approximate arctan(u) by a polynomial poly.		#
6063 #									#
6064 #	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a	#
6065 #		table of values calculated beforehand. Exit.		#
6066 #									#
6067 #	Step 5. If |X| >= 16, go to Step 7.				#
6068 #									#
6069 #	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
6070 #									#
6071 #	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd	#
6072 #		polynomial in X'.					#
6073 #		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
6074 #									#
6075 #########################################################################
6076 
6077 ATANA3:	long		0xBFF6687E,0x314987D8
6078 ATANA2:	long		0x4002AC69,0x34A26DB3
6079 ATANA1:	long		0xBFC2476F,0x4E1DA28E
6080 
6081 ATANB6:	long		0x3FB34444,0x7F876989
6082 ATANB5:	long		0xBFB744EE,0x7FAF45DB
6083 ATANB4:	long		0x3FBC71C6,0x46940220
6084 ATANB3:	long		0xBFC24924,0x921872F9
6085 ATANB2:	long		0x3FC99999,0x99998FA9
6086 ATANB1:	long		0xBFD55555,0x55555555
6087 
6088 ATANC5:	long		0xBFB70BF3,0x98539E6A
6089 ATANC4:	long		0x3FBC7187,0x962D1D7D
6090 ATANC3:	long		0xBFC24924,0x827107B8
6091 ATANC2:	long		0x3FC99999,0x9996263E
6092 ATANC1:	long		0xBFD55555,0x55555536
6093 
6094 PPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
6095 NPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
6096 
6097 PTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
6098 NTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
6099 
6100 ATANTBL:
6101 	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
6102 	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
6103 	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
6104 	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
6105 	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
6106 	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
6107 	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
6108 	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
6109 	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
6110 	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
6111 	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
6112 	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
6113 	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
6114 	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
6115 	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
6116 	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
6117 	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
6118 	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
6119 	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
6120 	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
6121 	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
6122 	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
6123 	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
6124 	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
6125 	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
6126 	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
6127 	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
6128 	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
6129 	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
6130 	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
6131 	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
6132 	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
6133 	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
6134 	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
6135 	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
6136 	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
6137 	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
6138 	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
6139 	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
6140 	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
6141 	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
6142 	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
6143 	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
6144 	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
6145 	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
6146 	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
6147 	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
6148 	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
6149 	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
6150 	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
6151 	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
6152 	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
6153 	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
6154 	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
6155 	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
6156 	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
6157 	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
6158 	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
6159 	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
6160 	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
6161 	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
6162 	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
6163 	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
6164 	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
6165 	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
6166 	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
6167 	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
6168 	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
6169 	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
6170 	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
6171 	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
6172 	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
6173 	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
6174 	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
6175 	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
6176 	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
6177 	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
6178 	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
6179 	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
6180 	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
6181 	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
6182 	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
6183 	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
6184 	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
6185 	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
6186 	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
6187 	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
6188 	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
6189 	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
6190 	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
6191 	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
6192 	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
6193 	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
6194 	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
6195 	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
6196 	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
6197 	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
6198 	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
6199 	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
6200 	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
6201 	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
6202 	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
6203 	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
6204 	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
6205 	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
6206 	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
6207 	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
6208 	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
6209 	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
6210 	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
6211 	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
6212 	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
6213 	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
6214 	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
6215 	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
6216 	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
6217 	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
6218 	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
6219 	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
6220 	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
6221 	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
6222 	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
6223 	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
6224 	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
6225 	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
6226 	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
6227 	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
6228 	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
6229 
6230 	set		X,FP_SCR0
6231 	set		XDCARE,X+2
6232 	set		XFRAC,X+4
6233 	set		XFRACLO,X+8
6234 
6235 	set		ATANF,FP_SCR1
6236 	set		ATANFHI,ATANF+4
6237 	set		ATANFLO,ATANF+8
6238 
6239 	global		satan
6240 #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
6241 satan:
6242 	fmov.x		(%a0),%fp0		# LOAD INPUT
6243 
6244 	mov.l		(%a0),%d1
6245 	mov.w		4(%a0),%d1
6246 	fmov.x		%fp0,X(%a6)
6247 	and.l		&0x7FFFFFFF,%d1
6248 
6249 	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
6250 	bge.b		ATANOK1
6251 	bra.w		ATANSM
6252 
6253 ATANOK1:
6254 	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
6255 	ble.b		ATANMAIN
6256 	bra.w		ATANBIG
6257 
6258 #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
6259 #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
6260 #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
6261 #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
6262 #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
6263 #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
6264 #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
6265 #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
6266 #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
6267 #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
6268 #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
6269 #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
6270 #--WILL INVOLVE A VERY LONG POLYNOMIAL.
6271 
6272 #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
6273 #--WE CHOSE F TO BE +-2^K * 1.BBBB1
6274 #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
6275 #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
6276 #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
6277 #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
6278 
6279 ATANMAIN:
6280 
6281 	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
6282 	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
6283 	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
6284 
6285 	fmov.x		%fp0,%fp1		# FP1 IS X
6286 	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
6287 	fsub.x		X(%a6),%fp0		# FP0 IS X-F
6288 	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
6289 	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
6290 
6291 #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
6292 #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
6293 #--SAVE REGISTERS FP2.
6294 
6295 	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
6296 	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
6297 	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
6298 	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
6299 	sub.l		&0x3FFB0000,%d2		# K+4
6300 	asr.l		&1,%d2
6301 	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
6302 	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
6303 	lea		ATANTBL(%pc),%a1
6304 	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
6305 	mov.l		(%a1)+,ATANF(%a6)
6306 	mov.l		(%a1)+,ATANFHI(%a6)
6307 	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
6308 	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
6309 	and.l		&0x80000000,%d1		# SIGN(F)
6310 	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
6311 	mov.l		(%sp)+,%d2		# RESTORE d2
6312 
6313 #--THAT'S ALL I HAVE TO DO FOR NOW,
6314 #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
6315 
6316 #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
6317 #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
6318 #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
6319 #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
6320 #--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
6321 #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
6322 #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
6323 
6324 	fmovm.x		&0x04,-(%sp)		# save fp2
6325 
6326 	fmov.x		%fp0,%fp1
6327 	fmul.x		%fp1,%fp1
6328 	fmov.d		ATANA3(%pc),%fp2
6329 	fadd.x		%fp1,%fp2		# A3+V
6330 	fmul.x		%fp1,%fp2		# V*(A3+V)
6331 	fmul.x		%fp0,%fp1		# U*V
6332 	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
6333 	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
6334 	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
6335 	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
6336 
6337 	fmovm.x		(%sp)+,&0x20		# restore fp2
6338 
6339 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
6340 	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
6341 	bra		t_inx2
6342 
6343 ATANBORS:
6344 #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
6345 #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
6346 	cmp.l		%d1,&0x3FFF8000
6347 	bgt.w		ATANBIG			# I.E. |X| >= 16
6348 
6349 ATANSM:
6350 #--|X| <= 1/16
6351 #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
6352 #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
6353 #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
6354 #--WHERE Y = X*X, AND Z = Y*Y.
6355 
6356 	cmp.l		%d1,&0x3FD78000
6357 	blt.w		ATANTINY
6358 
6359 #--COMPUTE POLYNOMIAL
6360 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
6361 
6362 	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
6363 
6364 	fmov.x		%fp0,%fp1
6365 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
6366 
6367 	fmov.d		ATANB6(%pc),%fp2
6368 	fmov.d		ATANB5(%pc),%fp3
6369 
6370 	fmul.x		%fp1,%fp2		# Z*B6
6371 	fmul.x		%fp1,%fp3		# Z*B5
6372 
6373 	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
6374 	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
6375 
6376 	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
6377 	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
6378 
6379 	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
6380 	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
6381 
6382 	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
6383 	fmul.x		X(%a6),%fp0		# X*Y
6384 
6385 	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
6386 
6387 	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
6388 
6389 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
6390 
6391 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
6392 	fadd.x		X(%a6),%fp0
6393 	bra		t_inx2
6394 
6395 ATANTINY:
6396 #--|X| < 2^(-40), ATAN(X) = X
6397 
6398 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
6399 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
6400 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
6401 
6402 	bra		t_catch
6403 
6404 ATANBIG:
6405 #--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
6406 #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
6407 	cmp.l		%d1,&0x40638000
6408 	bgt.w		ATANHUGE
6409 
6410 #--APPROXIMATE ATAN(-1/X) BY
6411 #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
6412 #--THIS CAN BE RE-WRITTEN AS
6413 #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
6414 
6415 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
6416 
6417 	fmov.s		&0xBF800000,%fp1	# LOAD -1
6418 	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
6419 
6420 #--DIVIDE IS STILL CRANKING
6421 
6422 	fmov.x		%fp1,%fp0		# FP0 IS X'
6423 	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
6424 	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
6425 
6426 	fmov.x		%fp0,%fp1
6427 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
6428 
6429 	fmov.d		ATANC5(%pc),%fp3
6430 	fmov.d		ATANC4(%pc),%fp2
6431 
6432 	fmul.x		%fp1,%fp3		# Z*C5
6433 	fmul.x		%fp1,%fp2		# Z*B4
6434 
6435 	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
6436 	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
6437 
6438 	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
6439 	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
6440 
6441 	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
6442 	fmul.x		X(%a6),%fp0		# X'*Y
6443 
6444 	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
6445 
6446 	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
6447 #					...	+[Y*(B2+Z*(B4+Z*B6))])
6448 	fadd.x		X(%a6),%fp0
6449 
6450 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
6451 
6452 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
6453 	tst.b		(%a0)
6454 	bpl.b		pos_big
6455 
6456 neg_big:
6457 	fadd.x		NPIBY2(%pc),%fp0
6458 	bra		t_minx2
6459 
6460 pos_big:
6461 	fadd.x		PPIBY2(%pc),%fp0
6462 	bra		t_pinx2
6463 
6464 ATANHUGE:
6465 #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
6466 	tst.b		(%a0)
6467 	bpl.b		pos_huge
6468 
6469 neg_huge:
6470 	fmov.x		NPIBY2(%pc),%fp0
6471 	fmov.l		%d0,%fpcr
6472 	fadd.x		PTINY(%pc),%fp0
6473 	bra		t_minx2
6474 
6475 pos_huge:
6476 	fmov.x		PPIBY2(%pc),%fp0
6477 	fmov.l		%d0,%fpcr
6478 	fadd.x		NTINY(%pc),%fp0
6479 	bra		t_pinx2
6480 
6481 	global		satand
6482 #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
6483 satand:
6484 	bra		t_extdnrm
6485 
6486 #########################################################################
6487 # sasin():  computes the inverse sine of a normalized input		#
6488 # sasind(): computes the inverse sine of a denormalized input		#
6489 #									#
6490 # INPUT ***************************************************************	#
6491 #	a0 = pointer to extended precision input			#
6492 #	d0 = round precision,mode					#
6493 #									#
6494 # OUTPUT **************************************************************	#
6495 #	fp0 = arcsin(X)							#
6496 #									#
6497 # ACCURACY and MONOTONICITY *******************************************	#
6498 #	The returned result is within 3 ulps in	64 significant bit,	#
6499 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
6500 #	rounded to double precision. The result is provably monotonic	#
6501 #	in double precision.						#
6502 #									#
6503 # ALGORITHM ***********************************************************	#
6504 #									#
6505 #	ASIN								#
6506 #	1. If |X| >= 1, go to 3.					#
6507 #									#
6508 #	2. (|X| < 1) Calculate asin(X) by				#
6509 #		z := sqrt( [1-X][1+X] )					#
6510 #		asin(X) = atan( x / z ).				#
6511 #		Exit.							#
6512 #									#
6513 #	3. If |X| > 1, go to 5.						#
6514 #									#
6515 #	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
6516 #									#
6517 #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
6518 #		Exit.							#
6519 #									#
6520 #########################################################################
6521 
6522 	global		sasin
6523 sasin:
6524 	fmov.x		(%a0),%fp0		# LOAD INPUT
6525 
6526 	mov.l		(%a0),%d1
6527 	mov.w		4(%a0),%d1
6528 	and.l		&0x7FFFFFFF,%d1
6529 	cmp.l		%d1,&0x3FFF8000
6530 	bge.b		ASINBIG
6531 
6532 # This catch is added here for the '060 QSP. Originally, the call to
6533 # satan() would handle this case by causing the exception which would
6534 # not be caught until gen_except(). Now, with the exceptions being
6535 # detected inside of satan(), the exception would have been handled there
6536 # instead of inside sasin() as expected.
6537 	cmp.l		%d1,&0x3FD78000
6538 	blt.w		ASINTINY
6539 
6540 #--THIS IS THE USUAL CASE, |X| < 1
6541 #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
6542 
6543 ASINMAIN:
6544 	fmov.s		&0x3F800000,%fp1
6545 	fsub.x		%fp0,%fp1		# 1-X
6546 	fmovm.x		&0x4,-(%sp)		#  {fp2}
6547 	fmov.s		&0x3F800000,%fp2
6548 	fadd.x		%fp0,%fp2		# 1+X
6549 	fmul.x		%fp2,%fp1		# (1+X)(1-X)
6550 	fmovm.x		(%sp)+,&0x20		#  {fp2}
6551 	fsqrt.x		%fp1			# SQRT([1-X][1+X])
6552 	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
6553 	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
6554 	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
6555 	bsr		satan
6556 	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
6557 	bra		t_inx2
6558 
6559 ASINBIG:
6560 	fabs.x		%fp0			# |X|
6561 	fcmp.s		%fp0,&0x3F800000
6562 	fbgt		t_operr			# cause an operr exception
6563 
6564 #--|X| = 1, ASIN(X) = +- PI/2.
6565 ASINONE:
6566 	fmov.x		PIBY2(%pc),%fp0
6567 	mov.l		(%a0),%d1
6568 	and.l		&0x80000000,%d1		# SIGN BIT OF X
6569 	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
6570 	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
6571 	fmov.l		%d0,%fpcr
6572 	fmul.s		(%sp)+,%fp0
6573 	bra		t_inx2
6574 
6575 #--|X| < 2^(-40), ATAN(X) = X
6576 ASINTINY:
6577 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
6578 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
6579 	fmov.x		(%a0),%fp0		# last inst - possible exception
6580 	bra		t_catch
6581 
6582 	global		sasind
6583 #--ASIN(X) = X FOR DENORMALIZED X
6584 sasind:
6585 	bra		t_extdnrm
6586 
6587 #########################################################################
6588 # sacos():  computes the inverse cosine of a normalized input		#
6589 # sacosd(): computes the inverse cosine of a denormalized input		#
6590 #									#
6591 # INPUT ***************************************************************	#
6592 #	a0 = pointer to extended precision input			#
6593 #	d0 = round precision,mode					#
6594 #									#
6595 # OUTPUT ************************************************************** #
6596 #	fp0 = arccos(X)							#
6597 #									#
6598 # ACCURACY and MONOTONICITY *******************************************	#
6599 #	The returned result is within 3 ulps in	64 significant bit,	#
6600 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
6601 #	rounded to double precision. The result is provably monotonic	#
6602 #	in double precision.						#
6603 #									#
6604 # ALGORITHM *********************************************************** #
6605 #									#
6606 #	ACOS								#
6607 #	1. If |X| >= 1, go to 3.					#
6608 #									#
6609 #	2. (|X| < 1) Calculate acos(X) by				#
6610 #		z := (1-X) / (1+X)					#
6611 #		acos(X) = 2 * atan( sqrt(z) ).				#
6612 #		Exit.							#
6613 #									#
6614 #	3. If |X| > 1, go to 5.						#
6615 #									#
6616 #	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
6617 #									#
6618 #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
6619 #		Exit.							#
6620 #									#
6621 #########################################################################
6622 
6623 	global		sacos
6624 sacos:
6625 	fmov.x		(%a0),%fp0		# LOAD INPUT
6626 
6627 	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
6628 	mov.w		4(%a0),%d1
6629 	and.l		&0x7FFFFFFF,%d1
6630 	cmp.l		%d1,&0x3FFF8000
6631 	bge.b		ACOSBIG
6632 
6633 #--THIS IS THE USUAL CASE, |X| < 1
6634 #--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
6635 
6636 ACOSMAIN:
6637 	fmov.s		&0x3F800000,%fp1
6638 	fadd.x		%fp0,%fp1		# 1+X
6639 	fneg.x		%fp0			# -X
6640 	fadd.s		&0x3F800000,%fp0	# 1-X
6641 	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
6642 	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
6643 	mov.l		%d0,-(%sp)		# save original users fpcr
6644 	clr.l		%d0
6645 	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
6646 	lea		(%sp),%a0		# pass ptr to sqrt
6647 	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
6648 	add.l		&0xc,%sp		# clear SQRT(...) from stack
6649 
6650 	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
6651 	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
6652 	bra		t_pinx2
6653 
6654 ACOSBIG:
6655 	fabs.x		%fp0
6656 	fcmp.s		%fp0,&0x3F800000
6657 	fbgt		t_operr			# cause an operr exception
6658 
6659 #--|X| = 1, ACOS(X) = 0 OR PI
6660 	tst.b		(%a0)			# is X positive or negative?
6661 	bpl.b		ACOSP1
6662 
6663 #--X = -1
6664 #Returns PI and inexact exception
6665 ACOSM1:
6666 	fmov.x		PI(%pc),%fp0		# load PI
6667 	fmov.l		%d0,%fpcr		# load round mode,prec
6668 	fadd.s		&0x00800000,%fp0	# add a small value
6669 	bra		t_pinx2
6670 
6671 ACOSP1:
6672 	bra		ld_pzero		# answer is positive zero
6673 
6674 	global		sacosd
6675 #--ACOS(X) = PI/2 FOR DENORMALIZED X
6676 sacosd:
6677 	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
6678 	fmov.x		PIBY2(%pc),%fp0
6679 	bra		t_pinx2
6680 
6681 #########################################################################
6682 # setox():    computes the exponential for a normalized input		#
6683 # setoxd():   computes the exponential for a denormalized input		#
6684 # setoxm1():  computes the exponential minus 1 for a normalized input	#
6685 # setoxm1d(): computes the exponential minus 1 for a denormalized input	#
6686 #									#
6687 # INPUT	*************************************************************** #
6688 #	a0 = pointer to extended precision input			#
6689 #	d0 = round precision,mode					#
6690 #									#
6691 # OUTPUT ************************************************************** #
6692 #	fp0 = exp(X) or exp(X)-1					#
6693 #									#
6694 # ACCURACY and MONOTONICITY ******************************************* #
6695 #	The returned result is within 0.85 ulps in 64 significant bit,	#
6696 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
6697 #	rounded to double precision. The result is provably monotonic	#
6698 #	in double precision.						#
6699 #									#
6700 # ALGORITHM and IMPLEMENTATION **************************************** #
6701 #									#
6702 #	setoxd								#
6703 #	------								#
6704 #	Step 1.	Set ans := 1.0						#
6705 #									#
6706 #	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
6707 #	Notes:	This will always generate one exception -- inexact.	#
6708 #									#
6709 #									#
6710 #	setox								#
6711 #	-----								#
6712 #									#
6713 #	Step 1.	Filter out extreme cases of input argument.		#
6714 #		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
6715 #		1.2	Go to Step 7.					#
6716 #		1.3	If |X| < 16380 log(2), go to Step 2.		#
6717 #		1.4	Go to Step 8.					#
6718 #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
6719 #		To avoid the use of floating-point comparisons, a	#
6720 #		compact representation of |X| is used. This format is a	#
6721 #		32-bit integer, the upper (more significant) 16 bits	#
6722 #		are the sign and biased exponent field of |X|; the	#
6723 #		lower 16 bits are the 16 most significant fraction	#
6724 #		(including the explicit bit) bits of |X|. Consequently,	#
6725 #		the comparisons in Steps 1.1 and 1.3 can be performed	#
6726 #		by integer comparison. Note also that the constant	#
6727 #		16380 log(2) used in Step 1.3 is also in the compact	#
6728 #		form. Thus taking the branch to Step 2 guarantees	#
6729 #		|X| < 16380 log(2). There is no harm to have a small	#
6730 #		number of cases where |X| is less than,	but close to,	#
6731 #		16380 log(2) and the branch to Step 9 is taken.		#
6732 #									#
6733 #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
6734 #		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
6735 #			was taken)					#
6736 #		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
6737 #		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
6738 #			or 63.						#
6739 #		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
6740 #		2.5	Calculate the address of the stored value of	#
6741 #			2^(J/64).					#
6742 #		2.6	Create the value Scale = 2^M.			#
6743 #	Notes:	The calculation in 2.2 is really performed by		#
6744 #			Z := X * constant				#
6745 #			N := round-to-nearest-integer(Z)		#
6746 #		where							#
6747 #			constant := single-precision( 64/log 2 ).	#
6748 #									#
6749 #		Using a single-precision constant avoids memory		#
6750 #		access. Another effect of using a single-precision	#
6751 #		"constant" is that the calculated value Z is		#
6752 #									#
6753 #			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
6754 #									#
6755 #		This error has to be considered later in Steps 3 and 4.	#
6756 #									#
6757 #	Step 3.	Calculate X - N*log2/64.				#
6758 #		3.1	R := X + N*L1,					#
6759 #				where L1 := single-precision(-log2/64).	#
6760 #		3.2	R := R + N*L2,					#
6761 #				L2 := extended-precision(-log2/64 - L1).#
6762 #	Notes:	a) The way L1 and L2 are chosen ensures L1+L2		#
6763 #		approximate the value -log2/64 to 88 bits of accuracy.	#
6764 #		b) N*L1 is exact because N is no longer than 22 bits	#
6765 #		and L1 is no longer than 24 bits.			#
6766 #		c) The calculation X+N*L1 is also exact due to		#
6767 #		cancellation. Thus, R is practically X+N(L1+L2) to full	#
6768 #		64 bits.						#
6769 #		d) It is important to estimate how large can |R| be	#
6770 #		after Step 3.2.						#
6771 #									#
6772 #		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
6773 #		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
6774 #		X*64/log2 - N	=	f - eps*X 64/log2		#
6775 #		X - N*log2/64	=	f*log2/64 - eps*X		#
6776 #									#
6777 #									#
6778 #		Now |X| <= 16446 log2, thus				#
6779 #									#
6780 #			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
6781 #					<= 0.57 log2/64.		#
6782 #		 This bound will be used in Step 4.			#
6783 #									#
6784 #	Step 4.	Approximate exp(R)-1 by a polynomial			#
6785 #		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
6786 #	Notes:	a) In order to reduce memory access, the coefficients	#
6787 #		are made as "short" as possible: A1 (which is 1/2), A4	#
6788 #		and A5 are single precision; A2 and A3 are double	#
6789 #		precision.						#
6790 #		b) Even with the restrictions above,			#
6791 #		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
6792 #		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
6793 #		c) To fully utilize the pipeline, p is separated into	#
6794 #		two independent pieces of roughly equal complexities	#
6795 #			p = [ R + R*S*(A2 + S*A4) ]	+		#
6796 #				[ S*(A1 + S*(A3 + S*A5)) ]		#
6797 #		where S = R*R.						#
6798 #									#
6799 #	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
6800 #				ans := T + ( T*p + t)			#
6801 #		where T and t are the stored values for 2^(J/64).	#
6802 #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
6803 #		2^(J/64) to roughly 85 bits; T is in extended precision	#
6804 #		and t is in single precision. Note also that T is	#
6805 #		rounded to 62 bits so that the last two bits of T are	#
6806 #		zero. The reason for such a special form is that T-1,	#
6807 #		T-2, and T-8 will all be exact --- a property that will	#
6808 #		give much more accurate computation of the function	#
6809 #		EXPM1.							#
6810 #									#
6811 #	Step 6.	Reconstruction of exp(X)				#
6812 #			exp(X) = 2^M * 2^(J/64) * exp(R).		#
6813 #		6.1	If AdjFlag = 0, go to 6.3			#
6814 #		6.2	ans := ans * AdjScale				#
6815 #		6.3	Restore the user FPCR				#
6816 #		6.4	Return ans := ans * Scale. Exit.		#
6817 #	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
6818 #		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
6819 #		neither overflow nor underflow. If AdjFlag = 1, that	#
6820 #		means that						#
6821 #			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
6822 #		Hence, exp(X) may overflow or underflow or neither.	#
6823 #		When that is the case, AdjScale = 2^(M1) where M1 is	#
6824 #		approximately M. Thus 6.2 will never cause		#
6825 #		over/underflow. Possible exception in 6.4 is overflow	#
6826 #		or underflow. The inexact exception is not generated in	#
6827 #		6.4. Although one can argue that the inexact flag	#
6828 #		should always be raised, to simulate that exception	#
6829 #		cost to much than the flag is worth in practical uses.	#
6830 #									#
6831 #	Step 7.	Return 1 + X.						#
6832 #		7.1	ans := X					#
6833 #		7.2	Restore user FPCR.				#
6834 #		7.3	Return ans := 1 + ans. Exit			#
6835 #	Notes:	For non-zero X, the inexact exception will always be	#
6836 #		raised by 7.3. That is the only exception raised by 7.3.#
6837 #		Note also that we use the FMOVEM instruction to move X	#
6838 #		in Step 7.1 to avoid unnecessary trapping. (Although	#
6839 #		the FMOVEM may not seem relevant since X is normalized,	#
6840 #		the precaution will be useful in the library version of	#
6841 #		this code where the separate entry for denormalized	#
6842 #		inputs will be done away with.)				#
6843 #									#
6844 #	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
6845 #		8.1	If |X| > 16480 log2, go to Step 9.		#
6846 #		(mimic 2.2 - 2.6)					#
6847 #		8.2	N := round-to-integer( X * 64/log2 )		#
6848 #		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
6849 #		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1,	#
6850 #			AdjFlag := 1.					#
6851 #		8.5	Calculate the address of the stored value	#
6852 #			2^(J/64).					#
6853 #		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
6854 #		8.7	Go to Step 3.					#
6855 #	Notes:	Refer to notes for 2.2 - 2.6.				#
6856 #									#
6857 #	Step 9.	Handle exp(X), |X| > 16480 log2.			#
6858 #		9.1	If X < 0, go to 9.3				#
6859 #		9.2	ans := Huge, go to 9.4				#
6860 #		9.3	ans := Tiny.					#
6861 #		9.4	Restore user FPCR.				#
6862 #		9.5	Return ans := ans * ans. Exit.			#
6863 #	Notes:	Exp(X) will surely overflow or underflow, depending on	#
6864 #		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
6865 #		extended-precision numbers whose square over/underflow	#
6866 #		with an inexact result. Thus, 9.5 always raises the	#
6867 #		inexact together with either overflow or underflow.	#
6868 #									#
6869 #	setoxm1d							#
6870 #	--------							#
6871 #									#
6872 #	Step 1.	Set ans := 0						#
6873 #									#
6874 #	Step 2.	Return	ans := X + ans. Exit.				#
6875 #	Notes:	This will return X with the appropriate rounding	#
6876 #		 precision prescribed by the user FPCR.			#
6877 #									#
6878 #	setoxm1								#
6879 #	-------								#
6880 #									#
6881 #	Step 1.	Check |X|						#
6882 #		1.1	If |X| >= 1/4, go to Step 1.3.			#
6883 #		1.2	Go to Step 7.					#
6884 #		1.3	If |X| < 70 log(2), go to Step 2.		#
6885 #		1.4	Go to Step 10.					#
6886 #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
6887 #		However, it is conceivable |X| can be small very often	#
6888 #		because EXPM1 is intended to evaluate exp(X)-1		#
6889 #		accurately when |X| is small. For further details on	#
6890 #		the comparisons, see the notes on Step 1 of setox.	#
6891 #									#
6892 #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
6893 #		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
6894 #		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
6895 #			or 63.						#
6896 #		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
6897 #		2.4	Calculate the address of the stored value of	#
6898 #			2^(J/64).					#
6899 #		2.5	Create the values Sc = 2^M and			#
6900 #			OnebySc := -2^(-M).				#
6901 #	Notes:	See the notes on Step 2 of setox.			#
6902 #									#
6903 #	Step 3.	Calculate X - N*log2/64.				#
6904 #		3.1	R := X + N*L1,					#
6905 #				where L1 := single-precision(-log2/64).	#
6906 #		3.2	R := R + N*L2,					#
6907 #				L2 := extended-precision(-log2/64 - L1).#
6908 #	Notes:	Applying the analysis of Step 3 of setox in this case	#
6909 #		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
6910 #		this case).						#
6911 #									#
6912 #	Step 4.	Approximate exp(R)-1 by a polynomial			#
6913 #			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
6914 #	Notes:	a) In order to reduce memory access, the coefficients	#
6915 #		are made as "short" as possible: A1 (which is 1/2), A5	#
6916 #		and A6 are single precision; A2, A3 and A4 are double	#
6917 #		precision.						#
6918 #		b) Even with the restriction above,			#
6919 #			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
6920 #		for all |R| <= 0.0055.					#
6921 #		c) To fully utilize the pipeline, p is separated into	#
6922 #		two independent pieces of roughly equal complexity	#
6923 #			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
6924 #				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
6925 #		where S = R*R.						#
6926 #									#
6927 #	Step 5.	Compute 2^(J/64)*p by					#
6928 #				p := T*p				#
6929 #		where T and t are the stored values for 2^(J/64).	#
6930 #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
6931 #		2^(J/64) to roughly 85 bits; T is in extended precision	#
6932 #		and t is in single precision. Note also that T is	#
6933 #		rounded to 62 bits so that the last two bits of T are	#
6934 #		zero. The reason for such a special form is that T-1,	#
6935 #		T-2, and T-8 will all be exact --- a property that will	#
6936 #		be exploited in Step 6 below. The total relative error	#
6937 #		in p is no bigger than 2^(-67.7) compared to the final	#
6938 #		result.							#
6939 #									#
6940 #	Step 6.	Reconstruction of exp(X)-1				#
6941 #			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
6942 #		6.1	If M <= 63, go to Step 6.3.			#
6943 #		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
6944 #		6.3	If M >= -3, go to 6.5.				#
6945 #		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
6946 #		6.5	ans := (T + OnebySc) + (p + t).			#
6947 #		6.6	Restore user FPCR.				#
6948 #		6.7	Return ans := Sc * ans. Exit.			#
6949 #	Notes:	The various arrangements of the expressions give	#
6950 #		accurate evaluations.					#
6951 #									#
6952 #	Step 7.	exp(X)-1 for |X| < 1/4.					#
6953 #		7.1	If |X| >= 2^(-65), go to Step 9.		#
6954 #		7.2	Go to Step 8.					#
6955 #									#
6956 #	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
6957 #		8.1	If |X| < 2^(-16312), goto 8.3			#
6958 #		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
6959 #			Exit.						#
6960 #		8.3	X := X * 2^(140).				#
6961 #		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
6962 #		 Return ans := ans*2^(140). Exit			#
6963 #	Notes:	The idea is to return "X - tiny" under the user		#
6964 #		precision and rounding modes. To avoid unnecessary	#
6965 #		inefficiency, we stay away from denormalized numbers	#
6966 #		the best we can. For |X| >= 2^(-16312), the		#
6967 #		straightforward 8.2 generates the inexact exception as	#
6968 #		the case warrants.					#
6969 #									#
6970 #	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
6971 #			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
6972 #	Notes:	a) In order to reduce memory access, the coefficients	#
6973 #		are made as "short" as possible: B1 (which is 1/2), B9	#
6974 #		to B12 are single precision; B3 to B8 are double	#
6975 #		precision; and B2 is double extended.			#
6976 #		b) Even with the restriction above,			#
6977 #			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
6978 #		for all |X| <= 0.251.					#
6979 #		Note that 0.251 is slightly bigger than 1/4.		#
6980 #		c) To fully preserve accuracy, the polynomial is	#
6981 #		computed as						#
6982 #			X + ( S*B1 +	Q ) where S = X*X and		#
6983 #			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
6984 #		d) To fully utilize the pipeline, Q is separated into	#
6985 #		two independent pieces of roughly equal complexity	#
6986 #			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
6987 #				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
6988 #									#
6989 #	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
6990 #		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all	#
6991 #		practical purposes. Therefore, go to Step 1 of setox.	#
6992 #		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
6993 #		purposes.						#
6994 #		ans := -1						#
6995 #		Restore user FPCR					#
6996 #		Return ans := ans + 2^(-126). Exit.			#
6997 #	Notes:	10.2 will always create an inexact and return -1 + tiny	#
6998 #		in the user rounding precision and mode.		#
6999 #									#
7000 #########################################################################
7001 
7002 L2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
7003 
7004 EEXPA3:	long		0x3FA55555,0x55554CC1
7005 EEXPA2:	long		0x3FC55555,0x55554A54
7006 
7007 EM1A4:	long		0x3F811111,0x11174385
7008 EM1A3:	long		0x3FA55555,0x55554F5A
7009 
7010 EM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
7011 
7012 EM1B8:	long		0x3EC71DE3,0xA5774682
7013 EM1B7:	long		0x3EFA01A0,0x19D7CB68
7014 
7015 EM1B6:	long		0x3F2A01A0,0x1A019DF3
7016 EM1B5:	long		0x3F56C16C,0x16C170E2
7017 
7018 EM1B4:	long		0x3F811111,0x11111111
7019 EM1B3:	long		0x3FA55555,0x55555555
7020 
7021 EM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
7022 	long		0x00000000
7023 
7024 TWO140:	long		0x48B00000,0x00000000
7025 TWON140:
7026 	long		0x37300000,0x00000000
7027 
7028 EEXPTBL:
7029 	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
7030 	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
7031 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
7032 	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
7033 	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
7034 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
7035 	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
7036 	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
7037 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
7038 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
7039 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
7040 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
7041 	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
7042 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
7043 	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
7044 	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
7045 	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
7046 	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
7047 	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
7048 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
7049 	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
7050 	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
7051 	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
7052 	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
7053 	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
7054 	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
7055 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
7056 	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
7057 	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
7058 	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
7059 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
7060 	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
7061 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
7062 	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
7063 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
7064 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
7065 	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
7066 	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
7067 	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
7068 	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
7069 	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
7070 	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
7071 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
7072 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
7073 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
7074 	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
7075 	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
7076 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
7077 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
7078 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
7079 	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
7080 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
7081 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
7082 	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
7083 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
7084 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
7085 	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
7086 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
7087 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
7088 	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
7089 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
7090 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
7091 	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
7092 	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
7093 
7094 	set		ADJFLAG,L_SCR2
7095 	set		SCALE,FP_SCR0
7096 	set		ADJSCALE,FP_SCR1
7097 	set		SC,FP_SCR0
7098 	set		ONEBYSC,FP_SCR1
7099 
7100 	global		setox
7101 setox:
7102 #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
7103 
7104 #--Step 1.
7105 	mov.l		(%a0),%d1		# load part of input X
7106 	and.l		&0x7FFF0000,%d1		# biased expo. of X
7107 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
7108 	bge.b		EXPC1			# normal case
7109 	bra		EXPSM
7110 
7111 EXPC1:
7112 #--The case |X| >= 2^(-65)
7113 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
7114 	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
7115 	blt.b		EXPMAIN			# normal case
7116 	bra		EEXPBIG
7117 
7118 EXPMAIN:
7119 #--Step 2.
7120 #--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
7121 	fmov.x		(%a0),%fp0		# load input from (a0)
7122 
7123 	fmov.x		%fp0,%fp1
7124 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
7125 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
7126 	mov.l		&0,ADJFLAG(%a6)
7127 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
7128 	lea		EEXPTBL(%pc),%a1
7129 	fmov.l		%d1,%fp0		# convert to floating-format
7130 
7131 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
7132 	and.l		&0x3F,%d1		# D0 is J = N mod 64
7133 	lsl.l		&4,%d1
7134 	add.l		%d1,%a1			# address of 2^(J/64)
7135 	mov.l		L_SCR1(%a6),%d1
7136 	asr.l		&6,%d1			# D0 is M
7137 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
7138 	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
7139 
7140 EXPCONT1:
7141 #--Step 3.
7142 #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
7143 #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
7144 	fmov.x		%fp0,%fp2
7145 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
7146 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
7147 	fadd.x		%fp1,%fp0		# X + N*L1
7148 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
7149 
7150 #--Step 4.
7151 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
7152 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
7153 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
7154 #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
7155 
7156 	fmov.x		%fp0,%fp1
7157 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
7158 
7159 	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
7160 
7161 	fmul.x		%fp1,%fp2		# fp2 IS S*A5
7162 	fmov.x		%fp1,%fp3
7163 	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
7164 
7165 	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
7166 	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
7167 
7168 	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
7169 	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
7170 	mov.l		&0x80000000,SCALE+4(%a6)
7171 	clr.l		SCALE+8(%a6)
7172 
7173 	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
7174 
7175 	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
7176 	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
7177 
7178 	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
7179 	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
7180 
7181 	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
7182 	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
7183 
7184 #--Step 5
7185 #--final reconstruction process
7186 #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
7187 
7188 	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
7189 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
7190 	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
7191 
7192 	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
7193 	mov.l		ADJFLAG(%a6),%d1
7194 
7195 #--Step 6
7196 	tst.l		%d1
7197 	beq.b		NORMAL
7198 ADJUST:
7199 	fmul.x		ADJSCALE(%a6),%fp0
7200 NORMAL:
7201 	fmov.l		%d0,%fpcr		# restore user FPCR
7202 	mov.b		&FMUL_OP,%d1		# last inst is MUL
7203 	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
7204 	bra		t_catch
7205 
7206 EXPSM:
7207 #--Step 7
7208 	fmovm.x		(%a0),&0x80		# load X
7209 	fmov.l		%d0,%fpcr
7210 	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
7211 	bra		t_pinx2
7212 
7213 EEXPBIG:
7214 #--Step 8
7215 	cmp.l		%d1,&0x400CB27C		# 16480 log2
7216 	bgt.b		EXP2BIG
7217 #--Steps 8.2 -- 8.6
7218 	fmov.x		(%a0),%fp0		# load input from (a0)
7219 
7220 	fmov.x		%fp0,%fp1
7221 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
7222 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
7223 	mov.l		&1,ADJFLAG(%a6)
7224 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
7225 	lea		EEXPTBL(%pc),%a1
7226 	fmov.l		%d1,%fp0		# convert to floating-format
7227 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
7228 	and.l		&0x3F,%d1		# D0 is J = N mod 64
7229 	lsl.l		&4,%d1
7230 	add.l		%d1,%a1			# address of 2^(J/64)
7231 	mov.l		L_SCR1(%a6),%d1
7232 	asr.l		&6,%d1			# D0 is K
7233 	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
7234 	asr.l		&1,%d1			# D0 is M1
7235 	sub.l		%d1,L_SCR1(%a6)		# a1 is M
7236 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
7237 	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
7238 	mov.l		&0x80000000,ADJSCALE+4(%a6)
7239 	clr.l		ADJSCALE+8(%a6)
7240 	mov.l		L_SCR1(%a6),%d1		# D0 is M
7241 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
7242 	bra.w		EXPCONT1		# go back to Step 3
7243 
7244 EXP2BIG:
7245 #--Step 9
7246 	tst.b		(%a0)			# is X positive or negative?
7247 	bmi		t_unfl2
7248 	bra		t_ovfl2
7249 
7250 	global		setoxd
7251 setoxd:
7252 #--entry point for EXP(X), X is denormalized
7253 	mov.l		(%a0),-(%sp)
7254 	andi.l		&0x80000000,(%sp)
7255 	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
7256 
7257 	fmov.s		&0x3F800000,%fp0
7258 
7259 	fmov.l		%d0,%fpcr
7260 	fadd.s		(%sp)+,%fp0
7261 	bra		t_pinx2
7262 
7263 	global		setoxm1
7264 setoxm1:
7265 #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
7266 
7267 #--Step 1.
7268 #--Step 1.1
7269 	mov.l		(%a0),%d1		# load part of input X
7270 	and.l		&0x7FFF0000,%d1		# biased expo. of X
7271 	cmp.l		%d1,&0x3FFD0000		# 1/4
7272 	bge.b		EM1CON1			# |X| >= 1/4
7273 	bra		EM1SM
7274 
7275 EM1CON1:
7276 #--Step 1.3
7277 #--The case |X| >= 1/4
7278 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
7279 	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
7280 	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
7281 	bra		EM1BIG
7282 
7283 EM1MAIN:
7284 #--Step 2.
7285 #--This is the case:	1/4 <= |X| <= 70 log2.
7286 	fmov.x		(%a0),%fp0		# load input from (a0)
7287 
7288 	fmov.x		%fp0,%fp1
7289 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
7290 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
7291 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
7292 	lea		EEXPTBL(%pc),%a1
7293 	fmov.l		%d1,%fp0		# convert to floating-format
7294 
7295 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
7296 	and.l		&0x3F,%d1		# D0 is J = N mod 64
7297 	lsl.l		&4,%d1
7298 	add.l		%d1,%a1			# address of 2^(J/64)
7299 	mov.l		L_SCR1(%a6),%d1
7300 	asr.l		&6,%d1			# D0 is M
7301 	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
7302 
7303 #--Step 3.
7304 #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
7305 #--a0 points to 2^(J/64), D0 and a1 both contain M
7306 	fmov.x		%fp0,%fp2
7307 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
7308 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
7309 	fadd.x		%fp1,%fp0		# X + N*L1
7310 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
7311 	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
7312 
7313 #--Step 4.
7314 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
7315 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
7316 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
7317 #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
7318 
7319 	fmov.x		%fp0,%fp1
7320 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
7321 
7322 	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
7323 
7324 	fmul.x		%fp1,%fp2		# fp2 IS S*A6
7325 	fmov.x		%fp1,%fp3
7326 	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
7327 
7328 	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
7329 	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
7330 	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
7331 	mov.l		&0x80000000,SC+4(%a6)
7332 	clr.l		SC+8(%a6)
7333 
7334 	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
7335 	mov.l		L_SCR1(%a6),%d1		# D0 is	M
7336 	neg.w		%d1			# D0 is -M
7337 	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
7338 	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
7339 	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
7340 	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
7341 
7342 	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
7343 	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
7344 	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
7345 	mov.l		&0x80000000,ONEBYSC+4(%a6)
7346 	clr.l		ONEBYSC+8(%a6)
7347 	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
7348 
7349 	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
7350 	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
7351 
7352 	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
7353 
7354 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
7355 
7356 #--Step 5
7357 #--Compute 2^(J/64)*p
7358 
7359 	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
7360 
7361 #--Step 6
7362 #--Step 6.1
7363 	mov.l		L_SCR1(%a6),%d1		# retrieve M
7364 	cmp.l		%d1,&63
7365 	ble.b		MLE63
7366 #--Step 6.2	M >= 64
7367 	fmov.s		12(%a1),%fp1		# fp1 is t
7368 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
7369 	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
7370 	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
7371 	bra		EM1SCALE
7372 MLE63:
7373 #--Step 6.3	M <= 63
7374 	cmp.l		%d1,&-3
7375 	bge.b		MGEN3
7376 MLTN3:
7377 #--Step 6.4	M <= -4
7378 	fadd.s		12(%a1),%fp0		# p+t
7379 	fadd.x		(%a1),%fp0		# T+(p+t)
7380 	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
7381 	bra		EM1SCALE
7382 MGEN3:
7383 #--Step 6.5	-3 <= M <= 63
7384 	fmov.x		(%a1)+,%fp1		# fp1 is T
7385 	fadd.s		(%a1),%fp0		# fp0 is p+t
7386 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
7387 	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
7388 
7389 EM1SCALE:
7390 #--Step 6.6
7391 	fmov.l		%d0,%fpcr
7392 	fmul.x		SC(%a6),%fp0
7393 	bra		t_inx2
7394 
7395 EM1SM:
7396 #--Step 7	|X| < 1/4.
7397 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
7398 	bge.b		EM1POLY
7399 
7400 EM1TINY:
7401 #--Step 8	|X| < 2^(-65)
7402 	cmp.l		%d1,&0x00330000		# 2^(-16312)
7403 	blt.b		EM12TINY
7404 #--Step 8.2
7405 	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
7406 	mov.l		&0x80000000,SC+4(%a6)
7407 	clr.l		SC+8(%a6)
7408 	fmov.x		(%a0),%fp0
7409 	fmov.l		%d0,%fpcr
7410 	mov.b		&FADD_OP,%d1		# last inst is ADD
7411 	fadd.x		SC(%a6),%fp0
7412 	bra		t_catch
7413 
7414 EM12TINY:
7415 #--Step 8.3
7416 	fmov.x		(%a0),%fp0
7417 	fmul.d		TWO140(%pc),%fp0
7418 	mov.l		&0x80010000,SC(%a6)
7419 	mov.l		&0x80000000,SC+4(%a6)
7420 	clr.l		SC+8(%a6)
7421 	fadd.x		SC(%a6),%fp0
7422 	fmov.l		%d0,%fpcr
7423 	mov.b		&FMUL_OP,%d1		# last inst is MUL
7424 	fmul.d		TWON140(%pc),%fp0
7425 	bra		t_catch
7426 
7427 EM1POLY:
7428 #--Step 9	exp(X)-1 by a simple polynomial
7429 	fmov.x		(%a0),%fp0		# fp0 is X
7430 	fmul.x		%fp0,%fp0		# fp0 is S := X*X
7431 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
7432 	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
7433 	fmul.x		%fp0,%fp1		# fp1 is S*B12
7434 	fmov.s		&0x310F8290,%fp2	# fp2 is B11
7435 	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
7436 
7437 	fmul.x		%fp0,%fp2		# fp2 is S*B11
7438 	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
7439 
7440 	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
7441 	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
7442 
7443 	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
7444 	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
7445 
7446 	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
7447 	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
7448 
7449 	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
7450 	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
7451 
7452 	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
7453 	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
7454 
7455 	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
7456 	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
7457 
7458 	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
7459 	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
7460 
7461 	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
7462 	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
7463 
7464 	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
7465 	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
7466 
7467 	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
7468 	fadd.x		%fp2,%fp1		# fp1 is Q
7469 
7470 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
7471 
7472 	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
7473 
7474 	fmov.l		%d0,%fpcr
7475 	fadd.x		(%a0),%fp0
7476 	bra		t_inx2
7477 
7478 EM1BIG:
7479 #--Step 10	|X| > 70 log2
7480 	mov.l		(%a0),%d1
7481 	cmp.l		%d1,&0
7482 	bgt.w		EXPC1
7483 #--Step 10.2
7484 	fmov.s		&0xBF800000,%fp0	# fp0 is -1
7485 	fmov.l		%d0,%fpcr
7486 	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
7487 	bra		t_minx2
7488 
7489 	global		setoxm1d
7490 setoxm1d:
7491 #--entry point for EXPM1(X), here X is denormalized
7492 #--Step 0.
7493 	bra		t_extdnrm
7494 
7495 #########################################################################
7496 # sgetexp():  returns the exponent portion of the input argument.	#
7497 #	      The exponent bias is removed and the exponent value is	#
7498 #	      returned as an extended precision number in fp0.		#
7499 # sgetexpd(): handles denormalized numbers.				#
7500 #									#
7501 # sgetman():  extracts the mantissa of the input argument. The		#
7502 #	      mantissa is converted to an extended precision number w/	#
7503 #	      an exponent of $3fff and is returned in fp0. The range of #
7504 #	      the result is [1.0 - 2.0).				#
7505 # sgetmand(): handles denormalized numbers.				#
7506 #									#
7507 # INPUT *************************************************************** #
7508 #	a0  = pointer to extended precision input			#
7509 #									#
7510 # OUTPUT ************************************************************** #
7511 #	fp0 = exponent(X) or mantissa(X)				#
7512 #									#
7513 #########################################################################
7514 
7515 	global		sgetexp
7516 sgetexp:
7517 	mov.w		SRC_EX(%a0),%d0		# get the exponent
7518 	bclr		&0xf,%d0		# clear the sign bit
7519 	subi.w		&0x3fff,%d0		# subtract off the bias
7520 	fmov.w		%d0,%fp0		# return exp in fp0
7521 	blt.b		sgetexpn		# it's negative
7522 	rts
7523 
7524 sgetexpn:
7525 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
7526 	rts
7527 
7528 	global		sgetexpd
7529 sgetexpd:
7530 	bsr.l		norm			# normalize
7531 	neg.w		%d0			# new exp = -(shft amt)
7532 	subi.w		&0x3fff,%d0		# subtract off the bias
7533 	fmov.w		%d0,%fp0		# return exp in fp0
7534 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
7535 	rts
7536 
7537 	global		sgetman
7538 sgetman:
7539 	mov.w		SRC_EX(%a0),%d0		# get the exp
7540 	ori.w		&0x7fff,%d0		# clear old exp
7541 	bclr		&0xe,%d0		# make it the new exp +-3fff
7542 
7543 # here, we build the result in a tmp location so as not to disturb the input
7544 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
7545 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
7546 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
7547 	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
7548 	bmi.b		sgetmann		# it's negative
7549 	rts
7550 
7551 sgetmann:
7552 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
7553 	rts
7554 
7555 #
7556 # For denormalized numbers, shift the mantissa until the j-bit = 1,
7557 # then load the exponent with +/1 $3fff.
7558 #
7559 	global		sgetmand
7560 sgetmand:
7561 	bsr.l		norm			# normalize exponent
7562 	bra.b		sgetman
7563 
7564 #########################################################################
7565 # scosh():  computes the hyperbolic cosine of a normalized input	#
7566 # scoshd(): computes the hyperbolic cosine of a denormalized input	#
7567 #									#
7568 # INPUT ***************************************************************	#
7569 #	a0 = pointer to extended precision input			#
7570 #	d0 = round precision,mode					#
7571 #									#
7572 # OUTPUT **************************************************************	#
7573 #	fp0 = cosh(X)							#
7574 #									#
7575 # ACCURACY and MONOTONICITY *******************************************	#
7576 #	The returned result is within 3 ulps in 64 significant bit,	#
7577 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
7578 #	rounded to double precision. The result is provably monotonic	#
7579 #	in double precision.						#
7580 #									#
7581 # ALGORITHM ***********************************************************	#
7582 #									#
7583 #	COSH								#
7584 #	1. If |X| > 16380 log2, go to 3.				#
7585 #									#
7586 #	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
7587 #		y = |X|, z = exp(Y), and				#
7588 #		cosh(X) = (1/2)*( z + 1/z ).				#
7589 #		Exit.							#
7590 #									#
7591 #	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
7592 #									#
7593 #	4. (16380 log2 < |X| <= 16480 log2)				#
7594 #		cosh(X) = sign(X) * exp(|X|)/2.				#
7595 #		However, invoking exp(|X|) may cause premature		#
7596 #		overflow. Thus, we calculate sinh(X) as follows:	#
7597 #		Y	:= |X|						#
7598 #		Fact	:=	2**(16380)				#
7599 #		Y'	:= Y - 16381 log2				#
7600 #		cosh(X) := Fact * exp(Y').				#
7601 #		Exit.							#
7602 #									#
7603 #	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
7604 #		Huge*Huge to generate overflow and an infinity with	#
7605 #		the appropriate sign. Huge is the largest finite number	#
7606 #		in extended format. Exit.				#
7607 #									#
7608 #########################################################################
7609 
7610 TWO16380:
7611 	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
7612 
7613 	global		scosh
7614 scosh:
7615 	fmov.x		(%a0),%fp0		# LOAD INPUT
7616 
7617 	mov.l		(%a0),%d1
7618 	mov.w		4(%a0),%d1
7619 	and.l		&0x7FFFFFFF,%d1
7620 	cmp.l		%d1,&0x400CB167
7621 	bgt.b		COSHBIG
7622 
7623 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
7624 #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
7625 
7626 	fabs.x		%fp0			# |X|
7627 
7628 	mov.l		%d0,-(%sp)
7629 	clr.l		%d0
7630 	fmovm.x		&0x01,-(%sp)		# save |X| to stack
7631 	lea		(%sp),%a0		# pass ptr to |X|
7632 	bsr		setox			# FP0 IS EXP(|X|)
7633 	add.l		&0xc,%sp		# erase |X| from stack
7634 	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
7635 	mov.l		(%sp)+,%d0
7636 
7637 	fmov.s		&0x3E800000,%fp1	# (1/4)
7638 	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
7639 
7640 	fmov.l		%d0,%fpcr
7641 	mov.b		&FADD_OP,%d1		# last inst is ADD
7642 	fadd.x		%fp1,%fp0
7643 	bra		t_catch
7644 
7645 COSHBIG:
7646 	cmp.l		%d1,&0x400CB2B3
7647 	bgt.b		COSHHUGE
7648 
7649 	fabs.x		%fp0
7650 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
7651 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
7652 
7653 	mov.l		%d0,-(%sp)
7654 	clr.l		%d0
7655 	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
7656 	lea		(%sp),%a0		# pass ptr to fp0
7657 	bsr		setox
7658 	add.l		&0xc,%sp		# clear fp0 from stack
7659 	mov.l		(%sp)+,%d0
7660 
7661 	fmov.l		%d0,%fpcr
7662 	mov.b		&FMUL_OP,%d1		# last inst is MUL
7663 	fmul.x		TWO16380(%pc),%fp0
7664 	bra		t_catch
7665 
7666 COSHHUGE:
7667 	bra		t_ovfl2
7668 
7669 	global		scoshd
7670 #--COSH(X) = 1 FOR DENORMALIZED X
7671 scoshd:
7672 	fmov.s		&0x3F800000,%fp0
7673 
7674 	fmov.l		%d0,%fpcr
7675 	fadd.s		&0x00800000,%fp0
7676 	bra		t_pinx2
7677 
7678 #########################################################################
7679 # ssinh():  computes the hyperbolic sine of a normalized input		#
7680 # ssinhd(): computes the hyperbolic sine of a denormalized input	#
7681 #									#
7682 # INPUT *************************************************************** #
7683 #	a0 = pointer to extended precision input			#
7684 #	d0 = round precision,mode					#
7685 #									#
7686 # OUTPUT ************************************************************** #
7687 #	fp0 = sinh(X)							#
7688 #									#
7689 # ACCURACY and MONOTONICITY *******************************************	#
7690 #	The returned result is within 3 ulps in 64 significant bit,	#
7691 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
7692 #	rounded to double precision. The result is provably monotonic	#
7693 #	in double precision.						#
7694 #									#
7695 # ALGORITHM *********************************************************** #
7696 #									#
7697 #       SINH								#
7698 #       1. If |X| > 16380 log2, go to 3.				#
7699 #									#
7700 #       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
7701 #               y = |X|, sgn = sign(X), and z = expm1(Y),		#
7702 #               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
7703 #          Exit.							#
7704 #									#
7705 #       3. If |X| > 16480 log2, go to 5.				#
7706 #									#
7707 #       4. (16380 log2 < |X| <= 16480 log2)				#
7708 #               sinh(X) = sign(X) * exp(|X|)/2.				#
7709 #          However, invoking exp(|X|) may cause premature overflow.	#
7710 #          Thus, we calculate sinh(X) as follows:			#
7711 #             Y       := |X|						#
7712 #             sgn     := sign(X)					#
7713 #             sgnFact := sgn * 2**(16380)				#
7714 #             Y'      := Y - 16381 log2					#
7715 #             sinh(X) := sgnFact * exp(Y').				#
7716 #          Exit.							#
7717 #									#
7718 #       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
7719 #          sign(X)*Huge*Huge to generate overflow and an infinity with	#
7720 #          the appropriate sign. Huge is the largest finite number in	#
7721 #          extended format. Exit.					#
7722 #									#
7723 #########################################################################
7724 
7725 	global		ssinh
7726 ssinh:
7727 	fmov.x		(%a0),%fp0		# LOAD INPUT
7728 
7729 	mov.l		(%a0),%d1
7730 	mov.w		4(%a0),%d1
7731 	mov.l		%d1,%a1			# save (compacted) operand
7732 	and.l		&0x7FFFFFFF,%d1
7733 	cmp.l		%d1,&0x400CB167
7734 	bgt.b		SINHBIG
7735 
7736 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
7737 #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
7738 
7739 	fabs.x		%fp0			# Y = |X|
7740 
7741 	movm.l		&0x8040,-(%sp)		# {a1/d0}
7742 	fmovm.x		&0x01,-(%sp)		# save Y on stack
7743 	lea		(%sp),%a0		# pass ptr to Y
7744 	clr.l		%d0
7745 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
7746 	add.l		&0xc,%sp		# clear Y from stack
7747 	fmov.l		&0,%fpcr
7748 	movm.l		(%sp)+,&0x0201		# {a1/d0}
7749 
7750 	fmov.x		%fp0,%fp1
7751 	fadd.s		&0x3F800000,%fp1	# 1+Z
7752 	fmov.x		%fp0,-(%sp)
7753 	fdiv.x		%fp1,%fp0		# Z/(1+Z)
7754 	mov.l		%a1,%d1
7755 	and.l		&0x80000000,%d1
7756 	or.l		&0x3F000000,%d1
7757 	fadd.x		(%sp)+,%fp0
7758 	mov.l		%d1,-(%sp)
7759 
7760 	fmov.l		%d0,%fpcr
7761 	mov.b		&FMUL_OP,%d1		# last inst is MUL
7762 	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
7763 	bra		t_catch
7764 
7765 SINHBIG:
7766 	cmp.l		%d1,&0x400CB2B3
7767 	bgt		t_ovfl
7768 	fabs.x		%fp0
7769 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
7770 	mov.l		&0,-(%sp)
7771 	mov.l		&0x80000000,-(%sp)
7772 	mov.l		%a1,%d1
7773 	and.l		&0x80000000,%d1
7774 	or.l		&0x7FFB0000,%d1
7775 	mov.l		%d1,-(%sp)		# EXTENDED FMT
7776 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
7777 
7778 	mov.l		%d0,-(%sp)
7779 	clr.l		%d0
7780 	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
7781 	lea		(%sp),%a0		# pass ptr to fp0
7782 	bsr		setox
7783 	add.l		&0xc,%sp		# clear fp0 from stack
7784 
7785 	mov.l		(%sp)+,%d0
7786 	fmov.l		%d0,%fpcr
7787 	mov.b		&FMUL_OP,%d1		# last inst is MUL
7788 	fmul.x		(%sp)+,%fp0		# possible exception
7789 	bra		t_catch
7790 
7791 	global		ssinhd
7792 #--SINH(X) = X FOR DENORMALIZED X
7793 ssinhd:
7794 	bra		t_extdnrm
7795 
7796 #########################################################################
7797 # stanh():  computes the hyperbolic tangent of a normalized input	#
7798 # stanhd(): computes the hyperbolic tangent of a denormalized input	#
7799 #									#
7800 # INPUT ***************************************************************	#
7801 #	a0 = pointer to extended precision input			#
7802 #	d0 = round precision,mode					#
7803 #									#
7804 # OUTPUT **************************************************************	#
7805 #	fp0 = tanh(X)							#
7806 #									#
7807 # ACCURACY and MONOTONICITY *******************************************	#
7808 #	The returned result is within 3 ulps in 64 significant bit,	#
7809 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
7810 #	rounded to double precision. The result is provably monotonic	#
7811 #	in double precision.						#
7812 #									#
7813 # ALGORITHM ***********************************************************	#
7814 #									#
7815 #	TANH								#
7816 #	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
7817 #									#
7818 #	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
7819 #		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
7820 #		tanh(X) = sgn*( z/(2+z) ).				#
7821 #		Exit.							#
7822 #									#
7823 #	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
7824 #		go to 7.						#
7825 #									#
7826 #	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
7827 #									#
7828 #	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
7829 #		sgn := sign(X), y := 2|X|, z := exp(Y),			#
7830 #		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
7831 #		Exit.							#
7832 #									#
7833 #	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
7834 #		calculate Tanh(X) by					#
7835 #		sgn := sign(X), Tiny := 2**(-126),			#
7836 #		tanh(X) := sgn - sgn*Tiny.				#
7837 #		Exit.							#
7838 #									#
7839 #	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
7840 #									#
7841 #########################################################################
7842 
7843 	set		X,FP_SCR0
7844 	set		XFRAC,X+4
7845 
7846 	set		SGN,L_SCR3
7847 
7848 	set		V,FP_SCR0
7849 
7850 	global		stanh
7851 stanh:
7852 	fmov.x		(%a0),%fp0		# LOAD INPUT
7853 
7854 	fmov.x		%fp0,X(%a6)
7855 	mov.l		(%a0),%d1
7856 	mov.w		4(%a0),%d1
7857 	mov.l		%d1,X(%a6)
7858 	and.l		&0x7FFFFFFF,%d1
7859 	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
7860 	blt.w		TANHBORS		# yes
7861 	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
7862 	bgt.w		TANHBORS		# yes
7863 
7864 #--THIS IS THE USUAL CASE
7865 #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
7866 
7867 	mov.l		X(%a6),%d1
7868 	mov.l		%d1,SGN(%a6)
7869 	and.l		&0x7FFF0000,%d1
7870 	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
7871 	mov.l		%d1,X(%a6)
7872 	and.l		&0x80000000,SGN(%a6)
7873 	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
7874 
7875 	mov.l		%d0,-(%sp)
7876 	clr.l		%d0
7877 	fmovm.x		&0x1,-(%sp)		# save Y on stack
7878 	lea		(%sp),%a0		# pass ptr to Y
7879 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
7880 	add.l		&0xc,%sp		# clear Y from stack
7881 	mov.l		(%sp)+,%d0
7882 
7883 	fmov.x		%fp0,%fp1
7884 	fadd.s		&0x40000000,%fp1	# Z+2
7885 	mov.l		SGN(%a6),%d1
7886 	fmov.x		%fp1,V(%a6)
7887 	eor.l		%d1,V(%a6)
7888 
7889 	fmov.l		%d0,%fpcr		# restore users round prec,mode
7890 	fdiv.x		V(%a6),%fp0
7891 	bra		t_inx2
7892 
7893 TANHBORS:
7894 	cmp.l		%d1,&0x3FFF8000
7895 	blt.w		TANHSM
7896 
7897 	cmp.l		%d1,&0x40048AA1
7898 	bgt.w		TANHHUGE
7899 
7900 #-- (5/2) LOG2 < |X| < 50 LOG2,
7901 #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
7902 #--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
7903 
7904 	mov.l		X(%a6),%d1
7905 	mov.l		%d1,SGN(%a6)
7906 	and.l		&0x7FFF0000,%d1
7907 	add.l		&0x00010000,%d1		# EXPO OF 2|X|
7908 	mov.l		%d1,X(%a6)		# Y = 2|X|
7909 	and.l		&0x80000000,SGN(%a6)
7910 	mov.l		SGN(%a6),%d1
7911 	fmov.x		X(%a6),%fp0		# Y = 2|X|
7912 
7913 	mov.l		%d0,-(%sp)
7914 	clr.l		%d0
7915 	fmovm.x		&0x01,-(%sp)		# save Y on stack
7916 	lea		(%sp),%a0		# pass ptr to Y
7917 	bsr		setox			# FP0 IS EXP(Y)
7918 	add.l		&0xc,%sp		# clear Y from stack
7919 	mov.l		(%sp)+,%d0
7920 	mov.l		SGN(%a6),%d1
7921 	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
7922 
7923 	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
7924 	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
7925 	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
7926 
7927 	mov.l		SGN(%a6),%d1
7928 	or.l		&0x3F800000,%d1		# SGN
7929 	fmov.s		%d1,%fp0		# SGN IN SGL FMT
7930 
7931 	fmov.l		%d0,%fpcr		# restore users round prec,mode
7932 	mov.b		&FADD_OP,%d1		# last inst is ADD
7933 	fadd.x		%fp1,%fp0
7934 	bra		t_inx2
7935 
7936 TANHSM:
7937 	fmov.l		%d0,%fpcr		# restore users round prec,mode
7938 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
7939 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
7940 	bra		t_catch
7941 
7942 #---RETURN SGN(X) - SGN(X)EPS
7943 TANHHUGE:
7944 	mov.l		X(%a6),%d1
7945 	and.l		&0x80000000,%d1
7946 	or.l		&0x3F800000,%d1
7947 	fmov.s		%d1,%fp0
7948 	and.l		&0x80000000,%d1
7949 	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
7950 
7951 	fmov.l		%d0,%fpcr		# restore users round prec,mode
7952 	fadd.s		%d1,%fp0
7953 	bra		t_inx2
7954 
7955 	global		stanhd
7956 #--TANH(X) = X FOR DENORMALIZED X
7957 stanhd:
7958 	bra		t_extdnrm
7959 
7960 #########################################################################
7961 # slogn():    computes the natural logarithm of a normalized input	#
7962 # slognd():   computes the natural logarithm of a denormalized input	#
7963 # slognp1():  computes the log(1+X) of a normalized input		#
7964 # slognp1d(): computes the log(1+X) of a denormalized input		#
7965 #									#
7966 # INPUT ***************************************************************	#
7967 #	a0 = pointer to extended precision input			#
7968 #	d0 = round precision,mode					#
7969 #									#
7970 # OUTPUT **************************************************************	#
7971 #	fp0 = log(X) or log(1+X)					#
7972 #									#
7973 # ACCURACY and MONOTONICITY *******************************************	#
7974 #	The returned result is within 2 ulps in 64 significant bit,	#
7975 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
7976 #	rounded to double precision. The result is provably monotonic	#
7977 #	in double precision.						#
7978 #									#
7979 # ALGORITHM ***********************************************************	#
7980 #	LOGN:								#
7981 #	Step 1. If |X-1| < 1/16, approximate log(X) by an odd		#
7982 #		polynomial in u, where u = 2(X-1)/(X+1). Otherwise,	#
7983 #		move on to Step 2.					#
7984 #									#
7985 #	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
7986 #		seven significant bits of Y plus 2**(-7), i.e.		#
7987 #		F = 1.xxxxxx1 in base 2 where the six "x" match those	#
7988 #		of Y. Note that |Y-F| <= 2**(-7).			#
7989 #									#
7990 #	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a		#
7991 #		polynomial in u, log(1+u) = poly.			#
7992 #									#
7993 #	Step 4. Reconstruct						#
7994 #		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
7995 #		by k*log(2) + (log(F) + poly). The values of log(F) are	#
7996 #		calculated beforehand and stored in the program.	#
7997 #									#
7998 #	lognp1:								#
7999 #	Step 1: If |X| < 1/16, approximate log(1+X) by an odd		#
8000 #		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
8001 #		to Step 2.						#
8002 #									#
8003 #	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
8004 #		in Step 2 of the algorithm for LOGN and compute		#
8005 #		log(1+X) as k*log(2) + log(F) + poly where poly		#
8006 #		approximates log(1+u), u = (Y-F)/F.			#
8007 #									#
8008 #	Implementation Notes:						#
8009 #	Note 1. There are 64 different possible values for F, thus 64	#
8010 #		log(F)'s need to be tabulated. Moreover, the values of	#
8011 #		1/F are also tabulated so that the division in (Y-F)/F	#
8012 #		can be performed by a multiplication.			#
8013 #									#
8014 #	Note 2. In Step 2 of lognp1, in order to preserved accuracy,	#
8015 #		the value Y-F has to be calculated carefully when	#
8016 #		1/2 <= X < 3/2.						#
8017 #									#
8018 #	Note 3. To fully exploit the pipeline, polynomials are usually	#
8019 #		separated into two parts evaluated independently before	#
8020 #		being added up.						#
8021 #									#
8022 #########################################################################
8023 LOGOF2:
8024 	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
8025 
8026 one:
8027 	long		0x3F800000
8028 zero:
8029 	long		0x00000000
8030 infty:
8031 	long		0x7F800000
8032 negone:
8033 	long		0xBF800000
8034 
8035 LOGA6:
8036 	long		0x3FC2499A,0xB5E4040B
8037 LOGA5:
8038 	long		0xBFC555B5,0x848CB7DB
8039 
8040 LOGA4:
8041 	long		0x3FC99999,0x987D8730
8042 LOGA3:
8043 	long		0xBFCFFFFF,0xFF6F7E97
8044 
8045 LOGA2:
8046 	long		0x3FD55555,0x555555A4
8047 LOGA1:
8048 	long		0xBFE00000,0x00000008
8049 
8050 LOGB5:
8051 	long		0x3F175496,0xADD7DAD6
8052 LOGB4:
8053 	long		0x3F3C71C2,0xFE80C7E0
8054 
8055 LOGB3:
8056 	long		0x3F624924,0x928BCCFF
8057 LOGB2:
8058 	long		0x3F899999,0x999995EC
8059 
8060 LOGB1:
8061 	long		0x3FB55555,0x55555555
8062 TWO:
8063 	long		0x40000000,0x00000000
8064 
8065 LTHOLD:
8066 	long		0x3f990000,0x80000000,0x00000000,0x00000000
8067 
8068 LOGTBL:
8069 	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
8070 	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
8071 	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
8072 	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
8073 	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
8074 	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
8075 	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
8076 	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
8077 	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
8078 	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
8079 	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
8080 	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
8081 	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
8082 	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
8083 	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
8084 	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
8085 	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
8086 	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
8087 	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
8088 	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
8089 	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
8090 	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
8091 	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
8092 	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
8093 	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
8094 	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
8095 	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
8096 	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
8097 	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
8098 	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
8099 	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
8100 	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
8101 	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
8102 	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
8103 	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
8104 	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
8105 	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
8106 	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
8107 	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
8108 	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
8109 	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
8110 	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
8111 	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
8112 	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
8113 	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
8114 	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
8115 	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
8116 	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
8117 	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
8118 	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
8119 	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
8120 	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
8121 	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
8122 	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
8123 	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
8124 	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
8125 	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
8126 	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
8127 	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
8128 	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
8129 	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
8130 	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
8131 	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
8132 	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
8133 	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
8134 	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
8135 	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
8136 	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
8137 	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
8138 	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
8139 	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
8140 	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
8141 	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
8142 	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
8143 	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
8144 	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
8145 	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
8146 	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
8147 	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
8148 	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
8149 	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
8150 	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
8151 	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
8152 	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
8153 	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
8154 	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
8155 	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
8156 	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
8157 	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
8158 	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
8159 	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
8160 	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
8161 	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
8162 	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
8163 	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
8164 	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
8165 	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
8166 	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
8167 	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
8168 	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
8169 	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
8170 	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
8171 	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
8172 	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
8173 	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
8174 	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
8175 	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
8176 	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
8177 	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
8178 	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
8179 	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
8180 	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
8181 	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
8182 	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
8183 	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
8184 	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
8185 	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
8186 	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
8187 	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
8188 	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
8189 	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
8190 	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
8191 	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
8192 	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
8193 	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
8194 	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
8195 	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
8196 	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
8197 
8198 	set		ADJK,L_SCR1
8199 
8200 	set		X,FP_SCR0
8201 	set		XDCARE,X+2
8202 	set		XFRAC,X+4
8203 
8204 	set		F,FP_SCR1
8205 	set		FFRAC,F+4
8206 
8207 	set		KLOG2,FP_SCR0
8208 
8209 	set		SAVEU,FP_SCR0
8210 
8211 	global		slogn
8212 #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
8213 slogn:
8214 	fmov.x		(%a0),%fp0		# LOAD INPUT
8215 	mov.l		&0x00000000,ADJK(%a6)
8216 
8217 LOGBGN:
8218 #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
8219 #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
8220 
8221 	mov.l		(%a0),%d1
8222 	mov.w		4(%a0),%d1
8223 
8224 	mov.l		(%a0),X(%a6)
8225 	mov.l		4(%a0),X+4(%a6)
8226 	mov.l		8(%a0),X+8(%a6)
8227 
8228 	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
8229 	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
8230 # X IS POSITIVE, CHECK IF X IS NEAR 1
8231 	cmp.l		%d1,&0x3ffef07d		# IS X < 15/16?
8232 	blt.b		LOGMAIN			# YES
8233 	cmp.l		%d1,&0x3fff8841		# IS X > 17/16?
8234 	ble.w		LOGNEAR1		# NO
8235 
8236 LOGMAIN:
8237 #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
8238 
8239 #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
8240 #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
8241 #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
8242 #--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
8243 #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
8244 #--LOG(1+U) CAN BE VERY EFFICIENT.
8245 #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
8246 #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
8247 
8248 #--GET K, Y, F, AND ADDRESS OF 1/F.
8249 	asr.l		&8,%d1
8250 	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
8251 	sub.l		&0x3FFF,%d1		# THIS IS K
8252 	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
8253 	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
8254 	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
8255 
8256 #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
8257 	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
8258 	mov.l		XFRAC(%a6),FFRAC(%a6)
8259 	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
8260 	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
8261 	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
8262 	and.l		&0x7E000000,%d1
8263 	asr.l		&8,%d1
8264 	asr.l		&8,%d1
8265 	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
8266 	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
8267 
8268 	fmov.x		X(%a6),%fp0
8269 	mov.l		&0x3fff0000,F(%a6)
8270 	clr.l		F+8(%a6)
8271 	fsub.x		F(%a6),%fp0		# Y-F
8272 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
8273 #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
8274 #--REGISTERS SAVED: FPCR, FP1, FP2
8275 
8276 LP1CONT1:
8277 #--AN RE-ENTRY POINT FOR LOGNP1
8278 	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
8279 	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
8280 	fmov.x		%fp0,%fp2
8281 	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
8282 	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
8283 
8284 #--LOG(1+U) IS APPROXIMATED BY
8285 #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
8286 #--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
8287 
8288 	fmov.x		%fp2,%fp3
8289 	fmov.x		%fp2,%fp1
8290 
8291 	fmul.d		LOGA6(%pc),%fp1		# V*A6
8292 	fmul.d		LOGA5(%pc),%fp2		# V*A5
8293 
8294 	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
8295 	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
8296 
8297 	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
8298 	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
8299 
8300 	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
8301 	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
8302 
8303 	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
8304 	add.l		&16,%a0			# ADDRESS OF LOG(F)
8305 	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
8306 
8307 	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
8308 	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
8309 
8310 	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
8311 	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
8312 	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
8313 
8314 	fmov.l		%d0,%fpcr
8315 	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
8316 	bra		t_inx2
8317 
8318 
8319 LOGNEAR1:
8320 
8321 # if the input is exactly equal to one, then exit through ld_pzero.
8322 # if these 2 lines weren't here, the correct answer would be returned
8323 # but the INEX2 bit would be set.
8324 	fcmp.b		%fp0,&0x1		# is it equal to one?
8325 	fbeq.l		ld_pzero		# yes
8326 
8327 #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
8328 	fmov.x		%fp0,%fp1
8329 	fsub.s		one(%pc),%fp1		# FP1 IS X-1
8330 	fadd.s		one(%pc),%fp0		# FP0 IS X+1
8331 	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
8332 #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
8333 #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
8334 
8335 LP1CONT2:
8336 #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
8337 	fdiv.x		%fp0,%fp1		# FP1 IS U
8338 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
8339 #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
8340 #--LET V=U*U, W=V*V, CALCULATE
8341 #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
8342 #--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
8343 	fmov.x		%fp1,%fp0
8344 	fmul.x		%fp0,%fp0		# FP0 IS V
8345 	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
8346 	fmov.x		%fp0,%fp1
8347 	fmul.x		%fp1,%fp1		# FP1 IS W
8348 
8349 	fmov.d		LOGB5(%pc),%fp3
8350 	fmov.d		LOGB4(%pc),%fp2
8351 
8352 	fmul.x		%fp1,%fp3		# W*B5
8353 	fmul.x		%fp1,%fp2		# W*B4
8354 
8355 	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
8356 	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
8357 
8358 	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
8359 
8360 	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
8361 
8362 	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
8363 	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
8364 
8365 	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
8366 	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
8367 
8368 	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
8369 
8370 	fmov.l		%d0,%fpcr
8371 	fadd.x		SAVEU(%a6),%fp0
8372 	bra		t_inx2
8373 
8374 #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
8375 LOGNEG:
8376 	bra		t_operr
8377 
8378 	global		slognd
8379 slognd:
8380 #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
8381 
8382 	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
8383 
8384 #----normalize the input value by left shifting k bits (k to be determined
8385 #----below), adjusting exponent and storing -k to  ADJK
8386 #----the value TWOTO100 is no longer needed.
8387 #----Note that this code assumes the denormalized input is NON-ZERO.
8388 
8389 	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
8390 	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
8391 	mov.l		4(%a0),%d4
8392 	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
8393 	clr.l		%d2			# D2 used for holding K
8394 
8395 	tst.l		%d4
8396 	bne.b		Hi_not0
8397 
8398 Hi_0:
8399 	mov.l		%d5,%d4
8400 	clr.l		%d5
8401 	mov.l		&32,%d2
8402 	clr.l		%d6
8403 	bfffo		%d4{&0:&32},%d6
8404 	lsl.l		%d6,%d4
8405 	add.l		%d6,%d2			# (D3,D4,D5) is normalized
8406 
8407 	mov.l		%d3,X(%a6)
8408 	mov.l		%d4,XFRAC(%a6)
8409 	mov.l		%d5,XFRAC+4(%a6)
8410 	neg.l		%d2
8411 	mov.l		%d2,ADJK(%a6)
8412 	fmov.x		X(%a6),%fp0
8413 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
8414 	lea		X(%a6),%a0
8415 	bra.w		LOGBGN			# begin regular log(X)
8416 
8417 Hi_not0:
8418 	clr.l		%d6
8419 	bfffo		%d4{&0:&32},%d6		# find first 1
8420 	mov.l		%d6,%d2			# get k
8421 	lsl.l		%d6,%d4
8422 	mov.l		%d5,%d7			# a copy of D5
8423 	lsl.l		%d6,%d5
8424 	neg.l		%d6
8425 	add.l		&32,%d6
8426 	lsr.l		%d6,%d7
8427 	or.l		%d7,%d4			# (D3,D4,D5) normalized
8428 
8429 	mov.l		%d3,X(%a6)
8430 	mov.l		%d4,XFRAC(%a6)
8431 	mov.l		%d5,XFRAC+4(%a6)
8432 	neg.l		%d2
8433 	mov.l		%d2,ADJK(%a6)
8434 	fmov.x		X(%a6),%fp0
8435 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
8436 	lea		X(%a6),%a0
8437 	bra.w		LOGBGN			# begin regular log(X)
8438 
8439 	global		slognp1
8440 #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
8441 slognp1:
8442 	fmov.x		(%a0),%fp0		# LOAD INPUT
8443 	fabs.x		%fp0			# test magnitude
8444 	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
8445 	fbgt.w		LP1REAL			# if greater, continue
8446 	fmov.l		%d0,%fpcr
8447 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
8448 	fmov.x		(%a0),%fp0		# return signed argument
8449 	bra		t_catch
8450 
8451 LP1REAL:
8452 	fmov.x		(%a0),%fp0		# LOAD INPUT
8453 	mov.l		&0x00000000,ADJK(%a6)
8454 	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
8455 	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
8456 	fmov.x		%fp0,X(%a6)
8457 	mov.w		XFRAC(%a6),XDCARE(%a6)
8458 	mov.l		X(%a6),%d1
8459 	cmp.l		%d1,&0
8460 	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
8461 	cmp.l		%d1,&0x3ffe8000		# IS BOUNDS [1/2,3/2]?
8462 	blt.w		LOGMAIN
8463 	cmp.l		%d1,&0x3fffc000
8464 	bgt.w		LOGMAIN
8465 #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
8466 #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
8467 #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
8468 
8469 LP1NEAR1:
8470 #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
8471 	cmp.l		%d1,&0x3ffef07d
8472 	blt.w		LP1CARE
8473 	cmp.l		%d1,&0x3fff8841
8474 	bgt.w		LP1CARE
8475 
8476 LP1ONE16:
8477 #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
8478 #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
8479 	fadd.x		%fp1,%fp1		# FP1 IS 2Z
8480 	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
8481 #--U = FP1/FP0
8482 	bra.w		LP1CONT2
8483 
8484 LP1CARE:
8485 #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
8486 #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
8487 #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
8488 #--THERE ARE ONLY TWO CASES.
8489 #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
8490 #--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
8491 #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
8492 #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
8493 
8494 	mov.l		XFRAC(%a6),FFRAC(%a6)
8495 	and.l		&0xFE000000,FFRAC(%a6)
8496 	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
8497 	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
8498 	bge.b		KISZERO
8499 
8500 KISNEG1:
8501 	fmov.s		TWO(%pc),%fp0
8502 	mov.l		&0x3fff0000,F(%a6)
8503 	clr.l		F+8(%a6)
8504 	fsub.x		F(%a6),%fp0		# 2-F
8505 	mov.l		FFRAC(%a6),%d1
8506 	and.l		&0x7E000000,%d1
8507 	asr.l		&8,%d1
8508 	asr.l		&8,%d1
8509 	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
8510 	fadd.x		%fp1,%fp1		# GET 2Z
8511 	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
8512 	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
8513 	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
8514 	add.l		%d1,%a0
8515 	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
8516 	bra.w		LP1CONT1
8517 
8518 KISZERO:
8519 	fmov.s		one(%pc),%fp0
8520 	mov.l		&0x3fff0000,F(%a6)
8521 	clr.l		F+8(%a6)
8522 	fsub.x		F(%a6),%fp0		# 1-F
8523 	mov.l		FFRAC(%a6),%d1
8524 	and.l		&0x7E000000,%d1
8525 	asr.l		&8,%d1
8526 	asr.l		&8,%d1
8527 	asr.l		&4,%d1
8528 	fadd.x		%fp1,%fp0		# FP0 IS Y-F
8529 	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
8530 	lea		LOGTBL(%pc),%a0
8531 	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
8532 	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
8533 	bra.w		LP1CONT1
8534 
8535 LP1NEG0:
8536 #--FPCR SAVED. D0 IS X IN COMPACT FORM.
8537 	cmp.l		%d1,&0
8538 	blt.b		LP1NEG
8539 LP1ZERO:
8540 	fmov.s		negone(%pc),%fp0
8541 
8542 	fmov.l		%d0,%fpcr
8543 	bra		t_dz
8544 
8545 LP1NEG:
8546 	fmov.s		zero(%pc),%fp0
8547 
8548 	fmov.l		%d0,%fpcr
8549 	bra		t_operr
8550 
8551 	global		slognp1d
8552 #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
8553 # Simply return the denorm
8554 slognp1d:
8555 	bra		t_extdnrm
8556 
8557 #########################################################################
8558 # satanh():  computes the inverse hyperbolic tangent of a norm input	#
8559 # satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
8560 #									#
8561 # INPUT ***************************************************************	#
8562 #	a0 = pointer to extended precision input			#
8563 #	d0 = round precision,mode					#
8564 #									#
8565 # OUTPUT **************************************************************	#
8566 #	fp0 = arctanh(X)						#
8567 #									#
8568 # ACCURACY and MONOTONICITY *******************************************	#
8569 #	The returned result is within 3 ulps in	64 significant bit,	#
8570 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
8571 #	rounded to double precision. The result is provably monotonic	#
8572 #	in double precision.						#
8573 #									#
8574 # ALGORITHM ***********************************************************	#
8575 #									#
8576 #	ATANH								#
8577 #	1. If |X| >= 1, go to 3.					#
8578 #									#
8579 #	2. (|X| < 1) Calculate atanh(X) by				#
8580 #		sgn := sign(X)						#
8581 #		y := |X|						#
8582 #		z := 2y/(1-y)						#
8583 #		atanh(X) := sgn * (1/2) * logp1(z)			#
8584 #		Exit.							#
8585 #									#
8586 #	3. If |X| > 1, go to 5.						#
8587 #									#
8588 #	4. (|X| = 1) Generate infinity with an appropriate sign and	#
8589 #		divide-by-zero by					#
8590 #		sgn := sign(X)						#
8591 #		atan(X) := sgn / (+0).					#
8592 #		Exit.							#
8593 #									#
8594 #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
8595 #		Exit.							#
8596 #									#
8597 #########################################################################
8598 
8599 	global		satanh
8600 satanh:
8601 	mov.l		(%a0),%d1
8602 	mov.w		4(%a0),%d1
8603 	and.l		&0x7FFFFFFF,%d1
8604 	cmp.l		%d1,&0x3FFF8000
8605 	bge.b		ATANHBIG
8606 
8607 #--THIS IS THE USUAL CASE, |X| < 1
8608 #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
8609 
8610 	fabs.x		(%a0),%fp0		# Y = |X|
8611 	fmov.x		%fp0,%fp1
8612 	fneg.x		%fp1			# -Y
8613 	fadd.x		%fp0,%fp0		# 2Y
8614 	fadd.s		&0x3F800000,%fp1	# 1-Y
8615 	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
8616 	mov.l		(%a0),%d1
8617 	and.l		&0x80000000,%d1
8618 	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
8619 	mov.l		%d1,-(%sp)
8620 
8621 	mov.l		%d0,-(%sp)		# save rnd prec,mode
8622 	clr.l		%d0			# pass ext prec,RN
8623 	fmovm.x		&0x01,-(%sp)		# save Z on stack
8624 	lea		(%sp),%a0		# pass ptr to Z
8625 	bsr		slognp1			# LOG1P(Z)
8626 	add.l		&0xc,%sp		# clear Z from stack
8627 
8628 	mov.l		(%sp)+,%d0		# fetch old prec,mode
8629 	fmov.l		%d0,%fpcr		# load it
8630 	mov.b		&FMUL_OP,%d1		# last inst is MUL
8631 	fmul.s		(%sp)+,%fp0
8632 	bra		t_catch
8633 
8634 ATANHBIG:
8635 	fabs.x		(%a0),%fp0		# |X|
8636 	fcmp.s		%fp0,&0x3F800000
8637 	fbgt		t_operr
8638 	bra		t_dz
8639 
8640 	global		satanhd
8641 #--ATANH(X) = X FOR DENORMALIZED X
8642 satanhd:
8643 	bra		t_extdnrm
8644 
8645 #########################################################################
8646 # slog10():  computes the base-10 logarithm of a normalized input	#
8647 # slog10d(): computes the base-10 logarithm of a denormalized input	#
8648 # slog2():   computes the base-2 logarithm of a normalized input	#
8649 # slog2d():  computes the base-2 logarithm of a denormalized input	#
8650 #									#
8651 # INPUT *************************************************************** #
8652 #	a0 = pointer to extended precision input			#
8653 #	d0 = round precision,mode					#
8654 #									#
8655 # OUTPUT **************************************************************	#
8656 #	fp0 = log_10(X) or log_2(X)					#
8657 #									#
8658 # ACCURACY and MONOTONICITY *******************************************	#
8659 #	The returned result is within 1.7 ulps in 64 significant bit,	#
8660 #	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
8661 #	rounded to double precision. The result is provably monotonic	#
8662 #	in double precision.						#
8663 #									#
8664 # ALGORITHM ***********************************************************	#
8665 #									#
8666 #       slog10d:							#
8667 #									#
8668 #       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
8669 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
8670 #       Notes:  Default means round-to-nearest mode, no floating-point	#
8671 #               traps, and precision control = double extended.		#
8672 #									#
8673 #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
8674 #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
8675 #									#
8676 #       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
8677 #            2.1 Restore the user FPCR					#
8678 #            2.2 Return ans := Y * INV_L10.				#
8679 #									#
8680 #       slog10:								#
8681 #									#
8682 #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
8683 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
8684 #       Notes:  Default means round-to-nearest mode, no floating-point	#
8685 #               traps, and precision control = double extended.		#
8686 #									#
8687 #       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
8688 #									#
8689 #       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
8690 #            2.1  Restore the user FPCR					#
8691 #            2.2  Return ans := Y * INV_L10.				#
8692 #									#
8693 #       sLog2d:								#
8694 #									#
8695 #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
8696 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
8697 #       Notes:  Default means round-to-nearest mode, no floating-point	#
8698 #               traps, and precision control = double extended.		#
8699 #									#
8700 #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
8701 #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
8702 #									#
8703 #       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
8704 #            2.1  Restore the user FPCR					#
8705 #            2.2  Return ans := Y * INV_L2.				#
8706 #									#
8707 #       sLog2:								#
8708 #									#
8709 #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
8710 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
8711 #       Notes:  Default means round-to-nearest mode, no floating-point	#
8712 #               traps, and precision control = double extended.		#
8713 #									#
8714 #       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
8715 #               go to Step 3.						#
8716 #									#
8717 #       Step 2.   Return k.						#
8718 #            2.1  Get integer k, X = 2^k.				#
8719 #            2.2  Restore the user FPCR.				#
8720 #            2.3  Return ans := convert-to-double-extended(k).		#
8721 #									#
8722 #       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
8723 #									#
8724 #       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
8725 #            4.1  Restore the user FPCR					#
8726 #            4.2  Return ans := Y * INV_L2.				#
8727 #									#
8728 #########################################################################
8729 
8730 INV_L10:
8731 	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
8732 
8733 INV_L2:
8734 	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
8735 
8736 	global		slog10
8737 #--entry point for Log10(X), X is normalized
8738 slog10:
8739 	fmov.b		&0x1,%fp0
8740 	fcmp.x		%fp0,(%a0)		# if operand == 1,
8741 	fbeq.l		ld_pzero		# return an EXACT zero
8742 
8743 	mov.l		(%a0),%d1
8744 	blt.w		invalid
8745 	mov.l		%d0,-(%sp)
8746 	clr.l		%d0
8747 	bsr		slogn			# log(X), X normal.
8748 	fmov.l		(%sp)+,%fpcr
8749 	fmul.x		INV_L10(%pc),%fp0
8750 	bra		t_inx2
8751 
8752 	global		slog10d
8753 #--entry point for Log10(X), X is denormalized
8754 slog10d:
8755 	mov.l		(%a0),%d1
8756 	blt.w		invalid
8757 	mov.l		%d0,-(%sp)
8758 	clr.l		%d0
8759 	bsr		slognd			# log(X), X denorm.
8760 	fmov.l		(%sp)+,%fpcr
8761 	fmul.x		INV_L10(%pc),%fp0
8762 	bra		t_minx2
8763 
8764 	global		slog2
8765 #--entry point for Log2(X), X is normalized
8766 slog2:
8767 	mov.l		(%a0),%d1
8768 	blt.w		invalid
8769 
8770 	mov.l		8(%a0),%d1
8771 	bne.b		continue		# X is not 2^k
8772 
8773 	mov.l		4(%a0),%d1
8774 	and.l		&0x7FFFFFFF,%d1
8775 	bne.b		continue
8776 
8777 #--X = 2^k.
8778 	mov.w		(%a0),%d1
8779 	and.l		&0x00007FFF,%d1
8780 	sub.l		&0x3FFF,%d1
8781 	beq.l		ld_pzero
8782 	fmov.l		%d0,%fpcr
8783 	fmov.l		%d1,%fp0
8784 	bra		t_inx2
8785 
8786 continue:
8787 	mov.l		%d0,-(%sp)
8788 	clr.l		%d0
8789 	bsr		slogn			# log(X), X normal.
8790 	fmov.l		(%sp)+,%fpcr
8791 	fmul.x		INV_L2(%pc),%fp0
8792 	bra		t_inx2
8793 
8794 invalid:
8795 	bra		t_operr
8796 
8797 	global		slog2d
8798 #--entry point for Log2(X), X is denormalized
8799 slog2d:
8800 	mov.l		(%a0),%d1
8801 	blt.w		invalid
8802 	mov.l		%d0,-(%sp)
8803 	clr.l		%d0
8804 	bsr		slognd			# log(X), X denorm.
8805 	fmov.l		(%sp)+,%fpcr
8806 	fmul.x		INV_L2(%pc),%fp0
8807 	bra		t_minx2
8808 
8809 #########################################################################
8810 # stwotox():  computes 2**X for a normalized input			#
8811 # stwotoxd(): computes 2**X for a denormalized input			#
8812 # stentox():  computes 10**X for a normalized input			#
8813 # stentoxd(): computes 10**X for a denormalized input			#
8814 #									#
8815 # INPUT ***************************************************************	#
8816 #	a0 = pointer to extended precision input			#
8817 #	d0 = round precision,mode					#
8818 #									#
8819 # OUTPUT **************************************************************	#
8820 #	fp0 = 2**X or 10**X						#
8821 #									#
8822 # ACCURACY and MONOTONICITY *******************************************	#
8823 #	The returned result is within 2 ulps in 64 significant bit,	#
8824 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
8825 #	rounded to double precision. The result is provably monotonic	#
8826 #	in double precision.						#
8827 #									#
8828 # ALGORITHM ***********************************************************	#
8829 #									#
8830 #	twotox								#
8831 #	1. If |X| > 16480, go to ExpBig.				#
8832 #									#
8833 #	2. If |X| < 2**(-70), go to ExpSm.				#
8834 #									#
8835 #	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
8836 #		decompose N as						#
8837 #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
8838 #									#
8839 #	4. Overwrite r := r * log2. Then				#
8840 #		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
8841 #		Go to expr to compute that expression.			#
8842 #									#
8843 #	tentox								#
8844 #	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
8845 #									#
8846 #	2. If |X| < 2**(-70), go to ExpSm.				#
8847 #									#
8848 #	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
8849 #		N := round-to-int(y). Decompose N as			#
8850 #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
8851 #									#
8852 #	4. Define r as							#
8853 #		r := ((X - N*L1)-N*L2) * L10				#
8854 #		where L1, L2 are the leading and trailing parts of	#
8855 #		log_10(2)/64 and L10 is the natural log of 10. Then	#
8856 #		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
8857 #		Go to expr to compute that expression.			#
8858 #									#
8859 #	expr								#
8860 #	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
8861 #									#
8862 #	2. Overwrite Fact1 and Fact2 by					#
8863 #		Fact1 := 2**(M) * Fact1					#
8864 #		Fact2 := 2**(M) * Fact2					#
8865 #		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
8866 #									#
8867 #	3. Calculate P where 1 + P approximates exp(r):			#
8868 #		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
8869 #									#
8870 #	4. Let AdjFact := 2**(M'). Return				#
8871 #		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
8872 #		Exit.							#
8873 #									#
8874 #	ExpBig								#
8875 #	1. Generate overflow by Huge * Huge if X > 0; otherwise,	#
8876 #	        generate underflow by Tiny * Tiny.			#
8877 #									#
8878 #	ExpSm								#
8879 #	1. Return 1 + X.						#
8880 #									#
8881 #########################################################################
8882 
8883 L2TEN64:
8884 	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
8885 L10TWO1:
8886 	long		0x3F734413,0x509F8000	# LOG2/64LOG10
8887 
8888 L10TWO2:
8889 	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
8890 
8891 LOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
8892 
8893 LOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
8894 
8895 EXPA5:	long		0x3F56C16D,0x6F7BD0B2
8896 EXPA4:	long		0x3F811112,0x302C712C
8897 EXPA3:	long		0x3FA55555,0x55554CC1
8898 EXPA2:	long		0x3FC55555,0x55554A54
8899 EXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
8900 
8901 TEXPTBL:
8902 	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
8903 	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
8904 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
8905 	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
8906 	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
8907 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
8908 	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
8909 	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
8910 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
8911 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
8912 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
8913 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
8914 	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
8915 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
8916 	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
8917 	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
8918 	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
8919 	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
8920 	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
8921 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
8922 	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
8923 	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
8924 	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
8925 	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
8926 	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
8927 	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
8928 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
8929 	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
8930 	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
8931 	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
8932 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
8933 	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
8934 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
8935 	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
8936 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
8937 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
8938 	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
8939 	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
8940 	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
8941 	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
8942 	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
8943 	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
8944 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
8945 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
8946 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
8947 	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
8948 	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
8949 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
8950 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
8951 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
8952 	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
8953 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
8954 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
8955 	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
8956 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
8957 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
8958 	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
8959 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
8960 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
8961 	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
8962 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
8963 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
8964 	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
8965 	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
8966 
8967 	set		INT,L_SCR1
8968 
8969 	set		X,FP_SCR0
8970 	set		XDCARE,X+2
8971 	set		XFRAC,X+4
8972 
8973 	set		ADJFACT,FP_SCR0
8974 
8975 	set		FACT1,FP_SCR0
8976 	set		FACT1HI,FACT1+4
8977 	set		FACT1LOW,FACT1+8
8978 
8979 	set		FACT2,FP_SCR1
8980 	set		FACT2HI,FACT2+4
8981 	set		FACT2LOW,FACT2+8
8982 
8983 	global		stwotox
8984 #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
8985 stwotox:
8986 	fmovm.x		(%a0),&0x80		# LOAD INPUT
8987 
8988 	mov.l		(%a0),%d1
8989 	mov.w		4(%a0),%d1
8990 	fmov.x		%fp0,X(%a6)
8991 	and.l		&0x7FFFFFFF,%d1
8992 
8993 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
8994 	bge.b		TWOOK1
8995 	bra.w		EXPBORS
8996 
8997 TWOOK1:
8998 	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
8999 	ble.b		TWOMAIN
9000 	bra.w		EXPBORS
9001 
9002 TWOMAIN:
9003 #--USUAL CASE, 2^(-70) <= |X| <= 16480
9004 
9005 	fmov.x		%fp0,%fp1
9006 	fmul.s		&0x42800000,%fp1	# 64 * X
9007 	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
9008 	mov.l		%d2,-(%sp)
9009 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
9010 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
9011 	mov.l		INT(%a6),%d1
9012 	mov.l		%d1,%d2
9013 	and.l		&0x3F,%d1		# D0 IS J
9014 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
9015 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
9016 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
9017 	mov.l		%d2,%d1
9018 	asr.l		&1,%d1			# D0 IS M
9019 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
9020 	add.l		&0x3FFF,%d2
9021 
9022 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
9023 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
9024 #--ADJFACT = 2^(M').
9025 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
9026 
9027 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
9028 
9029 	fmul.s		&0x3C800000,%fp1	# (1/64)*N
9030 	mov.l		(%a1)+,FACT1(%a6)
9031 	mov.l		(%a1)+,FACT1HI(%a6)
9032 	mov.l		(%a1)+,FACT1LOW(%a6)
9033 	mov.w		(%a1)+,FACT2(%a6)
9034 
9035 	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
9036 
9037 	mov.w		(%a1)+,FACT2HI(%a6)
9038 	clr.w		FACT2HI+2(%a6)
9039 	clr.l		FACT2LOW(%a6)
9040 	add.w		%d1,FACT1(%a6)
9041 	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
9042 	add.w		%d1,FACT2(%a6)
9043 
9044 	bra.w		expr
9045 
9046 EXPBORS:
9047 #--FPCR, D0 SAVED
9048 	cmp.l		%d1,&0x3FFF8000
9049 	bgt.b		TEXPBIG
9050 
9051 #--|X| IS SMALL, RETURN 1 + X
9052 
9053 	fmov.l		%d0,%fpcr		# restore users round prec,mode
9054 	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
9055 	bra		t_pinx2
9056 
9057 TEXPBIG:
9058 #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
9059 #--REGISTERS SAVE SO FAR ARE FPCR AND  D0
9060 	mov.l		X(%a6),%d1
9061 	cmp.l		%d1,&0
9062 	blt.b		EXPNEG
9063 
9064 	bra		t_ovfl2			# t_ovfl expects positive value
9065 
9066 EXPNEG:
9067 	bra		t_unfl2			# t_unfl expects positive value
9068 
9069 	global		stwotoxd
9070 stwotoxd:
9071 #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
9072 
9073 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
9074 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
9075 	mov.l		(%a0),%d1
9076 	or.l		&0x00800001,%d1
9077 	fadd.s		%d1,%fp0
9078 	bra		t_pinx2
9079 
9080 	global		stentox
9081 #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
9082 stentox:
9083 	fmovm.x		(%a0),&0x80		# LOAD INPUT
9084 
9085 	mov.l		(%a0),%d1
9086 	mov.w		4(%a0),%d1
9087 	fmov.x		%fp0,X(%a6)
9088 	and.l		&0x7FFFFFFF,%d1
9089 
9090 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
9091 	bge.b		TENOK1
9092 	bra.w		EXPBORS
9093 
9094 TENOK1:
9095 	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
9096 	ble.b		TENMAIN
9097 	bra.w		EXPBORS
9098 
9099 TENMAIN:
9100 #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
9101 
9102 	fmov.x		%fp0,%fp1
9103 	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
9104 	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
9105 	mov.l		%d2,-(%sp)
9106 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
9107 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
9108 	mov.l		INT(%a6),%d1
9109 	mov.l		%d1,%d2
9110 	and.l		&0x3F,%d1		# D0 IS J
9111 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
9112 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
9113 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
9114 	mov.l		%d2,%d1
9115 	asr.l		&1,%d1			# D0 IS M
9116 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
9117 	add.l		&0x3FFF,%d2
9118 
9119 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
9120 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
9121 #--ADJFACT = 2^(M').
9122 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
9123 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
9124 
9125 	fmov.x		%fp1,%fp2
9126 
9127 	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
9128 	mov.l		(%a1)+,FACT1(%a6)
9129 
9130 	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
9131 
9132 	mov.l		(%a1)+,FACT1HI(%a6)
9133 	mov.l		(%a1)+,FACT1LOW(%a6)
9134 	fsub.x		%fp1,%fp0		# X - N L_LEAD
9135 	mov.w		(%a1)+,FACT2(%a6)
9136 
9137 	fsub.x		%fp2,%fp0		# X - N L_TRAIL
9138 
9139 	mov.w		(%a1)+,FACT2HI(%a6)
9140 	clr.w		FACT2HI+2(%a6)
9141 	clr.l		FACT2LOW(%a6)
9142 
9143 	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
9144 	add.w		%d1,FACT1(%a6)
9145 	add.w		%d1,FACT2(%a6)
9146 
9147 expr:
9148 #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
9149 #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
9150 #--FP0 IS R. THE FOLLOWING CODE COMPUTES
9151 #--	2**(M'+M) * 2**(J/64) * EXP(R)
9152 
9153 	fmov.x		%fp0,%fp1
9154 	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
9155 
9156 	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
9157 	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
9158 
9159 	fmul.x		%fp1,%fp2		# FP2 IS S*A5
9160 	fmul.x		%fp1,%fp3		# FP3 IS S*A4
9161 
9162 	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
9163 	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
9164 
9165 	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
9166 	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
9167 
9168 	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
9169 	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
9170 
9171 	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
9172 	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
9173 	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
9174 
9175 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
9176 
9177 #--FINAL RECONSTRUCTION PROCESS
9178 #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
9179 
9180 	fmul.x		FACT1(%a6),%fp0
9181 	fadd.x		FACT2(%a6),%fp0
9182 	fadd.x		FACT1(%a6),%fp0
9183 
9184 	fmov.l		%d0,%fpcr		# restore users round prec,mode
9185 	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
9186 	mov.l		(%sp)+,%d2
9187 	mov.l		&0x80000000,ADJFACT+4(%a6)
9188 	clr.l		ADJFACT+8(%a6)
9189 	mov.b		&FMUL_OP,%d1		# last inst is MUL
9190 	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
9191 	bra		t_catch
9192 
9193 	global		stentoxd
9194 stentoxd:
9195 #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
9196 
9197 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
9198 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
9199 	mov.l		(%a0),%d1
9200 	or.l		&0x00800001,%d1
9201 	fadd.s		%d1,%fp0
9202 	bra		t_pinx2
9203 
9204 #########################################################################
9205 # sscale(): computes the destination operand scaled by the source	#
9206 #	    operand. If the absoulute value of the source operand is	#
9207 #	    >= 2^14, an overflow or underflow is returned.		#
9208 #									#
9209 # INPUT *************************************************************** #
9210 #	a0  = pointer to double-extended source operand X		#
9211 #	a1  = pointer to double-extended destination operand Y		#
9212 #									#
9213 # OUTPUT ************************************************************** #
9214 #	fp0 =  scale(X,Y)						#
9215 #									#
9216 #########################################################################
9217 
9218 set	SIGN,		L_SCR1
9219 
9220 	global		sscale
9221 sscale:
9222 	mov.l		%d0,-(%sp)		# store off ctrl bits for now
9223 
9224 	mov.w		DST_EX(%a1),%d1		# get dst exponent
9225 	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
9226 	andi.l		&0x00007fff,%d1		# strip sign from dst exp
9227 
9228 	mov.w		SRC_EX(%a0),%d0		# check src bounds
9229 	andi.w		&0x7fff,%d0		# clr src sign bit
9230 	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
9231 	blt.w		src_small		# yes
9232 	cmpi.w		%d0,&0x400c		# no; is src too big?
9233 	bgt.w		src_out			# yes
9234 
9235 #
9236 # Source is within 2^14 range.
9237 #
9238 src_ok:
9239 	fintrz.x	SRC(%a0),%fp0		# calc int of src
9240 	fmov.l		%fp0,%d0		# int src to d0
9241 # don't want any accrued bits from the fintrz showing up later since
9242 # we may need to read the fpsr for the last fp op in t_catch2().
9243 	fmov.l		&0x0,%fpsr
9244 
9245 	tst.b		DST_HI(%a1)		# is dst denormalized?
9246 	bmi.b		sok_norm
9247 
9248 # the dst is a DENORM. normalize the DENORM and add the adjustment to
9249 # the src value. then, jump to the norm part of the routine.
9250 sok_dnrm:
9251 	mov.l		%d0,-(%sp)		# save src for now
9252 
9253 	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
9254 	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
9255 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
9256 
9257 	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
9258 	bsr.l		norm			# normalize the DENORM
9259 	neg.l		%d0
9260 	add.l		(%sp)+,%d0		# add adjustment to src
9261 
9262 	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
9263 
9264 	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
9265 	bge.b		sok_norm2		# thank goodness no
9266 
9267 # the multiply factor that we're trying to create should be a denorm
9268 # for the multiply to work. therefore, we're going to actually do a
9269 # multiply with a denorm which will cause an unimplemented data type
9270 # exception to be put into the machine which will be caught and corrected
9271 # later. we don't do this with the DENORMs above because this method
9272 # is slower. but, don't fret, I don't see it being used much either.
9273 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
9274 	mov.l		&0x80000000,%d1		# load normalized mantissa
9275 	subi.l		&-0x3fff,%d0		# how many should we shift?
9276 	neg.l		%d0			# make it positive
9277 	cmpi.b		%d0,&0x20		# is it > 32?
9278 	bge.b		sok_dnrm_32		# yes
9279 	lsr.l		%d0,%d1			# no; bit stays in upper lw
9280 	clr.l		-(%sp)			# insert zero low mantissa
9281 	mov.l		%d1,-(%sp)		# insert new high mantissa
9282 	clr.l		-(%sp)			# make zero exponent
9283 	bra.b		sok_norm_cont
9284 sok_dnrm_32:
9285 	subi.b		&0x20,%d0		# get shift count
9286 	lsr.l		%d0,%d1			# make low mantissa longword
9287 	mov.l		%d1,-(%sp)		# insert new low mantissa
9288 	clr.l		-(%sp)			# insert zero high mantissa
9289 	clr.l		-(%sp)			# make zero exponent
9290 	bra.b		sok_norm_cont
9291 
9292 # the src will force the dst to a DENORM value or worse. so, let's
9293 # create an fp multiply that will create the result.
9294 sok_norm:
9295 	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
9296 sok_norm2:
9297 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
9298 
9299 	addi.w		&0x3fff,%d0		# turn src amt into exp value
9300 	swap		%d0			# put exponent in high word
9301 	clr.l		-(%sp)			# insert new exponent
9302 	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
9303 	mov.l		%d0,-(%sp)		# insert new lo mantissa
9304 
9305 sok_norm_cont:
9306 	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
9307 	mov.b		&FMUL_OP,%d1		# last inst is MUL
9308 	fmul.x		(%sp)+,%fp0		# do the multiply
9309 	bra		t_catch2		# catch any exceptions
9310 
9311 #
9312 # Source is outside of 2^14 range.  Test the sign and branch
9313 # to the appropriate exception handler.
9314 #
9315 src_out:
9316 	mov.l		(%sp)+,%d0		# restore ctrl bits
9317 	exg		%a0,%a1			# swap src,dst ptrs
9318 	tst.b		SRC_EX(%a1)		# is src negative?
9319 	bmi		t_unfl			# yes; underflow
9320 	bra		t_ovfl_sc		# no; overflow
9321 
9322 #
9323 # The source input is below 1, so we check for denormalized numbers
9324 # and set unfl.
9325 #
9326 src_small:
9327 	tst.b		DST_HI(%a1)		# is dst denormalized?
9328 	bpl.b		ssmall_done		# yes
9329 
9330 	mov.l		(%sp)+,%d0
9331 	fmov.l		%d0,%fpcr		# no; load control bits
9332 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
9333 	fmov.x		DST(%a1),%fp0		# simply return dest
9334 	bra		t_catch2
9335 ssmall_done:
9336 	mov.l		(%sp)+,%d0		# load control bits into d1
9337 	mov.l		%a1,%a0			# pass ptr to dst
9338 	bra		t_resdnrm
9339 
9340 #########################################################################
9341 # smod(): computes the fp MOD of the input values X,Y.			#
9342 # srem(): computes the fp (IEEE) REM of the input values X,Y.		#
9343 #									#
9344 # INPUT *************************************************************** #
9345 #	a0 = pointer to extended precision input X			#
9346 #	a1 = pointer to extended precision input Y			#
9347 #	d0 = round precision,mode					#
9348 #									#
9349 #	The input operands X and Y can be either normalized or		#
9350 #	denormalized.							#
9351 #									#
9352 # OUTPUT ************************************************************** #
9353 #      fp0 = FREM(X,Y) or FMOD(X,Y)					#
9354 #									#
9355 # ALGORITHM *********************************************************** #
9356 #									#
9357 #       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
9358 #                signY := sign(Y), X := |X|, Y := |Y|,			#
9359 #                signQ := signX EOR signY. Record whether MOD or REM	#
9360 #                is requested.						#
9361 #									#
9362 #       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
9363 #                If (L < 0) then					#
9364 #                   R := X, go to Step 4.				#
9365 #                else							#
9366 #                   R := 2^(-L)X, j := L.				#
9367 #                endif							#
9368 #									#
9369 #       Step 3.  Perform MOD(X,Y)					#
9370 #            3.1 If R = Y, go to Step 9.				#
9371 #            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
9372 #            3.3 If j = 0, go to Step 4.				#
9373 #            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
9374 #                Step 3.1.						#
9375 #									#
9376 #       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
9377 #                Last_Subtract := false (used in Step 7 below). If	#
9378 #                MOD is requested, go to Step 6.			#
9379 #									#
9380 #       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
9381 #            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
9382 #                Step 6.						#
9383 #            5.2 If R > Y/2, then { set Last_Subtract := true,		#
9384 #                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
9385 #            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
9386 #                then { Q := Q + 1, signX := -signX }.			#
9387 #									#
9388 #       Step 6.  R := signX*R.						#
9389 #									#
9390 #       Step 7.  If Last_Subtract = true, R := R - Y.			#
9391 #									#
9392 #       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
9393 #									#
9394 #       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
9395 #                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
9396 #                R := 0. Return signQ, last 7 bits of Q, and R.		#
9397 #									#
9398 #########################################################################
9399 
9400 	set		Mod_Flag,L_SCR3
9401 	set		Sc_Flag,L_SCR3+1
9402 
9403 	set		SignY,L_SCR2
9404 	set		SignX,L_SCR2+2
9405 	set		SignQ,L_SCR3+2
9406 
9407 	set		Y,FP_SCR0
9408 	set		Y_Hi,Y+4
9409 	set		Y_Lo,Y+8
9410 
9411 	set		R,FP_SCR1
9412 	set		R_Hi,R+4
9413 	set		R_Lo,R+8
9414 
9415 Scale:
9416 	long		0x00010000,0x80000000,0x00000000,0x00000000
9417 
9418 	global		smod
9419 smod:
9420 	clr.b		FPSR_QBYTE(%a6)
9421 	mov.l		%d0,-(%sp)		# save ctrl bits
9422 	clr.b		Mod_Flag(%a6)
9423 	bra.b		Mod_Rem
9424 
9425 	global		srem
9426 srem:
9427 	clr.b		FPSR_QBYTE(%a6)
9428 	mov.l		%d0,-(%sp)		# save ctrl bits
9429 	mov.b		&0x1,Mod_Flag(%a6)
9430 
9431 Mod_Rem:
9432 #..Save sign of X and Y
9433 	movm.l		&0x3f00,-(%sp)		# save data registers
9434 	mov.w		SRC_EX(%a0),%d3
9435 	mov.w		%d3,SignY(%a6)
9436 	and.l		&0x00007FFF,%d3		# Y := |Y|
9437 
9438 #
9439 	mov.l		SRC_HI(%a0),%d4
9440 	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
9441 
9442 	tst.l		%d3
9443 	bne.b		Y_Normal
9444 
9445 	mov.l		&0x00003FFE,%d3		# $3FFD + 1
9446 	tst.l		%d4
9447 	bne.b		HiY_not0
9448 
9449 HiY_0:
9450 	mov.l		%d5,%d4
9451 	clr.l		%d5
9452 	sub.l		&32,%d3
9453 	clr.l		%d6
9454 	bfffo		%d4{&0:&32},%d6
9455 	lsl.l		%d6,%d4
9456 	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
9457 #	                                        ...with bias $7FFD
9458 	bra.b		Chk_X
9459 
9460 HiY_not0:
9461 	clr.l		%d6
9462 	bfffo		%d4{&0:&32},%d6
9463 	sub.l		%d6,%d3
9464 	lsl.l		%d6,%d4
9465 	mov.l		%d5,%d7			# a copy of D5
9466 	lsl.l		%d6,%d5
9467 	neg.l		%d6
9468 	add.l		&32,%d6
9469 	lsr.l		%d6,%d7
9470 	or.l		%d7,%d4			# (D3,D4,D5) normalized
9471 #                                       ...with bias $7FFD
9472 	bra.b		Chk_X
9473 
9474 Y_Normal:
9475 	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
9476 #                                       ...with bias $7FFD
9477 
9478 Chk_X:
9479 	mov.w		DST_EX(%a1),%d0
9480 	mov.w		%d0,SignX(%a6)
9481 	mov.w		SignY(%a6),%d1
9482 	eor.l		%d0,%d1
9483 	and.l		&0x00008000,%d1
9484 	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
9485 	and.l		&0x00007FFF,%d0
9486 	mov.l		DST_HI(%a1),%d1
9487 	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
9488 	tst.l		%d0
9489 	bne.b		X_Normal
9490 	mov.l		&0x00003FFE,%d0
9491 	tst.l		%d1
9492 	bne.b		HiX_not0
9493 
9494 HiX_0:
9495 	mov.l		%d2,%d1
9496 	clr.l		%d2
9497 	sub.l		&32,%d0
9498 	clr.l		%d6
9499 	bfffo		%d1{&0:&32},%d6
9500 	lsl.l		%d6,%d1
9501 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
9502 #                                       ...with bias $7FFD
9503 	bra.b		Init
9504 
9505 HiX_not0:
9506 	clr.l		%d6
9507 	bfffo		%d1{&0:&32},%d6
9508 	sub.l		%d6,%d0
9509 	lsl.l		%d6,%d1
9510 	mov.l		%d2,%d7			# a copy of D2
9511 	lsl.l		%d6,%d2
9512 	neg.l		%d6
9513 	add.l		&32,%d6
9514 	lsr.l		%d6,%d7
9515 	or.l		%d7,%d1			# (D0,D1,D2) normalized
9516 #                                       ...with bias $7FFD
9517 	bra.b		Init
9518 
9519 X_Normal:
9520 	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
9521 #                                       ...with bias $7FFD
9522 
9523 Init:
9524 #
9525 	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
9526 	mov.l		%d0,-(%sp)		# save biased exp(X)
9527 	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
9528 
9529 	clr.l		%d6			# D6 := carry <- 0
9530 	clr.l		%d3			# D3 is Q
9531 	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
9532 
9533 #..(Carry,D1,D2) is R
9534 	tst.l		%d0
9535 	bge.b		Mod_Loop_pre
9536 
9537 #..expo(X) < expo(Y). Thus X = mod(X,Y)
9538 #
9539 	mov.l		(%sp)+,%d0		# restore d0
9540 	bra.w		Get_Mod
9541 
9542 Mod_Loop_pre:
9543 	addq.l		&0x4,%sp		# erase exp(X)
9544 #..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
9545 Mod_Loop:
9546 	tst.l		%d6			# test carry bit
9547 	bgt.b		R_GT_Y
9548 
9549 #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
9550 	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
9551 	bne.b		R_NE_Y
9552 	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
9553 	bne.b		R_NE_Y
9554 
9555 #..At this point, R = Y
9556 	bra.w		Rem_is_0
9557 
9558 R_NE_Y:
9559 #..use the borrow of the previous compare
9560 	bcs.b		R_LT_Y			# borrow is set iff R < Y
9561 
9562 R_GT_Y:
9563 #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
9564 #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
9565 	sub.l		%d5,%d2			# lo(R) - lo(Y)
9566 	subx.l		%d4,%d1			# hi(R) - hi(Y)
9567 	clr.l		%d6			# clear carry
9568 	addq.l		&1,%d3			# Q := Q + 1
9569 
9570 R_LT_Y:
9571 #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
9572 	tst.l		%d0			# see if j = 0.
9573 	beq.b		PostLoop
9574 
9575 	add.l		%d3,%d3			# Q := 2Q
9576 	add.l		%d2,%d2			# lo(R) = 2lo(R)
9577 	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
9578 	scs		%d6			# set Carry if 2(R) overflows
9579 	addq.l		&1,%a1			# k := k+1
9580 	subq.l		&1,%d0			# j := j - 1
9581 #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
9582 
9583 	bra.b		Mod_Loop
9584 
9585 PostLoop:
9586 #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
9587 
9588 #..normalize R.
9589 	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
9590 	tst.l		%d1
9591 	bne.b		HiR_not0
9592 
9593 HiR_0:
9594 	mov.l		%d2,%d1
9595 	clr.l		%d2
9596 	sub.l		&32,%d0
9597 	clr.l		%d6
9598 	bfffo		%d1{&0:&32},%d6
9599 	lsl.l		%d6,%d1
9600 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
9601 #                                       ...with bias $7FFD
9602 	bra.b		Get_Mod
9603 
9604 HiR_not0:
9605 	clr.l		%d6
9606 	bfffo		%d1{&0:&32},%d6
9607 	bmi.b		Get_Mod			# already normalized
9608 	sub.l		%d6,%d0
9609 	lsl.l		%d6,%d1
9610 	mov.l		%d2,%d7			# a copy of D2
9611 	lsl.l		%d6,%d2
9612 	neg.l		%d6
9613 	add.l		&32,%d6
9614 	lsr.l		%d6,%d7
9615 	or.l		%d7,%d1			# (D0,D1,D2) normalized
9616 
9617 #
9618 Get_Mod:
9619 	cmp.l		%d0,&0x000041FE
9620 	bge.b		No_Scale
9621 Do_Scale:
9622 	mov.w		%d0,R(%a6)
9623 	mov.l		%d1,R_Hi(%a6)
9624 	mov.l		%d2,R_Lo(%a6)
9625 	mov.l		L_SCR1(%a6),%d6
9626 	mov.w		%d6,Y(%a6)
9627 	mov.l		%d4,Y_Hi(%a6)
9628 	mov.l		%d5,Y_Lo(%a6)
9629 	fmov.x		R(%a6),%fp0		# no exception
9630 	mov.b		&1,Sc_Flag(%a6)
9631 	bra.b		ModOrRem
9632 No_Scale:
9633 	mov.l		%d1,R_Hi(%a6)
9634 	mov.l		%d2,R_Lo(%a6)
9635 	sub.l		&0x3FFE,%d0
9636 	mov.w		%d0,R(%a6)
9637 	mov.l		L_SCR1(%a6),%d6
9638 	sub.l		&0x3FFE,%d6
9639 	mov.l		%d6,L_SCR1(%a6)
9640 	fmov.x		R(%a6),%fp0
9641 	mov.w		%d6,Y(%a6)
9642 	mov.l		%d4,Y_Hi(%a6)
9643 	mov.l		%d5,Y_Lo(%a6)
9644 	clr.b		Sc_Flag(%a6)
9645 
9646 #
9647 ModOrRem:
9648 	tst.b		Mod_Flag(%a6)
9649 	beq.b		Fix_Sign
9650 
9651 	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
9652 	subq.l		&1,%d6			# biased expo(Y/2)
9653 	cmp.l		%d0,%d6
9654 	blt.b		Fix_Sign
9655 	bgt.b		Last_Sub
9656 
9657 	cmp.l		%d1,%d4
9658 	bne.b		Not_EQ
9659 	cmp.l		%d2,%d5
9660 	bne.b		Not_EQ
9661 	bra.w		Tie_Case
9662 
9663 Not_EQ:
9664 	bcs.b		Fix_Sign
9665 
9666 Last_Sub:
9667 #
9668 	fsub.x		Y(%a6),%fp0		# no exceptions
9669 	addq.l		&1,%d3			# Q := Q + 1
9670 
9671 #
9672 Fix_Sign:
9673 #..Get sign of X
9674 	mov.w		SignX(%a6),%d6
9675 	bge.b		Get_Q
9676 	fneg.x		%fp0
9677 
9678 #..Get Q
9679 #
9680 Get_Q:
9681 	clr.l		%d6
9682 	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
9683 	mov.l		&8,%d7
9684 	lsr.l		%d7,%d6
9685 	and.l		&0x0000007F,%d3		# 7 bits of Q
9686 	or.l		%d6,%d3			# sign and bits of Q
9687 #	swap		%d3
9688 #	fmov.l		%fpsr,%d6
9689 #	and.l		&0xFF00FFFF,%d6
9690 #	or.l		%d3,%d6
9691 #	fmov.l		%d6,%fpsr		# put Q in fpsr
9692 	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
9693 
9694 #
9695 Restore:
9696 	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
9697 	mov.l		(%sp)+,%d0
9698 	fmov.l		%d0,%fpcr
9699 	tst.b		Sc_Flag(%a6)
9700 	beq.b		Finish
9701 	mov.b		&FMUL_OP,%d1		# last inst is MUL
9702 	fmul.x		Scale(%pc),%fp0		# may cause underflow
9703 	bra		t_catch2
9704 # the '040 package did this apparently to see if the dst operand for the
9705 # preceding fmul was a denorm. but, it better not have been since the
9706 # algorithm just got done playing with fp0 and expected no exceptions
9707 # as a result. trust me...
9708 #	bra		t_avoid_unsupp		# check for denorm as a
9709 #						;result of the scaling
9710 
9711 Finish:
9712 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
9713 	fmov.x		%fp0,%fp0		# capture exceptions & round
9714 	bra		t_catch2
9715 
9716 Rem_is_0:
9717 #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
9718 	addq.l		&1,%d3
9719 	cmp.l		%d0,&8			# D0 is j
9720 	bge.b		Q_Big
9721 
9722 	lsl.l		%d0,%d3
9723 	bra.b		Set_R_0
9724 
9725 Q_Big:
9726 	clr.l		%d3
9727 
9728 Set_R_0:
9729 	fmov.s		&0x00000000,%fp0
9730 	clr.b		Sc_Flag(%a6)
9731 	bra.w		Fix_Sign
9732 
9733 Tie_Case:
9734 #..Check parity of Q
9735 	mov.l		%d3,%d6
9736 	and.l		&0x00000001,%d6
9737 	tst.l		%d6
9738 	beq.w		Fix_Sign		# Q is even
9739 
9740 #..Q is odd, Q := Q + 1, signX := -signX
9741 	addq.l		&1,%d3
9742 	mov.w		SignX(%a6),%d6
9743 	eor.l		&0x00008000,%d6
9744 	mov.w		%d6,SignX(%a6)
9745 	bra.w		Fix_Sign
9746 
9747 #########################################################################
9748 # XDEF ****************************************************************	#
9749 #	tag(): return the optype of the input ext fp number		#
9750 #									#
9751 #	This routine is used by the 060FPLSP.				#
9752 #									#
9753 # XREF ****************************************************************	#
9754 #	None								#
9755 #									#
9756 # INPUT ***************************************************************	#
9757 #	a0 = pointer to extended precision operand			#
9758 #									#
9759 # OUTPUT **************************************************************	#
9760 #	d0 = value of type tag						#
9761 #		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
9762 #									#
9763 # ALGORITHM ***********************************************************	#
9764 #	Simply test the exponent, j-bit, and mantissa values to		#
9765 # determine the type of operand.					#
9766 #	If it's an unnormalized zero, alter the operand and force it	#
9767 # to be a normal zero.							#
9768 #									#
9769 #########################################################################
9770 
9771 	global		tag
9772 tag:
9773 	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
9774 	andi.w		&0x7fff, %d0		# strip off sign
9775 	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
9776 	beq.b		inf_or_nan_x
9777 not_inf_or_nan_x:
9778 	btst		&0x7,FTEMP_HI(%a0)
9779 	beq.b		not_norm_x
9780 is_norm_x:
9781 	mov.b		&NORM, %d0
9782 	rts
9783 not_norm_x:
9784 	tst.w		%d0			# is exponent = 0?
9785 	bne.b		is_unnorm_x
9786 not_unnorm_x:
9787 	tst.l		FTEMP_HI(%a0)
9788 	bne.b		is_denorm_x
9789 	tst.l		FTEMP_LO(%a0)
9790 	bne.b		is_denorm_x
9791 is_zero_x:
9792 	mov.b		&ZERO, %d0
9793 	rts
9794 is_denorm_x:
9795 	mov.b		&DENORM, %d0
9796 	rts
9797 is_unnorm_x:
9798 	bsr.l		unnorm_fix		# convert to norm,denorm,or zero
9799 	rts
9800 is_unnorm_reg_x:
9801 	mov.b		&UNNORM, %d0
9802 	rts
9803 inf_or_nan_x:
9804 	tst.l		FTEMP_LO(%a0)
9805 	bne.b		is_nan_x
9806 	mov.l		FTEMP_HI(%a0), %d0
9807 	and.l		&0x7fffffff, %d0	# msb is a don't care!
9808 	bne.b		is_nan_x
9809 is_inf_x:
9810 	mov.b		&INF, %d0
9811 	rts
9812 is_nan_x:
9813 	mov.b		&QNAN, %d0
9814 	rts
9815 
9816 #############################################################
9817 
9818 qnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
9819 
9820 #########################################################################
9821 # XDEF ****************************************************************	#
9822 #	t_dz(): Handle 060FPLSP dz exception for "flogn" emulation.	#
9823 #	t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation.	#
9824 #									#
9825 #	These rouitnes are used by the 060FPLSP package.		#
9826 #									#
9827 # XREF ****************************************************************	#
9828 #	None								#
9829 #									#
9830 # INPUT ***************************************************************	#
9831 #	a0 = pointer to extended precision source operand.		#
9832 #									#
9833 # OUTPUT **************************************************************	#
9834 #	fp0 = default DZ result.					#
9835 #									#
9836 # ALGORITHM ***********************************************************	#
9837 #	Transcendental emulation for the 060FPLSP has detected that	#
9838 # a DZ exception should occur for the instruction. If DZ is disabled,	#
9839 # return the default result.						#
9840 #	If DZ is enabled, the dst operand should be returned unscathed	#
9841 # in fp0 while fp1 is used to create a DZ exception so that the		#
9842 # operating system can log that such an event occurred.			#
9843 #									#
9844 #########################################################################
9845 
9846 	global		t_dz
9847 t_dz:
9848 	tst.b		SRC_EX(%a0)		# check sign for neg or pos
9849 	bpl.b		dz_pinf			# branch if pos sign
9850 
9851 	global		t_dz2
9852 t_dz2:
9853 	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
9854 
9855 	btst		&dz_bit,FPCR_ENABLE(%a6)
9856 	bne.b		dz_minf_ena
9857 
9858 # dz is disabled. return a -INF.
9859 	fmov.s		&0xff800000,%fp0	# return -INF
9860 	rts
9861 
9862 # dz is enabled. create a dz exception so the user can record it
9863 # but use fp1 instead. return the dst operand unscathed in fp0.
9864 dz_minf_ena:
9865 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
9866 	fmov.l		USER_FPCR(%a6),%fpcr
9867 	fmov.s		&0xbf800000,%fp1	# load -1
9868 	fdiv.s		&0x00000000,%fp1	# -1 / 0
9869 	rts
9870 
9871 dz_pinf:
9872 	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
9873 
9874 	btst		&dz_bit,FPCR_ENABLE(%a6)
9875 	bne.b		dz_pinf_ena
9876 
9877 # dz is disabled. return a +INF.
9878 	fmov.s		&0x7f800000,%fp0	# return +INF
9879 	rts
9880 
9881 # dz is enabled. create a dz exception so the user can record it
9882 # but use fp1 instead. return the dst operand unscathed in fp0.
9883 dz_pinf_ena:
9884 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
9885 	fmov.l		USER_FPCR(%a6),%fpcr
9886 	fmov.s		&0x3f800000,%fp1	# load +1
9887 	fdiv.s		&0x00000000,%fp1	# +1 / 0
9888 	rts
9889 
9890 #########################################################################
9891 # XDEF ****************************************************************	#
9892 #	t_operr(): Handle 060FPLSP OPERR exception during emulation.	#
9893 #									#
9894 #	This routine is used by the 060FPLSP package.			#
9895 #									#
9896 # XREF ****************************************************************	#
9897 #	None.								#
9898 #									#
9899 # INPUT ***************************************************************	#
9900 #	fp1 = source operand						#
9901 #									#
9902 # OUTPUT **************************************************************	#
9903 #	fp0 = default result						#
9904 #	fp1 = unchanged							#
9905 #									#
9906 # ALGORITHM ***********************************************************	#
9907 #	An operand error should occur as the result of transcendental	#
9908 # emulation in the 060FPLSP. If OPERR is disabled, just return a NAN	#
9909 # in fp0. If OPERR is enabled, return the dst operand unscathed in fp0	#
9910 # and the source operand in fp1. Use fp2 to create an OPERR exception	#
9911 # so that the operating system can log the event.			#
9912 #									#
9913 #########################################################################
9914 
9915 	global		t_operr
9916 t_operr:
9917 	ori.l		&opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
9918 
9919 	btst		&operr_bit,FPCR_ENABLE(%a6)
9920 	bne.b		operr_ena
9921 
9922 # operr is disabled. return a QNAN in fp0
9923 	fmovm.x		qnan(%pc),&0x80		# return QNAN
9924 	rts
9925 
9926 # operr is enabled. create an operr exception so the user can record it
9927 # but use fp2 instead. return the dst operand unscathed in fp0.
9928 operr_ena:
9929 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
9930 	fmov.l		USER_FPCR(%a6),%fpcr
9931 	fmovm.x		&0x04,-(%sp)		# save fp2
9932 	fmov.s		&0x7f800000,%fp2	# load +INF
9933 	fmul.s		&0x00000000,%fp2	# +INF x 0
9934 	fmovm.x		(%sp)+,&0x20		# restore fp2
9935 	rts
9936 
9937 pls_huge:
9938 	long		0x7ffe0000,0xffffffff,0xffffffff
9939 mns_huge:
9940 	long		0xfffe0000,0xffffffff,0xffffffff
9941 pls_tiny:
9942 	long		0x00000000,0x80000000,0x00000000
9943 mns_tiny:
9944 	long		0x80000000,0x80000000,0x00000000
9945 
9946 #########################################################################
9947 # XDEF ****************************************************************	#
9948 #	t_unfl(): Handle 060FPLSP underflow exception during emulation.	#
9949 #	t_unfl2(): Handle 060FPLSP underflow exception during		#
9950 #	           emulation. result always positive.			#
9951 #									#
9952 #	This routine is used by the 060FPLSP package.			#
9953 #									#
9954 # XREF ****************************************************************	#
9955 #	None.								#
9956 #									#
9957 # INPUT ***************************************************************	#
9958 #	a0 = pointer to extended precision source operand		#
9959 #									#
9960 # OUTPUT **************************************************************	#
9961 #	fp0 = default underflow result					#
9962 #									#
9963 # ALGORITHM ***********************************************************	#
9964 #	An underflow should occur as the result of transcendental	#
9965 # emulation in the 060FPLSP. Create an underflow by using "fmul"	#
9966 # and two very small numbers of appropriate sign so the operating	#
9967 # system can log the event.						#
9968 #									#
9969 #########################################################################
9970 
9971 	global		t_unfl
9972 t_unfl:
9973 	tst.b		SRC_EX(%a0)
9974 	bpl.b		unf_pos
9975 
9976 	global		t_unfl2
9977 t_unfl2:
9978 	ori.l		&unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
9979 
9980 	fmov.l		USER_FPCR(%a6),%fpcr
9981 	fmovm.x		mns_tiny(%pc),&0x80
9982 	fmul.x		pls_tiny(%pc),%fp0
9983 
9984 	fmov.l		%fpsr,%d0
9985 	rol.l		&0x8,%d0
9986 	mov.b		%d0,FPSR_CC(%a6)
9987 	rts
9988 unf_pos:
9989 	ori.w		&unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
9990 
9991 	fmov.l		USER_FPCR(%a6),%fpcr
9992 	fmovm.x		pls_tiny(%pc),&0x80
9993 	fmul.x		%fp0,%fp0
9994 
9995 	fmov.l		%fpsr,%d0
9996 	rol.l		&0x8,%d0
9997 	mov.b		%d0,FPSR_CC(%a6)
9998 	rts
9999 
10000 #########################################################################
10001 # XDEF ****************************************************************	#
10002 #	t_ovfl(): Handle 060FPLSP overflow exception during emulation.	#
10003 #		  (monadic)						#
10004 #	t_ovfl2(): Handle 060FPLSP overflow exception during		#
10005 #	           emulation. result always positive. (dyadic)		#
10006 #	t_ovfl_sc(): Handle 060FPLSP overflow exception during		#
10007 #	             emulation for "fscale".				#
10008 #									#
10009 #	This routine is used by the 060FPLSP package.			#
10010 #									#
10011 # XREF ****************************************************************	#
10012 #	None.								#
10013 #									#
10014 # INPUT ***************************************************************	#
10015 #	a0 = pointer to extended precision source operand		#
10016 #									#
10017 # OUTPUT **************************************************************	#
10018 #	fp0 = default underflow result					#
10019 #									#
10020 # ALGORITHM ***********************************************************	#
10021 #	An overflow should occur as the result of transcendental	#
10022 # emulation in the 060FPLSP. Create an overflow by using "fmul"		#
10023 # and two very lareg numbers of appropriate sign so the operating	#
10024 # system can log the event.						#
10025 #	For t_ovfl_sc() we take special care not to lose the INEX2 bit.	#
10026 #									#
10027 #########################################################################
10028 
10029 	global		t_ovfl_sc
10030 t_ovfl_sc:
10031 	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
10032 
10033 	mov.b		%d0,%d1			# fetch rnd prec,mode
10034 	andi.b		&0xc0,%d1		# extract prec
10035 	beq.w		ovfl_work
10036 
10037 # dst op is a DENORM. we have to normalize the mantissa to see if the
10038 # result would be inexact for the given precision. make a copy of the
10039 # dst so we don't screw up the version passed to us.
10040 	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
10041 	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
10042 	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
10043 	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
10044 	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
10045 	bsr.l		norm			# normalize mantissa
10046 	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
10047 
10048 	cmpi.b		%d1,&0x40		# is precision sgl?
10049 	bne.b		ovfl_sc_dbl		# no; dbl
10050 ovfl_sc_sgl:
10051 	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
10052 	bne.b		ovfl_sc_inx		# yes
10053 	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
10054 	bne.b		ovfl_sc_inx		# yes
10055 	bra.w		ovfl_work		# don't set INEX2
10056 ovfl_sc_dbl:
10057 	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
10058 	andi.l		&0x7ff,%d1		# dbl mantissa set?
10059 	beq.w		ovfl_work		# no; don't set INEX2
10060 ovfl_sc_inx:
10061 	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
10062 	bra.b		ovfl_work		# continue
10063 
10064 	global		t_ovfl
10065 t_ovfl:
10066 	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
10067 ovfl_work:
10068 	tst.b		SRC_EX(%a0)
10069 	bpl.b		ovfl_p
10070 ovfl_m:
10071 	fmov.l		USER_FPCR(%a6),%fpcr
10072 	fmovm.x		mns_huge(%pc),&0x80
10073 	fmul.x		pls_huge(%pc),%fp0
10074 
10075 	fmov.l		%fpsr,%d0
10076 	rol.l		&0x8,%d0
10077 	ori.b		&neg_mask,%d0
10078 	mov.b		%d0,FPSR_CC(%a6)
10079 	rts
10080 ovfl_p:
10081 	fmov.l		USER_FPCR(%a6),%fpcr
10082 	fmovm.x		pls_huge(%pc),&0x80
10083 	fmul.x		pls_huge(%pc),%fp0
10084 
10085 	fmov.l		%fpsr,%d0
10086 	rol.l		&0x8,%d0
10087 	mov.b		%d0,FPSR_CC(%a6)
10088 	rts
10089 
10090 	global		t_ovfl2
10091 t_ovfl2:
10092 	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
10093 	fmov.l		USER_FPCR(%a6),%fpcr
10094 	fmovm.x		pls_huge(%pc),&0x80
10095 	fmul.x		pls_huge(%pc),%fp0
10096 
10097 	fmov.l		%fpsr,%d0
10098 	rol.l		&0x8,%d0
10099 	mov.b		%d0,FPSR_CC(%a6)
10100 	rts
10101 
10102 #########################################################################
10103 # XDEF ****************************************************************	#
10104 #	t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
10105 #		   emulation.						#
10106 #	t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
10107 #		    emulation.						#
10108 #									#
10109 #	These routines are used by the 060FPLSP package.		#
10110 #									#
10111 # XREF ****************************************************************	#
10112 #	None.								#
10113 #									#
10114 # INPUT ***************************************************************	#
10115 #	fp0 = default underflow or overflow result			#
10116 #									#
10117 # OUTPUT **************************************************************	#
10118 #	fp0 = default result						#
10119 #									#
10120 # ALGORITHM ***********************************************************	#
10121 #	If an overflow or underflow occurred during the last		#
10122 # instruction of transcendental 060FPLSP emulation, then it has already	#
10123 # occurred and has been logged. Now we need to see if an inexact	#
10124 # exception should occur.						#
10125 #									#
10126 #########################################################################
10127 
10128 	global		t_catch2
10129 t_catch2:
10130 	fmov.l		%fpsr,%d0
10131 	or.l		%d0,USER_FPSR(%a6)
10132 	bra.b		inx2_work
10133 
10134 	global		t_catch
10135 t_catch:
10136 	fmov.l		%fpsr,%d0
10137 	or.l		%d0,USER_FPSR(%a6)
10138 
10139 #########################################################################
10140 # XDEF ****************************************************************	#
10141 #	t_inx2(): Handle inexact 060FPLSP exception during emulation.	#
10142 #	t_pinx2(): Handle inexact 060FPLSP exception for "+" results.	#
10143 #	t_minx2(): Handle inexact 060FPLSP exception for "-" results.	#
10144 #									#
10145 # XREF ****************************************************************	#
10146 #	None.								#
10147 #									#
10148 # INPUT ***************************************************************	#
10149 #	fp0 = default result						#
10150 #									#
10151 # OUTPUT **************************************************************	#
10152 #	fp0 = default result						#
10153 #									#
10154 # ALGORITHM ***********************************************************	#
10155 #	The last instruction of transcendental emulation for the	#
10156 # 060FPLSP should be inexact. So, if inexact is enabled, then we create	#
10157 # the event here by adding a large and very small number together	#
10158 # so that the operating system can log the event.			#
10159 #	Must check, too, if the result was zero, in which case we just	#
10160 # set the FPSR bits and return.						#
10161 #									#
10162 #########################################################################
10163 
10164 	global		t_inx2
10165 t_inx2:
10166 	fblt.w		t_minx2
10167 	fbeq.w		inx2_zero
10168 
10169 	global		t_pinx2
10170 t_pinx2:
10171 	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
10172 	bra.b		inx2_work
10173 
10174 	global		t_minx2
10175 t_minx2:
10176 	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6)
10177 
10178 inx2_work:
10179 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
10180 	bne.b		inx2_work_ena		# yes
10181 	rts
10182 inx2_work_ena:
10183 	fmov.l		USER_FPCR(%a6),%fpcr	# insert user's exceptions
10184 	fmov.s		&0x3f800000,%fp1	# load +1
10185 	fadd.x		pls_tiny(%pc),%fp1	# cause exception
10186 	rts
10187 
10188 inx2_zero:
10189 	mov.b		&z_bmask,FPSR_CC(%a6)
10190 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
10191 	rts
10192 
10193 #########################################################################
10194 # XDEF ****************************************************************	#
10195 #	t_extdnrm(): Handle DENORM inputs in 060FPLSP.			#
10196 #	t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale".	#
10197 #									#
10198 #	This routine is used by the 060FPLSP package.			#
10199 #									#
10200 # XREF ****************************************************************	#
10201 #	None.								#
10202 #									#
10203 # INPUT ***************************************************************	#
10204 #	a0 = pointer to extended precision input operand		#
10205 #									#
10206 # OUTPUT **************************************************************	#
10207 #	fp0 = default result						#
10208 #									#
10209 # ALGORITHM ***********************************************************	#
10210 #	For all functions that have a denormalized input and that	#
10211 # f(x)=x, this is the entry point.					#
10212 #	DENORM value is moved using "fmove" which triggers an exception	#
10213 # if enabled so the operating system can log the event.			#
10214 #									#
10215 #########################################################################
10216 
10217 	global		t_extdnrm
10218 t_extdnrm:
10219 	fmov.l		USER_FPCR(%a6),%fpcr
10220 	fmov.x		SRC_EX(%a0),%fp0
10221 	fmov.l		%fpsr,%d0
10222 	ori.l		&unfinx_mask,%d0
10223 	or.l		%d0,USER_FPSR(%a6)
10224 	rts
10225 
10226 	global		t_resdnrm
10227 t_resdnrm:
10228 	fmov.l		USER_FPCR(%a6),%fpcr
10229 	fmov.x		SRC_EX(%a0),%fp0
10230 	fmov.l		%fpsr,%d0
10231 	or.l		%d0,USER_FPSR(%a6)
10232 	rts
10233 
10234 ##########################################
10235 
10236 #
10237 # sto_cos:
10238 #	This is used by fsincos library emulation. The correct
10239 # values are already in fp0 and fp1 so we do nothing here.
10240 #
10241 	global		sto_cos
10242 sto_cos:
10243 	rts
10244 
10245 ##########################################
10246 
10247 #
10248 #	dst_qnan --- force result when destination is a NaN
10249 #
10250 	global		dst_qnan
10251 dst_qnan:
10252 	fmov.x		DST(%a1),%fp0
10253 	tst.b		DST_EX(%a1)
10254 	bmi.b		dst_qnan_m
10255 dst_qnan_p:
10256 	mov.b		&nan_bmask,FPSR_CC(%a6)
10257 	rts
10258 dst_qnan_m:
10259 	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
10260 	rts
10261 
10262 #
10263 #	src_qnan --- force result when source is a NaN
10264 #
10265 	global		src_qnan
10266 src_qnan:
10267 	fmov.x		SRC(%a0),%fp0
10268 	tst.b		SRC_EX(%a0)
10269 	bmi.b		src_qnan_m
10270 src_qnan_p:
10271 	mov.b		&nan_bmask,FPSR_CC(%a6)
10272 	rts
10273 src_qnan_m:
10274 	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
10275 	rts
10276 
10277 ##########################################
10278 
10279 #
10280 #	Native instruction support
10281 #
10282 #	Some systems may need entry points even for 68060 native
10283 #	instructions.  These routines are provided for
10284 #	convenience.
10285 #
10286 	global		_fadds_
10287 _fadds_:
10288 	fmov.l		%fpcr,-(%sp)		# save fpcr
10289 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10290 	fmov.s		0x8(%sp),%fp0		# load sgl dst
10291 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10292 	fadd.s		0x8(%sp),%fp0		# fadd w/ sgl src
10293 	rts
10294 
10295 	global		_faddd_
10296 _faddd_:
10297 	fmov.l		%fpcr,-(%sp)		# save fpcr
10298 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10299 	fmov.d		0x8(%sp),%fp0		# load dbl dst
10300 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10301 	fadd.d		0xc(%sp),%fp0		# fadd w/ dbl src
10302 	rts
10303 
10304 	global		_faddx_
10305 _faddx_:
10306 	fmovm.x		0x4(%sp),&0x80		# load ext dst
10307 	fadd.x		0x10(%sp),%fp0		# fadd w/ ext src
10308 	rts
10309 
10310 	global		_fsubs_
10311 _fsubs_:
10312 	fmov.l		%fpcr,-(%sp)		# save fpcr
10313 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10314 	fmov.s		0x8(%sp),%fp0		# load sgl dst
10315 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10316 	fsub.s		0x8(%sp),%fp0		# fsub w/ sgl src
10317 	rts
10318 
10319 	global		_fsubd_
10320 _fsubd_:
10321 	fmov.l		%fpcr,-(%sp)		# save fpcr
10322 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10323 	fmov.d		0x8(%sp),%fp0		# load dbl dst
10324 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10325 	fsub.d		0xc(%sp),%fp0		# fsub w/ dbl src
10326 	rts
10327 
10328 	global		_fsubx_
10329 _fsubx_:
10330 	fmovm.x		0x4(%sp),&0x80		# load ext dst
10331 	fsub.x		0x10(%sp),%fp0		# fsub w/ ext src
10332 	rts
10333 
10334 	global		_fmuls_
10335 _fmuls_:
10336 	fmov.l		%fpcr,-(%sp)		# save fpcr
10337 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10338 	fmov.s		0x8(%sp),%fp0		# load sgl dst
10339 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10340 	fmul.s		0x8(%sp),%fp0		# fmul w/ sgl src
10341 	rts
10342 
10343 	global		_fmuld_
10344 _fmuld_:
10345 	fmov.l		%fpcr,-(%sp)		# save fpcr
10346 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10347 	fmov.d		0x8(%sp),%fp0		# load dbl dst
10348 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10349 	fmul.d		0xc(%sp),%fp0		# fmul w/ dbl src
10350 	rts
10351 
10352 	global		_fmulx_
10353 _fmulx_:
10354 	fmovm.x		0x4(%sp),&0x80		# load ext dst
10355 	fmul.x		0x10(%sp),%fp0		# fmul w/ ext src
10356 	rts
10357 
10358 	global		_fdivs_
10359 _fdivs_:
10360 	fmov.l		%fpcr,-(%sp)		# save fpcr
10361 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10362 	fmov.s		0x8(%sp),%fp0		# load sgl dst
10363 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10364 	fdiv.s		0x8(%sp),%fp0		# fdiv w/ sgl src
10365 	rts
10366 
10367 	global		_fdivd_
10368 _fdivd_:
10369 	fmov.l		%fpcr,-(%sp)		# save fpcr
10370 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10371 	fmov.d		0x8(%sp),%fp0		# load dbl dst
10372 	fmov.l		(%sp)+,%fpcr		# restore fpcr
10373 	fdiv.d		0xc(%sp),%fp0		# fdiv w/ dbl src
10374 	rts
10375 
10376 	global		_fdivx_
10377 _fdivx_:
10378 	fmovm.x		0x4(%sp),&0x80		# load ext dst
10379 	fdiv.x		0x10(%sp),%fp0		# fdiv w/ ext src
10380 	rts
10381 
10382 	global		_fabss_
10383 _fabss_:
10384 	fabs.s		0x4(%sp),%fp0		# fabs w/ sgl src
10385 	rts
10386 
10387 	global		_fabsd_
10388 _fabsd_:
10389 	fabs.d		0x4(%sp),%fp0		# fabs w/ dbl src
10390 	rts
10391 
10392 	global		_fabsx_
10393 _fabsx_:
10394 	fabs.x		0x4(%sp),%fp0		# fabs w/ ext src
10395 	rts
10396 
10397 	global		_fnegs_
10398 _fnegs_:
10399 	fneg.s		0x4(%sp),%fp0		# fneg w/ sgl src
10400 	rts
10401 
10402 	global		_fnegd_
10403 _fnegd_:
10404 	fneg.d		0x4(%sp),%fp0		# fneg w/ dbl src
10405 	rts
10406 
10407 	global		_fnegx_
10408 _fnegx_:
10409 	fneg.x		0x4(%sp),%fp0		# fneg w/ ext src
10410 	rts
10411 
10412 	global		_fsqrts_
10413 _fsqrts_:
10414 	fsqrt.s		0x4(%sp),%fp0		# fsqrt w/ sgl src
10415 	rts
10416 
10417 	global		_fsqrtd_
10418 _fsqrtd_:
10419 	fsqrt.d		0x4(%sp),%fp0		# fsqrt w/ dbl src
10420 	rts
10421 
10422 	global		_fsqrtx_
10423 _fsqrtx_:
10424 	fsqrt.x		0x4(%sp),%fp0		# fsqrt w/ ext src
10425 	rts
10426 
10427 	global		_fints_
10428 _fints_:
10429 	fint.s		0x4(%sp),%fp0		# fint w/ sgl src
10430 	rts
10431 
10432 	global		_fintd_
10433 _fintd_:
10434 	fint.d		0x4(%sp),%fp0		# fint w/ dbl src
10435 	rts
10436 
10437 	global		_fintx_
10438 _fintx_:
10439 	fint.x		0x4(%sp),%fp0		# fint w/ ext src
10440 	rts
10441 
10442 	global		_fintrzs_
10443 _fintrzs_:
10444 	fintrz.s	0x4(%sp),%fp0		# fintrz w/ sgl src
10445 	rts
10446 
10447 	global		_fintrzd_
10448 _fintrzd_:
10449 	fintrz.d	0x4(%sp),%fp0		# fintrx w/ dbl src
10450 	rts
10451 
10452 	global		_fintrzx_
10453 _fintrzx_:
10454 	fintrz.x	0x4(%sp),%fp0		# fintrz w/ ext src
10455 	rts
10456 
10457 ########################################################################
10458 
10459 #########################################################################
10460 # src_zero(): Return signed zero according to sign of src operand.	#
10461 #########################################################################
10462 	global		src_zero
10463 src_zero:
10464 	tst.b		SRC_EX(%a0)		# get sign of src operand
10465 	bmi.b		ld_mzero		# if neg, load neg zero
10466 
10467 #
10468 # ld_pzero(): return a positive zero.
10469 #
10470 	global		ld_pzero
10471 ld_pzero:
10472 	fmov.s		&0x00000000,%fp0	# load +0
10473 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
10474 	rts
10475 
10476 # ld_mzero(): return a negative zero.
10477 	global		ld_mzero
10478 ld_mzero:
10479 	fmov.s		&0x80000000,%fp0	# load -0
10480 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
10481 	rts
10482 
10483 #########################################################################
10484 # dst_zero(): Return signed zero according to sign of dst operand.	#
10485 #########################################################################
10486 	global		dst_zero
10487 dst_zero:
10488 	tst.b		DST_EX(%a1)		# get sign of dst operand
10489 	bmi.b		ld_mzero		# if neg, load neg zero
10490 	bra.b		ld_pzero		# load positive zero
10491 
10492 #########################################################################
10493 # src_inf(): Return signed inf according to sign of src operand.	#
10494 #########################################################################
10495 	global		src_inf
10496 src_inf:
10497 	tst.b		SRC_EX(%a0)		# get sign of src operand
10498 	bmi.b		ld_minf			# if negative branch
10499 
10500 #
10501 # ld_pinf(): return a positive infinity.
10502 #
10503 	global		ld_pinf
10504 ld_pinf:
10505 	fmov.s		&0x7f800000,%fp0	# load +INF
10506 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
10507 	rts
10508 
10509 #
10510 # ld_minf():return a negative infinity.
10511 #
10512 	global		ld_minf
10513 ld_minf:
10514 	fmov.s		&0xff800000,%fp0	# load -INF
10515 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
10516 	rts
10517 
10518 #########################################################################
10519 # dst_inf(): Return signed inf according to sign of dst operand.	#
10520 #########################################################################
10521 	global		dst_inf
10522 dst_inf:
10523 	tst.b		DST_EX(%a1)		# get sign of dst operand
10524 	bmi.b		ld_minf			# if negative branch
10525 	bra.b		ld_pinf
10526 
10527 	global		szr_inf
10528 #################################################################
10529 # szr_inf(): Return +ZERO for a negative src operand or		#
10530 #	            +INF for a positive src operand.		#
10531 #	     Routine used for fetox, ftwotox, and ftentox.	#
10532 #################################################################
10533 szr_inf:
10534 	tst.b		SRC_EX(%a0)		# check sign of source
10535 	bmi.b		ld_pzero
10536 	bra.b		ld_pinf
10537 
10538 #########################################################################
10539 # sopr_inf(): Return +INF for a positive src operand or			#
10540 #	      jump to operand error routine for a negative src operand.	#
10541 #	      Routine used for flogn, flognp1, flog10, and flog2.	#
10542 #########################################################################
10543 	global		sopr_inf
10544 sopr_inf:
10545 	tst.b		SRC_EX(%a0)		# check sign of source
10546 	bmi.w		t_operr
10547 	bra.b		ld_pinf
10548 
10549 #################################################################
10550 # setoxm1i(): Return minus one for a negative src operand or	#
10551 #	      positive infinity for a positive src operand.	#
10552 #	      Routine used for fetoxm1.				#
10553 #################################################################
10554 	global		setoxm1i
10555 setoxm1i:
10556 	tst.b		SRC_EX(%a0)		# check sign of source
10557 	bmi.b		ld_mone
10558 	bra.b		ld_pinf
10559 
10560 #########################################################################
10561 # src_one(): Return signed one according to sign of src operand.	#
10562 #########################################################################
10563 	global		src_one
10564 src_one:
10565 	tst.b		SRC_EX(%a0)		# check sign of source
10566 	bmi.b		ld_mone
10567 
10568 #
10569 # ld_pone(): return positive one.
10570 #
10571 	global		ld_pone
10572 ld_pone:
10573 	fmov.s		&0x3f800000,%fp0	# load +1
10574 	clr.b		FPSR_CC(%a6)
10575 	rts
10576 
10577 #
10578 # ld_mone(): return negative one.
10579 #
10580 	global		ld_mone
10581 ld_mone:
10582 	fmov.s		&0xbf800000,%fp0	# load -1
10583 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
10584 	rts
10585 
10586 ppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
10587 mpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
10588 
10589 #################################################################
10590 # spi_2(): Return signed PI/2 according to sign of src operand.	#
10591 #################################################################
10592 	global		spi_2
10593 spi_2:
10594 	tst.b		SRC_EX(%a0)		# check sign of source
10595 	bmi.b		ld_mpi2
10596 
10597 #
10598 # ld_ppi2(): return positive PI/2.
10599 #
10600 	global		ld_ppi2
10601 ld_ppi2:
10602 	fmov.l		%d0,%fpcr
10603 	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
10604 	bra.w		t_pinx2			# set INEX2
10605 
10606 #
10607 # ld_mpi2(): return negative PI/2.
10608 #
10609 	global		ld_mpi2
10610 ld_mpi2:
10611 	fmov.l		%d0,%fpcr
10612 	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
10613 	bra.w		t_minx2			# set INEX2
10614 
10615 ####################################################
10616 # The following routines give support for fsincos. #
10617 ####################################################
10618 
10619 #
10620 # ssincosz(): When the src operand is ZERO, store a one in the
10621 #	      cosine register and return a ZERO in fp0 w/ the same sign
10622 #	      as the src operand.
10623 #
10624 	global		ssincosz
10625 ssincosz:
10626 	fmov.s		&0x3f800000,%fp1
10627 	tst.b		SRC_EX(%a0)		# test sign
10628 	bpl.b		sincoszp
10629 	fmov.s		&0x80000000,%fp0	# return sin result in fp0
10630 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
10631 	rts
10632 sincoszp:
10633 	fmov.s		&0x00000000,%fp0	# return sin result in fp0
10634 	mov.b		&z_bmask,FPSR_CC(%a6)
10635 	rts
10636 
10637 #
10638 # ssincosi(): When the src operand is INF, store a QNAN in the cosine
10639 #	      register and jump to the operand error routine for negative
10640 #	      src operands.
10641 #
10642 	global		ssincosi
10643 ssincosi:
10644 	fmov.x		qnan(%pc),%fp1		# load NAN
10645 	bra.w		t_operr
10646 
10647 #
10648 # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
10649 #		 register and branch to the src QNAN routine.
10650 #
10651 	global		ssincosqnan
10652 ssincosqnan:
10653 	fmov.x		LOCAL_EX(%a0),%fp1
10654 	bra.w		src_qnan
10655 
10656 ########################################################################
10657 
10658 	global		smod_sdnrm
10659 	global		smod_snorm
10660 smod_sdnrm:
10661 smod_snorm:
10662 	mov.b		DTAG(%a6),%d1
10663 	beq.l		smod
10664 	cmpi.b		%d1,&ZERO
10665 	beq.w		smod_zro
10666 	cmpi.b		%d1,&INF
10667 	beq.l		t_operr
10668 	cmpi.b		%d1,&DENORM
10669 	beq.l		smod
10670 	bra.l		dst_qnan
10671 
10672 	global		smod_szero
10673 smod_szero:
10674 	mov.b		DTAG(%a6),%d1
10675 	beq.l		t_operr
10676 	cmpi.b		%d1,&ZERO
10677 	beq.l		t_operr
10678 	cmpi.b		%d1,&INF
10679 	beq.l		t_operr
10680 	cmpi.b		%d1,&DENORM
10681 	beq.l		t_operr
10682 	bra.l		dst_qnan
10683 
10684 	global		smod_sinf
10685 smod_sinf:
10686 	mov.b		DTAG(%a6),%d1
10687 	beq.l		smod_fpn
10688 	cmpi.b		%d1,&ZERO
10689 	beq.l		smod_zro
10690 	cmpi.b		%d1,&INF
10691 	beq.l		t_operr
10692 	cmpi.b		%d1,&DENORM
10693 	beq.l		smod_fpn
10694 	bra.l		dst_qnan
10695 
10696 smod_zro:
10697 srem_zro:
10698 	mov.b		SRC_EX(%a0),%d1		# get src sign
10699 	mov.b		DST_EX(%a1),%d0		# get dst sign
10700 	eor.b		%d0,%d1			# get qbyte sign
10701 	andi.b		&0x80,%d1
10702 	mov.b		%d1,FPSR_QBYTE(%a6)
10703 	tst.b		%d0
10704 	bpl.w		ld_pzero
10705 	bra.w		ld_mzero
10706 
10707 smod_fpn:
10708 srem_fpn:
10709 	clr.b		FPSR_QBYTE(%a6)
10710 	mov.l		%d0,-(%sp)
10711 	mov.b		SRC_EX(%a0),%d1		# get src sign
10712 	mov.b		DST_EX(%a1),%d0		# get dst sign
10713 	eor.b		%d0,%d1			# get qbyte sign
10714 	andi.b		&0x80,%d1
10715 	mov.b		%d1,FPSR_QBYTE(%a6)
10716 	cmpi.b		DTAG(%a6),&DENORM
10717 	bne.b		smod_nrm
10718 	lea		DST(%a1),%a0
10719 	mov.l		(%sp)+,%d0
10720 	bra		t_resdnrm
10721 smod_nrm:
10722 	fmov.l		(%sp)+,%fpcr
10723 	fmov.x		DST(%a1),%fp0
10724 	tst.b		DST_EX(%a1)
10725 	bmi.b		smod_nrm_neg
10726 	rts
10727 
10728 smod_nrm_neg:
10729 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' code
10730 	rts
10731 
10732 #########################################################################
10733 	global		srem_snorm
10734 	global		srem_sdnrm
10735 srem_sdnrm:
10736 srem_snorm:
10737 	mov.b		DTAG(%a6),%d1
10738 	beq.l		srem
10739 	cmpi.b		%d1,&ZERO
10740 	beq.w		srem_zro
10741 	cmpi.b		%d1,&INF
10742 	beq.l		t_operr
10743 	cmpi.b		%d1,&DENORM
10744 	beq.l		srem
10745 	bra.l		dst_qnan
10746 
10747 	global		srem_szero
10748 srem_szero:
10749 	mov.b		DTAG(%a6),%d1
10750 	beq.l		t_operr
10751 	cmpi.b		%d1,&ZERO
10752 	beq.l		t_operr
10753 	cmpi.b		%d1,&INF
10754 	beq.l		t_operr
10755 	cmpi.b		%d1,&DENORM
10756 	beq.l		t_operr
10757 	bra.l		dst_qnan
10758 
10759 	global		srem_sinf
10760 srem_sinf:
10761 	mov.b		DTAG(%a6),%d1
10762 	beq.w		srem_fpn
10763 	cmpi.b		%d1,&ZERO
10764 	beq.w		srem_zro
10765 	cmpi.b		%d1,&INF
10766 	beq.l		t_operr
10767 	cmpi.b		%d1,&DENORM
10768 	beq.l		srem_fpn
10769 	bra.l		dst_qnan
10770 
10771 #########################################################################
10772 
10773 	global		sscale_snorm
10774 	global		sscale_sdnrm
10775 sscale_snorm:
10776 sscale_sdnrm:
10777 	mov.b		DTAG(%a6),%d1
10778 	beq.l		sscale
10779 	cmpi.b		%d1,&ZERO
10780 	beq.l		dst_zero
10781 	cmpi.b		%d1,&INF
10782 	beq.l		dst_inf
10783 	cmpi.b		%d1,&DENORM
10784 	beq.l		sscale
10785 	bra.l		dst_qnan
10786 
10787 	global		sscale_szero
10788 sscale_szero:
10789 	mov.b		DTAG(%a6),%d1
10790 	beq.l		sscale
10791 	cmpi.b		%d1,&ZERO
10792 	beq.l		dst_zero
10793 	cmpi.b		%d1,&INF
10794 	beq.l		dst_inf
10795 	cmpi.b		%d1,&DENORM
10796 	beq.l		sscale
10797 	bra.l		dst_qnan
10798 
10799 	global		sscale_sinf
10800 sscale_sinf:
10801 	mov.b		DTAG(%a6),%d1
10802 	beq.l		t_operr
10803 	cmpi.b		%d1,&QNAN
10804 	beq.l		dst_qnan
10805 	bra.l		t_operr
10806 
10807 ########################################################################
10808 
10809 	global		sop_sqnan
10810 sop_sqnan:
10811 	mov.b		DTAG(%a6),%d1
10812 	cmpi.b		%d1,&QNAN
10813 	beq.l		dst_qnan
10814 	bra.l		src_qnan
10815 
10816 #########################################################################
10817 # norm(): normalize the mantissa of an extended precision input. the	#
10818 #	  input operand should not be normalized already.		#
10819 #									#
10820 # XDEF ****************************************************************	#
10821 #	norm()								#
10822 #									#
10823 # XREF **************************************************************** #
10824 #	none								#
10825 #									#
10826 # INPUT *************************************************************** #
10827 #	a0 = pointer fp extended precision operand to normalize		#
10828 #									#
10829 # OUTPUT ************************************************************** #
10830 #	d0 = number of bit positions the mantissa was shifted		#
10831 #	a0 = the input operand's mantissa is normalized; the exponent	#
10832 #	     is unchanged.						#
10833 #									#
10834 #########################################################################
10835 	global		norm
10836 norm:
10837 	mov.l		%d2, -(%sp)		# create some temp regs
10838 	mov.l		%d3, -(%sp)
10839 
10840 	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
10841 	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
10842 
10843 	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
10844 	beq.b		norm_lo			# hi(man) is all zeroes!
10845 
10846 norm_hi:
10847 	lsl.l		%d2, %d0		# left shift hi(man)
10848 	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
10849 
10850 	or.l		%d3, %d0		# create hi(man)
10851 	lsl.l		%d2, %d1		# create lo(man)
10852 
10853 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
10854 	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
10855 
10856 	mov.l		%d2, %d0		# return shift amount
10857 
10858 	mov.l		(%sp)+, %d3		# restore temp regs
10859 	mov.l		(%sp)+, %d2
10860 
10861 	rts
10862 
10863 norm_lo:
10864 	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
10865 	lsl.l		%d2, %d1		# shift lo(man)
10866 	add.l		&32, %d2		# add 32 to shft amount
10867 
10868 	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
10869 	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
10870 
10871 	mov.l		%d2, %d0		# return shift amount
10872 
10873 	mov.l		(%sp)+, %d3		# restore temp regs
10874 	mov.l		(%sp)+, %d2
10875 
10876 	rts
10877 
10878 #########################################################################
10879 # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
10880 #		- returns corresponding optype tag			#
10881 #									#
10882 # XDEF ****************************************************************	#
10883 #	unnorm_fix()							#
10884 #									#
10885 # XREF **************************************************************** #
10886 #	norm() - normalize the mantissa					#
10887 #									#
10888 # INPUT *************************************************************** #
10889 #	a0 = pointer to unnormalized extended precision number		#
10890 #									#
10891 # OUTPUT ************************************************************** #
10892 #	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
10893 #	a0 = input operand has been converted to a norm, denorm, or	#
10894 #	     zero; both the exponent and mantissa are changed.		#
10895 #									#
10896 #########################################################################
10897 
10898 	global		unnorm_fix
10899 unnorm_fix:
10900 	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
10901 	bne.b		unnorm_shift		# hi(man) is not all zeroes
10902 
10903 #
10904 # hi(man) is all zeroes so see if any bits in lo(man) are set
10905 #
10906 unnorm_chk_lo:
10907 	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
10908 	beq.w		unnorm_zero		# yes
10909 
10910 	add.w		&32, %d0		# no; fix shift distance
10911 
10912 #
10913 # d0 = # shifts needed for complete normalization
10914 #
10915 unnorm_shift:
10916 	clr.l		%d1			# clear top word
10917 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
10918 	and.w		&0x7fff, %d1		# strip off sgn
10919 
10920 	cmp.w		%d0, %d1		# will denorm push exp < 0?
10921 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
10922 
10923 #
10924 # exponent would not go < 0. therefore, number stays normalized
10925 #
10926 	sub.w		%d0, %d1		# shift exponent value
10927 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
10928 	and.w		&0x8000, %d0		# save old sign
10929 	or.w		%d0, %d1		# {sgn,new exp}
10930 	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
10931 
10932 	bsr.l		norm			# normalize UNNORM
10933 
10934 	mov.b		&NORM, %d0		# return new optype tag
10935 	rts
10936 
10937 #
10938 # exponent would go < 0, so only denormalize until exp = 0
10939 #
10940 unnorm_nrm_zero:
10941 	cmp.b		%d1, &32		# is exp <= 32?
10942 	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
10943 
10944 	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
10945 	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
10946 
10947 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
10948 	lsl.l		%d1, %d0		# extract new lo(man)
10949 	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
10950 
10951 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
10952 
10953 	mov.b		&DENORM, %d0		# return new optype tag
10954 	rts
10955 
10956 #
10957 # only mantissa bits set are in lo(man)
10958 #
10959 unnorm_nrm_zero_lrg:
10960 	sub.w		&32, %d1		# adjust shft amt by 32
10961 
10962 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
10963 	lsl.l		%d1, %d0		# left shift lo(man)
10964 
10965 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
10966 	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
10967 
10968 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
10969 
10970 	mov.b		&DENORM, %d0		# return new optype tag
10971 	rts
10972 
10973 #
10974 # whole mantissa is zero so this UNNORM is actually a zero
10975 #
10976 unnorm_zero:
10977 	and.w		&0x8000, FTEMP_EX(%a0)	# force exponent to zero
10978 
10979 	mov.b		&ZERO, %d0		# fix optype tag
10980 	rts
10981