xref: /linux/arch/m68k/ifpsp060/src/fplsp.S (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
11da177e4SLinus Torvalds~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21da177e4SLinus TorvaldsMOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
31da177e4SLinus TorvaldsM68000 Hi-Performance Microprocessor Division
41da177e4SLinus TorvaldsM68060 Software Package
51da177e4SLinus TorvaldsProduction Release P1.00 -- October 10, 1994
61da177e4SLinus Torvalds
7*96de0e25SJan EngelhardtM68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
81da177e4SLinus Torvalds
91da177e4SLinus TorvaldsTHE SOFTWARE is provided on an "AS IS" basis and without warranty.
101da177e4SLinus TorvaldsTo the maximum extent permitted by applicable law,
111da177e4SLinus TorvaldsMOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
121da177e4SLinus TorvaldsINCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
131da177e4SLinus Torvaldsand any warranty against infringement with regard to the SOFTWARE
141da177e4SLinus Torvalds(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
151da177e4SLinus Torvalds
161da177e4SLinus TorvaldsTo the maximum extent permitted by applicable law,
171da177e4SLinus TorvaldsIN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
181da177e4SLinus Torvalds(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
191da177e4SLinus TorvaldsBUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
201da177e4SLinus TorvaldsARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
211da177e4SLinus TorvaldsMotorola assumes no responsibility for the maintenance and support of the SOFTWARE.
221da177e4SLinus Torvalds
231da177e4SLinus TorvaldsYou are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
241da177e4SLinus Torvaldsso long as this entire notice is retained without alteration in any modified and/or
251da177e4SLinus Torvaldsredistributed versions, and that such modified versions are clearly identified as such.
261da177e4SLinus TorvaldsNo licenses are granted by implication, estoppel or otherwise under any patents
271da177e4SLinus Torvaldsor trademarks of Motorola, Inc.
281da177e4SLinus Torvalds~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291da177e4SLinus Torvalds#
301da177e4SLinus Torvalds# lfptop.s:
311da177e4SLinus Torvalds#	This file is appended to the top of the 060ILSP package
321da177e4SLinus Torvalds# and contains the entry points into the package. The user, in
331da177e4SLinus Torvalds# effect, branches to one of the branch table entries located here.
341da177e4SLinus Torvalds#
351da177e4SLinus Torvalds
361da177e4SLinus Torvalds	bra.l	_facoss_
371da177e4SLinus Torvalds	short	0x0000
381da177e4SLinus Torvalds	bra.l	_facosd_
391da177e4SLinus Torvalds	short	0x0000
401da177e4SLinus Torvalds	bra.l	_facosx_
411da177e4SLinus Torvalds	short	0x0000
421da177e4SLinus Torvalds
431da177e4SLinus Torvalds	bra.l	_fasins_
441da177e4SLinus Torvalds	short	0x0000
451da177e4SLinus Torvalds	bra.l	_fasind_
461da177e4SLinus Torvalds	short	0x0000
471da177e4SLinus Torvalds	bra.l	_fasinx_
481da177e4SLinus Torvalds	short	0x0000
491da177e4SLinus Torvalds
501da177e4SLinus Torvalds	bra.l	_fatans_
511da177e4SLinus Torvalds	short	0x0000
521da177e4SLinus Torvalds	bra.l	_fatand_
531da177e4SLinus Torvalds	short	0x0000
541da177e4SLinus Torvalds	bra.l	_fatanx_
551da177e4SLinus Torvalds	short	0x0000
561da177e4SLinus Torvalds
571da177e4SLinus Torvalds	bra.l	_fatanhs_
581da177e4SLinus Torvalds	short	0x0000
591da177e4SLinus Torvalds	bra.l	_fatanhd_
601da177e4SLinus Torvalds	short	0x0000
611da177e4SLinus Torvalds	bra.l	_fatanhx_
621da177e4SLinus Torvalds	short	0x0000
631da177e4SLinus Torvalds
641da177e4SLinus Torvalds	bra.l	_fcoss_
651da177e4SLinus Torvalds	short	0x0000
661da177e4SLinus Torvalds	bra.l	_fcosd_
671da177e4SLinus Torvalds	short	0x0000
681da177e4SLinus Torvalds	bra.l	_fcosx_
691da177e4SLinus Torvalds	short	0x0000
701da177e4SLinus Torvalds
711da177e4SLinus Torvalds	bra.l	_fcoshs_
721da177e4SLinus Torvalds	short	0x0000
731da177e4SLinus Torvalds	bra.l	_fcoshd_
741da177e4SLinus Torvalds	short	0x0000
751da177e4SLinus Torvalds	bra.l	_fcoshx_
761da177e4SLinus Torvalds	short	0x0000
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds	bra.l	_fetoxs_
791da177e4SLinus Torvalds	short	0x0000
801da177e4SLinus Torvalds	bra.l	_fetoxd_
811da177e4SLinus Torvalds	short	0x0000
821da177e4SLinus Torvalds	bra.l	_fetoxx_
831da177e4SLinus Torvalds	short	0x0000
841da177e4SLinus Torvalds
851da177e4SLinus Torvalds	bra.l	_fetoxm1s_
861da177e4SLinus Torvalds	short	0x0000
871da177e4SLinus Torvalds	bra.l	_fetoxm1d_
881da177e4SLinus Torvalds	short	0x0000
891da177e4SLinus Torvalds	bra.l	_fetoxm1x_
901da177e4SLinus Torvalds	short	0x0000
911da177e4SLinus Torvalds
921da177e4SLinus Torvalds	bra.l	_fgetexps_
931da177e4SLinus Torvalds	short	0x0000
941da177e4SLinus Torvalds	bra.l	_fgetexpd_
951da177e4SLinus Torvalds	short	0x0000
961da177e4SLinus Torvalds	bra.l	_fgetexpx_
971da177e4SLinus Torvalds	short	0x0000
981da177e4SLinus Torvalds
991da177e4SLinus Torvalds	bra.l	_fgetmans_
1001da177e4SLinus Torvalds	short	0x0000
1011da177e4SLinus Torvalds	bra.l	_fgetmand_
1021da177e4SLinus Torvalds	short	0x0000
1031da177e4SLinus Torvalds	bra.l	_fgetmanx_
1041da177e4SLinus Torvalds	short	0x0000
1051da177e4SLinus Torvalds
1061da177e4SLinus Torvalds	bra.l	_flog10s_
1071da177e4SLinus Torvalds	short	0x0000
1081da177e4SLinus Torvalds	bra.l	_flog10d_
1091da177e4SLinus Torvalds	short	0x0000
1101da177e4SLinus Torvalds	bra.l	_flog10x_
1111da177e4SLinus Torvalds	short	0x0000
1121da177e4SLinus Torvalds
1131da177e4SLinus Torvalds	bra.l	_flog2s_
1141da177e4SLinus Torvalds	short	0x0000
1151da177e4SLinus Torvalds	bra.l	_flog2d_
1161da177e4SLinus Torvalds	short	0x0000
1171da177e4SLinus Torvalds	bra.l	_flog2x_
1181da177e4SLinus Torvalds	short	0x0000
1191da177e4SLinus Torvalds
1201da177e4SLinus Torvalds	bra.l	_flogns_
1211da177e4SLinus Torvalds	short	0x0000
1221da177e4SLinus Torvalds	bra.l	_flognd_
1231da177e4SLinus Torvalds	short	0x0000
1241da177e4SLinus Torvalds	bra.l	_flognx_
1251da177e4SLinus Torvalds	short	0x0000
1261da177e4SLinus Torvalds
1271da177e4SLinus Torvalds	bra.l	_flognp1s_
1281da177e4SLinus Torvalds	short	0x0000
1291da177e4SLinus Torvalds	bra.l	_flognp1d_
1301da177e4SLinus Torvalds	short	0x0000
1311da177e4SLinus Torvalds	bra.l	_flognp1x_
1321da177e4SLinus Torvalds	short	0x0000
1331da177e4SLinus Torvalds
1341da177e4SLinus Torvalds	bra.l	_fmods_
1351da177e4SLinus Torvalds	short	0x0000
1361da177e4SLinus Torvalds	bra.l	_fmodd_
1371da177e4SLinus Torvalds	short	0x0000
1381da177e4SLinus Torvalds	bra.l	_fmodx_
1391da177e4SLinus Torvalds	short	0x0000
1401da177e4SLinus Torvalds
1411da177e4SLinus Torvalds	bra.l	_frems_
1421da177e4SLinus Torvalds	short	0x0000
1431da177e4SLinus Torvalds	bra.l	_fremd_
1441da177e4SLinus Torvalds	short	0x0000
1451da177e4SLinus Torvalds	bra.l	_fremx_
1461da177e4SLinus Torvalds	short	0x0000
1471da177e4SLinus Torvalds
1481da177e4SLinus Torvalds	bra.l	_fscales_
1491da177e4SLinus Torvalds	short	0x0000
1501da177e4SLinus Torvalds	bra.l	_fscaled_
1511da177e4SLinus Torvalds	short	0x0000
1521da177e4SLinus Torvalds	bra.l	_fscalex_
1531da177e4SLinus Torvalds	short	0x0000
1541da177e4SLinus Torvalds
1551da177e4SLinus Torvalds	bra.l	_fsins_
1561da177e4SLinus Torvalds	short	0x0000
1571da177e4SLinus Torvalds	bra.l	_fsind_
1581da177e4SLinus Torvalds	short	0x0000
1591da177e4SLinus Torvalds	bra.l	_fsinx_
1601da177e4SLinus Torvalds	short	0x0000
1611da177e4SLinus Torvalds
1621da177e4SLinus Torvalds	bra.l	_fsincoss_
1631da177e4SLinus Torvalds	short	0x0000
1641da177e4SLinus Torvalds	bra.l	_fsincosd_
1651da177e4SLinus Torvalds	short	0x0000
1661da177e4SLinus Torvalds	bra.l	_fsincosx_
1671da177e4SLinus Torvalds	short	0x0000
1681da177e4SLinus Torvalds
1691da177e4SLinus Torvalds	bra.l	_fsinhs_
1701da177e4SLinus Torvalds	short	0x0000
1711da177e4SLinus Torvalds	bra.l	_fsinhd_
1721da177e4SLinus Torvalds	short	0x0000
1731da177e4SLinus Torvalds	bra.l	_fsinhx_
1741da177e4SLinus Torvalds	short	0x0000
1751da177e4SLinus Torvalds
1761da177e4SLinus Torvalds	bra.l	_ftans_
1771da177e4SLinus Torvalds	short	0x0000
1781da177e4SLinus Torvalds	bra.l	_ftand_
1791da177e4SLinus Torvalds	short	0x0000
1801da177e4SLinus Torvalds	bra.l	_ftanx_
1811da177e4SLinus Torvalds	short	0x0000
1821da177e4SLinus Torvalds
1831da177e4SLinus Torvalds	bra.l	_ftanhs_
1841da177e4SLinus Torvalds	short	0x0000
1851da177e4SLinus Torvalds	bra.l	_ftanhd_
1861da177e4SLinus Torvalds	short	0x0000
1871da177e4SLinus Torvalds	bra.l	_ftanhx_
1881da177e4SLinus Torvalds	short	0x0000
1891da177e4SLinus Torvalds
1901da177e4SLinus Torvalds	bra.l	_ftentoxs_
1911da177e4SLinus Torvalds	short	0x0000
1921da177e4SLinus Torvalds	bra.l	_ftentoxd_
1931da177e4SLinus Torvalds	short	0x0000
1941da177e4SLinus Torvalds	bra.l	_ftentoxx_
1951da177e4SLinus Torvalds	short	0x0000
1961da177e4SLinus Torvalds
1971da177e4SLinus Torvalds	bra.l	_ftwotoxs_
1981da177e4SLinus Torvalds	short	0x0000
1991da177e4SLinus Torvalds	bra.l	_ftwotoxd_
2001da177e4SLinus Torvalds	short	0x0000
2011da177e4SLinus Torvalds	bra.l	_ftwotoxx_
2021da177e4SLinus Torvalds	short	0x0000
2031da177e4SLinus Torvalds
2041da177e4SLinus Torvalds	bra.l	_fabss_
2051da177e4SLinus Torvalds	short	0x0000
2061da177e4SLinus Torvalds	bra.l	_fabsd_
2071da177e4SLinus Torvalds	short	0x0000
2081da177e4SLinus Torvalds	bra.l	_fabsx_
2091da177e4SLinus Torvalds	short	0x0000
2101da177e4SLinus Torvalds
2111da177e4SLinus Torvalds	bra.l	_fadds_
2121da177e4SLinus Torvalds	short	0x0000
2131da177e4SLinus Torvalds	bra.l	_faddd_
2141da177e4SLinus Torvalds	short	0x0000
2151da177e4SLinus Torvalds	bra.l	_faddx_
2161da177e4SLinus Torvalds	short	0x0000
2171da177e4SLinus Torvalds
2181da177e4SLinus Torvalds	bra.l	_fdivs_
2191da177e4SLinus Torvalds	short	0x0000
2201da177e4SLinus Torvalds	bra.l	_fdivd_
2211da177e4SLinus Torvalds	short	0x0000
2221da177e4SLinus Torvalds	bra.l	_fdivx_
2231da177e4SLinus Torvalds	short	0x0000
2241da177e4SLinus Torvalds
2251da177e4SLinus Torvalds	bra.l	_fints_
2261da177e4SLinus Torvalds	short	0x0000
2271da177e4SLinus Torvalds	bra.l	_fintd_
2281da177e4SLinus Torvalds	short	0x0000
2291da177e4SLinus Torvalds	bra.l	_fintx_
2301da177e4SLinus Torvalds	short	0x0000
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvalds	bra.l	_fintrzs_
2331da177e4SLinus Torvalds	short	0x0000
2341da177e4SLinus Torvalds	bra.l	_fintrzd_
2351da177e4SLinus Torvalds	short	0x0000
2361da177e4SLinus Torvalds	bra.l	_fintrzx_
2371da177e4SLinus Torvalds	short	0x0000
2381da177e4SLinus Torvalds
2391da177e4SLinus Torvalds	bra.l	_fmuls_
2401da177e4SLinus Torvalds	short	0x0000
2411da177e4SLinus Torvalds	bra.l	_fmuld_
2421da177e4SLinus Torvalds	short	0x0000
2431da177e4SLinus Torvalds	bra.l	_fmulx_
2441da177e4SLinus Torvalds	short	0x0000
2451da177e4SLinus Torvalds
2461da177e4SLinus Torvalds	bra.l	_fnegs_
2471da177e4SLinus Torvalds	short	0x0000
2481da177e4SLinus Torvalds	bra.l	_fnegd_
2491da177e4SLinus Torvalds	short	0x0000
2501da177e4SLinus Torvalds	bra.l	_fnegx_
2511da177e4SLinus Torvalds	short	0x0000
2521da177e4SLinus Torvalds
2531da177e4SLinus Torvalds	bra.l	_fsqrts_
2541da177e4SLinus Torvalds	short	0x0000
2551da177e4SLinus Torvalds	bra.l	_fsqrtd_
2561da177e4SLinus Torvalds	short	0x0000
2571da177e4SLinus Torvalds	bra.l	_fsqrtx_
2581da177e4SLinus Torvalds	short	0x0000
2591da177e4SLinus Torvalds
2601da177e4SLinus Torvalds	bra.l	_fsubs_
2611da177e4SLinus Torvalds	short	0x0000
2621da177e4SLinus Torvalds	bra.l	_fsubd_
2631da177e4SLinus Torvalds	short	0x0000
2641da177e4SLinus Torvalds	bra.l	_fsubx_
2651da177e4SLinus Torvalds	short	0x0000
2661da177e4SLinus Torvalds
2671da177e4SLinus Torvalds# leave room for future possible additions
2681da177e4SLinus Torvalds	align	0x400
2691da177e4SLinus Torvalds
2701da177e4SLinus Torvalds#
2711da177e4SLinus Torvalds# This file contains a set of define statements for constants
2721da177e4SLinus Torvalds# in order to promote readability within the corecode itself.
2731da177e4SLinus Torvalds#
2741da177e4SLinus Torvalds
2751da177e4SLinus Torvaldsset LOCAL_SIZE,		192			# stack frame size(bytes)
2761da177e4SLinus Torvaldsset LV,			-LOCAL_SIZE		# stack offset
2771da177e4SLinus Torvalds
2781da177e4SLinus Torvaldsset EXC_SR,		0x4			# stack status register
2791da177e4SLinus Torvaldsset EXC_PC,		0x6			# stack pc
2801da177e4SLinus Torvaldsset EXC_VOFF,		0xa			# stacked vector offset
2811da177e4SLinus Torvaldsset EXC_EA,		0xc			# stacked <ea>
2821da177e4SLinus Torvalds
2831da177e4SLinus Torvaldsset EXC_FP,		0x0			# frame pointer
2841da177e4SLinus Torvalds
2851da177e4SLinus Torvaldsset EXC_AREGS,		-68			# offset of all address regs
2861da177e4SLinus Torvaldsset EXC_DREGS,		-100			# offset of all data regs
2871da177e4SLinus Torvaldsset EXC_FPREGS,		-36			# offset of all fp regs
2881da177e4SLinus Torvalds
2891da177e4SLinus Torvaldsset EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
2901da177e4SLinus Torvaldsset OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
2911da177e4SLinus Torvaldsset EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
2921da177e4SLinus Torvaldsset EXC_A5,		EXC_AREGS+(5*4)
2931da177e4SLinus Torvaldsset EXC_A4,		EXC_AREGS+(4*4)
2941da177e4SLinus Torvaldsset EXC_A3,		EXC_AREGS+(3*4)
2951da177e4SLinus Torvaldsset EXC_A2,		EXC_AREGS+(2*4)
2961da177e4SLinus Torvaldsset EXC_A1,		EXC_AREGS+(1*4)
2971da177e4SLinus Torvaldsset EXC_A0,		EXC_AREGS+(0*4)
2981da177e4SLinus Torvaldsset EXC_D7,		EXC_DREGS+(7*4)
2991da177e4SLinus Torvaldsset EXC_D6,		EXC_DREGS+(6*4)
3001da177e4SLinus Torvaldsset EXC_D5,		EXC_DREGS+(5*4)
3011da177e4SLinus Torvaldsset EXC_D4,		EXC_DREGS+(4*4)
3021da177e4SLinus Torvaldsset EXC_D3,		EXC_DREGS+(3*4)
3031da177e4SLinus Torvaldsset EXC_D2,		EXC_DREGS+(2*4)
3041da177e4SLinus Torvaldsset EXC_D1,		EXC_DREGS+(1*4)
3051da177e4SLinus Torvaldsset EXC_D0,		EXC_DREGS+(0*4)
3061da177e4SLinus Torvalds
3071da177e4SLinus Torvaldsset EXC_FP0,		EXC_FPREGS+(0*12)	# offset of saved fp0
3081da177e4SLinus Torvaldsset EXC_FP1,		EXC_FPREGS+(1*12)	# offset of saved fp1
3091da177e4SLinus Torvaldsset EXC_FP2,		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
3101da177e4SLinus Torvalds
3111da177e4SLinus Torvaldsset FP_SCR1,		LV+80			# fp scratch 1
3121da177e4SLinus Torvaldsset FP_SCR1_EX,		FP_SCR1+0
3131da177e4SLinus Torvaldsset FP_SCR1_SGN,	FP_SCR1+2
3141da177e4SLinus Torvaldsset FP_SCR1_HI,		FP_SCR1+4
3151da177e4SLinus Torvaldsset FP_SCR1_LO,		FP_SCR1+8
3161da177e4SLinus Torvalds
3171da177e4SLinus Torvaldsset FP_SCR0,		LV+68			# fp scratch 0
3181da177e4SLinus Torvaldsset FP_SCR0_EX,		FP_SCR0+0
3191da177e4SLinus Torvaldsset FP_SCR0_SGN,	FP_SCR0+2
3201da177e4SLinus Torvaldsset FP_SCR0_HI,		FP_SCR0+4
3211da177e4SLinus Torvaldsset FP_SCR0_LO,		FP_SCR0+8
3221da177e4SLinus Torvalds
3231da177e4SLinus Torvaldsset FP_DST,		LV+56			# fp destination operand
3241da177e4SLinus Torvaldsset FP_DST_EX,		FP_DST+0
3251da177e4SLinus Torvaldsset FP_DST_SGN,		FP_DST+2
3261da177e4SLinus Torvaldsset FP_DST_HI,		FP_DST+4
3271da177e4SLinus Torvaldsset FP_DST_LO,		FP_DST+8
3281da177e4SLinus Torvalds
3291da177e4SLinus Torvaldsset FP_SRC,		LV+44			# fp source operand
3301da177e4SLinus Torvaldsset FP_SRC_EX,		FP_SRC+0
3311da177e4SLinus Torvaldsset FP_SRC_SGN,		FP_SRC+2
3321da177e4SLinus Torvaldsset FP_SRC_HI,		FP_SRC+4
3331da177e4SLinus Torvaldsset FP_SRC_LO,		FP_SRC+8
3341da177e4SLinus Torvalds
3351da177e4SLinus Torvaldsset USER_FPIAR,		LV+40			# FP instr address register
3361da177e4SLinus Torvalds
3371da177e4SLinus Torvaldsset USER_FPSR,		LV+36			# FP status register
3381da177e4SLinus Torvaldsset FPSR_CC,		USER_FPSR+0		# FPSR condition codes
3391da177e4SLinus Torvaldsset FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
3401da177e4SLinus Torvaldsset FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
3411da177e4SLinus Torvaldsset FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
3421da177e4SLinus Torvalds
3431da177e4SLinus Torvaldsset USER_FPCR,		LV+32			# FP control register
3441da177e4SLinus Torvaldsset FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
3451da177e4SLinus Torvaldsset FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
3461da177e4SLinus Torvalds
3471da177e4SLinus Torvaldsset L_SCR3,		LV+28			# integer scratch 3
3481da177e4SLinus Torvaldsset L_SCR2,		LV+24			# integer scratch 2
3491da177e4SLinus Torvaldsset L_SCR1,		LV+20			# integer scratch 1
3501da177e4SLinus Torvalds
3511da177e4SLinus Torvaldsset STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
3521da177e4SLinus Torvalds
3531da177e4SLinus Torvaldsset EXC_TEMP2,		LV+24			# temporary space
3541da177e4SLinus Torvaldsset EXC_TEMP,		LV+16			# temporary space
3551da177e4SLinus Torvalds
3561da177e4SLinus Torvaldsset DTAG,		LV+15			# destination operand type
3571da177e4SLinus Torvaldsset STAG,		LV+14			# source operand type
3581da177e4SLinus Torvalds
3591da177e4SLinus Torvaldsset SPCOND_FLG,		LV+10			# flag: special case (see below)
3601da177e4SLinus Torvalds
3611da177e4SLinus Torvaldsset EXC_CC,		LV+8			# saved condition codes
3621da177e4SLinus Torvaldsset EXC_EXTWPTR,	LV+4			# saved current PC (active)
3631da177e4SLinus Torvaldsset EXC_EXTWORD,	LV+2			# saved extension word
3641da177e4SLinus Torvaldsset EXC_CMDREG,		LV+2			# saved extension word
3651da177e4SLinus Torvaldsset EXC_OPWORD,		LV+0			# saved operation word
3661da177e4SLinus Torvalds
3671da177e4SLinus Torvalds################################
3681da177e4SLinus Torvalds
3691da177e4SLinus Torvalds# Helpful macros
3701da177e4SLinus Torvalds
3711da177e4SLinus Torvaldsset FTEMP,		0			# offsets within an
3721da177e4SLinus Torvaldsset FTEMP_EX,		0			# extended precision
3731da177e4SLinus Torvaldsset FTEMP_SGN,		2			# value saved in memory.
3741da177e4SLinus Torvaldsset FTEMP_HI,		4
3751da177e4SLinus Torvaldsset FTEMP_LO,		8
3761da177e4SLinus Torvaldsset FTEMP_GRS,		12
3771da177e4SLinus Torvalds
3781da177e4SLinus Torvaldsset LOCAL,		0			# offsets within an
3791da177e4SLinus Torvaldsset LOCAL_EX,		0			# extended precision
3801da177e4SLinus Torvaldsset LOCAL_SGN,		2			# value saved in memory.
3811da177e4SLinus Torvaldsset LOCAL_HI,		4
3821da177e4SLinus Torvaldsset LOCAL_LO,		8
3831da177e4SLinus Torvaldsset LOCAL_GRS,		12
3841da177e4SLinus Torvalds
3851da177e4SLinus Torvaldsset DST,		0			# offsets within an
3861da177e4SLinus Torvaldsset DST_EX,		0			# extended precision
3871da177e4SLinus Torvaldsset DST_HI,		4			# value saved in memory.
3881da177e4SLinus Torvaldsset DST_LO,		8
3891da177e4SLinus Torvalds
3901da177e4SLinus Torvaldsset SRC,		0			# offsets within an
3911da177e4SLinus Torvaldsset SRC_EX,		0			# extended precision
3921da177e4SLinus Torvaldsset SRC_HI,		4			# value saved in memory.
3931da177e4SLinus Torvaldsset SRC_LO,		8
3941da177e4SLinus Torvalds
3951da177e4SLinus Torvaldsset SGL_LO,		0x3f81			# min sgl prec exponent
3961da177e4SLinus Torvaldsset SGL_HI,		0x407e			# max sgl prec exponent
3971da177e4SLinus Torvaldsset DBL_LO,		0x3c01			# min dbl prec exponent
3981da177e4SLinus Torvaldsset DBL_HI,		0x43fe			# max dbl prec exponent
3991da177e4SLinus Torvaldsset EXT_LO,		0x0			# min ext prec exponent
4001da177e4SLinus Torvaldsset EXT_HI,		0x7ffe			# max ext prec exponent
4011da177e4SLinus Torvalds
4021da177e4SLinus Torvaldsset EXT_BIAS,		0x3fff			# extended precision bias
4031da177e4SLinus Torvaldsset SGL_BIAS,		0x007f			# single precision bias
4041da177e4SLinus Torvaldsset DBL_BIAS,		0x03ff			# double precision bias
4051da177e4SLinus Torvalds
4061da177e4SLinus Torvaldsset NORM,		0x00			# operand type for STAG/DTAG
4071da177e4SLinus Torvaldsset ZERO,		0x01			# operand type for STAG/DTAG
4081da177e4SLinus Torvaldsset INF,		0x02			# operand type for STAG/DTAG
4091da177e4SLinus Torvaldsset QNAN,		0x03			# operand type for STAG/DTAG
4101da177e4SLinus Torvaldsset DENORM,		0x04			# operand type for STAG/DTAG
4111da177e4SLinus Torvaldsset SNAN,		0x05			# operand type for STAG/DTAG
4121da177e4SLinus Torvaldsset UNNORM,		0x06			# operand type for STAG/DTAG
4131da177e4SLinus Torvalds
4141da177e4SLinus Torvalds##################
4151da177e4SLinus Torvalds# FPSR/FPCR bits #
4161da177e4SLinus Torvalds##################
4171da177e4SLinus Torvaldsset neg_bit,		0x3			# negative result
4181da177e4SLinus Torvaldsset z_bit,		0x2			# zero result
4191da177e4SLinus Torvaldsset inf_bit,		0x1			# infinite result
4201da177e4SLinus Torvaldsset nan_bit,		0x0			# NAN result
4211da177e4SLinus Torvalds
4221da177e4SLinus Torvaldsset q_sn_bit,		0x7			# sign bit of quotient byte
4231da177e4SLinus Torvalds
4241da177e4SLinus Torvaldsset bsun_bit,		7			# branch on unordered
4251da177e4SLinus Torvaldsset snan_bit,		6			# signalling NAN
4261da177e4SLinus Torvaldsset operr_bit,		5			# operand error
4271da177e4SLinus Torvaldsset ovfl_bit,		4			# overflow
4281da177e4SLinus Torvaldsset unfl_bit,		3			# underflow
4291da177e4SLinus Torvaldsset dz_bit,		2			# divide by zero
4301da177e4SLinus Torvaldsset inex2_bit,		1			# inexact result 2
4311da177e4SLinus Torvaldsset inex1_bit,		0			# inexact result 1
4321da177e4SLinus Torvalds
4331da177e4SLinus Torvaldsset aiop_bit,		7			# accrued inexact operation bit
4341da177e4SLinus Torvaldsset aovfl_bit,		6			# accrued overflow bit
4351da177e4SLinus Torvaldsset aunfl_bit,		5			# accrued underflow bit
4361da177e4SLinus Torvaldsset adz_bit,		4			# accrued dz bit
4371da177e4SLinus Torvaldsset ainex_bit,		3			# accrued inexact bit
4381da177e4SLinus Torvalds
4391da177e4SLinus Torvalds#############################
4401da177e4SLinus Torvalds# FPSR individual bit masks #
4411da177e4SLinus Torvalds#############################
4421da177e4SLinus Torvaldsset neg_mask,		0x08000000		# negative bit mask (lw)
4431da177e4SLinus Torvaldsset inf_mask,		0x02000000		# infinity bit mask (lw)
4441da177e4SLinus Torvaldsset z_mask,		0x04000000		# zero bit mask (lw)
4451da177e4SLinus Torvaldsset nan_mask,		0x01000000		# nan bit mask (lw)
4461da177e4SLinus Torvalds
4471da177e4SLinus Torvaldsset neg_bmask,		0x08			# negative bit mask (byte)
4481da177e4SLinus Torvaldsset inf_bmask,		0x02			# infinity bit mask (byte)
4491da177e4SLinus Torvaldsset z_bmask,		0x04			# zero bit mask (byte)
4501da177e4SLinus Torvaldsset nan_bmask,		0x01			# nan bit mask (byte)
4511da177e4SLinus Torvalds
4521da177e4SLinus Torvaldsset bsun_mask,		0x00008000		# bsun exception mask
4531da177e4SLinus Torvaldsset snan_mask,		0x00004000		# snan exception mask
4541da177e4SLinus Torvaldsset operr_mask,		0x00002000		# operr exception mask
4551da177e4SLinus Torvaldsset ovfl_mask,		0x00001000		# overflow exception mask
4561da177e4SLinus Torvaldsset unfl_mask,		0x00000800		# underflow exception mask
4571da177e4SLinus Torvaldsset dz_mask,		0x00000400		# dz exception mask
4581da177e4SLinus Torvaldsset inex2_mask,		0x00000200		# inex2 exception mask
4591da177e4SLinus Torvaldsset inex1_mask,		0x00000100		# inex1 exception mask
4601da177e4SLinus Torvalds
4611da177e4SLinus Torvaldsset aiop_mask,		0x00000080		# accrued illegal operation
4621da177e4SLinus Torvaldsset aovfl_mask,		0x00000040		# accrued overflow
4631da177e4SLinus Torvaldsset aunfl_mask,		0x00000020		# accrued underflow
4641da177e4SLinus Torvaldsset adz_mask,		0x00000010		# accrued divide by zero
4651da177e4SLinus Torvaldsset ainex_mask,		0x00000008		# accrued inexact
4661da177e4SLinus Torvalds
4671da177e4SLinus Torvalds######################################
4681da177e4SLinus Torvalds# FPSR combinations used in the FPSP #
4691da177e4SLinus Torvalds######################################
4701da177e4SLinus Torvaldsset dzinf_mask,		inf_mask+dz_mask+adz_mask
4711da177e4SLinus Torvaldsset opnan_mask,		nan_mask+operr_mask+aiop_mask
4721da177e4SLinus Torvaldsset nzi_mask,		0x01ffffff		#clears N, Z, and I
4731da177e4SLinus Torvaldsset unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
4741da177e4SLinus Torvaldsset unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
4751da177e4SLinus Torvaldsset ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
4761da177e4SLinus Torvaldsset inx1a_mask,		inex1_mask+ainex_mask
4771da177e4SLinus Torvaldsset inx2a_mask,		inex2_mask+ainex_mask
4781da177e4SLinus Torvaldsset snaniop_mask,	nan_mask+snan_mask+aiop_mask
4791da177e4SLinus Torvaldsset snaniop2_mask,	snan_mask+aiop_mask
4801da177e4SLinus Torvaldsset naniop_mask,	nan_mask+aiop_mask
4811da177e4SLinus Torvaldsset neginf_mask,	neg_mask+inf_mask
4821da177e4SLinus Torvaldsset infaiop_mask,	inf_mask+aiop_mask
4831da177e4SLinus Torvaldsset negz_mask,		neg_mask+z_mask
4841da177e4SLinus Torvaldsset opaop_mask,		operr_mask+aiop_mask
4851da177e4SLinus Torvaldsset unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
4861da177e4SLinus Torvaldsset ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
4871da177e4SLinus Torvalds
4881da177e4SLinus Torvalds#########
4891da177e4SLinus Torvalds# misc. #
4901da177e4SLinus Torvalds#########
4911da177e4SLinus Torvaldsset rnd_stky_bit,	29			# stky bit pos in longword
4921da177e4SLinus Torvalds
4931da177e4SLinus Torvaldsset sign_bit,		0x7			# sign bit
4941da177e4SLinus Torvaldsset signan_bit,		0x6			# signalling nan bit
4951da177e4SLinus Torvalds
4961da177e4SLinus Torvaldsset sgl_thresh,		0x3f81			# minimum sgl exponent
4971da177e4SLinus Torvaldsset dbl_thresh,		0x3c01			# minimum dbl exponent
4981da177e4SLinus Torvalds
4991da177e4SLinus Torvaldsset x_mode,		0x0			# extended precision
5001da177e4SLinus Torvaldsset s_mode,		0x4			# single precision
5011da177e4SLinus Torvaldsset d_mode,		0x8			# double precision
5021da177e4SLinus Torvalds
5031da177e4SLinus Torvaldsset rn_mode,		0x0			# round-to-nearest
5041da177e4SLinus Torvaldsset rz_mode,		0x1			# round-to-zero
5051da177e4SLinus Torvaldsset rm_mode,		0x2			# round-tp-minus-infinity
5061da177e4SLinus Torvaldsset rp_mode,		0x3			# round-to-plus-infinity
5071da177e4SLinus Torvalds
5081da177e4SLinus Torvaldsset mantissalen,	64			# length of mantissa in bits
5091da177e4SLinus Torvalds
5101da177e4SLinus Torvaldsset BYTE,		1			# len(byte) == 1 byte
5111da177e4SLinus Torvaldsset WORD,		2			# len(word) == 2 bytes
5121da177e4SLinus Torvaldsset LONG,		4			# len(longword) == 2 bytes
5131da177e4SLinus Torvalds
5141da177e4SLinus Torvaldsset BSUN_VEC,		0xc0			# bsun    vector offset
5151da177e4SLinus Torvaldsset INEX_VEC,		0xc4			# inexact vector offset
5161da177e4SLinus Torvaldsset DZ_VEC,		0xc8			# dz      vector offset
5171da177e4SLinus Torvaldsset UNFL_VEC,		0xcc			# unfl    vector offset
5181da177e4SLinus Torvaldsset OPERR_VEC,		0xd0			# operr   vector offset
5191da177e4SLinus Torvaldsset OVFL_VEC,		0xd4			# ovfl    vector offset
5201da177e4SLinus Torvaldsset SNAN_VEC,		0xd8			# snan    vector offset
5211da177e4SLinus Torvalds
5221da177e4SLinus Torvalds###########################
5231da177e4SLinus Torvalds# SPecial CONDition FLaGs #
5241da177e4SLinus Torvalds###########################
5251da177e4SLinus Torvaldsset ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
5261da177e4SLinus Torvaldsset fbsun_flg,		0x02			# flag bit: bsun exception
5271da177e4SLinus Torvaldsset mia7_flg,		0x04			# flag bit: (a7)+ <ea>
5281da177e4SLinus Torvaldsset mda7_flg,		0x08			# flag bit: -(a7) <ea>
5291da177e4SLinus Torvaldsset fmovm_flg,		0x40			# flag bit: fmovm instruction
5301da177e4SLinus Torvaldsset immed_flg,		0x80			# flag bit: &<data> <ea>
5311da177e4SLinus Torvalds
5321da177e4SLinus Torvaldsset ftrapcc_bit,	0x0
5331da177e4SLinus Torvaldsset fbsun_bit,		0x1
5341da177e4SLinus Torvaldsset mia7_bit,		0x2
5351da177e4SLinus Torvaldsset mda7_bit,		0x3
5361da177e4SLinus Torvaldsset immed_bit,		0x7
5371da177e4SLinus Torvalds
5381da177e4SLinus Torvalds##################################
5391da177e4SLinus Torvalds# TRANSCENDENTAL "LAST-OP" FLAGS #
5401da177e4SLinus Torvalds##################################
5411da177e4SLinus Torvaldsset FMUL_OP,		0x0			# fmul instr performed last
5421da177e4SLinus Torvaldsset FDIV_OP,		0x1			# fdiv performed last
5431da177e4SLinus Torvaldsset FADD_OP,		0x2			# fadd performed last
5441da177e4SLinus Torvaldsset FMOV_OP,		0x3			# fmov performed last
5451da177e4SLinus Torvalds
5461da177e4SLinus Torvalds#############
5471da177e4SLinus Torvalds# CONSTANTS #
5481da177e4SLinus Torvalds#############
5491da177e4SLinus TorvaldsT1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
5501da177e4SLinus TorvaldsT2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
5511da177e4SLinus Torvalds
5521da177e4SLinus TorvaldsPI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
5531da177e4SLinus TorvaldsPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
5541da177e4SLinus Torvalds
5551da177e4SLinus TorvaldsTWOBYPI:
5561da177e4SLinus Torvalds	long		0x3FE45F30,0x6DC9C883
5571da177e4SLinus Torvalds
5581da177e4SLinus Torvalds#########################################################################
5591da177e4SLinus Torvalds# MONADIC TEMPLATE							#
5601da177e4SLinus Torvalds#########################################################################
5611da177e4SLinus Torvalds	global		_fsins_
5621da177e4SLinus Torvalds_fsins_:
5631da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
5641da177e4SLinus Torvalds
5651da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
5661da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
5671da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
5681da177e4SLinus Torvalds
5691da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
5701da177e4SLinus Torvalds
5711da177e4SLinus Torvalds#
5721da177e4SLinus Torvalds#	copy, convert, and tag input argument
5731da177e4SLinus Torvalds#
5741da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
5751da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
5761da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
5771da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
5781da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
5791da177e4SLinus Torvalds	mov.b		%d0,%d1
5801da177e4SLinus Torvalds
5811da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
5821da177e4SLinus Torvalds
5831da177e4SLinus Torvalds	clr.l		%d0
5841da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
5851da177e4SLinus Torvalds
5861da177e4SLinus Torvalds	tst.b		%d1
5871da177e4SLinus Torvalds	bne.b		_L0_2s
5881da177e4SLinus Torvalds	bsr.l		ssin			# operand is a NORM
5891da177e4SLinus Torvalds	bra.b		_L0_6s
5901da177e4SLinus Torvalds_L0_2s:
5911da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
5921da177e4SLinus Torvalds	bne.b		_L0_3s			# no
5931da177e4SLinus Torvalds	bsr.l		src_zero			# yes
5941da177e4SLinus Torvalds	bra.b		_L0_6s
5951da177e4SLinus Torvalds_L0_3s:
5961da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
5971da177e4SLinus Torvalds	bne.b		_L0_4s			# no
5981da177e4SLinus Torvalds	bsr.l		t_operr			# yes
5991da177e4SLinus Torvalds	bra.b		_L0_6s
6001da177e4SLinus Torvalds_L0_4s:
6011da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
6021da177e4SLinus Torvalds	bne.b		_L0_5s			# no
6031da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
6041da177e4SLinus Torvalds	bra.b		_L0_6s
6051da177e4SLinus Torvalds_L0_5s:
6061da177e4SLinus Torvalds	bsr.l		ssind			# operand is a DENORM
6071da177e4SLinus Torvalds_L0_6s:
6081da177e4SLinus Torvalds
6091da177e4SLinus Torvalds#
6101da177e4SLinus Torvalds#	Result is now in FP0
6111da177e4SLinus Torvalds#
6121da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
6131da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
6141da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
6151da177e4SLinus Torvalds	unlk		%a6
6161da177e4SLinus Torvalds	rts
6171da177e4SLinus Torvalds
6181da177e4SLinus Torvalds	global		_fsind_
6191da177e4SLinus Torvalds_fsind_:
6201da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
6211da177e4SLinus Torvalds
6221da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
6231da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
6241da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
6251da177e4SLinus Torvalds
6261da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
6271da177e4SLinus Torvalds
6281da177e4SLinus Torvalds#
6291da177e4SLinus Torvalds#	copy, convert, and tag input argument
6301da177e4SLinus Torvalds#
6311da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
6321da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
6331da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
6341da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
6351da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
6361da177e4SLinus Torvalds	mov.b		%d0,%d1
6371da177e4SLinus Torvalds
6381da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
6391da177e4SLinus Torvalds
6401da177e4SLinus Torvalds	clr.l		%d0
6411da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
6421da177e4SLinus Torvalds
6431da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
6441da177e4SLinus Torvalds	tst.b		%d1
6451da177e4SLinus Torvalds	bne.b		_L0_2d
6461da177e4SLinus Torvalds	bsr.l		ssin			# operand is a NORM
6471da177e4SLinus Torvalds	bra.b		_L0_6d
6481da177e4SLinus Torvalds_L0_2d:
6491da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
6501da177e4SLinus Torvalds	bne.b		_L0_3d			# no
6511da177e4SLinus Torvalds	bsr.l		src_zero			# yes
6521da177e4SLinus Torvalds	bra.b		_L0_6d
6531da177e4SLinus Torvalds_L0_3d:
6541da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
6551da177e4SLinus Torvalds	bne.b		_L0_4d			# no
6561da177e4SLinus Torvalds	bsr.l		t_operr			# yes
6571da177e4SLinus Torvalds	bra.b		_L0_6d
6581da177e4SLinus Torvalds_L0_4d:
6591da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
6601da177e4SLinus Torvalds	bne.b		_L0_5d			# no
6611da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
6621da177e4SLinus Torvalds	bra.b		_L0_6d
6631da177e4SLinus Torvalds_L0_5d:
6641da177e4SLinus Torvalds	bsr.l		ssind			# operand is a DENORM
6651da177e4SLinus Torvalds_L0_6d:
6661da177e4SLinus Torvalds
6671da177e4SLinus Torvalds#
6681da177e4SLinus Torvalds#	Result is now in FP0
6691da177e4SLinus Torvalds#
6701da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
6711da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
6721da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
6731da177e4SLinus Torvalds	unlk		%a6
6741da177e4SLinus Torvalds	rts
6751da177e4SLinus Torvalds
6761da177e4SLinus Torvalds	global		_fsinx_
6771da177e4SLinus Torvalds_fsinx_:
6781da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
6791da177e4SLinus Torvalds
6801da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
6811da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
6821da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
6831da177e4SLinus Torvalds
6841da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
6851da177e4SLinus Torvalds
6861da177e4SLinus Torvalds#
6871da177e4SLinus Torvalds#	copy, convert, and tag input argument
6881da177e4SLinus Torvalds#
6891da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
6901da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
6911da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
6921da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
6931da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
6941da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
6951da177e4SLinus Torvalds	mov.b		%d0,%d1
6961da177e4SLinus Torvalds
6971da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
6981da177e4SLinus Torvalds
6991da177e4SLinus Torvalds	clr.l		%d0
7001da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
7011da177e4SLinus Torvalds
7021da177e4SLinus Torvalds	tst.b		%d1
7031da177e4SLinus Torvalds	bne.b		_L0_2x
7041da177e4SLinus Torvalds	bsr.l		ssin			# operand is a NORM
7051da177e4SLinus Torvalds	bra.b		_L0_6x
7061da177e4SLinus Torvalds_L0_2x:
7071da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
7081da177e4SLinus Torvalds	bne.b		_L0_3x			# no
7091da177e4SLinus Torvalds	bsr.l		src_zero			# yes
7101da177e4SLinus Torvalds	bra.b		_L0_6x
7111da177e4SLinus Torvalds_L0_3x:
7121da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
7131da177e4SLinus Torvalds	bne.b		_L0_4x			# no
7141da177e4SLinus Torvalds	bsr.l		t_operr			# yes
7151da177e4SLinus Torvalds	bra.b		_L0_6x
7161da177e4SLinus Torvalds_L0_4x:
7171da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
7181da177e4SLinus Torvalds	bne.b		_L0_5x			# no
7191da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
7201da177e4SLinus Torvalds	bra.b		_L0_6x
7211da177e4SLinus Torvalds_L0_5x:
7221da177e4SLinus Torvalds	bsr.l		ssind			# operand is a DENORM
7231da177e4SLinus Torvalds_L0_6x:
7241da177e4SLinus Torvalds
7251da177e4SLinus Torvalds#
7261da177e4SLinus Torvalds#	Result is now in FP0
7271da177e4SLinus Torvalds#
7281da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
7291da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
7301da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
7311da177e4SLinus Torvalds	unlk		%a6
7321da177e4SLinus Torvalds	rts
7331da177e4SLinus Torvalds
7341da177e4SLinus Torvalds
7351da177e4SLinus Torvalds#########################################################################
7361da177e4SLinus Torvalds# MONADIC TEMPLATE							#
7371da177e4SLinus Torvalds#########################################################################
7381da177e4SLinus Torvalds	global		_fcoss_
7391da177e4SLinus Torvalds_fcoss_:
7401da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
7411da177e4SLinus Torvalds
7421da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
7431da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
7441da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
7451da177e4SLinus Torvalds
7461da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
7471da177e4SLinus Torvalds
7481da177e4SLinus Torvalds#
7491da177e4SLinus Torvalds#	copy, convert, and tag input argument
7501da177e4SLinus Torvalds#
7511da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
7521da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
7531da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
7541da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
7551da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
7561da177e4SLinus Torvalds	mov.b		%d0,%d1
7571da177e4SLinus Torvalds
7581da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
7591da177e4SLinus Torvalds
7601da177e4SLinus Torvalds	clr.l		%d0
7611da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
7621da177e4SLinus Torvalds
7631da177e4SLinus Torvalds	tst.b		%d1
7641da177e4SLinus Torvalds	bne.b		_L1_2s
7651da177e4SLinus Torvalds	bsr.l		scos			# operand is a NORM
7661da177e4SLinus Torvalds	bra.b		_L1_6s
7671da177e4SLinus Torvalds_L1_2s:
7681da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
7691da177e4SLinus Torvalds	bne.b		_L1_3s			# no
7701da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
7711da177e4SLinus Torvalds	bra.b		_L1_6s
7721da177e4SLinus Torvalds_L1_3s:
7731da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
7741da177e4SLinus Torvalds	bne.b		_L1_4s			# no
7751da177e4SLinus Torvalds	bsr.l		t_operr			# yes
7761da177e4SLinus Torvalds	bra.b		_L1_6s
7771da177e4SLinus Torvalds_L1_4s:
7781da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
7791da177e4SLinus Torvalds	bne.b		_L1_5s			# no
7801da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
7811da177e4SLinus Torvalds	bra.b		_L1_6s
7821da177e4SLinus Torvalds_L1_5s:
7831da177e4SLinus Torvalds	bsr.l		scosd			# operand is a DENORM
7841da177e4SLinus Torvalds_L1_6s:
7851da177e4SLinus Torvalds
7861da177e4SLinus Torvalds#
7871da177e4SLinus Torvalds#	Result is now in FP0
7881da177e4SLinus Torvalds#
7891da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
7901da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
7911da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
7921da177e4SLinus Torvalds	unlk		%a6
7931da177e4SLinus Torvalds	rts
7941da177e4SLinus Torvalds
7951da177e4SLinus Torvalds	global		_fcosd_
7961da177e4SLinus Torvalds_fcosd_:
7971da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
7981da177e4SLinus Torvalds
7991da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
8001da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
8011da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
8021da177e4SLinus Torvalds
8031da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
8041da177e4SLinus Torvalds
8051da177e4SLinus Torvalds#
8061da177e4SLinus Torvalds#	copy, convert, and tag input argument
8071da177e4SLinus Torvalds#
8081da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
8091da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
8101da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
8111da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
8121da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
8131da177e4SLinus Torvalds	mov.b		%d0,%d1
8141da177e4SLinus Torvalds
8151da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
8161da177e4SLinus Torvalds
8171da177e4SLinus Torvalds	clr.l		%d0
8181da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
8191da177e4SLinus Torvalds
8201da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
8211da177e4SLinus Torvalds	tst.b		%d1
8221da177e4SLinus Torvalds	bne.b		_L1_2d
8231da177e4SLinus Torvalds	bsr.l		scos			# operand is a NORM
8241da177e4SLinus Torvalds	bra.b		_L1_6d
8251da177e4SLinus Torvalds_L1_2d:
8261da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
8271da177e4SLinus Torvalds	bne.b		_L1_3d			# no
8281da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
8291da177e4SLinus Torvalds	bra.b		_L1_6d
8301da177e4SLinus Torvalds_L1_3d:
8311da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
8321da177e4SLinus Torvalds	bne.b		_L1_4d			# no
8331da177e4SLinus Torvalds	bsr.l		t_operr			# yes
8341da177e4SLinus Torvalds	bra.b		_L1_6d
8351da177e4SLinus Torvalds_L1_4d:
8361da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
8371da177e4SLinus Torvalds	bne.b		_L1_5d			# no
8381da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
8391da177e4SLinus Torvalds	bra.b		_L1_6d
8401da177e4SLinus Torvalds_L1_5d:
8411da177e4SLinus Torvalds	bsr.l		scosd			# operand is a DENORM
8421da177e4SLinus Torvalds_L1_6d:
8431da177e4SLinus Torvalds
8441da177e4SLinus Torvalds#
8451da177e4SLinus Torvalds#	Result is now in FP0
8461da177e4SLinus Torvalds#
8471da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
8481da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
8491da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
8501da177e4SLinus Torvalds	unlk		%a6
8511da177e4SLinus Torvalds	rts
8521da177e4SLinus Torvalds
8531da177e4SLinus Torvalds	global		_fcosx_
8541da177e4SLinus Torvalds_fcosx_:
8551da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
8561da177e4SLinus Torvalds
8571da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
8581da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
8591da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
8601da177e4SLinus Torvalds
8611da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
8621da177e4SLinus Torvalds
8631da177e4SLinus Torvalds#
8641da177e4SLinus Torvalds#	copy, convert, and tag input argument
8651da177e4SLinus Torvalds#
8661da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
8671da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
8681da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
8691da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
8701da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
8711da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
8721da177e4SLinus Torvalds	mov.b		%d0,%d1
8731da177e4SLinus Torvalds
8741da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
8751da177e4SLinus Torvalds
8761da177e4SLinus Torvalds	clr.l		%d0
8771da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
8781da177e4SLinus Torvalds
8791da177e4SLinus Torvalds	tst.b		%d1
8801da177e4SLinus Torvalds	bne.b		_L1_2x
8811da177e4SLinus Torvalds	bsr.l		scos			# operand is a NORM
8821da177e4SLinus Torvalds	bra.b		_L1_6x
8831da177e4SLinus Torvalds_L1_2x:
8841da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
8851da177e4SLinus Torvalds	bne.b		_L1_3x			# no
8861da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
8871da177e4SLinus Torvalds	bra.b		_L1_6x
8881da177e4SLinus Torvalds_L1_3x:
8891da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
8901da177e4SLinus Torvalds	bne.b		_L1_4x			# no
8911da177e4SLinus Torvalds	bsr.l		t_operr			# yes
8921da177e4SLinus Torvalds	bra.b		_L1_6x
8931da177e4SLinus Torvalds_L1_4x:
8941da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
8951da177e4SLinus Torvalds	bne.b		_L1_5x			# no
8961da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
8971da177e4SLinus Torvalds	bra.b		_L1_6x
8981da177e4SLinus Torvalds_L1_5x:
8991da177e4SLinus Torvalds	bsr.l		scosd			# operand is a DENORM
9001da177e4SLinus Torvalds_L1_6x:
9011da177e4SLinus Torvalds
9021da177e4SLinus Torvalds#
9031da177e4SLinus Torvalds#	Result is now in FP0
9041da177e4SLinus Torvalds#
9051da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
9061da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
9071da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
9081da177e4SLinus Torvalds	unlk		%a6
9091da177e4SLinus Torvalds	rts
9101da177e4SLinus Torvalds
9111da177e4SLinus Torvalds
9121da177e4SLinus Torvalds#########################################################################
9131da177e4SLinus Torvalds# MONADIC TEMPLATE							#
9141da177e4SLinus Torvalds#########################################################################
9151da177e4SLinus Torvalds	global		_fsinhs_
9161da177e4SLinus Torvalds_fsinhs_:
9171da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
9181da177e4SLinus Torvalds
9191da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
9201da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
9211da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
9221da177e4SLinus Torvalds
9231da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
9241da177e4SLinus Torvalds
9251da177e4SLinus Torvalds#
9261da177e4SLinus Torvalds#	copy, convert, and tag input argument
9271da177e4SLinus Torvalds#
9281da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
9291da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
9301da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
9311da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
9321da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
9331da177e4SLinus Torvalds	mov.b		%d0,%d1
9341da177e4SLinus Torvalds
9351da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
9361da177e4SLinus Torvalds
9371da177e4SLinus Torvalds	clr.l		%d0
9381da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
9391da177e4SLinus Torvalds
9401da177e4SLinus Torvalds	tst.b		%d1
9411da177e4SLinus Torvalds	bne.b		_L2_2s
9421da177e4SLinus Torvalds	bsr.l		ssinh			# operand is a NORM
9431da177e4SLinus Torvalds	bra.b		_L2_6s
9441da177e4SLinus Torvalds_L2_2s:
9451da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
9461da177e4SLinus Torvalds	bne.b		_L2_3s			# no
9471da177e4SLinus Torvalds	bsr.l		src_zero			# yes
9481da177e4SLinus Torvalds	bra.b		_L2_6s
9491da177e4SLinus Torvalds_L2_3s:
9501da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
9511da177e4SLinus Torvalds	bne.b		_L2_4s			# no
9521da177e4SLinus Torvalds	bsr.l		src_inf			# yes
9531da177e4SLinus Torvalds	bra.b		_L2_6s
9541da177e4SLinus Torvalds_L2_4s:
9551da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
9561da177e4SLinus Torvalds	bne.b		_L2_5s			# no
9571da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
9581da177e4SLinus Torvalds	bra.b		_L2_6s
9591da177e4SLinus Torvalds_L2_5s:
9601da177e4SLinus Torvalds	bsr.l		ssinhd			# operand is a DENORM
9611da177e4SLinus Torvalds_L2_6s:
9621da177e4SLinus Torvalds
9631da177e4SLinus Torvalds#
9641da177e4SLinus Torvalds#	Result is now in FP0
9651da177e4SLinus Torvalds#
9661da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
9671da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
9681da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
9691da177e4SLinus Torvalds	unlk		%a6
9701da177e4SLinus Torvalds	rts
9711da177e4SLinus Torvalds
9721da177e4SLinus Torvalds	global		_fsinhd_
9731da177e4SLinus Torvalds_fsinhd_:
9741da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
9751da177e4SLinus Torvalds
9761da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
9771da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
9781da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
9791da177e4SLinus Torvalds
9801da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
9811da177e4SLinus Torvalds
9821da177e4SLinus Torvalds#
9831da177e4SLinus Torvalds#	copy, convert, and tag input argument
9841da177e4SLinus Torvalds#
9851da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
9861da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
9871da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
9881da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
9891da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
9901da177e4SLinus Torvalds	mov.b		%d0,%d1
9911da177e4SLinus Torvalds
9921da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
9931da177e4SLinus Torvalds
9941da177e4SLinus Torvalds	clr.l		%d0
9951da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
9961da177e4SLinus Torvalds
9971da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
9981da177e4SLinus Torvalds	tst.b		%d1
9991da177e4SLinus Torvalds	bne.b		_L2_2d
10001da177e4SLinus Torvalds	bsr.l		ssinh			# operand is a NORM
10011da177e4SLinus Torvalds	bra.b		_L2_6d
10021da177e4SLinus Torvalds_L2_2d:
10031da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
10041da177e4SLinus Torvalds	bne.b		_L2_3d			# no
10051da177e4SLinus Torvalds	bsr.l		src_zero			# yes
10061da177e4SLinus Torvalds	bra.b		_L2_6d
10071da177e4SLinus Torvalds_L2_3d:
10081da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
10091da177e4SLinus Torvalds	bne.b		_L2_4d			# no
10101da177e4SLinus Torvalds	bsr.l		src_inf			# yes
10111da177e4SLinus Torvalds	bra.b		_L2_6d
10121da177e4SLinus Torvalds_L2_4d:
10131da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
10141da177e4SLinus Torvalds	bne.b		_L2_5d			# no
10151da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
10161da177e4SLinus Torvalds	bra.b		_L2_6d
10171da177e4SLinus Torvalds_L2_5d:
10181da177e4SLinus Torvalds	bsr.l		ssinhd			# operand is a DENORM
10191da177e4SLinus Torvalds_L2_6d:
10201da177e4SLinus Torvalds
10211da177e4SLinus Torvalds#
10221da177e4SLinus Torvalds#	Result is now in FP0
10231da177e4SLinus Torvalds#
10241da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
10251da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
10261da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
10271da177e4SLinus Torvalds	unlk		%a6
10281da177e4SLinus Torvalds	rts
10291da177e4SLinus Torvalds
10301da177e4SLinus Torvalds	global		_fsinhx_
10311da177e4SLinus Torvalds_fsinhx_:
10321da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
10331da177e4SLinus Torvalds
10341da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
10351da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
10361da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
10371da177e4SLinus Torvalds
10381da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
10391da177e4SLinus Torvalds
10401da177e4SLinus Torvalds#
10411da177e4SLinus Torvalds#	copy, convert, and tag input argument
10421da177e4SLinus Torvalds#
10431da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
10441da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
10451da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
10461da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
10471da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
10481da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
10491da177e4SLinus Torvalds	mov.b		%d0,%d1
10501da177e4SLinus Torvalds
10511da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
10521da177e4SLinus Torvalds
10531da177e4SLinus Torvalds	clr.l		%d0
10541da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
10551da177e4SLinus Torvalds
10561da177e4SLinus Torvalds	tst.b		%d1
10571da177e4SLinus Torvalds	bne.b		_L2_2x
10581da177e4SLinus Torvalds	bsr.l		ssinh			# operand is a NORM
10591da177e4SLinus Torvalds	bra.b		_L2_6x
10601da177e4SLinus Torvalds_L2_2x:
10611da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
10621da177e4SLinus Torvalds	bne.b		_L2_3x			# no
10631da177e4SLinus Torvalds	bsr.l		src_zero			# yes
10641da177e4SLinus Torvalds	bra.b		_L2_6x
10651da177e4SLinus Torvalds_L2_3x:
10661da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
10671da177e4SLinus Torvalds	bne.b		_L2_4x			# no
10681da177e4SLinus Torvalds	bsr.l		src_inf			# yes
10691da177e4SLinus Torvalds	bra.b		_L2_6x
10701da177e4SLinus Torvalds_L2_4x:
10711da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
10721da177e4SLinus Torvalds	bne.b		_L2_5x			# no
10731da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
10741da177e4SLinus Torvalds	bra.b		_L2_6x
10751da177e4SLinus Torvalds_L2_5x:
10761da177e4SLinus Torvalds	bsr.l		ssinhd			# operand is a DENORM
10771da177e4SLinus Torvalds_L2_6x:
10781da177e4SLinus Torvalds
10791da177e4SLinus Torvalds#
10801da177e4SLinus Torvalds#	Result is now in FP0
10811da177e4SLinus Torvalds#
10821da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
10831da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
10841da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
10851da177e4SLinus Torvalds	unlk		%a6
10861da177e4SLinus Torvalds	rts
10871da177e4SLinus Torvalds
10881da177e4SLinus Torvalds
10891da177e4SLinus Torvalds#########################################################################
10901da177e4SLinus Torvalds# MONADIC TEMPLATE							#
10911da177e4SLinus Torvalds#########################################################################
10921da177e4SLinus Torvalds	global		_flognp1s_
10931da177e4SLinus Torvalds_flognp1s_:
10941da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
10951da177e4SLinus Torvalds
10961da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
10971da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
10981da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
10991da177e4SLinus Torvalds
11001da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
11011da177e4SLinus Torvalds
11021da177e4SLinus Torvalds#
11031da177e4SLinus Torvalds#	copy, convert, and tag input argument
11041da177e4SLinus Torvalds#
11051da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
11061da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
11071da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
11081da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
11091da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
11101da177e4SLinus Torvalds	mov.b		%d0,%d1
11111da177e4SLinus Torvalds
11121da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
11131da177e4SLinus Torvalds
11141da177e4SLinus Torvalds	clr.l		%d0
11151da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
11161da177e4SLinus Torvalds
11171da177e4SLinus Torvalds	tst.b		%d1
11181da177e4SLinus Torvalds	bne.b		_L3_2s
11191da177e4SLinus Torvalds	bsr.l		slognp1			# operand is a NORM
11201da177e4SLinus Torvalds	bra.b		_L3_6s
11211da177e4SLinus Torvalds_L3_2s:
11221da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
11231da177e4SLinus Torvalds	bne.b		_L3_3s			# no
11241da177e4SLinus Torvalds	bsr.l		src_zero			# yes
11251da177e4SLinus Torvalds	bra.b		_L3_6s
11261da177e4SLinus Torvalds_L3_3s:
11271da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
11281da177e4SLinus Torvalds	bne.b		_L3_4s			# no
11291da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
11301da177e4SLinus Torvalds	bra.b		_L3_6s
11311da177e4SLinus Torvalds_L3_4s:
11321da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
11331da177e4SLinus Torvalds	bne.b		_L3_5s			# no
11341da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
11351da177e4SLinus Torvalds	bra.b		_L3_6s
11361da177e4SLinus Torvalds_L3_5s:
11371da177e4SLinus Torvalds	bsr.l		slognp1d			# operand is a DENORM
11381da177e4SLinus Torvalds_L3_6s:
11391da177e4SLinus Torvalds
11401da177e4SLinus Torvalds#
11411da177e4SLinus Torvalds#	Result is now in FP0
11421da177e4SLinus Torvalds#
11431da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
11441da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
11451da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
11461da177e4SLinus Torvalds	unlk		%a6
11471da177e4SLinus Torvalds	rts
11481da177e4SLinus Torvalds
11491da177e4SLinus Torvalds	global		_flognp1d_
11501da177e4SLinus Torvalds_flognp1d_:
11511da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
11521da177e4SLinus Torvalds
11531da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
11541da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
11551da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
11561da177e4SLinus Torvalds
11571da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
11581da177e4SLinus Torvalds
11591da177e4SLinus Torvalds#
11601da177e4SLinus Torvalds#	copy, convert, and tag input argument
11611da177e4SLinus Torvalds#
11621da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
11631da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
11641da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
11651da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
11661da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
11671da177e4SLinus Torvalds	mov.b		%d0,%d1
11681da177e4SLinus Torvalds
11691da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
11701da177e4SLinus Torvalds
11711da177e4SLinus Torvalds	clr.l		%d0
11721da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
11731da177e4SLinus Torvalds
11741da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
11751da177e4SLinus Torvalds	tst.b		%d1
11761da177e4SLinus Torvalds	bne.b		_L3_2d
11771da177e4SLinus Torvalds	bsr.l		slognp1			# operand is a NORM
11781da177e4SLinus Torvalds	bra.b		_L3_6d
11791da177e4SLinus Torvalds_L3_2d:
11801da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
11811da177e4SLinus Torvalds	bne.b		_L3_3d			# no
11821da177e4SLinus Torvalds	bsr.l		src_zero			# yes
11831da177e4SLinus Torvalds	bra.b		_L3_6d
11841da177e4SLinus Torvalds_L3_3d:
11851da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
11861da177e4SLinus Torvalds	bne.b		_L3_4d			# no
11871da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
11881da177e4SLinus Torvalds	bra.b		_L3_6d
11891da177e4SLinus Torvalds_L3_4d:
11901da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
11911da177e4SLinus Torvalds	bne.b		_L3_5d			# no
11921da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
11931da177e4SLinus Torvalds	bra.b		_L3_6d
11941da177e4SLinus Torvalds_L3_5d:
11951da177e4SLinus Torvalds	bsr.l		slognp1d			# operand is a DENORM
11961da177e4SLinus Torvalds_L3_6d:
11971da177e4SLinus Torvalds
11981da177e4SLinus Torvalds#
11991da177e4SLinus Torvalds#	Result is now in FP0
12001da177e4SLinus Torvalds#
12011da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
12021da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
12031da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
12041da177e4SLinus Torvalds	unlk		%a6
12051da177e4SLinus Torvalds	rts
12061da177e4SLinus Torvalds
12071da177e4SLinus Torvalds	global		_flognp1x_
12081da177e4SLinus Torvalds_flognp1x_:
12091da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
12101da177e4SLinus Torvalds
12111da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
12121da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
12131da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
12141da177e4SLinus Torvalds
12151da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
12161da177e4SLinus Torvalds
12171da177e4SLinus Torvalds#
12181da177e4SLinus Torvalds#	copy, convert, and tag input argument
12191da177e4SLinus Torvalds#
12201da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
12211da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
12221da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
12231da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
12241da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
12251da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
12261da177e4SLinus Torvalds	mov.b		%d0,%d1
12271da177e4SLinus Torvalds
12281da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
12291da177e4SLinus Torvalds
12301da177e4SLinus Torvalds	clr.l		%d0
12311da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
12321da177e4SLinus Torvalds
12331da177e4SLinus Torvalds	tst.b		%d1
12341da177e4SLinus Torvalds	bne.b		_L3_2x
12351da177e4SLinus Torvalds	bsr.l		slognp1			# operand is a NORM
12361da177e4SLinus Torvalds	bra.b		_L3_6x
12371da177e4SLinus Torvalds_L3_2x:
12381da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
12391da177e4SLinus Torvalds	bne.b		_L3_3x			# no
12401da177e4SLinus Torvalds	bsr.l		src_zero			# yes
12411da177e4SLinus Torvalds	bra.b		_L3_6x
12421da177e4SLinus Torvalds_L3_3x:
12431da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
12441da177e4SLinus Torvalds	bne.b		_L3_4x			# no
12451da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
12461da177e4SLinus Torvalds	bra.b		_L3_6x
12471da177e4SLinus Torvalds_L3_4x:
12481da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
12491da177e4SLinus Torvalds	bne.b		_L3_5x			# no
12501da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
12511da177e4SLinus Torvalds	bra.b		_L3_6x
12521da177e4SLinus Torvalds_L3_5x:
12531da177e4SLinus Torvalds	bsr.l		slognp1d			# operand is a DENORM
12541da177e4SLinus Torvalds_L3_6x:
12551da177e4SLinus Torvalds
12561da177e4SLinus Torvalds#
12571da177e4SLinus Torvalds#	Result is now in FP0
12581da177e4SLinus Torvalds#
12591da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
12601da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
12611da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
12621da177e4SLinus Torvalds	unlk		%a6
12631da177e4SLinus Torvalds	rts
12641da177e4SLinus Torvalds
12651da177e4SLinus Torvalds
12661da177e4SLinus Torvalds#########################################################################
12671da177e4SLinus Torvalds# MONADIC TEMPLATE							#
12681da177e4SLinus Torvalds#########################################################################
12691da177e4SLinus Torvalds	global		_fetoxm1s_
12701da177e4SLinus Torvalds_fetoxm1s_:
12711da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
12721da177e4SLinus Torvalds
12731da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
12741da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
12751da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
12761da177e4SLinus Torvalds
12771da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
12781da177e4SLinus Torvalds
12791da177e4SLinus Torvalds#
12801da177e4SLinus Torvalds#	copy, convert, and tag input argument
12811da177e4SLinus Torvalds#
12821da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
12831da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
12841da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
12851da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
12861da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
12871da177e4SLinus Torvalds	mov.b		%d0,%d1
12881da177e4SLinus Torvalds
12891da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
12901da177e4SLinus Torvalds
12911da177e4SLinus Torvalds	clr.l		%d0
12921da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
12931da177e4SLinus Torvalds
12941da177e4SLinus Torvalds	tst.b		%d1
12951da177e4SLinus Torvalds	bne.b		_L4_2s
12961da177e4SLinus Torvalds	bsr.l		setoxm1			# operand is a NORM
12971da177e4SLinus Torvalds	bra.b		_L4_6s
12981da177e4SLinus Torvalds_L4_2s:
12991da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
13001da177e4SLinus Torvalds	bne.b		_L4_3s			# no
13011da177e4SLinus Torvalds	bsr.l		src_zero			# yes
13021da177e4SLinus Torvalds	bra.b		_L4_6s
13031da177e4SLinus Torvalds_L4_3s:
13041da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
13051da177e4SLinus Torvalds	bne.b		_L4_4s			# no
13061da177e4SLinus Torvalds	bsr.l		setoxm1i			# yes
13071da177e4SLinus Torvalds	bra.b		_L4_6s
13081da177e4SLinus Torvalds_L4_4s:
13091da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
13101da177e4SLinus Torvalds	bne.b		_L4_5s			# no
13111da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
13121da177e4SLinus Torvalds	bra.b		_L4_6s
13131da177e4SLinus Torvalds_L4_5s:
13141da177e4SLinus Torvalds	bsr.l		setoxm1d			# operand is a DENORM
13151da177e4SLinus Torvalds_L4_6s:
13161da177e4SLinus Torvalds
13171da177e4SLinus Torvalds#
13181da177e4SLinus Torvalds#	Result is now in FP0
13191da177e4SLinus Torvalds#
13201da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
13211da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
13221da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
13231da177e4SLinus Torvalds	unlk		%a6
13241da177e4SLinus Torvalds	rts
13251da177e4SLinus Torvalds
13261da177e4SLinus Torvalds	global		_fetoxm1d_
13271da177e4SLinus Torvalds_fetoxm1d_:
13281da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
13291da177e4SLinus Torvalds
13301da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
13311da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
13321da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
13331da177e4SLinus Torvalds
13341da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
13351da177e4SLinus Torvalds
13361da177e4SLinus Torvalds#
13371da177e4SLinus Torvalds#	copy, convert, and tag input argument
13381da177e4SLinus Torvalds#
13391da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
13401da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
13411da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
13421da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
13431da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
13441da177e4SLinus Torvalds	mov.b		%d0,%d1
13451da177e4SLinus Torvalds
13461da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
13471da177e4SLinus Torvalds
13481da177e4SLinus Torvalds	clr.l		%d0
13491da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
13501da177e4SLinus Torvalds
13511da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
13521da177e4SLinus Torvalds	tst.b		%d1
13531da177e4SLinus Torvalds	bne.b		_L4_2d
13541da177e4SLinus Torvalds	bsr.l		setoxm1			# operand is a NORM
13551da177e4SLinus Torvalds	bra.b		_L4_6d
13561da177e4SLinus Torvalds_L4_2d:
13571da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
13581da177e4SLinus Torvalds	bne.b		_L4_3d			# no
13591da177e4SLinus Torvalds	bsr.l		src_zero			# yes
13601da177e4SLinus Torvalds	bra.b		_L4_6d
13611da177e4SLinus Torvalds_L4_3d:
13621da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
13631da177e4SLinus Torvalds	bne.b		_L4_4d			# no
13641da177e4SLinus Torvalds	bsr.l		setoxm1i			# yes
13651da177e4SLinus Torvalds	bra.b		_L4_6d
13661da177e4SLinus Torvalds_L4_4d:
13671da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
13681da177e4SLinus Torvalds	bne.b		_L4_5d			# no
13691da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
13701da177e4SLinus Torvalds	bra.b		_L4_6d
13711da177e4SLinus Torvalds_L4_5d:
13721da177e4SLinus Torvalds	bsr.l		setoxm1d			# operand is a DENORM
13731da177e4SLinus Torvalds_L4_6d:
13741da177e4SLinus Torvalds
13751da177e4SLinus Torvalds#
13761da177e4SLinus Torvalds#	Result is now in FP0
13771da177e4SLinus Torvalds#
13781da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
13791da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
13801da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
13811da177e4SLinus Torvalds	unlk		%a6
13821da177e4SLinus Torvalds	rts
13831da177e4SLinus Torvalds
13841da177e4SLinus Torvalds	global		_fetoxm1x_
13851da177e4SLinus Torvalds_fetoxm1x_:
13861da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
13871da177e4SLinus Torvalds
13881da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
13891da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
13901da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
13911da177e4SLinus Torvalds
13921da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
13931da177e4SLinus Torvalds
13941da177e4SLinus Torvalds#
13951da177e4SLinus Torvalds#	copy, convert, and tag input argument
13961da177e4SLinus Torvalds#
13971da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
13981da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
13991da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
14001da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
14011da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
14021da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
14031da177e4SLinus Torvalds	mov.b		%d0,%d1
14041da177e4SLinus Torvalds
14051da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
14061da177e4SLinus Torvalds
14071da177e4SLinus Torvalds	clr.l		%d0
14081da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
14091da177e4SLinus Torvalds
14101da177e4SLinus Torvalds	tst.b		%d1
14111da177e4SLinus Torvalds	bne.b		_L4_2x
14121da177e4SLinus Torvalds	bsr.l		setoxm1			# operand is a NORM
14131da177e4SLinus Torvalds	bra.b		_L4_6x
14141da177e4SLinus Torvalds_L4_2x:
14151da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
14161da177e4SLinus Torvalds	bne.b		_L4_3x			# no
14171da177e4SLinus Torvalds	bsr.l		src_zero			# yes
14181da177e4SLinus Torvalds	bra.b		_L4_6x
14191da177e4SLinus Torvalds_L4_3x:
14201da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
14211da177e4SLinus Torvalds	bne.b		_L4_4x			# no
14221da177e4SLinus Torvalds	bsr.l		setoxm1i			# yes
14231da177e4SLinus Torvalds	bra.b		_L4_6x
14241da177e4SLinus Torvalds_L4_4x:
14251da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
14261da177e4SLinus Torvalds	bne.b		_L4_5x			# no
14271da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
14281da177e4SLinus Torvalds	bra.b		_L4_6x
14291da177e4SLinus Torvalds_L4_5x:
14301da177e4SLinus Torvalds	bsr.l		setoxm1d			# operand is a DENORM
14311da177e4SLinus Torvalds_L4_6x:
14321da177e4SLinus Torvalds
14331da177e4SLinus Torvalds#
14341da177e4SLinus Torvalds#	Result is now in FP0
14351da177e4SLinus Torvalds#
14361da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
14371da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
14381da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
14391da177e4SLinus Torvalds	unlk		%a6
14401da177e4SLinus Torvalds	rts
14411da177e4SLinus Torvalds
14421da177e4SLinus Torvalds
14431da177e4SLinus Torvalds#########################################################################
14441da177e4SLinus Torvalds# MONADIC TEMPLATE							#
14451da177e4SLinus Torvalds#########################################################################
14461da177e4SLinus Torvalds	global		_ftanhs_
14471da177e4SLinus Torvalds_ftanhs_:
14481da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
14491da177e4SLinus Torvalds
14501da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
14511da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
14521da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
14531da177e4SLinus Torvalds
14541da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
14551da177e4SLinus Torvalds
14561da177e4SLinus Torvalds#
14571da177e4SLinus Torvalds#	copy, convert, and tag input argument
14581da177e4SLinus Torvalds#
14591da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
14601da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
14611da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
14621da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
14631da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
14641da177e4SLinus Torvalds	mov.b		%d0,%d1
14651da177e4SLinus Torvalds
14661da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
14671da177e4SLinus Torvalds
14681da177e4SLinus Torvalds	clr.l		%d0
14691da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
14701da177e4SLinus Torvalds
14711da177e4SLinus Torvalds	tst.b		%d1
14721da177e4SLinus Torvalds	bne.b		_L5_2s
14731da177e4SLinus Torvalds	bsr.l		stanh			# operand is a NORM
14741da177e4SLinus Torvalds	bra.b		_L5_6s
14751da177e4SLinus Torvalds_L5_2s:
14761da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
14771da177e4SLinus Torvalds	bne.b		_L5_3s			# no
14781da177e4SLinus Torvalds	bsr.l		src_zero			# yes
14791da177e4SLinus Torvalds	bra.b		_L5_6s
14801da177e4SLinus Torvalds_L5_3s:
14811da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
14821da177e4SLinus Torvalds	bne.b		_L5_4s			# no
14831da177e4SLinus Torvalds	bsr.l		src_one			# yes
14841da177e4SLinus Torvalds	bra.b		_L5_6s
14851da177e4SLinus Torvalds_L5_4s:
14861da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
14871da177e4SLinus Torvalds	bne.b		_L5_5s			# no
14881da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
14891da177e4SLinus Torvalds	bra.b		_L5_6s
14901da177e4SLinus Torvalds_L5_5s:
14911da177e4SLinus Torvalds	bsr.l		stanhd			# operand is a DENORM
14921da177e4SLinus Torvalds_L5_6s:
14931da177e4SLinus Torvalds
14941da177e4SLinus Torvalds#
14951da177e4SLinus Torvalds#	Result is now in FP0
14961da177e4SLinus Torvalds#
14971da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
14981da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
14991da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
15001da177e4SLinus Torvalds	unlk		%a6
15011da177e4SLinus Torvalds	rts
15021da177e4SLinus Torvalds
15031da177e4SLinus Torvalds	global		_ftanhd_
15041da177e4SLinus Torvalds_ftanhd_:
15051da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
15061da177e4SLinus Torvalds
15071da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
15081da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
15091da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
15101da177e4SLinus Torvalds
15111da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
15121da177e4SLinus Torvalds
15131da177e4SLinus Torvalds#
15141da177e4SLinus Torvalds#	copy, convert, and tag input argument
15151da177e4SLinus Torvalds#
15161da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
15171da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
15181da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
15191da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
15201da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
15211da177e4SLinus Torvalds	mov.b		%d0,%d1
15221da177e4SLinus Torvalds
15231da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
15241da177e4SLinus Torvalds
15251da177e4SLinus Torvalds	clr.l		%d0
15261da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
15271da177e4SLinus Torvalds
15281da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
15291da177e4SLinus Torvalds	tst.b		%d1
15301da177e4SLinus Torvalds	bne.b		_L5_2d
15311da177e4SLinus Torvalds	bsr.l		stanh			# operand is a NORM
15321da177e4SLinus Torvalds	bra.b		_L5_6d
15331da177e4SLinus Torvalds_L5_2d:
15341da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
15351da177e4SLinus Torvalds	bne.b		_L5_3d			# no
15361da177e4SLinus Torvalds	bsr.l		src_zero			# yes
15371da177e4SLinus Torvalds	bra.b		_L5_6d
15381da177e4SLinus Torvalds_L5_3d:
15391da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
15401da177e4SLinus Torvalds	bne.b		_L5_4d			# no
15411da177e4SLinus Torvalds	bsr.l		src_one			# yes
15421da177e4SLinus Torvalds	bra.b		_L5_6d
15431da177e4SLinus Torvalds_L5_4d:
15441da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
15451da177e4SLinus Torvalds	bne.b		_L5_5d			# no
15461da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
15471da177e4SLinus Torvalds	bra.b		_L5_6d
15481da177e4SLinus Torvalds_L5_5d:
15491da177e4SLinus Torvalds	bsr.l		stanhd			# operand is a DENORM
15501da177e4SLinus Torvalds_L5_6d:
15511da177e4SLinus Torvalds
15521da177e4SLinus Torvalds#
15531da177e4SLinus Torvalds#	Result is now in FP0
15541da177e4SLinus Torvalds#
15551da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
15561da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
15571da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
15581da177e4SLinus Torvalds	unlk		%a6
15591da177e4SLinus Torvalds	rts
15601da177e4SLinus Torvalds
15611da177e4SLinus Torvalds	global		_ftanhx_
15621da177e4SLinus Torvalds_ftanhx_:
15631da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
15641da177e4SLinus Torvalds
15651da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
15661da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
15671da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
15681da177e4SLinus Torvalds
15691da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
15701da177e4SLinus Torvalds
15711da177e4SLinus Torvalds#
15721da177e4SLinus Torvalds#	copy, convert, and tag input argument
15731da177e4SLinus Torvalds#
15741da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
15751da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
15761da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
15771da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
15781da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
15791da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
15801da177e4SLinus Torvalds	mov.b		%d0,%d1
15811da177e4SLinus Torvalds
15821da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
15831da177e4SLinus Torvalds
15841da177e4SLinus Torvalds	clr.l		%d0
15851da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
15861da177e4SLinus Torvalds
15871da177e4SLinus Torvalds	tst.b		%d1
15881da177e4SLinus Torvalds	bne.b		_L5_2x
15891da177e4SLinus Torvalds	bsr.l		stanh			# operand is a NORM
15901da177e4SLinus Torvalds	bra.b		_L5_6x
15911da177e4SLinus Torvalds_L5_2x:
15921da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
15931da177e4SLinus Torvalds	bne.b		_L5_3x			# no
15941da177e4SLinus Torvalds	bsr.l		src_zero			# yes
15951da177e4SLinus Torvalds	bra.b		_L5_6x
15961da177e4SLinus Torvalds_L5_3x:
15971da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
15981da177e4SLinus Torvalds	bne.b		_L5_4x			# no
15991da177e4SLinus Torvalds	bsr.l		src_one			# yes
16001da177e4SLinus Torvalds	bra.b		_L5_6x
16011da177e4SLinus Torvalds_L5_4x:
16021da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
16031da177e4SLinus Torvalds	bne.b		_L5_5x			# no
16041da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
16051da177e4SLinus Torvalds	bra.b		_L5_6x
16061da177e4SLinus Torvalds_L5_5x:
16071da177e4SLinus Torvalds	bsr.l		stanhd			# operand is a DENORM
16081da177e4SLinus Torvalds_L5_6x:
16091da177e4SLinus Torvalds
16101da177e4SLinus Torvalds#
16111da177e4SLinus Torvalds#	Result is now in FP0
16121da177e4SLinus Torvalds#
16131da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
16141da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
16151da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
16161da177e4SLinus Torvalds	unlk		%a6
16171da177e4SLinus Torvalds	rts
16181da177e4SLinus Torvalds
16191da177e4SLinus Torvalds
16201da177e4SLinus Torvalds#########################################################################
16211da177e4SLinus Torvalds# MONADIC TEMPLATE							#
16221da177e4SLinus Torvalds#########################################################################
16231da177e4SLinus Torvalds	global		_fatans_
16241da177e4SLinus Torvalds_fatans_:
16251da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
16261da177e4SLinus Torvalds
16271da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
16281da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
16291da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
16301da177e4SLinus Torvalds
16311da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
16321da177e4SLinus Torvalds
16331da177e4SLinus Torvalds#
16341da177e4SLinus Torvalds#	copy, convert, and tag input argument
16351da177e4SLinus Torvalds#
16361da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
16371da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
16381da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
16391da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
16401da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
16411da177e4SLinus Torvalds	mov.b		%d0,%d1
16421da177e4SLinus Torvalds
16431da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
16441da177e4SLinus Torvalds
16451da177e4SLinus Torvalds	clr.l		%d0
16461da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
16471da177e4SLinus Torvalds
16481da177e4SLinus Torvalds	tst.b		%d1
16491da177e4SLinus Torvalds	bne.b		_L6_2s
16501da177e4SLinus Torvalds	bsr.l		satan			# operand is a NORM
16511da177e4SLinus Torvalds	bra.b		_L6_6s
16521da177e4SLinus Torvalds_L6_2s:
16531da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
16541da177e4SLinus Torvalds	bne.b		_L6_3s			# no
16551da177e4SLinus Torvalds	bsr.l		src_zero			# yes
16561da177e4SLinus Torvalds	bra.b		_L6_6s
16571da177e4SLinus Torvalds_L6_3s:
16581da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
16591da177e4SLinus Torvalds	bne.b		_L6_4s			# no
16601da177e4SLinus Torvalds	bsr.l		spi_2			# yes
16611da177e4SLinus Torvalds	bra.b		_L6_6s
16621da177e4SLinus Torvalds_L6_4s:
16631da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
16641da177e4SLinus Torvalds	bne.b		_L6_5s			# no
16651da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
16661da177e4SLinus Torvalds	bra.b		_L6_6s
16671da177e4SLinus Torvalds_L6_5s:
16681da177e4SLinus Torvalds	bsr.l		satand			# operand is a DENORM
16691da177e4SLinus Torvalds_L6_6s:
16701da177e4SLinus Torvalds
16711da177e4SLinus Torvalds#
16721da177e4SLinus Torvalds#	Result is now in FP0
16731da177e4SLinus Torvalds#
16741da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
16751da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
16761da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
16771da177e4SLinus Torvalds	unlk		%a6
16781da177e4SLinus Torvalds	rts
16791da177e4SLinus Torvalds
16801da177e4SLinus Torvalds	global		_fatand_
16811da177e4SLinus Torvalds_fatand_:
16821da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
16831da177e4SLinus Torvalds
16841da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
16851da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
16861da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
16871da177e4SLinus Torvalds
16881da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
16891da177e4SLinus Torvalds
16901da177e4SLinus Torvalds#
16911da177e4SLinus Torvalds#	copy, convert, and tag input argument
16921da177e4SLinus Torvalds#
16931da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
16941da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
16951da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
16961da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
16971da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
16981da177e4SLinus Torvalds	mov.b		%d0,%d1
16991da177e4SLinus Torvalds
17001da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
17011da177e4SLinus Torvalds
17021da177e4SLinus Torvalds	clr.l		%d0
17031da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
17041da177e4SLinus Torvalds
17051da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
17061da177e4SLinus Torvalds	tst.b		%d1
17071da177e4SLinus Torvalds	bne.b		_L6_2d
17081da177e4SLinus Torvalds	bsr.l		satan			# operand is a NORM
17091da177e4SLinus Torvalds	bra.b		_L6_6d
17101da177e4SLinus Torvalds_L6_2d:
17111da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
17121da177e4SLinus Torvalds	bne.b		_L6_3d			# no
17131da177e4SLinus Torvalds	bsr.l		src_zero			# yes
17141da177e4SLinus Torvalds	bra.b		_L6_6d
17151da177e4SLinus Torvalds_L6_3d:
17161da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
17171da177e4SLinus Torvalds	bne.b		_L6_4d			# no
17181da177e4SLinus Torvalds	bsr.l		spi_2			# yes
17191da177e4SLinus Torvalds	bra.b		_L6_6d
17201da177e4SLinus Torvalds_L6_4d:
17211da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
17221da177e4SLinus Torvalds	bne.b		_L6_5d			# no
17231da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
17241da177e4SLinus Torvalds	bra.b		_L6_6d
17251da177e4SLinus Torvalds_L6_5d:
17261da177e4SLinus Torvalds	bsr.l		satand			# operand is a DENORM
17271da177e4SLinus Torvalds_L6_6d:
17281da177e4SLinus Torvalds
17291da177e4SLinus Torvalds#
17301da177e4SLinus Torvalds#	Result is now in FP0
17311da177e4SLinus Torvalds#
17321da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
17331da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
17341da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
17351da177e4SLinus Torvalds	unlk		%a6
17361da177e4SLinus Torvalds	rts
17371da177e4SLinus Torvalds
17381da177e4SLinus Torvalds	global		_fatanx_
17391da177e4SLinus Torvalds_fatanx_:
17401da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
17411da177e4SLinus Torvalds
17421da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
17431da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
17441da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
17451da177e4SLinus Torvalds
17461da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
17471da177e4SLinus Torvalds
17481da177e4SLinus Torvalds#
17491da177e4SLinus Torvalds#	copy, convert, and tag input argument
17501da177e4SLinus Torvalds#
17511da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
17521da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
17531da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
17541da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
17551da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
17561da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
17571da177e4SLinus Torvalds	mov.b		%d0,%d1
17581da177e4SLinus Torvalds
17591da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
17601da177e4SLinus Torvalds
17611da177e4SLinus Torvalds	clr.l		%d0
17621da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
17631da177e4SLinus Torvalds
17641da177e4SLinus Torvalds	tst.b		%d1
17651da177e4SLinus Torvalds	bne.b		_L6_2x
17661da177e4SLinus Torvalds	bsr.l		satan			# operand is a NORM
17671da177e4SLinus Torvalds	bra.b		_L6_6x
17681da177e4SLinus Torvalds_L6_2x:
17691da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
17701da177e4SLinus Torvalds	bne.b		_L6_3x			# no
17711da177e4SLinus Torvalds	bsr.l		src_zero			# yes
17721da177e4SLinus Torvalds	bra.b		_L6_6x
17731da177e4SLinus Torvalds_L6_3x:
17741da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
17751da177e4SLinus Torvalds	bne.b		_L6_4x			# no
17761da177e4SLinus Torvalds	bsr.l		spi_2			# yes
17771da177e4SLinus Torvalds	bra.b		_L6_6x
17781da177e4SLinus Torvalds_L6_4x:
17791da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
17801da177e4SLinus Torvalds	bne.b		_L6_5x			# no
17811da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
17821da177e4SLinus Torvalds	bra.b		_L6_6x
17831da177e4SLinus Torvalds_L6_5x:
17841da177e4SLinus Torvalds	bsr.l		satand			# operand is a DENORM
17851da177e4SLinus Torvalds_L6_6x:
17861da177e4SLinus Torvalds
17871da177e4SLinus Torvalds#
17881da177e4SLinus Torvalds#	Result is now in FP0
17891da177e4SLinus Torvalds#
17901da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
17911da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
17921da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
17931da177e4SLinus Torvalds	unlk		%a6
17941da177e4SLinus Torvalds	rts
17951da177e4SLinus Torvalds
17961da177e4SLinus Torvalds
17971da177e4SLinus Torvalds#########################################################################
17981da177e4SLinus Torvalds# MONADIC TEMPLATE							#
17991da177e4SLinus Torvalds#########################################################################
18001da177e4SLinus Torvalds	global		_fasins_
18011da177e4SLinus Torvalds_fasins_:
18021da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
18031da177e4SLinus Torvalds
18041da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
18051da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
18061da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
18071da177e4SLinus Torvalds
18081da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
18091da177e4SLinus Torvalds
18101da177e4SLinus Torvalds#
18111da177e4SLinus Torvalds#	copy, convert, and tag input argument
18121da177e4SLinus Torvalds#
18131da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
18141da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
18151da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
18161da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
18171da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
18181da177e4SLinus Torvalds	mov.b		%d0,%d1
18191da177e4SLinus Torvalds
18201da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
18211da177e4SLinus Torvalds
18221da177e4SLinus Torvalds	clr.l		%d0
18231da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
18241da177e4SLinus Torvalds
18251da177e4SLinus Torvalds	tst.b		%d1
18261da177e4SLinus Torvalds	bne.b		_L7_2s
18271da177e4SLinus Torvalds	bsr.l		sasin			# operand is a NORM
18281da177e4SLinus Torvalds	bra.b		_L7_6s
18291da177e4SLinus Torvalds_L7_2s:
18301da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
18311da177e4SLinus Torvalds	bne.b		_L7_3s			# no
18321da177e4SLinus Torvalds	bsr.l		src_zero			# yes
18331da177e4SLinus Torvalds	bra.b		_L7_6s
18341da177e4SLinus Torvalds_L7_3s:
18351da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
18361da177e4SLinus Torvalds	bne.b		_L7_4s			# no
18371da177e4SLinus Torvalds	bsr.l		t_operr			# yes
18381da177e4SLinus Torvalds	bra.b		_L7_6s
18391da177e4SLinus Torvalds_L7_4s:
18401da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
18411da177e4SLinus Torvalds	bne.b		_L7_5s			# no
18421da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
18431da177e4SLinus Torvalds	bra.b		_L7_6s
18441da177e4SLinus Torvalds_L7_5s:
18451da177e4SLinus Torvalds	bsr.l		sasind			# operand is a DENORM
18461da177e4SLinus Torvalds_L7_6s:
18471da177e4SLinus Torvalds
18481da177e4SLinus Torvalds#
18491da177e4SLinus Torvalds#	Result is now in FP0
18501da177e4SLinus Torvalds#
18511da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
18521da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
18531da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
18541da177e4SLinus Torvalds	unlk		%a6
18551da177e4SLinus Torvalds	rts
18561da177e4SLinus Torvalds
18571da177e4SLinus Torvalds	global		_fasind_
18581da177e4SLinus Torvalds_fasind_:
18591da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
18601da177e4SLinus Torvalds
18611da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
18621da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
18631da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
18641da177e4SLinus Torvalds
18651da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
18661da177e4SLinus Torvalds
18671da177e4SLinus Torvalds#
18681da177e4SLinus Torvalds#	copy, convert, and tag input argument
18691da177e4SLinus Torvalds#
18701da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
18711da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
18721da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
18731da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
18741da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
18751da177e4SLinus Torvalds	mov.b		%d0,%d1
18761da177e4SLinus Torvalds
18771da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
18781da177e4SLinus Torvalds
18791da177e4SLinus Torvalds	clr.l		%d0
18801da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
18811da177e4SLinus Torvalds
18821da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
18831da177e4SLinus Torvalds	tst.b		%d1
18841da177e4SLinus Torvalds	bne.b		_L7_2d
18851da177e4SLinus Torvalds	bsr.l		sasin			# operand is a NORM
18861da177e4SLinus Torvalds	bra.b		_L7_6d
18871da177e4SLinus Torvalds_L7_2d:
18881da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
18891da177e4SLinus Torvalds	bne.b		_L7_3d			# no
18901da177e4SLinus Torvalds	bsr.l		src_zero			# yes
18911da177e4SLinus Torvalds	bra.b		_L7_6d
18921da177e4SLinus Torvalds_L7_3d:
18931da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
18941da177e4SLinus Torvalds	bne.b		_L7_4d			# no
18951da177e4SLinus Torvalds	bsr.l		t_operr			# yes
18961da177e4SLinus Torvalds	bra.b		_L7_6d
18971da177e4SLinus Torvalds_L7_4d:
18981da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
18991da177e4SLinus Torvalds	bne.b		_L7_5d			# no
19001da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
19011da177e4SLinus Torvalds	bra.b		_L7_6d
19021da177e4SLinus Torvalds_L7_5d:
19031da177e4SLinus Torvalds	bsr.l		sasind			# operand is a DENORM
19041da177e4SLinus Torvalds_L7_6d:
19051da177e4SLinus Torvalds
19061da177e4SLinus Torvalds#
19071da177e4SLinus Torvalds#	Result is now in FP0
19081da177e4SLinus Torvalds#
19091da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
19101da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
19111da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
19121da177e4SLinus Torvalds	unlk		%a6
19131da177e4SLinus Torvalds	rts
19141da177e4SLinus Torvalds
19151da177e4SLinus Torvalds	global		_fasinx_
19161da177e4SLinus Torvalds_fasinx_:
19171da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
19181da177e4SLinus Torvalds
19191da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
19201da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
19211da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
19221da177e4SLinus Torvalds
19231da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
19241da177e4SLinus Torvalds
19251da177e4SLinus Torvalds#
19261da177e4SLinus Torvalds#	copy, convert, and tag input argument
19271da177e4SLinus Torvalds#
19281da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
19291da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
19301da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
19311da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
19321da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
19331da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
19341da177e4SLinus Torvalds	mov.b		%d0,%d1
19351da177e4SLinus Torvalds
19361da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
19371da177e4SLinus Torvalds
19381da177e4SLinus Torvalds	clr.l		%d0
19391da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
19401da177e4SLinus Torvalds
19411da177e4SLinus Torvalds	tst.b		%d1
19421da177e4SLinus Torvalds	bne.b		_L7_2x
19431da177e4SLinus Torvalds	bsr.l		sasin			# operand is a NORM
19441da177e4SLinus Torvalds	bra.b		_L7_6x
19451da177e4SLinus Torvalds_L7_2x:
19461da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
19471da177e4SLinus Torvalds	bne.b		_L7_3x			# no
19481da177e4SLinus Torvalds	bsr.l		src_zero			# yes
19491da177e4SLinus Torvalds	bra.b		_L7_6x
19501da177e4SLinus Torvalds_L7_3x:
19511da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
19521da177e4SLinus Torvalds	bne.b		_L7_4x			# no
19531da177e4SLinus Torvalds	bsr.l		t_operr			# yes
19541da177e4SLinus Torvalds	bra.b		_L7_6x
19551da177e4SLinus Torvalds_L7_4x:
19561da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
19571da177e4SLinus Torvalds	bne.b		_L7_5x			# no
19581da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
19591da177e4SLinus Torvalds	bra.b		_L7_6x
19601da177e4SLinus Torvalds_L7_5x:
19611da177e4SLinus Torvalds	bsr.l		sasind			# operand is a DENORM
19621da177e4SLinus Torvalds_L7_6x:
19631da177e4SLinus Torvalds
19641da177e4SLinus Torvalds#
19651da177e4SLinus Torvalds#	Result is now in FP0
19661da177e4SLinus Torvalds#
19671da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
19681da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
19691da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
19701da177e4SLinus Torvalds	unlk		%a6
19711da177e4SLinus Torvalds	rts
19721da177e4SLinus Torvalds
19731da177e4SLinus Torvalds
19741da177e4SLinus Torvalds#########################################################################
19751da177e4SLinus Torvalds# MONADIC TEMPLATE							#
19761da177e4SLinus Torvalds#########################################################################
19771da177e4SLinus Torvalds	global		_fatanhs_
19781da177e4SLinus Torvalds_fatanhs_:
19791da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
19801da177e4SLinus Torvalds
19811da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
19821da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
19831da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
19841da177e4SLinus Torvalds
19851da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
19861da177e4SLinus Torvalds
19871da177e4SLinus Torvalds#
19881da177e4SLinus Torvalds#	copy, convert, and tag input argument
19891da177e4SLinus Torvalds#
19901da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
19911da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
19921da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
19931da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
19941da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
19951da177e4SLinus Torvalds	mov.b		%d0,%d1
19961da177e4SLinus Torvalds
19971da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
19981da177e4SLinus Torvalds
19991da177e4SLinus Torvalds	clr.l		%d0
20001da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
20011da177e4SLinus Torvalds
20021da177e4SLinus Torvalds	tst.b		%d1
20031da177e4SLinus Torvalds	bne.b		_L8_2s
20041da177e4SLinus Torvalds	bsr.l		satanh			# operand is a NORM
20051da177e4SLinus Torvalds	bra.b		_L8_6s
20061da177e4SLinus Torvalds_L8_2s:
20071da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
20081da177e4SLinus Torvalds	bne.b		_L8_3s			# no
20091da177e4SLinus Torvalds	bsr.l		src_zero			# yes
20101da177e4SLinus Torvalds	bra.b		_L8_6s
20111da177e4SLinus Torvalds_L8_3s:
20121da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
20131da177e4SLinus Torvalds	bne.b		_L8_4s			# no
20141da177e4SLinus Torvalds	bsr.l		t_operr			# yes
20151da177e4SLinus Torvalds	bra.b		_L8_6s
20161da177e4SLinus Torvalds_L8_4s:
20171da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
20181da177e4SLinus Torvalds	bne.b		_L8_5s			# no
20191da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
20201da177e4SLinus Torvalds	bra.b		_L8_6s
20211da177e4SLinus Torvalds_L8_5s:
20221da177e4SLinus Torvalds	bsr.l		satanhd			# operand is a DENORM
20231da177e4SLinus Torvalds_L8_6s:
20241da177e4SLinus Torvalds
20251da177e4SLinus Torvalds#
20261da177e4SLinus Torvalds#	Result is now in FP0
20271da177e4SLinus Torvalds#
20281da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
20291da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
20301da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
20311da177e4SLinus Torvalds	unlk		%a6
20321da177e4SLinus Torvalds	rts
20331da177e4SLinus Torvalds
20341da177e4SLinus Torvalds	global		_fatanhd_
20351da177e4SLinus Torvalds_fatanhd_:
20361da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
20371da177e4SLinus Torvalds
20381da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
20391da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
20401da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
20411da177e4SLinus Torvalds
20421da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
20431da177e4SLinus Torvalds
20441da177e4SLinus Torvalds#
20451da177e4SLinus Torvalds#	copy, convert, and tag input argument
20461da177e4SLinus Torvalds#
20471da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
20481da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
20491da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
20501da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
20511da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
20521da177e4SLinus Torvalds	mov.b		%d0,%d1
20531da177e4SLinus Torvalds
20541da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
20551da177e4SLinus Torvalds
20561da177e4SLinus Torvalds	clr.l		%d0
20571da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
20581da177e4SLinus Torvalds
20591da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
20601da177e4SLinus Torvalds	tst.b		%d1
20611da177e4SLinus Torvalds	bne.b		_L8_2d
20621da177e4SLinus Torvalds	bsr.l		satanh			# operand is a NORM
20631da177e4SLinus Torvalds	bra.b		_L8_6d
20641da177e4SLinus Torvalds_L8_2d:
20651da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
20661da177e4SLinus Torvalds	bne.b		_L8_3d			# no
20671da177e4SLinus Torvalds	bsr.l		src_zero			# yes
20681da177e4SLinus Torvalds	bra.b		_L8_6d
20691da177e4SLinus Torvalds_L8_3d:
20701da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
20711da177e4SLinus Torvalds	bne.b		_L8_4d			# no
20721da177e4SLinus Torvalds	bsr.l		t_operr			# yes
20731da177e4SLinus Torvalds	bra.b		_L8_6d
20741da177e4SLinus Torvalds_L8_4d:
20751da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
20761da177e4SLinus Torvalds	bne.b		_L8_5d			# no
20771da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
20781da177e4SLinus Torvalds	bra.b		_L8_6d
20791da177e4SLinus Torvalds_L8_5d:
20801da177e4SLinus Torvalds	bsr.l		satanhd			# operand is a DENORM
20811da177e4SLinus Torvalds_L8_6d:
20821da177e4SLinus Torvalds
20831da177e4SLinus Torvalds#
20841da177e4SLinus Torvalds#	Result is now in FP0
20851da177e4SLinus Torvalds#
20861da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
20871da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
20881da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
20891da177e4SLinus Torvalds	unlk		%a6
20901da177e4SLinus Torvalds	rts
20911da177e4SLinus Torvalds
20921da177e4SLinus Torvalds	global		_fatanhx_
20931da177e4SLinus Torvalds_fatanhx_:
20941da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
20951da177e4SLinus Torvalds
20961da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
20971da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
20981da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
20991da177e4SLinus Torvalds
21001da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
21011da177e4SLinus Torvalds
21021da177e4SLinus Torvalds#
21031da177e4SLinus Torvalds#	copy, convert, and tag input argument
21041da177e4SLinus Torvalds#
21051da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
21061da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
21071da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
21081da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
21091da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
21101da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
21111da177e4SLinus Torvalds	mov.b		%d0,%d1
21121da177e4SLinus Torvalds
21131da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
21141da177e4SLinus Torvalds
21151da177e4SLinus Torvalds	clr.l		%d0
21161da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
21171da177e4SLinus Torvalds
21181da177e4SLinus Torvalds	tst.b		%d1
21191da177e4SLinus Torvalds	bne.b		_L8_2x
21201da177e4SLinus Torvalds	bsr.l		satanh			# operand is a NORM
21211da177e4SLinus Torvalds	bra.b		_L8_6x
21221da177e4SLinus Torvalds_L8_2x:
21231da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
21241da177e4SLinus Torvalds	bne.b		_L8_3x			# no
21251da177e4SLinus Torvalds	bsr.l		src_zero			# yes
21261da177e4SLinus Torvalds	bra.b		_L8_6x
21271da177e4SLinus Torvalds_L8_3x:
21281da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
21291da177e4SLinus Torvalds	bne.b		_L8_4x			# no
21301da177e4SLinus Torvalds	bsr.l		t_operr			# yes
21311da177e4SLinus Torvalds	bra.b		_L8_6x
21321da177e4SLinus Torvalds_L8_4x:
21331da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
21341da177e4SLinus Torvalds	bne.b		_L8_5x			# no
21351da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
21361da177e4SLinus Torvalds	bra.b		_L8_6x
21371da177e4SLinus Torvalds_L8_5x:
21381da177e4SLinus Torvalds	bsr.l		satanhd			# operand is a DENORM
21391da177e4SLinus Torvalds_L8_6x:
21401da177e4SLinus Torvalds
21411da177e4SLinus Torvalds#
21421da177e4SLinus Torvalds#	Result is now in FP0
21431da177e4SLinus Torvalds#
21441da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
21451da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
21461da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
21471da177e4SLinus Torvalds	unlk		%a6
21481da177e4SLinus Torvalds	rts
21491da177e4SLinus Torvalds
21501da177e4SLinus Torvalds
21511da177e4SLinus Torvalds#########################################################################
21521da177e4SLinus Torvalds# MONADIC TEMPLATE							#
21531da177e4SLinus Torvalds#########################################################################
21541da177e4SLinus Torvalds	global		_ftans_
21551da177e4SLinus Torvalds_ftans_:
21561da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
21571da177e4SLinus Torvalds
21581da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
21591da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
21601da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
21611da177e4SLinus Torvalds
21621da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
21631da177e4SLinus Torvalds
21641da177e4SLinus Torvalds#
21651da177e4SLinus Torvalds#	copy, convert, and tag input argument
21661da177e4SLinus Torvalds#
21671da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
21681da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
21691da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
21701da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
21711da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
21721da177e4SLinus Torvalds	mov.b		%d0,%d1
21731da177e4SLinus Torvalds
21741da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
21751da177e4SLinus Torvalds
21761da177e4SLinus Torvalds	clr.l		%d0
21771da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
21781da177e4SLinus Torvalds
21791da177e4SLinus Torvalds	tst.b		%d1
21801da177e4SLinus Torvalds	bne.b		_L9_2s
21811da177e4SLinus Torvalds	bsr.l		stan			# operand is a NORM
21821da177e4SLinus Torvalds	bra.b		_L9_6s
21831da177e4SLinus Torvalds_L9_2s:
21841da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
21851da177e4SLinus Torvalds	bne.b		_L9_3s			# no
21861da177e4SLinus Torvalds	bsr.l		src_zero			# yes
21871da177e4SLinus Torvalds	bra.b		_L9_6s
21881da177e4SLinus Torvalds_L9_3s:
21891da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
21901da177e4SLinus Torvalds	bne.b		_L9_4s			# no
21911da177e4SLinus Torvalds	bsr.l		t_operr			# yes
21921da177e4SLinus Torvalds	bra.b		_L9_6s
21931da177e4SLinus Torvalds_L9_4s:
21941da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
21951da177e4SLinus Torvalds	bne.b		_L9_5s			# no
21961da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
21971da177e4SLinus Torvalds	bra.b		_L9_6s
21981da177e4SLinus Torvalds_L9_5s:
21991da177e4SLinus Torvalds	bsr.l		stand			# operand is a DENORM
22001da177e4SLinus Torvalds_L9_6s:
22011da177e4SLinus Torvalds
22021da177e4SLinus Torvalds#
22031da177e4SLinus Torvalds#	Result is now in FP0
22041da177e4SLinus Torvalds#
22051da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
22061da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
22071da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
22081da177e4SLinus Torvalds	unlk		%a6
22091da177e4SLinus Torvalds	rts
22101da177e4SLinus Torvalds
22111da177e4SLinus Torvalds	global		_ftand_
22121da177e4SLinus Torvalds_ftand_:
22131da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
22141da177e4SLinus Torvalds
22151da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
22161da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
22171da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
22181da177e4SLinus Torvalds
22191da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
22201da177e4SLinus Torvalds
22211da177e4SLinus Torvalds#
22221da177e4SLinus Torvalds#	copy, convert, and tag input argument
22231da177e4SLinus Torvalds#
22241da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
22251da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
22261da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
22271da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
22281da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
22291da177e4SLinus Torvalds	mov.b		%d0,%d1
22301da177e4SLinus Torvalds
22311da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
22321da177e4SLinus Torvalds
22331da177e4SLinus Torvalds	clr.l		%d0
22341da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
22351da177e4SLinus Torvalds
22361da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
22371da177e4SLinus Torvalds	tst.b		%d1
22381da177e4SLinus Torvalds	bne.b		_L9_2d
22391da177e4SLinus Torvalds	bsr.l		stan			# operand is a NORM
22401da177e4SLinus Torvalds	bra.b		_L9_6d
22411da177e4SLinus Torvalds_L9_2d:
22421da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
22431da177e4SLinus Torvalds	bne.b		_L9_3d			# no
22441da177e4SLinus Torvalds	bsr.l		src_zero			# yes
22451da177e4SLinus Torvalds	bra.b		_L9_6d
22461da177e4SLinus Torvalds_L9_3d:
22471da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
22481da177e4SLinus Torvalds	bne.b		_L9_4d			# no
22491da177e4SLinus Torvalds	bsr.l		t_operr			# yes
22501da177e4SLinus Torvalds	bra.b		_L9_6d
22511da177e4SLinus Torvalds_L9_4d:
22521da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
22531da177e4SLinus Torvalds	bne.b		_L9_5d			# no
22541da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
22551da177e4SLinus Torvalds	bra.b		_L9_6d
22561da177e4SLinus Torvalds_L9_5d:
22571da177e4SLinus Torvalds	bsr.l		stand			# operand is a DENORM
22581da177e4SLinus Torvalds_L9_6d:
22591da177e4SLinus Torvalds
22601da177e4SLinus Torvalds#
22611da177e4SLinus Torvalds#	Result is now in FP0
22621da177e4SLinus Torvalds#
22631da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
22641da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
22651da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
22661da177e4SLinus Torvalds	unlk		%a6
22671da177e4SLinus Torvalds	rts
22681da177e4SLinus Torvalds
22691da177e4SLinus Torvalds	global		_ftanx_
22701da177e4SLinus Torvalds_ftanx_:
22711da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
22721da177e4SLinus Torvalds
22731da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
22741da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
22751da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
22761da177e4SLinus Torvalds
22771da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
22781da177e4SLinus Torvalds
22791da177e4SLinus Torvalds#
22801da177e4SLinus Torvalds#	copy, convert, and tag input argument
22811da177e4SLinus Torvalds#
22821da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
22831da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
22841da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
22851da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
22861da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
22871da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
22881da177e4SLinus Torvalds	mov.b		%d0,%d1
22891da177e4SLinus Torvalds
22901da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
22911da177e4SLinus Torvalds
22921da177e4SLinus Torvalds	clr.l		%d0
22931da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
22941da177e4SLinus Torvalds
22951da177e4SLinus Torvalds	tst.b		%d1
22961da177e4SLinus Torvalds	bne.b		_L9_2x
22971da177e4SLinus Torvalds	bsr.l		stan			# operand is a NORM
22981da177e4SLinus Torvalds	bra.b		_L9_6x
22991da177e4SLinus Torvalds_L9_2x:
23001da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
23011da177e4SLinus Torvalds	bne.b		_L9_3x			# no
23021da177e4SLinus Torvalds	bsr.l		src_zero			# yes
23031da177e4SLinus Torvalds	bra.b		_L9_6x
23041da177e4SLinus Torvalds_L9_3x:
23051da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
23061da177e4SLinus Torvalds	bne.b		_L9_4x			# no
23071da177e4SLinus Torvalds	bsr.l		t_operr			# yes
23081da177e4SLinus Torvalds	bra.b		_L9_6x
23091da177e4SLinus Torvalds_L9_4x:
23101da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
23111da177e4SLinus Torvalds	bne.b		_L9_5x			# no
23121da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
23131da177e4SLinus Torvalds	bra.b		_L9_6x
23141da177e4SLinus Torvalds_L9_5x:
23151da177e4SLinus Torvalds	bsr.l		stand			# operand is a DENORM
23161da177e4SLinus Torvalds_L9_6x:
23171da177e4SLinus Torvalds
23181da177e4SLinus Torvalds#
23191da177e4SLinus Torvalds#	Result is now in FP0
23201da177e4SLinus Torvalds#
23211da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
23221da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
23231da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
23241da177e4SLinus Torvalds	unlk		%a6
23251da177e4SLinus Torvalds	rts
23261da177e4SLinus Torvalds
23271da177e4SLinus Torvalds
23281da177e4SLinus Torvalds#########################################################################
23291da177e4SLinus Torvalds# MONADIC TEMPLATE							#
23301da177e4SLinus Torvalds#########################################################################
23311da177e4SLinus Torvalds	global		_fetoxs_
23321da177e4SLinus Torvalds_fetoxs_:
23331da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
23341da177e4SLinus Torvalds
23351da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
23361da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
23371da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
23381da177e4SLinus Torvalds
23391da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
23401da177e4SLinus Torvalds
23411da177e4SLinus Torvalds#
23421da177e4SLinus Torvalds#	copy, convert, and tag input argument
23431da177e4SLinus Torvalds#
23441da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
23451da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
23461da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
23471da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
23481da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
23491da177e4SLinus Torvalds	mov.b		%d0,%d1
23501da177e4SLinus Torvalds
23511da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
23521da177e4SLinus Torvalds
23531da177e4SLinus Torvalds	clr.l		%d0
23541da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
23551da177e4SLinus Torvalds
23561da177e4SLinus Torvalds	tst.b		%d1
23571da177e4SLinus Torvalds	bne.b		_L10_2s
23581da177e4SLinus Torvalds	bsr.l		setox			# operand is a NORM
23591da177e4SLinus Torvalds	bra.b		_L10_6s
23601da177e4SLinus Torvalds_L10_2s:
23611da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
23621da177e4SLinus Torvalds	bne.b		_L10_3s			# no
23631da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
23641da177e4SLinus Torvalds	bra.b		_L10_6s
23651da177e4SLinus Torvalds_L10_3s:
23661da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
23671da177e4SLinus Torvalds	bne.b		_L10_4s			# no
23681da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
23691da177e4SLinus Torvalds	bra.b		_L10_6s
23701da177e4SLinus Torvalds_L10_4s:
23711da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
23721da177e4SLinus Torvalds	bne.b		_L10_5s			# no
23731da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
23741da177e4SLinus Torvalds	bra.b		_L10_6s
23751da177e4SLinus Torvalds_L10_5s:
23761da177e4SLinus Torvalds	bsr.l		setoxd			# operand is a DENORM
23771da177e4SLinus Torvalds_L10_6s:
23781da177e4SLinus Torvalds
23791da177e4SLinus Torvalds#
23801da177e4SLinus Torvalds#	Result is now in FP0
23811da177e4SLinus Torvalds#
23821da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
23831da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
23841da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
23851da177e4SLinus Torvalds	unlk		%a6
23861da177e4SLinus Torvalds	rts
23871da177e4SLinus Torvalds
23881da177e4SLinus Torvalds	global		_fetoxd_
23891da177e4SLinus Torvalds_fetoxd_:
23901da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
23911da177e4SLinus Torvalds
23921da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
23931da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
23941da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
23951da177e4SLinus Torvalds
23961da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
23971da177e4SLinus Torvalds
23981da177e4SLinus Torvalds#
23991da177e4SLinus Torvalds#	copy, convert, and tag input argument
24001da177e4SLinus Torvalds#
24011da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
24021da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
24031da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
24041da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
24051da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
24061da177e4SLinus Torvalds	mov.b		%d0,%d1
24071da177e4SLinus Torvalds
24081da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
24091da177e4SLinus Torvalds
24101da177e4SLinus Torvalds	clr.l		%d0
24111da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
24121da177e4SLinus Torvalds
24131da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
24141da177e4SLinus Torvalds	tst.b		%d1
24151da177e4SLinus Torvalds	bne.b		_L10_2d
24161da177e4SLinus Torvalds	bsr.l		setox			# operand is a NORM
24171da177e4SLinus Torvalds	bra.b		_L10_6d
24181da177e4SLinus Torvalds_L10_2d:
24191da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
24201da177e4SLinus Torvalds	bne.b		_L10_3d			# no
24211da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
24221da177e4SLinus Torvalds	bra.b		_L10_6d
24231da177e4SLinus Torvalds_L10_3d:
24241da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
24251da177e4SLinus Torvalds	bne.b		_L10_4d			# no
24261da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
24271da177e4SLinus Torvalds	bra.b		_L10_6d
24281da177e4SLinus Torvalds_L10_4d:
24291da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
24301da177e4SLinus Torvalds	bne.b		_L10_5d			# no
24311da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
24321da177e4SLinus Torvalds	bra.b		_L10_6d
24331da177e4SLinus Torvalds_L10_5d:
24341da177e4SLinus Torvalds	bsr.l		setoxd			# operand is a DENORM
24351da177e4SLinus Torvalds_L10_6d:
24361da177e4SLinus Torvalds
24371da177e4SLinus Torvalds#
24381da177e4SLinus Torvalds#	Result is now in FP0
24391da177e4SLinus Torvalds#
24401da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
24411da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
24421da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
24431da177e4SLinus Torvalds	unlk		%a6
24441da177e4SLinus Torvalds	rts
24451da177e4SLinus Torvalds
24461da177e4SLinus Torvalds	global		_fetoxx_
24471da177e4SLinus Torvalds_fetoxx_:
24481da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
24491da177e4SLinus Torvalds
24501da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
24511da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
24521da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
24531da177e4SLinus Torvalds
24541da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
24551da177e4SLinus Torvalds
24561da177e4SLinus Torvalds#
24571da177e4SLinus Torvalds#	copy, convert, and tag input argument
24581da177e4SLinus Torvalds#
24591da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
24601da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
24611da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
24621da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
24631da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
24641da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
24651da177e4SLinus Torvalds	mov.b		%d0,%d1
24661da177e4SLinus Torvalds
24671da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
24681da177e4SLinus Torvalds
24691da177e4SLinus Torvalds	clr.l		%d0
24701da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
24711da177e4SLinus Torvalds
24721da177e4SLinus Torvalds	tst.b		%d1
24731da177e4SLinus Torvalds	bne.b		_L10_2x
24741da177e4SLinus Torvalds	bsr.l		setox			# operand is a NORM
24751da177e4SLinus Torvalds	bra.b		_L10_6x
24761da177e4SLinus Torvalds_L10_2x:
24771da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
24781da177e4SLinus Torvalds	bne.b		_L10_3x			# no
24791da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
24801da177e4SLinus Torvalds	bra.b		_L10_6x
24811da177e4SLinus Torvalds_L10_3x:
24821da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
24831da177e4SLinus Torvalds	bne.b		_L10_4x			# no
24841da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
24851da177e4SLinus Torvalds	bra.b		_L10_6x
24861da177e4SLinus Torvalds_L10_4x:
24871da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
24881da177e4SLinus Torvalds	bne.b		_L10_5x			# no
24891da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
24901da177e4SLinus Torvalds	bra.b		_L10_6x
24911da177e4SLinus Torvalds_L10_5x:
24921da177e4SLinus Torvalds	bsr.l		setoxd			# operand is a DENORM
24931da177e4SLinus Torvalds_L10_6x:
24941da177e4SLinus Torvalds
24951da177e4SLinus Torvalds#
24961da177e4SLinus Torvalds#	Result is now in FP0
24971da177e4SLinus Torvalds#
24981da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
24991da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
25001da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
25011da177e4SLinus Torvalds	unlk		%a6
25021da177e4SLinus Torvalds	rts
25031da177e4SLinus Torvalds
25041da177e4SLinus Torvalds
25051da177e4SLinus Torvalds#########################################################################
25061da177e4SLinus Torvalds# MONADIC TEMPLATE							#
25071da177e4SLinus Torvalds#########################################################################
25081da177e4SLinus Torvalds	global		_ftwotoxs_
25091da177e4SLinus Torvalds_ftwotoxs_:
25101da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
25111da177e4SLinus Torvalds
25121da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
25131da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
25141da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
25151da177e4SLinus Torvalds
25161da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
25171da177e4SLinus Torvalds
25181da177e4SLinus Torvalds#
25191da177e4SLinus Torvalds#	copy, convert, and tag input argument
25201da177e4SLinus Torvalds#
25211da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
25221da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
25231da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
25241da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
25251da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
25261da177e4SLinus Torvalds	mov.b		%d0,%d1
25271da177e4SLinus Torvalds
25281da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
25291da177e4SLinus Torvalds
25301da177e4SLinus Torvalds	clr.l		%d0
25311da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
25321da177e4SLinus Torvalds
25331da177e4SLinus Torvalds	tst.b		%d1
25341da177e4SLinus Torvalds	bne.b		_L11_2s
25351da177e4SLinus Torvalds	bsr.l		stwotox			# operand is a NORM
25361da177e4SLinus Torvalds	bra.b		_L11_6s
25371da177e4SLinus Torvalds_L11_2s:
25381da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
25391da177e4SLinus Torvalds	bne.b		_L11_3s			# no
25401da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
25411da177e4SLinus Torvalds	bra.b		_L11_6s
25421da177e4SLinus Torvalds_L11_3s:
25431da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
25441da177e4SLinus Torvalds	bne.b		_L11_4s			# no
25451da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
25461da177e4SLinus Torvalds	bra.b		_L11_6s
25471da177e4SLinus Torvalds_L11_4s:
25481da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
25491da177e4SLinus Torvalds	bne.b		_L11_5s			# no
25501da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
25511da177e4SLinus Torvalds	bra.b		_L11_6s
25521da177e4SLinus Torvalds_L11_5s:
25531da177e4SLinus Torvalds	bsr.l		stwotoxd			# operand is a DENORM
25541da177e4SLinus Torvalds_L11_6s:
25551da177e4SLinus Torvalds
25561da177e4SLinus Torvalds#
25571da177e4SLinus Torvalds#	Result is now in FP0
25581da177e4SLinus Torvalds#
25591da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
25601da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
25611da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
25621da177e4SLinus Torvalds	unlk		%a6
25631da177e4SLinus Torvalds	rts
25641da177e4SLinus Torvalds
25651da177e4SLinus Torvalds	global		_ftwotoxd_
25661da177e4SLinus Torvalds_ftwotoxd_:
25671da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
25681da177e4SLinus Torvalds
25691da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
25701da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
25711da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
25721da177e4SLinus Torvalds
25731da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
25741da177e4SLinus Torvalds
25751da177e4SLinus Torvalds#
25761da177e4SLinus Torvalds#	copy, convert, and tag input argument
25771da177e4SLinus Torvalds#
25781da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
25791da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
25801da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
25811da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
25821da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
25831da177e4SLinus Torvalds	mov.b		%d0,%d1
25841da177e4SLinus Torvalds
25851da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
25861da177e4SLinus Torvalds
25871da177e4SLinus Torvalds	clr.l		%d0
25881da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
25891da177e4SLinus Torvalds
25901da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
25911da177e4SLinus Torvalds	tst.b		%d1
25921da177e4SLinus Torvalds	bne.b		_L11_2d
25931da177e4SLinus Torvalds	bsr.l		stwotox			# operand is a NORM
25941da177e4SLinus Torvalds	bra.b		_L11_6d
25951da177e4SLinus Torvalds_L11_2d:
25961da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
25971da177e4SLinus Torvalds	bne.b		_L11_3d			# no
25981da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
25991da177e4SLinus Torvalds	bra.b		_L11_6d
26001da177e4SLinus Torvalds_L11_3d:
26011da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
26021da177e4SLinus Torvalds	bne.b		_L11_4d			# no
26031da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
26041da177e4SLinus Torvalds	bra.b		_L11_6d
26051da177e4SLinus Torvalds_L11_4d:
26061da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
26071da177e4SLinus Torvalds	bne.b		_L11_5d			# no
26081da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
26091da177e4SLinus Torvalds	bra.b		_L11_6d
26101da177e4SLinus Torvalds_L11_5d:
26111da177e4SLinus Torvalds	bsr.l		stwotoxd			# operand is a DENORM
26121da177e4SLinus Torvalds_L11_6d:
26131da177e4SLinus Torvalds
26141da177e4SLinus Torvalds#
26151da177e4SLinus Torvalds#	Result is now in FP0
26161da177e4SLinus Torvalds#
26171da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
26181da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
26191da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
26201da177e4SLinus Torvalds	unlk		%a6
26211da177e4SLinus Torvalds	rts
26221da177e4SLinus Torvalds
26231da177e4SLinus Torvalds	global		_ftwotoxx_
26241da177e4SLinus Torvalds_ftwotoxx_:
26251da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
26261da177e4SLinus Torvalds
26271da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
26281da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
26291da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
26301da177e4SLinus Torvalds
26311da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
26321da177e4SLinus Torvalds
26331da177e4SLinus Torvalds#
26341da177e4SLinus Torvalds#	copy, convert, and tag input argument
26351da177e4SLinus Torvalds#
26361da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
26371da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
26381da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
26391da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
26401da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
26411da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
26421da177e4SLinus Torvalds	mov.b		%d0,%d1
26431da177e4SLinus Torvalds
26441da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
26451da177e4SLinus Torvalds
26461da177e4SLinus Torvalds	clr.l		%d0
26471da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
26481da177e4SLinus Torvalds
26491da177e4SLinus Torvalds	tst.b		%d1
26501da177e4SLinus Torvalds	bne.b		_L11_2x
26511da177e4SLinus Torvalds	bsr.l		stwotox			# operand is a NORM
26521da177e4SLinus Torvalds	bra.b		_L11_6x
26531da177e4SLinus Torvalds_L11_2x:
26541da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
26551da177e4SLinus Torvalds	bne.b		_L11_3x			# no
26561da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
26571da177e4SLinus Torvalds	bra.b		_L11_6x
26581da177e4SLinus Torvalds_L11_3x:
26591da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
26601da177e4SLinus Torvalds	bne.b		_L11_4x			# no
26611da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
26621da177e4SLinus Torvalds	bra.b		_L11_6x
26631da177e4SLinus Torvalds_L11_4x:
26641da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
26651da177e4SLinus Torvalds	bne.b		_L11_5x			# no
26661da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
26671da177e4SLinus Torvalds	bra.b		_L11_6x
26681da177e4SLinus Torvalds_L11_5x:
26691da177e4SLinus Torvalds	bsr.l		stwotoxd			# operand is a DENORM
26701da177e4SLinus Torvalds_L11_6x:
26711da177e4SLinus Torvalds
26721da177e4SLinus Torvalds#
26731da177e4SLinus Torvalds#	Result is now in FP0
26741da177e4SLinus Torvalds#
26751da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
26761da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
26771da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
26781da177e4SLinus Torvalds	unlk		%a6
26791da177e4SLinus Torvalds	rts
26801da177e4SLinus Torvalds
26811da177e4SLinus Torvalds
26821da177e4SLinus Torvalds#########################################################################
26831da177e4SLinus Torvalds# MONADIC TEMPLATE							#
26841da177e4SLinus Torvalds#########################################################################
26851da177e4SLinus Torvalds	global		_ftentoxs_
26861da177e4SLinus Torvalds_ftentoxs_:
26871da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
26881da177e4SLinus Torvalds
26891da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
26901da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
26911da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
26921da177e4SLinus Torvalds
26931da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
26941da177e4SLinus Torvalds
26951da177e4SLinus Torvalds#
26961da177e4SLinus Torvalds#	copy, convert, and tag input argument
26971da177e4SLinus Torvalds#
26981da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
26991da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
27001da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
27011da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
27021da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
27031da177e4SLinus Torvalds	mov.b		%d0,%d1
27041da177e4SLinus Torvalds
27051da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
27061da177e4SLinus Torvalds
27071da177e4SLinus Torvalds	clr.l		%d0
27081da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
27091da177e4SLinus Torvalds
27101da177e4SLinus Torvalds	tst.b		%d1
27111da177e4SLinus Torvalds	bne.b		_L12_2s
27121da177e4SLinus Torvalds	bsr.l		stentox			# operand is a NORM
27131da177e4SLinus Torvalds	bra.b		_L12_6s
27141da177e4SLinus Torvalds_L12_2s:
27151da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
27161da177e4SLinus Torvalds	bne.b		_L12_3s			# no
27171da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
27181da177e4SLinus Torvalds	bra.b		_L12_6s
27191da177e4SLinus Torvalds_L12_3s:
27201da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
27211da177e4SLinus Torvalds	bne.b		_L12_4s			# no
27221da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
27231da177e4SLinus Torvalds	bra.b		_L12_6s
27241da177e4SLinus Torvalds_L12_4s:
27251da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
27261da177e4SLinus Torvalds	bne.b		_L12_5s			# no
27271da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
27281da177e4SLinus Torvalds	bra.b		_L12_6s
27291da177e4SLinus Torvalds_L12_5s:
27301da177e4SLinus Torvalds	bsr.l		stentoxd			# operand is a DENORM
27311da177e4SLinus Torvalds_L12_6s:
27321da177e4SLinus Torvalds
27331da177e4SLinus Torvalds#
27341da177e4SLinus Torvalds#	Result is now in FP0
27351da177e4SLinus Torvalds#
27361da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
27371da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
27381da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
27391da177e4SLinus Torvalds	unlk		%a6
27401da177e4SLinus Torvalds	rts
27411da177e4SLinus Torvalds
27421da177e4SLinus Torvalds	global		_ftentoxd_
27431da177e4SLinus Torvalds_ftentoxd_:
27441da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
27451da177e4SLinus Torvalds
27461da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
27471da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
27481da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
27491da177e4SLinus Torvalds
27501da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
27511da177e4SLinus Torvalds
27521da177e4SLinus Torvalds#
27531da177e4SLinus Torvalds#	copy, convert, and tag input argument
27541da177e4SLinus Torvalds#
27551da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
27561da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
27571da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
27581da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
27591da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
27601da177e4SLinus Torvalds	mov.b		%d0,%d1
27611da177e4SLinus Torvalds
27621da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
27631da177e4SLinus Torvalds
27641da177e4SLinus Torvalds	clr.l		%d0
27651da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
27661da177e4SLinus Torvalds
27671da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
27681da177e4SLinus Torvalds	tst.b		%d1
27691da177e4SLinus Torvalds	bne.b		_L12_2d
27701da177e4SLinus Torvalds	bsr.l		stentox			# operand is a NORM
27711da177e4SLinus Torvalds	bra.b		_L12_6d
27721da177e4SLinus Torvalds_L12_2d:
27731da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
27741da177e4SLinus Torvalds	bne.b		_L12_3d			# no
27751da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
27761da177e4SLinus Torvalds	bra.b		_L12_6d
27771da177e4SLinus Torvalds_L12_3d:
27781da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
27791da177e4SLinus Torvalds	bne.b		_L12_4d			# no
27801da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
27811da177e4SLinus Torvalds	bra.b		_L12_6d
27821da177e4SLinus Torvalds_L12_4d:
27831da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
27841da177e4SLinus Torvalds	bne.b		_L12_5d			# no
27851da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
27861da177e4SLinus Torvalds	bra.b		_L12_6d
27871da177e4SLinus Torvalds_L12_5d:
27881da177e4SLinus Torvalds	bsr.l		stentoxd			# operand is a DENORM
27891da177e4SLinus Torvalds_L12_6d:
27901da177e4SLinus Torvalds
27911da177e4SLinus Torvalds#
27921da177e4SLinus Torvalds#	Result is now in FP0
27931da177e4SLinus Torvalds#
27941da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
27951da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
27961da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
27971da177e4SLinus Torvalds	unlk		%a6
27981da177e4SLinus Torvalds	rts
27991da177e4SLinus Torvalds
28001da177e4SLinus Torvalds	global		_ftentoxx_
28011da177e4SLinus Torvalds_ftentoxx_:
28021da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
28031da177e4SLinus Torvalds
28041da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
28051da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
28061da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
28071da177e4SLinus Torvalds
28081da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
28091da177e4SLinus Torvalds
28101da177e4SLinus Torvalds#
28111da177e4SLinus Torvalds#	copy, convert, and tag input argument
28121da177e4SLinus Torvalds#
28131da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
28141da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
28151da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
28161da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
28171da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
28181da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
28191da177e4SLinus Torvalds	mov.b		%d0,%d1
28201da177e4SLinus Torvalds
28211da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
28221da177e4SLinus Torvalds
28231da177e4SLinus Torvalds	clr.l		%d0
28241da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
28251da177e4SLinus Torvalds
28261da177e4SLinus Torvalds	tst.b		%d1
28271da177e4SLinus Torvalds	bne.b		_L12_2x
28281da177e4SLinus Torvalds	bsr.l		stentox			# operand is a NORM
28291da177e4SLinus Torvalds	bra.b		_L12_6x
28301da177e4SLinus Torvalds_L12_2x:
28311da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
28321da177e4SLinus Torvalds	bne.b		_L12_3x			# no
28331da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
28341da177e4SLinus Torvalds	bra.b		_L12_6x
28351da177e4SLinus Torvalds_L12_3x:
28361da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
28371da177e4SLinus Torvalds	bne.b		_L12_4x			# no
28381da177e4SLinus Torvalds	bsr.l		szr_inf			# yes
28391da177e4SLinus Torvalds	bra.b		_L12_6x
28401da177e4SLinus Torvalds_L12_4x:
28411da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
28421da177e4SLinus Torvalds	bne.b		_L12_5x			# no
28431da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
28441da177e4SLinus Torvalds	bra.b		_L12_6x
28451da177e4SLinus Torvalds_L12_5x:
28461da177e4SLinus Torvalds	bsr.l		stentoxd			# operand is a DENORM
28471da177e4SLinus Torvalds_L12_6x:
28481da177e4SLinus Torvalds
28491da177e4SLinus Torvalds#
28501da177e4SLinus Torvalds#	Result is now in FP0
28511da177e4SLinus Torvalds#
28521da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
28531da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
28541da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
28551da177e4SLinus Torvalds	unlk		%a6
28561da177e4SLinus Torvalds	rts
28571da177e4SLinus Torvalds
28581da177e4SLinus Torvalds
28591da177e4SLinus Torvalds#########################################################################
28601da177e4SLinus Torvalds# MONADIC TEMPLATE							#
28611da177e4SLinus Torvalds#########################################################################
28621da177e4SLinus Torvalds	global		_flogns_
28631da177e4SLinus Torvalds_flogns_:
28641da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
28651da177e4SLinus Torvalds
28661da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
28671da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
28681da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
28691da177e4SLinus Torvalds
28701da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
28711da177e4SLinus Torvalds
28721da177e4SLinus Torvalds#
28731da177e4SLinus Torvalds#	copy, convert, and tag input argument
28741da177e4SLinus Torvalds#
28751da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
28761da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
28771da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
28781da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
28791da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
28801da177e4SLinus Torvalds	mov.b		%d0,%d1
28811da177e4SLinus Torvalds
28821da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
28831da177e4SLinus Torvalds
28841da177e4SLinus Torvalds	clr.l		%d0
28851da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
28861da177e4SLinus Torvalds
28871da177e4SLinus Torvalds	tst.b		%d1
28881da177e4SLinus Torvalds	bne.b		_L13_2s
28891da177e4SLinus Torvalds	bsr.l		slogn			# operand is a NORM
28901da177e4SLinus Torvalds	bra.b		_L13_6s
28911da177e4SLinus Torvalds_L13_2s:
28921da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
28931da177e4SLinus Torvalds	bne.b		_L13_3s			# no
28941da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
28951da177e4SLinus Torvalds	bra.b		_L13_6s
28961da177e4SLinus Torvalds_L13_3s:
28971da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
28981da177e4SLinus Torvalds	bne.b		_L13_4s			# no
28991da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
29001da177e4SLinus Torvalds	bra.b		_L13_6s
29011da177e4SLinus Torvalds_L13_4s:
29021da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
29031da177e4SLinus Torvalds	bne.b		_L13_5s			# no
29041da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
29051da177e4SLinus Torvalds	bra.b		_L13_6s
29061da177e4SLinus Torvalds_L13_5s:
29071da177e4SLinus Torvalds	bsr.l		slognd			# operand is a DENORM
29081da177e4SLinus Torvalds_L13_6s:
29091da177e4SLinus Torvalds
29101da177e4SLinus Torvalds#
29111da177e4SLinus Torvalds#	Result is now in FP0
29121da177e4SLinus Torvalds#
29131da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
29141da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
29151da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
29161da177e4SLinus Torvalds	unlk		%a6
29171da177e4SLinus Torvalds	rts
29181da177e4SLinus Torvalds
29191da177e4SLinus Torvalds	global		_flognd_
29201da177e4SLinus Torvalds_flognd_:
29211da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
29221da177e4SLinus Torvalds
29231da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
29241da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
29251da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
29261da177e4SLinus Torvalds
29271da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
29281da177e4SLinus Torvalds
29291da177e4SLinus Torvalds#
29301da177e4SLinus Torvalds#	copy, convert, and tag input argument
29311da177e4SLinus Torvalds#
29321da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
29331da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
29341da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
29351da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
29361da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
29371da177e4SLinus Torvalds	mov.b		%d0,%d1
29381da177e4SLinus Torvalds
29391da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
29401da177e4SLinus Torvalds
29411da177e4SLinus Torvalds	clr.l		%d0
29421da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
29431da177e4SLinus Torvalds
29441da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
29451da177e4SLinus Torvalds	tst.b		%d1
29461da177e4SLinus Torvalds	bne.b		_L13_2d
29471da177e4SLinus Torvalds	bsr.l		slogn			# operand is a NORM
29481da177e4SLinus Torvalds	bra.b		_L13_6d
29491da177e4SLinus Torvalds_L13_2d:
29501da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
29511da177e4SLinus Torvalds	bne.b		_L13_3d			# no
29521da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
29531da177e4SLinus Torvalds	bra.b		_L13_6d
29541da177e4SLinus Torvalds_L13_3d:
29551da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
29561da177e4SLinus Torvalds	bne.b		_L13_4d			# no
29571da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
29581da177e4SLinus Torvalds	bra.b		_L13_6d
29591da177e4SLinus Torvalds_L13_4d:
29601da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
29611da177e4SLinus Torvalds	bne.b		_L13_5d			# no
29621da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
29631da177e4SLinus Torvalds	bra.b		_L13_6d
29641da177e4SLinus Torvalds_L13_5d:
29651da177e4SLinus Torvalds	bsr.l		slognd			# operand is a DENORM
29661da177e4SLinus Torvalds_L13_6d:
29671da177e4SLinus Torvalds
29681da177e4SLinus Torvalds#
29691da177e4SLinus Torvalds#	Result is now in FP0
29701da177e4SLinus Torvalds#
29711da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
29721da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
29731da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
29741da177e4SLinus Torvalds	unlk		%a6
29751da177e4SLinus Torvalds	rts
29761da177e4SLinus Torvalds
29771da177e4SLinus Torvalds	global		_flognx_
29781da177e4SLinus Torvalds_flognx_:
29791da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
29801da177e4SLinus Torvalds
29811da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
29821da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
29831da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
29841da177e4SLinus Torvalds
29851da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
29861da177e4SLinus Torvalds
29871da177e4SLinus Torvalds#
29881da177e4SLinus Torvalds#	copy, convert, and tag input argument
29891da177e4SLinus Torvalds#
29901da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
29911da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
29921da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
29931da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
29941da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
29951da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
29961da177e4SLinus Torvalds	mov.b		%d0,%d1
29971da177e4SLinus Torvalds
29981da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
29991da177e4SLinus Torvalds
30001da177e4SLinus Torvalds	clr.l		%d0
30011da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
30021da177e4SLinus Torvalds
30031da177e4SLinus Torvalds	tst.b		%d1
30041da177e4SLinus Torvalds	bne.b		_L13_2x
30051da177e4SLinus Torvalds	bsr.l		slogn			# operand is a NORM
30061da177e4SLinus Torvalds	bra.b		_L13_6x
30071da177e4SLinus Torvalds_L13_2x:
30081da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
30091da177e4SLinus Torvalds	bne.b		_L13_3x			# no
30101da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
30111da177e4SLinus Torvalds	bra.b		_L13_6x
30121da177e4SLinus Torvalds_L13_3x:
30131da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
30141da177e4SLinus Torvalds	bne.b		_L13_4x			# no
30151da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
30161da177e4SLinus Torvalds	bra.b		_L13_6x
30171da177e4SLinus Torvalds_L13_4x:
30181da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
30191da177e4SLinus Torvalds	bne.b		_L13_5x			# no
30201da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
30211da177e4SLinus Torvalds	bra.b		_L13_6x
30221da177e4SLinus Torvalds_L13_5x:
30231da177e4SLinus Torvalds	bsr.l		slognd			# operand is a DENORM
30241da177e4SLinus Torvalds_L13_6x:
30251da177e4SLinus Torvalds
30261da177e4SLinus Torvalds#
30271da177e4SLinus Torvalds#	Result is now in FP0
30281da177e4SLinus Torvalds#
30291da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
30301da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
30311da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
30321da177e4SLinus Torvalds	unlk		%a6
30331da177e4SLinus Torvalds	rts
30341da177e4SLinus Torvalds
30351da177e4SLinus Torvalds
30361da177e4SLinus Torvalds#########################################################################
30371da177e4SLinus Torvalds# MONADIC TEMPLATE							#
30381da177e4SLinus Torvalds#########################################################################
30391da177e4SLinus Torvalds	global		_flog10s_
30401da177e4SLinus Torvalds_flog10s_:
30411da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
30421da177e4SLinus Torvalds
30431da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
30441da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
30451da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
30461da177e4SLinus Torvalds
30471da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
30481da177e4SLinus Torvalds
30491da177e4SLinus Torvalds#
30501da177e4SLinus Torvalds#	copy, convert, and tag input argument
30511da177e4SLinus Torvalds#
30521da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
30531da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
30541da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
30551da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
30561da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
30571da177e4SLinus Torvalds	mov.b		%d0,%d1
30581da177e4SLinus Torvalds
30591da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
30601da177e4SLinus Torvalds
30611da177e4SLinus Torvalds	clr.l		%d0
30621da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
30631da177e4SLinus Torvalds
30641da177e4SLinus Torvalds	tst.b		%d1
30651da177e4SLinus Torvalds	bne.b		_L14_2s
30661da177e4SLinus Torvalds	bsr.l		slog10			# operand is a NORM
30671da177e4SLinus Torvalds	bra.b		_L14_6s
30681da177e4SLinus Torvalds_L14_2s:
30691da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
30701da177e4SLinus Torvalds	bne.b		_L14_3s			# no
30711da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
30721da177e4SLinus Torvalds	bra.b		_L14_6s
30731da177e4SLinus Torvalds_L14_3s:
30741da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
30751da177e4SLinus Torvalds	bne.b		_L14_4s			# no
30761da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
30771da177e4SLinus Torvalds	bra.b		_L14_6s
30781da177e4SLinus Torvalds_L14_4s:
30791da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
30801da177e4SLinus Torvalds	bne.b		_L14_5s			# no
30811da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
30821da177e4SLinus Torvalds	bra.b		_L14_6s
30831da177e4SLinus Torvalds_L14_5s:
30841da177e4SLinus Torvalds	bsr.l		slog10d			# operand is a DENORM
30851da177e4SLinus Torvalds_L14_6s:
30861da177e4SLinus Torvalds
30871da177e4SLinus Torvalds#
30881da177e4SLinus Torvalds#	Result is now in FP0
30891da177e4SLinus Torvalds#
30901da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
30911da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
30921da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
30931da177e4SLinus Torvalds	unlk		%a6
30941da177e4SLinus Torvalds	rts
30951da177e4SLinus Torvalds
30961da177e4SLinus Torvalds	global		_flog10d_
30971da177e4SLinus Torvalds_flog10d_:
30981da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
30991da177e4SLinus Torvalds
31001da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
31011da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
31021da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
31031da177e4SLinus Torvalds
31041da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
31051da177e4SLinus Torvalds
31061da177e4SLinus Torvalds#
31071da177e4SLinus Torvalds#	copy, convert, and tag input argument
31081da177e4SLinus Torvalds#
31091da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
31101da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
31111da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
31121da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
31131da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
31141da177e4SLinus Torvalds	mov.b		%d0,%d1
31151da177e4SLinus Torvalds
31161da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
31171da177e4SLinus Torvalds
31181da177e4SLinus Torvalds	clr.l		%d0
31191da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
31201da177e4SLinus Torvalds
31211da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
31221da177e4SLinus Torvalds	tst.b		%d1
31231da177e4SLinus Torvalds	bne.b		_L14_2d
31241da177e4SLinus Torvalds	bsr.l		slog10			# operand is a NORM
31251da177e4SLinus Torvalds	bra.b		_L14_6d
31261da177e4SLinus Torvalds_L14_2d:
31271da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
31281da177e4SLinus Torvalds	bne.b		_L14_3d			# no
31291da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
31301da177e4SLinus Torvalds	bra.b		_L14_6d
31311da177e4SLinus Torvalds_L14_3d:
31321da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
31331da177e4SLinus Torvalds	bne.b		_L14_4d			# no
31341da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
31351da177e4SLinus Torvalds	bra.b		_L14_6d
31361da177e4SLinus Torvalds_L14_4d:
31371da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
31381da177e4SLinus Torvalds	bne.b		_L14_5d			# no
31391da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
31401da177e4SLinus Torvalds	bra.b		_L14_6d
31411da177e4SLinus Torvalds_L14_5d:
31421da177e4SLinus Torvalds	bsr.l		slog10d			# operand is a DENORM
31431da177e4SLinus Torvalds_L14_6d:
31441da177e4SLinus Torvalds
31451da177e4SLinus Torvalds#
31461da177e4SLinus Torvalds#	Result is now in FP0
31471da177e4SLinus Torvalds#
31481da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
31491da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
31501da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
31511da177e4SLinus Torvalds	unlk		%a6
31521da177e4SLinus Torvalds	rts
31531da177e4SLinus Torvalds
31541da177e4SLinus Torvalds	global		_flog10x_
31551da177e4SLinus Torvalds_flog10x_:
31561da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
31571da177e4SLinus Torvalds
31581da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
31591da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
31601da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
31611da177e4SLinus Torvalds
31621da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
31631da177e4SLinus Torvalds
31641da177e4SLinus Torvalds#
31651da177e4SLinus Torvalds#	copy, convert, and tag input argument
31661da177e4SLinus Torvalds#
31671da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
31681da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
31691da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
31701da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
31711da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
31721da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
31731da177e4SLinus Torvalds	mov.b		%d0,%d1
31741da177e4SLinus Torvalds
31751da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
31761da177e4SLinus Torvalds
31771da177e4SLinus Torvalds	clr.l		%d0
31781da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
31791da177e4SLinus Torvalds
31801da177e4SLinus Torvalds	tst.b		%d1
31811da177e4SLinus Torvalds	bne.b		_L14_2x
31821da177e4SLinus Torvalds	bsr.l		slog10			# operand is a NORM
31831da177e4SLinus Torvalds	bra.b		_L14_6x
31841da177e4SLinus Torvalds_L14_2x:
31851da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
31861da177e4SLinus Torvalds	bne.b		_L14_3x			# no
31871da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
31881da177e4SLinus Torvalds	bra.b		_L14_6x
31891da177e4SLinus Torvalds_L14_3x:
31901da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
31911da177e4SLinus Torvalds	bne.b		_L14_4x			# no
31921da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
31931da177e4SLinus Torvalds	bra.b		_L14_6x
31941da177e4SLinus Torvalds_L14_4x:
31951da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
31961da177e4SLinus Torvalds	bne.b		_L14_5x			# no
31971da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
31981da177e4SLinus Torvalds	bra.b		_L14_6x
31991da177e4SLinus Torvalds_L14_5x:
32001da177e4SLinus Torvalds	bsr.l		slog10d			# operand is a DENORM
32011da177e4SLinus Torvalds_L14_6x:
32021da177e4SLinus Torvalds
32031da177e4SLinus Torvalds#
32041da177e4SLinus Torvalds#	Result is now in FP0
32051da177e4SLinus Torvalds#
32061da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
32071da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
32081da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
32091da177e4SLinus Torvalds	unlk		%a6
32101da177e4SLinus Torvalds	rts
32111da177e4SLinus Torvalds
32121da177e4SLinus Torvalds
32131da177e4SLinus Torvalds#########################################################################
32141da177e4SLinus Torvalds# MONADIC TEMPLATE							#
32151da177e4SLinus Torvalds#########################################################################
32161da177e4SLinus Torvalds	global		_flog2s_
32171da177e4SLinus Torvalds_flog2s_:
32181da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
32191da177e4SLinus Torvalds
32201da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
32211da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
32221da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
32231da177e4SLinus Torvalds
32241da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
32251da177e4SLinus Torvalds
32261da177e4SLinus Torvalds#
32271da177e4SLinus Torvalds#	copy, convert, and tag input argument
32281da177e4SLinus Torvalds#
32291da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
32301da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
32311da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
32321da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
32331da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
32341da177e4SLinus Torvalds	mov.b		%d0,%d1
32351da177e4SLinus Torvalds
32361da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
32371da177e4SLinus Torvalds
32381da177e4SLinus Torvalds	clr.l		%d0
32391da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
32401da177e4SLinus Torvalds
32411da177e4SLinus Torvalds	tst.b		%d1
32421da177e4SLinus Torvalds	bne.b		_L15_2s
32431da177e4SLinus Torvalds	bsr.l		slog2			# operand is a NORM
32441da177e4SLinus Torvalds	bra.b		_L15_6s
32451da177e4SLinus Torvalds_L15_2s:
32461da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
32471da177e4SLinus Torvalds	bne.b		_L15_3s			# no
32481da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
32491da177e4SLinus Torvalds	bra.b		_L15_6s
32501da177e4SLinus Torvalds_L15_3s:
32511da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
32521da177e4SLinus Torvalds	bne.b		_L15_4s			# no
32531da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
32541da177e4SLinus Torvalds	bra.b		_L15_6s
32551da177e4SLinus Torvalds_L15_4s:
32561da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
32571da177e4SLinus Torvalds	bne.b		_L15_5s			# no
32581da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
32591da177e4SLinus Torvalds	bra.b		_L15_6s
32601da177e4SLinus Torvalds_L15_5s:
32611da177e4SLinus Torvalds	bsr.l		slog2d			# operand is a DENORM
32621da177e4SLinus Torvalds_L15_6s:
32631da177e4SLinus Torvalds
32641da177e4SLinus Torvalds#
32651da177e4SLinus Torvalds#	Result is now in FP0
32661da177e4SLinus Torvalds#
32671da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
32681da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
32691da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
32701da177e4SLinus Torvalds	unlk		%a6
32711da177e4SLinus Torvalds	rts
32721da177e4SLinus Torvalds
32731da177e4SLinus Torvalds	global		_flog2d_
32741da177e4SLinus Torvalds_flog2d_:
32751da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
32761da177e4SLinus Torvalds
32771da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
32781da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
32791da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
32801da177e4SLinus Torvalds
32811da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
32821da177e4SLinus Torvalds
32831da177e4SLinus Torvalds#
32841da177e4SLinus Torvalds#	copy, convert, and tag input argument
32851da177e4SLinus Torvalds#
32861da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
32871da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
32881da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
32891da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
32901da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
32911da177e4SLinus Torvalds	mov.b		%d0,%d1
32921da177e4SLinus Torvalds
32931da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
32941da177e4SLinus Torvalds
32951da177e4SLinus Torvalds	clr.l		%d0
32961da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
32971da177e4SLinus Torvalds
32981da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
32991da177e4SLinus Torvalds	tst.b		%d1
33001da177e4SLinus Torvalds	bne.b		_L15_2d
33011da177e4SLinus Torvalds	bsr.l		slog2			# operand is a NORM
33021da177e4SLinus Torvalds	bra.b		_L15_6d
33031da177e4SLinus Torvalds_L15_2d:
33041da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
33051da177e4SLinus Torvalds	bne.b		_L15_3d			# no
33061da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
33071da177e4SLinus Torvalds	bra.b		_L15_6d
33081da177e4SLinus Torvalds_L15_3d:
33091da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
33101da177e4SLinus Torvalds	bne.b		_L15_4d			# no
33111da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
33121da177e4SLinus Torvalds	bra.b		_L15_6d
33131da177e4SLinus Torvalds_L15_4d:
33141da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
33151da177e4SLinus Torvalds	bne.b		_L15_5d			# no
33161da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
33171da177e4SLinus Torvalds	bra.b		_L15_6d
33181da177e4SLinus Torvalds_L15_5d:
33191da177e4SLinus Torvalds	bsr.l		slog2d			# operand is a DENORM
33201da177e4SLinus Torvalds_L15_6d:
33211da177e4SLinus Torvalds
33221da177e4SLinus Torvalds#
33231da177e4SLinus Torvalds#	Result is now in FP0
33241da177e4SLinus Torvalds#
33251da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
33261da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
33271da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
33281da177e4SLinus Torvalds	unlk		%a6
33291da177e4SLinus Torvalds	rts
33301da177e4SLinus Torvalds
33311da177e4SLinus Torvalds	global		_flog2x_
33321da177e4SLinus Torvalds_flog2x_:
33331da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
33341da177e4SLinus Torvalds
33351da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
33361da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
33371da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
33381da177e4SLinus Torvalds
33391da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
33401da177e4SLinus Torvalds
33411da177e4SLinus Torvalds#
33421da177e4SLinus Torvalds#	copy, convert, and tag input argument
33431da177e4SLinus Torvalds#
33441da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
33451da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
33461da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
33471da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
33481da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
33491da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
33501da177e4SLinus Torvalds	mov.b		%d0,%d1
33511da177e4SLinus Torvalds
33521da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
33531da177e4SLinus Torvalds
33541da177e4SLinus Torvalds	clr.l		%d0
33551da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
33561da177e4SLinus Torvalds
33571da177e4SLinus Torvalds	tst.b		%d1
33581da177e4SLinus Torvalds	bne.b		_L15_2x
33591da177e4SLinus Torvalds	bsr.l		slog2			# operand is a NORM
33601da177e4SLinus Torvalds	bra.b		_L15_6x
33611da177e4SLinus Torvalds_L15_2x:
33621da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
33631da177e4SLinus Torvalds	bne.b		_L15_3x			# no
33641da177e4SLinus Torvalds	bsr.l		t_dz2			# yes
33651da177e4SLinus Torvalds	bra.b		_L15_6x
33661da177e4SLinus Torvalds_L15_3x:
33671da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
33681da177e4SLinus Torvalds	bne.b		_L15_4x			# no
33691da177e4SLinus Torvalds	bsr.l		sopr_inf			# yes
33701da177e4SLinus Torvalds	bra.b		_L15_6x
33711da177e4SLinus Torvalds_L15_4x:
33721da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
33731da177e4SLinus Torvalds	bne.b		_L15_5x			# no
33741da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
33751da177e4SLinus Torvalds	bra.b		_L15_6x
33761da177e4SLinus Torvalds_L15_5x:
33771da177e4SLinus Torvalds	bsr.l		slog2d			# operand is a DENORM
33781da177e4SLinus Torvalds_L15_6x:
33791da177e4SLinus Torvalds
33801da177e4SLinus Torvalds#
33811da177e4SLinus Torvalds#	Result is now in FP0
33821da177e4SLinus Torvalds#
33831da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
33841da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
33851da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
33861da177e4SLinus Torvalds	unlk		%a6
33871da177e4SLinus Torvalds	rts
33881da177e4SLinus Torvalds
33891da177e4SLinus Torvalds
33901da177e4SLinus Torvalds#########################################################################
33911da177e4SLinus Torvalds# MONADIC TEMPLATE							#
33921da177e4SLinus Torvalds#########################################################################
33931da177e4SLinus Torvalds	global		_fcoshs_
33941da177e4SLinus Torvalds_fcoshs_:
33951da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
33961da177e4SLinus Torvalds
33971da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
33981da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
33991da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
34001da177e4SLinus Torvalds
34011da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
34021da177e4SLinus Torvalds
34031da177e4SLinus Torvalds#
34041da177e4SLinus Torvalds#	copy, convert, and tag input argument
34051da177e4SLinus Torvalds#
34061da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
34071da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
34081da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
34091da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
34101da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
34111da177e4SLinus Torvalds	mov.b		%d0,%d1
34121da177e4SLinus Torvalds
34131da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
34141da177e4SLinus Torvalds
34151da177e4SLinus Torvalds	clr.l		%d0
34161da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
34171da177e4SLinus Torvalds
34181da177e4SLinus Torvalds	tst.b		%d1
34191da177e4SLinus Torvalds	bne.b		_L16_2s
34201da177e4SLinus Torvalds	bsr.l		scosh			# operand is a NORM
34211da177e4SLinus Torvalds	bra.b		_L16_6s
34221da177e4SLinus Torvalds_L16_2s:
34231da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
34241da177e4SLinus Torvalds	bne.b		_L16_3s			# no
34251da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
34261da177e4SLinus Torvalds	bra.b		_L16_6s
34271da177e4SLinus Torvalds_L16_3s:
34281da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
34291da177e4SLinus Torvalds	bne.b		_L16_4s			# no
34301da177e4SLinus Torvalds	bsr.l		ld_pinf			# yes
34311da177e4SLinus Torvalds	bra.b		_L16_6s
34321da177e4SLinus Torvalds_L16_4s:
34331da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
34341da177e4SLinus Torvalds	bne.b		_L16_5s			# no
34351da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
34361da177e4SLinus Torvalds	bra.b		_L16_6s
34371da177e4SLinus Torvalds_L16_5s:
34381da177e4SLinus Torvalds	bsr.l		scoshd			# operand is a DENORM
34391da177e4SLinus Torvalds_L16_6s:
34401da177e4SLinus Torvalds
34411da177e4SLinus Torvalds#
34421da177e4SLinus Torvalds#	Result is now in FP0
34431da177e4SLinus Torvalds#
34441da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
34451da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
34461da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
34471da177e4SLinus Torvalds	unlk		%a6
34481da177e4SLinus Torvalds	rts
34491da177e4SLinus Torvalds
34501da177e4SLinus Torvalds	global		_fcoshd_
34511da177e4SLinus Torvalds_fcoshd_:
34521da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
34531da177e4SLinus Torvalds
34541da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
34551da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
34561da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
34571da177e4SLinus Torvalds
34581da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
34591da177e4SLinus Torvalds
34601da177e4SLinus Torvalds#
34611da177e4SLinus Torvalds#	copy, convert, and tag input argument
34621da177e4SLinus Torvalds#
34631da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
34641da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
34651da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
34661da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
34671da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
34681da177e4SLinus Torvalds	mov.b		%d0,%d1
34691da177e4SLinus Torvalds
34701da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
34711da177e4SLinus Torvalds
34721da177e4SLinus Torvalds	clr.l		%d0
34731da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
34741da177e4SLinus Torvalds
34751da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
34761da177e4SLinus Torvalds	tst.b		%d1
34771da177e4SLinus Torvalds	bne.b		_L16_2d
34781da177e4SLinus Torvalds	bsr.l		scosh			# operand is a NORM
34791da177e4SLinus Torvalds	bra.b		_L16_6d
34801da177e4SLinus Torvalds_L16_2d:
34811da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
34821da177e4SLinus Torvalds	bne.b		_L16_3d			# no
34831da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
34841da177e4SLinus Torvalds	bra.b		_L16_6d
34851da177e4SLinus Torvalds_L16_3d:
34861da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
34871da177e4SLinus Torvalds	bne.b		_L16_4d			# no
34881da177e4SLinus Torvalds	bsr.l		ld_pinf			# yes
34891da177e4SLinus Torvalds	bra.b		_L16_6d
34901da177e4SLinus Torvalds_L16_4d:
34911da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
34921da177e4SLinus Torvalds	bne.b		_L16_5d			# no
34931da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
34941da177e4SLinus Torvalds	bra.b		_L16_6d
34951da177e4SLinus Torvalds_L16_5d:
34961da177e4SLinus Torvalds	bsr.l		scoshd			# operand is a DENORM
34971da177e4SLinus Torvalds_L16_6d:
34981da177e4SLinus Torvalds
34991da177e4SLinus Torvalds#
35001da177e4SLinus Torvalds#	Result is now in FP0
35011da177e4SLinus Torvalds#
35021da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
35031da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
35041da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
35051da177e4SLinus Torvalds	unlk		%a6
35061da177e4SLinus Torvalds	rts
35071da177e4SLinus Torvalds
35081da177e4SLinus Torvalds	global		_fcoshx_
35091da177e4SLinus Torvalds_fcoshx_:
35101da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
35111da177e4SLinus Torvalds
35121da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
35131da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
35141da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
35151da177e4SLinus Torvalds
35161da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
35171da177e4SLinus Torvalds
35181da177e4SLinus Torvalds#
35191da177e4SLinus Torvalds#	copy, convert, and tag input argument
35201da177e4SLinus Torvalds#
35211da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
35221da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
35231da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
35241da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
35251da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
35261da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
35271da177e4SLinus Torvalds	mov.b		%d0,%d1
35281da177e4SLinus Torvalds
35291da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
35301da177e4SLinus Torvalds
35311da177e4SLinus Torvalds	clr.l		%d0
35321da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
35331da177e4SLinus Torvalds
35341da177e4SLinus Torvalds	tst.b		%d1
35351da177e4SLinus Torvalds	bne.b		_L16_2x
35361da177e4SLinus Torvalds	bsr.l		scosh			# operand is a NORM
35371da177e4SLinus Torvalds	bra.b		_L16_6x
35381da177e4SLinus Torvalds_L16_2x:
35391da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
35401da177e4SLinus Torvalds	bne.b		_L16_3x			# no
35411da177e4SLinus Torvalds	bsr.l		ld_pone			# yes
35421da177e4SLinus Torvalds	bra.b		_L16_6x
35431da177e4SLinus Torvalds_L16_3x:
35441da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
35451da177e4SLinus Torvalds	bne.b		_L16_4x			# no
35461da177e4SLinus Torvalds	bsr.l		ld_pinf			# yes
35471da177e4SLinus Torvalds	bra.b		_L16_6x
35481da177e4SLinus Torvalds_L16_4x:
35491da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
35501da177e4SLinus Torvalds	bne.b		_L16_5x			# no
35511da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
35521da177e4SLinus Torvalds	bra.b		_L16_6x
35531da177e4SLinus Torvalds_L16_5x:
35541da177e4SLinus Torvalds	bsr.l		scoshd			# operand is a DENORM
35551da177e4SLinus Torvalds_L16_6x:
35561da177e4SLinus Torvalds
35571da177e4SLinus Torvalds#
35581da177e4SLinus Torvalds#	Result is now in FP0
35591da177e4SLinus Torvalds#
35601da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
35611da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
35621da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
35631da177e4SLinus Torvalds	unlk		%a6
35641da177e4SLinus Torvalds	rts
35651da177e4SLinus Torvalds
35661da177e4SLinus Torvalds
35671da177e4SLinus Torvalds#########################################################################
35681da177e4SLinus Torvalds# MONADIC TEMPLATE							#
35691da177e4SLinus Torvalds#########################################################################
35701da177e4SLinus Torvalds	global		_facoss_
35711da177e4SLinus Torvalds_facoss_:
35721da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
35731da177e4SLinus Torvalds
35741da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
35751da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
35761da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
35771da177e4SLinus Torvalds
35781da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
35791da177e4SLinus Torvalds
35801da177e4SLinus Torvalds#
35811da177e4SLinus Torvalds#	copy, convert, and tag input argument
35821da177e4SLinus Torvalds#
35831da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
35841da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
35851da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
35861da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
35871da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
35881da177e4SLinus Torvalds	mov.b		%d0,%d1
35891da177e4SLinus Torvalds
35901da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
35911da177e4SLinus Torvalds
35921da177e4SLinus Torvalds	clr.l		%d0
35931da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
35941da177e4SLinus Torvalds
35951da177e4SLinus Torvalds	tst.b		%d1
35961da177e4SLinus Torvalds	bne.b		_L17_2s
35971da177e4SLinus Torvalds	bsr.l		sacos			# operand is a NORM
35981da177e4SLinus Torvalds	bra.b		_L17_6s
35991da177e4SLinus Torvalds_L17_2s:
36001da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
36011da177e4SLinus Torvalds	bne.b		_L17_3s			# no
36021da177e4SLinus Torvalds	bsr.l		ld_ppi2			# yes
36031da177e4SLinus Torvalds	bra.b		_L17_6s
36041da177e4SLinus Torvalds_L17_3s:
36051da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
36061da177e4SLinus Torvalds	bne.b		_L17_4s			# no
36071da177e4SLinus Torvalds	bsr.l		t_operr			# yes
36081da177e4SLinus Torvalds	bra.b		_L17_6s
36091da177e4SLinus Torvalds_L17_4s:
36101da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
36111da177e4SLinus Torvalds	bne.b		_L17_5s			# no
36121da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
36131da177e4SLinus Torvalds	bra.b		_L17_6s
36141da177e4SLinus Torvalds_L17_5s:
36151da177e4SLinus Torvalds	bsr.l		sacosd			# operand is a DENORM
36161da177e4SLinus Torvalds_L17_6s:
36171da177e4SLinus Torvalds
36181da177e4SLinus Torvalds#
36191da177e4SLinus Torvalds#	Result is now in FP0
36201da177e4SLinus Torvalds#
36211da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
36221da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
36231da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
36241da177e4SLinus Torvalds	unlk		%a6
36251da177e4SLinus Torvalds	rts
36261da177e4SLinus Torvalds
36271da177e4SLinus Torvalds	global		_facosd_
36281da177e4SLinus Torvalds_facosd_:
36291da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
36301da177e4SLinus Torvalds
36311da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
36321da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
36331da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
36341da177e4SLinus Torvalds
36351da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
36361da177e4SLinus Torvalds
36371da177e4SLinus Torvalds#
36381da177e4SLinus Torvalds#	copy, convert, and tag input argument
36391da177e4SLinus Torvalds#
36401da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
36411da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
36421da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
36431da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
36441da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
36451da177e4SLinus Torvalds	mov.b		%d0,%d1
36461da177e4SLinus Torvalds
36471da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
36481da177e4SLinus Torvalds
36491da177e4SLinus Torvalds	clr.l		%d0
36501da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
36511da177e4SLinus Torvalds
36521da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
36531da177e4SLinus Torvalds	tst.b		%d1
36541da177e4SLinus Torvalds	bne.b		_L17_2d
36551da177e4SLinus Torvalds	bsr.l		sacos			# operand is a NORM
36561da177e4SLinus Torvalds	bra.b		_L17_6d
36571da177e4SLinus Torvalds_L17_2d:
36581da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
36591da177e4SLinus Torvalds	bne.b		_L17_3d			# no
36601da177e4SLinus Torvalds	bsr.l		ld_ppi2			# yes
36611da177e4SLinus Torvalds	bra.b		_L17_6d
36621da177e4SLinus Torvalds_L17_3d:
36631da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
36641da177e4SLinus Torvalds	bne.b		_L17_4d			# no
36651da177e4SLinus Torvalds	bsr.l		t_operr			# yes
36661da177e4SLinus Torvalds	bra.b		_L17_6d
36671da177e4SLinus Torvalds_L17_4d:
36681da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
36691da177e4SLinus Torvalds	bne.b		_L17_5d			# no
36701da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
36711da177e4SLinus Torvalds	bra.b		_L17_6d
36721da177e4SLinus Torvalds_L17_5d:
36731da177e4SLinus Torvalds	bsr.l		sacosd			# operand is a DENORM
36741da177e4SLinus Torvalds_L17_6d:
36751da177e4SLinus Torvalds
36761da177e4SLinus Torvalds#
36771da177e4SLinus Torvalds#	Result is now in FP0
36781da177e4SLinus Torvalds#
36791da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
36801da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
36811da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
36821da177e4SLinus Torvalds	unlk		%a6
36831da177e4SLinus Torvalds	rts
36841da177e4SLinus Torvalds
36851da177e4SLinus Torvalds	global		_facosx_
36861da177e4SLinus Torvalds_facosx_:
36871da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
36881da177e4SLinus Torvalds
36891da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
36901da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
36911da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
36921da177e4SLinus Torvalds
36931da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
36941da177e4SLinus Torvalds
36951da177e4SLinus Torvalds#
36961da177e4SLinus Torvalds#	copy, convert, and tag input argument
36971da177e4SLinus Torvalds#
36981da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
36991da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
37001da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
37011da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
37021da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
37031da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
37041da177e4SLinus Torvalds	mov.b		%d0,%d1
37051da177e4SLinus Torvalds
37061da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
37071da177e4SLinus Torvalds
37081da177e4SLinus Torvalds	clr.l		%d0
37091da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
37101da177e4SLinus Torvalds
37111da177e4SLinus Torvalds	tst.b		%d1
37121da177e4SLinus Torvalds	bne.b		_L17_2x
37131da177e4SLinus Torvalds	bsr.l		sacos			# operand is a NORM
37141da177e4SLinus Torvalds	bra.b		_L17_6x
37151da177e4SLinus Torvalds_L17_2x:
37161da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
37171da177e4SLinus Torvalds	bne.b		_L17_3x			# no
37181da177e4SLinus Torvalds	bsr.l		ld_ppi2			# yes
37191da177e4SLinus Torvalds	bra.b		_L17_6x
37201da177e4SLinus Torvalds_L17_3x:
37211da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
37221da177e4SLinus Torvalds	bne.b		_L17_4x			# no
37231da177e4SLinus Torvalds	bsr.l		t_operr			# yes
37241da177e4SLinus Torvalds	bra.b		_L17_6x
37251da177e4SLinus Torvalds_L17_4x:
37261da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
37271da177e4SLinus Torvalds	bne.b		_L17_5x			# no
37281da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
37291da177e4SLinus Torvalds	bra.b		_L17_6x
37301da177e4SLinus Torvalds_L17_5x:
37311da177e4SLinus Torvalds	bsr.l		sacosd			# operand is a DENORM
37321da177e4SLinus Torvalds_L17_6x:
37331da177e4SLinus Torvalds
37341da177e4SLinus Torvalds#
37351da177e4SLinus Torvalds#	Result is now in FP0
37361da177e4SLinus Torvalds#
37371da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
37381da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
37391da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
37401da177e4SLinus Torvalds	unlk		%a6
37411da177e4SLinus Torvalds	rts
37421da177e4SLinus Torvalds
37431da177e4SLinus Torvalds
37441da177e4SLinus Torvalds#########################################################################
37451da177e4SLinus Torvalds# MONADIC TEMPLATE							#
37461da177e4SLinus Torvalds#########################################################################
37471da177e4SLinus Torvalds	global		_fgetexps_
37481da177e4SLinus Torvalds_fgetexps_:
37491da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
37501da177e4SLinus Torvalds
37511da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
37521da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
37531da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
37541da177e4SLinus Torvalds
37551da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
37561da177e4SLinus Torvalds
37571da177e4SLinus Torvalds#
37581da177e4SLinus Torvalds#	copy, convert, and tag input argument
37591da177e4SLinus Torvalds#
37601da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
37611da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
37621da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
37631da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
37641da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
37651da177e4SLinus Torvalds	mov.b		%d0,%d1
37661da177e4SLinus Torvalds
37671da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
37681da177e4SLinus Torvalds
37691da177e4SLinus Torvalds	clr.l		%d0
37701da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
37711da177e4SLinus Torvalds
37721da177e4SLinus Torvalds	tst.b		%d1
37731da177e4SLinus Torvalds	bne.b		_L18_2s
37741da177e4SLinus Torvalds	bsr.l		sgetexp			# operand is a NORM
37751da177e4SLinus Torvalds	bra.b		_L18_6s
37761da177e4SLinus Torvalds_L18_2s:
37771da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
37781da177e4SLinus Torvalds	bne.b		_L18_3s			# no
37791da177e4SLinus Torvalds	bsr.l		src_zero			# yes
37801da177e4SLinus Torvalds	bra.b		_L18_6s
37811da177e4SLinus Torvalds_L18_3s:
37821da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
37831da177e4SLinus Torvalds	bne.b		_L18_4s			# no
37841da177e4SLinus Torvalds	bsr.l		t_operr			# yes
37851da177e4SLinus Torvalds	bra.b		_L18_6s
37861da177e4SLinus Torvalds_L18_4s:
37871da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
37881da177e4SLinus Torvalds	bne.b		_L18_5s			# no
37891da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
37901da177e4SLinus Torvalds	bra.b		_L18_6s
37911da177e4SLinus Torvalds_L18_5s:
37921da177e4SLinus Torvalds	bsr.l		sgetexpd			# operand is a DENORM
37931da177e4SLinus Torvalds_L18_6s:
37941da177e4SLinus Torvalds
37951da177e4SLinus Torvalds#
37961da177e4SLinus Torvalds#	Result is now in FP0
37971da177e4SLinus Torvalds#
37981da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
37991da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
38001da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
38011da177e4SLinus Torvalds	unlk		%a6
38021da177e4SLinus Torvalds	rts
38031da177e4SLinus Torvalds
38041da177e4SLinus Torvalds	global		_fgetexpd_
38051da177e4SLinus Torvalds_fgetexpd_:
38061da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
38071da177e4SLinus Torvalds
38081da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
38091da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
38101da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
38111da177e4SLinus Torvalds
38121da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
38131da177e4SLinus Torvalds
38141da177e4SLinus Torvalds#
38151da177e4SLinus Torvalds#	copy, convert, and tag input argument
38161da177e4SLinus Torvalds#
38171da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
38181da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
38191da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
38201da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
38211da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
38221da177e4SLinus Torvalds	mov.b		%d0,%d1
38231da177e4SLinus Torvalds
38241da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
38251da177e4SLinus Torvalds
38261da177e4SLinus Torvalds	clr.l		%d0
38271da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
38281da177e4SLinus Torvalds
38291da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
38301da177e4SLinus Torvalds	tst.b		%d1
38311da177e4SLinus Torvalds	bne.b		_L18_2d
38321da177e4SLinus Torvalds	bsr.l		sgetexp			# operand is a NORM
38331da177e4SLinus Torvalds	bra.b		_L18_6d
38341da177e4SLinus Torvalds_L18_2d:
38351da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
38361da177e4SLinus Torvalds	bne.b		_L18_3d			# no
38371da177e4SLinus Torvalds	bsr.l		src_zero			# yes
38381da177e4SLinus Torvalds	bra.b		_L18_6d
38391da177e4SLinus Torvalds_L18_3d:
38401da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
38411da177e4SLinus Torvalds	bne.b		_L18_4d			# no
38421da177e4SLinus Torvalds	bsr.l		t_operr			# yes
38431da177e4SLinus Torvalds	bra.b		_L18_6d
38441da177e4SLinus Torvalds_L18_4d:
38451da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
38461da177e4SLinus Torvalds	bne.b		_L18_5d			# no
38471da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
38481da177e4SLinus Torvalds	bra.b		_L18_6d
38491da177e4SLinus Torvalds_L18_5d:
38501da177e4SLinus Torvalds	bsr.l		sgetexpd			# operand is a DENORM
38511da177e4SLinus Torvalds_L18_6d:
38521da177e4SLinus Torvalds
38531da177e4SLinus Torvalds#
38541da177e4SLinus Torvalds#	Result is now in FP0
38551da177e4SLinus Torvalds#
38561da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
38571da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
38581da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
38591da177e4SLinus Torvalds	unlk		%a6
38601da177e4SLinus Torvalds	rts
38611da177e4SLinus Torvalds
38621da177e4SLinus Torvalds	global		_fgetexpx_
38631da177e4SLinus Torvalds_fgetexpx_:
38641da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
38651da177e4SLinus Torvalds
38661da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
38671da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
38681da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
38691da177e4SLinus Torvalds
38701da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
38711da177e4SLinus Torvalds
38721da177e4SLinus Torvalds#
38731da177e4SLinus Torvalds#	copy, convert, and tag input argument
38741da177e4SLinus Torvalds#
38751da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
38761da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
38771da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
38781da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
38791da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
38801da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
38811da177e4SLinus Torvalds	mov.b		%d0,%d1
38821da177e4SLinus Torvalds
38831da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
38841da177e4SLinus Torvalds
38851da177e4SLinus Torvalds	clr.l		%d0
38861da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
38871da177e4SLinus Torvalds
38881da177e4SLinus Torvalds	tst.b		%d1
38891da177e4SLinus Torvalds	bne.b		_L18_2x
38901da177e4SLinus Torvalds	bsr.l		sgetexp			# operand is a NORM
38911da177e4SLinus Torvalds	bra.b		_L18_6x
38921da177e4SLinus Torvalds_L18_2x:
38931da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
38941da177e4SLinus Torvalds	bne.b		_L18_3x			# no
38951da177e4SLinus Torvalds	bsr.l		src_zero			# yes
38961da177e4SLinus Torvalds	bra.b		_L18_6x
38971da177e4SLinus Torvalds_L18_3x:
38981da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
38991da177e4SLinus Torvalds	bne.b		_L18_4x			# no
39001da177e4SLinus Torvalds	bsr.l		t_operr			# yes
39011da177e4SLinus Torvalds	bra.b		_L18_6x
39021da177e4SLinus Torvalds_L18_4x:
39031da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
39041da177e4SLinus Torvalds	bne.b		_L18_5x			# no
39051da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
39061da177e4SLinus Torvalds	bra.b		_L18_6x
39071da177e4SLinus Torvalds_L18_5x:
39081da177e4SLinus Torvalds	bsr.l		sgetexpd			# operand is a DENORM
39091da177e4SLinus Torvalds_L18_6x:
39101da177e4SLinus Torvalds
39111da177e4SLinus Torvalds#
39121da177e4SLinus Torvalds#	Result is now in FP0
39131da177e4SLinus Torvalds#
39141da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
39151da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
39161da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
39171da177e4SLinus Torvalds	unlk		%a6
39181da177e4SLinus Torvalds	rts
39191da177e4SLinus Torvalds
39201da177e4SLinus Torvalds
39211da177e4SLinus Torvalds#########################################################################
39221da177e4SLinus Torvalds# MONADIC TEMPLATE							#
39231da177e4SLinus Torvalds#########################################################################
39241da177e4SLinus Torvalds	global		_fgetmans_
39251da177e4SLinus Torvalds_fgetmans_:
39261da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
39271da177e4SLinus Torvalds
39281da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
39291da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
39301da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
39311da177e4SLinus Torvalds
39321da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
39331da177e4SLinus Torvalds
39341da177e4SLinus Torvalds#
39351da177e4SLinus Torvalds#	copy, convert, and tag input argument
39361da177e4SLinus Torvalds#
39371da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
39381da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
39391da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
39401da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
39411da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
39421da177e4SLinus Torvalds	mov.b		%d0,%d1
39431da177e4SLinus Torvalds
39441da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
39451da177e4SLinus Torvalds
39461da177e4SLinus Torvalds	clr.l		%d0
39471da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
39481da177e4SLinus Torvalds
39491da177e4SLinus Torvalds	tst.b		%d1
39501da177e4SLinus Torvalds	bne.b		_L19_2s
39511da177e4SLinus Torvalds	bsr.l		sgetman			# operand is a NORM
39521da177e4SLinus Torvalds	bra.b		_L19_6s
39531da177e4SLinus Torvalds_L19_2s:
39541da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
39551da177e4SLinus Torvalds	bne.b		_L19_3s			# no
39561da177e4SLinus Torvalds	bsr.l		src_zero			# yes
39571da177e4SLinus Torvalds	bra.b		_L19_6s
39581da177e4SLinus Torvalds_L19_3s:
39591da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
39601da177e4SLinus Torvalds	bne.b		_L19_4s			# no
39611da177e4SLinus Torvalds	bsr.l		t_operr			# yes
39621da177e4SLinus Torvalds	bra.b		_L19_6s
39631da177e4SLinus Torvalds_L19_4s:
39641da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
39651da177e4SLinus Torvalds	bne.b		_L19_5s			# no
39661da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
39671da177e4SLinus Torvalds	bra.b		_L19_6s
39681da177e4SLinus Torvalds_L19_5s:
39691da177e4SLinus Torvalds	bsr.l		sgetmand			# operand is a DENORM
39701da177e4SLinus Torvalds_L19_6s:
39711da177e4SLinus Torvalds
39721da177e4SLinus Torvalds#
39731da177e4SLinus Torvalds#	Result is now in FP0
39741da177e4SLinus Torvalds#
39751da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
39761da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
39771da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
39781da177e4SLinus Torvalds	unlk		%a6
39791da177e4SLinus Torvalds	rts
39801da177e4SLinus Torvalds
39811da177e4SLinus Torvalds	global		_fgetmand_
39821da177e4SLinus Torvalds_fgetmand_:
39831da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
39841da177e4SLinus Torvalds
39851da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
39861da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
39871da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
39881da177e4SLinus Torvalds
39891da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
39901da177e4SLinus Torvalds
39911da177e4SLinus Torvalds#
39921da177e4SLinus Torvalds#	copy, convert, and tag input argument
39931da177e4SLinus Torvalds#
39941da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
39951da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
39961da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
39971da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
39981da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
39991da177e4SLinus Torvalds	mov.b		%d0,%d1
40001da177e4SLinus Torvalds
40011da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
40021da177e4SLinus Torvalds
40031da177e4SLinus Torvalds	clr.l		%d0
40041da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
40051da177e4SLinus Torvalds
40061da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
40071da177e4SLinus Torvalds	tst.b		%d1
40081da177e4SLinus Torvalds	bne.b		_L19_2d
40091da177e4SLinus Torvalds	bsr.l		sgetman			# operand is a NORM
40101da177e4SLinus Torvalds	bra.b		_L19_6d
40111da177e4SLinus Torvalds_L19_2d:
40121da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
40131da177e4SLinus Torvalds	bne.b		_L19_3d			# no
40141da177e4SLinus Torvalds	bsr.l		src_zero			# yes
40151da177e4SLinus Torvalds	bra.b		_L19_6d
40161da177e4SLinus Torvalds_L19_3d:
40171da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
40181da177e4SLinus Torvalds	bne.b		_L19_4d			# no
40191da177e4SLinus Torvalds	bsr.l		t_operr			# yes
40201da177e4SLinus Torvalds	bra.b		_L19_6d
40211da177e4SLinus Torvalds_L19_4d:
40221da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
40231da177e4SLinus Torvalds	bne.b		_L19_5d			# no
40241da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
40251da177e4SLinus Torvalds	bra.b		_L19_6d
40261da177e4SLinus Torvalds_L19_5d:
40271da177e4SLinus Torvalds	bsr.l		sgetmand			# operand is a DENORM
40281da177e4SLinus Torvalds_L19_6d:
40291da177e4SLinus Torvalds
40301da177e4SLinus Torvalds#
40311da177e4SLinus Torvalds#	Result is now in FP0
40321da177e4SLinus Torvalds#
40331da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
40341da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
40351da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
40361da177e4SLinus Torvalds	unlk		%a6
40371da177e4SLinus Torvalds	rts
40381da177e4SLinus Torvalds
40391da177e4SLinus Torvalds	global		_fgetmanx_
40401da177e4SLinus Torvalds_fgetmanx_:
40411da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
40421da177e4SLinus Torvalds
40431da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
40441da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
40451da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
40461da177e4SLinus Torvalds
40471da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
40481da177e4SLinus Torvalds
40491da177e4SLinus Torvalds#
40501da177e4SLinus Torvalds#	copy, convert, and tag input argument
40511da177e4SLinus Torvalds#
40521da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
40531da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
40541da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
40551da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
40561da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
40571da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
40581da177e4SLinus Torvalds	mov.b		%d0,%d1
40591da177e4SLinus Torvalds
40601da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
40611da177e4SLinus Torvalds
40621da177e4SLinus Torvalds	clr.l		%d0
40631da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
40641da177e4SLinus Torvalds
40651da177e4SLinus Torvalds	tst.b		%d1
40661da177e4SLinus Torvalds	bne.b		_L19_2x
40671da177e4SLinus Torvalds	bsr.l		sgetman			# operand is a NORM
40681da177e4SLinus Torvalds	bra.b		_L19_6x
40691da177e4SLinus Torvalds_L19_2x:
40701da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
40711da177e4SLinus Torvalds	bne.b		_L19_3x			# no
40721da177e4SLinus Torvalds	bsr.l		src_zero			# yes
40731da177e4SLinus Torvalds	bra.b		_L19_6x
40741da177e4SLinus Torvalds_L19_3x:
40751da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
40761da177e4SLinus Torvalds	bne.b		_L19_4x			# no
40771da177e4SLinus Torvalds	bsr.l		t_operr			# yes
40781da177e4SLinus Torvalds	bra.b		_L19_6x
40791da177e4SLinus Torvalds_L19_4x:
40801da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
40811da177e4SLinus Torvalds	bne.b		_L19_5x			# no
40821da177e4SLinus Torvalds	bsr.l		src_qnan			# yes
40831da177e4SLinus Torvalds	bra.b		_L19_6x
40841da177e4SLinus Torvalds_L19_5x:
40851da177e4SLinus Torvalds	bsr.l		sgetmand			# operand is a DENORM
40861da177e4SLinus Torvalds_L19_6x:
40871da177e4SLinus Torvalds
40881da177e4SLinus Torvalds#
40891da177e4SLinus Torvalds#	Result is now in FP0
40901da177e4SLinus Torvalds#
40911da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
40921da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
40931da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
40941da177e4SLinus Torvalds	unlk		%a6
40951da177e4SLinus Torvalds	rts
40961da177e4SLinus Torvalds
40971da177e4SLinus Torvalds
40981da177e4SLinus Torvalds#########################################################################
40991da177e4SLinus Torvalds# MONADIC TEMPLATE							#
41001da177e4SLinus Torvalds#########################################################################
41011da177e4SLinus Torvalds	global		_fsincoss_
41021da177e4SLinus Torvalds_fsincoss_:
41031da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
41041da177e4SLinus Torvalds
41051da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
41061da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
41071da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
41081da177e4SLinus Torvalds
41091da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
41101da177e4SLinus Torvalds
41111da177e4SLinus Torvalds#
41121da177e4SLinus Torvalds#	copy, convert, and tag input argument
41131da177e4SLinus Torvalds#
41141da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl input
41151da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
41161da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
41171da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
41181da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
41191da177e4SLinus Torvalds	mov.b		%d0,%d1
41201da177e4SLinus Torvalds
41211da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
41221da177e4SLinus Torvalds
41231da177e4SLinus Torvalds	clr.l		%d0
41241da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
41251da177e4SLinus Torvalds
41261da177e4SLinus Torvalds	tst.b		%d1
41271da177e4SLinus Torvalds	bne.b		_L20_2s
41281da177e4SLinus Torvalds	bsr.l		ssincos			# operand is a NORM
41291da177e4SLinus Torvalds	bra.b		_L20_6s
41301da177e4SLinus Torvalds_L20_2s:
41311da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
41321da177e4SLinus Torvalds	bne.b		_L20_3s			# no
41331da177e4SLinus Torvalds	bsr.l		ssincosz			# yes
41341da177e4SLinus Torvalds	bra.b		_L20_6s
41351da177e4SLinus Torvalds_L20_3s:
41361da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
41371da177e4SLinus Torvalds	bne.b		_L20_4s			# no
41381da177e4SLinus Torvalds	bsr.l		ssincosi			# yes
41391da177e4SLinus Torvalds	bra.b		_L20_6s
41401da177e4SLinus Torvalds_L20_4s:
41411da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
41421da177e4SLinus Torvalds	bne.b		_L20_5s			# no
41431da177e4SLinus Torvalds	bsr.l		ssincosqnan			# yes
41441da177e4SLinus Torvalds	bra.b		_L20_6s
41451da177e4SLinus Torvalds_L20_5s:
41461da177e4SLinus Torvalds	bsr.l		ssincosd			# operand is a DENORM
41471da177e4SLinus Torvalds_L20_6s:
41481da177e4SLinus Torvalds
41491da177e4SLinus Torvalds#
41501da177e4SLinus Torvalds#	Result is now in FP0
41511da177e4SLinus Torvalds#
41521da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
41531da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
41541da177e4SLinus Torvalds	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
41551da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
41561da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
41571da177e4SLinus Torvalds	unlk		%a6
41581da177e4SLinus Torvalds	rts
41591da177e4SLinus Torvalds
41601da177e4SLinus Torvalds	global		_fsincosd_
41611da177e4SLinus Torvalds_fsincosd_:
41621da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
41631da177e4SLinus Torvalds
41641da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
41651da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
41661da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
41671da177e4SLinus Torvalds
41681da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
41691da177e4SLinus Torvalds
41701da177e4SLinus Torvalds#
41711da177e4SLinus Torvalds#	copy, convert, and tag input argument
41721da177e4SLinus Torvalds#
41731da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl input
41741da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
41751da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
41761da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
41771da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
41781da177e4SLinus Torvalds	mov.b		%d0,%d1
41791da177e4SLinus Torvalds
41801da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
41811da177e4SLinus Torvalds
41821da177e4SLinus Torvalds	clr.l		%d0
41831da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
41841da177e4SLinus Torvalds
41851da177e4SLinus Torvalds	mov.b		%d1,STAG(%a6)
41861da177e4SLinus Torvalds	tst.b		%d1
41871da177e4SLinus Torvalds	bne.b		_L20_2d
41881da177e4SLinus Torvalds	bsr.l		ssincos			# operand is a NORM
41891da177e4SLinus Torvalds	bra.b		_L20_6d
41901da177e4SLinus Torvalds_L20_2d:
41911da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
41921da177e4SLinus Torvalds	bne.b		_L20_3d			# no
41931da177e4SLinus Torvalds	bsr.l		ssincosz			# yes
41941da177e4SLinus Torvalds	bra.b		_L20_6d
41951da177e4SLinus Torvalds_L20_3d:
41961da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
41971da177e4SLinus Torvalds	bne.b		_L20_4d			# no
41981da177e4SLinus Torvalds	bsr.l		ssincosi			# yes
41991da177e4SLinus Torvalds	bra.b		_L20_6d
42001da177e4SLinus Torvalds_L20_4d:
42011da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
42021da177e4SLinus Torvalds	bne.b		_L20_5d			# no
42031da177e4SLinus Torvalds	bsr.l		ssincosqnan			# yes
42041da177e4SLinus Torvalds	bra.b		_L20_6d
42051da177e4SLinus Torvalds_L20_5d:
42061da177e4SLinus Torvalds	bsr.l		ssincosd			# operand is a DENORM
42071da177e4SLinus Torvalds_L20_6d:
42081da177e4SLinus Torvalds
42091da177e4SLinus Torvalds#
42101da177e4SLinus Torvalds#	Result is now in FP0
42111da177e4SLinus Torvalds#
42121da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
42131da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
42141da177e4SLinus Torvalds	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
42151da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
42161da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
42171da177e4SLinus Torvalds	unlk		%a6
42181da177e4SLinus Torvalds	rts
42191da177e4SLinus Torvalds
42201da177e4SLinus Torvalds	global		_fsincosx_
42211da177e4SLinus Torvalds_fsincosx_:
42221da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
42231da177e4SLinus Torvalds
42241da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
42251da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
42261da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
42271da177e4SLinus Torvalds
42281da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
42291da177e4SLinus Torvalds
42301da177e4SLinus Torvalds#
42311da177e4SLinus Torvalds#	copy, convert, and tag input argument
42321da177e4SLinus Torvalds#
42331da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
42341da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
42351da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
42361da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
42371da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
42381da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
42391da177e4SLinus Torvalds	mov.b		%d0,%d1
42401da177e4SLinus Torvalds
42411da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
42421da177e4SLinus Torvalds
42431da177e4SLinus Torvalds	clr.l		%d0
42441da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
42451da177e4SLinus Torvalds
42461da177e4SLinus Torvalds	tst.b		%d1
42471da177e4SLinus Torvalds	bne.b		_L20_2x
42481da177e4SLinus Torvalds	bsr.l		ssincos			# operand is a NORM
42491da177e4SLinus Torvalds	bra.b		_L20_6x
42501da177e4SLinus Torvalds_L20_2x:
42511da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
42521da177e4SLinus Torvalds	bne.b		_L20_3x			# no
42531da177e4SLinus Torvalds	bsr.l		ssincosz			# yes
42541da177e4SLinus Torvalds	bra.b		_L20_6x
42551da177e4SLinus Torvalds_L20_3x:
42561da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
42571da177e4SLinus Torvalds	bne.b		_L20_4x			# no
42581da177e4SLinus Torvalds	bsr.l		ssincosi			# yes
42591da177e4SLinus Torvalds	bra.b		_L20_6x
42601da177e4SLinus Torvalds_L20_4x:
42611da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
42621da177e4SLinus Torvalds	bne.b		_L20_5x			# no
42631da177e4SLinus Torvalds	bsr.l		ssincosqnan			# yes
42641da177e4SLinus Torvalds	bra.b		_L20_6x
42651da177e4SLinus Torvalds_L20_5x:
42661da177e4SLinus Torvalds	bsr.l		ssincosd			# operand is a DENORM
42671da177e4SLinus Torvalds_L20_6x:
42681da177e4SLinus Torvalds
42691da177e4SLinus Torvalds#
42701da177e4SLinus Torvalds#	Result is now in FP0
42711da177e4SLinus Torvalds#
42721da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
42731da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
42741da177e4SLinus Torvalds	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
42751da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
42761da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
42771da177e4SLinus Torvalds	unlk		%a6
42781da177e4SLinus Torvalds	rts
42791da177e4SLinus Torvalds
42801da177e4SLinus Torvalds
42811da177e4SLinus Torvalds#########################################################################
42821da177e4SLinus Torvalds# DYADIC TEMPLATE							#
42831da177e4SLinus Torvalds#########################################################################
42841da177e4SLinus Torvalds	global		_frems_
42851da177e4SLinus Torvalds_frems_:
42861da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
42871da177e4SLinus Torvalds
42881da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
42891da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
42901da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
42911da177e4SLinus Torvalds
42921da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
42931da177e4SLinus Torvalds
42941da177e4SLinus Torvalds#
42951da177e4SLinus Torvalds#	copy, convert, and tag input argument
42961da177e4SLinus Torvalds#
42971da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl dst
42981da177e4SLinus Torvalds	fmov.x		%fp0,FP_DST(%a6)
42991da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
43001da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
43011da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
43021da177e4SLinus Torvalds
43031da177e4SLinus Torvalds	fmov.s		0xc(%a6),%fp0		# load sgl src
43041da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
43051da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
43061da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
43071da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
43081da177e4SLinus Torvalds	mov.l		%d0,%d1
43091da177e4SLinus Torvalds
43101da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
43111da177e4SLinus Torvalds
43121da177e4SLinus Torvalds	clr.l		%d0
43131da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
43141da177e4SLinus Torvalds
43151da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
43161da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
43171da177e4SLinus Torvalds
43181da177e4SLinus Torvalds	tst.b		%d1
43191da177e4SLinus Torvalds	bne.b		_L21_2s
43201da177e4SLinus Torvalds	bsr.l		srem_snorm			# operand is a NORM
43211da177e4SLinus Torvalds	bra.b		_L21_6s
43221da177e4SLinus Torvalds_L21_2s:
43231da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
43241da177e4SLinus Torvalds	bne.b		_L21_3s			# no
43251da177e4SLinus Torvalds	bsr.l		srem_szero			# yes
43261da177e4SLinus Torvalds	bra.b		_L21_6s
43271da177e4SLinus Torvalds_L21_3s:
43281da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
43291da177e4SLinus Torvalds	bne.b		_L21_4s			# no
43301da177e4SLinus Torvalds	bsr.l		srem_sinf			# yes
43311da177e4SLinus Torvalds	bra.b		_L21_6s
43321da177e4SLinus Torvalds_L21_4s:
43331da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
43341da177e4SLinus Torvalds	bne.b		_L21_5s			# no
43351da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
43361da177e4SLinus Torvalds	bra.b		_L21_6s
43371da177e4SLinus Torvalds_L21_5s:
43381da177e4SLinus Torvalds	bsr.l		srem_sdnrm			# operand is a DENORM
43391da177e4SLinus Torvalds_L21_6s:
43401da177e4SLinus Torvalds
43411da177e4SLinus Torvalds#
43421da177e4SLinus Torvalds#	Result is now in FP0
43431da177e4SLinus Torvalds#
43441da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
43451da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
43461da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
43471da177e4SLinus Torvalds	unlk		%a6
43481da177e4SLinus Torvalds	rts
43491da177e4SLinus Torvalds
43501da177e4SLinus Torvalds	global		_fremd_
43511da177e4SLinus Torvalds_fremd_:
43521da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
43531da177e4SLinus Torvalds
43541da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
43551da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
43561da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
43571da177e4SLinus Torvalds
43581da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
43591da177e4SLinus Torvalds
43601da177e4SLinus Torvalds#
43611da177e4SLinus Torvalds#	copy, convert, and tag input argument
43621da177e4SLinus Torvalds#
43631da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl dst
43641da177e4SLinus Torvalds	fmov.x		%fp0,FP_DST(%a6)
43651da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
43661da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
43671da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
43681da177e4SLinus Torvalds
43691da177e4SLinus Torvalds	fmov.d		0x10(%a6),%fp0		# load dbl src
43701da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
43711da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
43721da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
43731da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
43741da177e4SLinus Torvalds	mov.l		%d0,%d1
43751da177e4SLinus Torvalds
43761da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
43771da177e4SLinus Torvalds
43781da177e4SLinus Torvalds	clr.l		%d0
43791da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
43801da177e4SLinus Torvalds
43811da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
43821da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
43831da177e4SLinus Torvalds
43841da177e4SLinus Torvalds	tst.b		%d1
43851da177e4SLinus Torvalds	bne.b		_L21_2d
43861da177e4SLinus Torvalds	bsr.l		srem_snorm			# operand is a NORM
43871da177e4SLinus Torvalds	bra.b		_L21_6d
43881da177e4SLinus Torvalds_L21_2d:
43891da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
43901da177e4SLinus Torvalds	bne.b		_L21_3d			# no
43911da177e4SLinus Torvalds	bsr.l		srem_szero			# yes
43921da177e4SLinus Torvalds	bra.b		_L21_6d
43931da177e4SLinus Torvalds_L21_3d:
43941da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
43951da177e4SLinus Torvalds	bne.b		_L21_4d			# no
43961da177e4SLinus Torvalds	bsr.l		srem_sinf			# yes
43971da177e4SLinus Torvalds	bra.b		_L21_6d
43981da177e4SLinus Torvalds_L21_4d:
43991da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
44001da177e4SLinus Torvalds	bne.b		_L21_5d			# no
44011da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
44021da177e4SLinus Torvalds	bra.b		_L21_6d
44031da177e4SLinus Torvalds_L21_5d:
44041da177e4SLinus Torvalds	bsr.l		srem_sdnrm			# operand is a DENORM
44051da177e4SLinus Torvalds_L21_6d:
44061da177e4SLinus Torvalds
44071da177e4SLinus Torvalds#
44081da177e4SLinus Torvalds#	Result is now in FP0
44091da177e4SLinus Torvalds#
44101da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
44111da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
44121da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
44131da177e4SLinus Torvalds	unlk		%a6
44141da177e4SLinus Torvalds	rts
44151da177e4SLinus Torvalds
44161da177e4SLinus Torvalds	global		_fremx_
44171da177e4SLinus Torvalds_fremx_:
44181da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
44191da177e4SLinus Torvalds
44201da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
44211da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
44221da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
44231da177e4SLinus Torvalds
44241da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
44251da177e4SLinus Torvalds
44261da177e4SLinus Torvalds#
44271da177e4SLinus Torvalds#	copy, convert, and tag input argument
44281da177e4SLinus Torvalds#
44291da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
44301da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
44311da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
44321da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
44331da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
44341da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
44351da177e4SLinus Torvalds
44361da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
44371da177e4SLinus Torvalds	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
44381da177e4SLinus Torvalds	mov.l		0x14+0x4(%a6),0x4(%a0)
44391da177e4SLinus Torvalds	mov.l		0x14+0x8(%a6),0x8(%a0)
44401da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
44411da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
44421da177e4SLinus Torvalds	mov.l		%d0,%d1
44431da177e4SLinus Torvalds
44441da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
44451da177e4SLinus Torvalds
44461da177e4SLinus Torvalds	clr.l		%d0
44471da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
44481da177e4SLinus Torvalds
44491da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
44501da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
44511da177e4SLinus Torvalds
44521da177e4SLinus Torvalds	tst.b		%d1
44531da177e4SLinus Torvalds	bne.b		_L21_2x
44541da177e4SLinus Torvalds	bsr.l		srem_snorm			# operand is a NORM
44551da177e4SLinus Torvalds	bra.b		_L21_6x
44561da177e4SLinus Torvalds_L21_2x:
44571da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
44581da177e4SLinus Torvalds	bne.b		_L21_3x			# no
44591da177e4SLinus Torvalds	bsr.l		srem_szero			# yes
44601da177e4SLinus Torvalds	bra.b		_L21_6x
44611da177e4SLinus Torvalds_L21_3x:
44621da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
44631da177e4SLinus Torvalds	bne.b		_L21_4x			# no
44641da177e4SLinus Torvalds	bsr.l		srem_sinf			# yes
44651da177e4SLinus Torvalds	bra.b		_L21_6x
44661da177e4SLinus Torvalds_L21_4x:
44671da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
44681da177e4SLinus Torvalds	bne.b		_L21_5x			# no
44691da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
44701da177e4SLinus Torvalds	bra.b		_L21_6x
44711da177e4SLinus Torvalds_L21_5x:
44721da177e4SLinus Torvalds	bsr.l		srem_sdnrm			# operand is a DENORM
44731da177e4SLinus Torvalds_L21_6x:
44741da177e4SLinus Torvalds
44751da177e4SLinus Torvalds#
44761da177e4SLinus Torvalds#	Result is now in FP0
44771da177e4SLinus Torvalds#
44781da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
44791da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
44801da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
44811da177e4SLinus Torvalds	unlk		%a6
44821da177e4SLinus Torvalds	rts
44831da177e4SLinus Torvalds
44841da177e4SLinus Torvalds
44851da177e4SLinus Torvalds#########################################################################
44861da177e4SLinus Torvalds# DYADIC TEMPLATE							#
44871da177e4SLinus Torvalds#########################################################################
44881da177e4SLinus Torvalds	global		_fmods_
44891da177e4SLinus Torvalds_fmods_:
44901da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
44911da177e4SLinus Torvalds
44921da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
44931da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
44941da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
44951da177e4SLinus Torvalds
44961da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
44971da177e4SLinus Torvalds
44981da177e4SLinus Torvalds#
44991da177e4SLinus Torvalds#	copy, convert, and tag input argument
45001da177e4SLinus Torvalds#
45011da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl dst
45021da177e4SLinus Torvalds	fmov.x		%fp0,FP_DST(%a6)
45031da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
45041da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
45051da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
45061da177e4SLinus Torvalds
45071da177e4SLinus Torvalds	fmov.s		0xc(%a6),%fp0		# load sgl src
45081da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
45091da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
45101da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
45111da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
45121da177e4SLinus Torvalds	mov.l		%d0,%d1
45131da177e4SLinus Torvalds
45141da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
45151da177e4SLinus Torvalds
45161da177e4SLinus Torvalds	clr.l		%d0
45171da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
45181da177e4SLinus Torvalds
45191da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
45201da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
45211da177e4SLinus Torvalds
45221da177e4SLinus Torvalds	tst.b		%d1
45231da177e4SLinus Torvalds	bne.b		_L22_2s
45241da177e4SLinus Torvalds	bsr.l		smod_snorm			# operand is a NORM
45251da177e4SLinus Torvalds	bra.b		_L22_6s
45261da177e4SLinus Torvalds_L22_2s:
45271da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
45281da177e4SLinus Torvalds	bne.b		_L22_3s			# no
45291da177e4SLinus Torvalds	bsr.l		smod_szero			# yes
45301da177e4SLinus Torvalds	bra.b		_L22_6s
45311da177e4SLinus Torvalds_L22_3s:
45321da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
45331da177e4SLinus Torvalds	bne.b		_L22_4s			# no
45341da177e4SLinus Torvalds	bsr.l		smod_sinf			# yes
45351da177e4SLinus Torvalds	bra.b		_L22_6s
45361da177e4SLinus Torvalds_L22_4s:
45371da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
45381da177e4SLinus Torvalds	bne.b		_L22_5s			# no
45391da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
45401da177e4SLinus Torvalds	bra.b		_L22_6s
45411da177e4SLinus Torvalds_L22_5s:
45421da177e4SLinus Torvalds	bsr.l		smod_sdnrm			# operand is a DENORM
45431da177e4SLinus Torvalds_L22_6s:
45441da177e4SLinus Torvalds
45451da177e4SLinus Torvalds#
45461da177e4SLinus Torvalds#	Result is now in FP0
45471da177e4SLinus Torvalds#
45481da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
45491da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
45501da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
45511da177e4SLinus Torvalds	unlk		%a6
45521da177e4SLinus Torvalds	rts
45531da177e4SLinus Torvalds
45541da177e4SLinus Torvalds	global		_fmodd_
45551da177e4SLinus Torvalds_fmodd_:
45561da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
45571da177e4SLinus Torvalds
45581da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
45591da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
45601da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
45611da177e4SLinus Torvalds
45621da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
45631da177e4SLinus Torvalds
45641da177e4SLinus Torvalds#
45651da177e4SLinus Torvalds#	copy, convert, and tag input argument
45661da177e4SLinus Torvalds#
45671da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl dst
45681da177e4SLinus Torvalds	fmov.x		%fp0,FP_DST(%a6)
45691da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
45701da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
45711da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
45721da177e4SLinus Torvalds
45731da177e4SLinus Torvalds	fmov.d		0x10(%a6),%fp0		# load dbl src
45741da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
45751da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
45761da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
45771da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
45781da177e4SLinus Torvalds	mov.l		%d0,%d1
45791da177e4SLinus Torvalds
45801da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
45811da177e4SLinus Torvalds
45821da177e4SLinus Torvalds	clr.l		%d0
45831da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
45841da177e4SLinus Torvalds
45851da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
45861da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
45871da177e4SLinus Torvalds
45881da177e4SLinus Torvalds	tst.b		%d1
45891da177e4SLinus Torvalds	bne.b		_L22_2d
45901da177e4SLinus Torvalds	bsr.l		smod_snorm			# operand is a NORM
45911da177e4SLinus Torvalds	bra.b		_L22_6d
45921da177e4SLinus Torvalds_L22_2d:
45931da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
45941da177e4SLinus Torvalds	bne.b		_L22_3d			# no
45951da177e4SLinus Torvalds	bsr.l		smod_szero			# yes
45961da177e4SLinus Torvalds	bra.b		_L22_6d
45971da177e4SLinus Torvalds_L22_3d:
45981da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
45991da177e4SLinus Torvalds	bne.b		_L22_4d			# no
46001da177e4SLinus Torvalds	bsr.l		smod_sinf			# yes
46011da177e4SLinus Torvalds	bra.b		_L22_6d
46021da177e4SLinus Torvalds_L22_4d:
46031da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
46041da177e4SLinus Torvalds	bne.b		_L22_5d			# no
46051da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
46061da177e4SLinus Torvalds	bra.b		_L22_6d
46071da177e4SLinus Torvalds_L22_5d:
46081da177e4SLinus Torvalds	bsr.l		smod_sdnrm			# operand is a DENORM
46091da177e4SLinus Torvalds_L22_6d:
46101da177e4SLinus Torvalds
46111da177e4SLinus Torvalds#
46121da177e4SLinus Torvalds#	Result is now in FP0
46131da177e4SLinus Torvalds#
46141da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
46151da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
46161da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
46171da177e4SLinus Torvalds	unlk		%a6
46181da177e4SLinus Torvalds	rts
46191da177e4SLinus Torvalds
46201da177e4SLinus Torvalds	global		_fmodx_
46211da177e4SLinus Torvalds_fmodx_:
46221da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
46231da177e4SLinus Torvalds
46241da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
46251da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
46261da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
46271da177e4SLinus Torvalds
46281da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
46291da177e4SLinus Torvalds
46301da177e4SLinus Torvalds#
46311da177e4SLinus Torvalds#	copy, convert, and tag input argument
46321da177e4SLinus Torvalds#
46331da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
46341da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
46351da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
46361da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
46371da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
46381da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
46391da177e4SLinus Torvalds
46401da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
46411da177e4SLinus Torvalds	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
46421da177e4SLinus Torvalds	mov.l		0x14+0x4(%a6),0x4(%a0)
46431da177e4SLinus Torvalds	mov.l		0x14+0x8(%a6),0x8(%a0)
46441da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
46451da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
46461da177e4SLinus Torvalds	mov.l		%d0,%d1
46471da177e4SLinus Torvalds
46481da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
46491da177e4SLinus Torvalds
46501da177e4SLinus Torvalds	clr.l		%d0
46511da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
46521da177e4SLinus Torvalds
46531da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
46541da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
46551da177e4SLinus Torvalds
46561da177e4SLinus Torvalds	tst.b		%d1
46571da177e4SLinus Torvalds	bne.b		_L22_2x
46581da177e4SLinus Torvalds	bsr.l		smod_snorm			# operand is a NORM
46591da177e4SLinus Torvalds	bra.b		_L22_6x
46601da177e4SLinus Torvalds_L22_2x:
46611da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
46621da177e4SLinus Torvalds	bne.b		_L22_3x			# no
46631da177e4SLinus Torvalds	bsr.l		smod_szero			# yes
46641da177e4SLinus Torvalds	bra.b		_L22_6x
46651da177e4SLinus Torvalds_L22_3x:
46661da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
46671da177e4SLinus Torvalds	bne.b		_L22_4x			# no
46681da177e4SLinus Torvalds	bsr.l		smod_sinf			# yes
46691da177e4SLinus Torvalds	bra.b		_L22_6x
46701da177e4SLinus Torvalds_L22_4x:
46711da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
46721da177e4SLinus Torvalds	bne.b		_L22_5x			# no
46731da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
46741da177e4SLinus Torvalds	bra.b		_L22_6x
46751da177e4SLinus Torvalds_L22_5x:
46761da177e4SLinus Torvalds	bsr.l		smod_sdnrm			# operand is a DENORM
46771da177e4SLinus Torvalds_L22_6x:
46781da177e4SLinus Torvalds
46791da177e4SLinus Torvalds#
46801da177e4SLinus Torvalds#	Result is now in FP0
46811da177e4SLinus Torvalds#
46821da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
46831da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
46841da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
46851da177e4SLinus Torvalds	unlk		%a6
46861da177e4SLinus Torvalds	rts
46871da177e4SLinus Torvalds
46881da177e4SLinus Torvalds
46891da177e4SLinus Torvalds#########################################################################
46901da177e4SLinus Torvalds# DYADIC TEMPLATE							#
46911da177e4SLinus Torvalds#########################################################################
46921da177e4SLinus Torvalds	global		_fscales_
46931da177e4SLinus Torvalds_fscales_:
46941da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
46951da177e4SLinus Torvalds
46961da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
46971da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
46981da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
46991da177e4SLinus Torvalds
47001da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
47011da177e4SLinus Torvalds
47021da177e4SLinus Torvalds#
47031da177e4SLinus Torvalds#	copy, convert, and tag input argument
47041da177e4SLinus Torvalds#
47051da177e4SLinus Torvalds	fmov.s		0x8(%a6),%fp0		# load sgl dst
47061da177e4SLinus Torvalds	fmov.x		%fp0,FP_DST(%a6)
47071da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
47081da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
47091da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
47101da177e4SLinus Torvalds
47111da177e4SLinus Torvalds	fmov.s		0xc(%a6),%fp0		# load sgl src
47121da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
47131da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
47141da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
47151da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
47161da177e4SLinus Torvalds	mov.l		%d0,%d1
47171da177e4SLinus Torvalds
47181da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
47191da177e4SLinus Torvalds
47201da177e4SLinus Torvalds	clr.l		%d0
47211da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
47221da177e4SLinus Torvalds
47231da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
47241da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
47251da177e4SLinus Torvalds
47261da177e4SLinus Torvalds	tst.b		%d1
47271da177e4SLinus Torvalds	bne.b		_L23_2s
47281da177e4SLinus Torvalds	bsr.l		sscale_snorm			# operand is a NORM
47291da177e4SLinus Torvalds	bra.b		_L23_6s
47301da177e4SLinus Torvalds_L23_2s:
47311da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
47321da177e4SLinus Torvalds	bne.b		_L23_3s			# no
47331da177e4SLinus Torvalds	bsr.l		sscale_szero			# yes
47341da177e4SLinus Torvalds	bra.b		_L23_6s
47351da177e4SLinus Torvalds_L23_3s:
47361da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
47371da177e4SLinus Torvalds	bne.b		_L23_4s			# no
47381da177e4SLinus Torvalds	bsr.l		sscale_sinf			# yes
47391da177e4SLinus Torvalds	bra.b		_L23_6s
47401da177e4SLinus Torvalds_L23_4s:
47411da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
47421da177e4SLinus Torvalds	bne.b		_L23_5s			# no
47431da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
47441da177e4SLinus Torvalds	bra.b		_L23_6s
47451da177e4SLinus Torvalds_L23_5s:
47461da177e4SLinus Torvalds	bsr.l		sscale_sdnrm			# operand is a DENORM
47471da177e4SLinus Torvalds_L23_6s:
47481da177e4SLinus Torvalds
47491da177e4SLinus Torvalds#
47501da177e4SLinus Torvalds#	Result is now in FP0
47511da177e4SLinus Torvalds#
47521da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
47531da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
47541da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
47551da177e4SLinus Torvalds	unlk		%a6
47561da177e4SLinus Torvalds	rts
47571da177e4SLinus Torvalds
47581da177e4SLinus Torvalds	global		_fscaled_
47591da177e4SLinus Torvalds_fscaled_:
47601da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
47611da177e4SLinus Torvalds
47621da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
47631da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
47641da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
47651da177e4SLinus Torvalds
47661da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
47671da177e4SLinus Torvalds
47681da177e4SLinus Torvalds#
47691da177e4SLinus Torvalds#	copy, convert, and tag input argument
47701da177e4SLinus Torvalds#
47711da177e4SLinus Torvalds	fmov.d		0x8(%a6),%fp0		# load dbl dst
47721da177e4SLinus Torvalds	fmov.x		%fp0,FP_DST(%a6)
47731da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
47741da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
47751da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
47761da177e4SLinus Torvalds
47771da177e4SLinus Torvalds	fmov.d		0x10(%a6),%fp0		# load dbl src
47781da177e4SLinus Torvalds	fmov.x		%fp0,FP_SRC(%a6)
47791da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
47801da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
47811da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
47821da177e4SLinus Torvalds	mov.l		%d0,%d1
47831da177e4SLinus Torvalds
47841da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
47851da177e4SLinus Torvalds
47861da177e4SLinus Torvalds	clr.l		%d0
47871da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
47881da177e4SLinus Torvalds
47891da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
47901da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
47911da177e4SLinus Torvalds
47921da177e4SLinus Torvalds	tst.b		%d1
47931da177e4SLinus Torvalds	bne.b		_L23_2d
47941da177e4SLinus Torvalds	bsr.l		sscale_snorm			# operand is a NORM
47951da177e4SLinus Torvalds	bra.b		_L23_6d
47961da177e4SLinus Torvalds_L23_2d:
47971da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
47981da177e4SLinus Torvalds	bne.b		_L23_3d			# no
47991da177e4SLinus Torvalds	bsr.l		sscale_szero			# yes
48001da177e4SLinus Torvalds	bra.b		_L23_6d
48011da177e4SLinus Torvalds_L23_3d:
48021da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
48031da177e4SLinus Torvalds	bne.b		_L23_4d			# no
48041da177e4SLinus Torvalds	bsr.l		sscale_sinf			# yes
48051da177e4SLinus Torvalds	bra.b		_L23_6d
48061da177e4SLinus Torvalds_L23_4d:
48071da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
48081da177e4SLinus Torvalds	bne.b		_L23_5d			# no
48091da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
48101da177e4SLinus Torvalds	bra.b		_L23_6d
48111da177e4SLinus Torvalds_L23_5d:
48121da177e4SLinus Torvalds	bsr.l		sscale_sdnrm			# operand is a DENORM
48131da177e4SLinus Torvalds_L23_6d:
48141da177e4SLinus Torvalds
48151da177e4SLinus Torvalds#
48161da177e4SLinus Torvalds#	Result is now in FP0
48171da177e4SLinus Torvalds#
48181da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
48191da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
48201da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
48211da177e4SLinus Torvalds	unlk		%a6
48221da177e4SLinus Torvalds	rts
48231da177e4SLinus Torvalds
48241da177e4SLinus Torvalds	global		_fscalex_
48251da177e4SLinus Torvalds_fscalex_:
48261da177e4SLinus Torvalds	link		%a6,&-LOCAL_SIZE
48271da177e4SLinus Torvalds
48281da177e4SLinus Torvalds	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
48291da177e4SLinus Torvalds	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
48301da177e4SLinus Torvalds	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
48311da177e4SLinus Torvalds
48321da177e4SLinus Torvalds	fmov.l		&0x0,%fpcr		# zero FPCR
48331da177e4SLinus Torvalds
48341da177e4SLinus Torvalds#
48351da177e4SLinus Torvalds#	copy, convert, and tag input argument
48361da177e4SLinus Torvalds#
48371da177e4SLinus Torvalds	lea		FP_DST(%a6),%a0
48381da177e4SLinus Torvalds	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
48391da177e4SLinus Torvalds	mov.l		0x8+0x4(%a6),0x4(%a0)
48401da177e4SLinus Torvalds	mov.l		0x8+0x8(%a6),0x8(%a0)
48411da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
48421da177e4SLinus Torvalds	mov.b		%d0,DTAG(%a6)
48431da177e4SLinus Torvalds
48441da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0
48451da177e4SLinus Torvalds	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
48461da177e4SLinus Torvalds	mov.l		0x14+0x4(%a6),0x4(%a0)
48471da177e4SLinus Torvalds	mov.l		0x14+0x8(%a6),0x8(%a0)
48481da177e4SLinus Torvalds	bsr.l		tag			# fetch operand type
48491da177e4SLinus Torvalds	mov.b		%d0,STAG(%a6)
48501da177e4SLinus Torvalds	mov.l		%d0,%d1
48511da177e4SLinus Torvalds
48521da177e4SLinus Torvalds	andi.l		&0x00ff00ff,USER_FPSR(%a6)
48531da177e4SLinus Torvalds
48541da177e4SLinus Torvalds	clr.l		%d0
48551da177e4SLinus Torvalds	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
48561da177e4SLinus Torvalds
48571da177e4SLinus Torvalds	lea		FP_SRC(%a6),%a0		# pass ptr to src
48581da177e4SLinus Torvalds	lea		FP_DST(%a6),%a1		# pass ptr to dst
48591da177e4SLinus Torvalds
48601da177e4SLinus Torvalds	tst.b		%d1
48611da177e4SLinus Torvalds	bne.b		_L23_2x
48621da177e4SLinus Torvalds	bsr.l		sscale_snorm			# operand is a NORM
48631da177e4SLinus Torvalds	bra.b		_L23_6x
48641da177e4SLinus Torvalds_L23_2x:
48651da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO		# is operand a ZERO?
48661da177e4SLinus Torvalds	bne.b		_L23_3x			# no
48671da177e4SLinus Torvalds	bsr.l		sscale_szero			# yes
48681da177e4SLinus Torvalds	bra.b		_L23_6x
48691da177e4SLinus Torvalds_L23_3x:
48701da177e4SLinus Torvalds	cmpi.b		%d1,&INF		# is operand an INF?
48711da177e4SLinus Torvalds	bne.b		_L23_4x			# no
48721da177e4SLinus Torvalds	bsr.l		sscale_sinf			# yes
48731da177e4SLinus Torvalds	bra.b		_L23_6x
48741da177e4SLinus Torvalds_L23_4x:
48751da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN		# is operand a QNAN?
48761da177e4SLinus Torvalds	bne.b		_L23_5x			# no
48771da177e4SLinus Torvalds	bsr.l		sop_sqnan			# yes
48781da177e4SLinus Torvalds	bra.b		_L23_6x
48791da177e4SLinus Torvalds_L23_5x:
48801da177e4SLinus Torvalds	bsr.l		sscale_sdnrm			# operand is a DENORM
48811da177e4SLinus Torvalds_L23_6x:
48821da177e4SLinus Torvalds
48831da177e4SLinus Torvalds#
48841da177e4SLinus Torvalds#	Result is now in FP0
48851da177e4SLinus Torvalds#
48861da177e4SLinus Torvalds	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
48871da177e4SLinus Torvalds	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
48881da177e4SLinus Torvalds	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
48891da177e4SLinus Torvalds	unlk		%a6
48901da177e4SLinus Torvalds	rts
48911da177e4SLinus Torvalds
48921da177e4SLinus Torvalds
48931da177e4SLinus Torvalds#########################################################################
48941da177e4SLinus Torvalds# ssin():     computes the sine of a normalized input			#
48951da177e4SLinus Torvalds# ssind():    computes the sine of a denormalized input			#
48961da177e4SLinus Torvalds# scos():     computes the cosine of a normalized input			#
48971da177e4SLinus Torvalds# scosd():    computes the cosine of a denormalized input		#
48981da177e4SLinus Torvalds# ssincos():  computes the sine and cosine of a normalized input	#
48991da177e4SLinus Torvalds# ssincosd(): computes the sine and cosine of a denormalized input	#
49001da177e4SLinus Torvalds#									#
49011da177e4SLinus Torvalds# INPUT *************************************************************** #
49021da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
49031da177e4SLinus Torvalds#	d0 = round precision,mode					#
49041da177e4SLinus Torvalds#									#
49051da177e4SLinus Torvalds# OUTPUT ************************************************************** #
49061da177e4SLinus Torvalds#	fp0 = sin(X) or cos(X)						#
49071da177e4SLinus Torvalds#									#
49081da177e4SLinus Torvalds#    For ssincos(X):							#
49091da177e4SLinus Torvalds#	fp0 = sin(X)							#
49101da177e4SLinus Torvalds#	fp1 = cos(X)							#
49111da177e4SLinus Torvalds#									#
49121da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* #
49131da177e4SLinus Torvalds#	The returned result is within 1 ulp in 64 significant bit, i.e.	#
49141da177e4SLinus Torvalds#	within 0.5001 ulp to 53 bits if the result is subsequently	#
49151da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
49161da177e4SLinus Torvalds#	in double precision.						#
49171da177e4SLinus Torvalds#									#
49181da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
49191da177e4SLinus Torvalds#									#
49201da177e4SLinus Torvalds#	SIN and COS:							#
49211da177e4SLinus Torvalds#	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
49221da177e4SLinus Torvalds#									#
49231da177e4SLinus Torvalds#	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
49241da177e4SLinus Torvalds#									#
49251da177e4SLinus Torvalds#	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
49261da177e4SLinus Torvalds#		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
49271da177e4SLinus Torvalds#		Overwrite k by k := k + AdjN.				#
49281da177e4SLinus Torvalds#									#
49291da177e4SLinus Torvalds#	4. If k is even, go to 6.					#
49301da177e4SLinus Torvalds#									#
49311da177e4SLinus Torvalds#	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j.			#
49321da177e4SLinus Torvalds#		Return sgn*cos(r) where cos(r) is approximated by an	#
49331da177e4SLinus Torvalds#		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
49341da177e4SLinus Torvalds#		s = r*r.						#
49351da177e4SLinus Torvalds#		Exit.							#
49361da177e4SLinus Torvalds#									#
49371da177e4SLinus Torvalds#	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
49381da177e4SLinus Torvalds#		where sin(r) is approximated by an odd polynomial in r	#
49391da177e4SLinus Torvalds#		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
49401da177e4SLinus Torvalds#		Exit.							#
49411da177e4SLinus Torvalds#									#
49421da177e4SLinus Torvalds#	7. If |X| > 1, go to 9.						#
49431da177e4SLinus Torvalds#									#
49441da177e4SLinus Torvalds#	8. (|X|<2**(-40)) If SIN is invoked, return X;			#
49451da177e4SLinus Torvalds#		otherwise return 1.					#
49461da177e4SLinus Torvalds#									#
49471da177e4SLinus Torvalds#	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
49481da177e4SLinus Torvalds#		go back to 3.						#
49491da177e4SLinus Torvalds#									#
49501da177e4SLinus Torvalds#	SINCOS:								#
49511da177e4SLinus Torvalds#	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
49521da177e4SLinus Torvalds#									#
49531da177e4SLinus Torvalds#	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
49541da177e4SLinus Torvalds#		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
49551da177e4SLinus Torvalds#									#
49561da177e4SLinus Torvalds#	3. If k is even, go to 5.					#
49571da177e4SLinus Torvalds#									#
49581da177e4SLinus Torvalds#	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
49591da177e4SLinus Torvalds#		j1 exclusive or with the l.s.b. of k.			#
49601da177e4SLinus Torvalds#		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
49611da177e4SLinus Torvalds#		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
49621da177e4SLinus Torvalds#		sin(r) and cos(r) are computed as odd and even		#
49631da177e4SLinus Torvalds#		polynomials in r, respectively. Exit			#
49641da177e4SLinus Torvalds#									#
49651da177e4SLinus Torvalds#	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
49661da177e4SLinus Torvalds#		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
49671da177e4SLinus Torvalds#		sin(r) and cos(r) are computed as odd and even		#
49681da177e4SLinus Torvalds#		polynomials in r, respectively. Exit			#
49691da177e4SLinus Torvalds#									#
49701da177e4SLinus Torvalds#	6. If |X| > 1, go to 8.						#
49711da177e4SLinus Torvalds#									#
49721da177e4SLinus Torvalds#	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
49731da177e4SLinus Torvalds#									#
49741da177e4SLinus Torvalds#	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
49751da177e4SLinus Torvalds#		go back to 2.						#
49761da177e4SLinus Torvalds#									#
49771da177e4SLinus Torvalds#########################################################################
49781da177e4SLinus Torvalds
49791da177e4SLinus TorvaldsSINA7:	long		0xBD6AAA77,0xCCC994F5
49801da177e4SLinus TorvaldsSINA6:	long		0x3DE61209,0x7AAE8DA1
49811da177e4SLinus TorvaldsSINA5:	long		0xBE5AE645,0x2A118AE4
49821da177e4SLinus TorvaldsSINA4:	long		0x3EC71DE3,0xA5341531
49831da177e4SLinus TorvaldsSINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
49841da177e4SLinus TorvaldsSINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
49851da177e4SLinus TorvaldsSINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
49861da177e4SLinus Torvalds
49871da177e4SLinus TorvaldsCOSB8:	long		0x3D2AC4D0,0xD6011EE3
49881da177e4SLinus TorvaldsCOSB7:	long		0xBDA9396F,0x9F45AC19
49891da177e4SLinus TorvaldsCOSB6:	long		0x3E21EED9,0x0612C972
49901da177e4SLinus TorvaldsCOSB5:	long		0xBE927E4F,0xB79D9FCF
49911da177e4SLinus TorvaldsCOSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
49921da177e4SLinus TorvaldsCOSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
49931da177e4SLinus TorvaldsCOSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
49941da177e4SLinus TorvaldsCOSB1:	long		0xBF000000
49951da177e4SLinus Torvalds
49961da177e4SLinus Torvalds	set		INARG,FP_SCR0
49971da177e4SLinus Torvalds
49981da177e4SLinus Torvalds	set		X,FP_SCR0
49991da177e4SLinus Torvalds#	set		XDCARE,X+2
50001da177e4SLinus Torvalds	set		XFRAC,X+4
50011da177e4SLinus Torvalds
50021da177e4SLinus Torvalds	set		RPRIME,FP_SCR0
50031da177e4SLinus Torvalds	set		SPRIME,FP_SCR1
50041da177e4SLinus Torvalds
50051da177e4SLinus Torvalds	set		POSNEG1,L_SCR1
50061da177e4SLinus Torvalds	set		TWOTO63,L_SCR1
50071da177e4SLinus Torvalds
50081da177e4SLinus Torvalds	set		ENDFLAG,L_SCR2
50091da177e4SLinus Torvalds	set		INT,L_SCR2
50101da177e4SLinus Torvalds
50111da177e4SLinus Torvalds	set		ADJN,L_SCR3
50121da177e4SLinus Torvalds
50131da177e4SLinus Torvalds############################################
50141da177e4SLinus Torvalds	global		ssin
50151da177e4SLinus Torvaldsssin:
50161da177e4SLinus Torvalds	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
50171da177e4SLinus Torvalds	bra.b		SINBGN
50181da177e4SLinus Torvalds
50191da177e4SLinus Torvalds############################################
50201da177e4SLinus Torvalds	global		scos
50211da177e4SLinus Torvaldsscos:
50221da177e4SLinus Torvalds	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
50231da177e4SLinus Torvalds
50241da177e4SLinus Torvalds############################################
50251da177e4SLinus TorvaldsSINBGN:
50261da177e4SLinus Torvalds#--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
50271da177e4SLinus Torvalds
50281da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
50291da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)		# save input at X
50301da177e4SLinus Torvalds
50311da177e4SLinus Torvalds# "COMPACTIFY" X
50321da177e4SLinus Torvalds	mov.l		(%a0),%d1		# put exp in hi word
50331da177e4SLinus Torvalds	mov.w		4(%a0),%d1		# fetch hi(man)
50341da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1		# strip sign
50351da177e4SLinus Torvalds
50361da177e4SLinus Torvalds	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
50371da177e4SLinus Torvalds	bge.b		SOK1			# no
50381da177e4SLinus Torvalds	bra.w		SINSM			# yes; input is very small
50391da177e4SLinus Torvalds
50401da177e4SLinus TorvaldsSOK1:
50411da177e4SLinus Torvalds	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
50421da177e4SLinus Torvalds	blt.b		SINMAIN			# no
50431da177e4SLinus Torvalds	bra.w		SREDUCEX		# yes; input is very large
50441da177e4SLinus Torvalds
50451da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| <= 15 PI.
50461da177e4SLinus Torvalds#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
50471da177e4SLinus TorvaldsSINMAIN:
50481da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
50491da177e4SLinus Torvalds	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
50501da177e4SLinus Torvalds
50511da177e4SLinus Torvalds	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
50521da177e4SLinus Torvalds
50531da177e4SLinus Torvalds	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
50541da177e4SLinus Torvalds
50551da177e4SLinus Torvalds	mov.l		INT(%a6),%d1		# make a copy of N
50561da177e4SLinus Torvalds	asl.l		&4,%d1			# N *= 16
50571da177e4SLinus Torvalds	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
50581da177e4SLinus Torvalds
50591da177e4SLinus Torvalds# A1 IS THE ADDRESS OF N*PIBY2
50601da177e4SLinus Torvalds# ...WHICH IS IN TWO PIECES Y1 & Y2
50611da177e4SLinus Torvalds	fsub.x		(%a1)+,%fp0		# X-Y1
50621da177e4SLinus Torvalds	fsub.s		(%a1),%fp0		# fp0 = R = (X-Y1)-Y2
50631da177e4SLinus Torvalds
50641da177e4SLinus TorvaldsSINCONT:
50651da177e4SLinus Torvalds#--continuation from REDUCEX
50661da177e4SLinus Torvalds
50671da177e4SLinus Torvalds#--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
50681da177e4SLinus Torvalds	mov.l		INT(%a6),%d1
50691da177e4SLinus Torvalds	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
50701da177e4SLinus Torvalds	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
50711da177e4SLinus Torvalds	cmp.l		%d1,&0
50721da177e4SLinus Torvalds	blt.w		COSPOLY
50731da177e4SLinus Torvalds
50741da177e4SLinus Torvalds#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
50751da177e4SLinus Torvalds#--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
50761da177e4SLinus Torvalds#--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
50771da177e4SLinus Torvalds#--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
50781da177e4SLinus Torvalds#--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
50791da177e4SLinus Torvalds#--WHERE T=S*S.
50801da177e4SLinus Torvalds#--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
50811da177e4SLinus Torvalds#--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
50821da177e4SLinus TorvaldsSINPOLY:
50831da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
50841da177e4SLinus Torvalds
50851da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)		# X IS R
50861da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FP0 IS S
50871da177e4SLinus Torvalds
50881da177e4SLinus Torvalds	fmov.d		SINA7(%pc),%fp3
50891da177e4SLinus Torvalds	fmov.d		SINA6(%pc),%fp2
50901da177e4SLinus Torvalds
50911da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
50921da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# FP1 IS T
50931da177e4SLinus Torvalds
50941da177e4SLinus Torvalds	ror.l		&1,%d1
50951da177e4SLinus Torvalds	and.l		&0x80000000,%d1
50961da177e4SLinus Torvalds# ...LEAST SIG. BIT OF D0 IN SIGN POSITION
50971da177e4SLinus Torvalds	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
50981da177e4SLinus Torvalds
50991da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# TA7
51001da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# TA6
51011da177e4SLinus Torvalds
51021da177e4SLinus Torvalds	fadd.d		SINA5(%pc),%fp3		# A5+TA7
51031da177e4SLinus Torvalds	fadd.d		SINA4(%pc),%fp2		# A4+TA6
51041da177e4SLinus Torvalds
51051da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# T(A5+TA7)
51061da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# T(A4+TA6)
51071da177e4SLinus Torvalds
51081da177e4SLinus Torvalds	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
51091da177e4SLinus Torvalds	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
51101da177e4SLinus Torvalds
51111da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
51121da177e4SLinus Torvalds
51131da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
51141da177e4SLinus Torvalds	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
51151da177e4SLinus Torvalds	fmul.x		X(%a6),%fp0		# R'*S
51161da177e4SLinus Torvalds
51171da177e4SLinus Torvalds	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
51181da177e4SLinus Torvalds
51191da177e4SLinus Torvalds	fmul.x		%fp1,%fp0		# SIN(R')-R'
51201da177e4SLinus Torvalds
51211da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
51221da177e4SLinus Torvalds
51231da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
51241da177e4SLinus Torvalds	fadd.x		X(%a6),%fp0		# last inst - possible exception set
51251da177e4SLinus Torvalds	bra		t_inx2
51261da177e4SLinus Torvalds
51271da177e4SLinus Torvalds#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
51281da177e4SLinus Torvalds#--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
51291da177e4SLinus Torvalds#--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
51301da177e4SLinus Torvalds#--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
51311da177e4SLinus Torvalds#--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
51321da177e4SLinus Torvalds#--WHERE T=S*S.
51331da177e4SLinus Torvalds#--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
51341da177e4SLinus Torvalds#--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
51351da177e4SLinus Torvalds#--AND IS THEREFORE STORED AS SINGLE PRECISION.
51361da177e4SLinus TorvaldsCOSPOLY:
51371da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
51381da177e4SLinus Torvalds
51391da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FP0 IS S
51401da177e4SLinus Torvalds
51411da177e4SLinus Torvalds	fmov.d		COSB8(%pc),%fp2
51421da177e4SLinus Torvalds	fmov.d		COSB7(%pc),%fp3
51431da177e4SLinus Torvalds
51441da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
51451da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# FP1 IS T
51461da177e4SLinus Torvalds
51471da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)		# X IS S
51481da177e4SLinus Torvalds	ror.l		&1,%d1
51491da177e4SLinus Torvalds	and.l		&0x80000000,%d1
51501da177e4SLinus Torvalds# ...LEAST SIG. BIT OF D0 IN SIGN POSITION
51511da177e4SLinus Torvalds
51521da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# TB8
51531da177e4SLinus Torvalds
51541da177e4SLinus Torvalds	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
51551da177e4SLinus Torvalds	and.l		&0x80000000,%d1
51561da177e4SLinus Torvalds
51571da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# TB7
51581da177e4SLinus Torvalds
51591da177e4SLinus Torvalds	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
51601da177e4SLinus Torvalds	mov.l		%d1,POSNEG1(%a6)
51611da177e4SLinus Torvalds
51621da177e4SLinus Torvalds	fadd.d		COSB6(%pc),%fp2		# B6+TB8
51631da177e4SLinus Torvalds	fadd.d		COSB5(%pc),%fp3		# B5+TB7
51641da177e4SLinus Torvalds
51651da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# T(B6+TB8)
51661da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# T(B5+TB7)
51671da177e4SLinus Torvalds
51681da177e4SLinus Torvalds	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
51691da177e4SLinus Torvalds	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
51701da177e4SLinus Torvalds
51711da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
51721da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
51731da177e4SLinus Torvalds
51741da177e4SLinus Torvalds	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
51751da177e4SLinus Torvalds	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
51761da177e4SLinus Torvalds
51771da177e4SLinus Torvalds	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
51781da177e4SLinus Torvalds
51791da177e4SLinus Torvalds	fadd.x		%fp1,%fp0
51801da177e4SLinus Torvalds
51811da177e4SLinus Torvalds	fmul.x		X(%a6),%fp0
51821da177e4SLinus Torvalds
51831da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
51841da177e4SLinus Torvalds
51851da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
51861da177e4SLinus Torvalds	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
51871da177e4SLinus Torvalds	bra		t_inx2
51881da177e4SLinus Torvalds
51891da177e4SLinus Torvalds##############################################
51901da177e4SLinus Torvalds
51911da177e4SLinus Torvalds# SINe: Big OR Small?
51921da177e4SLinus Torvalds#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
51931da177e4SLinus Torvalds#--IF |X| < 2**(-40), RETURN X OR 1.
51941da177e4SLinus TorvaldsSINBORS:
51951da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
51961da177e4SLinus Torvalds	bgt.l		SREDUCEX
51971da177e4SLinus Torvalds
51981da177e4SLinus TorvaldsSINSM:
51991da177e4SLinus Torvalds	mov.l		ADJN(%a6),%d1
52001da177e4SLinus Torvalds	cmp.l		%d1,&0
52011da177e4SLinus Torvalds	bgt.b		COSTINY
52021da177e4SLinus Torvalds
52031da177e4SLinus Torvalds# here, the operation may underflow iff the precision is sgl or dbl.
52041da177e4SLinus Torvalds# extended denorms are handled through another entry point.
52051da177e4SLinus TorvaldsSINTINY:
52061da177e4SLinus Torvalds#	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
52071da177e4SLinus Torvalds
52081da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
52091da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
52101da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0		# last inst - possible exception set
52111da177e4SLinus Torvalds	bra		t_catch
52121da177e4SLinus Torvalds
52131da177e4SLinus TorvaldsCOSTINY:
52141da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
52151da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
52161da177e4SLinus Torvalds	fadd.s		&0x80800000,%fp0	# last inst - possible exception set
52171da177e4SLinus Torvalds	bra		t_pinx2
52181da177e4SLinus Torvalds
52191da177e4SLinus Torvalds################################################
52201da177e4SLinus Torvalds	global		ssind
52211da177e4SLinus Torvalds#--SIN(X) = X FOR DENORMALIZED X
52221da177e4SLinus Torvaldsssind:
52231da177e4SLinus Torvalds	bra		t_extdnrm
52241da177e4SLinus Torvalds
52251da177e4SLinus Torvalds############################################
52261da177e4SLinus Torvalds	global		scosd
52271da177e4SLinus Torvalds#--COS(X) = 1 FOR DENORMALIZED X
52281da177e4SLinus Torvaldsscosd:
52291da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
52301da177e4SLinus Torvalds	bra		t_pinx2
52311da177e4SLinus Torvalds
52321da177e4SLinus Torvalds##################################################
52331da177e4SLinus Torvalds
52341da177e4SLinus Torvalds	global		ssincos
52351da177e4SLinus Torvaldsssincos:
52361da177e4SLinus Torvalds#--SET ADJN TO 4
52371da177e4SLinus Torvalds	mov.l		&4,ADJN(%a6)
52381da177e4SLinus Torvalds
52391da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
52401da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)
52411da177e4SLinus Torvalds
52421da177e4SLinus Torvalds	mov.l		(%a0),%d1
52431da177e4SLinus Torvalds	mov.w		4(%a0),%d1
52441da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
52451da177e4SLinus Torvalds
52461da177e4SLinus Torvalds	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
52471da177e4SLinus Torvalds	bge.b		SCOK1
52481da177e4SLinus Torvalds	bra.w		SCSM
52491da177e4SLinus Torvalds
52501da177e4SLinus TorvaldsSCOK1:
52511da177e4SLinus Torvalds	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
52521da177e4SLinus Torvalds	blt.b		SCMAIN
52531da177e4SLinus Torvalds	bra.w		SREDUCEX
52541da177e4SLinus Torvalds
52551da177e4SLinus Torvalds
52561da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| <= 15 PI.
52571da177e4SLinus Torvalds#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
52581da177e4SLinus TorvaldsSCMAIN:
52591da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
52601da177e4SLinus Torvalds
52611da177e4SLinus Torvalds	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
52621da177e4SLinus Torvalds
52631da177e4SLinus Torvalds	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
52641da177e4SLinus Torvalds
52651da177e4SLinus Torvalds	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
52661da177e4SLinus Torvalds
52671da177e4SLinus Torvalds	mov.l		INT(%a6),%d1
52681da177e4SLinus Torvalds	asl.l		&4,%d1
52691da177e4SLinus Torvalds	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
52701da177e4SLinus Torvalds
52711da177e4SLinus Torvalds	fsub.x		(%a1)+,%fp0		# X-Y1
52721da177e4SLinus Torvalds	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
52731da177e4SLinus Torvalds
52741da177e4SLinus TorvaldsSCCONT:
52751da177e4SLinus Torvalds#--continuation point from REDUCEX
52761da177e4SLinus Torvalds
52771da177e4SLinus Torvalds	mov.l		INT(%a6),%d1
52781da177e4SLinus Torvalds	ror.l		&1,%d1
52791da177e4SLinus Torvalds	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
52801da177e4SLinus Torvalds	bge.w		NEVEN
52811da177e4SLinus Torvalds
52821da177e4SLinus TorvaldsSNODD:
52831da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR: D0, A0, FP2.
52841da177e4SLinus Torvalds	fmovm.x		&0x04,-(%sp)		# save fp2
52851da177e4SLinus Torvalds
52861da177e4SLinus Torvalds	fmov.x		%fp0,RPRIME(%a6)
52871da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
52881da177e4SLinus Torvalds	fmov.d		SINA7(%pc),%fp1		# A7
52891da177e4SLinus Torvalds	fmov.d		COSB8(%pc),%fp2		# B8
52901da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# SA7
52911da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# SB8
52921da177e4SLinus Torvalds
52931da177e4SLinus Torvalds	mov.l		%d2,-(%sp)
52941da177e4SLinus Torvalds	mov.l		%d1,%d2
52951da177e4SLinus Torvalds	ror.l		&1,%d2
52961da177e4SLinus Torvalds	and.l		&0x80000000,%d2
52971da177e4SLinus Torvalds	eor.l		%d1,%d2
52981da177e4SLinus Torvalds	and.l		&0x80000000,%d2
52991da177e4SLinus Torvalds
53001da177e4SLinus Torvalds	fadd.d		SINA6(%pc),%fp1		# A6+SA7
53011da177e4SLinus Torvalds	fadd.d		COSB7(%pc),%fp2		# B7+SB8
53021da177e4SLinus Torvalds
53031da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(A6+SA7)
53041da177e4SLinus Torvalds	eor.l		%d2,RPRIME(%a6)
53051da177e4SLinus Torvalds	mov.l		(%sp)+,%d2
53061da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(B7+SB8)
53071da177e4SLinus Torvalds	ror.l		&1,%d1
53081da177e4SLinus Torvalds	and.l		&0x80000000,%d1
53091da177e4SLinus Torvalds	mov.l		&0x3F800000,POSNEG1(%a6)
53101da177e4SLinus Torvalds	eor.l		%d1,POSNEG1(%a6)
53111da177e4SLinus Torvalds
53121da177e4SLinus Torvalds	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
53131da177e4SLinus Torvalds	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
53141da177e4SLinus Torvalds
53151da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
53161da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
53171da177e4SLinus Torvalds	fmov.x		%fp0,SPRIME(%a6)
53181da177e4SLinus Torvalds
53191da177e4SLinus Torvalds	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
53201da177e4SLinus Torvalds	eor.l		%d1,SPRIME(%a6)
53211da177e4SLinus Torvalds	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
53221da177e4SLinus Torvalds
53231da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(A4+...)
53241da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(B5+...)
53251da177e4SLinus Torvalds
53261da177e4SLinus Torvalds	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
53271da177e4SLinus Torvalds	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
53281da177e4SLinus Torvalds
53291da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(A3+...)
53301da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(B4+...)
53311da177e4SLinus Torvalds
53321da177e4SLinus Torvalds	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
53331da177e4SLinus Torvalds	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
53341da177e4SLinus Torvalds
53351da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(A2+...)
53361da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(B3+...)
53371da177e4SLinus Torvalds
53381da177e4SLinus Torvalds	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
53391da177e4SLinus Torvalds	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
53401da177e4SLinus Torvalds
53411da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(A1+...)
53421da177e4SLinus Torvalds	fmul.x		%fp2,%fp0		# S(B2+...)
53431da177e4SLinus Torvalds
53441da177e4SLinus Torvalds	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
53451da177e4SLinus Torvalds	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
53461da177e4SLinus Torvalds	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
53471da177e4SLinus Torvalds
53481da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x20		# restore fp2
53491da177e4SLinus Torvalds
53501da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
53511da177e4SLinus Torvalds	fadd.x		RPRIME(%a6),%fp1	# COS(X)
53521da177e4SLinus Torvalds	bsr		sto_cos			# store cosine result
53531da177e4SLinus Torvalds	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
53541da177e4SLinus Torvalds	bra		t_inx2
53551da177e4SLinus Torvalds
53561da177e4SLinus TorvaldsNEVEN:
53571da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR: FP2.
53581da177e4SLinus Torvalds	fmovm.x		&0x04,-(%sp)		# save fp2
53591da177e4SLinus Torvalds
53601da177e4SLinus Torvalds	fmov.x		%fp0,RPRIME(%a6)
53611da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
53621da177e4SLinus Torvalds
53631da177e4SLinus Torvalds	fmov.d		COSB8(%pc),%fp1		# B8
53641da177e4SLinus Torvalds	fmov.d		SINA7(%pc),%fp2		# A7
53651da177e4SLinus Torvalds
53661da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# SB8
53671da177e4SLinus Torvalds	fmov.x		%fp0,SPRIME(%a6)
53681da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# SA7
53691da177e4SLinus Torvalds
53701da177e4SLinus Torvalds	ror.l		&1,%d1
53711da177e4SLinus Torvalds	and.l		&0x80000000,%d1
53721da177e4SLinus Torvalds
53731da177e4SLinus Torvalds	fadd.d		COSB7(%pc),%fp1		# B7+SB8
53741da177e4SLinus Torvalds	fadd.d		SINA6(%pc),%fp2		# A6+SA7
53751da177e4SLinus Torvalds
53761da177e4SLinus Torvalds	eor.l		%d1,RPRIME(%a6)
53771da177e4SLinus Torvalds	eor.l		%d1,SPRIME(%a6)
53781da177e4SLinus Torvalds
53791da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(B7+SB8)
53801da177e4SLinus Torvalds
53811da177e4SLinus Torvalds	or.l		&0x3F800000,%d1
53821da177e4SLinus Torvalds	mov.l		%d1,POSNEG1(%a6)
53831da177e4SLinus Torvalds
53841da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(A6+SA7)
53851da177e4SLinus Torvalds
53861da177e4SLinus Torvalds	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
53871da177e4SLinus Torvalds	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
53881da177e4SLinus Torvalds
53891da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
53901da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
53911da177e4SLinus Torvalds
53921da177e4SLinus Torvalds	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
53931da177e4SLinus Torvalds	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
53941da177e4SLinus Torvalds
53951da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(B5+...)
53961da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(A4+...)
53971da177e4SLinus Torvalds
53981da177e4SLinus Torvalds	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
53991da177e4SLinus Torvalds	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
54001da177e4SLinus Torvalds
54011da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(B4+...)
54021da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(A3+...)
54031da177e4SLinus Torvalds
54041da177e4SLinus Torvalds	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
54051da177e4SLinus Torvalds	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
54061da177e4SLinus Torvalds
54071da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(B3+...)
54081da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(A2+...)
54091da177e4SLinus Torvalds
54101da177e4SLinus Torvalds	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
54111da177e4SLinus Torvalds	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
54121da177e4SLinus Torvalds
54131da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# S(B2+...)
54141da177e4SLinus Torvalds	fmul.x		%fp2,%fp0		# s(a1+...)
54151da177e4SLinus Torvalds
54161da177e4SLinus Torvalds
54171da177e4SLinus Torvalds	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
54181da177e4SLinus Torvalds	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
54191da177e4SLinus Torvalds	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
54201da177e4SLinus Torvalds
54211da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x20		# restore fp2
54221da177e4SLinus Torvalds
54231da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
54241da177e4SLinus Torvalds	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
54251da177e4SLinus Torvalds	bsr		sto_cos			# store cosine result
54261da177e4SLinus Torvalds	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
54271da177e4SLinus Torvalds	bra		t_inx2
54281da177e4SLinus Torvalds
54291da177e4SLinus Torvalds################################################
54301da177e4SLinus Torvalds
54311da177e4SLinus TorvaldsSCBORS:
54321da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
54331da177e4SLinus Torvalds	bgt.w		SREDUCEX
54341da177e4SLinus Torvalds
54351da177e4SLinus Torvalds################################################
54361da177e4SLinus Torvalds
54371da177e4SLinus TorvaldsSCSM:
54381da177e4SLinus Torvalds#	mov.w		&0x0000,XDCARE(%a6)
54391da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp1
54401da177e4SLinus Torvalds
54411da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
54421da177e4SLinus Torvalds	fsub.s		&0x00800000,%fp1
54431da177e4SLinus Torvalds	bsr		sto_cos			# store cosine result
54441da177e4SLinus Torvalds	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
54451da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
54461da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0
54471da177e4SLinus Torvalds	bra		t_catch
54481da177e4SLinus Torvalds
54491da177e4SLinus Torvalds##############################################
54501da177e4SLinus Torvalds
54511da177e4SLinus Torvalds	global		ssincosd
54521da177e4SLinus Torvalds#--SIN AND COS OF X FOR DENORMALIZED X
54531da177e4SLinus Torvaldsssincosd:
54541da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save d0
54551da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp1
54561da177e4SLinus Torvalds	bsr		sto_cos			# store cosine result
54571da177e4SLinus Torvalds	mov.l		(%sp)+,%d0		# restore d0
54581da177e4SLinus Torvalds	bra		t_extdnrm
54591da177e4SLinus Torvalds
54601da177e4SLinus Torvalds############################################
54611da177e4SLinus Torvalds
54621da177e4SLinus Torvalds#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
54631da177e4SLinus Torvalds#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
54641da177e4SLinus Torvalds#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
54651da177e4SLinus TorvaldsSREDUCEX:
54661da177e4SLinus Torvalds	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
54671da177e4SLinus Torvalds	mov.l		%d2,-(%sp)		# save d2
54681da177e4SLinus Torvalds	fmov.s		&0x00000000,%fp1	# fp1 = 0
54691da177e4SLinus Torvalds
54701da177e4SLinus Torvalds#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
54711da177e4SLinus Torvalds#--there is a danger of unwanted overflow in first LOOP iteration.  In this
54721da177e4SLinus Torvalds#--case, reduce argument by one remainder step to make subsequent reduction
54731da177e4SLinus Torvalds#--safe.
54741da177e4SLinus Torvalds	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
54751da177e4SLinus Torvalds	bne.b		SLOOP			# no
54761da177e4SLinus Torvalds
54771da177e4SLinus Torvalds# yes; create 2**16383*PI/2
54781da177e4SLinus Torvalds	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
54791da177e4SLinus Torvalds	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
54801da177e4SLinus Torvalds	clr.l		FP_SCR0_LO(%a6)
54811da177e4SLinus Torvalds
54821da177e4SLinus Torvalds# create low half of 2**16383*PI/2 at FP_SCR1
54831da177e4SLinus Torvalds	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
54841da177e4SLinus Torvalds	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
54851da177e4SLinus Torvalds	clr.l		FP_SCR1_LO(%a6)
54861da177e4SLinus Torvalds
54871da177e4SLinus Torvalds	ftest.x		%fp0			# test sign of argument
54881da177e4SLinus Torvalds	fblt.w		sred_neg
54891da177e4SLinus Torvalds
54901da177e4SLinus Torvalds	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
54911da177e4SLinus Torvalds	or.b		&0x80,FP_SCR1_EX(%a6)
54921da177e4SLinus Torvaldssred_neg:
54931da177e4SLinus Torvalds	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
54941da177e4SLinus Torvalds	fmov.x		%fp0,%fp1		# save high result in fp1
54951da177e4SLinus Torvalds	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
54961da177e4SLinus Torvalds	fsub.x		%fp0,%fp1		# determine low component of result
54971da177e4SLinus Torvalds	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
54981da177e4SLinus Torvalds
54991da177e4SLinus Torvalds#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
55001da177e4SLinus Torvalds#--integer quotient will be stored in N
55011da177e4SLinus Torvalds#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
55021da177e4SLinus TorvaldsSLOOP:
55031da177e4SLinus Torvalds	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
55041da177e4SLinus Torvalds	mov.w		INARG(%a6),%d1
55051da177e4SLinus Torvalds	mov.l		%d1,%a1			# save a copy of D0
55061da177e4SLinus Torvalds	and.l		&0x00007FFF,%d1
55071da177e4SLinus Torvalds	sub.l		&0x00003FFF,%d1		# d0 = K
55081da177e4SLinus Torvalds	cmp.l		%d1,&28
55091da177e4SLinus Torvalds	ble.b		SLASTLOOP
55101da177e4SLinus TorvaldsSCONTLOOP:
55111da177e4SLinus Torvalds	sub.l		&27,%d1			# d0 = L := K-27
55121da177e4SLinus Torvalds	mov.b		&0,ENDFLAG(%a6)
55131da177e4SLinus Torvalds	bra.b		SWORK
55141da177e4SLinus TorvaldsSLASTLOOP:
55151da177e4SLinus Torvalds	clr.l		%d1			# d0 = L := 0
55161da177e4SLinus Torvalds	mov.b		&1,ENDFLAG(%a6)
55171da177e4SLinus Torvalds
55181da177e4SLinus TorvaldsSWORK:
55191da177e4SLinus Torvalds#--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
55201da177e4SLinus Torvalds#--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
55211da177e4SLinus Torvalds
55221da177e4SLinus Torvalds#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
55231da177e4SLinus Torvalds#--2**L * (PIby2_1), 2**L * (PIby2_2)
55241da177e4SLinus Torvalds
55251da177e4SLinus Torvalds	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
55261da177e4SLinus Torvalds	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
55271da177e4SLinus Torvalds
55281da177e4SLinus Torvalds	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
55291da177e4SLinus Torvalds	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
55301da177e4SLinus Torvalds	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
55311da177e4SLinus Torvalds
55321da177e4SLinus Torvalds	fmov.x		%fp0,%fp2
55331da177e4SLinus Torvalds	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
55341da177e4SLinus Torvalds
55351da177e4SLinus Torvalds#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
55361da177e4SLinus Torvalds#--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
55371da177e4SLinus Torvalds#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
55381da177e4SLinus Torvalds#--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
55391da177e4SLinus Torvalds#--US THE DESIRED VALUE IN FLOATING POINT.
55401da177e4SLinus Torvalds	mov.l		%a1,%d2
55411da177e4SLinus Torvalds	swap		%d2
55421da177e4SLinus Torvalds	and.l		&0x80000000,%d2
55431da177e4SLinus Torvalds	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
55441da177e4SLinus Torvalds	mov.l		%d2,TWOTO63(%a6)
55451da177e4SLinus Torvalds	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
55461da177e4SLinus Torvalds	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
55471da177e4SLinus Torvalds#	fint.x		%fp2
55481da177e4SLinus Torvalds
55491da177e4SLinus Torvalds#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
55501da177e4SLinus Torvalds	mov.l		%d1,%d2			# d2 = L
55511da177e4SLinus Torvalds
55521da177e4SLinus Torvalds	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
55531da177e4SLinus Torvalds	mov.w		%d2,FP_SCR0_EX(%a6)
55541da177e4SLinus Torvalds	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
55551da177e4SLinus Torvalds	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
55561da177e4SLinus Torvalds
55571da177e4SLinus Torvalds	add.l		&0x00003FDD,%d1
55581da177e4SLinus Torvalds	mov.w		%d1,FP_SCR1_EX(%a6)
55591da177e4SLinus Torvalds	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
55601da177e4SLinus Torvalds	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
55611da177e4SLinus Torvalds
55621da177e4SLinus Torvalds	mov.b		ENDFLAG(%a6),%d1
55631da177e4SLinus Torvalds
55641da177e4SLinus Torvalds#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
55651da177e4SLinus Torvalds#--P2 = 2**(L) * Piby2_2
55661da177e4SLinus Torvalds	fmov.x		%fp2,%fp4		# fp4 = N
55671da177e4SLinus Torvalds	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
55681da177e4SLinus Torvalds	fmov.x		%fp2,%fp5		# fp5 = N
55691da177e4SLinus Torvalds	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
55701da177e4SLinus Torvalds	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
55711da177e4SLinus Torvalds
55721da177e4SLinus Torvalds#--we want P+p = W+w  but  |p| <= half ulp of P
55731da177e4SLinus Torvalds#--Then, we need to compute  A := R-P   and  a := r-p
55741da177e4SLinus Torvalds	fadd.x		%fp5,%fp3		# fp3 = P
55751da177e4SLinus Torvalds	fsub.x		%fp3,%fp4		# fp4 = W-P
55761da177e4SLinus Torvalds
55771da177e4SLinus Torvalds	fsub.x		%fp3,%fp0		# fp0 = A := R - P
55781da177e4SLinus Torvalds	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
55791da177e4SLinus Torvalds
55801da177e4SLinus Torvalds	fmov.x		%fp0,%fp3		# fp3 = A
55811da177e4SLinus Torvalds	fsub.x		%fp4,%fp1		# fp1 = a := r - p
55821da177e4SLinus Torvalds
55831da177e4SLinus Torvalds#--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
55841da177e4SLinus Torvalds#--|r| <= half ulp of R.
55851da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# fp0 = R := A+a
55861da177e4SLinus Torvalds#--No need to calculate r if this is the last loop
55871da177e4SLinus Torvalds	cmp.b		%d1,&0
55881da177e4SLinus Torvalds	bgt.w		SRESTORE
55891da177e4SLinus Torvalds
55901da177e4SLinus Torvalds#--Need to calculate r
55911da177e4SLinus Torvalds	fsub.x		%fp0,%fp3		# fp3 = A-R
55921da177e4SLinus Torvalds	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
55931da177e4SLinus Torvalds	bra.w		SLOOP
55941da177e4SLinus Torvalds
55951da177e4SLinus TorvaldsSRESTORE:
55961da177e4SLinus Torvalds	fmov.l		%fp2,INT(%a6)
55971da177e4SLinus Torvalds	mov.l		(%sp)+,%d2		# restore d2
55981da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
55991da177e4SLinus Torvalds
56001da177e4SLinus Torvalds	mov.l		ADJN(%a6),%d1
56011da177e4SLinus Torvalds	cmp.l		%d1,&4
56021da177e4SLinus Torvalds
56031da177e4SLinus Torvalds	blt.w		SINCONT
56041da177e4SLinus Torvalds	bra.w		SCCONT
56051da177e4SLinus Torvalds
56061da177e4SLinus Torvalds#########################################################################
56071da177e4SLinus Torvalds# stan():  computes the tangent of a normalized input			#
56081da177e4SLinus Torvalds# stand(): computes the tangent of a denormalized input			#
56091da177e4SLinus Torvalds#									#
56101da177e4SLinus Torvalds# INPUT *************************************************************** #
56111da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
56121da177e4SLinus Torvalds#	d0 = round precision,mode					#
56131da177e4SLinus Torvalds#									#
56141da177e4SLinus Torvalds# OUTPUT ************************************************************** #
56151da177e4SLinus Torvalds#	fp0 = tan(X)							#
56161da177e4SLinus Torvalds#									#
56171da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* #
56181da177e4SLinus Torvalds#	The returned result is within 3 ulp in 64 significant bit, i.e. #
56191da177e4SLinus Torvalds#	within 0.5001 ulp to 53 bits if the result is subsequently	#
56201da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
56211da177e4SLinus Torvalds#	in double precision.						#
56221da177e4SLinus Torvalds#									#
56231da177e4SLinus Torvalds# ALGORITHM *********************************************************** #
56241da177e4SLinus Torvalds#									#
56251da177e4SLinus Torvalds#	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
56261da177e4SLinus Torvalds#									#
56271da177e4SLinus Torvalds#	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
56281da177e4SLinus Torvalds#		k = N mod 2, so in particular, k = 0 or 1.		#
56291da177e4SLinus Torvalds#									#
56301da177e4SLinus Torvalds#	3. If k is odd, go to 5.					#
56311da177e4SLinus Torvalds#									#
56321da177e4SLinus Torvalds#	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
56331da177e4SLinus Torvalds#		rational function U/V where				#
56341da177e4SLinus Torvalds#		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
56351da177e4SLinus Torvalds#		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
56361da177e4SLinus Torvalds#		Exit.							#
56371da177e4SLinus Torvalds#									#
56381da177e4SLinus Torvalds#	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
56391da177e4SLinus Torvalds#		a rational function U/V where				#
56401da177e4SLinus Torvalds#		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
56411da177e4SLinus Torvalds#		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
56421da177e4SLinus Torvalds#		-Cot(r) = -V/U. Exit.					#
56431da177e4SLinus Torvalds#									#
56441da177e4SLinus Torvalds#	6. If |X| > 1, go to 8.						#
56451da177e4SLinus Torvalds#									#
56461da177e4SLinus Torvalds#	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
56471da177e4SLinus Torvalds#									#
56481da177e4SLinus Torvalds#	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back	#
56491da177e4SLinus Torvalds#		to 2.							#
56501da177e4SLinus Torvalds#									#
56511da177e4SLinus Torvalds#########################################################################
56521da177e4SLinus Torvalds
56531da177e4SLinus TorvaldsTANQ4:
56541da177e4SLinus Torvalds	long		0x3EA0B759,0xF50F8688
56551da177e4SLinus TorvaldsTANP3:
56561da177e4SLinus Torvalds	long		0xBEF2BAA5,0xA8924F04
56571da177e4SLinus Torvalds
56581da177e4SLinus TorvaldsTANQ3:
56591da177e4SLinus Torvalds	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
56601da177e4SLinus Torvalds
56611da177e4SLinus TorvaldsTANP2:
56621da177e4SLinus Torvalds	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
56631da177e4SLinus Torvalds
56641da177e4SLinus TorvaldsTANQ2:
56651da177e4SLinus Torvalds	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
56661da177e4SLinus Torvalds
56671da177e4SLinus TorvaldsTANP1:
56681da177e4SLinus Torvalds	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
56691da177e4SLinus Torvalds
56701da177e4SLinus TorvaldsTANQ1:
56711da177e4SLinus Torvalds	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
56721da177e4SLinus Torvalds
56731da177e4SLinus TorvaldsINVTWOPI:
56741da177e4SLinus Torvalds	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
56751da177e4SLinus Torvalds
56761da177e4SLinus TorvaldsTWOPI1:
56771da177e4SLinus Torvalds	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
56781da177e4SLinus TorvaldsTWOPI2:
56791da177e4SLinus Torvalds	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
56801da177e4SLinus Torvalds
56811da177e4SLinus Torvalds#--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
56821da177e4SLinus Torvalds#--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
56831da177e4SLinus Torvalds#--MOST 69 BITS LONG.
56841da177e4SLinus Torvalds#	global		PITBL
56851da177e4SLinus TorvaldsPITBL:
56861da177e4SLinus Torvalds	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
56871da177e4SLinus Torvalds	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
56881da177e4SLinus Torvalds	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
56891da177e4SLinus Torvalds	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
56901da177e4SLinus Torvalds	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
56911da177e4SLinus Torvalds	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
56921da177e4SLinus Torvalds	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
56931da177e4SLinus Torvalds	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
56941da177e4SLinus Torvalds	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
56951da177e4SLinus Torvalds	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
56961da177e4SLinus Torvalds	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
56971da177e4SLinus Torvalds	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
56981da177e4SLinus Torvalds	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
56991da177e4SLinus Torvalds	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
57001da177e4SLinus Torvalds	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
57011da177e4SLinus Torvalds	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
57021da177e4SLinus Torvalds	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
57031da177e4SLinus Torvalds	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
57041da177e4SLinus Torvalds	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
57051da177e4SLinus Torvalds	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
57061da177e4SLinus Torvalds	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
57071da177e4SLinus Torvalds	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
57081da177e4SLinus Torvalds	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
57091da177e4SLinus Torvalds	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
57101da177e4SLinus Torvalds	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
57111da177e4SLinus Torvalds	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
57121da177e4SLinus Torvalds	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
57131da177e4SLinus Torvalds	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
57141da177e4SLinus Torvalds	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
57151da177e4SLinus Torvalds	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
57161da177e4SLinus Torvalds	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
57171da177e4SLinus Torvalds	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
57181da177e4SLinus Torvalds	long		0x00000000,0x00000000,0x00000000,0x00000000
57191da177e4SLinus Torvalds	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
57201da177e4SLinus Torvalds	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
57211da177e4SLinus Torvalds	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
57221da177e4SLinus Torvalds	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
57231da177e4SLinus Torvalds	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
57241da177e4SLinus Torvalds	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
57251da177e4SLinus Torvalds	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
57261da177e4SLinus Torvalds	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
57271da177e4SLinus Torvalds	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
57281da177e4SLinus Torvalds	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
57291da177e4SLinus Torvalds	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
57301da177e4SLinus Torvalds	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
57311da177e4SLinus Torvalds	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
57321da177e4SLinus Torvalds	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
57331da177e4SLinus Torvalds	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
57341da177e4SLinus Torvalds	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
57351da177e4SLinus Torvalds	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
57361da177e4SLinus Torvalds	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
57371da177e4SLinus Torvalds	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
57381da177e4SLinus Torvalds	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
57391da177e4SLinus Torvalds	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
57401da177e4SLinus Torvalds	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
57411da177e4SLinus Torvalds	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
57421da177e4SLinus Torvalds	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
57431da177e4SLinus Torvalds	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
57441da177e4SLinus Torvalds	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
57451da177e4SLinus Torvalds	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
57461da177e4SLinus Torvalds	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
57471da177e4SLinus Torvalds	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
57481da177e4SLinus Torvalds	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
57491da177e4SLinus Torvalds	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
57501da177e4SLinus Torvalds	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
57511da177e4SLinus Torvalds
57521da177e4SLinus Torvalds	set		INARG,FP_SCR0
57531da177e4SLinus Torvalds
57541da177e4SLinus Torvalds	set		TWOTO63,L_SCR1
57551da177e4SLinus Torvalds	set		INT,L_SCR1
57561da177e4SLinus Torvalds	set		ENDFLAG,L_SCR2
57571da177e4SLinus Torvalds
57581da177e4SLinus Torvalds	global		stan
57591da177e4SLinus Torvaldsstan:
57601da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
57611da177e4SLinus Torvalds
57621da177e4SLinus Torvalds	mov.l		(%a0),%d1
57631da177e4SLinus Torvalds	mov.w		4(%a0),%d1
57641da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
57651da177e4SLinus Torvalds
57661da177e4SLinus Torvalds	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
57671da177e4SLinus Torvalds	bge.b		TANOK1
57681da177e4SLinus Torvalds	bra.w		TANSM
57691da177e4SLinus TorvaldsTANOK1:
57701da177e4SLinus Torvalds	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
57711da177e4SLinus Torvalds	blt.b		TANMAIN
57721da177e4SLinus Torvalds	bra.w		REDUCEX
57731da177e4SLinus Torvalds
57741da177e4SLinus TorvaldsTANMAIN:
57751da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| <= 15 PI.
57761da177e4SLinus Torvalds#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
57771da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
57781da177e4SLinus Torvalds	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
57791da177e4SLinus Torvalds
57801da177e4SLinus Torvalds	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
57811da177e4SLinus Torvalds
57821da177e4SLinus Torvalds	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
57831da177e4SLinus Torvalds
57841da177e4SLinus Torvalds	asl.l		&4,%d1
57851da177e4SLinus Torvalds	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
57861da177e4SLinus Torvalds
57871da177e4SLinus Torvalds	fsub.x		(%a1)+,%fp0		# X-Y1
57881da177e4SLinus Torvalds
57891da177e4SLinus Torvalds	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
57901da177e4SLinus Torvalds
57911da177e4SLinus Torvalds	ror.l		&5,%d1
57921da177e4SLinus Torvalds	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
57931da177e4SLinus Torvalds
57941da177e4SLinus TorvaldsTANCONT:
57951da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
57961da177e4SLinus Torvalds
57971da177e4SLinus Torvalds	cmp.l		%d1,&0
57981da177e4SLinus Torvalds	blt.w		NODD
57991da177e4SLinus Torvalds
58001da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
58011da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# S = R*R
58021da177e4SLinus Torvalds
58031da177e4SLinus Torvalds	fmov.d		TANQ4(%pc),%fp3
58041da177e4SLinus Torvalds	fmov.d		TANP3(%pc),%fp2
58051da177e4SLinus Torvalds
58061da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# SQ4
58071da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# SP3
58081da177e4SLinus Torvalds
58091da177e4SLinus Torvalds	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
58101da177e4SLinus Torvalds	fadd.x		TANP2(%pc),%fp2		# P2+SP3
58111da177e4SLinus Torvalds
58121da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
58131da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# S(P2+SP3)
58141da177e4SLinus Torvalds
58151da177e4SLinus Torvalds	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
58161da177e4SLinus Torvalds	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
58171da177e4SLinus Torvalds
58181da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
58191da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
58201da177e4SLinus Torvalds
58211da177e4SLinus Torvalds	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
58221da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
58231da177e4SLinus Torvalds
58241da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
58251da177e4SLinus Torvalds
58261da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
58271da177e4SLinus Torvalds
58281da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
58291da177e4SLinus Torvalds
58301da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
58311da177e4SLinus Torvalds
58321da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
58331da177e4SLinus Torvalds	fdiv.x		%fp1,%fp0		# last inst - possible exception set
58341da177e4SLinus Torvalds	bra		t_inx2
58351da177e4SLinus Torvalds
58361da177e4SLinus TorvaldsNODD:
58371da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
58381da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# S = R*R
58391da177e4SLinus Torvalds
58401da177e4SLinus Torvalds	fmov.d		TANQ4(%pc),%fp3
58411da177e4SLinus Torvalds	fmov.d		TANP3(%pc),%fp2
58421da177e4SLinus Torvalds
58431da177e4SLinus Torvalds	fmul.x		%fp0,%fp3		# SQ4
58441da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# SP3
58451da177e4SLinus Torvalds
58461da177e4SLinus Torvalds	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
58471da177e4SLinus Torvalds	fadd.x		TANP2(%pc),%fp2		# P2+SP3
58481da177e4SLinus Torvalds
58491da177e4SLinus Torvalds	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
58501da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(P2+SP3)
58511da177e4SLinus Torvalds
58521da177e4SLinus Torvalds	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
58531da177e4SLinus Torvalds	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
58541da177e4SLinus Torvalds
58551da177e4SLinus Torvalds	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
58561da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
58571da177e4SLinus Torvalds
58581da177e4SLinus Torvalds	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
58591da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
58601da177e4SLinus Torvalds
58611da177e4SLinus Torvalds	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
58621da177e4SLinus Torvalds
58631da177e4SLinus Torvalds	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
58641da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
58651da177e4SLinus Torvalds
58661da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
58671da177e4SLinus Torvalds
58681da177e4SLinus Torvalds	fmov.x		%fp1,-(%sp)
58691da177e4SLinus Torvalds	eor.l		&0x80000000,(%sp)
58701da177e4SLinus Torvalds
58711da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
58721da177e4SLinus Torvalds	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
58731da177e4SLinus Torvalds	bra		t_inx2
58741da177e4SLinus Torvalds
58751da177e4SLinus TorvaldsTANBORS:
58761da177e4SLinus Torvalds#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
58771da177e4SLinus Torvalds#--IF |X| < 2**(-40), RETURN X OR 1.
58781da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
58791da177e4SLinus Torvalds	bgt.b		REDUCEX
58801da177e4SLinus Torvalds
58811da177e4SLinus TorvaldsTANSM:
58821da177e4SLinus Torvalds	fmov.x		%fp0,-(%sp)
58831da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round mode,prec
58841da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
58851da177e4SLinus Torvalds	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
58861da177e4SLinus Torvalds	bra		t_catch
58871da177e4SLinus Torvalds
58881da177e4SLinus Torvalds	global		stand
58891da177e4SLinus Torvalds#--TAN(X) = X FOR DENORMALIZED X
58901da177e4SLinus Torvaldsstand:
58911da177e4SLinus Torvalds	bra		t_extdnrm
58921da177e4SLinus Torvalds
58931da177e4SLinus Torvalds#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
58941da177e4SLinus Torvalds#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
58951da177e4SLinus Torvalds#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
58961da177e4SLinus TorvaldsREDUCEX:
58971da177e4SLinus Torvalds	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
58981da177e4SLinus Torvalds	mov.l		%d2,-(%sp)		# save d2
58991da177e4SLinus Torvalds	fmov.s		&0x00000000,%fp1	# fp1 = 0
59001da177e4SLinus Torvalds
59011da177e4SLinus Torvalds#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
59021da177e4SLinus Torvalds#--there is a danger of unwanted overflow in first LOOP iteration.  In this
59031da177e4SLinus Torvalds#--case, reduce argument by one remainder step to make subsequent reduction
59041da177e4SLinus Torvalds#--safe.
59051da177e4SLinus Torvalds	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
59061da177e4SLinus Torvalds	bne.b		LOOP			# no
59071da177e4SLinus Torvalds
59081da177e4SLinus Torvalds# yes; create 2**16383*PI/2
59091da177e4SLinus Torvalds	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
59101da177e4SLinus Torvalds	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
59111da177e4SLinus Torvalds	clr.l		FP_SCR0_LO(%a6)
59121da177e4SLinus Torvalds
59131da177e4SLinus Torvalds# create low half of 2**16383*PI/2 at FP_SCR1
59141da177e4SLinus Torvalds	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
59151da177e4SLinus Torvalds	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
59161da177e4SLinus Torvalds	clr.l		FP_SCR1_LO(%a6)
59171da177e4SLinus Torvalds
59181da177e4SLinus Torvalds	ftest.x		%fp0			# test sign of argument
59191da177e4SLinus Torvalds	fblt.w		red_neg
59201da177e4SLinus Torvalds
59211da177e4SLinus Torvalds	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
59221da177e4SLinus Torvalds	or.b		&0x80,FP_SCR1_EX(%a6)
59231da177e4SLinus Torvaldsred_neg:
59241da177e4SLinus Torvalds	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
59251da177e4SLinus Torvalds	fmov.x		%fp0,%fp1		# save high result in fp1
59261da177e4SLinus Torvalds	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
59271da177e4SLinus Torvalds	fsub.x		%fp0,%fp1		# determine low component of result
59281da177e4SLinus Torvalds	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
59291da177e4SLinus Torvalds
59301da177e4SLinus Torvalds#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
59311da177e4SLinus Torvalds#--integer quotient will be stored in N
59321da177e4SLinus Torvalds#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
59331da177e4SLinus TorvaldsLOOP:
59341da177e4SLinus Torvalds	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
59351da177e4SLinus Torvalds	mov.w		INARG(%a6),%d1
59361da177e4SLinus Torvalds	mov.l		%d1,%a1			# save a copy of D0
59371da177e4SLinus Torvalds	and.l		&0x00007FFF,%d1
59381da177e4SLinus Torvalds	sub.l		&0x00003FFF,%d1		# d0 = K
59391da177e4SLinus Torvalds	cmp.l		%d1,&28
59401da177e4SLinus Torvalds	ble.b		LASTLOOP
59411da177e4SLinus TorvaldsCONTLOOP:
59421da177e4SLinus Torvalds	sub.l		&27,%d1			# d0 = L := K-27
59431da177e4SLinus Torvalds	mov.b		&0,ENDFLAG(%a6)
59441da177e4SLinus Torvalds	bra.b		WORK
59451da177e4SLinus TorvaldsLASTLOOP:
59461da177e4SLinus Torvalds	clr.l		%d1			# d0 = L := 0
59471da177e4SLinus Torvalds	mov.b		&1,ENDFLAG(%a6)
59481da177e4SLinus Torvalds
59491da177e4SLinus TorvaldsWORK:
59501da177e4SLinus Torvalds#--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
59511da177e4SLinus Torvalds#--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
59521da177e4SLinus Torvalds
59531da177e4SLinus Torvalds#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
59541da177e4SLinus Torvalds#--2**L * (PIby2_1), 2**L * (PIby2_2)
59551da177e4SLinus Torvalds
59561da177e4SLinus Torvalds	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
59571da177e4SLinus Torvalds	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
59581da177e4SLinus Torvalds
59591da177e4SLinus Torvalds	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
59601da177e4SLinus Torvalds	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
59611da177e4SLinus Torvalds	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
59621da177e4SLinus Torvalds
59631da177e4SLinus Torvalds	fmov.x		%fp0,%fp2
59641da177e4SLinus Torvalds	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
59651da177e4SLinus Torvalds
59661da177e4SLinus Torvalds#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
59671da177e4SLinus Torvalds#--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
59681da177e4SLinus Torvalds#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
59691da177e4SLinus Torvalds#--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
59701da177e4SLinus Torvalds#--US THE DESIRED VALUE IN FLOATING POINT.
59711da177e4SLinus Torvalds	mov.l		%a1,%d2
59721da177e4SLinus Torvalds	swap		%d2
59731da177e4SLinus Torvalds	and.l		&0x80000000,%d2
59741da177e4SLinus Torvalds	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
59751da177e4SLinus Torvalds	mov.l		%d2,TWOTO63(%a6)
59761da177e4SLinus Torvalds	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
59771da177e4SLinus Torvalds	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
59781da177e4SLinus Torvalds#	fintrz.x	%fp2,%fp2
59791da177e4SLinus Torvalds
59801da177e4SLinus Torvalds#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
59811da177e4SLinus Torvalds	mov.l		%d1,%d2			# d2 = L
59821da177e4SLinus Torvalds
59831da177e4SLinus Torvalds	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
59841da177e4SLinus Torvalds	mov.w		%d2,FP_SCR0_EX(%a6)
59851da177e4SLinus Torvalds	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
59861da177e4SLinus Torvalds	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
59871da177e4SLinus Torvalds
59881da177e4SLinus Torvalds	add.l		&0x00003FDD,%d1
59891da177e4SLinus Torvalds	mov.w		%d1,FP_SCR1_EX(%a6)
59901da177e4SLinus Torvalds	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
59911da177e4SLinus Torvalds	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
59921da177e4SLinus Torvalds
59931da177e4SLinus Torvalds	mov.b		ENDFLAG(%a6),%d1
59941da177e4SLinus Torvalds
59951da177e4SLinus Torvalds#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
59961da177e4SLinus Torvalds#--P2 = 2**(L) * Piby2_2
59971da177e4SLinus Torvalds	fmov.x		%fp2,%fp4		# fp4 = N
59981da177e4SLinus Torvalds	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
59991da177e4SLinus Torvalds	fmov.x		%fp2,%fp5		# fp5 = N
60001da177e4SLinus Torvalds	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
60011da177e4SLinus Torvalds	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
60021da177e4SLinus Torvalds
60031da177e4SLinus Torvalds#--we want P+p = W+w  but  |p| <= half ulp of P
60041da177e4SLinus Torvalds#--Then, we need to compute  A := R-P   and  a := r-p
60051da177e4SLinus Torvalds	fadd.x		%fp5,%fp3		# fp3 = P
60061da177e4SLinus Torvalds	fsub.x		%fp3,%fp4		# fp4 = W-P
60071da177e4SLinus Torvalds
60081da177e4SLinus Torvalds	fsub.x		%fp3,%fp0		# fp0 = A := R - P
60091da177e4SLinus Torvalds	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
60101da177e4SLinus Torvalds
60111da177e4SLinus Torvalds	fmov.x		%fp0,%fp3		# fp3 = A
60121da177e4SLinus Torvalds	fsub.x		%fp4,%fp1		# fp1 = a := r - p
60131da177e4SLinus Torvalds
60141da177e4SLinus Torvalds#--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
60151da177e4SLinus Torvalds#--|r| <= half ulp of R.
60161da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# fp0 = R := A+a
60171da177e4SLinus Torvalds#--No need to calculate r if this is the last loop
60181da177e4SLinus Torvalds	cmp.b		%d1,&0
60191da177e4SLinus Torvalds	bgt.w		RESTORE
60201da177e4SLinus Torvalds
60211da177e4SLinus Torvalds#--Need to calculate r
60221da177e4SLinus Torvalds	fsub.x		%fp0,%fp3		# fp3 = A-R
60231da177e4SLinus Torvalds	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
60241da177e4SLinus Torvalds	bra.w		LOOP
60251da177e4SLinus Torvalds
60261da177e4SLinus TorvaldsRESTORE:
60271da177e4SLinus Torvalds	fmov.l		%fp2,INT(%a6)
60281da177e4SLinus Torvalds	mov.l		(%sp)+,%d2		# restore d2
60291da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
60301da177e4SLinus Torvalds
60311da177e4SLinus Torvalds	mov.l		INT(%a6),%d1
60321da177e4SLinus Torvalds	ror.l		&1,%d1
60331da177e4SLinus Torvalds
60341da177e4SLinus Torvalds	bra.w		TANCONT
60351da177e4SLinus Torvalds
60361da177e4SLinus Torvalds#########################################################################
60371da177e4SLinus Torvalds# satan():  computes the arctangent of a normalized number		#
60381da177e4SLinus Torvalds# satand(): computes the arctangent of a denormalized number		#
60391da177e4SLinus Torvalds#									#
60401da177e4SLinus Torvalds# INPUT	*************************************************************** #
60411da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
60421da177e4SLinus Torvalds#	d0 = round precision,mode					#
60431da177e4SLinus Torvalds#									#
60441da177e4SLinus Torvalds# OUTPUT ************************************************************** #
60451da177e4SLinus Torvalds#	fp0 = arctan(X)							#
60461da177e4SLinus Torvalds#									#
60471da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* #
60481da177e4SLinus Torvalds#	The returned result is within 2 ulps in	64 significant bit,	#
60491da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
60501da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
60511da177e4SLinus Torvalds#	in double precision.						#
60521da177e4SLinus Torvalds#									#
60531da177e4SLinus Torvalds# ALGORITHM *********************************************************** #
60541da177e4SLinus Torvalds#	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
60551da177e4SLinus Torvalds#									#
60561da177e4SLinus Torvalds#	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x.			#
60571da177e4SLinus Torvalds#		Note that k = -4, -3,..., or 3.				#
60581da177e4SLinus Torvalds#		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5	#
60591da177e4SLinus Torvalds#		significant bits of X with a bit-1 attached at the 6-th	#
60601da177e4SLinus Torvalds#		bit position. Define u to be u = (X-F) / (1 + X*F).	#
60611da177e4SLinus Torvalds#									#
60621da177e4SLinus Torvalds#	Step 3. Approximate arctan(u) by a polynomial poly.		#
60631da177e4SLinus Torvalds#									#
60641da177e4SLinus Torvalds#	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a	#
60651da177e4SLinus Torvalds#		table of values calculated beforehand. Exit.		#
60661da177e4SLinus Torvalds#									#
60671da177e4SLinus Torvalds#	Step 5. If |X| >= 16, go to Step 7.				#
60681da177e4SLinus Torvalds#									#
60691da177e4SLinus Torvalds#	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
60701da177e4SLinus Torvalds#									#
60711da177e4SLinus Torvalds#	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd	#
60721da177e4SLinus Torvalds#		polynomial in X'.					#
60731da177e4SLinus Torvalds#		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
60741da177e4SLinus Torvalds#									#
60751da177e4SLinus Torvalds#########################################################################
60761da177e4SLinus Torvalds
60771da177e4SLinus TorvaldsATANA3:	long		0xBFF6687E,0x314987D8
60781da177e4SLinus TorvaldsATANA2:	long		0x4002AC69,0x34A26DB3
60791da177e4SLinus TorvaldsATANA1:	long		0xBFC2476F,0x4E1DA28E
60801da177e4SLinus Torvalds
60811da177e4SLinus TorvaldsATANB6:	long		0x3FB34444,0x7F876989
60821da177e4SLinus TorvaldsATANB5:	long		0xBFB744EE,0x7FAF45DB
60831da177e4SLinus TorvaldsATANB4:	long		0x3FBC71C6,0x46940220
60841da177e4SLinus TorvaldsATANB3:	long		0xBFC24924,0x921872F9
60851da177e4SLinus TorvaldsATANB2:	long		0x3FC99999,0x99998FA9
60861da177e4SLinus TorvaldsATANB1:	long		0xBFD55555,0x55555555
60871da177e4SLinus Torvalds
60881da177e4SLinus TorvaldsATANC5:	long		0xBFB70BF3,0x98539E6A
60891da177e4SLinus TorvaldsATANC4:	long		0x3FBC7187,0x962D1D7D
60901da177e4SLinus TorvaldsATANC3:	long		0xBFC24924,0x827107B8
60911da177e4SLinus TorvaldsATANC2:	long		0x3FC99999,0x9996263E
60921da177e4SLinus TorvaldsATANC1:	long		0xBFD55555,0x55555536
60931da177e4SLinus Torvalds
60941da177e4SLinus TorvaldsPPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
60951da177e4SLinus TorvaldsNPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
60961da177e4SLinus Torvalds
60971da177e4SLinus TorvaldsPTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
60981da177e4SLinus TorvaldsNTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
60991da177e4SLinus Torvalds
61001da177e4SLinus TorvaldsATANTBL:
61011da177e4SLinus Torvalds	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
61021da177e4SLinus Torvalds	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
61031da177e4SLinus Torvalds	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
61041da177e4SLinus Torvalds	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
61051da177e4SLinus Torvalds	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
61061da177e4SLinus Torvalds	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
61071da177e4SLinus Torvalds	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
61081da177e4SLinus Torvalds	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
61091da177e4SLinus Torvalds	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
61101da177e4SLinus Torvalds	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
61111da177e4SLinus Torvalds	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
61121da177e4SLinus Torvalds	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
61131da177e4SLinus Torvalds	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
61141da177e4SLinus Torvalds	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
61151da177e4SLinus Torvalds	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
61161da177e4SLinus Torvalds	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
61171da177e4SLinus Torvalds	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
61181da177e4SLinus Torvalds	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
61191da177e4SLinus Torvalds	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
61201da177e4SLinus Torvalds	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
61211da177e4SLinus Torvalds	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
61221da177e4SLinus Torvalds	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
61231da177e4SLinus Torvalds	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
61241da177e4SLinus Torvalds	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
61251da177e4SLinus Torvalds	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
61261da177e4SLinus Torvalds	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
61271da177e4SLinus Torvalds	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
61281da177e4SLinus Torvalds	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
61291da177e4SLinus Torvalds	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
61301da177e4SLinus Torvalds	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
61311da177e4SLinus Torvalds	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
61321da177e4SLinus Torvalds	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
61331da177e4SLinus Torvalds	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
61341da177e4SLinus Torvalds	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
61351da177e4SLinus Torvalds	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
61361da177e4SLinus Torvalds	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
61371da177e4SLinus Torvalds	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
61381da177e4SLinus Torvalds	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
61391da177e4SLinus Torvalds	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
61401da177e4SLinus Torvalds	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
61411da177e4SLinus Torvalds	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
61421da177e4SLinus Torvalds	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
61431da177e4SLinus Torvalds	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
61441da177e4SLinus Torvalds	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
61451da177e4SLinus Torvalds	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
61461da177e4SLinus Torvalds	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
61471da177e4SLinus Torvalds	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
61481da177e4SLinus Torvalds	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
61491da177e4SLinus Torvalds	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
61501da177e4SLinus Torvalds	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
61511da177e4SLinus Torvalds	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
61521da177e4SLinus Torvalds	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
61531da177e4SLinus Torvalds	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
61541da177e4SLinus Torvalds	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
61551da177e4SLinus Torvalds	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
61561da177e4SLinus Torvalds	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
61571da177e4SLinus Torvalds	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
61581da177e4SLinus Torvalds	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
61591da177e4SLinus Torvalds	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
61601da177e4SLinus Torvalds	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
61611da177e4SLinus Torvalds	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
61621da177e4SLinus Torvalds	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
61631da177e4SLinus Torvalds	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
61641da177e4SLinus Torvalds	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
61651da177e4SLinus Torvalds	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
61661da177e4SLinus Torvalds	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
61671da177e4SLinus Torvalds	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
61681da177e4SLinus Torvalds	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
61691da177e4SLinus Torvalds	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
61701da177e4SLinus Torvalds	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
61711da177e4SLinus Torvalds	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
61721da177e4SLinus Torvalds	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
61731da177e4SLinus Torvalds	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
61741da177e4SLinus Torvalds	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
61751da177e4SLinus Torvalds	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
61761da177e4SLinus Torvalds	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
61771da177e4SLinus Torvalds	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
61781da177e4SLinus Torvalds	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
61791da177e4SLinus Torvalds	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
61801da177e4SLinus Torvalds	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
61811da177e4SLinus Torvalds	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
61821da177e4SLinus Torvalds	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
61831da177e4SLinus Torvalds	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
61841da177e4SLinus Torvalds	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
61851da177e4SLinus Torvalds	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
61861da177e4SLinus Torvalds	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
61871da177e4SLinus Torvalds	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
61881da177e4SLinus Torvalds	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
61891da177e4SLinus Torvalds	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
61901da177e4SLinus Torvalds	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
61911da177e4SLinus Torvalds	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
61921da177e4SLinus Torvalds	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
61931da177e4SLinus Torvalds	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
61941da177e4SLinus Torvalds	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
61951da177e4SLinus Torvalds	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
61961da177e4SLinus Torvalds	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
61971da177e4SLinus Torvalds	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
61981da177e4SLinus Torvalds	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
61991da177e4SLinus Torvalds	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
62001da177e4SLinus Torvalds	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
62011da177e4SLinus Torvalds	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
62021da177e4SLinus Torvalds	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
62031da177e4SLinus Torvalds	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
62041da177e4SLinus Torvalds	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
62051da177e4SLinus Torvalds	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
62061da177e4SLinus Torvalds	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
62071da177e4SLinus Torvalds	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
62081da177e4SLinus Torvalds	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
62091da177e4SLinus Torvalds	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
62101da177e4SLinus Torvalds	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
62111da177e4SLinus Torvalds	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
62121da177e4SLinus Torvalds	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
62131da177e4SLinus Torvalds	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
62141da177e4SLinus Torvalds	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
62151da177e4SLinus Torvalds	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
62161da177e4SLinus Torvalds	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
62171da177e4SLinus Torvalds	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
62181da177e4SLinus Torvalds	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
62191da177e4SLinus Torvalds	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
62201da177e4SLinus Torvalds	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
62211da177e4SLinus Torvalds	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
62221da177e4SLinus Torvalds	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
62231da177e4SLinus Torvalds	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
62241da177e4SLinus Torvalds	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
62251da177e4SLinus Torvalds	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
62261da177e4SLinus Torvalds	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
62271da177e4SLinus Torvalds	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
62281da177e4SLinus Torvalds	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
62291da177e4SLinus Torvalds
62301da177e4SLinus Torvalds	set		X,FP_SCR0
62311da177e4SLinus Torvalds	set		XDCARE,X+2
62321da177e4SLinus Torvalds	set		XFRAC,X+4
62331da177e4SLinus Torvalds	set		XFRACLO,X+8
62341da177e4SLinus Torvalds
62351da177e4SLinus Torvalds	set		ATANF,FP_SCR1
62361da177e4SLinus Torvalds	set		ATANFHI,ATANF+4
62371da177e4SLinus Torvalds	set		ATANFLO,ATANF+8
62381da177e4SLinus Torvalds
62391da177e4SLinus Torvalds	global		satan
62401da177e4SLinus Torvalds#--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
62411da177e4SLinus Torvaldssatan:
62421da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
62431da177e4SLinus Torvalds
62441da177e4SLinus Torvalds	mov.l		(%a0),%d1
62451da177e4SLinus Torvalds	mov.w		4(%a0),%d1
62461da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)
62471da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
62481da177e4SLinus Torvalds
62491da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
62501da177e4SLinus Torvalds	bge.b		ATANOK1
62511da177e4SLinus Torvalds	bra.w		ATANSM
62521da177e4SLinus Torvalds
62531da177e4SLinus TorvaldsATANOK1:
62541da177e4SLinus Torvalds	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
62551da177e4SLinus Torvalds	ble.b		ATANMAIN
62561da177e4SLinus Torvalds	bra.w		ATANBIG
62571da177e4SLinus Torvalds
62581da177e4SLinus Torvalds#--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
62591da177e4SLinus Torvalds#--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
62601da177e4SLinus Torvalds#--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
62611da177e4SLinus Torvalds#--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
62621da177e4SLinus Torvalds#--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
62631da177e4SLinus Torvalds#--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
62641da177e4SLinus Torvalds#--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
62651da177e4SLinus Torvalds#--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
62661da177e4SLinus Torvalds#--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
62671da177e4SLinus Torvalds#--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
62681da177e4SLinus Torvalds#--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
62691da177e4SLinus Torvalds#--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
62701da177e4SLinus Torvalds#--WILL INVOLVE A VERY LONG POLYNOMIAL.
62711da177e4SLinus Torvalds
62721da177e4SLinus Torvalds#--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
62731da177e4SLinus Torvalds#--WE CHOSE F TO BE +-2^K * 1.BBBB1
62741da177e4SLinus Torvalds#--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
62751da177e4SLinus Torvalds#--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
62761da177e4SLinus Torvalds#--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
62771da177e4SLinus Torvalds#-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
62781da177e4SLinus Torvalds
62791da177e4SLinus TorvaldsATANMAIN:
62801da177e4SLinus Torvalds
62811da177e4SLinus Torvalds	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
62821da177e4SLinus Torvalds	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
62831da177e4SLinus Torvalds	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
62841da177e4SLinus Torvalds
62851da177e4SLinus Torvalds	fmov.x		%fp0,%fp1		# FP1 IS X
62861da177e4SLinus Torvalds	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
62871da177e4SLinus Torvalds	fsub.x		X(%a6),%fp0		# FP0 IS X-F
62881da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
62891da177e4SLinus Torvalds	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
62901da177e4SLinus Torvalds
62911da177e4SLinus Torvalds#--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
62921da177e4SLinus Torvalds#--CREATE ATAN(F) AND STORE IT IN ATANF, AND
62931da177e4SLinus Torvalds#--SAVE REGISTERS FP2.
62941da177e4SLinus Torvalds
62951da177e4SLinus Torvalds	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
62961da177e4SLinus Torvalds	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
62971da177e4SLinus Torvalds	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
62981da177e4SLinus Torvalds	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
62991da177e4SLinus Torvalds	sub.l		&0x3FFB0000,%d2		# K+4
63001da177e4SLinus Torvalds	asr.l		&1,%d2
63011da177e4SLinus Torvalds	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
63021da177e4SLinus Torvalds	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
63031da177e4SLinus Torvalds	lea		ATANTBL(%pc),%a1
63041da177e4SLinus Torvalds	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
63051da177e4SLinus Torvalds	mov.l		(%a1)+,ATANF(%a6)
63061da177e4SLinus Torvalds	mov.l		(%a1)+,ATANFHI(%a6)
63071da177e4SLinus Torvalds	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
63081da177e4SLinus Torvalds	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
63091da177e4SLinus Torvalds	and.l		&0x80000000,%d1		# SIGN(F)
63101da177e4SLinus Torvalds	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
63111da177e4SLinus Torvalds	mov.l		(%sp)+,%d2		# RESTORE d2
63121da177e4SLinus Torvalds
63131da177e4SLinus Torvalds#--THAT'S ALL I HAVE TO DO FOR NOW,
63141da177e4SLinus Torvalds#--BUT ALAS, THE DIVIDE IS STILL CRANKING!
63151da177e4SLinus Torvalds
63161da177e4SLinus Torvalds#--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
63171da177e4SLinus Torvalds#--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
63181da177e4SLinus Torvalds#--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
63191da177e4SLinus Torvalds#--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
63201da177e4SLinus Torvalds#--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
63211da177e4SLinus Torvalds#--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
63221da177e4SLinus Torvalds#--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
63231da177e4SLinus Torvalds
63241da177e4SLinus Torvalds	fmovm.x		&0x04,-(%sp)		# save fp2
63251da177e4SLinus Torvalds
63261da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
63271da177e4SLinus Torvalds	fmul.x		%fp1,%fp1
63281da177e4SLinus Torvalds	fmov.d		ATANA3(%pc),%fp2
63291da177e4SLinus Torvalds	fadd.x		%fp1,%fp2		# A3+V
63301da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# V*(A3+V)
63311da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# U*V
63321da177e4SLinus Torvalds	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
63331da177e4SLinus Torvalds	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
63341da177e4SLinus Torvalds	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
63351da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
63361da177e4SLinus Torvalds
63371da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x20		# restore fp2
63381da177e4SLinus Torvalds
63391da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
63401da177e4SLinus Torvalds	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
63411da177e4SLinus Torvalds	bra		t_inx2
63421da177e4SLinus Torvalds
63431da177e4SLinus TorvaldsATANBORS:
63441da177e4SLinus Torvalds#--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
63451da177e4SLinus Torvalds#--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
63461da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
63471da177e4SLinus Torvalds	bgt.w		ATANBIG			# I.E. |X| >= 16
63481da177e4SLinus Torvalds
63491da177e4SLinus TorvaldsATANSM:
63501da177e4SLinus Torvalds#--|X| <= 1/16
63511da177e4SLinus Torvalds#--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
63521da177e4SLinus Torvalds#--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
63531da177e4SLinus Torvalds#--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
63541da177e4SLinus Torvalds#--WHERE Y = X*X, AND Z = Y*Y.
63551da177e4SLinus Torvalds
63561da177e4SLinus Torvalds	cmp.l		%d1,&0x3FD78000
63571da177e4SLinus Torvalds	blt.w		ATANTINY
63581da177e4SLinus Torvalds
63591da177e4SLinus Torvalds#--COMPUTE POLYNOMIAL
63601da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
63611da177e4SLinus Torvalds
63621da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
63631da177e4SLinus Torvalds
63641da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
63651da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
63661da177e4SLinus Torvalds
63671da177e4SLinus Torvalds	fmov.d		ATANB6(%pc),%fp2
63681da177e4SLinus Torvalds	fmov.d		ATANB5(%pc),%fp3
63691da177e4SLinus Torvalds
63701da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# Z*B6
63711da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# Z*B5
63721da177e4SLinus Torvalds
63731da177e4SLinus Torvalds	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
63741da177e4SLinus Torvalds	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
63751da177e4SLinus Torvalds
63761da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
63771da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
63781da177e4SLinus Torvalds
63791da177e4SLinus Torvalds	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
63801da177e4SLinus Torvalds	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
63811da177e4SLinus Torvalds
63821da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
63831da177e4SLinus Torvalds	fmul.x		X(%a6),%fp0		# X*Y
63841da177e4SLinus Torvalds
63851da177e4SLinus Torvalds	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
63861da177e4SLinus Torvalds
63871da177e4SLinus Torvalds	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
63881da177e4SLinus Torvalds
63891da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
63901da177e4SLinus Torvalds
63911da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
63921da177e4SLinus Torvalds	fadd.x		X(%a6),%fp0
63931da177e4SLinus Torvalds	bra		t_inx2
63941da177e4SLinus Torvalds
63951da177e4SLinus TorvaldsATANTINY:
63961da177e4SLinus Torvalds#--|X| < 2^(-40), ATAN(X) = X
63971da177e4SLinus Torvalds
63981da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
63991da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
64001da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0		# last inst - possible exception set
64011da177e4SLinus Torvalds
64021da177e4SLinus Torvalds	bra		t_catch
64031da177e4SLinus Torvalds
64041da177e4SLinus TorvaldsATANBIG:
64051da177e4SLinus Torvalds#--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
64061da177e4SLinus Torvalds#--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
64071da177e4SLinus Torvalds	cmp.l		%d1,&0x40638000
64081da177e4SLinus Torvalds	bgt.w		ATANHUGE
64091da177e4SLinus Torvalds
64101da177e4SLinus Torvalds#--APPROXIMATE ATAN(-1/X) BY
64111da177e4SLinus Torvalds#--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
64121da177e4SLinus Torvalds#--THIS CAN BE RE-WRITTEN AS
64131da177e4SLinus Torvalds#--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
64141da177e4SLinus Torvalds
64151da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
64161da177e4SLinus Torvalds
64171da177e4SLinus Torvalds	fmov.s		&0xBF800000,%fp1	# LOAD -1
64181da177e4SLinus Torvalds	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
64191da177e4SLinus Torvalds
64201da177e4SLinus Torvalds#--DIVIDE IS STILL CRANKING
64211da177e4SLinus Torvalds
64221da177e4SLinus Torvalds	fmov.x		%fp1,%fp0		# FP0 IS X'
64231da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
64241da177e4SLinus Torvalds	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
64251da177e4SLinus Torvalds
64261da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
64271da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
64281da177e4SLinus Torvalds
64291da177e4SLinus Torvalds	fmov.d		ATANC5(%pc),%fp3
64301da177e4SLinus Torvalds	fmov.d		ATANC4(%pc),%fp2
64311da177e4SLinus Torvalds
64321da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# Z*C5
64331da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# Z*B4
64341da177e4SLinus Torvalds
64351da177e4SLinus Torvalds	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
64361da177e4SLinus Torvalds	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
64371da177e4SLinus Torvalds
64381da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
64391da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
64401da177e4SLinus Torvalds
64411da177e4SLinus Torvalds	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
64421da177e4SLinus Torvalds	fmul.x		X(%a6),%fp0		# X'*Y
64431da177e4SLinus Torvalds
64441da177e4SLinus Torvalds	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
64451da177e4SLinus Torvalds
64461da177e4SLinus Torvalds	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
64471da177e4SLinus Torvalds#					...	+[Y*(B2+Z*(B4+Z*B6))])
64481da177e4SLinus Torvalds	fadd.x		X(%a6),%fp0
64491da177e4SLinus Torvalds
64501da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
64511da177e4SLinus Torvalds
64521da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
64531da177e4SLinus Torvalds	tst.b		(%a0)
64541da177e4SLinus Torvalds	bpl.b		pos_big
64551da177e4SLinus Torvalds
64561da177e4SLinus Torvaldsneg_big:
64571da177e4SLinus Torvalds	fadd.x		NPIBY2(%pc),%fp0
64581da177e4SLinus Torvalds	bra		t_minx2
64591da177e4SLinus Torvalds
64601da177e4SLinus Torvaldspos_big:
64611da177e4SLinus Torvalds	fadd.x		PPIBY2(%pc),%fp0
64621da177e4SLinus Torvalds	bra		t_pinx2
64631da177e4SLinus Torvalds
64641da177e4SLinus TorvaldsATANHUGE:
64651da177e4SLinus Torvalds#--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
64661da177e4SLinus Torvalds	tst.b		(%a0)
64671da177e4SLinus Torvalds	bpl.b		pos_huge
64681da177e4SLinus Torvalds
64691da177e4SLinus Torvaldsneg_huge:
64701da177e4SLinus Torvalds	fmov.x		NPIBY2(%pc),%fp0
64711da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
64721da177e4SLinus Torvalds	fadd.x		PTINY(%pc),%fp0
64731da177e4SLinus Torvalds	bra		t_minx2
64741da177e4SLinus Torvalds
64751da177e4SLinus Torvaldspos_huge:
64761da177e4SLinus Torvalds	fmov.x		PPIBY2(%pc),%fp0
64771da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
64781da177e4SLinus Torvalds	fadd.x		NTINY(%pc),%fp0
64791da177e4SLinus Torvalds	bra		t_pinx2
64801da177e4SLinus Torvalds
64811da177e4SLinus Torvalds	global		satand
64821da177e4SLinus Torvalds#--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
64831da177e4SLinus Torvaldssatand:
64841da177e4SLinus Torvalds	bra		t_extdnrm
64851da177e4SLinus Torvalds
64861da177e4SLinus Torvalds#########################################################################
64871da177e4SLinus Torvalds# sasin():  computes the inverse sine of a normalized input		#
64881da177e4SLinus Torvalds# sasind(): computes the inverse sine of a denormalized input		#
64891da177e4SLinus Torvalds#									#
64901da177e4SLinus Torvalds# INPUT ***************************************************************	#
64911da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
64921da177e4SLinus Torvalds#	d0 = round precision,mode					#
64931da177e4SLinus Torvalds#									#
64941da177e4SLinus Torvalds# OUTPUT **************************************************************	#
64951da177e4SLinus Torvalds#	fp0 = arcsin(X)							#
64961da177e4SLinus Torvalds#									#
64971da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
64981da177e4SLinus Torvalds#	The returned result is within 3 ulps in	64 significant bit,	#
64991da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
65001da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
65011da177e4SLinus Torvalds#	in double precision.						#
65021da177e4SLinus Torvalds#									#
65031da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
65041da177e4SLinus Torvalds#									#
65051da177e4SLinus Torvalds#	ASIN								#
65061da177e4SLinus Torvalds#	1. If |X| >= 1, go to 3.					#
65071da177e4SLinus Torvalds#									#
65081da177e4SLinus Torvalds#	2. (|X| < 1) Calculate asin(X) by				#
65091da177e4SLinus Torvalds#		z := sqrt( [1-X][1+X] )					#
65101da177e4SLinus Torvalds#		asin(X) = atan( x / z ).				#
65111da177e4SLinus Torvalds#		Exit.							#
65121da177e4SLinus Torvalds#									#
65131da177e4SLinus Torvalds#	3. If |X| > 1, go to 5.						#
65141da177e4SLinus Torvalds#									#
65151da177e4SLinus Torvalds#	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
65161da177e4SLinus Torvalds#									#
65171da177e4SLinus Torvalds#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
65181da177e4SLinus Torvalds#		Exit.							#
65191da177e4SLinus Torvalds#									#
65201da177e4SLinus Torvalds#########################################################################
65211da177e4SLinus Torvalds
65221da177e4SLinus Torvalds	global		sasin
65231da177e4SLinus Torvaldssasin:
65241da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
65251da177e4SLinus Torvalds
65261da177e4SLinus Torvalds	mov.l		(%a0),%d1
65271da177e4SLinus Torvalds	mov.w		4(%a0),%d1
65281da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
65291da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
65301da177e4SLinus Torvalds	bge.b		ASINBIG
65311da177e4SLinus Torvalds
65321da177e4SLinus Torvalds# This catch is added here for the '060 QSP. Originally, the call to
65331da177e4SLinus Torvalds# satan() would handle this case by causing the exception which would
65341da177e4SLinus Torvalds# not be caught until gen_except(). Now, with the exceptions being
65351da177e4SLinus Torvalds# detected inside of satan(), the exception would have been handled there
65361da177e4SLinus Torvalds# instead of inside sasin() as expected.
65371da177e4SLinus Torvalds	cmp.l		%d1,&0x3FD78000
65381da177e4SLinus Torvalds	blt.w		ASINTINY
65391da177e4SLinus Torvalds
65401da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 1
65411da177e4SLinus Torvalds#--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
65421da177e4SLinus Torvalds
65431da177e4SLinus TorvaldsASINMAIN:
65441da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp1
65451da177e4SLinus Torvalds	fsub.x		%fp0,%fp1		# 1-X
65461da177e4SLinus Torvalds	fmovm.x		&0x4,-(%sp)		#  {fp2}
65471da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp2
65481da177e4SLinus Torvalds	fadd.x		%fp0,%fp2		# 1+X
65491da177e4SLinus Torvalds	fmul.x		%fp2,%fp1		# (1+X)(1-X)
65501da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x20		#  {fp2}
65511da177e4SLinus Torvalds	fsqrt.x		%fp1			# SQRT([1-X][1+X])
65521da177e4SLinus Torvalds	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
65531da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
65541da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
65551da177e4SLinus Torvalds	bsr		satan
65561da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
65571da177e4SLinus Torvalds	bra		t_inx2
65581da177e4SLinus Torvalds
65591da177e4SLinus TorvaldsASINBIG:
65601da177e4SLinus Torvalds	fabs.x		%fp0			# |X|
65611da177e4SLinus Torvalds	fcmp.s		%fp0,&0x3F800000
65621da177e4SLinus Torvalds	fbgt		t_operr			# cause an operr exception
65631da177e4SLinus Torvalds
65641da177e4SLinus Torvalds#--|X| = 1, ASIN(X) = +- PI/2.
65651da177e4SLinus TorvaldsASINONE:
65661da177e4SLinus Torvalds	fmov.x		PIBY2(%pc),%fp0
65671da177e4SLinus Torvalds	mov.l		(%a0),%d1
65681da177e4SLinus Torvalds	and.l		&0x80000000,%d1		# SIGN BIT OF X
65691da177e4SLinus Torvalds	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
65701da177e4SLinus Torvalds	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
65711da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
65721da177e4SLinus Torvalds	fmul.s		(%sp)+,%fp0
65731da177e4SLinus Torvalds	bra		t_inx2
65741da177e4SLinus Torvalds
65751da177e4SLinus Torvalds#--|X| < 2^(-40), ATAN(X) = X
65761da177e4SLinus TorvaldsASINTINY:
65771da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
65781da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
65791da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# last inst - possible exception
65801da177e4SLinus Torvalds	bra		t_catch
65811da177e4SLinus Torvalds
65821da177e4SLinus Torvalds	global		sasind
65831da177e4SLinus Torvalds#--ASIN(X) = X FOR DENORMALIZED X
65841da177e4SLinus Torvaldssasind:
65851da177e4SLinus Torvalds	bra		t_extdnrm
65861da177e4SLinus Torvalds
65871da177e4SLinus Torvalds#########################################################################
65881da177e4SLinus Torvalds# sacos():  computes the inverse cosine of a normalized input		#
65891da177e4SLinus Torvalds# sacosd(): computes the inverse cosine of a denormalized input		#
65901da177e4SLinus Torvalds#									#
65911da177e4SLinus Torvalds# INPUT ***************************************************************	#
65921da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
65931da177e4SLinus Torvalds#	d0 = round precision,mode					#
65941da177e4SLinus Torvalds#									#
65951da177e4SLinus Torvalds# OUTPUT ************************************************************** #
65961da177e4SLinus Torvalds#	fp0 = arccos(X)							#
65971da177e4SLinus Torvalds#									#
65981da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
65991da177e4SLinus Torvalds#	The returned result is within 3 ulps in	64 significant bit,	#
66001da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
66011da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
66021da177e4SLinus Torvalds#	in double precision.						#
66031da177e4SLinus Torvalds#									#
66041da177e4SLinus Torvalds# ALGORITHM *********************************************************** #
66051da177e4SLinus Torvalds#									#
66061da177e4SLinus Torvalds#	ACOS								#
66071da177e4SLinus Torvalds#	1. If |X| >= 1, go to 3.					#
66081da177e4SLinus Torvalds#									#
66091da177e4SLinus Torvalds#	2. (|X| < 1) Calculate acos(X) by				#
66101da177e4SLinus Torvalds#		z := (1-X) / (1+X)					#
66111da177e4SLinus Torvalds#		acos(X) = 2 * atan( sqrt(z) ).				#
66121da177e4SLinus Torvalds#		Exit.							#
66131da177e4SLinus Torvalds#									#
66141da177e4SLinus Torvalds#	3. If |X| > 1, go to 5.						#
66151da177e4SLinus Torvalds#									#
66161da177e4SLinus Torvalds#	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
66171da177e4SLinus Torvalds#									#
66181da177e4SLinus Torvalds#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
66191da177e4SLinus Torvalds#		Exit.							#
66201da177e4SLinus Torvalds#									#
66211da177e4SLinus Torvalds#########################################################################
66221da177e4SLinus Torvalds
66231da177e4SLinus Torvalds	global		sacos
66241da177e4SLinus Torvaldssacos:
66251da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
66261da177e4SLinus Torvalds
66271da177e4SLinus Torvalds	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
66281da177e4SLinus Torvalds	mov.w		4(%a0),%d1
66291da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
66301da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
66311da177e4SLinus Torvalds	bge.b		ACOSBIG
66321da177e4SLinus Torvalds
66331da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 1
66341da177e4SLinus Torvalds#--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
66351da177e4SLinus Torvalds
66361da177e4SLinus TorvaldsACOSMAIN:
66371da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp1
66381da177e4SLinus Torvalds	fadd.x		%fp0,%fp1		# 1+X
66391da177e4SLinus Torvalds	fneg.x		%fp0			# -X
66401da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp0	# 1-X
66411da177e4SLinus Torvalds	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
66421da177e4SLinus Torvalds	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
66431da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save original users fpcr
66441da177e4SLinus Torvalds	clr.l		%d0
66451da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
66461da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to sqrt
66471da177e4SLinus Torvalds	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
66481da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear SQRT(...) from stack
66491da177e4SLinus Torvalds
66501da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
66511da177e4SLinus Torvalds	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
66521da177e4SLinus Torvalds	bra		t_pinx2
66531da177e4SLinus Torvalds
66541da177e4SLinus TorvaldsACOSBIG:
66551da177e4SLinus Torvalds	fabs.x		%fp0
66561da177e4SLinus Torvalds	fcmp.s		%fp0,&0x3F800000
66571da177e4SLinus Torvalds	fbgt		t_operr			# cause an operr exception
66581da177e4SLinus Torvalds
66591da177e4SLinus Torvalds#--|X| = 1, ACOS(X) = 0 OR PI
66601da177e4SLinus Torvalds	tst.b		(%a0)			# is X positive or negative?
66611da177e4SLinus Torvalds	bpl.b		ACOSP1
66621da177e4SLinus Torvalds
66631da177e4SLinus Torvalds#--X = -1
66641da177e4SLinus Torvalds#Returns PI and inexact exception
66651da177e4SLinus TorvaldsACOSM1:
66661da177e4SLinus Torvalds	fmov.x		PI(%pc),%fp0		# load PI
66671da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# load round mode,prec
66681da177e4SLinus Torvalds	fadd.s		&0x00800000,%fp0	# add a small value
66691da177e4SLinus Torvalds	bra		t_pinx2
66701da177e4SLinus Torvalds
66711da177e4SLinus TorvaldsACOSP1:
66721da177e4SLinus Torvalds	bra		ld_pzero		# answer is positive zero
66731da177e4SLinus Torvalds
66741da177e4SLinus Torvalds	global		sacosd
66751da177e4SLinus Torvalds#--ACOS(X) = PI/2 FOR DENORMALIZED X
66761da177e4SLinus Torvaldssacosd:
66771da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
66781da177e4SLinus Torvalds	fmov.x		PIBY2(%pc),%fp0
66791da177e4SLinus Torvalds	bra		t_pinx2
66801da177e4SLinus Torvalds
66811da177e4SLinus Torvalds#########################################################################
66821da177e4SLinus Torvalds# setox():    computes the exponential for a normalized input		#
66831da177e4SLinus Torvalds# setoxd():   computes the exponential for a denormalized input		#
66841da177e4SLinus Torvalds# setoxm1():  computes the exponential minus 1 for a normalized input	#
66851da177e4SLinus Torvalds# setoxm1d(): computes the exponential minus 1 for a denormalized input	#
66861da177e4SLinus Torvalds#									#
66871da177e4SLinus Torvalds# INPUT	*************************************************************** #
66881da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
66891da177e4SLinus Torvalds#	d0 = round precision,mode					#
66901da177e4SLinus Torvalds#									#
66911da177e4SLinus Torvalds# OUTPUT ************************************************************** #
66921da177e4SLinus Torvalds#	fp0 = exp(X) or exp(X)-1					#
66931da177e4SLinus Torvalds#									#
66941da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* #
66951da177e4SLinus Torvalds#	The returned result is within 0.85 ulps in 64 significant bit,	#
66961da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
66971da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
66981da177e4SLinus Torvalds#	in double precision.						#
66991da177e4SLinus Torvalds#									#
67001da177e4SLinus Torvalds# ALGORITHM and IMPLEMENTATION **************************************** #
67011da177e4SLinus Torvalds#									#
67021da177e4SLinus Torvalds#	setoxd								#
67031da177e4SLinus Torvalds#	------								#
67041da177e4SLinus Torvalds#	Step 1.	Set ans := 1.0						#
67051da177e4SLinus Torvalds#									#
67061da177e4SLinus Torvalds#	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
67071da177e4SLinus Torvalds#	Notes:	This will always generate one exception -- inexact.	#
67081da177e4SLinus Torvalds#									#
67091da177e4SLinus Torvalds#									#
67101da177e4SLinus Torvalds#	setox								#
67111da177e4SLinus Torvalds#	-----								#
67121da177e4SLinus Torvalds#									#
67131da177e4SLinus Torvalds#	Step 1.	Filter out extreme cases of input argument.		#
67141da177e4SLinus Torvalds#		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
67151da177e4SLinus Torvalds#		1.2	Go to Step 7.					#
67161da177e4SLinus Torvalds#		1.3	If |X| < 16380 log(2), go to Step 2.		#
67171da177e4SLinus Torvalds#		1.4	Go to Step 8.					#
67181da177e4SLinus Torvalds#	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
67191da177e4SLinus Torvalds#		To avoid the use of floating-point comparisons, a	#
67201da177e4SLinus Torvalds#		compact representation of |X| is used. This format is a	#
67211da177e4SLinus Torvalds#		32-bit integer, the upper (more significant) 16 bits	#
67221da177e4SLinus Torvalds#		are the sign and biased exponent field of |X|; the	#
67231da177e4SLinus Torvalds#		lower 16 bits are the 16 most significant fraction	#
67241da177e4SLinus Torvalds#		(including the explicit bit) bits of |X|. Consequently,	#
67251da177e4SLinus Torvalds#		the comparisons in Steps 1.1 and 1.3 can be performed	#
67261da177e4SLinus Torvalds#		by integer comparison. Note also that the constant	#
67271da177e4SLinus Torvalds#		16380 log(2) used in Step 1.3 is also in the compact	#
67281da177e4SLinus Torvalds#		form. Thus taking the branch to Step 2 guarantees	#
67291da177e4SLinus Torvalds#		|X| < 16380 log(2). There is no harm to have a small	#
67301da177e4SLinus Torvalds#		number of cases where |X| is less than,	but close to,	#
67311da177e4SLinus Torvalds#		16380 log(2) and the branch to Step 9 is taken.		#
67321da177e4SLinus Torvalds#									#
67331da177e4SLinus Torvalds#	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
67341da177e4SLinus Torvalds#		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
67351da177e4SLinus Torvalds#			was taken)					#
67361da177e4SLinus Torvalds#		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
67371da177e4SLinus Torvalds#		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
67381da177e4SLinus Torvalds#			or 63.						#
67391da177e4SLinus Torvalds#		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
67401da177e4SLinus Torvalds#		2.5	Calculate the address of the stored value of	#
67411da177e4SLinus Torvalds#			2^(J/64).					#
67421da177e4SLinus Torvalds#		2.6	Create the value Scale = 2^M.			#
67431da177e4SLinus Torvalds#	Notes:	The calculation in 2.2 is really performed by		#
67441da177e4SLinus Torvalds#			Z := X * constant				#
67451da177e4SLinus Torvalds#			N := round-to-nearest-integer(Z)		#
67461da177e4SLinus Torvalds#		where							#
67471da177e4SLinus Torvalds#			constant := single-precision( 64/log 2 ).	#
67481da177e4SLinus Torvalds#									#
67491da177e4SLinus Torvalds#		Using a single-precision constant avoids memory		#
67501da177e4SLinus Torvalds#		access. Another effect of using a single-precision	#
67511da177e4SLinus Torvalds#		"constant" is that the calculated value Z is		#
67521da177e4SLinus Torvalds#									#
67531da177e4SLinus Torvalds#			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
67541da177e4SLinus Torvalds#									#
67551da177e4SLinus Torvalds#		This error has to be considered later in Steps 3 and 4.	#
67561da177e4SLinus Torvalds#									#
67571da177e4SLinus Torvalds#	Step 3.	Calculate X - N*log2/64.				#
67581da177e4SLinus Torvalds#		3.1	R := X + N*L1,					#
67591da177e4SLinus Torvalds#				where L1 := single-precision(-log2/64).	#
67601da177e4SLinus Torvalds#		3.2	R := R + N*L2,					#
67611da177e4SLinus Torvalds#				L2 := extended-precision(-log2/64 - L1).#
67621da177e4SLinus Torvalds#	Notes:	a) The way L1 and L2 are chosen ensures L1+L2		#
67631da177e4SLinus Torvalds#		approximate the value -log2/64 to 88 bits of accuracy.	#
67641da177e4SLinus Torvalds#		b) N*L1 is exact because N is no longer than 22 bits	#
67651da177e4SLinus Torvalds#		and L1 is no longer than 24 bits.			#
67661da177e4SLinus Torvalds#		c) The calculation X+N*L1 is also exact due to		#
67671da177e4SLinus Torvalds#		cancellation. Thus, R is practically X+N(L1+L2) to full	#
67681da177e4SLinus Torvalds#		64 bits.						#
67691da177e4SLinus Torvalds#		d) It is important to estimate how large can |R| be	#
67701da177e4SLinus Torvalds#		after Step 3.2.						#
67711da177e4SLinus Torvalds#									#
67721da177e4SLinus Torvalds#		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
67731da177e4SLinus Torvalds#		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
67741da177e4SLinus Torvalds#		X*64/log2 - N	=	f - eps*X 64/log2		#
67751da177e4SLinus Torvalds#		X - N*log2/64	=	f*log2/64 - eps*X		#
67761da177e4SLinus Torvalds#									#
67771da177e4SLinus Torvalds#									#
67781da177e4SLinus Torvalds#		Now |X| <= 16446 log2, thus				#
67791da177e4SLinus Torvalds#									#
67801da177e4SLinus Torvalds#			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
67811da177e4SLinus Torvalds#					<= 0.57 log2/64.		#
67821da177e4SLinus Torvalds#		 This bound will be used in Step 4.			#
67831da177e4SLinus Torvalds#									#
67841da177e4SLinus Torvalds#	Step 4.	Approximate exp(R)-1 by a polynomial			#
67851da177e4SLinus Torvalds#		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
67861da177e4SLinus Torvalds#	Notes:	a) In order to reduce memory access, the coefficients	#
67871da177e4SLinus Torvalds#		are made as "short" as possible: A1 (which is 1/2), A4	#
67881da177e4SLinus Torvalds#		and A5 are single precision; A2 and A3 are double	#
67891da177e4SLinus Torvalds#		precision.						#
67901da177e4SLinus Torvalds#		b) Even with the restrictions above,			#
67911da177e4SLinus Torvalds#		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
67921da177e4SLinus Torvalds#		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
67931da177e4SLinus Torvalds#		c) To fully utilize the pipeline, p is separated into	#
67941da177e4SLinus Torvalds#		two independent pieces of roughly equal complexities	#
67951da177e4SLinus Torvalds#			p = [ R + R*S*(A2 + S*A4) ]	+		#
67961da177e4SLinus Torvalds#				[ S*(A1 + S*(A3 + S*A5)) ]		#
67971da177e4SLinus Torvalds#		where S = R*R.						#
67981da177e4SLinus Torvalds#									#
67991da177e4SLinus Torvalds#	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
68001da177e4SLinus Torvalds#				ans := T + ( T*p + t)			#
68011da177e4SLinus Torvalds#		where T and t are the stored values for 2^(J/64).	#
68021da177e4SLinus Torvalds#	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
68031da177e4SLinus Torvalds#		2^(J/64) to roughly 85 bits; T is in extended precision	#
68041da177e4SLinus Torvalds#		and t is in single precision. Note also that T is	#
68051da177e4SLinus Torvalds#		rounded to 62 bits so that the last two bits of T are	#
68061da177e4SLinus Torvalds#		zero. The reason for such a special form is that T-1,	#
68071da177e4SLinus Torvalds#		T-2, and T-8 will all be exact --- a property that will	#
68081da177e4SLinus Torvalds#		give much more accurate computation of the function	#
68091da177e4SLinus Torvalds#		EXPM1.							#
68101da177e4SLinus Torvalds#									#
68111da177e4SLinus Torvalds#	Step 6.	Reconstruction of exp(X)				#
68121da177e4SLinus Torvalds#			exp(X) = 2^M * 2^(J/64) * exp(R).		#
68131da177e4SLinus Torvalds#		6.1	If AdjFlag = 0, go to 6.3			#
68141da177e4SLinus Torvalds#		6.2	ans := ans * AdjScale				#
68151da177e4SLinus Torvalds#		6.3	Restore the user FPCR				#
68161da177e4SLinus Torvalds#		6.4	Return ans := ans * Scale. Exit.		#
68171da177e4SLinus Torvalds#	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
68181da177e4SLinus Torvalds#		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
68191da177e4SLinus Torvalds#		neither overflow nor underflow. If AdjFlag = 1, that	#
68201da177e4SLinus Torvalds#		means that						#
68211da177e4SLinus Torvalds#			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
68221da177e4SLinus Torvalds#		Hence, exp(X) may overflow or underflow or neither.	#
68231da177e4SLinus Torvalds#		When that is the case, AdjScale = 2^(M1) where M1 is	#
68241da177e4SLinus Torvalds#		approximately M. Thus 6.2 will never cause		#
68251da177e4SLinus Torvalds#		over/underflow. Possible exception in 6.4 is overflow	#
68261da177e4SLinus Torvalds#		or underflow. The inexact exception is not generated in	#
68271da177e4SLinus Torvalds#		6.4. Although one can argue that the inexact flag	#
68281da177e4SLinus Torvalds#		should always be raised, to simulate that exception	#
68291da177e4SLinus Torvalds#		cost to much than the flag is worth in practical uses.	#
68301da177e4SLinus Torvalds#									#
68311da177e4SLinus Torvalds#	Step 7.	Return 1 + X.						#
68321da177e4SLinus Torvalds#		7.1	ans := X					#
68331da177e4SLinus Torvalds#		7.2	Restore user FPCR.				#
68341da177e4SLinus Torvalds#		7.3	Return ans := 1 + ans. Exit			#
68351da177e4SLinus Torvalds#	Notes:	For non-zero X, the inexact exception will always be	#
68361da177e4SLinus Torvalds#		raised by 7.3. That is the only exception raised by 7.3.#
68371da177e4SLinus Torvalds#		Note also that we use the FMOVEM instruction to move X	#
68381da177e4SLinus Torvalds#		in Step 7.1 to avoid unnecessary trapping. (Although	#
68391da177e4SLinus Torvalds#		the FMOVEM may not seem relevant since X is normalized,	#
68401da177e4SLinus Torvalds#		the precaution will be useful in the library version of	#
68411da177e4SLinus Torvalds#		this code where the separate entry for denormalized	#
68421da177e4SLinus Torvalds#		inputs will be done away with.)				#
68431da177e4SLinus Torvalds#									#
68441da177e4SLinus Torvalds#	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
68451da177e4SLinus Torvalds#		8.1	If |X| > 16480 log2, go to Step 9.		#
68461da177e4SLinus Torvalds#		(mimic 2.2 - 2.6)					#
68471da177e4SLinus Torvalds#		8.2	N := round-to-integer( X * 64/log2 )		#
68481da177e4SLinus Torvalds#		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
68491da177e4SLinus Torvalds#		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1,	#
68501da177e4SLinus Torvalds#			AdjFlag := 1.					#
68511da177e4SLinus Torvalds#		8.5	Calculate the address of the stored value	#
68521da177e4SLinus Torvalds#			2^(J/64).					#
68531da177e4SLinus Torvalds#		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
68541da177e4SLinus Torvalds#		8.7	Go to Step 3.					#
68551da177e4SLinus Torvalds#	Notes:	Refer to notes for 2.2 - 2.6.				#
68561da177e4SLinus Torvalds#									#
68571da177e4SLinus Torvalds#	Step 9.	Handle exp(X), |X| > 16480 log2.			#
68581da177e4SLinus Torvalds#		9.1	If X < 0, go to 9.3				#
68591da177e4SLinus Torvalds#		9.2	ans := Huge, go to 9.4				#
68601da177e4SLinus Torvalds#		9.3	ans := Tiny.					#
68611da177e4SLinus Torvalds#		9.4	Restore user FPCR.				#
68621da177e4SLinus Torvalds#		9.5	Return ans := ans * ans. Exit.			#
68631da177e4SLinus Torvalds#	Notes:	Exp(X) will surely overflow or underflow, depending on	#
68641da177e4SLinus Torvalds#		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
68651da177e4SLinus Torvalds#		extended-precision numbers whose square over/underflow	#
68661da177e4SLinus Torvalds#		with an inexact result. Thus, 9.5 always raises the	#
68671da177e4SLinus Torvalds#		inexact together with either overflow or underflow.	#
68681da177e4SLinus Torvalds#									#
68691da177e4SLinus Torvalds#	setoxm1d							#
68701da177e4SLinus Torvalds#	--------							#
68711da177e4SLinus Torvalds#									#
68721da177e4SLinus Torvalds#	Step 1.	Set ans := 0						#
68731da177e4SLinus Torvalds#									#
68741da177e4SLinus Torvalds#	Step 2.	Return	ans := X + ans. Exit.				#
68751da177e4SLinus Torvalds#	Notes:	This will return X with the appropriate rounding	#
68761da177e4SLinus Torvalds#		 precision prescribed by the user FPCR.			#
68771da177e4SLinus Torvalds#									#
68781da177e4SLinus Torvalds#	setoxm1								#
68791da177e4SLinus Torvalds#	-------								#
68801da177e4SLinus Torvalds#									#
68811da177e4SLinus Torvalds#	Step 1.	Check |X|						#
68821da177e4SLinus Torvalds#		1.1	If |X| >= 1/4, go to Step 1.3.			#
68831da177e4SLinus Torvalds#		1.2	Go to Step 7.					#
68841da177e4SLinus Torvalds#		1.3	If |X| < 70 log(2), go to Step 2.		#
68851da177e4SLinus Torvalds#		1.4	Go to Step 10.					#
68861da177e4SLinus Torvalds#	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
68871da177e4SLinus Torvalds#		However, it is conceivable |X| can be small very often	#
68881da177e4SLinus Torvalds#		because EXPM1 is intended to evaluate exp(X)-1		#
68891da177e4SLinus Torvalds#		accurately when |X| is small. For further details on	#
68901da177e4SLinus Torvalds#		the comparisons, see the notes on Step 1 of setox.	#
68911da177e4SLinus Torvalds#									#
68921da177e4SLinus Torvalds#	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
68931da177e4SLinus Torvalds#		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
68941da177e4SLinus Torvalds#		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
68951da177e4SLinus Torvalds#			or 63.						#
68961da177e4SLinus Torvalds#		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
68971da177e4SLinus Torvalds#		2.4	Calculate the address of the stored value of	#
68981da177e4SLinus Torvalds#			2^(J/64).					#
68991da177e4SLinus Torvalds#		2.5	Create the values Sc = 2^M and			#
69001da177e4SLinus Torvalds#			OnebySc := -2^(-M).				#
69011da177e4SLinus Torvalds#	Notes:	See the notes on Step 2 of setox.			#
69021da177e4SLinus Torvalds#									#
69031da177e4SLinus Torvalds#	Step 3.	Calculate X - N*log2/64.				#
69041da177e4SLinus Torvalds#		3.1	R := X + N*L1,					#
69051da177e4SLinus Torvalds#				where L1 := single-precision(-log2/64).	#
69061da177e4SLinus Torvalds#		3.2	R := R + N*L2,					#
69071da177e4SLinus Torvalds#				L2 := extended-precision(-log2/64 - L1).#
69081da177e4SLinus Torvalds#	Notes:	Applying the analysis of Step 3 of setox in this case	#
69091da177e4SLinus Torvalds#		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
69101da177e4SLinus Torvalds#		this case).						#
69111da177e4SLinus Torvalds#									#
69121da177e4SLinus Torvalds#	Step 4.	Approximate exp(R)-1 by a polynomial			#
69131da177e4SLinus Torvalds#			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
69141da177e4SLinus Torvalds#	Notes:	a) In order to reduce memory access, the coefficients	#
69151da177e4SLinus Torvalds#		are made as "short" as possible: A1 (which is 1/2), A5	#
69161da177e4SLinus Torvalds#		and A6 are single precision; A2, A3 and A4 are double	#
69171da177e4SLinus Torvalds#		precision.						#
69181da177e4SLinus Torvalds#		b) Even with the restriction above,			#
69191da177e4SLinus Torvalds#			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
69201da177e4SLinus Torvalds#		for all |R| <= 0.0055.					#
69211da177e4SLinus Torvalds#		c) To fully utilize the pipeline, p is separated into	#
69221da177e4SLinus Torvalds#		two independent pieces of roughly equal complexity	#
69231da177e4SLinus Torvalds#			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
69241da177e4SLinus Torvalds#				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
69251da177e4SLinus Torvalds#		where S = R*R.						#
69261da177e4SLinus Torvalds#									#
69271da177e4SLinus Torvalds#	Step 5.	Compute 2^(J/64)*p by					#
69281da177e4SLinus Torvalds#				p := T*p				#
69291da177e4SLinus Torvalds#		where T and t are the stored values for 2^(J/64).	#
69301da177e4SLinus Torvalds#	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
69311da177e4SLinus Torvalds#		2^(J/64) to roughly 85 bits; T is in extended precision	#
69321da177e4SLinus Torvalds#		and t is in single precision. Note also that T is	#
69331da177e4SLinus Torvalds#		rounded to 62 bits so that the last two bits of T are	#
69341da177e4SLinus Torvalds#		zero. The reason for such a special form is that T-1,	#
69351da177e4SLinus Torvalds#		T-2, and T-8 will all be exact --- a property that will	#
69361da177e4SLinus Torvalds#		be exploited in Step 6 below. The total relative error	#
69371da177e4SLinus Torvalds#		in p is no bigger than 2^(-67.7) compared to the final	#
69381da177e4SLinus Torvalds#		result.							#
69391da177e4SLinus Torvalds#									#
69401da177e4SLinus Torvalds#	Step 6.	Reconstruction of exp(X)-1				#
69411da177e4SLinus Torvalds#			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
69421da177e4SLinus Torvalds#		6.1	If M <= 63, go to Step 6.3.			#
69431da177e4SLinus Torvalds#		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
69441da177e4SLinus Torvalds#		6.3	If M >= -3, go to 6.5.				#
69451da177e4SLinus Torvalds#		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
69461da177e4SLinus Torvalds#		6.5	ans := (T + OnebySc) + (p + t).			#
69471da177e4SLinus Torvalds#		6.6	Restore user FPCR.				#
69481da177e4SLinus Torvalds#		6.7	Return ans := Sc * ans. Exit.			#
69491da177e4SLinus Torvalds#	Notes:	The various arrangements of the expressions give	#
69501da177e4SLinus Torvalds#		accurate evaluations.					#
69511da177e4SLinus Torvalds#									#
69521da177e4SLinus Torvalds#	Step 7.	exp(X)-1 for |X| < 1/4.					#
69531da177e4SLinus Torvalds#		7.1	If |X| >= 2^(-65), go to Step 9.		#
69541da177e4SLinus Torvalds#		7.2	Go to Step 8.					#
69551da177e4SLinus Torvalds#									#
69561da177e4SLinus Torvalds#	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
69571da177e4SLinus Torvalds#		8.1	If |X| < 2^(-16312), goto 8.3			#
69581da177e4SLinus Torvalds#		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
69591da177e4SLinus Torvalds#			Exit.						#
69601da177e4SLinus Torvalds#		8.3	X := X * 2^(140).				#
69611da177e4SLinus Torvalds#		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
69621da177e4SLinus Torvalds#		 Return ans := ans*2^(140). Exit			#
69631da177e4SLinus Torvalds#	Notes:	The idea is to return "X - tiny" under the user		#
69641da177e4SLinus Torvalds#		precision and rounding modes. To avoid unnecessary	#
69651da177e4SLinus Torvalds#		inefficiency, we stay away from denormalized numbers	#
69661da177e4SLinus Torvalds#		the best we can. For |X| >= 2^(-16312), the		#
69671da177e4SLinus Torvalds#		straightforward 8.2 generates the inexact exception as	#
69681da177e4SLinus Torvalds#		the case warrants.					#
69691da177e4SLinus Torvalds#									#
69701da177e4SLinus Torvalds#	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
69711da177e4SLinus Torvalds#			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
69721da177e4SLinus Torvalds#	Notes:	a) In order to reduce memory access, the coefficients	#
69731da177e4SLinus Torvalds#		are made as "short" as possible: B1 (which is 1/2), B9	#
69741da177e4SLinus Torvalds#		to B12 are single precision; B3 to B8 are double	#
69751da177e4SLinus Torvalds#		precision; and B2 is double extended.			#
69761da177e4SLinus Torvalds#		b) Even with the restriction above,			#
69771da177e4SLinus Torvalds#			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
69781da177e4SLinus Torvalds#		for all |X| <= 0.251.					#
69791da177e4SLinus Torvalds#		Note that 0.251 is slightly bigger than 1/4.		#
69801da177e4SLinus Torvalds#		c) To fully preserve accuracy, the polynomial is	#
69811da177e4SLinus Torvalds#		computed as						#
69821da177e4SLinus Torvalds#			X + ( S*B1 +	Q ) where S = X*X and		#
69831da177e4SLinus Torvalds#			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
69841da177e4SLinus Torvalds#		d) To fully utilize the pipeline, Q is separated into	#
69851da177e4SLinus Torvalds#		two independent pieces of roughly equal complexity	#
69861da177e4SLinus Torvalds#			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
69871da177e4SLinus Torvalds#				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
69881da177e4SLinus Torvalds#									#
69891da177e4SLinus Torvalds#	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
69901da177e4SLinus Torvalds#		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all	#
69911da177e4SLinus Torvalds#		practical purposes. Therefore, go to Step 1 of setox.	#
69921da177e4SLinus Torvalds#		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
69931da177e4SLinus Torvalds#		purposes.						#
69941da177e4SLinus Torvalds#		ans := -1						#
69951da177e4SLinus Torvalds#		Restore user FPCR					#
69961da177e4SLinus Torvalds#		Return ans := ans + 2^(-126). Exit.			#
69971da177e4SLinus Torvalds#	Notes:	10.2 will always create an inexact and return -1 + tiny	#
69981da177e4SLinus Torvalds#		in the user rounding precision and mode.		#
69991da177e4SLinus Torvalds#									#
70001da177e4SLinus Torvalds#########################################################################
70011da177e4SLinus Torvalds
70021da177e4SLinus TorvaldsL2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
70031da177e4SLinus Torvalds
70041da177e4SLinus TorvaldsEEXPA3:	long		0x3FA55555,0x55554CC1
70051da177e4SLinus TorvaldsEEXPA2:	long		0x3FC55555,0x55554A54
70061da177e4SLinus Torvalds
70071da177e4SLinus TorvaldsEM1A4:	long		0x3F811111,0x11174385
70081da177e4SLinus TorvaldsEM1A3:	long		0x3FA55555,0x55554F5A
70091da177e4SLinus Torvalds
70101da177e4SLinus TorvaldsEM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
70111da177e4SLinus Torvalds
70121da177e4SLinus TorvaldsEM1B8:	long		0x3EC71DE3,0xA5774682
70131da177e4SLinus TorvaldsEM1B7:	long		0x3EFA01A0,0x19D7CB68
70141da177e4SLinus Torvalds
70151da177e4SLinus TorvaldsEM1B6:	long		0x3F2A01A0,0x1A019DF3
70161da177e4SLinus TorvaldsEM1B5:	long		0x3F56C16C,0x16C170E2
70171da177e4SLinus Torvalds
70181da177e4SLinus TorvaldsEM1B4:	long		0x3F811111,0x11111111
70191da177e4SLinus TorvaldsEM1B3:	long		0x3FA55555,0x55555555
70201da177e4SLinus Torvalds
70211da177e4SLinus TorvaldsEM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
70221da177e4SLinus Torvalds	long		0x00000000
70231da177e4SLinus Torvalds
70241da177e4SLinus TorvaldsTWO140:	long		0x48B00000,0x00000000
70251da177e4SLinus TorvaldsTWON140:
70261da177e4SLinus Torvalds	long		0x37300000,0x00000000
70271da177e4SLinus Torvalds
70281da177e4SLinus TorvaldsEEXPTBL:
70291da177e4SLinus Torvalds	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
70301da177e4SLinus Torvalds	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
70311da177e4SLinus Torvalds	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
70321da177e4SLinus Torvalds	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
70331da177e4SLinus Torvalds	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
70341da177e4SLinus Torvalds	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
70351da177e4SLinus Torvalds	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
70361da177e4SLinus Torvalds	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
70371da177e4SLinus Torvalds	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
70381da177e4SLinus Torvalds	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
70391da177e4SLinus Torvalds	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
70401da177e4SLinus Torvalds	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
70411da177e4SLinus Torvalds	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
70421da177e4SLinus Torvalds	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
70431da177e4SLinus Torvalds	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
70441da177e4SLinus Torvalds	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
70451da177e4SLinus Torvalds	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
70461da177e4SLinus Torvalds	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
70471da177e4SLinus Torvalds	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
70481da177e4SLinus Torvalds	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
70491da177e4SLinus Torvalds	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
70501da177e4SLinus Torvalds	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
70511da177e4SLinus Torvalds	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
70521da177e4SLinus Torvalds	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
70531da177e4SLinus Torvalds	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
70541da177e4SLinus Torvalds	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
70551da177e4SLinus Torvalds	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
70561da177e4SLinus Torvalds	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
70571da177e4SLinus Torvalds	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
70581da177e4SLinus Torvalds	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
70591da177e4SLinus Torvalds	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
70601da177e4SLinus Torvalds	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
70611da177e4SLinus Torvalds	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
70621da177e4SLinus Torvalds	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
70631da177e4SLinus Torvalds	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
70641da177e4SLinus Torvalds	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
70651da177e4SLinus Torvalds	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
70661da177e4SLinus Torvalds	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
70671da177e4SLinus Torvalds	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
70681da177e4SLinus Torvalds	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
70691da177e4SLinus Torvalds	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
70701da177e4SLinus Torvalds	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
70711da177e4SLinus Torvalds	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
70721da177e4SLinus Torvalds	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
70731da177e4SLinus Torvalds	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
70741da177e4SLinus Torvalds	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
70751da177e4SLinus Torvalds	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
70761da177e4SLinus Torvalds	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
70771da177e4SLinus Torvalds	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
70781da177e4SLinus Torvalds	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
70791da177e4SLinus Torvalds	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
70801da177e4SLinus Torvalds	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
70811da177e4SLinus Torvalds	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
70821da177e4SLinus Torvalds	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
70831da177e4SLinus Torvalds	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
70841da177e4SLinus Torvalds	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
70851da177e4SLinus Torvalds	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
70861da177e4SLinus Torvalds	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
70871da177e4SLinus Torvalds	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
70881da177e4SLinus Torvalds	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
70891da177e4SLinus Torvalds	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
70901da177e4SLinus Torvalds	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
70911da177e4SLinus Torvalds	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
70921da177e4SLinus Torvalds	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
70931da177e4SLinus Torvalds
70941da177e4SLinus Torvalds	set		ADJFLAG,L_SCR2
70951da177e4SLinus Torvalds	set		SCALE,FP_SCR0
70961da177e4SLinus Torvalds	set		ADJSCALE,FP_SCR1
70971da177e4SLinus Torvalds	set		SC,FP_SCR0
70981da177e4SLinus Torvalds	set		ONEBYSC,FP_SCR1
70991da177e4SLinus Torvalds
71001da177e4SLinus Torvalds	global		setox
71011da177e4SLinus Torvaldssetox:
71021da177e4SLinus Torvalds#--entry point for EXP(X), here X is finite, non-zero, and not NaN's
71031da177e4SLinus Torvalds
71041da177e4SLinus Torvalds#--Step 1.
71051da177e4SLinus Torvalds	mov.l		(%a0),%d1		# load part of input X
71061da177e4SLinus Torvalds	and.l		&0x7FFF0000,%d1		# biased expo. of X
71071da177e4SLinus Torvalds	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
71081da177e4SLinus Torvalds	bge.b		EXPC1			# normal case
71091da177e4SLinus Torvalds	bra		EXPSM
71101da177e4SLinus Torvalds
71111da177e4SLinus TorvaldsEXPC1:
71121da177e4SLinus Torvalds#--The case |X| >= 2^(-65)
71131da177e4SLinus Torvalds	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
71141da177e4SLinus Torvalds	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
71151da177e4SLinus Torvalds	blt.b		EXPMAIN			# normal case
71161da177e4SLinus Torvalds	bra		EEXPBIG
71171da177e4SLinus Torvalds
71181da177e4SLinus TorvaldsEXPMAIN:
71191da177e4SLinus Torvalds#--Step 2.
71201da177e4SLinus Torvalds#--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
71211da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# load input from (a0)
71221da177e4SLinus Torvalds
71231da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
71241da177e4SLinus Torvalds	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
71251da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
71261da177e4SLinus Torvalds	mov.l		&0,ADJFLAG(%a6)
71271da177e4SLinus Torvalds	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
71281da177e4SLinus Torvalds	lea		EEXPTBL(%pc),%a1
71291da177e4SLinus Torvalds	fmov.l		%d1,%fp0		# convert to floating-format
71301da177e4SLinus Torvalds
71311da177e4SLinus Torvalds	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
71321da177e4SLinus Torvalds	and.l		&0x3F,%d1		# D0 is J = N mod 64
71331da177e4SLinus Torvalds	lsl.l		&4,%d1
71341da177e4SLinus Torvalds	add.l		%d1,%a1			# address of 2^(J/64)
71351da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d1
71361da177e4SLinus Torvalds	asr.l		&6,%d1			# D0 is M
71371da177e4SLinus Torvalds	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
71381da177e4SLinus Torvalds	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
71391da177e4SLinus Torvalds
71401da177e4SLinus TorvaldsEXPCONT1:
71411da177e4SLinus Torvalds#--Step 3.
71421da177e4SLinus Torvalds#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
71431da177e4SLinus Torvalds#--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
71441da177e4SLinus Torvalds	fmov.x		%fp0,%fp2
71451da177e4SLinus Torvalds	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
71461da177e4SLinus Torvalds	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
71471da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# X + N*L1
71481da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
71491da177e4SLinus Torvalds
71501da177e4SLinus Torvalds#--Step 4.
71511da177e4SLinus Torvalds#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
71521da177e4SLinus Torvalds#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
71531da177e4SLinus Torvalds#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
71541da177e4SLinus Torvalds#--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
71551da177e4SLinus Torvalds
71561da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
71571da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
71581da177e4SLinus Torvalds
71591da177e4SLinus Torvalds	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
71601da177e4SLinus Torvalds
71611da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# fp2 IS S*A5
71621da177e4SLinus Torvalds	fmov.x		%fp1,%fp3
71631da177e4SLinus Torvalds	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
71641da177e4SLinus Torvalds
71651da177e4SLinus Torvalds	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
71661da177e4SLinus Torvalds	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
71671da177e4SLinus Torvalds
71681da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
71691da177e4SLinus Torvalds	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
71701da177e4SLinus Torvalds	mov.l		&0x80000000,SCALE+4(%a6)
71711da177e4SLinus Torvalds	clr.l		SCALE+8(%a6)
71721da177e4SLinus Torvalds
71731da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
71741da177e4SLinus Torvalds
71751da177e4SLinus Torvalds	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
71761da177e4SLinus Torvalds	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
71771da177e4SLinus Torvalds
71781da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
71791da177e4SLinus Torvalds	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
71801da177e4SLinus Torvalds
71811da177e4SLinus Torvalds	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
71821da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
71831da177e4SLinus Torvalds
71841da177e4SLinus Torvalds#--Step 5
71851da177e4SLinus Torvalds#--final reconstruction process
71861da177e4SLinus Torvalds#--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
71871da177e4SLinus Torvalds
71881da177e4SLinus Torvalds	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
71891da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
71901da177e4SLinus Torvalds	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
71911da177e4SLinus Torvalds
71921da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
71931da177e4SLinus Torvalds	mov.l		ADJFLAG(%a6),%d1
71941da177e4SLinus Torvalds
71951da177e4SLinus Torvalds#--Step 6
71961da177e4SLinus Torvalds	tst.l		%d1
71971da177e4SLinus Torvalds	beq.b		NORMAL
71981da177e4SLinus TorvaldsADJUST:
71991da177e4SLinus Torvalds	fmul.x		ADJSCALE(%a6),%fp0
72001da177e4SLinus TorvaldsNORMAL:
72011da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore user FPCR
72021da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
72031da177e4SLinus Torvalds	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
72041da177e4SLinus Torvalds	bra		t_catch
72051da177e4SLinus Torvalds
72061da177e4SLinus TorvaldsEXPSM:
72071da177e4SLinus Torvalds#--Step 7
72081da177e4SLinus Torvalds	fmovm.x		(%a0),&0x80		# load X
72091da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
72101da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
72111da177e4SLinus Torvalds	bra		t_pinx2
72121da177e4SLinus Torvalds
72131da177e4SLinus TorvaldsEEXPBIG:
72141da177e4SLinus Torvalds#--Step 8
72151da177e4SLinus Torvalds	cmp.l		%d1,&0x400CB27C		# 16480 log2
72161da177e4SLinus Torvalds	bgt.b		EXP2BIG
72171da177e4SLinus Torvalds#--Steps 8.2 -- 8.6
72181da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# load input from (a0)
72191da177e4SLinus Torvalds
72201da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
72211da177e4SLinus Torvalds	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
72221da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
72231da177e4SLinus Torvalds	mov.l		&1,ADJFLAG(%a6)
72241da177e4SLinus Torvalds	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
72251da177e4SLinus Torvalds	lea		EEXPTBL(%pc),%a1
72261da177e4SLinus Torvalds	fmov.l		%d1,%fp0		# convert to floating-format
72271da177e4SLinus Torvalds	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
72281da177e4SLinus Torvalds	and.l		&0x3F,%d1		# D0 is J = N mod 64
72291da177e4SLinus Torvalds	lsl.l		&4,%d1
72301da177e4SLinus Torvalds	add.l		%d1,%a1			# address of 2^(J/64)
72311da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d1
72321da177e4SLinus Torvalds	asr.l		&6,%d1			# D0 is K
72331da177e4SLinus Torvalds	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
72341da177e4SLinus Torvalds	asr.l		&1,%d1			# D0 is M1
72351da177e4SLinus Torvalds	sub.l		%d1,L_SCR1(%a6)		# a1 is M
72361da177e4SLinus Torvalds	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
72371da177e4SLinus Torvalds	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
72381da177e4SLinus Torvalds	mov.l		&0x80000000,ADJSCALE+4(%a6)
72391da177e4SLinus Torvalds	clr.l		ADJSCALE+8(%a6)
72401da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d1		# D0 is M
72411da177e4SLinus Torvalds	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
72421da177e4SLinus Torvalds	bra.w		EXPCONT1		# go back to Step 3
72431da177e4SLinus Torvalds
72441da177e4SLinus TorvaldsEXP2BIG:
72451da177e4SLinus Torvalds#--Step 9
72461da177e4SLinus Torvalds	tst.b		(%a0)			# is X positive or negative?
72471da177e4SLinus Torvalds	bmi		t_unfl2
72481da177e4SLinus Torvalds	bra		t_ovfl2
72491da177e4SLinus Torvalds
72501da177e4SLinus Torvalds	global		setoxd
72511da177e4SLinus Torvaldssetoxd:
72521da177e4SLinus Torvalds#--entry point for EXP(X), X is denormalized
72531da177e4SLinus Torvalds	mov.l		(%a0),-(%sp)
72541da177e4SLinus Torvalds	andi.l		&0x80000000,(%sp)
72551da177e4SLinus Torvalds	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
72561da177e4SLinus Torvalds
72571da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp0
72581da177e4SLinus Torvalds
72591da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
72601da177e4SLinus Torvalds	fadd.s		(%sp)+,%fp0
72611da177e4SLinus Torvalds	bra		t_pinx2
72621da177e4SLinus Torvalds
72631da177e4SLinus Torvalds	global		setoxm1
72641da177e4SLinus Torvaldssetoxm1:
72651da177e4SLinus Torvalds#--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
72661da177e4SLinus Torvalds
72671da177e4SLinus Torvalds#--Step 1.
72681da177e4SLinus Torvalds#--Step 1.1
72691da177e4SLinus Torvalds	mov.l		(%a0),%d1		# load part of input X
72701da177e4SLinus Torvalds	and.l		&0x7FFF0000,%d1		# biased expo. of X
72711da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFD0000		# 1/4
72721da177e4SLinus Torvalds	bge.b		EM1CON1			# |X| >= 1/4
72731da177e4SLinus Torvalds	bra		EM1SM
72741da177e4SLinus Torvalds
72751da177e4SLinus TorvaldsEM1CON1:
72761da177e4SLinus Torvalds#--Step 1.3
72771da177e4SLinus Torvalds#--The case |X| >= 1/4
72781da177e4SLinus Torvalds	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
72791da177e4SLinus Torvalds	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
72801da177e4SLinus Torvalds	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
72811da177e4SLinus Torvalds	bra		EM1BIG
72821da177e4SLinus Torvalds
72831da177e4SLinus TorvaldsEM1MAIN:
72841da177e4SLinus Torvalds#--Step 2.
72851da177e4SLinus Torvalds#--This is the case:	1/4 <= |X| <= 70 log2.
72861da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# load input from (a0)
72871da177e4SLinus Torvalds
72881da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
72891da177e4SLinus Torvalds	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
72901da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
72911da177e4SLinus Torvalds	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
72921da177e4SLinus Torvalds	lea		EEXPTBL(%pc),%a1
72931da177e4SLinus Torvalds	fmov.l		%d1,%fp0		# convert to floating-format
72941da177e4SLinus Torvalds
72951da177e4SLinus Torvalds	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
72961da177e4SLinus Torvalds	and.l		&0x3F,%d1		# D0 is J = N mod 64
72971da177e4SLinus Torvalds	lsl.l		&4,%d1
72981da177e4SLinus Torvalds	add.l		%d1,%a1			# address of 2^(J/64)
72991da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d1
73001da177e4SLinus Torvalds	asr.l		&6,%d1			# D0 is M
73011da177e4SLinus Torvalds	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
73021da177e4SLinus Torvalds
73031da177e4SLinus Torvalds#--Step 3.
73041da177e4SLinus Torvalds#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
73051da177e4SLinus Torvalds#--a0 points to 2^(J/64), D0 and a1 both contain M
73061da177e4SLinus Torvalds	fmov.x		%fp0,%fp2
73071da177e4SLinus Torvalds	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
73081da177e4SLinus Torvalds	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
73091da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# X + N*L1
73101da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
73111da177e4SLinus Torvalds	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
73121da177e4SLinus Torvalds
73131da177e4SLinus Torvalds#--Step 4.
73141da177e4SLinus Torvalds#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
73151da177e4SLinus Torvalds#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
73161da177e4SLinus Torvalds#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
73171da177e4SLinus Torvalds#--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
73181da177e4SLinus Torvalds
73191da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
73201da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
73211da177e4SLinus Torvalds
73221da177e4SLinus Torvalds	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
73231da177e4SLinus Torvalds
73241da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# fp2 IS S*A6
73251da177e4SLinus Torvalds	fmov.x		%fp1,%fp3
73261da177e4SLinus Torvalds	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
73271da177e4SLinus Torvalds
73281da177e4SLinus Torvalds	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
73291da177e4SLinus Torvalds	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
73301da177e4SLinus Torvalds	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
73311da177e4SLinus Torvalds	mov.l		&0x80000000,SC+4(%a6)
73321da177e4SLinus Torvalds	clr.l		SC+8(%a6)
73331da177e4SLinus Torvalds
73341da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
73351da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d1		# D0 is	M
73361da177e4SLinus Torvalds	neg.w		%d1			# D0 is -M
73371da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
73381da177e4SLinus Torvalds	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
73391da177e4SLinus Torvalds	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
73401da177e4SLinus Torvalds	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
73411da177e4SLinus Torvalds
73421da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
73431da177e4SLinus Torvalds	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
73441da177e4SLinus Torvalds	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
73451da177e4SLinus Torvalds	mov.l		&0x80000000,ONEBYSC+4(%a6)
73461da177e4SLinus Torvalds	clr.l		ONEBYSC+8(%a6)
73471da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
73481da177e4SLinus Torvalds
73491da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
73501da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
73511da177e4SLinus Torvalds
73521da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
73531da177e4SLinus Torvalds
73541da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
73551da177e4SLinus Torvalds
73561da177e4SLinus Torvalds#--Step 5
73571da177e4SLinus Torvalds#--Compute 2^(J/64)*p
73581da177e4SLinus Torvalds
73591da177e4SLinus Torvalds	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
73601da177e4SLinus Torvalds
73611da177e4SLinus Torvalds#--Step 6
73621da177e4SLinus Torvalds#--Step 6.1
73631da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d1		# retrieve M
73641da177e4SLinus Torvalds	cmp.l		%d1,&63
73651da177e4SLinus Torvalds	ble.b		MLE63
73661da177e4SLinus Torvalds#--Step 6.2	M >= 64
73671da177e4SLinus Torvalds	fmov.s		12(%a1),%fp1		# fp1 is t
73681da177e4SLinus Torvalds	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
73691da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
73701da177e4SLinus Torvalds	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
73711da177e4SLinus Torvalds	bra		EM1SCALE
73721da177e4SLinus TorvaldsMLE63:
73731da177e4SLinus Torvalds#--Step 6.3	M <= 63
73741da177e4SLinus Torvalds	cmp.l		%d1,&-3
73751da177e4SLinus Torvalds	bge.b		MGEN3
73761da177e4SLinus TorvaldsMLTN3:
73771da177e4SLinus Torvalds#--Step 6.4	M <= -4
73781da177e4SLinus Torvalds	fadd.s		12(%a1),%fp0		# p+t
73791da177e4SLinus Torvalds	fadd.x		(%a1),%fp0		# T+(p+t)
73801da177e4SLinus Torvalds	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
73811da177e4SLinus Torvalds	bra		EM1SCALE
73821da177e4SLinus TorvaldsMGEN3:
73831da177e4SLinus Torvalds#--Step 6.5	-3 <= M <= 63
73841da177e4SLinus Torvalds	fmov.x		(%a1)+,%fp1		# fp1 is T
73851da177e4SLinus Torvalds	fadd.s		(%a1),%fp0		# fp0 is p+t
73861da177e4SLinus Torvalds	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
73871da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
73881da177e4SLinus Torvalds
73891da177e4SLinus TorvaldsEM1SCALE:
73901da177e4SLinus Torvalds#--Step 6.6
73911da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
73921da177e4SLinus Torvalds	fmul.x		SC(%a6),%fp0
73931da177e4SLinus Torvalds	bra		t_inx2
73941da177e4SLinus Torvalds
73951da177e4SLinus TorvaldsEM1SM:
73961da177e4SLinus Torvalds#--Step 7	|X| < 1/4.
73971da177e4SLinus Torvalds	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
73981da177e4SLinus Torvalds	bge.b		EM1POLY
73991da177e4SLinus Torvalds
74001da177e4SLinus TorvaldsEM1TINY:
74011da177e4SLinus Torvalds#--Step 8	|X| < 2^(-65)
74021da177e4SLinus Torvalds	cmp.l		%d1,&0x00330000		# 2^(-16312)
74031da177e4SLinus Torvalds	blt.b		EM12TINY
74041da177e4SLinus Torvalds#--Step 8.2
74051da177e4SLinus Torvalds	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
74061da177e4SLinus Torvalds	mov.l		&0x80000000,SC+4(%a6)
74071da177e4SLinus Torvalds	clr.l		SC+8(%a6)
74081da177e4SLinus Torvalds	fmov.x		(%a0),%fp0
74091da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
74101da177e4SLinus Torvalds	mov.b		&FADD_OP,%d1		# last inst is ADD
74111da177e4SLinus Torvalds	fadd.x		SC(%a6),%fp0
74121da177e4SLinus Torvalds	bra		t_catch
74131da177e4SLinus Torvalds
74141da177e4SLinus TorvaldsEM12TINY:
74151da177e4SLinus Torvalds#--Step 8.3
74161da177e4SLinus Torvalds	fmov.x		(%a0),%fp0
74171da177e4SLinus Torvalds	fmul.d		TWO140(%pc),%fp0
74181da177e4SLinus Torvalds	mov.l		&0x80010000,SC(%a6)
74191da177e4SLinus Torvalds	mov.l		&0x80000000,SC+4(%a6)
74201da177e4SLinus Torvalds	clr.l		SC+8(%a6)
74211da177e4SLinus Torvalds	fadd.x		SC(%a6),%fp0
74221da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
74231da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
74241da177e4SLinus Torvalds	fmul.d		TWON140(%pc),%fp0
74251da177e4SLinus Torvalds	bra		t_catch
74261da177e4SLinus Torvalds
74271da177e4SLinus TorvaldsEM1POLY:
74281da177e4SLinus Torvalds#--Step 9	exp(X)-1 by a simple polynomial
74291da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# fp0 is X
74301da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# fp0 is S := X*X
74311da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
74321da177e4SLinus Torvalds	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
74331da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# fp1 is S*B12
74341da177e4SLinus Torvalds	fmov.s		&0x310F8290,%fp2	# fp2 is B11
74351da177e4SLinus Torvalds	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
74361da177e4SLinus Torvalds
74371da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 is S*B11
74381da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
74391da177e4SLinus Torvalds
74401da177e4SLinus Torvalds	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
74411da177e4SLinus Torvalds	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
74421da177e4SLinus Torvalds
74431da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
74441da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
74451da177e4SLinus Torvalds
74461da177e4SLinus Torvalds	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
74471da177e4SLinus Torvalds	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
74481da177e4SLinus Torvalds
74491da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
74501da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
74511da177e4SLinus Torvalds
74521da177e4SLinus Torvalds	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
74531da177e4SLinus Torvalds	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
74541da177e4SLinus Torvalds
74551da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
74561da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
74571da177e4SLinus Torvalds
74581da177e4SLinus Torvalds	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
74591da177e4SLinus Torvalds	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
74601da177e4SLinus Torvalds
74611da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
74621da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
74631da177e4SLinus Torvalds
74641da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
74651da177e4SLinus Torvalds	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
74661da177e4SLinus Torvalds
74671da177e4SLinus Torvalds	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
74681da177e4SLinus Torvalds	fadd.x		%fp2,%fp1		# fp1 is Q
74691da177e4SLinus Torvalds
74701da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
74711da177e4SLinus Torvalds
74721da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
74731da177e4SLinus Torvalds
74741da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
74751da177e4SLinus Torvalds	fadd.x		(%a0),%fp0
74761da177e4SLinus Torvalds	bra		t_inx2
74771da177e4SLinus Torvalds
74781da177e4SLinus TorvaldsEM1BIG:
74791da177e4SLinus Torvalds#--Step 10	|X| > 70 log2
74801da177e4SLinus Torvalds	mov.l		(%a0),%d1
74811da177e4SLinus Torvalds	cmp.l		%d1,&0
74821da177e4SLinus Torvalds	bgt.w		EXPC1
74831da177e4SLinus Torvalds#--Step 10.2
74841da177e4SLinus Torvalds	fmov.s		&0xBF800000,%fp0	# fp0 is -1
74851da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
74861da177e4SLinus Torvalds	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
74871da177e4SLinus Torvalds	bra		t_minx2
74881da177e4SLinus Torvalds
74891da177e4SLinus Torvalds	global		setoxm1d
74901da177e4SLinus Torvaldssetoxm1d:
74911da177e4SLinus Torvalds#--entry point for EXPM1(X), here X is denormalized
74921da177e4SLinus Torvalds#--Step 0.
74931da177e4SLinus Torvalds	bra		t_extdnrm
74941da177e4SLinus Torvalds
74951da177e4SLinus Torvalds#########################################################################
74961da177e4SLinus Torvalds# sgetexp():  returns the exponent portion of the input argument.	#
74971da177e4SLinus Torvalds#	      The exponent bias is removed and the exponent value is	#
74981da177e4SLinus Torvalds#	      returned as an extended precision number in fp0.		#
74991da177e4SLinus Torvalds# sgetexpd(): handles denormalized numbers.				#
75001da177e4SLinus Torvalds#									#
75011da177e4SLinus Torvalds# sgetman():  extracts the mantissa of the input argument. The		#
75021da177e4SLinus Torvalds#	      mantissa is converted to an extended precision number w/	#
75031da177e4SLinus Torvalds#	      an exponent of $3fff and is returned in fp0. The range of #
75041da177e4SLinus Torvalds#	      the result is [1.0 - 2.0).				#
75051da177e4SLinus Torvalds# sgetmand(): handles denormalized numbers.				#
75061da177e4SLinus Torvalds#									#
75071da177e4SLinus Torvalds# INPUT *************************************************************** #
75081da177e4SLinus Torvalds#	a0  = pointer to extended precision input			#
75091da177e4SLinus Torvalds#									#
75101da177e4SLinus Torvalds# OUTPUT ************************************************************** #
75111da177e4SLinus Torvalds#	fp0 = exponent(X) or mantissa(X)				#
75121da177e4SLinus Torvalds#									#
75131da177e4SLinus Torvalds#########################################################################
75141da177e4SLinus Torvalds
75151da177e4SLinus Torvalds	global		sgetexp
75161da177e4SLinus Torvaldssgetexp:
75171da177e4SLinus Torvalds	mov.w		SRC_EX(%a0),%d0		# get the exponent
75181da177e4SLinus Torvalds	bclr		&0xf,%d0		# clear the sign bit
75191da177e4SLinus Torvalds	subi.w		&0x3fff,%d0		# subtract off the bias
75201da177e4SLinus Torvalds	fmov.w		%d0,%fp0		# return exp in fp0
75211da177e4SLinus Torvalds	blt.b		sgetexpn		# it's negative
75221da177e4SLinus Torvalds	rts
75231da177e4SLinus Torvalds
75241da177e4SLinus Torvaldssgetexpn:
75251da177e4SLinus Torvalds	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
75261da177e4SLinus Torvalds	rts
75271da177e4SLinus Torvalds
75281da177e4SLinus Torvalds	global		sgetexpd
75291da177e4SLinus Torvaldssgetexpd:
75301da177e4SLinus Torvalds	bsr.l		norm			# normalize
75311da177e4SLinus Torvalds	neg.w		%d0			# new exp = -(shft amt)
75321da177e4SLinus Torvalds	subi.w		&0x3fff,%d0		# subtract off the bias
75331da177e4SLinus Torvalds	fmov.w		%d0,%fp0		# return exp in fp0
75341da177e4SLinus Torvalds	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
75351da177e4SLinus Torvalds	rts
75361da177e4SLinus Torvalds
75371da177e4SLinus Torvalds	global		sgetman
75381da177e4SLinus Torvaldssgetman:
75391da177e4SLinus Torvalds	mov.w		SRC_EX(%a0),%d0		# get the exp
75401da177e4SLinus Torvalds	ori.w		&0x7fff,%d0		# clear old exp
75411da177e4SLinus Torvalds	bclr		&0xe,%d0		# make it the new exp +-3fff
75421da177e4SLinus Torvalds
75431da177e4SLinus Torvalds# here, we build the result in a tmp location so as not to disturb the input
75441da177e4SLinus Torvalds	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
75451da177e4SLinus Torvalds	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
75461da177e4SLinus Torvalds	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
75471da177e4SLinus Torvalds	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
75481da177e4SLinus Torvalds	bmi.b		sgetmann		# it's negative
75491da177e4SLinus Torvalds	rts
75501da177e4SLinus Torvalds
75511da177e4SLinus Torvaldssgetmann:
75521da177e4SLinus Torvalds	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
75531da177e4SLinus Torvalds	rts
75541da177e4SLinus Torvalds
75551da177e4SLinus Torvalds#
75561da177e4SLinus Torvalds# For denormalized numbers, shift the mantissa until the j-bit = 1,
75571da177e4SLinus Torvalds# then load the exponent with +/1 $3fff.
75581da177e4SLinus Torvalds#
75591da177e4SLinus Torvalds	global		sgetmand
75601da177e4SLinus Torvaldssgetmand:
75611da177e4SLinus Torvalds	bsr.l		norm			# normalize exponent
75621da177e4SLinus Torvalds	bra.b		sgetman
75631da177e4SLinus Torvalds
75641da177e4SLinus Torvalds#########################################################################
75651da177e4SLinus Torvalds# scosh():  computes the hyperbolic cosine of a normalized input	#
75661da177e4SLinus Torvalds# scoshd(): computes the hyperbolic cosine of a denormalized input	#
75671da177e4SLinus Torvalds#									#
75681da177e4SLinus Torvalds# INPUT ***************************************************************	#
75691da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
75701da177e4SLinus Torvalds#	d0 = round precision,mode					#
75711da177e4SLinus Torvalds#									#
75721da177e4SLinus Torvalds# OUTPUT **************************************************************	#
75731da177e4SLinus Torvalds#	fp0 = cosh(X)							#
75741da177e4SLinus Torvalds#									#
75751da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
75761da177e4SLinus Torvalds#	The returned result is within 3 ulps in 64 significant bit,	#
75771da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
75781da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
75791da177e4SLinus Torvalds#	in double precision.						#
75801da177e4SLinus Torvalds#									#
75811da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
75821da177e4SLinus Torvalds#									#
75831da177e4SLinus Torvalds#	COSH								#
75841da177e4SLinus Torvalds#	1. If |X| > 16380 log2, go to 3.				#
75851da177e4SLinus Torvalds#									#
75861da177e4SLinus Torvalds#	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
75871da177e4SLinus Torvalds#		y = |X|, z = exp(Y), and				#
75881da177e4SLinus Torvalds#		cosh(X) = (1/2)*( z + 1/z ).				#
75891da177e4SLinus Torvalds#		Exit.							#
75901da177e4SLinus Torvalds#									#
75911da177e4SLinus Torvalds#	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
75921da177e4SLinus Torvalds#									#
75931da177e4SLinus Torvalds#	4. (16380 log2 < |X| <= 16480 log2)				#
75941da177e4SLinus Torvalds#		cosh(X) = sign(X) * exp(|X|)/2.				#
75951da177e4SLinus Torvalds#		However, invoking exp(|X|) may cause premature		#
75961da177e4SLinus Torvalds#		overflow. Thus, we calculate sinh(X) as follows:	#
75971da177e4SLinus Torvalds#		Y	:= |X|						#
75981da177e4SLinus Torvalds#		Fact	:=	2**(16380)				#
75991da177e4SLinus Torvalds#		Y'	:= Y - 16381 log2				#
76001da177e4SLinus Torvalds#		cosh(X) := Fact * exp(Y').				#
76011da177e4SLinus Torvalds#		Exit.							#
76021da177e4SLinus Torvalds#									#
76031da177e4SLinus Torvalds#	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
76041da177e4SLinus Torvalds#		Huge*Huge to generate overflow and an infinity with	#
76051da177e4SLinus Torvalds#		the appropriate sign. Huge is the largest finite number	#
76061da177e4SLinus Torvalds#		in extended format. Exit.				#
76071da177e4SLinus Torvalds#									#
76081da177e4SLinus Torvalds#########################################################################
76091da177e4SLinus Torvalds
76101da177e4SLinus TorvaldsTWO16380:
76111da177e4SLinus Torvalds	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
76121da177e4SLinus Torvalds
76131da177e4SLinus Torvalds	global		scosh
76141da177e4SLinus Torvaldsscosh:
76151da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
76161da177e4SLinus Torvalds
76171da177e4SLinus Torvalds	mov.l		(%a0),%d1
76181da177e4SLinus Torvalds	mov.w		4(%a0),%d1
76191da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
76201da177e4SLinus Torvalds	cmp.l		%d1,&0x400CB167
76211da177e4SLinus Torvalds	bgt.b		COSHBIG
76221da177e4SLinus Torvalds
76231da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 16380 LOG2
76241da177e4SLinus Torvalds#--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
76251da177e4SLinus Torvalds
76261da177e4SLinus Torvalds	fabs.x		%fp0			# |X|
76271da177e4SLinus Torvalds
76281da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
76291da177e4SLinus Torvalds	clr.l		%d0
76301da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save |X| to stack
76311da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to |X|
76321da177e4SLinus Torvalds	bsr		setox			# FP0 IS EXP(|X|)
76331da177e4SLinus Torvalds	add.l		&0xc,%sp		# erase |X| from stack
76341da177e4SLinus Torvalds	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
76351da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
76361da177e4SLinus Torvalds
76371da177e4SLinus Torvalds	fmov.s		&0x3E800000,%fp1	# (1/4)
76381da177e4SLinus Torvalds	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
76391da177e4SLinus Torvalds
76401da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
76411da177e4SLinus Torvalds	mov.b		&FADD_OP,%d1		# last inst is ADD
76421da177e4SLinus Torvalds	fadd.x		%fp1,%fp0
76431da177e4SLinus Torvalds	bra		t_catch
76441da177e4SLinus Torvalds
76451da177e4SLinus TorvaldsCOSHBIG:
76461da177e4SLinus Torvalds	cmp.l		%d1,&0x400CB2B3
76471da177e4SLinus Torvalds	bgt.b		COSHHUGE
76481da177e4SLinus Torvalds
76491da177e4SLinus Torvalds	fabs.x		%fp0
76501da177e4SLinus Torvalds	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
76511da177e4SLinus Torvalds	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
76521da177e4SLinus Torvalds
76531da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
76541da177e4SLinus Torvalds	clr.l		%d0
76551da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
76561da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to fp0
76571da177e4SLinus Torvalds	bsr		setox
76581da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear fp0 from stack
76591da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
76601da177e4SLinus Torvalds
76611da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
76621da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
76631da177e4SLinus Torvalds	fmul.x		TWO16380(%pc),%fp0
76641da177e4SLinus Torvalds	bra		t_catch
76651da177e4SLinus Torvalds
76661da177e4SLinus TorvaldsCOSHHUGE:
76671da177e4SLinus Torvalds	bra		t_ovfl2
76681da177e4SLinus Torvalds
76691da177e4SLinus Torvalds	global		scoshd
76701da177e4SLinus Torvalds#--COSH(X) = 1 FOR DENORMALIZED X
76711da177e4SLinus Torvaldsscoshd:
76721da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp0
76731da177e4SLinus Torvalds
76741da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
76751da177e4SLinus Torvalds	fadd.s		&0x00800000,%fp0
76761da177e4SLinus Torvalds	bra		t_pinx2
76771da177e4SLinus Torvalds
76781da177e4SLinus Torvalds#########################################################################
76791da177e4SLinus Torvalds# ssinh():  computes the hyperbolic sine of a normalized input		#
76801da177e4SLinus Torvalds# ssinhd(): computes the hyperbolic sine of a denormalized input	#
76811da177e4SLinus Torvalds#									#
76821da177e4SLinus Torvalds# INPUT *************************************************************** #
76831da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
76841da177e4SLinus Torvalds#	d0 = round precision,mode					#
76851da177e4SLinus Torvalds#									#
76861da177e4SLinus Torvalds# OUTPUT ************************************************************** #
76871da177e4SLinus Torvalds#	fp0 = sinh(X)							#
76881da177e4SLinus Torvalds#									#
76891da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
76901da177e4SLinus Torvalds#	The returned result is within 3 ulps in 64 significant bit,	#
76911da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
76921da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
76931da177e4SLinus Torvalds#	in double precision.						#
76941da177e4SLinus Torvalds#									#
76951da177e4SLinus Torvalds# ALGORITHM *********************************************************** #
76961da177e4SLinus Torvalds#									#
76971da177e4SLinus Torvalds#       SINH								#
76981da177e4SLinus Torvalds#       1. If |X| > 16380 log2, go to 3.				#
76991da177e4SLinus Torvalds#									#
77001da177e4SLinus Torvalds#       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
77011da177e4SLinus Torvalds#               y = |X|, sgn = sign(X), and z = expm1(Y),		#
77021da177e4SLinus Torvalds#               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
77031da177e4SLinus Torvalds#          Exit.							#
77041da177e4SLinus Torvalds#									#
77051da177e4SLinus Torvalds#       3. If |X| > 16480 log2, go to 5.				#
77061da177e4SLinus Torvalds#									#
77071da177e4SLinus Torvalds#       4. (16380 log2 < |X| <= 16480 log2)				#
77081da177e4SLinus Torvalds#               sinh(X) = sign(X) * exp(|X|)/2.				#
77091da177e4SLinus Torvalds#          However, invoking exp(|X|) may cause premature overflow.	#
77101da177e4SLinus Torvalds#          Thus, we calculate sinh(X) as follows:			#
77111da177e4SLinus Torvalds#             Y       := |X|						#
77121da177e4SLinus Torvalds#             sgn     := sign(X)					#
77131da177e4SLinus Torvalds#             sgnFact := sgn * 2**(16380)				#
77141da177e4SLinus Torvalds#             Y'      := Y - 16381 log2					#
77151da177e4SLinus Torvalds#             sinh(X) := sgnFact * exp(Y').				#
77161da177e4SLinus Torvalds#          Exit.							#
77171da177e4SLinus Torvalds#									#
77181da177e4SLinus Torvalds#       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
77191da177e4SLinus Torvalds#          sign(X)*Huge*Huge to generate overflow and an infinity with	#
77201da177e4SLinus Torvalds#          the appropriate sign. Huge is the largest finite number in	#
77211da177e4SLinus Torvalds#          extended format. Exit.					#
77221da177e4SLinus Torvalds#									#
77231da177e4SLinus Torvalds#########################################################################
77241da177e4SLinus Torvalds
77251da177e4SLinus Torvalds	global		ssinh
77261da177e4SLinus Torvaldsssinh:
77271da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
77281da177e4SLinus Torvalds
77291da177e4SLinus Torvalds	mov.l		(%a0),%d1
77301da177e4SLinus Torvalds	mov.w		4(%a0),%d1
77311da177e4SLinus Torvalds	mov.l		%d1,%a1			# save (compacted) operand
77321da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
77331da177e4SLinus Torvalds	cmp.l		%d1,&0x400CB167
77341da177e4SLinus Torvalds	bgt.b		SINHBIG
77351da177e4SLinus Torvalds
77361da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 16380 LOG2
77371da177e4SLinus Torvalds#--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
77381da177e4SLinus Torvalds
77391da177e4SLinus Torvalds	fabs.x		%fp0			# Y = |X|
77401da177e4SLinus Torvalds
77411da177e4SLinus Torvalds	movm.l		&0x8040,-(%sp)		# {a1/d0}
77421da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save Y on stack
77431da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to Y
77441da177e4SLinus Torvalds	clr.l		%d0
77451da177e4SLinus Torvalds	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
77461da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear Y from stack
77471da177e4SLinus Torvalds	fmov.l		&0,%fpcr
77481da177e4SLinus Torvalds	movm.l		(%sp)+,&0x0201		# {a1/d0}
77491da177e4SLinus Torvalds
77501da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
77511da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp1	# 1+Z
77521da177e4SLinus Torvalds	fmov.x		%fp0,-(%sp)
77531da177e4SLinus Torvalds	fdiv.x		%fp1,%fp0		# Z/(1+Z)
77541da177e4SLinus Torvalds	mov.l		%a1,%d1
77551da177e4SLinus Torvalds	and.l		&0x80000000,%d1
77561da177e4SLinus Torvalds	or.l		&0x3F000000,%d1
77571da177e4SLinus Torvalds	fadd.x		(%sp)+,%fp0
77581da177e4SLinus Torvalds	mov.l		%d1,-(%sp)
77591da177e4SLinus Torvalds
77601da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
77611da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
77621da177e4SLinus Torvalds	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
77631da177e4SLinus Torvalds	bra		t_catch
77641da177e4SLinus Torvalds
77651da177e4SLinus TorvaldsSINHBIG:
77661da177e4SLinus Torvalds	cmp.l		%d1,&0x400CB2B3
77671da177e4SLinus Torvalds	bgt		t_ovfl
77681da177e4SLinus Torvalds	fabs.x		%fp0
77691da177e4SLinus Torvalds	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
77701da177e4SLinus Torvalds	mov.l		&0,-(%sp)
77711da177e4SLinus Torvalds	mov.l		&0x80000000,-(%sp)
77721da177e4SLinus Torvalds	mov.l		%a1,%d1
77731da177e4SLinus Torvalds	and.l		&0x80000000,%d1
77741da177e4SLinus Torvalds	or.l		&0x7FFB0000,%d1
77751da177e4SLinus Torvalds	mov.l		%d1,-(%sp)		# EXTENDED FMT
77761da177e4SLinus Torvalds	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
77771da177e4SLinus Torvalds
77781da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
77791da177e4SLinus Torvalds	clr.l		%d0
77801da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
77811da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to fp0
77821da177e4SLinus Torvalds	bsr		setox
77831da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear fp0 from stack
77841da177e4SLinus Torvalds
77851da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
77861da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
77871da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
77881da177e4SLinus Torvalds	fmul.x		(%sp)+,%fp0		# possible exception
77891da177e4SLinus Torvalds	bra		t_catch
77901da177e4SLinus Torvalds
77911da177e4SLinus Torvalds	global		ssinhd
77921da177e4SLinus Torvalds#--SINH(X) = X FOR DENORMALIZED X
77931da177e4SLinus Torvaldsssinhd:
77941da177e4SLinus Torvalds	bra		t_extdnrm
77951da177e4SLinus Torvalds
77961da177e4SLinus Torvalds#########################################################################
77971da177e4SLinus Torvalds# stanh():  computes the hyperbolic tangent of a normalized input	#
77981da177e4SLinus Torvalds# stanhd(): computes the hyperbolic tangent of a denormalized input	#
77991da177e4SLinus Torvalds#									#
78001da177e4SLinus Torvalds# INPUT ***************************************************************	#
78011da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
78021da177e4SLinus Torvalds#	d0 = round precision,mode					#
78031da177e4SLinus Torvalds#									#
78041da177e4SLinus Torvalds# OUTPUT **************************************************************	#
78051da177e4SLinus Torvalds#	fp0 = tanh(X)							#
78061da177e4SLinus Torvalds#									#
78071da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
78081da177e4SLinus Torvalds#	The returned result is within 3 ulps in 64 significant bit,	#
78091da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
78101da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
78111da177e4SLinus Torvalds#	in double precision.						#
78121da177e4SLinus Torvalds#									#
78131da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
78141da177e4SLinus Torvalds#									#
78151da177e4SLinus Torvalds#	TANH								#
78161da177e4SLinus Torvalds#	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
78171da177e4SLinus Torvalds#									#
78181da177e4SLinus Torvalds#	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
78191da177e4SLinus Torvalds#		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
78201da177e4SLinus Torvalds#		tanh(X) = sgn*( z/(2+z) ).				#
78211da177e4SLinus Torvalds#		Exit.							#
78221da177e4SLinus Torvalds#									#
78231da177e4SLinus Torvalds#	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
78241da177e4SLinus Torvalds#		go to 7.						#
78251da177e4SLinus Torvalds#									#
78261da177e4SLinus Torvalds#	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
78271da177e4SLinus Torvalds#									#
78281da177e4SLinus Torvalds#	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
78291da177e4SLinus Torvalds#		sgn := sign(X), y := 2|X|, z := exp(Y),			#
78301da177e4SLinus Torvalds#		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
78311da177e4SLinus Torvalds#		Exit.							#
78321da177e4SLinus Torvalds#									#
78331da177e4SLinus Torvalds#	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
78341da177e4SLinus Torvalds#		calculate Tanh(X) by					#
78351da177e4SLinus Torvalds#		sgn := sign(X), Tiny := 2**(-126),			#
78361da177e4SLinus Torvalds#		tanh(X) := sgn - sgn*Tiny.				#
78371da177e4SLinus Torvalds#		Exit.							#
78381da177e4SLinus Torvalds#									#
78391da177e4SLinus Torvalds#	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
78401da177e4SLinus Torvalds#									#
78411da177e4SLinus Torvalds#########################################################################
78421da177e4SLinus Torvalds
78431da177e4SLinus Torvalds	set		X,FP_SCR0
78441da177e4SLinus Torvalds	set		XFRAC,X+4
78451da177e4SLinus Torvalds
78461da177e4SLinus Torvalds	set		SGN,L_SCR3
78471da177e4SLinus Torvalds
78481da177e4SLinus Torvalds	set		V,FP_SCR0
78491da177e4SLinus Torvalds
78501da177e4SLinus Torvalds	global		stanh
78511da177e4SLinus Torvaldsstanh:
78521da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
78531da177e4SLinus Torvalds
78541da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)
78551da177e4SLinus Torvalds	mov.l		(%a0),%d1
78561da177e4SLinus Torvalds	mov.w		4(%a0),%d1
78571da177e4SLinus Torvalds	mov.l		%d1,X(%a6)
78581da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
78591da177e4SLinus Torvalds	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
78601da177e4SLinus Torvalds	blt.w		TANHBORS		# yes
78611da177e4SLinus Torvalds	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
78621da177e4SLinus Torvalds	bgt.w		TANHBORS		# yes
78631da177e4SLinus Torvalds
78641da177e4SLinus Torvalds#--THIS IS THE USUAL CASE
78651da177e4SLinus Torvalds#--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
78661da177e4SLinus Torvalds
78671da177e4SLinus Torvalds	mov.l		X(%a6),%d1
78681da177e4SLinus Torvalds	mov.l		%d1,SGN(%a6)
78691da177e4SLinus Torvalds	and.l		&0x7FFF0000,%d1
78701da177e4SLinus Torvalds	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
78711da177e4SLinus Torvalds	mov.l		%d1,X(%a6)
78721da177e4SLinus Torvalds	and.l		&0x80000000,SGN(%a6)
78731da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
78741da177e4SLinus Torvalds
78751da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
78761da177e4SLinus Torvalds	clr.l		%d0
78771da177e4SLinus Torvalds	fmovm.x		&0x1,-(%sp)		# save Y on stack
78781da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to Y
78791da177e4SLinus Torvalds	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
78801da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear Y from stack
78811da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
78821da177e4SLinus Torvalds
78831da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
78841da177e4SLinus Torvalds	fadd.s		&0x40000000,%fp1	# Z+2
78851da177e4SLinus Torvalds	mov.l		SGN(%a6),%d1
78861da177e4SLinus Torvalds	fmov.x		%fp1,V(%a6)
78871da177e4SLinus Torvalds	eor.l		%d1,V(%a6)
78881da177e4SLinus Torvalds
78891da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round prec,mode
78901da177e4SLinus Torvalds	fdiv.x		V(%a6),%fp0
78911da177e4SLinus Torvalds	bra		t_inx2
78921da177e4SLinus Torvalds
78931da177e4SLinus TorvaldsTANHBORS:
78941da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
78951da177e4SLinus Torvalds	blt.w		TANHSM
78961da177e4SLinus Torvalds
78971da177e4SLinus Torvalds	cmp.l		%d1,&0x40048AA1
78981da177e4SLinus Torvalds	bgt.w		TANHHUGE
78991da177e4SLinus Torvalds
79001da177e4SLinus Torvalds#-- (5/2) LOG2 < |X| < 50 LOG2,
79011da177e4SLinus Torvalds#--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
79021da177e4SLinus Torvalds#--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
79031da177e4SLinus Torvalds
79041da177e4SLinus Torvalds	mov.l		X(%a6),%d1
79051da177e4SLinus Torvalds	mov.l		%d1,SGN(%a6)
79061da177e4SLinus Torvalds	and.l		&0x7FFF0000,%d1
79071da177e4SLinus Torvalds	add.l		&0x00010000,%d1		# EXPO OF 2|X|
79081da177e4SLinus Torvalds	mov.l		%d1,X(%a6)		# Y = 2|X|
79091da177e4SLinus Torvalds	and.l		&0x80000000,SGN(%a6)
79101da177e4SLinus Torvalds	mov.l		SGN(%a6),%d1
79111da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0		# Y = 2|X|
79121da177e4SLinus Torvalds
79131da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
79141da177e4SLinus Torvalds	clr.l		%d0
79151da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save Y on stack
79161da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to Y
79171da177e4SLinus Torvalds	bsr		setox			# FP0 IS EXP(Y)
79181da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear Y from stack
79191da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
79201da177e4SLinus Torvalds	mov.l		SGN(%a6),%d1
79211da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
79221da177e4SLinus Torvalds
79231da177e4SLinus Torvalds	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
79241da177e4SLinus Torvalds	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
79251da177e4SLinus Torvalds	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
79261da177e4SLinus Torvalds
79271da177e4SLinus Torvalds	mov.l		SGN(%a6),%d1
79281da177e4SLinus Torvalds	or.l		&0x3F800000,%d1		# SGN
79291da177e4SLinus Torvalds	fmov.s		%d1,%fp0		# SGN IN SGL FMT
79301da177e4SLinus Torvalds
79311da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round prec,mode
79321da177e4SLinus Torvalds	mov.b		&FADD_OP,%d1		# last inst is ADD
79331da177e4SLinus Torvalds	fadd.x		%fp1,%fp0
79341da177e4SLinus Torvalds	bra		t_inx2
79351da177e4SLinus Torvalds
79361da177e4SLinus TorvaldsTANHSM:
79371da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round prec,mode
79381da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
79391da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0		# last inst - possible exception set
79401da177e4SLinus Torvalds	bra		t_catch
79411da177e4SLinus Torvalds
79421da177e4SLinus Torvalds#---RETURN SGN(X) - SGN(X)EPS
79431da177e4SLinus TorvaldsTANHHUGE:
79441da177e4SLinus Torvalds	mov.l		X(%a6),%d1
79451da177e4SLinus Torvalds	and.l		&0x80000000,%d1
79461da177e4SLinus Torvalds	or.l		&0x3F800000,%d1
79471da177e4SLinus Torvalds	fmov.s		%d1,%fp0
79481da177e4SLinus Torvalds	and.l		&0x80000000,%d1
79491da177e4SLinus Torvalds	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
79501da177e4SLinus Torvalds
79511da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round prec,mode
79521da177e4SLinus Torvalds	fadd.s		%d1,%fp0
79531da177e4SLinus Torvalds	bra		t_inx2
79541da177e4SLinus Torvalds
79551da177e4SLinus Torvalds	global		stanhd
79561da177e4SLinus Torvalds#--TANH(X) = X FOR DENORMALIZED X
79571da177e4SLinus Torvaldsstanhd:
79581da177e4SLinus Torvalds	bra		t_extdnrm
79591da177e4SLinus Torvalds
79601da177e4SLinus Torvalds#########################################################################
79611da177e4SLinus Torvalds# slogn():    computes the natural logarithm of a normalized input	#
79621da177e4SLinus Torvalds# slognd():   computes the natural logarithm of a denormalized input	#
79631da177e4SLinus Torvalds# slognp1():  computes the log(1+X) of a normalized input		#
79641da177e4SLinus Torvalds# slognp1d(): computes the log(1+X) of a denormalized input		#
79651da177e4SLinus Torvalds#									#
79661da177e4SLinus Torvalds# INPUT ***************************************************************	#
79671da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
79681da177e4SLinus Torvalds#	d0 = round precision,mode					#
79691da177e4SLinus Torvalds#									#
79701da177e4SLinus Torvalds# OUTPUT **************************************************************	#
79711da177e4SLinus Torvalds#	fp0 = log(X) or log(1+X)					#
79721da177e4SLinus Torvalds#									#
79731da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
79741da177e4SLinus Torvalds#	The returned result is within 2 ulps in 64 significant bit,	#
79751da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
79761da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
79771da177e4SLinus Torvalds#	in double precision.						#
79781da177e4SLinus Torvalds#									#
79791da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
79801da177e4SLinus Torvalds#	LOGN:								#
79811da177e4SLinus Torvalds#	Step 1. If |X-1| < 1/16, approximate log(X) by an odd		#
79821da177e4SLinus Torvalds#		polynomial in u, where u = 2(X-1)/(X+1). Otherwise,	#
79831da177e4SLinus Torvalds#		move on to Step 2.					#
79841da177e4SLinus Torvalds#									#
79851da177e4SLinus Torvalds#	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
79861da177e4SLinus Torvalds#		seven significant bits of Y plus 2**(-7), i.e.		#
79871da177e4SLinus Torvalds#		F = 1.xxxxxx1 in base 2 where the six "x" match those	#
79881da177e4SLinus Torvalds#		of Y. Note that |Y-F| <= 2**(-7).			#
79891da177e4SLinus Torvalds#									#
79901da177e4SLinus Torvalds#	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a		#
79911da177e4SLinus Torvalds#		polynomial in u, log(1+u) = poly.			#
79921da177e4SLinus Torvalds#									#
79931da177e4SLinus Torvalds#	Step 4. Reconstruct						#
79941da177e4SLinus Torvalds#		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
79951da177e4SLinus Torvalds#		by k*log(2) + (log(F) + poly). The values of log(F) are	#
79961da177e4SLinus Torvalds#		calculated beforehand and stored in the program.	#
79971da177e4SLinus Torvalds#									#
79981da177e4SLinus Torvalds#	lognp1:								#
79991da177e4SLinus Torvalds#	Step 1: If |X| < 1/16, approximate log(1+X) by an odd		#
80001da177e4SLinus Torvalds#		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
80011da177e4SLinus Torvalds#		to Step 2.						#
80021da177e4SLinus Torvalds#									#
80031da177e4SLinus Torvalds#	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
80041da177e4SLinus Torvalds#		in Step 2 of the algorithm for LOGN and compute		#
80051da177e4SLinus Torvalds#		log(1+X) as k*log(2) + log(F) + poly where poly		#
80061da177e4SLinus Torvalds#		approximates log(1+u), u = (Y-F)/F.			#
80071da177e4SLinus Torvalds#									#
80081da177e4SLinus Torvalds#	Implementation Notes:						#
80091da177e4SLinus Torvalds#	Note 1. There are 64 different possible values for F, thus 64	#
80101da177e4SLinus Torvalds#		log(F)'s need to be tabulated. Moreover, the values of	#
80111da177e4SLinus Torvalds#		1/F are also tabulated so that the division in (Y-F)/F	#
80121da177e4SLinus Torvalds#		can be performed by a multiplication.			#
80131da177e4SLinus Torvalds#									#
80141da177e4SLinus Torvalds#	Note 2. In Step 2 of lognp1, in order to preserved accuracy,	#
80151da177e4SLinus Torvalds#		the value Y-F has to be calculated carefully when	#
80161da177e4SLinus Torvalds#		1/2 <= X < 3/2.						#
80171da177e4SLinus Torvalds#									#
80181da177e4SLinus Torvalds#	Note 3. To fully exploit the pipeline, polynomials are usually	#
80191da177e4SLinus Torvalds#		separated into two parts evaluated independently before	#
80201da177e4SLinus Torvalds#		being added up.						#
80211da177e4SLinus Torvalds#									#
80221da177e4SLinus Torvalds#########################################################################
80231da177e4SLinus TorvaldsLOGOF2:
80241da177e4SLinus Torvalds	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
80251da177e4SLinus Torvalds
80261da177e4SLinus Torvaldsone:
80271da177e4SLinus Torvalds	long		0x3F800000
80281da177e4SLinus Torvaldszero:
80291da177e4SLinus Torvalds	long		0x00000000
80301da177e4SLinus Torvaldsinfty:
80311da177e4SLinus Torvalds	long		0x7F800000
80321da177e4SLinus Torvaldsnegone:
80331da177e4SLinus Torvalds	long		0xBF800000
80341da177e4SLinus Torvalds
80351da177e4SLinus TorvaldsLOGA6:
80361da177e4SLinus Torvalds	long		0x3FC2499A,0xB5E4040B
80371da177e4SLinus TorvaldsLOGA5:
80381da177e4SLinus Torvalds	long		0xBFC555B5,0x848CB7DB
80391da177e4SLinus Torvalds
80401da177e4SLinus TorvaldsLOGA4:
80411da177e4SLinus Torvalds	long		0x3FC99999,0x987D8730
80421da177e4SLinus TorvaldsLOGA3:
80431da177e4SLinus Torvalds	long		0xBFCFFFFF,0xFF6F7E97
80441da177e4SLinus Torvalds
80451da177e4SLinus TorvaldsLOGA2:
80461da177e4SLinus Torvalds	long		0x3FD55555,0x555555A4
80471da177e4SLinus TorvaldsLOGA1:
80481da177e4SLinus Torvalds	long		0xBFE00000,0x00000008
80491da177e4SLinus Torvalds
80501da177e4SLinus TorvaldsLOGB5:
80511da177e4SLinus Torvalds	long		0x3F175496,0xADD7DAD6
80521da177e4SLinus TorvaldsLOGB4:
80531da177e4SLinus Torvalds	long		0x3F3C71C2,0xFE80C7E0
80541da177e4SLinus Torvalds
80551da177e4SLinus TorvaldsLOGB3:
80561da177e4SLinus Torvalds	long		0x3F624924,0x928BCCFF
80571da177e4SLinus TorvaldsLOGB2:
80581da177e4SLinus Torvalds	long		0x3F899999,0x999995EC
80591da177e4SLinus Torvalds
80601da177e4SLinus TorvaldsLOGB1:
80611da177e4SLinus Torvalds	long		0x3FB55555,0x55555555
80621da177e4SLinus TorvaldsTWO:
80631da177e4SLinus Torvalds	long		0x40000000,0x00000000
80641da177e4SLinus Torvalds
80651da177e4SLinus TorvaldsLTHOLD:
80661da177e4SLinus Torvalds	long		0x3f990000,0x80000000,0x00000000,0x00000000
80671da177e4SLinus Torvalds
80681da177e4SLinus TorvaldsLOGTBL:
80691da177e4SLinus Torvalds	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
80701da177e4SLinus Torvalds	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
80711da177e4SLinus Torvalds	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
80721da177e4SLinus Torvalds	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
80731da177e4SLinus Torvalds	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
80741da177e4SLinus Torvalds	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
80751da177e4SLinus Torvalds	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
80761da177e4SLinus Torvalds	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
80771da177e4SLinus Torvalds	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
80781da177e4SLinus Torvalds	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
80791da177e4SLinus Torvalds	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
80801da177e4SLinus Torvalds	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
80811da177e4SLinus Torvalds	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
80821da177e4SLinus Torvalds	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
80831da177e4SLinus Torvalds	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
80841da177e4SLinus Torvalds	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
80851da177e4SLinus Torvalds	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
80861da177e4SLinus Torvalds	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
80871da177e4SLinus Torvalds	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
80881da177e4SLinus Torvalds	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
80891da177e4SLinus Torvalds	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
80901da177e4SLinus Torvalds	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
80911da177e4SLinus Torvalds	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
80921da177e4SLinus Torvalds	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
80931da177e4SLinus Torvalds	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
80941da177e4SLinus Torvalds	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
80951da177e4SLinus Torvalds	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
80961da177e4SLinus Torvalds	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
80971da177e4SLinus Torvalds	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
80981da177e4SLinus Torvalds	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
80991da177e4SLinus Torvalds	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
81001da177e4SLinus Torvalds	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
81011da177e4SLinus Torvalds	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
81021da177e4SLinus Torvalds	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
81031da177e4SLinus Torvalds	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
81041da177e4SLinus Torvalds	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
81051da177e4SLinus Torvalds	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
81061da177e4SLinus Torvalds	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
81071da177e4SLinus Torvalds	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
81081da177e4SLinus Torvalds	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
81091da177e4SLinus Torvalds	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
81101da177e4SLinus Torvalds	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
81111da177e4SLinus Torvalds	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
81121da177e4SLinus Torvalds	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
81131da177e4SLinus Torvalds	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
81141da177e4SLinus Torvalds	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
81151da177e4SLinus Torvalds	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
81161da177e4SLinus Torvalds	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
81171da177e4SLinus Torvalds	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
81181da177e4SLinus Torvalds	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
81191da177e4SLinus Torvalds	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
81201da177e4SLinus Torvalds	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
81211da177e4SLinus Torvalds	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
81221da177e4SLinus Torvalds	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
81231da177e4SLinus Torvalds	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
81241da177e4SLinus Torvalds	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
81251da177e4SLinus Torvalds	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
81261da177e4SLinus Torvalds	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
81271da177e4SLinus Torvalds	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
81281da177e4SLinus Torvalds	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
81291da177e4SLinus Torvalds	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
81301da177e4SLinus Torvalds	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
81311da177e4SLinus Torvalds	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
81321da177e4SLinus Torvalds	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
81331da177e4SLinus Torvalds	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
81341da177e4SLinus Torvalds	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
81351da177e4SLinus Torvalds	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
81361da177e4SLinus Torvalds	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
81371da177e4SLinus Torvalds	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
81381da177e4SLinus Torvalds	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
81391da177e4SLinus Torvalds	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
81401da177e4SLinus Torvalds	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
81411da177e4SLinus Torvalds	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
81421da177e4SLinus Torvalds	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
81431da177e4SLinus Torvalds	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
81441da177e4SLinus Torvalds	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
81451da177e4SLinus Torvalds	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
81461da177e4SLinus Torvalds	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
81471da177e4SLinus Torvalds	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
81481da177e4SLinus Torvalds	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
81491da177e4SLinus Torvalds	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
81501da177e4SLinus Torvalds	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
81511da177e4SLinus Torvalds	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
81521da177e4SLinus Torvalds	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
81531da177e4SLinus Torvalds	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
81541da177e4SLinus Torvalds	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
81551da177e4SLinus Torvalds	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
81561da177e4SLinus Torvalds	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
81571da177e4SLinus Torvalds	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
81581da177e4SLinus Torvalds	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
81591da177e4SLinus Torvalds	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
81601da177e4SLinus Torvalds	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
81611da177e4SLinus Torvalds	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
81621da177e4SLinus Torvalds	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
81631da177e4SLinus Torvalds	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
81641da177e4SLinus Torvalds	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
81651da177e4SLinus Torvalds	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
81661da177e4SLinus Torvalds	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
81671da177e4SLinus Torvalds	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
81681da177e4SLinus Torvalds	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
81691da177e4SLinus Torvalds	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
81701da177e4SLinus Torvalds	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
81711da177e4SLinus Torvalds	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
81721da177e4SLinus Torvalds	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
81731da177e4SLinus Torvalds	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
81741da177e4SLinus Torvalds	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
81751da177e4SLinus Torvalds	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
81761da177e4SLinus Torvalds	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
81771da177e4SLinus Torvalds	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
81781da177e4SLinus Torvalds	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
81791da177e4SLinus Torvalds	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
81801da177e4SLinus Torvalds	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
81811da177e4SLinus Torvalds	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
81821da177e4SLinus Torvalds	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
81831da177e4SLinus Torvalds	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
81841da177e4SLinus Torvalds	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
81851da177e4SLinus Torvalds	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
81861da177e4SLinus Torvalds	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
81871da177e4SLinus Torvalds	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
81881da177e4SLinus Torvalds	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
81891da177e4SLinus Torvalds	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
81901da177e4SLinus Torvalds	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
81911da177e4SLinus Torvalds	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
81921da177e4SLinus Torvalds	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
81931da177e4SLinus Torvalds	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
81941da177e4SLinus Torvalds	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
81951da177e4SLinus Torvalds	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
81961da177e4SLinus Torvalds	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
81971da177e4SLinus Torvalds
81981da177e4SLinus Torvalds	set		ADJK,L_SCR1
81991da177e4SLinus Torvalds
82001da177e4SLinus Torvalds	set		X,FP_SCR0
82011da177e4SLinus Torvalds	set		XDCARE,X+2
82021da177e4SLinus Torvalds	set		XFRAC,X+4
82031da177e4SLinus Torvalds
82041da177e4SLinus Torvalds	set		F,FP_SCR1
82051da177e4SLinus Torvalds	set		FFRAC,F+4
82061da177e4SLinus Torvalds
82071da177e4SLinus Torvalds	set		KLOG2,FP_SCR0
82081da177e4SLinus Torvalds
82091da177e4SLinus Torvalds	set		SAVEU,FP_SCR0
82101da177e4SLinus Torvalds
82111da177e4SLinus Torvalds	global		slogn
82121da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
82131da177e4SLinus Torvaldsslogn:
82141da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
82151da177e4SLinus Torvalds	mov.l		&0x00000000,ADJK(%a6)
82161da177e4SLinus Torvalds
82171da177e4SLinus TorvaldsLOGBGN:
82181da177e4SLinus Torvalds#--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
82191da177e4SLinus Torvalds#--A FINITE, NON-ZERO, NORMALIZED NUMBER.
82201da177e4SLinus Torvalds
82211da177e4SLinus Torvalds	mov.l		(%a0),%d1
82221da177e4SLinus Torvalds	mov.w		4(%a0),%d1
82231da177e4SLinus Torvalds
82241da177e4SLinus Torvalds	mov.l		(%a0),X(%a6)
82251da177e4SLinus Torvalds	mov.l		4(%a0),X+4(%a6)
82261da177e4SLinus Torvalds	mov.l		8(%a0),X+8(%a6)
82271da177e4SLinus Torvalds
82281da177e4SLinus Torvalds	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
82291da177e4SLinus Torvalds	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
82301da177e4SLinus Torvalds# X IS POSITIVE, CHECK IF X IS NEAR 1
82311da177e4SLinus Torvalds	cmp.l		%d1,&0x3ffef07d		# IS X < 15/16?
82321da177e4SLinus Torvalds	blt.b		LOGMAIN			# YES
82331da177e4SLinus Torvalds	cmp.l		%d1,&0x3fff8841		# IS X > 17/16?
82341da177e4SLinus Torvalds	ble.w		LOGNEAR1		# NO
82351da177e4SLinus Torvalds
82361da177e4SLinus TorvaldsLOGMAIN:
82371da177e4SLinus Torvalds#--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
82381da177e4SLinus Torvalds
82391da177e4SLinus Torvalds#--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
82401da177e4SLinus Torvalds#--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
82411da177e4SLinus Torvalds#--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
82421da177e4SLinus Torvalds#--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
82431da177e4SLinus Torvalds#--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
82441da177e4SLinus Torvalds#--LOG(1+U) CAN BE VERY EFFICIENT.
82451da177e4SLinus Torvalds#--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
82461da177e4SLinus Torvalds#--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
82471da177e4SLinus Torvalds
82481da177e4SLinus Torvalds#--GET K, Y, F, AND ADDRESS OF 1/F.
82491da177e4SLinus Torvalds	asr.l		&8,%d1
82501da177e4SLinus Torvalds	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
82511da177e4SLinus Torvalds	sub.l		&0x3FFF,%d1		# THIS IS K
82521da177e4SLinus Torvalds	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
82531da177e4SLinus Torvalds	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
82541da177e4SLinus Torvalds	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
82551da177e4SLinus Torvalds
82561da177e4SLinus Torvalds#--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
82571da177e4SLinus Torvalds	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
82581da177e4SLinus Torvalds	mov.l		XFRAC(%a6),FFRAC(%a6)
82591da177e4SLinus Torvalds	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
82601da177e4SLinus Torvalds	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
82611da177e4SLinus Torvalds	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
82621da177e4SLinus Torvalds	and.l		&0x7E000000,%d1
82631da177e4SLinus Torvalds	asr.l		&8,%d1
82641da177e4SLinus Torvalds	asr.l		&8,%d1
82651da177e4SLinus Torvalds	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
82661da177e4SLinus Torvalds	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
82671da177e4SLinus Torvalds
82681da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0
82691da177e4SLinus Torvalds	mov.l		&0x3fff0000,F(%a6)
82701da177e4SLinus Torvalds	clr.l		F+8(%a6)
82711da177e4SLinus Torvalds	fsub.x		F(%a6),%fp0		# Y-F
82721da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
82731da177e4SLinus Torvalds#--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
82741da177e4SLinus Torvalds#--REGISTERS SAVED: FPCR, FP1, FP2
82751da177e4SLinus Torvalds
82761da177e4SLinus TorvaldsLP1CONT1:
82771da177e4SLinus Torvalds#--AN RE-ENTRY POINT FOR LOGNP1
82781da177e4SLinus Torvalds	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
82791da177e4SLinus Torvalds	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
82801da177e4SLinus Torvalds	fmov.x		%fp0,%fp2
82811da177e4SLinus Torvalds	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
82821da177e4SLinus Torvalds	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
82831da177e4SLinus Torvalds
82841da177e4SLinus Torvalds#--LOG(1+U) IS APPROXIMATED BY
82851da177e4SLinus Torvalds#--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
82861da177e4SLinus Torvalds#--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
82871da177e4SLinus Torvalds
82881da177e4SLinus Torvalds	fmov.x		%fp2,%fp3
82891da177e4SLinus Torvalds	fmov.x		%fp2,%fp1
82901da177e4SLinus Torvalds
82911da177e4SLinus Torvalds	fmul.d		LOGA6(%pc),%fp1		# V*A6
82921da177e4SLinus Torvalds	fmul.d		LOGA5(%pc),%fp2		# V*A5
82931da177e4SLinus Torvalds
82941da177e4SLinus Torvalds	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
82951da177e4SLinus Torvalds	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
82961da177e4SLinus Torvalds
82971da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
82981da177e4SLinus Torvalds	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
82991da177e4SLinus Torvalds
83001da177e4SLinus Torvalds	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
83011da177e4SLinus Torvalds	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
83021da177e4SLinus Torvalds
83031da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
83041da177e4SLinus Torvalds	add.l		&16,%a0			# ADDRESS OF LOG(F)
83051da177e4SLinus Torvalds	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
83061da177e4SLinus Torvalds
83071da177e4SLinus Torvalds	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
83081da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
83091da177e4SLinus Torvalds
83101da177e4SLinus Torvalds	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
83111da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
83121da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
83131da177e4SLinus Torvalds
83141da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
83151da177e4SLinus Torvalds	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
83161da177e4SLinus Torvalds	bra		t_inx2
83171da177e4SLinus Torvalds
83181da177e4SLinus Torvalds
83191da177e4SLinus TorvaldsLOGNEAR1:
83201da177e4SLinus Torvalds
83211da177e4SLinus Torvalds# if the input is exactly equal to one, then exit through ld_pzero.
83221da177e4SLinus Torvalds# if these 2 lines weren't here, the correct answer would be returned
83231da177e4SLinus Torvalds# but the INEX2 bit would be set.
83241da177e4SLinus Torvalds	fcmp.b		%fp0,&0x1		# is it equal to one?
83251da177e4SLinus Torvalds	fbeq.l		ld_pzero		# yes
83261da177e4SLinus Torvalds
83271da177e4SLinus Torvalds#--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
83281da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
83291da177e4SLinus Torvalds	fsub.s		one(%pc),%fp1		# FP1 IS X-1
83301da177e4SLinus Torvalds	fadd.s		one(%pc),%fp0		# FP0 IS X+1
83311da177e4SLinus Torvalds	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
83321da177e4SLinus Torvalds#--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
83331da177e4SLinus Torvalds#--IN U, U = 2(X-1)/(X+1) = FP1/FP0
83341da177e4SLinus Torvalds
83351da177e4SLinus TorvaldsLP1CONT2:
83361da177e4SLinus Torvalds#--THIS IS AN RE-ENTRY POINT FOR LOGNP1
83371da177e4SLinus Torvalds	fdiv.x		%fp0,%fp1		# FP1 IS U
83381da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
83391da177e4SLinus Torvalds#--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
83401da177e4SLinus Torvalds#--LET V=U*U, W=V*V, CALCULATE
83411da177e4SLinus Torvalds#--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
83421da177e4SLinus Torvalds#--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
83431da177e4SLinus Torvalds	fmov.x		%fp1,%fp0
83441da177e4SLinus Torvalds	fmul.x		%fp0,%fp0		# FP0 IS V
83451da177e4SLinus Torvalds	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
83461da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
83471da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# FP1 IS W
83481da177e4SLinus Torvalds
83491da177e4SLinus Torvalds	fmov.d		LOGB5(%pc),%fp3
83501da177e4SLinus Torvalds	fmov.d		LOGB4(%pc),%fp2
83511da177e4SLinus Torvalds
83521da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# W*B5
83531da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# W*B4
83541da177e4SLinus Torvalds
83551da177e4SLinus Torvalds	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
83561da177e4SLinus Torvalds	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
83571da177e4SLinus Torvalds
83581da177e4SLinus Torvalds	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
83591da177e4SLinus Torvalds
83601da177e4SLinus Torvalds	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
83611da177e4SLinus Torvalds
83621da177e4SLinus Torvalds	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
83631da177e4SLinus Torvalds	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
83641da177e4SLinus Torvalds
83651da177e4SLinus Torvalds	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
83661da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
83671da177e4SLinus Torvalds
83681da177e4SLinus Torvalds	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
83691da177e4SLinus Torvalds
83701da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
83711da177e4SLinus Torvalds	fadd.x		SAVEU(%a6),%fp0
83721da177e4SLinus Torvalds	bra		t_inx2
83731da177e4SLinus Torvalds
83741da177e4SLinus Torvalds#--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
83751da177e4SLinus TorvaldsLOGNEG:
83761da177e4SLinus Torvalds	bra		t_operr
83771da177e4SLinus Torvalds
83781da177e4SLinus Torvalds	global		slognd
83791da177e4SLinus Torvaldsslognd:
83801da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
83811da177e4SLinus Torvalds
83821da177e4SLinus Torvalds	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
83831da177e4SLinus Torvalds
83841da177e4SLinus Torvalds#----normalize the input value by left shifting k bits (k to be determined
83851da177e4SLinus Torvalds#----below), adjusting exponent and storing -k to  ADJK
83861da177e4SLinus Torvalds#----the value TWOTO100 is no longer needed.
83871da177e4SLinus Torvalds#----Note that this code assumes the denormalized input is NON-ZERO.
83881da177e4SLinus Torvalds
83891da177e4SLinus Torvalds	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
83901da177e4SLinus Torvalds	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
83911da177e4SLinus Torvalds	mov.l		4(%a0),%d4
83921da177e4SLinus Torvalds	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
83931da177e4SLinus Torvalds	clr.l		%d2			# D2 used for holding K
83941da177e4SLinus Torvalds
83951da177e4SLinus Torvalds	tst.l		%d4
83961da177e4SLinus Torvalds	bne.b		Hi_not0
83971da177e4SLinus Torvalds
83981da177e4SLinus TorvaldsHi_0:
83991da177e4SLinus Torvalds	mov.l		%d5,%d4
84001da177e4SLinus Torvalds	clr.l		%d5
84011da177e4SLinus Torvalds	mov.l		&32,%d2
84021da177e4SLinus Torvalds	clr.l		%d6
84031da177e4SLinus Torvalds	bfffo		%d4{&0:&32},%d6
84041da177e4SLinus Torvalds	lsl.l		%d6,%d4
84051da177e4SLinus Torvalds	add.l		%d6,%d2			# (D3,D4,D5) is normalized
84061da177e4SLinus Torvalds
84071da177e4SLinus Torvalds	mov.l		%d3,X(%a6)
84081da177e4SLinus Torvalds	mov.l		%d4,XFRAC(%a6)
84091da177e4SLinus Torvalds	mov.l		%d5,XFRAC+4(%a6)
84101da177e4SLinus Torvalds	neg.l		%d2
84111da177e4SLinus Torvalds	mov.l		%d2,ADJK(%a6)
84121da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0
84131da177e4SLinus Torvalds	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
84141da177e4SLinus Torvalds	lea		X(%a6),%a0
84151da177e4SLinus Torvalds	bra.w		LOGBGN			# begin regular log(X)
84161da177e4SLinus Torvalds
84171da177e4SLinus TorvaldsHi_not0:
84181da177e4SLinus Torvalds	clr.l		%d6
84191da177e4SLinus Torvalds	bfffo		%d4{&0:&32},%d6		# find first 1
84201da177e4SLinus Torvalds	mov.l		%d6,%d2			# get k
84211da177e4SLinus Torvalds	lsl.l		%d6,%d4
84221da177e4SLinus Torvalds	mov.l		%d5,%d7			# a copy of D5
84231da177e4SLinus Torvalds	lsl.l		%d6,%d5
84241da177e4SLinus Torvalds	neg.l		%d6
84251da177e4SLinus Torvalds	add.l		&32,%d6
84261da177e4SLinus Torvalds	lsr.l		%d6,%d7
84271da177e4SLinus Torvalds	or.l		%d7,%d4			# (D3,D4,D5) normalized
84281da177e4SLinus Torvalds
84291da177e4SLinus Torvalds	mov.l		%d3,X(%a6)
84301da177e4SLinus Torvalds	mov.l		%d4,XFRAC(%a6)
84311da177e4SLinus Torvalds	mov.l		%d5,XFRAC+4(%a6)
84321da177e4SLinus Torvalds	neg.l		%d2
84331da177e4SLinus Torvalds	mov.l		%d2,ADJK(%a6)
84341da177e4SLinus Torvalds	fmov.x		X(%a6),%fp0
84351da177e4SLinus Torvalds	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
84361da177e4SLinus Torvalds	lea		X(%a6),%a0
84371da177e4SLinus Torvalds	bra.w		LOGBGN			# begin regular log(X)
84381da177e4SLinus Torvalds
84391da177e4SLinus Torvalds	global		slognp1
84401da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
84411da177e4SLinus Torvaldsslognp1:
84421da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
84431da177e4SLinus Torvalds	fabs.x		%fp0			# test magnitude
84441da177e4SLinus Torvalds	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
84451da177e4SLinus Torvalds	fbgt.w		LP1REAL			# if greater, continue
84461da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
84471da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
84481da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# return signed argument
84491da177e4SLinus Torvalds	bra		t_catch
84501da177e4SLinus Torvalds
84511da177e4SLinus TorvaldsLP1REAL:
84521da177e4SLinus Torvalds	fmov.x		(%a0),%fp0		# LOAD INPUT
84531da177e4SLinus Torvalds	mov.l		&0x00000000,ADJK(%a6)
84541da177e4SLinus Torvalds	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
84551da177e4SLinus Torvalds	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
84561da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)
84571da177e4SLinus Torvalds	mov.w		XFRAC(%a6),XDCARE(%a6)
84581da177e4SLinus Torvalds	mov.l		X(%a6),%d1
84591da177e4SLinus Torvalds	cmp.l		%d1,&0
84601da177e4SLinus Torvalds	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
84611da177e4SLinus Torvalds	cmp.l		%d1,&0x3ffe8000		# IS BOUNDS [1/2,3/2]?
84621da177e4SLinus Torvalds	blt.w		LOGMAIN
84631da177e4SLinus Torvalds	cmp.l		%d1,&0x3fffc000
84641da177e4SLinus Torvalds	bgt.w		LOGMAIN
84651da177e4SLinus Torvalds#--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
84661da177e4SLinus Torvalds#--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
84671da177e4SLinus Torvalds#--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
84681da177e4SLinus Torvalds
84691da177e4SLinus TorvaldsLP1NEAR1:
84701da177e4SLinus Torvalds#--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
84711da177e4SLinus Torvalds	cmp.l		%d1,&0x3ffef07d
84721da177e4SLinus Torvalds	blt.w		LP1CARE
84731da177e4SLinus Torvalds	cmp.l		%d1,&0x3fff8841
84741da177e4SLinus Torvalds	bgt.w		LP1CARE
84751da177e4SLinus Torvalds
84761da177e4SLinus TorvaldsLP1ONE16:
84771da177e4SLinus Torvalds#--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
84781da177e4SLinus Torvalds#--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
84791da177e4SLinus Torvalds	fadd.x		%fp1,%fp1		# FP1 IS 2Z
84801da177e4SLinus Torvalds	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
84811da177e4SLinus Torvalds#--U = FP1/FP0
84821da177e4SLinus Torvalds	bra.w		LP1CONT2
84831da177e4SLinus Torvalds
84841da177e4SLinus TorvaldsLP1CARE:
84851da177e4SLinus Torvalds#--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
84861da177e4SLinus Torvalds#--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
84871da177e4SLinus Torvalds#--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
84881da177e4SLinus Torvalds#--THERE ARE ONLY TWO CASES.
84891da177e4SLinus Torvalds#--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
84901da177e4SLinus Torvalds#--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
84911da177e4SLinus Torvalds#--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
84921da177e4SLinus Torvalds#--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
84931da177e4SLinus Torvalds
84941da177e4SLinus Torvalds	mov.l		XFRAC(%a6),FFRAC(%a6)
84951da177e4SLinus Torvalds	and.l		&0xFE000000,FFRAC(%a6)
84961da177e4SLinus Torvalds	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
84971da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
84981da177e4SLinus Torvalds	bge.b		KISZERO
84991da177e4SLinus Torvalds
85001da177e4SLinus TorvaldsKISNEG1:
85011da177e4SLinus Torvalds	fmov.s		TWO(%pc),%fp0
85021da177e4SLinus Torvalds	mov.l		&0x3fff0000,F(%a6)
85031da177e4SLinus Torvalds	clr.l		F+8(%a6)
85041da177e4SLinus Torvalds	fsub.x		F(%a6),%fp0		# 2-F
85051da177e4SLinus Torvalds	mov.l		FFRAC(%a6),%d1
85061da177e4SLinus Torvalds	and.l		&0x7E000000,%d1
85071da177e4SLinus Torvalds	asr.l		&8,%d1
85081da177e4SLinus Torvalds	asr.l		&8,%d1
85091da177e4SLinus Torvalds	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
85101da177e4SLinus Torvalds	fadd.x		%fp1,%fp1		# GET 2Z
85111da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
85121da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
85131da177e4SLinus Torvalds	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
85141da177e4SLinus Torvalds	add.l		%d1,%a0
85151da177e4SLinus Torvalds	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
85161da177e4SLinus Torvalds	bra.w		LP1CONT1
85171da177e4SLinus Torvalds
85181da177e4SLinus TorvaldsKISZERO:
85191da177e4SLinus Torvalds	fmov.s		one(%pc),%fp0
85201da177e4SLinus Torvalds	mov.l		&0x3fff0000,F(%a6)
85211da177e4SLinus Torvalds	clr.l		F+8(%a6)
85221da177e4SLinus Torvalds	fsub.x		F(%a6),%fp0		# 1-F
85231da177e4SLinus Torvalds	mov.l		FFRAC(%a6),%d1
85241da177e4SLinus Torvalds	and.l		&0x7E000000,%d1
85251da177e4SLinus Torvalds	asr.l		&8,%d1
85261da177e4SLinus Torvalds	asr.l		&8,%d1
85271da177e4SLinus Torvalds	asr.l		&4,%d1
85281da177e4SLinus Torvalds	fadd.x		%fp1,%fp0		# FP0 IS Y-F
85291da177e4SLinus Torvalds	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
85301da177e4SLinus Torvalds	lea		LOGTBL(%pc),%a0
85311da177e4SLinus Torvalds	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
85321da177e4SLinus Torvalds	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
85331da177e4SLinus Torvalds	bra.w		LP1CONT1
85341da177e4SLinus Torvalds
85351da177e4SLinus TorvaldsLP1NEG0:
85361da177e4SLinus Torvalds#--FPCR SAVED. D0 IS X IN COMPACT FORM.
85371da177e4SLinus Torvalds	cmp.l		%d1,&0
85381da177e4SLinus Torvalds	blt.b		LP1NEG
85391da177e4SLinus TorvaldsLP1ZERO:
85401da177e4SLinus Torvalds	fmov.s		negone(%pc),%fp0
85411da177e4SLinus Torvalds
85421da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
85431da177e4SLinus Torvalds	bra		t_dz
85441da177e4SLinus Torvalds
85451da177e4SLinus TorvaldsLP1NEG:
85461da177e4SLinus Torvalds	fmov.s		zero(%pc),%fp0
85471da177e4SLinus Torvalds
85481da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
85491da177e4SLinus Torvalds	bra		t_operr
85501da177e4SLinus Torvalds
85511da177e4SLinus Torvalds	global		slognp1d
85521da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
85531da177e4SLinus Torvalds# Simply return the denorm
85541da177e4SLinus Torvaldsslognp1d:
85551da177e4SLinus Torvalds	bra		t_extdnrm
85561da177e4SLinus Torvalds
85571da177e4SLinus Torvalds#########################################################################
85581da177e4SLinus Torvalds# satanh():  computes the inverse hyperbolic tangent of a norm input	#
85591da177e4SLinus Torvalds# satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
85601da177e4SLinus Torvalds#									#
85611da177e4SLinus Torvalds# INPUT ***************************************************************	#
85621da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
85631da177e4SLinus Torvalds#	d0 = round precision,mode					#
85641da177e4SLinus Torvalds#									#
85651da177e4SLinus Torvalds# OUTPUT **************************************************************	#
85661da177e4SLinus Torvalds#	fp0 = arctanh(X)						#
85671da177e4SLinus Torvalds#									#
85681da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
85691da177e4SLinus Torvalds#	The returned result is within 3 ulps in	64 significant bit,	#
85701da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
85711da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
85721da177e4SLinus Torvalds#	in double precision.						#
85731da177e4SLinus Torvalds#									#
85741da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
85751da177e4SLinus Torvalds#									#
85761da177e4SLinus Torvalds#	ATANH								#
85771da177e4SLinus Torvalds#	1. If |X| >= 1, go to 3.					#
85781da177e4SLinus Torvalds#									#
85791da177e4SLinus Torvalds#	2. (|X| < 1) Calculate atanh(X) by				#
85801da177e4SLinus Torvalds#		sgn := sign(X)						#
85811da177e4SLinus Torvalds#		y := |X|						#
85821da177e4SLinus Torvalds#		z := 2y/(1-y)						#
85831da177e4SLinus Torvalds#		atanh(X) := sgn * (1/2) * logp1(z)			#
85841da177e4SLinus Torvalds#		Exit.							#
85851da177e4SLinus Torvalds#									#
85861da177e4SLinus Torvalds#	3. If |X| > 1, go to 5.						#
85871da177e4SLinus Torvalds#									#
85881da177e4SLinus Torvalds#	4. (|X| = 1) Generate infinity with an appropriate sign and	#
85891da177e4SLinus Torvalds#		divide-by-zero by					#
85901da177e4SLinus Torvalds#		sgn := sign(X)						#
85911da177e4SLinus Torvalds#		atan(X) := sgn / (+0).					#
85921da177e4SLinus Torvalds#		Exit.							#
85931da177e4SLinus Torvalds#									#
85941da177e4SLinus Torvalds#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
85951da177e4SLinus Torvalds#		Exit.							#
85961da177e4SLinus Torvalds#									#
85971da177e4SLinus Torvalds#########################################################################
85981da177e4SLinus Torvalds
85991da177e4SLinus Torvalds	global		satanh
86001da177e4SLinus Torvaldssatanh:
86011da177e4SLinus Torvalds	mov.l		(%a0),%d1
86021da177e4SLinus Torvalds	mov.w		4(%a0),%d1
86031da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
86041da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
86051da177e4SLinus Torvalds	bge.b		ATANHBIG
86061da177e4SLinus Torvalds
86071da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 1
86081da177e4SLinus Torvalds#--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
86091da177e4SLinus Torvalds
86101da177e4SLinus Torvalds	fabs.x		(%a0),%fp0		# Y = |X|
86111da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
86121da177e4SLinus Torvalds	fneg.x		%fp1			# -Y
86131da177e4SLinus Torvalds	fadd.x		%fp0,%fp0		# 2Y
86141da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp1	# 1-Y
86151da177e4SLinus Torvalds	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
86161da177e4SLinus Torvalds	mov.l		(%a0),%d1
86171da177e4SLinus Torvalds	and.l		&0x80000000,%d1
86181da177e4SLinus Torvalds	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
86191da177e4SLinus Torvalds	mov.l		%d1,-(%sp)
86201da177e4SLinus Torvalds
86211da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save rnd prec,mode
86221da177e4SLinus Torvalds	clr.l		%d0			# pass ext prec,RN
86231da177e4SLinus Torvalds	fmovm.x		&0x01,-(%sp)		# save Z on stack
86241da177e4SLinus Torvalds	lea		(%sp),%a0		# pass ptr to Z
86251da177e4SLinus Torvalds	bsr		slognp1			# LOG1P(Z)
86261da177e4SLinus Torvalds	add.l		&0xc,%sp		# clear Z from stack
86271da177e4SLinus Torvalds
86281da177e4SLinus Torvalds	mov.l		(%sp)+,%d0		# fetch old prec,mode
86291da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# load it
86301da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
86311da177e4SLinus Torvalds	fmul.s		(%sp)+,%fp0
86321da177e4SLinus Torvalds	bra		t_catch
86331da177e4SLinus Torvalds
86341da177e4SLinus TorvaldsATANHBIG:
86351da177e4SLinus Torvalds	fabs.x		(%a0),%fp0		# |X|
86361da177e4SLinus Torvalds	fcmp.s		%fp0,&0x3F800000
86371da177e4SLinus Torvalds	fbgt		t_operr
86381da177e4SLinus Torvalds	bra		t_dz
86391da177e4SLinus Torvalds
86401da177e4SLinus Torvalds	global		satanhd
86411da177e4SLinus Torvalds#--ATANH(X) = X FOR DENORMALIZED X
86421da177e4SLinus Torvaldssatanhd:
86431da177e4SLinus Torvalds	bra		t_extdnrm
86441da177e4SLinus Torvalds
86451da177e4SLinus Torvalds#########################################################################
86461da177e4SLinus Torvalds# slog10():  computes the base-10 logarithm of a normalized input	#
86471da177e4SLinus Torvalds# slog10d(): computes the base-10 logarithm of a denormalized input	#
86481da177e4SLinus Torvalds# slog2():   computes the base-2 logarithm of a normalized input	#
86491da177e4SLinus Torvalds# slog2d():  computes the base-2 logarithm of a denormalized input	#
86501da177e4SLinus Torvalds#									#
86511da177e4SLinus Torvalds# INPUT *************************************************************** #
86521da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
86531da177e4SLinus Torvalds#	d0 = round precision,mode					#
86541da177e4SLinus Torvalds#									#
86551da177e4SLinus Torvalds# OUTPUT **************************************************************	#
86561da177e4SLinus Torvalds#	fp0 = log_10(X) or log_2(X)					#
86571da177e4SLinus Torvalds#									#
86581da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
86591da177e4SLinus Torvalds#	The returned result is within 1.7 ulps in 64 significant bit,	#
86601da177e4SLinus Torvalds#	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
86611da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
86621da177e4SLinus Torvalds#	in double precision.						#
86631da177e4SLinus Torvalds#									#
86641da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
86651da177e4SLinus Torvalds#									#
86661da177e4SLinus Torvalds#       slog10d:							#
86671da177e4SLinus Torvalds#									#
86681da177e4SLinus Torvalds#       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
86691da177e4SLinus Torvalds#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
86701da177e4SLinus Torvalds#       Notes:  Default means round-to-nearest mode, no floating-point	#
86711da177e4SLinus Torvalds#               traps, and precision control = double extended.		#
86721da177e4SLinus Torvalds#									#
86731da177e4SLinus Torvalds#       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
86741da177e4SLinus Torvalds#       Notes:  Even if X is denormalized, log(X) is always normalized.	#
86751da177e4SLinus Torvalds#									#
86761da177e4SLinus Torvalds#       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
86771da177e4SLinus Torvalds#            2.1 Restore the user FPCR					#
86781da177e4SLinus Torvalds#            2.2 Return ans := Y * INV_L10.				#
86791da177e4SLinus Torvalds#									#
86801da177e4SLinus Torvalds#       slog10:								#
86811da177e4SLinus Torvalds#									#
86821da177e4SLinus Torvalds#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
86831da177e4SLinus Torvalds#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
86841da177e4SLinus Torvalds#       Notes:  Default means round-to-nearest mode, no floating-point	#
86851da177e4SLinus Torvalds#               traps, and precision control = double extended.		#
86861da177e4SLinus Torvalds#									#
86871da177e4SLinus Torvalds#       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
86881da177e4SLinus Torvalds#									#
86891da177e4SLinus Torvalds#       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
86901da177e4SLinus Torvalds#            2.1  Restore the user FPCR					#
86911da177e4SLinus Torvalds#            2.2  Return ans := Y * INV_L10.				#
86921da177e4SLinus Torvalds#									#
86931da177e4SLinus Torvalds#       sLog2d:								#
86941da177e4SLinus Torvalds#									#
86951da177e4SLinus Torvalds#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
86961da177e4SLinus Torvalds#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
86971da177e4SLinus Torvalds#       Notes:  Default means round-to-nearest mode, no floating-point	#
86981da177e4SLinus Torvalds#               traps, and precision control = double extended.		#
86991da177e4SLinus Torvalds#									#
87001da177e4SLinus Torvalds#       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
87011da177e4SLinus Torvalds#       Notes:  Even if X is denormalized, log(X) is always normalized.	#
87021da177e4SLinus Torvalds#									#
87031da177e4SLinus Torvalds#       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
87041da177e4SLinus Torvalds#            2.1  Restore the user FPCR					#
87051da177e4SLinus Torvalds#            2.2  Return ans := Y * INV_L2.				#
87061da177e4SLinus Torvalds#									#
87071da177e4SLinus Torvalds#       sLog2:								#
87081da177e4SLinus Torvalds#									#
87091da177e4SLinus Torvalds#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
87101da177e4SLinus Torvalds#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
87111da177e4SLinus Torvalds#       Notes:  Default means round-to-nearest mode, no floating-point	#
87121da177e4SLinus Torvalds#               traps, and precision control = double extended.		#
87131da177e4SLinus Torvalds#									#
87141da177e4SLinus Torvalds#       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
87151da177e4SLinus Torvalds#               go to Step 3.						#
87161da177e4SLinus Torvalds#									#
87171da177e4SLinus Torvalds#       Step 2.   Return k.						#
87181da177e4SLinus Torvalds#            2.1  Get integer k, X = 2^k.				#
87191da177e4SLinus Torvalds#            2.2  Restore the user FPCR.				#
87201da177e4SLinus Torvalds#            2.3  Return ans := convert-to-double-extended(k).		#
87211da177e4SLinus Torvalds#									#
87221da177e4SLinus Torvalds#       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
87231da177e4SLinus Torvalds#									#
87241da177e4SLinus Torvalds#       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
87251da177e4SLinus Torvalds#            4.1  Restore the user FPCR					#
87261da177e4SLinus Torvalds#            4.2  Return ans := Y * INV_L2.				#
87271da177e4SLinus Torvalds#									#
87281da177e4SLinus Torvalds#########################################################################
87291da177e4SLinus Torvalds
87301da177e4SLinus TorvaldsINV_L10:
87311da177e4SLinus Torvalds	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
87321da177e4SLinus Torvalds
87331da177e4SLinus TorvaldsINV_L2:
87341da177e4SLinus Torvalds	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
87351da177e4SLinus Torvalds
87361da177e4SLinus Torvalds	global		slog10
87371da177e4SLinus Torvalds#--entry point for Log10(X), X is normalized
87381da177e4SLinus Torvaldsslog10:
87391da177e4SLinus Torvalds	fmov.b		&0x1,%fp0
87401da177e4SLinus Torvalds	fcmp.x		%fp0,(%a0)		# if operand == 1,
87411da177e4SLinus Torvalds	fbeq.l		ld_pzero		# return an EXACT zero
87421da177e4SLinus Torvalds
87431da177e4SLinus Torvalds	mov.l		(%a0),%d1
87441da177e4SLinus Torvalds	blt.w		invalid
87451da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
87461da177e4SLinus Torvalds	clr.l		%d0
87471da177e4SLinus Torvalds	bsr		slogn			# log(X), X normal.
87481da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr
87491da177e4SLinus Torvalds	fmul.x		INV_L10(%pc),%fp0
87501da177e4SLinus Torvalds	bra		t_inx2
87511da177e4SLinus Torvalds
87521da177e4SLinus Torvalds	global		slog10d
87531da177e4SLinus Torvalds#--entry point for Log10(X), X is denormalized
87541da177e4SLinus Torvaldsslog10d:
87551da177e4SLinus Torvalds	mov.l		(%a0),%d1
87561da177e4SLinus Torvalds	blt.w		invalid
87571da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
87581da177e4SLinus Torvalds	clr.l		%d0
87591da177e4SLinus Torvalds	bsr		slognd			# log(X), X denorm.
87601da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr
87611da177e4SLinus Torvalds	fmul.x		INV_L10(%pc),%fp0
87621da177e4SLinus Torvalds	bra		t_minx2
87631da177e4SLinus Torvalds
87641da177e4SLinus Torvalds	global		slog2
87651da177e4SLinus Torvalds#--entry point for Log2(X), X is normalized
87661da177e4SLinus Torvaldsslog2:
87671da177e4SLinus Torvalds	mov.l		(%a0),%d1
87681da177e4SLinus Torvalds	blt.w		invalid
87691da177e4SLinus Torvalds
87701da177e4SLinus Torvalds	mov.l		8(%a0),%d1
87711da177e4SLinus Torvalds	bne.b		continue		# X is not 2^k
87721da177e4SLinus Torvalds
87731da177e4SLinus Torvalds	mov.l		4(%a0),%d1
87741da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
87751da177e4SLinus Torvalds	bne.b		continue
87761da177e4SLinus Torvalds
87771da177e4SLinus Torvalds#--X = 2^k.
87781da177e4SLinus Torvalds	mov.w		(%a0),%d1
87791da177e4SLinus Torvalds	and.l		&0x00007FFF,%d1
87801da177e4SLinus Torvalds	sub.l		&0x3FFF,%d1
87811da177e4SLinus Torvalds	beq.l		ld_pzero
87821da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
87831da177e4SLinus Torvalds	fmov.l		%d1,%fp0
87841da177e4SLinus Torvalds	bra		t_inx2
87851da177e4SLinus Torvalds
87861da177e4SLinus Torvaldscontinue:
87871da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
87881da177e4SLinus Torvalds	clr.l		%d0
87891da177e4SLinus Torvalds	bsr		slogn			# log(X), X normal.
87901da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr
87911da177e4SLinus Torvalds	fmul.x		INV_L2(%pc),%fp0
87921da177e4SLinus Torvalds	bra		t_inx2
87931da177e4SLinus Torvalds
87941da177e4SLinus Torvaldsinvalid:
87951da177e4SLinus Torvalds	bra		t_operr
87961da177e4SLinus Torvalds
87971da177e4SLinus Torvalds	global		slog2d
87981da177e4SLinus Torvalds#--entry point for Log2(X), X is denormalized
87991da177e4SLinus Torvaldsslog2d:
88001da177e4SLinus Torvalds	mov.l		(%a0),%d1
88011da177e4SLinus Torvalds	blt.w		invalid
88021da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
88031da177e4SLinus Torvalds	clr.l		%d0
88041da177e4SLinus Torvalds	bsr		slognd			# log(X), X denorm.
88051da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr
88061da177e4SLinus Torvalds	fmul.x		INV_L2(%pc),%fp0
88071da177e4SLinus Torvalds	bra		t_minx2
88081da177e4SLinus Torvalds
88091da177e4SLinus Torvalds#########################################################################
88101da177e4SLinus Torvalds# stwotox():  computes 2**X for a normalized input			#
88111da177e4SLinus Torvalds# stwotoxd(): computes 2**X for a denormalized input			#
88121da177e4SLinus Torvalds# stentox():  computes 10**X for a normalized input			#
88131da177e4SLinus Torvalds# stentoxd(): computes 10**X for a denormalized input			#
88141da177e4SLinus Torvalds#									#
88151da177e4SLinus Torvalds# INPUT ***************************************************************	#
88161da177e4SLinus Torvalds#	a0 = pointer to extended precision input			#
88171da177e4SLinus Torvalds#	d0 = round precision,mode					#
88181da177e4SLinus Torvalds#									#
88191da177e4SLinus Torvalds# OUTPUT **************************************************************	#
88201da177e4SLinus Torvalds#	fp0 = 2**X or 10**X						#
88211da177e4SLinus Torvalds#									#
88221da177e4SLinus Torvalds# ACCURACY and MONOTONICITY *******************************************	#
88231da177e4SLinus Torvalds#	The returned result is within 2 ulps in 64 significant bit,	#
88241da177e4SLinus Torvalds#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
88251da177e4SLinus Torvalds#	rounded to double precision. The result is provably monotonic	#
88261da177e4SLinus Torvalds#	in double precision.						#
88271da177e4SLinus Torvalds#									#
88281da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
88291da177e4SLinus Torvalds#									#
88301da177e4SLinus Torvalds#	twotox								#
88311da177e4SLinus Torvalds#	1. If |X| > 16480, go to ExpBig.				#
88321da177e4SLinus Torvalds#									#
88331da177e4SLinus Torvalds#	2. If |X| < 2**(-70), go to ExpSm.				#
88341da177e4SLinus Torvalds#									#
88351da177e4SLinus Torvalds#	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
88361da177e4SLinus Torvalds#		decompose N as						#
88371da177e4SLinus Torvalds#		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
88381da177e4SLinus Torvalds#									#
88391da177e4SLinus Torvalds#	4. Overwrite r := r * log2. Then				#
88401da177e4SLinus Torvalds#		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
88411da177e4SLinus Torvalds#		Go to expr to compute that expression.			#
88421da177e4SLinus Torvalds#									#
88431da177e4SLinus Torvalds#	tentox								#
88441da177e4SLinus Torvalds#	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
88451da177e4SLinus Torvalds#									#
88461da177e4SLinus Torvalds#	2. If |X| < 2**(-70), go to ExpSm.				#
88471da177e4SLinus Torvalds#									#
88481da177e4SLinus Torvalds#	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
88491da177e4SLinus Torvalds#		N := round-to-int(y). Decompose N as			#
88501da177e4SLinus Torvalds#		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
88511da177e4SLinus Torvalds#									#
88521da177e4SLinus Torvalds#	4. Define r as							#
88531da177e4SLinus Torvalds#		r := ((X - N*L1)-N*L2) * L10				#
88541da177e4SLinus Torvalds#		where L1, L2 are the leading and trailing parts of	#
88551da177e4SLinus Torvalds#		log_10(2)/64 and L10 is the natural log of 10. Then	#
88561da177e4SLinus Torvalds#		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
88571da177e4SLinus Torvalds#		Go to expr to compute that expression.			#
88581da177e4SLinus Torvalds#									#
88591da177e4SLinus Torvalds#	expr								#
88601da177e4SLinus Torvalds#	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
88611da177e4SLinus Torvalds#									#
88621da177e4SLinus Torvalds#	2. Overwrite Fact1 and Fact2 by					#
88631da177e4SLinus Torvalds#		Fact1 := 2**(M) * Fact1					#
88641da177e4SLinus Torvalds#		Fact2 := 2**(M) * Fact2					#
88651da177e4SLinus Torvalds#		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
88661da177e4SLinus Torvalds#									#
88671da177e4SLinus Torvalds#	3. Calculate P where 1 + P approximates exp(r):			#
88681da177e4SLinus Torvalds#		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
88691da177e4SLinus Torvalds#									#
88701da177e4SLinus Torvalds#	4. Let AdjFact := 2**(M'). Return				#
88711da177e4SLinus Torvalds#		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
88721da177e4SLinus Torvalds#		Exit.							#
88731da177e4SLinus Torvalds#									#
88741da177e4SLinus Torvalds#	ExpBig								#
88751da177e4SLinus Torvalds#	1. Generate overflow by Huge * Huge if X > 0; otherwise,	#
88761da177e4SLinus Torvalds#	        generate underflow by Tiny * Tiny.			#
88771da177e4SLinus Torvalds#									#
88781da177e4SLinus Torvalds#	ExpSm								#
88791da177e4SLinus Torvalds#	1. Return 1 + X.						#
88801da177e4SLinus Torvalds#									#
88811da177e4SLinus Torvalds#########################################################################
88821da177e4SLinus Torvalds
88831da177e4SLinus TorvaldsL2TEN64:
88841da177e4SLinus Torvalds	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
88851da177e4SLinus TorvaldsL10TWO1:
88861da177e4SLinus Torvalds	long		0x3F734413,0x509F8000	# LOG2/64LOG10
88871da177e4SLinus Torvalds
88881da177e4SLinus TorvaldsL10TWO2:
88891da177e4SLinus Torvalds	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
88901da177e4SLinus Torvalds
88911da177e4SLinus TorvaldsLOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
88921da177e4SLinus Torvalds
88931da177e4SLinus TorvaldsLOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
88941da177e4SLinus Torvalds
88951da177e4SLinus TorvaldsEXPA5:	long		0x3F56C16D,0x6F7BD0B2
88961da177e4SLinus TorvaldsEXPA4:	long		0x3F811112,0x302C712C
88971da177e4SLinus TorvaldsEXPA3:	long		0x3FA55555,0x55554CC1
88981da177e4SLinus TorvaldsEXPA2:	long		0x3FC55555,0x55554A54
88991da177e4SLinus TorvaldsEXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
89001da177e4SLinus Torvalds
89011da177e4SLinus TorvaldsTEXPTBL:
89021da177e4SLinus Torvalds	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
89031da177e4SLinus Torvalds	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
89041da177e4SLinus Torvalds	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
89051da177e4SLinus Torvalds	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
89061da177e4SLinus Torvalds	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
89071da177e4SLinus Torvalds	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
89081da177e4SLinus Torvalds	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
89091da177e4SLinus Torvalds	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
89101da177e4SLinus Torvalds	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
89111da177e4SLinus Torvalds	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
89121da177e4SLinus Torvalds	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
89131da177e4SLinus Torvalds	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
89141da177e4SLinus Torvalds	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
89151da177e4SLinus Torvalds	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
89161da177e4SLinus Torvalds	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
89171da177e4SLinus Torvalds	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
89181da177e4SLinus Torvalds	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
89191da177e4SLinus Torvalds	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
89201da177e4SLinus Torvalds	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
89211da177e4SLinus Torvalds	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
89221da177e4SLinus Torvalds	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
89231da177e4SLinus Torvalds	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
89241da177e4SLinus Torvalds	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
89251da177e4SLinus Torvalds	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
89261da177e4SLinus Torvalds	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
89271da177e4SLinus Torvalds	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
89281da177e4SLinus Torvalds	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
89291da177e4SLinus Torvalds	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
89301da177e4SLinus Torvalds	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
89311da177e4SLinus Torvalds	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
89321da177e4SLinus Torvalds	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
89331da177e4SLinus Torvalds	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
89341da177e4SLinus Torvalds	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
89351da177e4SLinus Torvalds	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
89361da177e4SLinus Torvalds	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
89371da177e4SLinus Torvalds	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
89381da177e4SLinus Torvalds	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
89391da177e4SLinus Torvalds	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
89401da177e4SLinus Torvalds	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
89411da177e4SLinus Torvalds	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
89421da177e4SLinus Torvalds	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
89431da177e4SLinus Torvalds	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
89441da177e4SLinus Torvalds	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
89451da177e4SLinus Torvalds	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
89461da177e4SLinus Torvalds	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
89471da177e4SLinus Torvalds	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
89481da177e4SLinus Torvalds	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
89491da177e4SLinus Torvalds	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
89501da177e4SLinus Torvalds	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
89511da177e4SLinus Torvalds	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
89521da177e4SLinus Torvalds	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
89531da177e4SLinus Torvalds	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
89541da177e4SLinus Torvalds	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
89551da177e4SLinus Torvalds	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
89561da177e4SLinus Torvalds	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
89571da177e4SLinus Torvalds	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
89581da177e4SLinus Torvalds	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
89591da177e4SLinus Torvalds	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
89601da177e4SLinus Torvalds	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
89611da177e4SLinus Torvalds	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
89621da177e4SLinus Torvalds	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
89631da177e4SLinus Torvalds	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
89641da177e4SLinus Torvalds	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
89651da177e4SLinus Torvalds	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
89661da177e4SLinus Torvalds
89671da177e4SLinus Torvalds	set		INT,L_SCR1
89681da177e4SLinus Torvalds
89691da177e4SLinus Torvalds	set		X,FP_SCR0
89701da177e4SLinus Torvalds	set		XDCARE,X+2
89711da177e4SLinus Torvalds	set		XFRAC,X+4
89721da177e4SLinus Torvalds
89731da177e4SLinus Torvalds	set		ADJFACT,FP_SCR0
89741da177e4SLinus Torvalds
89751da177e4SLinus Torvalds	set		FACT1,FP_SCR0
89761da177e4SLinus Torvalds	set		FACT1HI,FACT1+4
89771da177e4SLinus Torvalds	set		FACT1LOW,FACT1+8
89781da177e4SLinus Torvalds
89791da177e4SLinus Torvalds	set		FACT2,FP_SCR1
89801da177e4SLinus Torvalds	set		FACT2HI,FACT2+4
89811da177e4SLinus Torvalds	set		FACT2LOW,FACT2+8
89821da177e4SLinus Torvalds
89831da177e4SLinus Torvalds	global		stwotox
89841da177e4SLinus Torvalds#--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
89851da177e4SLinus Torvaldsstwotox:
89861da177e4SLinus Torvalds	fmovm.x		(%a0),&0x80		# LOAD INPUT
89871da177e4SLinus Torvalds
89881da177e4SLinus Torvalds	mov.l		(%a0),%d1
89891da177e4SLinus Torvalds	mov.w		4(%a0),%d1
89901da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)
89911da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
89921da177e4SLinus Torvalds
89931da177e4SLinus Torvalds	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
89941da177e4SLinus Torvalds	bge.b		TWOOK1
89951da177e4SLinus Torvalds	bra.w		EXPBORS
89961da177e4SLinus Torvalds
89971da177e4SLinus TorvaldsTWOOK1:
89981da177e4SLinus Torvalds	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
89991da177e4SLinus Torvalds	ble.b		TWOMAIN
90001da177e4SLinus Torvalds	bra.w		EXPBORS
90011da177e4SLinus Torvalds
90021da177e4SLinus TorvaldsTWOMAIN:
90031da177e4SLinus Torvalds#--USUAL CASE, 2^(-70) <= |X| <= 16480
90041da177e4SLinus Torvalds
90051da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
90061da177e4SLinus Torvalds	fmul.s		&0x42800000,%fp1	# 64 * X
90071da177e4SLinus Torvalds	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
90081da177e4SLinus Torvalds	mov.l		%d2,-(%sp)
90091da177e4SLinus Torvalds	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
90101da177e4SLinus Torvalds	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
90111da177e4SLinus Torvalds	mov.l		INT(%a6),%d1
90121da177e4SLinus Torvalds	mov.l		%d1,%d2
90131da177e4SLinus Torvalds	and.l		&0x3F,%d1		# D0 IS J
90141da177e4SLinus Torvalds	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
90151da177e4SLinus Torvalds	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
90161da177e4SLinus Torvalds	asr.l		&6,%d2			# d2 IS L, N = 64L + J
90171da177e4SLinus Torvalds	mov.l		%d2,%d1
90181da177e4SLinus Torvalds	asr.l		&1,%d1			# D0 IS M
90191da177e4SLinus Torvalds	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
90201da177e4SLinus Torvalds	add.l		&0x3FFF,%d2
90211da177e4SLinus Torvalds
90221da177e4SLinus Torvalds#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
90231da177e4SLinus Torvalds#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
90241da177e4SLinus Torvalds#--ADJFACT = 2^(M').
90251da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
90261da177e4SLinus Torvalds
90271da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
90281da177e4SLinus Torvalds
90291da177e4SLinus Torvalds	fmul.s		&0x3C800000,%fp1	# (1/64)*N
90301da177e4SLinus Torvalds	mov.l		(%a1)+,FACT1(%a6)
90311da177e4SLinus Torvalds	mov.l		(%a1)+,FACT1HI(%a6)
90321da177e4SLinus Torvalds	mov.l		(%a1)+,FACT1LOW(%a6)
90331da177e4SLinus Torvalds	mov.w		(%a1)+,FACT2(%a6)
90341da177e4SLinus Torvalds
90351da177e4SLinus Torvalds	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
90361da177e4SLinus Torvalds
90371da177e4SLinus Torvalds	mov.w		(%a1)+,FACT2HI(%a6)
90381da177e4SLinus Torvalds	clr.w		FACT2HI+2(%a6)
90391da177e4SLinus Torvalds	clr.l		FACT2LOW(%a6)
90401da177e4SLinus Torvalds	add.w		%d1,FACT1(%a6)
90411da177e4SLinus Torvalds	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
90421da177e4SLinus Torvalds	add.w		%d1,FACT2(%a6)
90431da177e4SLinus Torvalds
90441da177e4SLinus Torvalds	bra.w		expr
90451da177e4SLinus Torvalds
90461da177e4SLinus TorvaldsEXPBORS:
90471da177e4SLinus Torvalds#--FPCR, D0 SAVED
90481da177e4SLinus Torvalds	cmp.l		%d1,&0x3FFF8000
90491da177e4SLinus Torvalds	bgt.b		TEXPBIG
90501da177e4SLinus Torvalds
90511da177e4SLinus Torvalds#--|X| IS SMALL, RETURN 1 + X
90521da177e4SLinus Torvalds
90531da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round prec,mode
90541da177e4SLinus Torvalds	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
90551da177e4SLinus Torvalds	bra		t_pinx2
90561da177e4SLinus Torvalds
90571da177e4SLinus TorvaldsTEXPBIG:
90581da177e4SLinus Torvalds#--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
90591da177e4SLinus Torvalds#--REGISTERS SAVE SO FAR ARE FPCR AND  D0
90601da177e4SLinus Torvalds	mov.l		X(%a6),%d1
90611da177e4SLinus Torvalds	cmp.l		%d1,&0
90621da177e4SLinus Torvalds	blt.b		EXPNEG
90631da177e4SLinus Torvalds
90641da177e4SLinus Torvalds	bra		t_ovfl2			# t_ovfl expects positive value
90651da177e4SLinus Torvalds
90661da177e4SLinus TorvaldsEXPNEG:
90671da177e4SLinus Torvalds	bra		t_unfl2			# t_unfl expects positive value
90681da177e4SLinus Torvalds
90691da177e4SLinus Torvalds	global		stwotoxd
90701da177e4SLinus Torvaldsstwotoxd:
90711da177e4SLinus Torvalds#--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
90721da177e4SLinus Torvalds
90731da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
90741da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
90751da177e4SLinus Torvalds	mov.l		(%a0),%d1
90761da177e4SLinus Torvalds	or.l		&0x00800001,%d1
90771da177e4SLinus Torvalds	fadd.s		%d1,%fp0
90781da177e4SLinus Torvalds	bra		t_pinx2
90791da177e4SLinus Torvalds
90801da177e4SLinus Torvalds	global		stentox
90811da177e4SLinus Torvalds#--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
90821da177e4SLinus Torvaldsstentox:
90831da177e4SLinus Torvalds	fmovm.x		(%a0),&0x80		# LOAD INPUT
90841da177e4SLinus Torvalds
90851da177e4SLinus Torvalds	mov.l		(%a0),%d1
90861da177e4SLinus Torvalds	mov.w		4(%a0),%d1
90871da177e4SLinus Torvalds	fmov.x		%fp0,X(%a6)
90881da177e4SLinus Torvalds	and.l		&0x7FFFFFFF,%d1
90891da177e4SLinus Torvalds
90901da177e4SLinus Torvalds	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
90911da177e4SLinus Torvalds	bge.b		TENOK1
90921da177e4SLinus Torvalds	bra.w		EXPBORS
90931da177e4SLinus Torvalds
90941da177e4SLinus TorvaldsTENOK1:
90951da177e4SLinus Torvalds	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
90961da177e4SLinus Torvalds	ble.b		TENMAIN
90971da177e4SLinus Torvalds	bra.w		EXPBORS
90981da177e4SLinus Torvalds
90991da177e4SLinus TorvaldsTENMAIN:
91001da177e4SLinus Torvalds#--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
91011da177e4SLinus Torvalds
91021da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
91031da177e4SLinus Torvalds	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
91041da177e4SLinus Torvalds	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
91051da177e4SLinus Torvalds	mov.l		%d2,-(%sp)
91061da177e4SLinus Torvalds	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
91071da177e4SLinus Torvalds	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
91081da177e4SLinus Torvalds	mov.l		INT(%a6),%d1
91091da177e4SLinus Torvalds	mov.l		%d1,%d2
91101da177e4SLinus Torvalds	and.l		&0x3F,%d1		# D0 IS J
91111da177e4SLinus Torvalds	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
91121da177e4SLinus Torvalds	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
91131da177e4SLinus Torvalds	asr.l		&6,%d2			# d2 IS L, N = 64L + J
91141da177e4SLinus Torvalds	mov.l		%d2,%d1
91151da177e4SLinus Torvalds	asr.l		&1,%d1			# D0 IS M
91161da177e4SLinus Torvalds	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
91171da177e4SLinus Torvalds	add.l		&0x3FFF,%d2
91181da177e4SLinus Torvalds
91191da177e4SLinus Torvalds#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
91201da177e4SLinus Torvalds#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
91211da177e4SLinus Torvalds#--ADJFACT = 2^(M').
91221da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
91231da177e4SLinus Torvalds	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
91241da177e4SLinus Torvalds
91251da177e4SLinus Torvalds	fmov.x		%fp1,%fp2
91261da177e4SLinus Torvalds
91271da177e4SLinus Torvalds	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
91281da177e4SLinus Torvalds	mov.l		(%a1)+,FACT1(%a6)
91291da177e4SLinus Torvalds
91301da177e4SLinus Torvalds	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
91311da177e4SLinus Torvalds
91321da177e4SLinus Torvalds	mov.l		(%a1)+,FACT1HI(%a6)
91331da177e4SLinus Torvalds	mov.l		(%a1)+,FACT1LOW(%a6)
91341da177e4SLinus Torvalds	fsub.x		%fp1,%fp0		# X - N L_LEAD
91351da177e4SLinus Torvalds	mov.w		(%a1)+,FACT2(%a6)
91361da177e4SLinus Torvalds
91371da177e4SLinus Torvalds	fsub.x		%fp2,%fp0		# X - N L_TRAIL
91381da177e4SLinus Torvalds
91391da177e4SLinus Torvalds	mov.w		(%a1)+,FACT2HI(%a6)
91401da177e4SLinus Torvalds	clr.w		FACT2HI+2(%a6)
91411da177e4SLinus Torvalds	clr.l		FACT2LOW(%a6)
91421da177e4SLinus Torvalds
91431da177e4SLinus Torvalds	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
91441da177e4SLinus Torvalds	add.w		%d1,FACT1(%a6)
91451da177e4SLinus Torvalds	add.w		%d1,FACT2(%a6)
91461da177e4SLinus Torvalds
91471da177e4SLinus Torvaldsexpr:
91481da177e4SLinus Torvalds#--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
91491da177e4SLinus Torvalds#--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
91501da177e4SLinus Torvalds#--FP0 IS R. THE FOLLOWING CODE COMPUTES
91511da177e4SLinus Torvalds#--	2**(M'+M) * 2**(J/64) * EXP(R)
91521da177e4SLinus Torvalds
91531da177e4SLinus Torvalds	fmov.x		%fp0,%fp1
91541da177e4SLinus Torvalds	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
91551da177e4SLinus Torvalds
91561da177e4SLinus Torvalds	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
91571da177e4SLinus Torvalds	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
91581da177e4SLinus Torvalds
91591da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# FP2 IS S*A5
91601da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# FP3 IS S*A4
91611da177e4SLinus Torvalds
91621da177e4SLinus Torvalds	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
91631da177e4SLinus Torvalds	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
91641da177e4SLinus Torvalds
91651da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
91661da177e4SLinus Torvalds	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
91671da177e4SLinus Torvalds
91681da177e4SLinus Torvalds	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
91691da177e4SLinus Torvalds	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
91701da177e4SLinus Torvalds
91711da177e4SLinus Torvalds	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
91721da177e4SLinus Torvalds	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
91731da177e4SLinus Torvalds	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
91741da177e4SLinus Torvalds
91751da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
91761da177e4SLinus Torvalds
91771da177e4SLinus Torvalds#--FINAL RECONSTRUCTION PROCESS
91781da177e4SLinus Torvalds#--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
91791da177e4SLinus Torvalds
91801da177e4SLinus Torvalds	fmul.x		FACT1(%a6),%fp0
91811da177e4SLinus Torvalds	fadd.x		FACT2(%a6),%fp0
91821da177e4SLinus Torvalds	fadd.x		FACT1(%a6),%fp0
91831da177e4SLinus Torvalds
91841da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# restore users round prec,mode
91851da177e4SLinus Torvalds	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
91861da177e4SLinus Torvalds	mov.l		(%sp)+,%d2
91871da177e4SLinus Torvalds	mov.l		&0x80000000,ADJFACT+4(%a6)
91881da177e4SLinus Torvalds	clr.l		ADJFACT+8(%a6)
91891da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
91901da177e4SLinus Torvalds	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
91911da177e4SLinus Torvalds	bra		t_catch
91921da177e4SLinus Torvalds
91931da177e4SLinus Torvalds	global		stentoxd
91941da177e4SLinus Torvaldsstentoxd:
91951da177e4SLinus Torvalds#--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
91961da177e4SLinus Torvalds
91971da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
91981da177e4SLinus Torvalds	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
91991da177e4SLinus Torvalds	mov.l		(%a0),%d1
92001da177e4SLinus Torvalds	or.l		&0x00800001,%d1
92011da177e4SLinus Torvalds	fadd.s		%d1,%fp0
92021da177e4SLinus Torvalds	bra		t_pinx2
92031da177e4SLinus Torvalds
92041da177e4SLinus Torvalds#########################################################################
92051da177e4SLinus Torvalds# sscale(): computes the destination operand scaled by the source	#
92061da177e4SLinus Torvalds#	    operand. If the absoulute value of the source operand is	#
92071da177e4SLinus Torvalds#	    >= 2^14, an overflow or underflow is returned.		#
92081da177e4SLinus Torvalds#									#
92091da177e4SLinus Torvalds# INPUT *************************************************************** #
92101da177e4SLinus Torvalds#	a0  = pointer to double-extended source operand X		#
92111da177e4SLinus Torvalds#	a1  = pointer to double-extended destination operand Y		#
92121da177e4SLinus Torvalds#									#
92131da177e4SLinus Torvalds# OUTPUT ************************************************************** #
92141da177e4SLinus Torvalds#	fp0 =  scale(X,Y)						#
92151da177e4SLinus Torvalds#									#
92161da177e4SLinus Torvalds#########################################################################
92171da177e4SLinus Torvalds
92181da177e4SLinus Torvaldsset	SIGN,		L_SCR1
92191da177e4SLinus Torvalds
92201da177e4SLinus Torvalds	global		sscale
92211da177e4SLinus Torvaldssscale:
92221da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# store off ctrl bits for now
92231da177e4SLinus Torvalds
92241da177e4SLinus Torvalds	mov.w		DST_EX(%a1),%d1		# get dst exponent
92251da177e4SLinus Torvalds	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
92261da177e4SLinus Torvalds	andi.l		&0x00007fff,%d1		# strip sign from dst exp
92271da177e4SLinus Torvalds
92281da177e4SLinus Torvalds	mov.w		SRC_EX(%a0),%d0		# check src bounds
92291da177e4SLinus Torvalds	andi.w		&0x7fff,%d0		# clr src sign bit
92301da177e4SLinus Torvalds	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
92311da177e4SLinus Torvalds	blt.w		src_small		# yes
92321da177e4SLinus Torvalds	cmpi.w		%d0,&0x400c		# no; is src too big?
92331da177e4SLinus Torvalds	bgt.w		src_out			# yes
92341da177e4SLinus Torvalds
92351da177e4SLinus Torvalds#
92361da177e4SLinus Torvalds# Source is within 2^14 range.
92371da177e4SLinus Torvalds#
92381da177e4SLinus Torvaldssrc_ok:
92391da177e4SLinus Torvalds	fintrz.x	SRC(%a0),%fp0		# calc int of src
92401da177e4SLinus Torvalds	fmov.l		%fp0,%d0		# int src to d0
92411da177e4SLinus Torvalds# don't want any accrued bits from the fintrz showing up later since
92421da177e4SLinus Torvalds# we may need to read the fpsr for the last fp op in t_catch2().
92431da177e4SLinus Torvalds	fmov.l		&0x0,%fpsr
92441da177e4SLinus Torvalds
92451da177e4SLinus Torvalds	tst.b		DST_HI(%a1)		# is dst denormalized?
92461da177e4SLinus Torvalds	bmi.b		sok_norm
92471da177e4SLinus Torvalds
92481da177e4SLinus Torvalds# the dst is a DENORM. normalize the DENORM and add the adjustment to
92491da177e4SLinus Torvalds# the src value. then, jump to the norm part of the routine.
92501da177e4SLinus Torvaldssok_dnrm:
92511da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save src for now
92521da177e4SLinus Torvalds
92531da177e4SLinus Torvalds	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
92541da177e4SLinus Torvalds	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
92551da177e4SLinus Torvalds	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
92561da177e4SLinus Torvalds
92571da177e4SLinus Torvalds	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
92581da177e4SLinus Torvalds	bsr.l		norm			# normalize the DENORM
92591da177e4SLinus Torvalds	neg.l		%d0
92601da177e4SLinus Torvalds	add.l		(%sp)+,%d0		# add adjustment to src
92611da177e4SLinus Torvalds
92621da177e4SLinus Torvalds	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
92631da177e4SLinus Torvalds
92641da177e4SLinus Torvalds	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
92651da177e4SLinus Torvalds	bge.b		sok_norm2		# thank goodness no
92661da177e4SLinus Torvalds
92671da177e4SLinus Torvalds# the multiply factor that we're trying to create should be a denorm
92681da177e4SLinus Torvalds# for the multiply to work. therefore, we're going to actually do a
92691da177e4SLinus Torvalds# multiply with a denorm which will cause an unimplemented data type
92701da177e4SLinus Torvalds# exception to be put into the machine which will be caught and corrected
92711da177e4SLinus Torvalds# later. we don't do this with the DENORMs above because this method
92721da177e4SLinus Torvalds# is slower. but, don't fret, I don't see it being used much either.
92731da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore user fpcr
92741da177e4SLinus Torvalds	mov.l		&0x80000000,%d1		# load normalized mantissa
92751da177e4SLinus Torvalds	subi.l		&-0x3fff,%d0		# how many should we shift?
92761da177e4SLinus Torvalds	neg.l		%d0			# make it positive
92771da177e4SLinus Torvalds	cmpi.b		%d0,&0x20		# is it > 32?
92781da177e4SLinus Torvalds	bge.b		sok_dnrm_32		# yes
92791da177e4SLinus Torvalds	lsr.l		%d0,%d1			# no; bit stays in upper lw
92801da177e4SLinus Torvalds	clr.l		-(%sp)			# insert zero low mantissa
92811da177e4SLinus Torvalds	mov.l		%d1,-(%sp)		# insert new high mantissa
92821da177e4SLinus Torvalds	clr.l		-(%sp)			# make zero exponent
92831da177e4SLinus Torvalds	bra.b		sok_norm_cont
92841da177e4SLinus Torvaldssok_dnrm_32:
92851da177e4SLinus Torvalds	subi.b		&0x20,%d0		# get shift count
92861da177e4SLinus Torvalds	lsr.l		%d0,%d1			# make low mantissa longword
92871da177e4SLinus Torvalds	mov.l		%d1,-(%sp)		# insert new low mantissa
92881da177e4SLinus Torvalds	clr.l		-(%sp)			# insert zero high mantissa
92891da177e4SLinus Torvalds	clr.l		-(%sp)			# make zero exponent
92901da177e4SLinus Torvalds	bra.b		sok_norm_cont
92911da177e4SLinus Torvalds
92921da177e4SLinus Torvalds# the src will force the dst to a DENORM value or worse. so, let's
92931da177e4SLinus Torvalds# create an fp multiply that will create the result.
92941da177e4SLinus Torvaldssok_norm:
92951da177e4SLinus Torvalds	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
92961da177e4SLinus Torvaldssok_norm2:
92971da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore user fpcr
92981da177e4SLinus Torvalds
92991da177e4SLinus Torvalds	addi.w		&0x3fff,%d0		# turn src amt into exp value
93001da177e4SLinus Torvalds	swap		%d0			# put exponent in high word
93011da177e4SLinus Torvalds	clr.l		-(%sp)			# insert new exponent
93021da177e4SLinus Torvalds	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
93031da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# insert new lo mantissa
93041da177e4SLinus Torvalds
93051da177e4SLinus Torvaldssok_norm_cont:
93061da177e4SLinus Torvalds	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
93071da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
93081da177e4SLinus Torvalds	fmul.x		(%sp)+,%fp0		# do the multiply
93091da177e4SLinus Torvalds	bra		t_catch2		# catch any exceptions
93101da177e4SLinus Torvalds
93111da177e4SLinus Torvalds#
93121da177e4SLinus Torvalds# Source is outside of 2^14 range.  Test the sign and branch
93131da177e4SLinus Torvalds# to the appropriate exception handler.
93141da177e4SLinus Torvalds#
93151da177e4SLinus Torvaldssrc_out:
93161da177e4SLinus Torvalds	mov.l		(%sp)+,%d0		# restore ctrl bits
93171da177e4SLinus Torvalds	exg		%a0,%a1			# swap src,dst ptrs
93181da177e4SLinus Torvalds	tst.b		SRC_EX(%a1)		# is src negative?
93191da177e4SLinus Torvalds	bmi		t_unfl			# yes; underflow
93201da177e4SLinus Torvalds	bra		t_ovfl_sc		# no; overflow
93211da177e4SLinus Torvalds
93221da177e4SLinus Torvalds#
93231da177e4SLinus Torvalds# The source input is below 1, so we check for denormalized numbers
93241da177e4SLinus Torvalds# and set unfl.
93251da177e4SLinus Torvalds#
93261da177e4SLinus Torvaldssrc_small:
93271da177e4SLinus Torvalds	tst.b		DST_HI(%a1)		# is dst denormalized?
93281da177e4SLinus Torvalds	bpl.b		ssmall_done		# yes
93291da177e4SLinus Torvalds
93301da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
93311da177e4SLinus Torvalds	fmov.l		%d0,%fpcr		# no; load control bits
93321da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
93331da177e4SLinus Torvalds	fmov.x		DST(%a1),%fp0		# simply return dest
93341da177e4SLinus Torvalds	bra		t_catch2
93351da177e4SLinus Torvaldsssmall_done:
93361da177e4SLinus Torvalds	mov.l		(%sp)+,%d0		# load control bits into d1
93371da177e4SLinus Torvalds	mov.l		%a1,%a0			# pass ptr to dst
93381da177e4SLinus Torvalds	bra		t_resdnrm
93391da177e4SLinus Torvalds
93401da177e4SLinus Torvalds#########################################################################
93411da177e4SLinus Torvalds# smod(): computes the fp MOD of the input values X,Y.			#
93421da177e4SLinus Torvalds# srem(): computes the fp (IEEE) REM of the input values X,Y.		#
93431da177e4SLinus Torvalds#									#
93441da177e4SLinus Torvalds# INPUT *************************************************************** #
93451da177e4SLinus Torvalds#	a0 = pointer to extended precision input X			#
93461da177e4SLinus Torvalds#	a1 = pointer to extended precision input Y			#
93471da177e4SLinus Torvalds#	d0 = round precision,mode					#
93481da177e4SLinus Torvalds#									#
93491da177e4SLinus Torvalds#	The input operands X and Y can be either normalized or		#
93501da177e4SLinus Torvalds#	denormalized.							#
93511da177e4SLinus Torvalds#									#
93521da177e4SLinus Torvalds# OUTPUT ************************************************************** #
93531da177e4SLinus Torvalds#      fp0 = FREM(X,Y) or FMOD(X,Y)					#
93541da177e4SLinus Torvalds#									#
93551da177e4SLinus Torvalds# ALGORITHM *********************************************************** #
93561da177e4SLinus Torvalds#									#
93571da177e4SLinus Torvalds#       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
93581da177e4SLinus Torvalds#                signY := sign(Y), X := |X|, Y := |Y|,			#
93591da177e4SLinus Torvalds#                signQ := signX EOR signY. Record whether MOD or REM	#
93601da177e4SLinus Torvalds#                is requested.						#
93611da177e4SLinus Torvalds#									#
93621da177e4SLinus Torvalds#       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
93631da177e4SLinus Torvalds#                If (L < 0) then					#
93641da177e4SLinus Torvalds#                   R := X, go to Step 4.				#
93651da177e4SLinus Torvalds#                else							#
93661da177e4SLinus Torvalds#                   R := 2^(-L)X, j := L.				#
93671da177e4SLinus Torvalds#                endif							#
93681da177e4SLinus Torvalds#									#
93691da177e4SLinus Torvalds#       Step 3.  Perform MOD(X,Y)					#
93701da177e4SLinus Torvalds#            3.1 If R = Y, go to Step 9.				#
93711da177e4SLinus Torvalds#            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
93721da177e4SLinus Torvalds#            3.3 If j = 0, go to Step 4.				#
93731da177e4SLinus Torvalds#            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
93741da177e4SLinus Torvalds#                Step 3.1.						#
93751da177e4SLinus Torvalds#									#
93761da177e4SLinus Torvalds#       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
93771da177e4SLinus Torvalds#                Last_Subtract := false (used in Step 7 below). If	#
93781da177e4SLinus Torvalds#                MOD is requested, go to Step 6.			#
93791da177e4SLinus Torvalds#									#
93801da177e4SLinus Torvalds#       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
93811da177e4SLinus Torvalds#            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
93821da177e4SLinus Torvalds#                Step 6.						#
93831da177e4SLinus Torvalds#            5.2 If R > Y/2, then { set Last_Subtract := true,		#
93841da177e4SLinus Torvalds#                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
93851da177e4SLinus Torvalds#            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
93861da177e4SLinus Torvalds#                then { Q := Q + 1, signX := -signX }.			#
93871da177e4SLinus Torvalds#									#
93881da177e4SLinus Torvalds#       Step 6.  R := signX*R.						#
93891da177e4SLinus Torvalds#									#
93901da177e4SLinus Torvalds#       Step 7.  If Last_Subtract = true, R := R - Y.			#
93911da177e4SLinus Torvalds#									#
93921da177e4SLinus Torvalds#       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
93931da177e4SLinus Torvalds#									#
93941da177e4SLinus Torvalds#       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
93951da177e4SLinus Torvalds#                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
93961da177e4SLinus Torvalds#                R := 0. Return signQ, last 7 bits of Q, and R.		#
93971da177e4SLinus Torvalds#									#
93981da177e4SLinus Torvalds#########################################################################
93991da177e4SLinus Torvalds
94001da177e4SLinus Torvalds	set		Mod_Flag,L_SCR3
94011da177e4SLinus Torvalds	set		Sc_Flag,L_SCR3+1
94021da177e4SLinus Torvalds
94031da177e4SLinus Torvalds	set		SignY,L_SCR2
94041da177e4SLinus Torvalds	set		SignX,L_SCR2+2
94051da177e4SLinus Torvalds	set		SignQ,L_SCR3+2
94061da177e4SLinus Torvalds
94071da177e4SLinus Torvalds	set		Y,FP_SCR0
94081da177e4SLinus Torvalds	set		Y_Hi,Y+4
94091da177e4SLinus Torvalds	set		Y_Lo,Y+8
94101da177e4SLinus Torvalds
94111da177e4SLinus Torvalds	set		R,FP_SCR1
94121da177e4SLinus Torvalds	set		R_Hi,R+4
94131da177e4SLinus Torvalds	set		R_Lo,R+8
94141da177e4SLinus Torvalds
94151da177e4SLinus TorvaldsScale:
94161da177e4SLinus Torvalds	long		0x00010000,0x80000000,0x00000000,0x00000000
94171da177e4SLinus Torvalds
94181da177e4SLinus Torvalds	global		smod
94191da177e4SLinus Torvaldssmod:
94201da177e4SLinus Torvalds	clr.b		FPSR_QBYTE(%a6)
94211da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save ctrl bits
94221da177e4SLinus Torvalds	clr.b		Mod_Flag(%a6)
94231da177e4SLinus Torvalds	bra.b		Mod_Rem
94241da177e4SLinus Torvalds
94251da177e4SLinus Torvalds	global		srem
94261da177e4SLinus Torvaldssrem:
94271da177e4SLinus Torvalds	clr.b		FPSR_QBYTE(%a6)
94281da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save ctrl bits
94291da177e4SLinus Torvalds	mov.b		&0x1,Mod_Flag(%a6)
94301da177e4SLinus Torvalds
94311da177e4SLinus TorvaldsMod_Rem:
94321da177e4SLinus Torvalds#..Save sign of X and Y
94331da177e4SLinus Torvalds	movm.l		&0x3f00,-(%sp)		# save data registers
94341da177e4SLinus Torvalds	mov.w		SRC_EX(%a0),%d3
94351da177e4SLinus Torvalds	mov.w		%d3,SignY(%a6)
94361da177e4SLinus Torvalds	and.l		&0x00007FFF,%d3		# Y := |Y|
94371da177e4SLinus Torvalds
94381da177e4SLinus Torvalds#
94391da177e4SLinus Torvalds	mov.l		SRC_HI(%a0),%d4
94401da177e4SLinus Torvalds	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
94411da177e4SLinus Torvalds
94421da177e4SLinus Torvalds	tst.l		%d3
94431da177e4SLinus Torvalds	bne.b		Y_Normal
94441da177e4SLinus Torvalds
94451da177e4SLinus Torvalds	mov.l		&0x00003FFE,%d3		# $3FFD + 1
94461da177e4SLinus Torvalds	tst.l		%d4
94471da177e4SLinus Torvalds	bne.b		HiY_not0
94481da177e4SLinus Torvalds
94491da177e4SLinus TorvaldsHiY_0:
94501da177e4SLinus Torvalds	mov.l		%d5,%d4
94511da177e4SLinus Torvalds	clr.l		%d5
94521da177e4SLinus Torvalds	sub.l		&32,%d3
94531da177e4SLinus Torvalds	clr.l		%d6
94541da177e4SLinus Torvalds	bfffo		%d4{&0:&32},%d6
94551da177e4SLinus Torvalds	lsl.l		%d6,%d4
94561da177e4SLinus Torvalds	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
94571da177e4SLinus Torvalds#	                                        ...with bias $7FFD
94581da177e4SLinus Torvalds	bra.b		Chk_X
94591da177e4SLinus Torvalds
94601da177e4SLinus TorvaldsHiY_not0:
94611da177e4SLinus Torvalds	clr.l		%d6
94621da177e4SLinus Torvalds	bfffo		%d4{&0:&32},%d6
94631da177e4SLinus Torvalds	sub.l		%d6,%d3
94641da177e4SLinus Torvalds	lsl.l		%d6,%d4
94651da177e4SLinus Torvalds	mov.l		%d5,%d7			# a copy of D5
94661da177e4SLinus Torvalds	lsl.l		%d6,%d5
94671da177e4SLinus Torvalds	neg.l		%d6
94681da177e4SLinus Torvalds	add.l		&32,%d6
94691da177e4SLinus Torvalds	lsr.l		%d6,%d7
94701da177e4SLinus Torvalds	or.l		%d7,%d4			# (D3,D4,D5) normalized
94711da177e4SLinus Torvalds#                                       ...with bias $7FFD
94721da177e4SLinus Torvalds	bra.b		Chk_X
94731da177e4SLinus Torvalds
94741da177e4SLinus TorvaldsY_Normal:
94751da177e4SLinus Torvalds	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
94761da177e4SLinus Torvalds#                                       ...with bias $7FFD
94771da177e4SLinus Torvalds
94781da177e4SLinus TorvaldsChk_X:
94791da177e4SLinus Torvalds	mov.w		DST_EX(%a1),%d0
94801da177e4SLinus Torvalds	mov.w		%d0,SignX(%a6)
94811da177e4SLinus Torvalds	mov.w		SignY(%a6),%d1
94821da177e4SLinus Torvalds	eor.l		%d0,%d1
94831da177e4SLinus Torvalds	and.l		&0x00008000,%d1
94841da177e4SLinus Torvalds	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
94851da177e4SLinus Torvalds	and.l		&0x00007FFF,%d0
94861da177e4SLinus Torvalds	mov.l		DST_HI(%a1),%d1
94871da177e4SLinus Torvalds	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
94881da177e4SLinus Torvalds	tst.l		%d0
94891da177e4SLinus Torvalds	bne.b		X_Normal
94901da177e4SLinus Torvalds	mov.l		&0x00003FFE,%d0
94911da177e4SLinus Torvalds	tst.l		%d1
94921da177e4SLinus Torvalds	bne.b		HiX_not0
94931da177e4SLinus Torvalds
94941da177e4SLinus TorvaldsHiX_0:
94951da177e4SLinus Torvalds	mov.l		%d2,%d1
94961da177e4SLinus Torvalds	clr.l		%d2
94971da177e4SLinus Torvalds	sub.l		&32,%d0
94981da177e4SLinus Torvalds	clr.l		%d6
94991da177e4SLinus Torvalds	bfffo		%d1{&0:&32},%d6
95001da177e4SLinus Torvalds	lsl.l		%d6,%d1
95011da177e4SLinus Torvalds	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
95021da177e4SLinus Torvalds#                                       ...with bias $7FFD
95031da177e4SLinus Torvalds	bra.b		Init
95041da177e4SLinus Torvalds
95051da177e4SLinus TorvaldsHiX_not0:
95061da177e4SLinus Torvalds	clr.l		%d6
95071da177e4SLinus Torvalds	bfffo		%d1{&0:&32},%d6
95081da177e4SLinus Torvalds	sub.l		%d6,%d0
95091da177e4SLinus Torvalds	lsl.l		%d6,%d1
95101da177e4SLinus Torvalds	mov.l		%d2,%d7			# a copy of D2
95111da177e4SLinus Torvalds	lsl.l		%d6,%d2
95121da177e4SLinus Torvalds	neg.l		%d6
95131da177e4SLinus Torvalds	add.l		&32,%d6
95141da177e4SLinus Torvalds	lsr.l		%d6,%d7
95151da177e4SLinus Torvalds	or.l		%d7,%d1			# (D0,D1,D2) normalized
95161da177e4SLinus Torvalds#                                       ...with bias $7FFD
95171da177e4SLinus Torvalds	bra.b		Init
95181da177e4SLinus Torvalds
95191da177e4SLinus TorvaldsX_Normal:
95201da177e4SLinus Torvalds	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
95211da177e4SLinus Torvalds#                                       ...with bias $7FFD
95221da177e4SLinus Torvalds
95231da177e4SLinus TorvaldsInit:
95241da177e4SLinus Torvalds#
95251da177e4SLinus Torvalds	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
95261da177e4SLinus Torvalds	mov.l		%d0,-(%sp)		# save biased exp(X)
95271da177e4SLinus Torvalds	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
95281da177e4SLinus Torvalds
95291da177e4SLinus Torvalds	clr.l		%d6			# D6 := carry <- 0
95301da177e4SLinus Torvalds	clr.l		%d3			# D3 is Q
95311da177e4SLinus Torvalds	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
95321da177e4SLinus Torvalds
95331da177e4SLinus Torvalds#..(Carry,D1,D2) is R
95341da177e4SLinus Torvalds	tst.l		%d0
95351da177e4SLinus Torvalds	bge.b		Mod_Loop_pre
95361da177e4SLinus Torvalds
95371da177e4SLinus Torvalds#..expo(X) < expo(Y). Thus X = mod(X,Y)
95381da177e4SLinus Torvalds#
95391da177e4SLinus Torvalds	mov.l		(%sp)+,%d0		# restore d0
95401da177e4SLinus Torvalds	bra.w		Get_Mod
95411da177e4SLinus Torvalds
95421da177e4SLinus TorvaldsMod_Loop_pre:
95431da177e4SLinus Torvalds	addq.l		&0x4,%sp		# erase exp(X)
95441da177e4SLinus Torvalds#..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
95451da177e4SLinus TorvaldsMod_Loop:
95461da177e4SLinus Torvalds	tst.l		%d6			# test carry bit
95471da177e4SLinus Torvalds	bgt.b		R_GT_Y
95481da177e4SLinus Torvalds
95491da177e4SLinus Torvalds#..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
95501da177e4SLinus Torvalds	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
95511da177e4SLinus Torvalds	bne.b		R_NE_Y
95521da177e4SLinus Torvalds	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
95531da177e4SLinus Torvalds	bne.b		R_NE_Y
95541da177e4SLinus Torvalds
95551da177e4SLinus Torvalds#..At this point, R = Y
95561da177e4SLinus Torvalds	bra.w		Rem_is_0
95571da177e4SLinus Torvalds
95581da177e4SLinus TorvaldsR_NE_Y:
95591da177e4SLinus Torvalds#..use the borrow of the previous compare
95601da177e4SLinus Torvalds	bcs.b		R_LT_Y			# borrow is set iff R < Y
95611da177e4SLinus Torvalds
95621da177e4SLinus TorvaldsR_GT_Y:
95631da177e4SLinus Torvalds#..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
95641da177e4SLinus Torvalds#..and Y < (D1,D2) < 2Y. Either way, perform R - Y
95651da177e4SLinus Torvalds	sub.l		%d5,%d2			# lo(R) - lo(Y)
95661da177e4SLinus Torvalds	subx.l		%d4,%d1			# hi(R) - hi(Y)
95671da177e4SLinus Torvalds	clr.l		%d6			# clear carry
95681da177e4SLinus Torvalds	addq.l		&1,%d3			# Q := Q + 1
95691da177e4SLinus Torvalds
95701da177e4SLinus TorvaldsR_LT_Y:
95711da177e4SLinus Torvalds#..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
95721da177e4SLinus Torvalds	tst.l		%d0			# see if j = 0.
95731da177e4SLinus Torvalds	beq.b		PostLoop
95741da177e4SLinus Torvalds
95751da177e4SLinus Torvalds	add.l		%d3,%d3			# Q := 2Q
95761da177e4SLinus Torvalds	add.l		%d2,%d2			# lo(R) = 2lo(R)
95771da177e4SLinus Torvalds	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
95781da177e4SLinus Torvalds	scs		%d6			# set Carry if 2(R) overflows
95791da177e4SLinus Torvalds	addq.l		&1,%a1			# k := k+1
95801da177e4SLinus Torvalds	subq.l		&1,%d0			# j := j - 1
95811da177e4SLinus Torvalds#..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
95821da177e4SLinus Torvalds
95831da177e4SLinus Torvalds	bra.b		Mod_Loop
95841da177e4SLinus Torvalds
95851da177e4SLinus TorvaldsPostLoop:
95861da177e4SLinus Torvalds#..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
95871da177e4SLinus Torvalds
95881da177e4SLinus Torvalds#..normalize R.
95891da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
95901da177e4SLinus Torvalds	tst.l		%d1
95911da177e4SLinus Torvalds	bne.b		HiR_not0
95921da177e4SLinus Torvalds
95931da177e4SLinus TorvaldsHiR_0:
95941da177e4SLinus Torvalds	mov.l		%d2,%d1
95951da177e4SLinus Torvalds	clr.l		%d2
95961da177e4SLinus Torvalds	sub.l		&32,%d0
95971da177e4SLinus Torvalds	clr.l		%d6
95981da177e4SLinus Torvalds	bfffo		%d1{&0:&32},%d6
95991da177e4SLinus Torvalds	lsl.l		%d6,%d1
96001da177e4SLinus Torvalds	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
96011da177e4SLinus Torvalds#                                       ...with bias $7FFD
96021da177e4SLinus Torvalds	bra.b		Get_Mod
96031da177e4SLinus Torvalds
96041da177e4SLinus TorvaldsHiR_not0:
96051da177e4SLinus Torvalds	clr.l		%d6
96061da177e4SLinus Torvalds	bfffo		%d1{&0:&32},%d6
96071da177e4SLinus Torvalds	bmi.b		Get_Mod			# already normalized
96081da177e4SLinus Torvalds	sub.l		%d6,%d0
96091da177e4SLinus Torvalds	lsl.l		%d6,%d1
96101da177e4SLinus Torvalds	mov.l		%d2,%d7			# a copy of D2
96111da177e4SLinus Torvalds	lsl.l		%d6,%d2
96121da177e4SLinus Torvalds	neg.l		%d6
96131da177e4SLinus Torvalds	add.l		&32,%d6
96141da177e4SLinus Torvalds	lsr.l		%d6,%d7
96151da177e4SLinus Torvalds	or.l		%d7,%d1			# (D0,D1,D2) normalized
96161da177e4SLinus Torvalds
96171da177e4SLinus Torvalds#
96181da177e4SLinus TorvaldsGet_Mod:
96191da177e4SLinus Torvalds	cmp.l		%d0,&0x000041FE
96201da177e4SLinus Torvalds	bge.b		No_Scale
96211da177e4SLinus TorvaldsDo_Scale:
96221da177e4SLinus Torvalds	mov.w		%d0,R(%a6)
96231da177e4SLinus Torvalds	mov.l		%d1,R_Hi(%a6)
96241da177e4SLinus Torvalds	mov.l		%d2,R_Lo(%a6)
96251da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d6
96261da177e4SLinus Torvalds	mov.w		%d6,Y(%a6)
96271da177e4SLinus Torvalds	mov.l		%d4,Y_Hi(%a6)
96281da177e4SLinus Torvalds	mov.l		%d5,Y_Lo(%a6)
96291da177e4SLinus Torvalds	fmov.x		R(%a6),%fp0		# no exception
96301da177e4SLinus Torvalds	mov.b		&1,Sc_Flag(%a6)
96311da177e4SLinus Torvalds	bra.b		ModOrRem
96321da177e4SLinus TorvaldsNo_Scale:
96331da177e4SLinus Torvalds	mov.l		%d1,R_Hi(%a6)
96341da177e4SLinus Torvalds	mov.l		%d2,R_Lo(%a6)
96351da177e4SLinus Torvalds	sub.l		&0x3FFE,%d0
96361da177e4SLinus Torvalds	mov.w		%d0,R(%a6)
96371da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d6
96381da177e4SLinus Torvalds	sub.l		&0x3FFE,%d6
96391da177e4SLinus Torvalds	mov.l		%d6,L_SCR1(%a6)
96401da177e4SLinus Torvalds	fmov.x		R(%a6),%fp0
96411da177e4SLinus Torvalds	mov.w		%d6,Y(%a6)
96421da177e4SLinus Torvalds	mov.l		%d4,Y_Hi(%a6)
96431da177e4SLinus Torvalds	mov.l		%d5,Y_Lo(%a6)
96441da177e4SLinus Torvalds	clr.b		Sc_Flag(%a6)
96451da177e4SLinus Torvalds
96461da177e4SLinus Torvalds#
96471da177e4SLinus TorvaldsModOrRem:
96481da177e4SLinus Torvalds	tst.b		Mod_Flag(%a6)
96491da177e4SLinus Torvalds	beq.b		Fix_Sign
96501da177e4SLinus Torvalds
96511da177e4SLinus Torvalds	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
96521da177e4SLinus Torvalds	subq.l		&1,%d6			# biased expo(Y/2)
96531da177e4SLinus Torvalds	cmp.l		%d0,%d6
96541da177e4SLinus Torvalds	blt.b		Fix_Sign
96551da177e4SLinus Torvalds	bgt.b		Last_Sub
96561da177e4SLinus Torvalds
96571da177e4SLinus Torvalds	cmp.l		%d1,%d4
96581da177e4SLinus Torvalds	bne.b		Not_EQ
96591da177e4SLinus Torvalds	cmp.l		%d2,%d5
96601da177e4SLinus Torvalds	bne.b		Not_EQ
96611da177e4SLinus Torvalds	bra.w		Tie_Case
96621da177e4SLinus Torvalds
96631da177e4SLinus TorvaldsNot_EQ:
96641da177e4SLinus Torvalds	bcs.b		Fix_Sign
96651da177e4SLinus Torvalds
96661da177e4SLinus TorvaldsLast_Sub:
96671da177e4SLinus Torvalds#
96681da177e4SLinus Torvalds	fsub.x		Y(%a6),%fp0		# no exceptions
96691da177e4SLinus Torvalds	addq.l		&1,%d3			# Q := Q + 1
96701da177e4SLinus Torvalds
96711da177e4SLinus Torvalds#
96721da177e4SLinus TorvaldsFix_Sign:
96731da177e4SLinus Torvalds#..Get sign of X
96741da177e4SLinus Torvalds	mov.w		SignX(%a6),%d6
96751da177e4SLinus Torvalds	bge.b		Get_Q
96761da177e4SLinus Torvalds	fneg.x		%fp0
96771da177e4SLinus Torvalds
96781da177e4SLinus Torvalds#..Get Q
96791da177e4SLinus Torvalds#
96801da177e4SLinus TorvaldsGet_Q:
96811da177e4SLinus Torvalds	clr.l		%d6
96821da177e4SLinus Torvalds	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
96831da177e4SLinus Torvalds	mov.l		&8,%d7
96841da177e4SLinus Torvalds	lsr.l		%d7,%d6
96851da177e4SLinus Torvalds	and.l		&0x0000007F,%d3		# 7 bits of Q
96861da177e4SLinus Torvalds	or.l		%d6,%d3			# sign and bits of Q
96871da177e4SLinus Torvalds#	swap		%d3
96881da177e4SLinus Torvalds#	fmov.l		%fpsr,%d6
96891da177e4SLinus Torvalds#	and.l		&0xFF00FFFF,%d6
96901da177e4SLinus Torvalds#	or.l		%d3,%d6
96911da177e4SLinus Torvalds#	fmov.l		%d6,%fpsr		# put Q in fpsr
96921da177e4SLinus Torvalds	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
96931da177e4SLinus Torvalds
96941da177e4SLinus Torvalds#
96951da177e4SLinus TorvaldsRestore:
96961da177e4SLinus Torvalds	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
96971da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
96981da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
96991da177e4SLinus Torvalds	tst.b		Sc_Flag(%a6)
97001da177e4SLinus Torvalds	beq.b		Finish
97011da177e4SLinus Torvalds	mov.b		&FMUL_OP,%d1		# last inst is MUL
97021da177e4SLinus Torvalds	fmul.x		Scale(%pc),%fp0		# may cause underflow
97031da177e4SLinus Torvalds	bra		t_catch2
97041da177e4SLinus Torvalds# the '040 package did this apparently to see if the dst operand for the
97051da177e4SLinus Torvalds# preceding fmul was a denorm. but, it better not have been since the
97061da177e4SLinus Torvalds# algorithm just got done playing with fp0 and expected no exceptions
97071da177e4SLinus Torvalds# as a result. trust me...
97081da177e4SLinus Torvalds#	bra		t_avoid_unsupp		# check for denorm as a
97091da177e4SLinus Torvalds#						;result of the scaling
97101da177e4SLinus Torvalds
97111da177e4SLinus TorvaldsFinish:
97121da177e4SLinus Torvalds	mov.b		&FMOV_OP,%d1		# last inst is MOVE
97131da177e4SLinus Torvalds	fmov.x		%fp0,%fp0		# capture exceptions & round
97141da177e4SLinus Torvalds	bra		t_catch2
97151da177e4SLinus Torvalds
97161da177e4SLinus TorvaldsRem_is_0:
97171da177e4SLinus Torvalds#..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
97181da177e4SLinus Torvalds	addq.l		&1,%d3
97191da177e4SLinus Torvalds	cmp.l		%d0,&8			# D0 is j
97201da177e4SLinus Torvalds	bge.b		Q_Big
97211da177e4SLinus Torvalds
97221da177e4SLinus Torvalds	lsl.l		%d0,%d3
97231da177e4SLinus Torvalds	bra.b		Set_R_0
97241da177e4SLinus Torvalds
97251da177e4SLinus TorvaldsQ_Big:
97261da177e4SLinus Torvalds	clr.l		%d3
97271da177e4SLinus Torvalds
97281da177e4SLinus TorvaldsSet_R_0:
97291da177e4SLinus Torvalds	fmov.s		&0x00000000,%fp0
97301da177e4SLinus Torvalds	clr.b		Sc_Flag(%a6)
97311da177e4SLinus Torvalds	bra.w		Fix_Sign
97321da177e4SLinus Torvalds
97331da177e4SLinus TorvaldsTie_Case:
97341da177e4SLinus Torvalds#..Check parity of Q
97351da177e4SLinus Torvalds	mov.l		%d3,%d6
97361da177e4SLinus Torvalds	and.l		&0x00000001,%d6
97371da177e4SLinus Torvalds	tst.l		%d6
97381da177e4SLinus Torvalds	beq.w		Fix_Sign		# Q is even
97391da177e4SLinus Torvalds
97401da177e4SLinus Torvalds#..Q is odd, Q := Q + 1, signX := -signX
97411da177e4SLinus Torvalds	addq.l		&1,%d3
97421da177e4SLinus Torvalds	mov.w		SignX(%a6),%d6
97431da177e4SLinus Torvalds	eor.l		&0x00008000,%d6
97441da177e4SLinus Torvalds	mov.w		%d6,SignX(%a6)
97451da177e4SLinus Torvalds	bra.w		Fix_Sign
97461da177e4SLinus Torvalds
97471da177e4SLinus Torvalds#########################################################################
97481da177e4SLinus Torvalds# XDEF ****************************************************************	#
97491da177e4SLinus Torvalds#	tag(): return the optype of the input ext fp number		#
97501da177e4SLinus Torvalds#									#
97511da177e4SLinus Torvalds#	This routine is used by the 060FPLSP.				#
97521da177e4SLinus Torvalds#									#
97531da177e4SLinus Torvalds# XREF ****************************************************************	#
97541da177e4SLinus Torvalds#	None								#
97551da177e4SLinus Torvalds#									#
97561da177e4SLinus Torvalds# INPUT ***************************************************************	#
97571da177e4SLinus Torvalds#	a0 = pointer to extended precision operand			#
97581da177e4SLinus Torvalds#									#
97591da177e4SLinus Torvalds# OUTPUT **************************************************************	#
97601da177e4SLinus Torvalds#	d0 = value of type tag						#
97611da177e4SLinus Torvalds#		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
97621da177e4SLinus Torvalds#									#
97631da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
97641da177e4SLinus Torvalds#	Simply test the exponent, j-bit, and mantissa values to		#
97651da177e4SLinus Torvalds# determine the type of operand.					#
97661da177e4SLinus Torvalds#	If it's an unnormalized zero, alter the operand and force it	#
97671da177e4SLinus Torvalds# to be a normal zero.							#
97681da177e4SLinus Torvalds#									#
97691da177e4SLinus Torvalds#########################################################################
97701da177e4SLinus Torvalds
97711da177e4SLinus Torvalds	global		tag
97721da177e4SLinus Torvaldstag:
97731da177e4SLinus Torvalds	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
97741da177e4SLinus Torvalds	andi.w		&0x7fff, %d0		# strip off sign
97751da177e4SLinus Torvalds	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
97761da177e4SLinus Torvalds	beq.b		inf_or_nan_x
97771da177e4SLinus Torvaldsnot_inf_or_nan_x:
97781da177e4SLinus Torvalds	btst		&0x7,FTEMP_HI(%a0)
97791da177e4SLinus Torvalds	beq.b		not_norm_x
97801da177e4SLinus Torvaldsis_norm_x:
97811da177e4SLinus Torvalds	mov.b		&NORM, %d0
97821da177e4SLinus Torvalds	rts
97831da177e4SLinus Torvaldsnot_norm_x:
97841da177e4SLinus Torvalds	tst.w		%d0			# is exponent = 0?
97851da177e4SLinus Torvalds	bne.b		is_unnorm_x
97861da177e4SLinus Torvaldsnot_unnorm_x:
97871da177e4SLinus Torvalds	tst.l		FTEMP_HI(%a0)
97881da177e4SLinus Torvalds	bne.b		is_denorm_x
97891da177e4SLinus Torvalds	tst.l		FTEMP_LO(%a0)
97901da177e4SLinus Torvalds	bne.b		is_denorm_x
97911da177e4SLinus Torvaldsis_zero_x:
97921da177e4SLinus Torvalds	mov.b		&ZERO, %d0
97931da177e4SLinus Torvalds	rts
97941da177e4SLinus Torvaldsis_denorm_x:
97951da177e4SLinus Torvalds	mov.b		&DENORM, %d0
97961da177e4SLinus Torvalds	rts
97971da177e4SLinus Torvaldsis_unnorm_x:
97981da177e4SLinus Torvalds	bsr.l		unnorm_fix		# convert to norm,denorm,or zero
97991da177e4SLinus Torvalds	rts
98001da177e4SLinus Torvaldsis_unnorm_reg_x:
98011da177e4SLinus Torvalds	mov.b		&UNNORM, %d0
98021da177e4SLinus Torvalds	rts
98031da177e4SLinus Torvaldsinf_or_nan_x:
98041da177e4SLinus Torvalds	tst.l		FTEMP_LO(%a0)
98051da177e4SLinus Torvalds	bne.b		is_nan_x
98061da177e4SLinus Torvalds	mov.l		FTEMP_HI(%a0), %d0
98071da177e4SLinus Torvalds	and.l		&0x7fffffff, %d0	# msb is a don't care!
98081da177e4SLinus Torvalds	bne.b		is_nan_x
98091da177e4SLinus Torvaldsis_inf_x:
98101da177e4SLinus Torvalds	mov.b		&INF, %d0
98111da177e4SLinus Torvalds	rts
98121da177e4SLinus Torvaldsis_nan_x:
98131da177e4SLinus Torvalds	mov.b		&QNAN, %d0
98141da177e4SLinus Torvalds	rts
98151da177e4SLinus Torvalds
98161da177e4SLinus Torvalds#############################################################
98171da177e4SLinus Torvalds
98181da177e4SLinus Torvaldsqnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
98191da177e4SLinus Torvalds
98201da177e4SLinus Torvalds#########################################################################
98211da177e4SLinus Torvalds# XDEF ****************************************************************	#
98221da177e4SLinus Torvalds#	t_dz(): Handle 060FPLSP dz exception for "flogn" emulation.	#
98231da177e4SLinus Torvalds#	t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation.	#
98241da177e4SLinus Torvalds#									#
98251da177e4SLinus Torvalds#	These rouitnes are used by the 060FPLSP package.		#
98261da177e4SLinus Torvalds#									#
98271da177e4SLinus Torvalds# XREF ****************************************************************	#
98281da177e4SLinus Torvalds#	None								#
98291da177e4SLinus Torvalds#									#
98301da177e4SLinus Torvalds# INPUT ***************************************************************	#
98311da177e4SLinus Torvalds#	a0 = pointer to extended precision source operand.		#
98321da177e4SLinus Torvalds#									#
98331da177e4SLinus Torvalds# OUTPUT **************************************************************	#
98341da177e4SLinus Torvalds#	fp0 = default DZ result.					#
98351da177e4SLinus Torvalds#									#
98361da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
98371da177e4SLinus Torvalds#	Transcendental emulation for the 060FPLSP has detected that	#
98381da177e4SLinus Torvalds# a DZ exception should occur for the instruction. If DZ is disabled,	#
98391da177e4SLinus Torvalds# return the default result.						#
98401da177e4SLinus Torvalds#	If DZ is enabled, the dst operand should be returned unscathed	#
98411da177e4SLinus Torvalds# in fp0 while fp1 is used to create a DZ exception so that the		#
98421da177e4SLinus Torvalds# operating system can log that such an event occurred.			#
98431da177e4SLinus Torvalds#									#
98441da177e4SLinus Torvalds#########################################################################
98451da177e4SLinus Torvalds
98461da177e4SLinus Torvalds	global		t_dz
98471da177e4SLinus Torvaldst_dz:
98481da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# check sign for neg or pos
98491da177e4SLinus Torvalds	bpl.b		dz_pinf			# branch if pos sign
98501da177e4SLinus Torvalds
98511da177e4SLinus Torvalds	global		t_dz2
98521da177e4SLinus Torvaldst_dz2:
98531da177e4SLinus Torvalds	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
98541da177e4SLinus Torvalds
98551da177e4SLinus Torvalds	btst		&dz_bit,FPCR_ENABLE(%a6)
98561da177e4SLinus Torvalds	bne.b		dz_minf_ena
98571da177e4SLinus Torvalds
98581da177e4SLinus Torvalds# dz is disabled. return a -INF.
98591da177e4SLinus Torvalds	fmov.s		&0xff800000,%fp0	# return -INF
98601da177e4SLinus Torvalds	rts
98611da177e4SLinus Torvalds
98621da177e4SLinus Torvalds# dz is enabled. create a dz exception so the user can record it
98631da177e4SLinus Torvalds# but use fp1 instead. return the dst operand unscathed in fp0.
98641da177e4SLinus Torvaldsdz_minf_ena:
98651da177e4SLinus Torvalds	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
98661da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
98671da177e4SLinus Torvalds	fmov.s		&0xbf800000,%fp1	# load -1
98681da177e4SLinus Torvalds	fdiv.s		&0x00000000,%fp1	# -1 / 0
98691da177e4SLinus Torvalds	rts
98701da177e4SLinus Torvalds
98711da177e4SLinus Torvaldsdz_pinf:
98721da177e4SLinus Torvalds	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
98731da177e4SLinus Torvalds
98741da177e4SLinus Torvalds	btst		&dz_bit,FPCR_ENABLE(%a6)
98751da177e4SLinus Torvalds	bne.b		dz_pinf_ena
98761da177e4SLinus Torvalds
98771da177e4SLinus Torvalds# dz is disabled. return a +INF.
98781da177e4SLinus Torvalds	fmov.s		&0x7f800000,%fp0	# return +INF
98791da177e4SLinus Torvalds	rts
98801da177e4SLinus Torvalds
98811da177e4SLinus Torvalds# dz is enabled. create a dz exception so the user can record it
98821da177e4SLinus Torvalds# but use fp1 instead. return the dst operand unscathed in fp0.
98831da177e4SLinus Torvaldsdz_pinf_ena:
98841da177e4SLinus Torvalds	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
98851da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
98861da177e4SLinus Torvalds	fmov.s		&0x3f800000,%fp1	# load +1
98871da177e4SLinus Torvalds	fdiv.s		&0x00000000,%fp1	# +1 / 0
98881da177e4SLinus Torvalds	rts
98891da177e4SLinus Torvalds
98901da177e4SLinus Torvalds#########################################################################
98911da177e4SLinus Torvalds# XDEF ****************************************************************	#
98921da177e4SLinus Torvalds#	t_operr(): Handle 060FPLSP OPERR exception during emulation.	#
98931da177e4SLinus Torvalds#									#
98941da177e4SLinus Torvalds#	This routine is used by the 060FPLSP package.			#
98951da177e4SLinus Torvalds#									#
98961da177e4SLinus Torvalds# XREF ****************************************************************	#
98971da177e4SLinus Torvalds#	None.								#
98981da177e4SLinus Torvalds#									#
98991da177e4SLinus Torvalds# INPUT ***************************************************************	#
99001da177e4SLinus Torvalds#	fp1 = source operand						#
99011da177e4SLinus Torvalds#									#
99021da177e4SLinus Torvalds# OUTPUT **************************************************************	#
99031da177e4SLinus Torvalds#	fp0 = default result						#
99041da177e4SLinus Torvalds#	fp1 = unchanged							#
99051da177e4SLinus Torvalds#									#
99061da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
99071da177e4SLinus Torvalds#	An operand error should occur as the result of transcendental	#
99081da177e4SLinus Torvalds# emulation in the 060FPLSP. If OPERR is disabled, just return a NAN	#
99091da177e4SLinus Torvalds# in fp0. If OPERR is enabled, return the dst operand unscathed in fp0	#
99101da177e4SLinus Torvalds# and the source operand in fp1. Use fp2 to create an OPERR exception	#
99111da177e4SLinus Torvalds# so that the operating system can log the event.			#
99121da177e4SLinus Torvalds#									#
99131da177e4SLinus Torvalds#########################################################################
99141da177e4SLinus Torvalds
99151da177e4SLinus Torvalds	global		t_operr
99161da177e4SLinus Torvaldst_operr:
99171da177e4SLinus Torvalds	ori.l		&opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
99181da177e4SLinus Torvalds
99191da177e4SLinus Torvalds	btst		&operr_bit,FPCR_ENABLE(%a6)
99201da177e4SLinus Torvalds	bne.b		operr_ena
99211da177e4SLinus Torvalds
99221da177e4SLinus Torvalds# operr is disabled. return a QNAN in fp0
99231da177e4SLinus Torvalds	fmovm.x		qnan(%pc),&0x80		# return QNAN
99241da177e4SLinus Torvalds	rts
99251da177e4SLinus Torvalds
99261da177e4SLinus Torvalds# operr is enabled. create an operr exception so the user can record it
99271da177e4SLinus Torvalds# but use fp2 instead. return the dst operand unscathed in fp0.
99281da177e4SLinus Torvaldsoperr_ena:
99291da177e4SLinus Torvalds	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
99301da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
99311da177e4SLinus Torvalds	fmovm.x		&0x04,-(%sp)		# save fp2
99321da177e4SLinus Torvalds	fmov.s		&0x7f800000,%fp2	# load +INF
99331da177e4SLinus Torvalds	fmul.s		&0x00000000,%fp2	# +INF x 0
99341da177e4SLinus Torvalds	fmovm.x		(%sp)+,&0x20		# restore fp2
99351da177e4SLinus Torvalds	rts
99361da177e4SLinus Torvalds
99371da177e4SLinus Torvaldspls_huge:
99381da177e4SLinus Torvalds	long		0x7ffe0000,0xffffffff,0xffffffff
99391da177e4SLinus Torvaldsmns_huge:
99401da177e4SLinus Torvalds	long		0xfffe0000,0xffffffff,0xffffffff
99411da177e4SLinus Torvaldspls_tiny:
99421da177e4SLinus Torvalds	long		0x00000000,0x80000000,0x00000000
99431da177e4SLinus Torvaldsmns_tiny:
99441da177e4SLinus Torvalds	long		0x80000000,0x80000000,0x00000000
99451da177e4SLinus Torvalds
99461da177e4SLinus Torvalds#########################################################################
99471da177e4SLinus Torvalds# XDEF ****************************************************************	#
99481da177e4SLinus Torvalds#	t_unfl(): Handle 060FPLSP underflow exception during emulation.	#
99491da177e4SLinus Torvalds#	t_unfl2(): Handle 060FPLSP underflow exception during		#
99501da177e4SLinus Torvalds#	           emulation. result always positive.			#
99511da177e4SLinus Torvalds#									#
99521da177e4SLinus Torvalds#	This routine is used by the 060FPLSP package.			#
99531da177e4SLinus Torvalds#									#
99541da177e4SLinus Torvalds# XREF ****************************************************************	#
99551da177e4SLinus Torvalds#	None.								#
99561da177e4SLinus Torvalds#									#
99571da177e4SLinus Torvalds# INPUT ***************************************************************	#
99581da177e4SLinus Torvalds#	a0 = pointer to extended precision source operand		#
99591da177e4SLinus Torvalds#									#
99601da177e4SLinus Torvalds# OUTPUT **************************************************************	#
99611da177e4SLinus Torvalds#	fp0 = default underflow result					#
99621da177e4SLinus Torvalds#									#
99631da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
99641da177e4SLinus Torvalds#	An underflow should occur as the result of transcendental	#
99651da177e4SLinus Torvalds# emulation in the 060FPLSP. Create an underflow by using "fmul"	#
99661da177e4SLinus Torvalds# and two very small numbers of appropriate sign so the operating	#
99671da177e4SLinus Torvalds# system can log the event.						#
99681da177e4SLinus Torvalds#									#
99691da177e4SLinus Torvalds#########################################################################
99701da177e4SLinus Torvalds
99711da177e4SLinus Torvalds	global		t_unfl
99721da177e4SLinus Torvaldst_unfl:
99731da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)
99741da177e4SLinus Torvalds	bpl.b		unf_pos
99751da177e4SLinus Torvalds
99761da177e4SLinus Torvalds	global		t_unfl2
99771da177e4SLinus Torvaldst_unfl2:
99781da177e4SLinus Torvalds	ori.l		&unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
99791da177e4SLinus Torvalds
99801da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
99811da177e4SLinus Torvalds	fmovm.x		mns_tiny(%pc),&0x80
99821da177e4SLinus Torvalds	fmul.x		pls_tiny(%pc),%fp0
99831da177e4SLinus Torvalds
99841da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
99851da177e4SLinus Torvalds	rol.l		&0x8,%d0
99861da177e4SLinus Torvalds	mov.b		%d0,FPSR_CC(%a6)
99871da177e4SLinus Torvalds	rts
99881da177e4SLinus Torvaldsunf_pos:
99891da177e4SLinus Torvalds	ori.w		&unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
99901da177e4SLinus Torvalds
99911da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
99921da177e4SLinus Torvalds	fmovm.x		pls_tiny(%pc),&0x80
99931da177e4SLinus Torvalds	fmul.x		%fp0,%fp0
99941da177e4SLinus Torvalds
99951da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
99961da177e4SLinus Torvalds	rol.l		&0x8,%d0
99971da177e4SLinus Torvalds	mov.b		%d0,FPSR_CC(%a6)
99981da177e4SLinus Torvalds	rts
99991da177e4SLinus Torvalds
100001da177e4SLinus Torvalds#########################################################################
100011da177e4SLinus Torvalds# XDEF ****************************************************************	#
100021da177e4SLinus Torvalds#	t_ovfl(): Handle 060FPLSP overflow exception during emulation.	#
100031da177e4SLinus Torvalds#		  (monadic)						#
100041da177e4SLinus Torvalds#	t_ovfl2(): Handle 060FPLSP overflow exception during		#
100051da177e4SLinus Torvalds#	           emulation. result always positive. (dyadic)		#
100061da177e4SLinus Torvalds#	t_ovfl_sc(): Handle 060FPLSP overflow exception during		#
100071da177e4SLinus Torvalds#	             emulation for "fscale".				#
100081da177e4SLinus Torvalds#									#
100091da177e4SLinus Torvalds#	This routine is used by the 060FPLSP package.			#
100101da177e4SLinus Torvalds#									#
100111da177e4SLinus Torvalds# XREF ****************************************************************	#
100121da177e4SLinus Torvalds#	None.								#
100131da177e4SLinus Torvalds#									#
100141da177e4SLinus Torvalds# INPUT ***************************************************************	#
100151da177e4SLinus Torvalds#	a0 = pointer to extended precision source operand		#
100161da177e4SLinus Torvalds#									#
100171da177e4SLinus Torvalds# OUTPUT **************************************************************	#
100181da177e4SLinus Torvalds#	fp0 = default underflow result					#
100191da177e4SLinus Torvalds#									#
100201da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
100211da177e4SLinus Torvalds#	An overflow should occur as the result of transcendental	#
100221da177e4SLinus Torvalds# emulation in the 060FPLSP. Create an overflow by using "fmul"		#
100231da177e4SLinus Torvalds# and two very lareg numbers of appropriate sign so the operating	#
100241da177e4SLinus Torvalds# system can log the event.						#
100251da177e4SLinus Torvalds#	For t_ovfl_sc() we take special care not to lose the INEX2 bit.	#
100261da177e4SLinus Torvalds#									#
100271da177e4SLinus Torvalds#########################################################################
100281da177e4SLinus Torvalds
100291da177e4SLinus Torvalds	global		t_ovfl_sc
100301da177e4SLinus Torvaldst_ovfl_sc:
100311da177e4SLinus Torvalds	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
100321da177e4SLinus Torvalds
100331da177e4SLinus Torvalds	mov.b		%d0,%d1			# fetch rnd prec,mode
100341da177e4SLinus Torvalds	andi.b		&0xc0,%d1		# extract prec
100351da177e4SLinus Torvalds	beq.w		ovfl_work
100361da177e4SLinus Torvalds
100371da177e4SLinus Torvalds# dst op is a DENORM. we have to normalize the mantissa to see if the
100381da177e4SLinus Torvalds# result would be inexact for the given precision. make a copy of the
100391da177e4SLinus Torvalds# dst so we don't screw up the version passed to us.
100401da177e4SLinus Torvalds	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
100411da177e4SLinus Torvalds	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
100421da177e4SLinus Torvalds	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
100431da177e4SLinus Torvalds	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
100441da177e4SLinus Torvalds	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
100451da177e4SLinus Torvalds	bsr.l		norm			# normalize mantissa
100461da177e4SLinus Torvalds	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
100471da177e4SLinus Torvalds
100481da177e4SLinus Torvalds	cmpi.b		%d1,&0x40		# is precision sgl?
100491da177e4SLinus Torvalds	bne.b		ovfl_sc_dbl		# no; dbl
100501da177e4SLinus Torvaldsovfl_sc_sgl:
100511da177e4SLinus Torvalds	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
100521da177e4SLinus Torvalds	bne.b		ovfl_sc_inx		# yes
100531da177e4SLinus Torvalds	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
100541da177e4SLinus Torvalds	bne.b		ovfl_sc_inx		# yes
100551da177e4SLinus Torvalds	bra.w		ovfl_work		# don't set INEX2
100561da177e4SLinus Torvaldsovfl_sc_dbl:
100571da177e4SLinus Torvalds	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
100581da177e4SLinus Torvalds	andi.l		&0x7ff,%d1		# dbl mantissa set?
100591da177e4SLinus Torvalds	beq.w		ovfl_work		# no; don't set INEX2
100601da177e4SLinus Torvaldsovfl_sc_inx:
100611da177e4SLinus Torvalds	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
100621da177e4SLinus Torvalds	bra.b		ovfl_work		# continue
100631da177e4SLinus Torvalds
100641da177e4SLinus Torvalds	global		t_ovfl
100651da177e4SLinus Torvaldst_ovfl:
100661da177e4SLinus Torvalds	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
100671da177e4SLinus Torvaldsovfl_work:
100681da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)
100691da177e4SLinus Torvalds	bpl.b		ovfl_p
100701da177e4SLinus Torvaldsovfl_m:
100711da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
100721da177e4SLinus Torvalds	fmovm.x		mns_huge(%pc),&0x80
100731da177e4SLinus Torvalds	fmul.x		pls_huge(%pc),%fp0
100741da177e4SLinus Torvalds
100751da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
100761da177e4SLinus Torvalds	rol.l		&0x8,%d0
100771da177e4SLinus Torvalds	ori.b		&neg_mask,%d0
100781da177e4SLinus Torvalds	mov.b		%d0,FPSR_CC(%a6)
100791da177e4SLinus Torvalds	rts
100801da177e4SLinus Torvaldsovfl_p:
100811da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
100821da177e4SLinus Torvalds	fmovm.x		pls_huge(%pc),&0x80
100831da177e4SLinus Torvalds	fmul.x		pls_huge(%pc),%fp0
100841da177e4SLinus Torvalds
100851da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
100861da177e4SLinus Torvalds	rol.l		&0x8,%d0
100871da177e4SLinus Torvalds	mov.b		%d0,FPSR_CC(%a6)
100881da177e4SLinus Torvalds	rts
100891da177e4SLinus Torvalds
100901da177e4SLinus Torvalds	global		t_ovfl2
100911da177e4SLinus Torvaldst_ovfl2:
100921da177e4SLinus Torvalds	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
100931da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
100941da177e4SLinus Torvalds	fmovm.x		pls_huge(%pc),&0x80
100951da177e4SLinus Torvalds	fmul.x		pls_huge(%pc),%fp0
100961da177e4SLinus Torvalds
100971da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
100981da177e4SLinus Torvalds	rol.l		&0x8,%d0
100991da177e4SLinus Torvalds	mov.b		%d0,FPSR_CC(%a6)
101001da177e4SLinus Torvalds	rts
101011da177e4SLinus Torvalds
101021da177e4SLinus Torvalds#########################################################################
101031da177e4SLinus Torvalds# XDEF ****************************************************************	#
101041da177e4SLinus Torvalds#	t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
101051da177e4SLinus Torvalds#		   emulation.						#
101061da177e4SLinus Torvalds#	t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
101071da177e4SLinus Torvalds#		    emulation.						#
101081da177e4SLinus Torvalds#									#
101091da177e4SLinus Torvalds#	These routines are used by the 060FPLSP package.		#
101101da177e4SLinus Torvalds#									#
101111da177e4SLinus Torvalds# XREF ****************************************************************	#
101121da177e4SLinus Torvalds#	None.								#
101131da177e4SLinus Torvalds#									#
101141da177e4SLinus Torvalds# INPUT ***************************************************************	#
101151da177e4SLinus Torvalds#	fp0 = default underflow or overflow result			#
101161da177e4SLinus Torvalds#									#
101171da177e4SLinus Torvalds# OUTPUT **************************************************************	#
101181da177e4SLinus Torvalds#	fp0 = default result						#
101191da177e4SLinus Torvalds#									#
101201da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
101211da177e4SLinus Torvalds#	If an overflow or underflow occurred during the last		#
101221da177e4SLinus Torvalds# instruction of transcendental 060FPLSP emulation, then it has already	#
101231da177e4SLinus Torvalds# occurred and has been logged. Now we need to see if an inexact	#
101241da177e4SLinus Torvalds# exception should occur.						#
101251da177e4SLinus Torvalds#									#
101261da177e4SLinus Torvalds#########################################################################
101271da177e4SLinus Torvalds
101281da177e4SLinus Torvalds	global		t_catch2
101291da177e4SLinus Torvaldst_catch2:
101301da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
101311da177e4SLinus Torvalds	or.l		%d0,USER_FPSR(%a6)
101321da177e4SLinus Torvalds	bra.b		inx2_work
101331da177e4SLinus Torvalds
101341da177e4SLinus Torvalds	global		t_catch
101351da177e4SLinus Torvaldst_catch:
101361da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
101371da177e4SLinus Torvalds	or.l		%d0,USER_FPSR(%a6)
101381da177e4SLinus Torvalds
101391da177e4SLinus Torvalds#########################################################################
101401da177e4SLinus Torvalds# XDEF ****************************************************************	#
101411da177e4SLinus Torvalds#	t_inx2(): Handle inexact 060FPLSP exception during emulation.	#
101421da177e4SLinus Torvalds#	t_pinx2(): Handle inexact 060FPLSP exception for "+" results.	#
101431da177e4SLinus Torvalds#	t_minx2(): Handle inexact 060FPLSP exception for "-" results.	#
101441da177e4SLinus Torvalds#									#
101451da177e4SLinus Torvalds# XREF ****************************************************************	#
101461da177e4SLinus Torvalds#	None.								#
101471da177e4SLinus Torvalds#									#
101481da177e4SLinus Torvalds# INPUT ***************************************************************	#
101491da177e4SLinus Torvalds#	fp0 = default result						#
101501da177e4SLinus Torvalds#									#
101511da177e4SLinus Torvalds# OUTPUT **************************************************************	#
101521da177e4SLinus Torvalds#	fp0 = default result						#
101531da177e4SLinus Torvalds#									#
101541da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
101551da177e4SLinus Torvalds#	The last instruction of transcendental emulation for the	#
101561da177e4SLinus Torvalds# 060FPLSP should be inexact. So, if inexact is enabled, then we create	#
101571da177e4SLinus Torvalds# the event here by adding a large and very small number together	#
101581da177e4SLinus Torvalds# so that the operating system can log the event.			#
101591da177e4SLinus Torvalds#	Must check, too, if the result was zero, in which case we just	#
101601da177e4SLinus Torvalds# set the FPSR bits and return.						#
101611da177e4SLinus Torvalds#									#
101621da177e4SLinus Torvalds#########################################################################
101631da177e4SLinus Torvalds
101641da177e4SLinus Torvalds	global		t_inx2
101651da177e4SLinus Torvaldst_inx2:
101661da177e4SLinus Torvalds	fblt.w		t_minx2
101671da177e4SLinus Torvalds	fbeq.w		inx2_zero
101681da177e4SLinus Torvalds
101691da177e4SLinus Torvalds	global		t_pinx2
101701da177e4SLinus Torvaldst_pinx2:
101711da177e4SLinus Torvalds	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
101721da177e4SLinus Torvalds	bra.b		inx2_work
101731da177e4SLinus Torvalds
101741da177e4SLinus Torvalds	global		t_minx2
101751da177e4SLinus Torvaldst_minx2:
101761da177e4SLinus Torvalds	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6)
101771da177e4SLinus Torvalds
101781da177e4SLinus Torvaldsinx2_work:
101791da177e4SLinus Torvalds	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
101801da177e4SLinus Torvalds	bne.b		inx2_work_ena		# yes
101811da177e4SLinus Torvalds	rts
101821da177e4SLinus Torvaldsinx2_work_ena:
101831da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr	# insert user's exceptions
101841da177e4SLinus Torvalds	fmov.s		&0x3f800000,%fp1	# load +1
101851da177e4SLinus Torvalds	fadd.x		pls_tiny(%pc),%fp1	# cause exception
101861da177e4SLinus Torvalds	rts
101871da177e4SLinus Torvalds
101881da177e4SLinus Torvaldsinx2_zero:
101891da177e4SLinus Torvalds	mov.b		&z_bmask,FPSR_CC(%a6)
101901da177e4SLinus Torvalds	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
101911da177e4SLinus Torvalds	rts
101921da177e4SLinus Torvalds
101931da177e4SLinus Torvalds#########################################################################
101941da177e4SLinus Torvalds# XDEF ****************************************************************	#
101951da177e4SLinus Torvalds#	t_extdnrm(): Handle DENORM inputs in 060FPLSP.			#
101961da177e4SLinus Torvalds#	t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale".	#
101971da177e4SLinus Torvalds#									#
101981da177e4SLinus Torvalds#	This routine is used by the 060FPLSP package.			#
101991da177e4SLinus Torvalds#									#
102001da177e4SLinus Torvalds# XREF ****************************************************************	#
102011da177e4SLinus Torvalds#	None.								#
102021da177e4SLinus Torvalds#									#
102031da177e4SLinus Torvalds# INPUT ***************************************************************	#
102041da177e4SLinus Torvalds#	a0 = pointer to extended precision input operand		#
102051da177e4SLinus Torvalds#									#
102061da177e4SLinus Torvalds# OUTPUT **************************************************************	#
102071da177e4SLinus Torvalds#	fp0 = default result						#
102081da177e4SLinus Torvalds#									#
102091da177e4SLinus Torvalds# ALGORITHM ***********************************************************	#
102101da177e4SLinus Torvalds#	For all functions that have a denormalized input and that	#
102111da177e4SLinus Torvalds# f(x)=x, this is the entry point.					#
102121da177e4SLinus Torvalds#	DENORM value is moved using "fmove" which triggers an exception	#
102131da177e4SLinus Torvalds# if enabled so the operating system can log the event.			#
102141da177e4SLinus Torvalds#									#
102151da177e4SLinus Torvalds#########################################################################
102161da177e4SLinus Torvalds
102171da177e4SLinus Torvalds	global		t_extdnrm
102181da177e4SLinus Torvaldst_extdnrm:
102191da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
102201da177e4SLinus Torvalds	fmov.x		SRC_EX(%a0),%fp0
102211da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
102221da177e4SLinus Torvalds	ori.l		&unfinx_mask,%d0
102231da177e4SLinus Torvalds	or.l		%d0,USER_FPSR(%a6)
102241da177e4SLinus Torvalds	rts
102251da177e4SLinus Torvalds
102261da177e4SLinus Torvalds	global		t_resdnrm
102271da177e4SLinus Torvaldst_resdnrm:
102281da177e4SLinus Torvalds	fmov.l		USER_FPCR(%a6),%fpcr
102291da177e4SLinus Torvalds	fmov.x		SRC_EX(%a0),%fp0
102301da177e4SLinus Torvalds	fmov.l		%fpsr,%d0
102311da177e4SLinus Torvalds	or.l		%d0,USER_FPSR(%a6)
102321da177e4SLinus Torvalds	rts
102331da177e4SLinus Torvalds
102341da177e4SLinus Torvalds##########################################
102351da177e4SLinus Torvalds
102361da177e4SLinus Torvalds#
102371da177e4SLinus Torvalds# sto_cos:
102381da177e4SLinus Torvalds#	This is used by fsincos library emulation. The correct
102391da177e4SLinus Torvalds# values are already in fp0 and fp1 so we do nothing here.
102401da177e4SLinus Torvalds#
102411da177e4SLinus Torvalds	global		sto_cos
102421da177e4SLinus Torvaldssto_cos:
102431da177e4SLinus Torvalds	rts
102441da177e4SLinus Torvalds
102451da177e4SLinus Torvalds##########################################
102461da177e4SLinus Torvalds
102471da177e4SLinus Torvalds#
102481da177e4SLinus Torvalds#	dst_qnan --- force result when destination is a NaN
102491da177e4SLinus Torvalds#
102501da177e4SLinus Torvalds	global		dst_qnan
102511da177e4SLinus Torvaldsdst_qnan:
102521da177e4SLinus Torvalds	fmov.x		DST(%a1),%fp0
102531da177e4SLinus Torvalds	tst.b		DST_EX(%a1)
102541da177e4SLinus Torvalds	bmi.b		dst_qnan_m
102551da177e4SLinus Torvaldsdst_qnan_p:
102561da177e4SLinus Torvalds	mov.b		&nan_bmask,FPSR_CC(%a6)
102571da177e4SLinus Torvalds	rts
102581da177e4SLinus Torvaldsdst_qnan_m:
102591da177e4SLinus Torvalds	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
102601da177e4SLinus Torvalds	rts
102611da177e4SLinus Torvalds
102621da177e4SLinus Torvalds#
102631da177e4SLinus Torvalds#	src_qnan --- force result when source is a NaN
102641da177e4SLinus Torvalds#
102651da177e4SLinus Torvalds	global		src_qnan
102661da177e4SLinus Torvaldssrc_qnan:
102671da177e4SLinus Torvalds	fmov.x		SRC(%a0),%fp0
102681da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)
102691da177e4SLinus Torvalds	bmi.b		src_qnan_m
102701da177e4SLinus Torvaldssrc_qnan_p:
102711da177e4SLinus Torvalds	mov.b		&nan_bmask,FPSR_CC(%a6)
102721da177e4SLinus Torvalds	rts
102731da177e4SLinus Torvaldssrc_qnan_m:
102741da177e4SLinus Torvalds	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
102751da177e4SLinus Torvalds	rts
102761da177e4SLinus Torvalds
102771da177e4SLinus Torvalds##########################################
102781da177e4SLinus Torvalds
102791da177e4SLinus Torvalds#
102801da177e4SLinus Torvalds#	Native instruction support
102811da177e4SLinus Torvalds#
102821da177e4SLinus Torvalds#	Some systems may need entry points even for 68060 native
102831da177e4SLinus Torvalds#	instructions.  These routines are provided for
102841da177e4SLinus Torvalds#	convenience.
102851da177e4SLinus Torvalds#
102861da177e4SLinus Torvalds	global		_fadds_
102871da177e4SLinus Torvalds_fadds_:
102881da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
102891da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
102901da177e4SLinus Torvalds	fmov.s		0x8(%sp),%fp0		# load sgl dst
102911da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
102921da177e4SLinus Torvalds	fadd.s		0x8(%sp),%fp0		# fadd w/ sgl src
102931da177e4SLinus Torvalds	rts
102941da177e4SLinus Torvalds
102951da177e4SLinus Torvalds	global		_faddd_
102961da177e4SLinus Torvalds_faddd_:
102971da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
102981da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
102991da177e4SLinus Torvalds	fmov.d		0x8(%sp),%fp0		# load dbl dst
103001da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103011da177e4SLinus Torvalds	fadd.d		0xc(%sp),%fp0		# fadd w/ dbl src
103021da177e4SLinus Torvalds	rts
103031da177e4SLinus Torvalds
103041da177e4SLinus Torvalds	global		_faddx_
103051da177e4SLinus Torvalds_faddx_:
103061da177e4SLinus Torvalds	fmovm.x		0x4(%sp),&0x80		# load ext dst
103071da177e4SLinus Torvalds	fadd.x		0x10(%sp),%fp0		# fadd w/ ext src
103081da177e4SLinus Torvalds	rts
103091da177e4SLinus Torvalds
103101da177e4SLinus Torvalds	global		_fsubs_
103111da177e4SLinus Torvalds_fsubs_:
103121da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
103131da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
103141da177e4SLinus Torvalds	fmov.s		0x8(%sp),%fp0		# load sgl dst
103151da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103161da177e4SLinus Torvalds	fsub.s		0x8(%sp),%fp0		# fsub w/ sgl src
103171da177e4SLinus Torvalds	rts
103181da177e4SLinus Torvalds
103191da177e4SLinus Torvalds	global		_fsubd_
103201da177e4SLinus Torvalds_fsubd_:
103211da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
103221da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
103231da177e4SLinus Torvalds	fmov.d		0x8(%sp),%fp0		# load dbl dst
103241da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103251da177e4SLinus Torvalds	fsub.d		0xc(%sp),%fp0		# fsub w/ dbl src
103261da177e4SLinus Torvalds	rts
103271da177e4SLinus Torvalds
103281da177e4SLinus Torvalds	global		_fsubx_
103291da177e4SLinus Torvalds_fsubx_:
103301da177e4SLinus Torvalds	fmovm.x		0x4(%sp),&0x80		# load ext dst
103311da177e4SLinus Torvalds	fsub.x		0x10(%sp),%fp0		# fsub w/ ext src
103321da177e4SLinus Torvalds	rts
103331da177e4SLinus Torvalds
103341da177e4SLinus Torvalds	global		_fmuls_
103351da177e4SLinus Torvalds_fmuls_:
103361da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
103371da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
103381da177e4SLinus Torvalds	fmov.s		0x8(%sp),%fp0		# load sgl dst
103391da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103401da177e4SLinus Torvalds	fmul.s		0x8(%sp),%fp0		# fmul w/ sgl src
103411da177e4SLinus Torvalds	rts
103421da177e4SLinus Torvalds
103431da177e4SLinus Torvalds	global		_fmuld_
103441da177e4SLinus Torvalds_fmuld_:
103451da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
103461da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
103471da177e4SLinus Torvalds	fmov.d		0x8(%sp),%fp0		# load dbl dst
103481da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103491da177e4SLinus Torvalds	fmul.d		0xc(%sp),%fp0		# fmul w/ dbl src
103501da177e4SLinus Torvalds	rts
103511da177e4SLinus Torvalds
103521da177e4SLinus Torvalds	global		_fmulx_
103531da177e4SLinus Torvalds_fmulx_:
103541da177e4SLinus Torvalds	fmovm.x		0x4(%sp),&0x80		# load ext dst
103551da177e4SLinus Torvalds	fmul.x		0x10(%sp),%fp0		# fmul w/ ext src
103561da177e4SLinus Torvalds	rts
103571da177e4SLinus Torvalds
103581da177e4SLinus Torvalds	global		_fdivs_
103591da177e4SLinus Torvalds_fdivs_:
103601da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
103611da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
103621da177e4SLinus Torvalds	fmov.s		0x8(%sp),%fp0		# load sgl dst
103631da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103641da177e4SLinus Torvalds	fdiv.s		0x8(%sp),%fp0		# fdiv w/ sgl src
103651da177e4SLinus Torvalds	rts
103661da177e4SLinus Torvalds
103671da177e4SLinus Torvalds	global		_fdivd_
103681da177e4SLinus Torvalds_fdivd_:
103691da177e4SLinus Torvalds	fmov.l		%fpcr,-(%sp)		# save fpcr
103701da177e4SLinus Torvalds	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
103711da177e4SLinus Torvalds	fmov.d		0x8(%sp),%fp0		# load dbl dst
103721da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr		# restore fpcr
103731da177e4SLinus Torvalds	fdiv.d		0xc(%sp),%fp0		# fdiv w/ dbl src
103741da177e4SLinus Torvalds	rts
103751da177e4SLinus Torvalds
103761da177e4SLinus Torvalds	global		_fdivx_
103771da177e4SLinus Torvalds_fdivx_:
103781da177e4SLinus Torvalds	fmovm.x		0x4(%sp),&0x80		# load ext dst
103791da177e4SLinus Torvalds	fdiv.x		0x10(%sp),%fp0		# fdiv w/ ext src
103801da177e4SLinus Torvalds	rts
103811da177e4SLinus Torvalds
103821da177e4SLinus Torvalds	global		_fabss_
103831da177e4SLinus Torvalds_fabss_:
103841da177e4SLinus Torvalds	fabs.s		0x4(%sp),%fp0		# fabs w/ sgl src
103851da177e4SLinus Torvalds	rts
103861da177e4SLinus Torvalds
103871da177e4SLinus Torvalds	global		_fabsd_
103881da177e4SLinus Torvalds_fabsd_:
103891da177e4SLinus Torvalds	fabs.d		0x4(%sp),%fp0		# fabs w/ dbl src
103901da177e4SLinus Torvalds	rts
103911da177e4SLinus Torvalds
103921da177e4SLinus Torvalds	global		_fabsx_
103931da177e4SLinus Torvalds_fabsx_:
103941da177e4SLinus Torvalds	fabs.x		0x4(%sp),%fp0		# fabs w/ ext src
103951da177e4SLinus Torvalds	rts
103961da177e4SLinus Torvalds
103971da177e4SLinus Torvalds	global		_fnegs_
103981da177e4SLinus Torvalds_fnegs_:
103991da177e4SLinus Torvalds	fneg.s		0x4(%sp),%fp0		# fneg w/ sgl src
104001da177e4SLinus Torvalds	rts
104011da177e4SLinus Torvalds
104021da177e4SLinus Torvalds	global		_fnegd_
104031da177e4SLinus Torvalds_fnegd_:
104041da177e4SLinus Torvalds	fneg.d		0x4(%sp),%fp0		# fneg w/ dbl src
104051da177e4SLinus Torvalds	rts
104061da177e4SLinus Torvalds
104071da177e4SLinus Torvalds	global		_fnegx_
104081da177e4SLinus Torvalds_fnegx_:
104091da177e4SLinus Torvalds	fneg.x		0x4(%sp),%fp0		# fneg w/ ext src
104101da177e4SLinus Torvalds	rts
104111da177e4SLinus Torvalds
104121da177e4SLinus Torvalds	global		_fsqrts_
104131da177e4SLinus Torvalds_fsqrts_:
104141da177e4SLinus Torvalds	fsqrt.s		0x4(%sp),%fp0		# fsqrt w/ sgl src
104151da177e4SLinus Torvalds	rts
104161da177e4SLinus Torvalds
104171da177e4SLinus Torvalds	global		_fsqrtd_
104181da177e4SLinus Torvalds_fsqrtd_:
104191da177e4SLinus Torvalds	fsqrt.d		0x4(%sp),%fp0		# fsqrt w/ dbl src
104201da177e4SLinus Torvalds	rts
104211da177e4SLinus Torvalds
104221da177e4SLinus Torvalds	global		_fsqrtx_
104231da177e4SLinus Torvalds_fsqrtx_:
104241da177e4SLinus Torvalds	fsqrt.x		0x4(%sp),%fp0		# fsqrt w/ ext src
104251da177e4SLinus Torvalds	rts
104261da177e4SLinus Torvalds
104271da177e4SLinus Torvalds	global		_fints_
104281da177e4SLinus Torvalds_fints_:
104291da177e4SLinus Torvalds	fint.s		0x4(%sp),%fp0		# fint w/ sgl src
104301da177e4SLinus Torvalds	rts
104311da177e4SLinus Torvalds
104321da177e4SLinus Torvalds	global		_fintd_
104331da177e4SLinus Torvalds_fintd_:
104341da177e4SLinus Torvalds	fint.d		0x4(%sp),%fp0		# fint w/ dbl src
104351da177e4SLinus Torvalds	rts
104361da177e4SLinus Torvalds
104371da177e4SLinus Torvalds	global		_fintx_
104381da177e4SLinus Torvalds_fintx_:
104391da177e4SLinus Torvalds	fint.x		0x4(%sp),%fp0		# fint w/ ext src
104401da177e4SLinus Torvalds	rts
104411da177e4SLinus Torvalds
104421da177e4SLinus Torvalds	global		_fintrzs_
104431da177e4SLinus Torvalds_fintrzs_:
104441da177e4SLinus Torvalds	fintrz.s	0x4(%sp),%fp0		# fintrz w/ sgl src
104451da177e4SLinus Torvalds	rts
104461da177e4SLinus Torvalds
104471da177e4SLinus Torvalds	global		_fintrzd_
104481da177e4SLinus Torvalds_fintrzd_:
104491da177e4SLinus Torvalds	fintrz.d	0x4(%sp),%fp0		# fintrx w/ dbl src
104501da177e4SLinus Torvalds	rts
104511da177e4SLinus Torvalds
104521da177e4SLinus Torvalds	global		_fintrzx_
104531da177e4SLinus Torvalds_fintrzx_:
104541da177e4SLinus Torvalds	fintrz.x	0x4(%sp),%fp0		# fintrz w/ ext src
104551da177e4SLinus Torvalds	rts
104561da177e4SLinus Torvalds
104571da177e4SLinus Torvalds########################################################################
104581da177e4SLinus Torvalds
104591da177e4SLinus Torvalds#########################################################################
104601da177e4SLinus Torvalds# src_zero(): Return signed zero according to sign of src operand.	#
104611da177e4SLinus Torvalds#########################################################################
104621da177e4SLinus Torvalds	global		src_zero
104631da177e4SLinus Torvaldssrc_zero:
104641da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# get sign of src operand
104651da177e4SLinus Torvalds	bmi.b		ld_mzero		# if neg, load neg zero
104661da177e4SLinus Torvalds
104671da177e4SLinus Torvalds#
104681da177e4SLinus Torvalds# ld_pzero(): return a positive zero.
104691da177e4SLinus Torvalds#
104701da177e4SLinus Torvalds	global		ld_pzero
104711da177e4SLinus Torvaldsld_pzero:
104721da177e4SLinus Torvalds	fmov.s		&0x00000000,%fp0	# load +0
104731da177e4SLinus Torvalds	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
104741da177e4SLinus Torvalds	rts
104751da177e4SLinus Torvalds
104761da177e4SLinus Torvalds# ld_mzero(): return a negative zero.
104771da177e4SLinus Torvalds	global		ld_mzero
104781da177e4SLinus Torvaldsld_mzero:
104791da177e4SLinus Torvalds	fmov.s		&0x80000000,%fp0	# load -0
104801da177e4SLinus Torvalds	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
104811da177e4SLinus Torvalds	rts
104821da177e4SLinus Torvalds
104831da177e4SLinus Torvalds#########################################################################
104841da177e4SLinus Torvalds# dst_zero(): Return signed zero according to sign of dst operand.	#
104851da177e4SLinus Torvalds#########################################################################
104861da177e4SLinus Torvalds	global		dst_zero
104871da177e4SLinus Torvaldsdst_zero:
104881da177e4SLinus Torvalds	tst.b		DST_EX(%a1)		# get sign of dst operand
104891da177e4SLinus Torvalds	bmi.b		ld_mzero		# if neg, load neg zero
104901da177e4SLinus Torvalds	bra.b		ld_pzero		# load positive zero
104911da177e4SLinus Torvalds
104921da177e4SLinus Torvalds#########################################################################
104931da177e4SLinus Torvalds# src_inf(): Return signed inf according to sign of src operand.	#
104941da177e4SLinus Torvalds#########################################################################
104951da177e4SLinus Torvalds	global		src_inf
104961da177e4SLinus Torvaldssrc_inf:
104971da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# get sign of src operand
104981da177e4SLinus Torvalds	bmi.b		ld_minf			# if negative branch
104991da177e4SLinus Torvalds
105001da177e4SLinus Torvalds#
105011da177e4SLinus Torvalds# ld_pinf(): return a positive infinity.
105021da177e4SLinus Torvalds#
105031da177e4SLinus Torvalds	global		ld_pinf
105041da177e4SLinus Torvaldsld_pinf:
105051da177e4SLinus Torvalds	fmov.s		&0x7f800000,%fp0	# load +INF
105061da177e4SLinus Torvalds	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
105071da177e4SLinus Torvalds	rts
105081da177e4SLinus Torvalds
105091da177e4SLinus Torvalds#
105101da177e4SLinus Torvalds# ld_minf():return a negative infinity.
105111da177e4SLinus Torvalds#
105121da177e4SLinus Torvalds	global		ld_minf
105131da177e4SLinus Torvaldsld_minf:
105141da177e4SLinus Torvalds	fmov.s		&0xff800000,%fp0	# load -INF
105151da177e4SLinus Torvalds	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
105161da177e4SLinus Torvalds	rts
105171da177e4SLinus Torvalds
105181da177e4SLinus Torvalds#########################################################################
105191da177e4SLinus Torvalds# dst_inf(): Return signed inf according to sign of dst operand.	#
105201da177e4SLinus Torvalds#########################################################################
105211da177e4SLinus Torvalds	global		dst_inf
105221da177e4SLinus Torvaldsdst_inf:
105231da177e4SLinus Torvalds	tst.b		DST_EX(%a1)		# get sign of dst operand
105241da177e4SLinus Torvalds	bmi.b		ld_minf			# if negative branch
105251da177e4SLinus Torvalds	bra.b		ld_pinf
105261da177e4SLinus Torvalds
105271da177e4SLinus Torvalds	global		szr_inf
105281da177e4SLinus Torvalds#################################################################
105291da177e4SLinus Torvalds# szr_inf(): Return +ZERO for a negative src operand or		#
105301da177e4SLinus Torvalds#	            +INF for a positive src operand.		#
105311da177e4SLinus Torvalds#	     Routine used for fetox, ftwotox, and ftentox.	#
105321da177e4SLinus Torvalds#################################################################
105331da177e4SLinus Torvaldsszr_inf:
105341da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# check sign of source
105351da177e4SLinus Torvalds	bmi.b		ld_pzero
105361da177e4SLinus Torvalds	bra.b		ld_pinf
105371da177e4SLinus Torvalds
105381da177e4SLinus Torvalds#########################################################################
105391da177e4SLinus Torvalds# sopr_inf(): Return +INF for a positive src operand or			#
105401da177e4SLinus Torvalds#	      jump to operand error routine for a negative src operand.	#
105411da177e4SLinus Torvalds#	      Routine used for flogn, flognp1, flog10, and flog2.	#
105421da177e4SLinus Torvalds#########################################################################
105431da177e4SLinus Torvalds	global		sopr_inf
105441da177e4SLinus Torvaldssopr_inf:
105451da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# check sign of source
105461da177e4SLinus Torvalds	bmi.w		t_operr
105471da177e4SLinus Torvalds	bra.b		ld_pinf
105481da177e4SLinus Torvalds
105491da177e4SLinus Torvalds#################################################################
105501da177e4SLinus Torvalds# setoxm1i(): Return minus one for a negative src operand or	#
105511da177e4SLinus Torvalds#	      positive infinity for a positive src operand.	#
105521da177e4SLinus Torvalds#	      Routine used for fetoxm1.				#
105531da177e4SLinus Torvalds#################################################################
105541da177e4SLinus Torvalds	global		setoxm1i
105551da177e4SLinus Torvaldssetoxm1i:
105561da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# check sign of source
105571da177e4SLinus Torvalds	bmi.b		ld_mone
105581da177e4SLinus Torvalds	bra.b		ld_pinf
105591da177e4SLinus Torvalds
105601da177e4SLinus Torvalds#########################################################################
105611da177e4SLinus Torvalds# src_one(): Return signed one according to sign of src operand.	#
105621da177e4SLinus Torvalds#########################################################################
105631da177e4SLinus Torvalds	global		src_one
105641da177e4SLinus Torvaldssrc_one:
105651da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# check sign of source
105661da177e4SLinus Torvalds	bmi.b		ld_mone
105671da177e4SLinus Torvalds
105681da177e4SLinus Torvalds#
105691da177e4SLinus Torvalds# ld_pone(): return positive one.
105701da177e4SLinus Torvalds#
105711da177e4SLinus Torvalds	global		ld_pone
105721da177e4SLinus Torvaldsld_pone:
105731da177e4SLinus Torvalds	fmov.s		&0x3f800000,%fp0	# load +1
105741da177e4SLinus Torvalds	clr.b		FPSR_CC(%a6)
105751da177e4SLinus Torvalds	rts
105761da177e4SLinus Torvalds
105771da177e4SLinus Torvalds#
105781da177e4SLinus Torvalds# ld_mone(): return negative one.
105791da177e4SLinus Torvalds#
105801da177e4SLinus Torvalds	global		ld_mone
105811da177e4SLinus Torvaldsld_mone:
105821da177e4SLinus Torvalds	fmov.s		&0xbf800000,%fp0	# load -1
105831da177e4SLinus Torvalds	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
105841da177e4SLinus Torvalds	rts
105851da177e4SLinus Torvalds
105861da177e4SLinus Torvaldsppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
105871da177e4SLinus Torvaldsmpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
105881da177e4SLinus Torvalds
105891da177e4SLinus Torvalds#################################################################
105901da177e4SLinus Torvalds# spi_2(): Return signed PI/2 according to sign of src operand.	#
105911da177e4SLinus Torvalds#################################################################
105921da177e4SLinus Torvalds	global		spi_2
105931da177e4SLinus Torvaldsspi_2:
105941da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# check sign of source
105951da177e4SLinus Torvalds	bmi.b		ld_mpi2
105961da177e4SLinus Torvalds
105971da177e4SLinus Torvalds#
105981da177e4SLinus Torvalds# ld_ppi2(): return positive PI/2.
105991da177e4SLinus Torvalds#
106001da177e4SLinus Torvalds	global		ld_ppi2
106011da177e4SLinus Torvaldsld_ppi2:
106021da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
106031da177e4SLinus Torvalds	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
106041da177e4SLinus Torvalds	bra.w		t_pinx2			# set INEX2
106051da177e4SLinus Torvalds
106061da177e4SLinus Torvalds#
106071da177e4SLinus Torvalds# ld_mpi2(): return negative PI/2.
106081da177e4SLinus Torvalds#
106091da177e4SLinus Torvalds	global		ld_mpi2
106101da177e4SLinus Torvaldsld_mpi2:
106111da177e4SLinus Torvalds	fmov.l		%d0,%fpcr
106121da177e4SLinus Torvalds	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
106131da177e4SLinus Torvalds	bra.w		t_minx2			# set INEX2
106141da177e4SLinus Torvalds
106151da177e4SLinus Torvalds####################################################
106161da177e4SLinus Torvalds# The following routines give support for fsincos. #
106171da177e4SLinus Torvalds####################################################
106181da177e4SLinus Torvalds
106191da177e4SLinus Torvalds#
106201da177e4SLinus Torvalds# ssincosz(): When the src operand is ZERO, store a one in the
106211da177e4SLinus Torvalds#	      cosine register and return a ZERO in fp0 w/ the same sign
106221da177e4SLinus Torvalds#	      as the src operand.
106231da177e4SLinus Torvalds#
106241da177e4SLinus Torvalds	global		ssincosz
106251da177e4SLinus Torvaldsssincosz:
106261da177e4SLinus Torvalds	fmov.s		&0x3f800000,%fp1
106271da177e4SLinus Torvalds	tst.b		SRC_EX(%a0)		# test sign
106281da177e4SLinus Torvalds	bpl.b		sincoszp
106291da177e4SLinus Torvalds	fmov.s		&0x80000000,%fp0	# return sin result in fp0
106301da177e4SLinus Torvalds	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
106311da177e4SLinus Torvalds	rts
106321da177e4SLinus Torvaldssincoszp:
106331da177e4SLinus Torvalds	fmov.s		&0x00000000,%fp0	# return sin result in fp0
106341da177e4SLinus Torvalds	mov.b		&z_bmask,FPSR_CC(%a6)
106351da177e4SLinus Torvalds	rts
106361da177e4SLinus Torvalds
106371da177e4SLinus Torvalds#
106381da177e4SLinus Torvalds# ssincosi(): When the src operand is INF, store a QNAN in the cosine
106391da177e4SLinus Torvalds#	      register and jump to the operand error routine for negative
106401da177e4SLinus Torvalds#	      src operands.
106411da177e4SLinus Torvalds#
106421da177e4SLinus Torvalds	global		ssincosi
106431da177e4SLinus Torvaldsssincosi:
106441da177e4SLinus Torvalds	fmov.x		qnan(%pc),%fp1		# load NAN
106451da177e4SLinus Torvalds	bra.w		t_operr
106461da177e4SLinus Torvalds
106471da177e4SLinus Torvalds#
106481da177e4SLinus Torvalds# ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
106491da177e4SLinus Torvalds#		 register and branch to the src QNAN routine.
106501da177e4SLinus Torvalds#
106511da177e4SLinus Torvalds	global		ssincosqnan
106521da177e4SLinus Torvaldsssincosqnan:
106531da177e4SLinus Torvalds	fmov.x		LOCAL_EX(%a0),%fp1
106541da177e4SLinus Torvalds	bra.w		src_qnan
106551da177e4SLinus Torvalds
106561da177e4SLinus Torvalds########################################################################
106571da177e4SLinus Torvalds
106581da177e4SLinus Torvalds	global		smod_sdnrm
106591da177e4SLinus Torvalds	global		smod_snorm
106601da177e4SLinus Torvaldssmod_sdnrm:
106611da177e4SLinus Torvaldssmod_snorm:
106621da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
106631da177e4SLinus Torvalds	beq.l		smod
106641da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
106651da177e4SLinus Torvalds	beq.w		smod_zro
106661da177e4SLinus Torvalds	cmpi.b		%d1,&INF
106671da177e4SLinus Torvalds	beq.l		t_operr
106681da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
106691da177e4SLinus Torvalds	beq.l		smod
106701da177e4SLinus Torvalds	bra.l		dst_qnan
106711da177e4SLinus Torvalds
106721da177e4SLinus Torvalds	global		smod_szero
106731da177e4SLinus Torvaldssmod_szero:
106741da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
106751da177e4SLinus Torvalds	beq.l		t_operr
106761da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
106771da177e4SLinus Torvalds	beq.l		t_operr
106781da177e4SLinus Torvalds	cmpi.b		%d1,&INF
106791da177e4SLinus Torvalds	beq.l		t_operr
106801da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
106811da177e4SLinus Torvalds	beq.l		t_operr
106821da177e4SLinus Torvalds	bra.l		dst_qnan
106831da177e4SLinus Torvalds
106841da177e4SLinus Torvalds	global		smod_sinf
106851da177e4SLinus Torvaldssmod_sinf:
106861da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
106871da177e4SLinus Torvalds	beq.l		smod_fpn
106881da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
106891da177e4SLinus Torvalds	beq.l		smod_zro
106901da177e4SLinus Torvalds	cmpi.b		%d1,&INF
106911da177e4SLinus Torvalds	beq.l		t_operr
106921da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
106931da177e4SLinus Torvalds	beq.l		smod_fpn
106941da177e4SLinus Torvalds	bra.l		dst_qnan
106951da177e4SLinus Torvalds
106961da177e4SLinus Torvaldssmod_zro:
106971da177e4SLinus Torvaldssrem_zro:
106981da177e4SLinus Torvalds	mov.b		SRC_EX(%a0),%d1		# get src sign
106991da177e4SLinus Torvalds	mov.b		DST_EX(%a1),%d0		# get dst sign
107001da177e4SLinus Torvalds	eor.b		%d0,%d1			# get qbyte sign
107011da177e4SLinus Torvalds	andi.b		&0x80,%d1
107021da177e4SLinus Torvalds	mov.b		%d1,FPSR_QBYTE(%a6)
107031da177e4SLinus Torvalds	tst.b		%d0
107041da177e4SLinus Torvalds	bpl.w		ld_pzero
107051da177e4SLinus Torvalds	bra.w		ld_mzero
107061da177e4SLinus Torvalds
107071da177e4SLinus Torvaldssmod_fpn:
107081da177e4SLinus Torvaldssrem_fpn:
107091da177e4SLinus Torvalds	clr.b		FPSR_QBYTE(%a6)
107101da177e4SLinus Torvalds	mov.l		%d0,-(%sp)
107111da177e4SLinus Torvalds	mov.b		SRC_EX(%a0),%d1		# get src sign
107121da177e4SLinus Torvalds	mov.b		DST_EX(%a1),%d0		# get dst sign
107131da177e4SLinus Torvalds	eor.b		%d0,%d1			# get qbyte sign
107141da177e4SLinus Torvalds	andi.b		&0x80,%d1
107151da177e4SLinus Torvalds	mov.b		%d1,FPSR_QBYTE(%a6)
107161da177e4SLinus Torvalds	cmpi.b		DTAG(%a6),&DENORM
107171da177e4SLinus Torvalds	bne.b		smod_nrm
107181da177e4SLinus Torvalds	lea		DST(%a1),%a0
107191da177e4SLinus Torvalds	mov.l		(%sp)+,%d0
107201da177e4SLinus Torvalds	bra		t_resdnrm
107211da177e4SLinus Torvaldssmod_nrm:
107221da177e4SLinus Torvalds	fmov.l		(%sp)+,%fpcr
107231da177e4SLinus Torvalds	fmov.x		DST(%a1),%fp0
107241da177e4SLinus Torvalds	tst.b		DST_EX(%a1)
107251da177e4SLinus Torvalds	bmi.b		smod_nrm_neg
107261da177e4SLinus Torvalds	rts
107271da177e4SLinus Torvalds
107281da177e4SLinus Torvaldssmod_nrm_neg:
107291da177e4SLinus Torvalds	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' code
107301da177e4SLinus Torvalds	rts
107311da177e4SLinus Torvalds
107321da177e4SLinus Torvalds#########################################################################
107331da177e4SLinus Torvalds	global		srem_snorm
107341da177e4SLinus Torvalds	global		srem_sdnrm
107351da177e4SLinus Torvaldssrem_sdnrm:
107361da177e4SLinus Torvaldssrem_snorm:
107371da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
107381da177e4SLinus Torvalds	beq.l		srem
107391da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
107401da177e4SLinus Torvalds	beq.w		srem_zro
107411da177e4SLinus Torvalds	cmpi.b		%d1,&INF
107421da177e4SLinus Torvalds	beq.l		t_operr
107431da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
107441da177e4SLinus Torvalds	beq.l		srem
107451da177e4SLinus Torvalds	bra.l		dst_qnan
107461da177e4SLinus Torvalds
107471da177e4SLinus Torvalds	global		srem_szero
107481da177e4SLinus Torvaldssrem_szero:
107491da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
107501da177e4SLinus Torvalds	beq.l		t_operr
107511da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
107521da177e4SLinus Torvalds	beq.l		t_operr
107531da177e4SLinus Torvalds	cmpi.b		%d1,&INF
107541da177e4SLinus Torvalds	beq.l		t_operr
107551da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
107561da177e4SLinus Torvalds	beq.l		t_operr
107571da177e4SLinus Torvalds	bra.l		dst_qnan
107581da177e4SLinus Torvalds
107591da177e4SLinus Torvalds	global		srem_sinf
107601da177e4SLinus Torvaldssrem_sinf:
107611da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
107621da177e4SLinus Torvalds	beq.w		srem_fpn
107631da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
107641da177e4SLinus Torvalds	beq.w		srem_zro
107651da177e4SLinus Torvalds	cmpi.b		%d1,&INF
107661da177e4SLinus Torvalds	beq.l		t_operr
107671da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
107681da177e4SLinus Torvalds	beq.l		srem_fpn
107691da177e4SLinus Torvalds	bra.l		dst_qnan
107701da177e4SLinus Torvalds
107711da177e4SLinus Torvalds#########################################################################
107721da177e4SLinus Torvalds
107731da177e4SLinus Torvalds	global		sscale_snorm
107741da177e4SLinus Torvalds	global		sscale_sdnrm
107751da177e4SLinus Torvaldssscale_snorm:
107761da177e4SLinus Torvaldssscale_sdnrm:
107771da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
107781da177e4SLinus Torvalds	beq.l		sscale
107791da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
107801da177e4SLinus Torvalds	beq.l		dst_zero
107811da177e4SLinus Torvalds	cmpi.b		%d1,&INF
107821da177e4SLinus Torvalds	beq.l		dst_inf
107831da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
107841da177e4SLinus Torvalds	beq.l		sscale
107851da177e4SLinus Torvalds	bra.l		dst_qnan
107861da177e4SLinus Torvalds
107871da177e4SLinus Torvalds	global		sscale_szero
107881da177e4SLinus Torvaldssscale_szero:
107891da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
107901da177e4SLinus Torvalds	beq.l		sscale
107911da177e4SLinus Torvalds	cmpi.b		%d1,&ZERO
107921da177e4SLinus Torvalds	beq.l		dst_zero
107931da177e4SLinus Torvalds	cmpi.b		%d1,&INF
107941da177e4SLinus Torvalds	beq.l		dst_inf
107951da177e4SLinus Torvalds	cmpi.b		%d1,&DENORM
107961da177e4SLinus Torvalds	beq.l		sscale
107971da177e4SLinus Torvalds	bra.l		dst_qnan
107981da177e4SLinus Torvalds
107991da177e4SLinus Torvalds	global		sscale_sinf
108001da177e4SLinus Torvaldssscale_sinf:
108011da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
108021da177e4SLinus Torvalds	beq.l		t_operr
108031da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN
108041da177e4SLinus Torvalds	beq.l		dst_qnan
108051da177e4SLinus Torvalds	bra.l		t_operr
108061da177e4SLinus Torvalds
108071da177e4SLinus Torvalds########################################################################
108081da177e4SLinus Torvalds
108091da177e4SLinus Torvalds	global		sop_sqnan
108101da177e4SLinus Torvaldssop_sqnan:
108111da177e4SLinus Torvalds	mov.b		DTAG(%a6),%d1
108121da177e4SLinus Torvalds	cmpi.b		%d1,&QNAN
108131da177e4SLinus Torvalds	beq.l		dst_qnan
108141da177e4SLinus Torvalds	bra.l		src_qnan
108151da177e4SLinus Torvalds
108161da177e4SLinus Torvalds#########################################################################
108171da177e4SLinus Torvalds# norm(): normalize the mantissa of an extended precision input. the	#
108181da177e4SLinus Torvalds#	  input operand should not be normalized already.		#
108191da177e4SLinus Torvalds#									#
108201da177e4SLinus Torvalds# XDEF ****************************************************************	#
108211da177e4SLinus Torvalds#	norm()								#
108221da177e4SLinus Torvalds#									#
108231da177e4SLinus Torvalds# XREF **************************************************************** #
108241da177e4SLinus Torvalds#	none								#
108251da177e4SLinus Torvalds#									#
108261da177e4SLinus Torvalds# INPUT *************************************************************** #
108271da177e4SLinus Torvalds#	a0 = pointer fp extended precision operand to normalize		#
108281da177e4SLinus Torvalds#									#
108291da177e4SLinus Torvalds# OUTPUT ************************************************************** #
108301da177e4SLinus Torvalds#	d0 = number of bit positions the mantissa was shifted		#
108311da177e4SLinus Torvalds#	a0 = the input operand's mantissa is normalized; the exponent	#
108321da177e4SLinus Torvalds#	     is unchanged.						#
108331da177e4SLinus Torvalds#									#
108341da177e4SLinus Torvalds#########################################################################
108351da177e4SLinus Torvalds	global		norm
108361da177e4SLinus Torvaldsnorm:
108371da177e4SLinus Torvalds	mov.l		%d2, -(%sp)		# create some temp regs
108381da177e4SLinus Torvalds	mov.l		%d3, -(%sp)
108391da177e4SLinus Torvalds
108401da177e4SLinus Torvalds	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
108411da177e4SLinus Torvalds	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
108421da177e4SLinus Torvalds
108431da177e4SLinus Torvalds	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
108441da177e4SLinus Torvalds	beq.b		norm_lo			# hi(man) is all zeroes!
108451da177e4SLinus Torvalds
108461da177e4SLinus Torvaldsnorm_hi:
108471da177e4SLinus Torvalds	lsl.l		%d2, %d0		# left shift hi(man)
108481da177e4SLinus Torvalds	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
108491da177e4SLinus Torvalds
108501da177e4SLinus Torvalds	or.l		%d3, %d0		# create hi(man)
108511da177e4SLinus Torvalds	lsl.l		%d2, %d1		# create lo(man)
108521da177e4SLinus Torvalds
108531da177e4SLinus Torvalds	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
108541da177e4SLinus Torvalds	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
108551da177e4SLinus Torvalds
108561da177e4SLinus Torvalds	mov.l		%d2, %d0		# return shift amount
108571da177e4SLinus Torvalds
108581da177e4SLinus Torvalds	mov.l		(%sp)+, %d3		# restore temp regs
108591da177e4SLinus Torvalds	mov.l		(%sp)+, %d2
108601da177e4SLinus Torvalds
108611da177e4SLinus Torvalds	rts
108621da177e4SLinus Torvalds
108631da177e4SLinus Torvaldsnorm_lo:
108641da177e4SLinus Torvalds	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
108651da177e4SLinus Torvalds	lsl.l		%d2, %d1		# shift lo(man)
108661da177e4SLinus Torvalds	add.l		&32, %d2		# add 32 to shft amount
108671da177e4SLinus Torvalds
108681da177e4SLinus Torvalds	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
108691da177e4SLinus Torvalds	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
108701da177e4SLinus Torvalds
108711da177e4SLinus Torvalds	mov.l		%d2, %d0		# return shift amount
108721da177e4SLinus Torvalds
108731da177e4SLinus Torvalds	mov.l		(%sp)+, %d3		# restore temp regs
108741da177e4SLinus Torvalds	mov.l		(%sp)+, %d2
108751da177e4SLinus Torvalds
108761da177e4SLinus Torvalds	rts
108771da177e4SLinus Torvalds
108781da177e4SLinus Torvalds#########################################################################
108791da177e4SLinus Torvalds# unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
108801da177e4SLinus Torvalds#		- returns corresponding optype tag			#
108811da177e4SLinus Torvalds#									#
108821da177e4SLinus Torvalds# XDEF ****************************************************************	#
108831da177e4SLinus Torvalds#	unnorm_fix()							#
108841da177e4SLinus Torvalds#									#
108851da177e4SLinus Torvalds# XREF **************************************************************** #
108861da177e4SLinus Torvalds#	norm() - normalize the mantissa					#
108871da177e4SLinus Torvalds#									#
108881da177e4SLinus Torvalds# INPUT *************************************************************** #
108891da177e4SLinus Torvalds#	a0 = pointer to unnormalized extended precision number		#
108901da177e4SLinus Torvalds#									#
108911da177e4SLinus Torvalds# OUTPUT ************************************************************** #
108921da177e4SLinus Torvalds#	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
108931da177e4SLinus Torvalds#	a0 = input operand has been converted to a norm, denorm, or	#
108941da177e4SLinus Torvalds#	     zero; both the exponent and mantissa are changed.		#
108951da177e4SLinus Torvalds#									#
108961da177e4SLinus Torvalds#########################################################################
108971da177e4SLinus Torvalds
108981da177e4SLinus Torvalds	global		unnorm_fix
108991da177e4SLinus Torvaldsunnorm_fix:
109001da177e4SLinus Torvalds	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
109011da177e4SLinus Torvalds	bne.b		unnorm_shift		# hi(man) is not all zeroes
109021da177e4SLinus Torvalds
109031da177e4SLinus Torvalds#
109041da177e4SLinus Torvalds# hi(man) is all zeroes so see if any bits in lo(man) are set
109051da177e4SLinus Torvalds#
109061da177e4SLinus Torvaldsunnorm_chk_lo:
109071da177e4SLinus Torvalds	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
109081da177e4SLinus Torvalds	beq.w		unnorm_zero		# yes
109091da177e4SLinus Torvalds
109101da177e4SLinus Torvalds	add.w		&32, %d0		# no; fix shift distance
109111da177e4SLinus Torvalds
109121da177e4SLinus Torvalds#
109131da177e4SLinus Torvalds# d0 = # shifts needed for complete normalization
109141da177e4SLinus Torvalds#
109151da177e4SLinus Torvaldsunnorm_shift:
109161da177e4SLinus Torvalds	clr.l		%d1			# clear top word
109171da177e4SLinus Torvalds	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
109181da177e4SLinus Torvalds	and.w		&0x7fff, %d1		# strip off sgn
109191da177e4SLinus Torvalds
109201da177e4SLinus Torvalds	cmp.w		%d0, %d1		# will denorm push exp < 0?
109211da177e4SLinus Torvalds	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
109221da177e4SLinus Torvalds
109231da177e4SLinus Torvalds#
109241da177e4SLinus Torvalds# exponent would not go < 0. therefore, number stays normalized
109251da177e4SLinus Torvalds#
109261da177e4SLinus Torvalds	sub.w		%d0, %d1		# shift exponent value
109271da177e4SLinus Torvalds	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
109281da177e4SLinus Torvalds	and.w		&0x8000, %d0		# save old sign
109291da177e4SLinus Torvalds	or.w		%d0, %d1		# {sgn,new exp}
109301da177e4SLinus Torvalds	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
109311da177e4SLinus Torvalds
109321da177e4SLinus Torvalds	bsr.l		norm			# normalize UNNORM
109331da177e4SLinus Torvalds
109341da177e4SLinus Torvalds	mov.b		&NORM, %d0		# return new optype tag
109351da177e4SLinus Torvalds	rts
109361da177e4SLinus Torvalds
109371da177e4SLinus Torvalds#
109381da177e4SLinus Torvalds# exponent would go < 0, so only denormalize until exp = 0
109391da177e4SLinus Torvalds#
109401da177e4SLinus Torvaldsunnorm_nrm_zero:
109411da177e4SLinus Torvalds	cmp.b		%d1, &32		# is exp <= 32?
109421da177e4SLinus Torvalds	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
109431da177e4SLinus Torvalds
109441da177e4SLinus Torvalds	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
109451da177e4SLinus Torvalds	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
109461da177e4SLinus Torvalds
109471da177e4SLinus Torvalds	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
109481da177e4SLinus Torvalds	lsl.l		%d1, %d0		# extract new lo(man)
109491da177e4SLinus Torvalds	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
109501da177e4SLinus Torvalds
109511da177e4SLinus Torvalds	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
109521da177e4SLinus Torvalds
109531da177e4SLinus Torvalds	mov.b		&DENORM, %d0		# return new optype tag
109541da177e4SLinus Torvalds	rts
109551da177e4SLinus Torvalds
109561da177e4SLinus Torvalds#
109571da177e4SLinus Torvalds# only mantissa bits set are in lo(man)
109581da177e4SLinus Torvalds#
109591da177e4SLinus Torvaldsunnorm_nrm_zero_lrg:
109601da177e4SLinus Torvalds	sub.w		&32, %d1		# adjust shft amt by 32
109611da177e4SLinus Torvalds
109621da177e4SLinus Torvalds	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
109631da177e4SLinus Torvalds	lsl.l		%d1, %d0		# left shift lo(man)
109641da177e4SLinus Torvalds
109651da177e4SLinus Torvalds	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
109661da177e4SLinus Torvalds	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
109671da177e4SLinus Torvalds
109681da177e4SLinus Torvalds	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
109691da177e4SLinus Torvalds
109701da177e4SLinus Torvalds	mov.b		&DENORM, %d0		# return new optype tag
109711da177e4SLinus Torvalds	rts
109721da177e4SLinus Torvalds
109731da177e4SLinus Torvalds#
109741da177e4SLinus Torvalds# whole mantissa is zero so this UNNORM is actually a zero
109751da177e4SLinus Torvalds#
109761da177e4SLinus Torvaldsunnorm_zero:
109771da177e4SLinus Torvalds	and.w		&0x8000, FTEMP_EX(%a0)	# force exponent to zero
109781da177e4SLinus Torvalds
109791da177e4SLinus Torvalds	mov.b		&ZERO, %d0		# fix optype tag
109801da177e4SLinus Torvalds	rts
10981