162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
262306a36Sopenharmony_ciMOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
362306a36Sopenharmony_ciM68000 Hi-Performance Microprocessor Division
462306a36Sopenharmony_ciM68060 Software Package
562306a36Sopenharmony_ciProduction Release P1.00 -- October 10, 1994
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciM68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
862306a36Sopenharmony_ci
962306a36Sopenharmony_ciTHE SOFTWARE is provided on an "AS IS" basis and without warranty.
1062306a36Sopenharmony_ciTo the maximum extent permitted by applicable law,
1162306a36Sopenharmony_ciMOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
1262306a36Sopenharmony_ciINCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
1362306a36Sopenharmony_ciand any warranty against infringement with regard to the SOFTWARE
1462306a36Sopenharmony_ci(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciTo the maximum extent permitted by applicable law,
1762306a36Sopenharmony_ciIN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
1862306a36Sopenharmony_ci(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
1962306a36Sopenharmony_ciBUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
2062306a36Sopenharmony_ciARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
2162306a36Sopenharmony_ciMotorola assumes no responsibility for the maintenance and support of the SOFTWARE.
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciYou are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
2462306a36Sopenharmony_ciso long as this entire notice is retained without alteration in any modified and/or
2562306a36Sopenharmony_ciredistributed versions, and that such modified versions are clearly identified as such.
2662306a36Sopenharmony_ciNo licenses are granted by implication, estoppel or otherwise under any patents
2762306a36Sopenharmony_cior trademarks of Motorola, Inc.
2862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2962306a36Sopenharmony_ci#
3062306a36Sopenharmony_ci# lfptop.s:
3162306a36Sopenharmony_ci#	This file is appended to the top of the 060ILSP package
3262306a36Sopenharmony_ci# and contains the entry points into the package. The user, in
3362306a36Sopenharmony_ci# effect, branches to one of the branch table entries located here.
3462306a36Sopenharmony_ci#
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	bra.l	_facoss_
3762306a36Sopenharmony_ci	short	0x0000
3862306a36Sopenharmony_ci	bra.l	_facosd_
3962306a36Sopenharmony_ci	short	0x0000
4062306a36Sopenharmony_ci	bra.l	_facosx_
4162306a36Sopenharmony_ci	short	0x0000
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	bra.l	_fasins_
4462306a36Sopenharmony_ci	short	0x0000
4562306a36Sopenharmony_ci	bra.l	_fasind_
4662306a36Sopenharmony_ci	short	0x0000
4762306a36Sopenharmony_ci	bra.l	_fasinx_
4862306a36Sopenharmony_ci	short	0x0000
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	bra.l	_fatans_
5162306a36Sopenharmony_ci	short	0x0000
5262306a36Sopenharmony_ci	bra.l	_fatand_
5362306a36Sopenharmony_ci	short	0x0000
5462306a36Sopenharmony_ci	bra.l	_fatanx_
5562306a36Sopenharmony_ci	short	0x0000
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	bra.l	_fatanhs_
5862306a36Sopenharmony_ci	short	0x0000
5962306a36Sopenharmony_ci	bra.l	_fatanhd_
6062306a36Sopenharmony_ci	short	0x0000
6162306a36Sopenharmony_ci	bra.l	_fatanhx_
6262306a36Sopenharmony_ci	short	0x0000
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	bra.l	_fcoss_
6562306a36Sopenharmony_ci	short	0x0000
6662306a36Sopenharmony_ci	bra.l	_fcosd_
6762306a36Sopenharmony_ci	short	0x0000
6862306a36Sopenharmony_ci	bra.l	_fcosx_
6962306a36Sopenharmony_ci	short	0x0000
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	bra.l	_fcoshs_
7262306a36Sopenharmony_ci	short	0x0000
7362306a36Sopenharmony_ci	bra.l	_fcoshd_
7462306a36Sopenharmony_ci	short	0x0000
7562306a36Sopenharmony_ci	bra.l	_fcoshx_
7662306a36Sopenharmony_ci	short	0x0000
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	bra.l	_fetoxs_
7962306a36Sopenharmony_ci	short	0x0000
8062306a36Sopenharmony_ci	bra.l	_fetoxd_
8162306a36Sopenharmony_ci	short	0x0000
8262306a36Sopenharmony_ci	bra.l	_fetoxx_
8362306a36Sopenharmony_ci	short	0x0000
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	bra.l	_fetoxm1s_
8662306a36Sopenharmony_ci	short	0x0000
8762306a36Sopenharmony_ci	bra.l	_fetoxm1d_
8862306a36Sopenharmony_ci	short	0x0000
8962306a36Sopenharmony_ci	bra.l	_fetoxm1x_
9062306a36Sopenharmony_ci	short	0x0000
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	bra.l	_fgetexps_
9362306a36Sopenharmony_ci	short	0x0000
9462306a36Sopenharmony_ci	bra.l	_fgetexpd_
9562306a36Sopenharmony_ci	short	0x0000
9662306a36Sopenharmony_ci	bra.l	_fgetexpx_
9762306a36Sopenharmony_ci	short	0x0000
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	bra.l	_fgetmans_
10062306a36Sopenharmony_ci	short	0x0000
10162306a36Sopenharmony_ci	bra.l	_fgetmand_
10262306a36Sopenharmony_ci	short	0x0000
10362306a36Sopenharmony_ci	bra.l	_fgetmanx_
10462306a36Sopenharmony_ci	short	0x0000
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	bra.l	_flog10s_
10762306a36Sopenharmony_ci	short	0x0000
10862306a36Sopenharmony_ci	bra.l	_flog10d_
10962306a36Sopenharmony_ci	short	0x0000
11062306a36Sopenharmony_ci	bra.l	_flog10x_
11162306a36Sopenharmony_ci	short	0x0000
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	bra.l	_flog2s_
11462306a36Sopenharmony_ci	short	0x0000
11562306a36Sopenharmony_ci	bra.l	_flog2d_
11662306a36Sopenharmony_ci	short	0x0000
11762306a36Sopenharmony_ci	bra.l	_flog2x_
11862306a36Sopenharmony_ci	short	0x0000
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	bra.l	_flogns_
12162306a36Sopenharmony_ci	short	0x0000
12262306a36Sopenharmony_ci	bra.l	_flognd_
12362306a36Sopenharmony_ci	short	0x0000
12462306a36Sopenharmony_ci	bra.l	_flognx_
12562306a36Sopenharmony_ci	short	0x0000
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	bra.l	_flognp1s_
12862306a36Sopenharmony_ci	short	0x0000
12962306a36Sopenharmony_ci	bra.l	_flognp1d_
13062306a36Sopenharmony_ci	short	0x0000
13162306a36Sopenharmony_ci	bra.l	_flognp1x_
13262306a36Sopenharmony_ci	short	0x0000
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	bra.l	_fmods_
13562306a36Sopenharmony_ci	short	0x0000
13662306a36Sopenharmony_ci	bra.l	_fmodd_
13762306a36Sopenharmony_ci	short	0x0000
13862306a36Sopenharmony_ci	bra.l	_fmodx_
13962306a36Sopenharmony_ci	short	0x0000
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	bra.l	_frems_
14262306a36Sopenharmony_ci	short	0x0000
14362306a36Sopenharmony_ci	bra.l	_fremd_
14462306a36Sopenharmony_ci	short	0x0000
14562306a36Sopenharmony_ci	bra.l	_fremx_
14662306a36Sopenharmony_ci	short	0x0000
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	bra.l	_fscales_
14962306a36Sopenharmony_ci	short	0x0000
15062306a36Sopenharmony_ci	bra.l	_fscaled_
15162306a36Sopenharmony_ci	short	0x0000
15262306a36Sopenharmony_ci	bra.l	_fscalex_
15362306a36Sopenharmony_ci	short	0x0000
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	bra.l	_fsins_
15662306a36Sopenharmony_ci	short	0x0000
15762306a36Sopenharmony_ci	bra.l	_fsind_
15862306a36Sopenharmony_ci	short	0x0000
15962306a36Sopenharmony_ci	bra.l	_fsinx_
16062306a36Sopenharmony_ci	short	0x0000
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	bra.l	_fsincoss_
16362306a36Sopenharmony_ci	short	0x0000
16462306a36Sopenharmony_ci	bra.l	_fsincosd_
16562306a36Sopenharmony_ci	short	0x0000
16662306a36Sopenharmony_ci	bra.l	_fsincosx_
16762306a36Sopenharmony_ci	short	0x0000
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	bra.l	_fsinhs_
17062306a36Sopenharmony_ci	short	0x0000
17162306a36Sopenharmony_ci	bra.l	_fsinhd_
17262306a36Sopenharmony_ci	short	0x0000
17362306a36Sopenharmony_ci	bra.l	_fsinhx_
17462306a36Sopenharmony_ci	short	0x0000
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	bra.l	_ftans_
17762306a36Sopenharmony_ci	short	0x0000
17862306a36Sopenharmony_ci	bra.l	_ftand_
17962306a36Sopenharmony_ci	short	0x0000
18062306a36Sopenharmony_ci	bra.l	_ftanx_
18162306a36Sopenharmony_ci	short	0x0000
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	bra.l	_ftanhs_
18462306a36Sopenharmony_ci	short	0x0000
18562306a36Sopenharmony_ci	bra.l	_ftanhd_
18662306a36Sopenharmony_ci	short	0x0000
18762306a36Sopenharmony_ci	bra.l	_ftanhx_
18862306a36Sopenharmony_ci	short	0x0000
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	bra.l	_ftentoxs_
19162306a36Sopenharmony_ci	short	0x0000
19262306a36Sopenharmony_ci	bra.l	_ftentoxd_
19362306a36Sopenharmony_ci	short	0x0000
19462306a36Sopenharmony_ci	bra.l	_ftentoxx_
19562306a36Sopenharmony_ci	short	0x0000
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	bra.l	_ftwotoxs_
19862306a36Sopenharmony_ci	short	0x0000
19962306a36Sopenharmony_ci	bra.l	_ftwotoxd_
20062306a36Sopenharmony_ci	short	0x0000
20162306a36Sopenharmony_ci	bra.l	_ftwotoxx_
20262306a36Sopenharmony_ci	short	0x0000
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	bra.l	_fabss_
20562306a36Sopenharmony_ci	short	0x0000
20662306a36Sopenharmony_ci	bra.l	_fabsd_
20762306a36Sopenharmony_ci	short	0x0000
20862306a36Sopenharmony_ci	bra.l	_fabsx_
20962306a36Sopenharmony_ci	short	0x0000
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	bra.l	_fadds_
21262306a36Sopenharmony_ci	short	0x0000
21362306a36Sopenharmony_ci	bra.l	_faddd_
21462306a36Sopenharmony_ci	short	0x0000
21562306a36Sopenharmony_ci	bra.l	_faddx_
21662306a36Sopenharmony_ci	short	0x0000
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	bra.l	_fdivs_
21962306a36Sopenharmony_ci	short	0x0000
22062306a36Sopenharmony_ci	bra.l	_fdivd_
22162306a36Sopenharmony_ci	short	0x0000
22262306a36Sopenharmony_ci	bra.l	_fdivx_
22362306a36Sopenharmony_ci	short	0x0000
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	bra.l	_fints_
22662306a36Sopenharmony_ci	short	0x0000
22762306a36Sopenharmony_ci	bra.l	_fintd_
22862306a36Sopenharmony_ci	short	0x0000
22962306a36Sopenharmony_ci	bra.l	_fintx_
23062306a36Sopenharmony_ci	short	0x0000
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	bra.l	_fintrzs_
23362306a36Sopenharmony_ci	short	0x0000
23462306a36Sopenharmony_ci	bra.l	_fintrzd_
23562306a36Sopenharmony_ci	short	0x0000
23662306a36Sopenharmony_ci	bra.l	_fintrzx_
23762306a36Sopenharmony_ci	short	0x0000
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	bra.l	_fmuls_
24062306a36Sopenharmony_ci	short	0x0000
24162306a36Sopenharmony_ci	bra.l	_fmuld_
24262306a36Sopenharmony_ci	short	0x0000
24362306a36Sopenharmony_ci	bra.l	_fmulx_
24462306a36Sopenharmony_ci	short	0x0000
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	bra.l	_fnegs_
24762306a36Sopenharmony_ci	short	0x0000
24862306a36Sopenharmony_ci	bra.l	_fnegd_
24962306a36Sopenharmony_ci	short	0x0000
25062306a36Sopenharmony_ci	bra.l	_fnegx_
25162306a36Sopenharmony_ci	short	0x0000
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	bra.l	_fsqrts_
25462306a36Sopenharmony_ci	short	0x0000
25562306a36Sopenharmony_ci	bra.l	_fsqrtd_
25662306a36Sopenharmony_ci	short	0x0000
25762306a36Sopenharmony_ci	bra.l	_fsqrtx_
25862306a36Sopenharmony_ci	short	0x0000
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	bra.l	_fsubs_
26162306a36Sopenharmony_ci	short	0x0000
26262306a36Sopenharmony_ci	bra.l	_fsubd_
26362306a36Sopenharmony_ci	short	0x0000
26462306a36Sopenharmony_ci	bra.l	_fsubx_
26562306a36Sopenharmony_ci	short	0x0000
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci# leave room for future possible additions
26862306a36Sopenharmony_ci	align	0x400
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci#
27162306a36Sopenharmony_ci# This file contains a set of define statements for constants
27262306a36Sopenharmony_ci# in order to promote readability within the corecode itself.
27362306a36Sopenharmony_ci#
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ciset LOCAL_SIZE,		192			# stack frame size(bytes)
27662306a36Sopenharmony_ciset LV,			-LOCAL_SIZE		# stack offset
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ciset EXC_SR,		0x4			# stack status register
27962306a36Sopenharmony_ciset EXC_PC,		0x6			# stack pc
28062306a36Sopenharmony_ciset EXC_VOFF,		0xa			# stacked vector offset
28162306a36Sopenharmony_ciset EXC_EA,		0xc			# stacked <ea>
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ciset EXC_FP,		0x0			# frame pointer
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ciset EXC_AREGS,		-68			# offset of all address regs
28662306a36Sopenharmony_ciset EXC_DREGS,		-100			# offset of all data regs
28762306a36Sopenharmony_ciset EXC_FPREGS,		-36			# offset of all fp regs
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ciset EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
29062306a36Sopenharmony_ciset OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
29162306a36Sopenharmony_ciset EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
29262306a36Sopenharmony_ciset EXC_A5,		EXC_AREGS+(5*4)
29362306a36Sopenharmony_ciset EXC_A4,		EXC_AREGS+(4*4)
29462306a36Sopenharmony_ciset EXC_A3,		EXC_AREGS+(3*4)
29562306a36Sopenharmony_ciset EXC_A2,		EXC_AREGS+(2*4)
29662306a36Sopenharmony_ciset EXC_A1,		EXC_AREGS+(1*4)
29762306a36Sopenharmony_ciset EXC_A0,		EXC_AREGS+(0*4)
29862306a36Sopenharmony_ciset EXC_D7,		EXC_DREGS+(7*4)
29962306a36Sopenharmony_ciset EXC_D6,		EXC_DREGS+(6*4)
30062306a36Sopenharmony_ciset EXC_D5,		EXC_DREGS+(5*4)
30162306a36Sopenharmony_ciset EXC_D4,		EXC_DREGS+(4*4)
30262306a36Sopenharmony_ciset EXC_D3,		EXC_DREGS+(3*4)
30362306a36Sopenharmony_ciset EXC_D2,		EXC_DREGS+(2*4)
30462306a36Sopenharmony_ciset EXC_D1,		EXC_DREGS+(1*4)
30562306a36Sopenharmony_ciset EXC_D0,		EXC_DREGS+(0*4)
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ciset EXC_FP0,		EXC_FPREGS+(0*12)	# offset of saved fp0
30862306a36Sopenharmony_ciset EXC_FP1,		EXC_FPREGS+(1*12)	# offset of saved fp1
30962306a36Sopenharmony_ciset EXC_FP2,		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ciset FP_SCR1,		LV+80			# fp scratch 1
31262306a36Sopenharmony_ciset FP_SCR1_EX,		FP_SCR1+0
31362306a36Sopenharmony_ciset FP_SCR1_SGN,	FP_SCR1+2
31462306a36Sopenharmony_ciset FP_SCR1_HI,		FP_SCR1+4
31562306a36Sopenharmony_ciset FP_SCR1_LO,		FP_SCR1+8
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ciset FP_SCR0,		LV+68			# fp scratch 0
31862306a36Sopenharmony_ciset FP_SCR0_EX,		FP_SCR0+0
31962306a36Sopenharmony_ciset FP_SCR0_SGN,	FP_SCR0+2
32062306a36Sopenharmony_ciset FP_SCR0_HI,		FP_SCR0+4
32162306a36Sopenharmony_ciset FP_SCR0_LO,		FP_SCR0+8
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ciset FP_DST,		LV+56			# fp destination operand
32462306a36Sopenharmony_ciset FP_DST_EX,		FP_DST+0
32562306a36Sopenharmony_ciset FP_DST_SGN,		FP_DST+2
32662306a36Sopenharmony_ciset FP_DST_HI,		FP_DST+4
32762306a36Sopenharmony_ciset FP_DST_LO,		FP_DST+8
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ciset FP_SRC,		LV+44			# fp source operand
33062306a36Sopenharmony_ciset FP_SRC_EX,		FP_SRC+0
33162306a36Sopenharmony_ciset FP_SRC_SGN,		FP_SRC+2
33262306a36Sopenharmony_ciset FP_SRC_HI,		FP_SRC+4
33362306a36Sopenharmony_ciset FP_SRC_LO,		FP_SRC+8
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ciset USER_FPIAR,		LV+40			# FP instr address register
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ciset USER_FPSR,		LV+36			# FP status register
33862306a36Sopenharmony_ciset FPSR_CC,		USER_FPSR+0		# FPSR condition codes
33962306a36Sopenharmony_ciset FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
34062306a36Sopenharmony_ciset FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
34162306a36Sopenharmony_ciset FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ciset USER_FPCR,		LV+32			# FP control register
34462306a36Sopenharmony_ciset FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
34562306a36Sopenharmony_ciset FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ciset L_SCR3,		LV+28			# integer scratch 3
34862306a36Sopenharmony_ciset L_SCR2,		LV+24			# integer scratch 2
34962306a36Sopenharmony_ciset L_SCR1,		LV+20			# integer scratch 1
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ciset STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ciset EXC_TEMP2,		LV+24			# temporary space
35462306a36Sopenharmony_ciset EXC_TEMP,		LV+16			# temporary space
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ciset DTAG,		LV+15			# destination operand type
35762306a36Sopenharmony_ciset STAG,		LV+14			# source operand type
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ciset SPCOND_FLG,		LV+10			# flag: special case (see below)
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ciset EXC_CC,		LV+8			# saved condition codes
36262306a36Sopenharmony_ciset EXC_EXTWPTR,	LV+4			# saved current PC (active)
36362306a36Sopenharmony_ciset EXC_EXTWORD,	LV+2			# saved extension word
36462306a36Sopenharmony_ciset EXC_CMDREG,		LV+2			# saved extension word
36562306a36Sopenharmony_ciset EXC_OPWORD,		LV+0			# saved operation word
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci################################
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci# Helpful macros
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ciset FTEMP,		0			# offsets within an
37262306a36Sopenharmony_ciset FTEMP_EX,		0			# extended precision
37362306a36Sopenharmony_ciset FTEMP_SGN,		2			# value saved in memory.
37462306a36Sopenharmony_ciset FTEMP_HI,		4
37562306a36Sopenharmony_ciset FTEMP_LO,		8
37662306a36Sopenharmony_ciset FTEMP_GRS,		12
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ciset LOCAL,		0			# offsets within an
37962306a36Sopenharmony_ciset LOCAL_EX,		0			# extended precision
38062306a36Sopenharmony_ciset LOCAL_SGN,		2			# value saved in memory.
38162306a36Sopenharmony_ciset LOCAL_HI,		4
38262306a36Sopenharmony_ciset LOCAL_LO,		8
38362306a36Sopenharmony_ciset LOCAL_GRS,		12
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ciset DST,		0			# offsets within an
38662306a36Sopenharmony_ciset DST_EX,		0			# extended precision
38762306a36Sopenharmony_ciset DST_HI,		4			# value saved in memory.
38862306a36Sopenharmony_ciset DST_LO,		8
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ciset SRC,		0			# offsets within an
39162306a36Sopenharmony_ciset SRC_EX,		0			# extended precision
39262306a36Sopenharmony_ciset SRC_HI,		4			# value saved in memory.
39362306a36Sopenharmony_ciset SRC_LO,		8
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ciset SGL_LO,		0x3f81			# min sgl prec exponent
39662306a36Sopenharmony_ciset SGL_HI,		0x407e			# max sgl prec exponent
39762306a36Sopenharmony_ciset DBL_LO,		0x3c01			# min dbl prec exponent
39862306a36Sopenharmony_ciset DBL_HI,		0x43fe			# max dbl prec exponent
39962306a36Sopenharmony_ciset EXT_LO,		0x0			# min ext prec exponent
40062306a36Sopenharmony_ciset EXT_HI,		0x7ffe			# max ext prec exponent
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ciset EXT_BIAS,		0x3fff			# extended precision bias
40362306a36Sopenharmony_ciset SGL_BIAS,		0x007f			# single precision bias
40462306a36Sopenharmony_ciset DBL_BIAS,		0x03ff			# double precision bias
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ciset NORM,		0x00			# operand type for STAG/DTAG
40762306a36Sopenharmony_ciset ZERO,		0x01			# operand type for STAG/DTAG
40862306a36Sopenharmony_ciset INF,		0x02			# operand type for STAG/DTAG
40962306a36Sopenharmony_ciset QNAN,		0x03			# operand type for STAG/DTAG
41062306a36Sopenharmony_ciset DENORM,		0x04			# operand type for STAG/DTAG
41162306a36Sopenharmony_ciset SNAN,		0x05			# operand type for STAG/DTAG
41262306a36Sopenharmony_ciset UNNORM,		0x06			# operand type for STAG/DTAG
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci##################
41562306a36Sopenharmony_ci# FPSR/FPCR bits #
41662306a36Sopenharmony_ci##################
41762306a36Sopenharmony_ciset neg_bit,		0x3			# negative result
41862306a36Sopenharmony_ciset z_bit,		0x2			# zero result
41962306a36Sopenharmony_ciset inf_bit,		0x1			# infinite result
42062306a36Sopenharmony_ciset nan_bit,		0x0			# NAN result
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ciset q_sn_bit,		0x7			# sign bit of quotient byte
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ciset bsun_bit,		7			# branch on unordered
42562306a36Sopenharmony_ciset snan_bit,		6			# signalling NAN
42662306a36Sopenharmony_ciset operr_bit,		5			# operand error
42762306a36Sopenharmony_ciset ovfl_bit,		4			# overflow
42862306a36Sopenharmony_ciset unfl_bit,		3			# underflow
42962306a36Sopenharmony_ciset dz_bit,		2			# divide by zero
43062306a36Sopenharmony_ciset inex2_bit,		1			# inexact result 2
43162306a36Sopenharmony_ciset inex1_bit,		0			# inexact result 1
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ciset aiop_bit,		7			# accrued inexact operation bit
43462306a36Sopenharmony_ciset aovfl_bit,		6			# accrued overflow bit
43562306a36Sopenharmony_ciset aunfl_bit,		5			# accrued underflow bit
43662306a36Sopenharmony_ciset adz_bit,		4			# accrued dz bit
43762306a36Sopenharmony_ciset ainex_bit,		3			# accrued inexact bit
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci#############################
44062306a36Sopenharmony_ci# FPSR individual bit masks #
44162306a36Sopenharmony_ci#############################
44262306a36Sopenharmony_ciset neg_mask,		0x08000000		# negative bit mask (lw)
44362306a36Sopenharmony_ciset inf_mask,		0x02000000		# infinity bit mask (lw)
44462306a36Sopenharmony_ciset z_mask,		0x04000000		# zero bit mask (lw)
44562306a36Sopenharmony_ciset nan_mask,		0x01000000		# nan bit mask (lw)
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ciset neg_bmask,		0x08			# negative bit mask (byte)
44862306a36Sopenharmony_ciset inf_bmask,		0x02			# infinity bit mask (byte)
44962306a36Sopenharmony_ciset z_bmask,		0x04			# zero bit mask (byte)
45062306a36Sopenharmony_ciset nan_bmask,		0x01			# nan bit mask (byte)
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ciset bsun_mask,		0x00008000		# bsun exception mask
45362306a36Sopenharmony_ciset snan_mask,		0x00004000		# snan exception mask
45462306a36Sopenharmony_ciset operr_mask,		0x00002000		# operr exception mask
45562306a36Sopenharmony_ciset ovfl_mask,		0x00001000		# overflow exception mask
45662306a36Sopenharmony_ciset unfl_mask,		0x00000800		# underflow exception mask
45762306a36Sopenharmony_ciset dz_mask,		0x00000400		# dz exception mask
45862306a36Sopenharmony_ciset inex2_mask,		0x00000200		# inex2 exception mask
45962306a36Sopenharmony_ciset inex1_mask,		0x00000100		# inex1 exception mask
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ciset aiop_mask,		0x00000080		# accrued illegal operation
46262306a36Sopenharmony_ciset aovfl_mask,		0x00000040		# accrued overflow
46362306a36Sopenharmony_ciset aunfl_mask,		0x00000020		# accrued underflow
46462306a36Sopenharmony_ciset adz_mask,		0x00000010		# accrued divide by zero
46562306a36Sopenharmony_ciset ainex_mask,		0x00000008		# accrued inexact
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci######################################
46862306a36Sopenharmony_ci# FPSR combinations used in the FPSP #
46962306a36Sopenharmony_ci######################################
47062306a36Sopenharmony_ciset dzinf_mask,		inf_mask+dz_mask+adz_mask
47162306a36Sopenharmony_ciset opnan_mask,		nan_mask+operr_mask+aiop_mask
47262306a36Sopenharmony_ciset nzi_mask,		0x01ffffff		#clears N, Z, and I
47362306a36Sopenharmony_ciset unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
47462306a36Sopenharmony_ciset unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
47562306a36Sopenharmony_ciset ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
47662306a36Sopenharmony_ciset inx1a_mask,		inex1_mask+ainex_mask
47762306a36Sopenharmony_ciset inx2a_mask,		inex2_mask+ainex_mask
47862306a36Sopenharmony_ciset snaniop_mask,	nan_mask+snan_mask+aiop_mask
47962306a36Sopenharmony_ciset snaniop2_mask,	snan_mask+aiop_mask
48062306a36Sopenharmony_ciset naniop_mask,	nan_mask+aiop_mask
48162306a36Sopenharmony_ciset neginf_mask,	neg_mask+inf_mask
48262306a36Sopenharmony_ciset infaiop_mask,	inf_mask+aiop_mask
48362306a36Sopenharmony_ciset negz_mask,		neg_mask+z_mask
48462306a36Sopenharmony_ciset opaop_mask,		operr_mask+aiop_mask
48562306a36Sopenharmony_ciset unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
48662306a36Sopenharmony_ciset ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci#########
48962306a36Sopenharmony_ci# misc. #
49062306a36Sopenharmony_ci#########
49162306a36Sopenharmony_ciset rnd_stky_bit,	29			# stky bit pos in longword
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ciset sign_bit,		0x7			# sign bit
49462306a36Sopenharmony_ciset signan_bit,		0x6			# signalling nan bit
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ciset sgl_thresh,		0x3f81			# minimum sgl exponent
49762306a36Sopenharmony_ciset dbl_thresh,		0x3c01			# minimum dbl exponent
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ciset x_mode,		0x0			# extended precision
50062306a36Sopenharmony_ciset s_mode,		0x4			# single precision
50162306a36Sopenharmony_ciset d_mode,		0x8			# double precision
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ciset rn_mode,		0x0			# round-to-nearest
50462306a36Sopenharmony_ciset rz_mode,		0x1			# round-to-zero
50562306a36Sopenharmony_ciset rm_mode,		0x2			# round-tp-minus-infinity
50662306a36Sopenharmony_ciset rp_mode,		0x3			# round-to-plus-infinity
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ciset mantissalen,	64			# length of mantissa in bits
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ciset BYTE,		1			# len(byte) == 1 byte
51162306a36Sopenharmony_ciset WORD,		2			# len(word) == 2 bytes
51262306a36Sopenharmony_ciset LONG,		4			# len(longword) == 2 bytes
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ciset BSUN_VEC,		0xc0			# bsun    vector offset
51562306a36Sopenharmony_ciset INEX_VEC,		0xc4			# inexact vector offset
51662306a36Sopenharmony_ciset DZ_VEC,		0xc8			# dz      vector offset
51762306a36Sopenharmony_ciset UNFL_VEC,		0xcc			# unfl    vector offset
51862306a36Sopenharmony_ciset OPERR_VEC,		0xd0			# operr   vector offset
51962306a36Sopenharmony_ciset OVFL_VEC,		0xd4			# ovfl    vector offset
52062306a36Sopenharmony_ciset SNAN_VEC,		0xd8			# snan    vector offset
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci###########################
52362306a36Sopenharmony_ci# SPecial CONDition FLaGs #
52462306a36Sopenharmony_ci###########################
52562306a36Sopenharmony_ciset ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
52662306a36Sopenharmony_ciset fbsun_flg,		0x02			# flag bit: bsun exception
52762306a36Sopenharmony_ciset mia7_flg,		0x04			# flag bit: (a7)+ <ea>
52862306a36Sopenharmony_ciset mda7_flg,		0x08			# flag bit: -(a7) <ea>
52962306a36Sopenharmony_ciset fmovm_flg,		0x40			# flag bit: fmovm instruction
53062306a36Sopenharmony_ciset immed_flg,		0x80			# flag bit: &<data> <ea>
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ciset ftrapcc_bit,	0x0
53362306a36Sopenharmony_ciset fbsun_bit,		0x1
53462306a36Sopenharmony_ciset mia7_bit,		0x2
53562306a36Sopenharmony_ciset mda7_bit,		0x3
53662306a36Sopenharmony_ciset immed_bit,		0x7
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci##################################
53962306a36Sopenharmony_ci# TRANSCENDENTAL "LAST-OP" FLAGS #
54062306a36Sopenharmony_ci##################################
54162306a36Sopenharmony_ciset FMUL_OP,		0x0			# fmul instr performed last
54262306a36Sopenharmony_ciset FDIV_OP,		0x1			# fdiv performed last
54362306a36Sopenharmony_ciset FADD_OP,		0x2			# fadd performed last
54462306a36Sopenharmony_ciset FMOV_OP,		0x3			# fmov performed last
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci#############
54762306a36Sopenharmony_ci# CONSTANTS #
54862306a36Sopenharmony_ci#############
54962306a36Sopenharmony_ciT1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
55062306a36Sopenharmony_ciT2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ciPI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
55362306a36Sopenharmony_ciPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ciTWOBYPI:
55662306a36Sopenharmony_ci	long		0x3FE45F30,0x6DC9C883
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci#########################################################################
55962306a36Sopenharmony_ci# MONADIC TEMPLATE							#
56062306a36Sopenharmony_ci#########################################################################
56162306a36Sopenharmony_ci	global		_fsins_
56262306a36Sopenharmony_ci_fsins_:
56362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
56662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
56762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci#
57262306a36Sopenharmony_ci#	copy, convert, and tag input argument
57362306a36Sopenharmony_ci#
57462306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
57562306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
57662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
57762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
57862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
57962306a36Sopenharmony_ci	mov.b		%d0,%d1
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	clr.l		%d0
58462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci	tst.b		%d1
58762306a36Sopenharmony_ci	bne.b		_L0_2s
58862306a36Sopenharmony_ci	bsr.l		ssin			# operand is a NORM
58962306a36Sopenharmony_ci	bra.b		_L0_6s
59062306a36Sopenharmony_ci_L0_2s:
59162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
59262306a36Sopenharmony_ci	bne.b		_L0_3s			# no
59362306a36Sopenharmony_ci	bsr.l		src_zero			# yes
59462306a36Sopenharmony_ci	bra.b		_L0_6s
59562306a36Sopenharmony_ci_L0_3s:
59662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
59762306a36Sopenharmony_ci	bne.b		_L0_4s			# no
59862306a36Sopenharmony_ci	bsr.l		t_operr			# yes
59962306a36Sopenharmony_ci	bra.b		_L0_6s
60062306a36Sopenharmony_ci_L0_4s:
60162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
60262306a36Sopenharmony_ci	bne.b		_L0_5s			# no
60362306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
60462306a36Sopenharmony_ci	bra.b		_L0_6s
60562306a36Sopenharmony_ci_L0_5s:
60662306a36Sopenharmony_ci	bsr.l		ssind			# operand is a DENORM
60762306a36Sopenharmony_ci_L0_6s:
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci#
61062306a36Sopenharmony_ci#	Result is now in FP0
61162306a36Sopenharmony_ci#
61262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
61362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
61462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
61562306a36Sopenharmony_ci	unlk		%a6
61662306a36Sopenharmony_ci	rts
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	global		_fsind_
61962306a36Sopenharmony_ci_fsind_:
62062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
62362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
62462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci#
62962306a36Sopenharmony_ci#	copy, convert, and tag input argument
63062306a36Sopenharmony_ci#
63162306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
63262306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
63362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
63462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
63562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
63662306a36Sopenharmony_ci	mov.b		%d0,%d1
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	clr.l		%d0
64162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
64462306a36Sopenharmony_ci	tst.b		%d1
64562306a36Sopenharmony_ci	bne.b		_L0_2d
64662306a36Sopenharmony_ci	bsr.l		ssin			# operand is a NORM
64762306a36Sopenharmony_ci	bra.b		_L0_6d
64862306a36Sopenharmony_ci_L0_2d:
64962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
65062306a36Sopenharmony_ci	bne.b		_L0_3d			# no
65162306a36Sopenharmony_ci	bsr.l		src_zero			# yes
65262306a36Sopenharmony_ci	bra.b		_L0_6d
65362306a36Sopenharmony_ci_L0_3d:
65462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
65562306a36Sopenharmony_ci	bne.b		_L0_4d			# no
65662306a36Sopenharmony_ci	bsr.l		t_operr			# yes
65762306a36Sopenharmony_ci	bra.b		_L0_6d
65862306a36Sopenharmony_ci_L0_4d:
65962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
66062306a36Sopenharmony_ci	bne.b		_L0_5d			# no
66162306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
66262306a36Sopenharmony_ci	bra.b		_L0_6d
66362306a36Sopenharmony_ci_L0_5d:
66462306a36Sopenharmony_ci	bsr.l		ssind			# operand is a DENORM
66562306a36Sopenharmony_ci_L0_6d:
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci#
66862306a36Sopenharmony_ci#	Result is now in FP0
66962306a36Sopenharmony_ci#
67062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
67162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
67262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
67362306a36Sopenharmony_ci	unlk		%a6
67462306a36Sopenharmony_ci	rts
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	global		_fsinx_
67762306a36Sopenharmony_ci_fsinx_:
67862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
68162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
68262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci#
68762306a36Sopenharmony_ci#	copy, convert, and tag input argument
68862306a36Sopenharmony_ci#
68962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
69062306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
69162306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
69262306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
69362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
69462306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
69562306a36Sopenharmony_ci	mov.b		%d0,%d1
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	clr.l		%d0
70062306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	tst.b		%d1
70362306a36Sopenharmony_ci	bne.b		_L0_2x
70462306a36Sopenharmony_ci	bsr.l		ssin			# operand is a NORM
70562306a36Sopenharmony_ci	bra.b		_L0_6x
70662306a36Sopenharmony_ci_L0_2x:
70762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
70862306a36Sopenharmony_ci	bne.b		_L0_3x			# no
70962306a36Sopenharmony_ci	bsr.l		src_zero			# yes
71062306a36Sopenharmony_ci	bra.b		_L0_6x
71162306a36Sopenharmony_ci_L0_3x:
71262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
71362306a36Sopenharmony_ci	bne.b		_L0_4x			# no
71462306a36Sopenharmony_ci	bsr.l		t_operr			# yes
71562306a36Sopenharmony_ci	bra.b		_L0_6x
71662306a36Sopenharmony_ci_L0_4x:
71762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
71862306a36Sopenharmony_ci	bne.b		_L0_5x			# no
71962306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
72062306a36Sopenharmony_ci	bra.b		_L0_6x
72162306a36Sopenharmony_ci_L0_5x:
72262306a36Sopenharmony_ci	bsr.l		ssind			# operand is a DENORM
72362306a36Sopenharmony_ci_L0_6x:
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci#
72662306a36Sopenharmony_ci#	Result is now in FP0
72762306a36Sopenharmony_ci#
72862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
72962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
73062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
73162306a36Sopenharmony_ci	unlk		%a6
73262306a36Sopenharmony_ci	rts
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci#########################################################################
73662306a36Sopenharmony_ci# MONADIC TEMPLATE							#
73762306a36Sopenharmony_ci#########################################################################
73862306a36Sopenharmony_ci	global		_fcoss_
73962306a36Sopenharmony_ci_fcoss_:
74062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
74362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
74462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci#
74962306a36Sopenharmony_ci#	copy, convert, and tag input argument
75062306a36Sopenharmony_ci#
75162306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
75262306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
75362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
75462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
75562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
75662306a36Sopenharmony_ci	mov.b		%d0,%d1
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ci	clr.l		%d0
76162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci	tst.b		%d1
76462306a36Sopenharmony_ci	bne.b		_L1_2s
76562306a36Sopenharmony_ci	bsr.l		scos			# operand is a NORM
76662306a36Sopenharmony_ci	bra.b		_L1_6s
76762306a36Sopenharmony_ci_L1_2s:
76862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
76962306a36Sopenharmony_ci	bne.b		_L1_3s			# no
77062306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
77162306a36Sopenharmony_ci	bra.b		_L1_6s
77262306a36Sopenharmony_ci_L1_3s:
77362306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
77462306a36Sopenharmony_ci	bne.b		_L1_4s			# no
77562306a36Sopenharmony_ci	bsr.l		t_operr			# yes
77662306a36Sopenharmony_ci	bra.b		_L1_6s
77762306a36Sopenharmony_ci_L1_4s:
77862306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
77962306a36Sopenharmony_ci	bne.b		_L1_5s			# no
78062306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
78162306a36Sopenharmony_ci	bra.b		_L1_6s
78262306a36Sopenharmony_ci_L1_5s:
78362306a36Sopenharmony_ci	bsr.l		scosd			# operand is a DENORM
78462306a36Sopenharmony_ci_L1_6s:
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci#
78762306a36Sopenharmony_ci#	Result is now in FP0
78862306a36Sopenharmony_ci#
78962306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
79062306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
79162306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
79262306a36Sopenharmony_ci	unlk		%a6
79362306a36Sopenharmony_ci	rts
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	global		_fcosd_
79662306a36Sopenharmony_ci_fcosd_:
79762306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
80062306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
80162306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci#
80662306a36Sopenharmony_ci#	copy, convert, and tag input argument
80762306a36Sopenharmony_ci#
80862306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
80962306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
81062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
81162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
81262306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
81362306a36Sopenharmony_ci	mov.b		%d0,%d1
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci	clr.l		%d0
81862306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
82162306a36Sopenharmony_ci	tst.b		%d1
82262306a36Sopenharmony_ci	bne.b		_L1_2d
82362306a36Sopenharmony_ci	bsr.l		scos			# operand is a NORM
82462306a36Sopenharmony_ci	bra.b		_L1_6d
82562306a36Sopenharmony_ci_L1_2d:
82662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
82762306a36Sopenharmony_ci	bne.b		_L1_3d			# no
82862306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
82962306a36Sopenharmony_ci	bra.b		_L1_6d
83062306a36Sopenharmony_ci_L1_3d:
83162306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
83262306a36Sopenharmony_ci	bne.b		_L1_4d			# no
83362306a36Sopenharmony_ci	bsr.l		t_operr			# yes
83462306a36Sopenharmony_ci	bra.b		_L1_6d
83562306a36Sopenharmony_ci_L1_4d:
83662306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
83762306a36Sopenharmony_ci	bne.b		_L1_5d			# no
83862306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
83962306a36Sopenharmony_ci	bra.b		_L1_6d
84062306a36Sopenharmony_ci_L1_5d:
84162306a36Sopenharmony_ci	bsr.l		scosd			# operand is a DENORM
84262306a36Sopenharmony_ci_L1_6d:
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci#
84562306a36Sopenharmony_ci#	Result is now in FP0
84662306a36Sopenharmony_ci#
84762306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
84862306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
84962306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
85062306a36Sopenharmony_ci	unlk		%a6
85162306a36Sopenharmony_ci	rts
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci	global		_fcosx_
85462306a36Sopenharmony_ci_fcosx_:
85562306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
85862306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
85962306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci#
86462306a36Sopenharmony_ci#	copy, convert, and tag input argument
86562306a36Sopenharmony_ci#
86662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
86762306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
86862306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
86962306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
87062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
87162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
87262306a36Sopenharmony_ci	mov.b		%d0,%d1
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	clr.l		%d0
87762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	tst.b		%d1
88062306a36Sopenharmony_ci	bne.b		_L1_2x
88162306a36Sopenharmony_ci	bsr.l		scos			# operand is a NORM
88262306a36Sopenharmony_ci	bra.b		_L1_6x
88362306a36Sopenharmony_ci_L1_2x:
88462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
88562306a36Sopenharmony_ci	bne.b		_L1_3x			# no
88662306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
88762306a36Sopenharmony_ci	bra.b		_L1_6x
88862306a36Sopenharmony_ci_L1_3x:
88962306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
89062306a36Sopenharmony_ci	bne.b		_L1_4x			# no
89162306a36Sopenharmony_ci	bsr.l		t_operr			# yes
89262306a36Sopenharmony_ci	bra.b		_L1_6x
89362306a36Sopenharmony_ci_L1_4x:
89462306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
89562306a36Sopenharmony_ci	bne.b		_L1_5x			# no
89662306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
89762306a36Sopenharmony_ci	bra.b		_L1_6x
89862306a36Sopenharmony_ci_L1_5x:
89962306a36Sopenharmony_ci	bsr.l		scosd			# operand is a DENORM
90062306a36Sopenharmony_ci_L1_6x:
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci#
90362306a36Sopenharmony_ci#	Result is now in FP0
90462306a36Sopenharmony_ci#
90562306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
90662306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
90762306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
90862306a36Sopenharmony_ci	unlk		%a6
90962306a36Sopenharmony_ci	rts
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci#########################################################################
91362306a36Sopenharmony_ci# MONADIC TEMPLATE							#
91462306a36Sopenharmony_ci#########################################################################
91562306a36Sopenharmony_ci	global		_fsinhs_
91662306a36Sopenharmony_ci_fsinhs_:
91762306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
92062306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
92162306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci#
92662306a36Sopenharmony_ci#	copy, convert, and tag input argument
92762306a36Sopenharmony_ci#
92862306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
92962306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
93062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
93162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
93262306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
93362306a36Sopenharmony_ci	mov.b		%d0,%d1
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci	clr.l		%d0
93862306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_ci	tst.b		%d1
94162306a36Sopenharmony_ci	bne.b		_L2_2s
94262306a36Sopenharmony_ci	bsr.l		ssinh			# operand is a NORM
94362306a36Sopenharmony_ci	bra.b		_L2_6s
94462306a36Sopenharmony_ci_L2_2s:
94562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
94662306a36Sopenharmony_ci	bne.b		_L2_3s			# no
94762306a36Sopenharmony_ci	bsr.l		src_zero			# yes
94862306a36Sopenharmony_ci	bra.b		_L2_6s
94962306a36Sopenharmony_ci_L2_3s:
95062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
95162306a36Sopenharmony_ci	bne.b		_L2_4s			# no
95262306a36Sopenharmony_ci	bsr.l		src_inf			# yes
95362306a36Sopenharmony_ci	bra.b		_L2_6s
95462306a36Sopenharmony_ci_L2_4s:
95562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
95662306a36Sopenharmony_ci	bne.b		_L2_5s			# no
95762306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
95862306a36Sopenharmony_ci	bra.b		_L2_6s
95962306a36Sopenharmony_ci_L2_5s:
96062306a36Sopenharmony_ci	bsr.l		ssinhd			# operand is a DENORM
96162306a36Sopenharmony_ci_L2_6s:
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci#
96462306a36Sopenharmony_ci#	Result is now in FP0
96562306a36Sopenharmony_ci#
96662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
96762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
96862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
96962306a36Sopenharmony_ci	unlk		%a6
97062306a36Sopenharmony_ci	rts
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci	global		_fsinhd_
97362306a36Sopenharmony_ci_fsinhd_:
97462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
97762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
97862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci#
98362306a36Sopenharmony_ci#	copy, convert, and tag input argument
98462306a36Sopenharmony_ci#
98562306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
98662306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
98762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
98862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
98962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
99062306a36Sopenharmony_ci	mov.b		%d0,%d1
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	clr.l		%d0
99562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
99662306a36Sopenharmony_ci
99762306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
99862306a36Sopenharmony_ci	tst.b		%d1
99962306a36Sopenharmony_ci	bne.b		_L2_2d
100062306a36Sopenharmony_ci	bsr.l		ssinh			# operand is a NORM
100162306a36Sopenharmony_ci	bra.b		_L2_6d
100262306a36Sopenharmony_ci_L2_2d:
100362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
100462306a36Sopenharmony_ci	bne.b		_L2_3d			# no
100562306a36Sopenharmony_ci	bsr.l		src_zero			# yes
100662306a36Sopenharmony_ci	bra.b		_L2_6d
100762306a36Sopenharmony_ci_L2_3d:
100862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
100962306a36Sopenharmony_ci	bne.b		_L2_4d			# no
101062306a36Sopenharmony_ci	bsr.l		src_inf			# yes
101162306a36Sopenharmony_ci	bra.b		_L2_6d
101262306a36Sopenharmony_ci_L2_4d:
101362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
101462306a36Sopenharmony_ci	bne.b		_L2_5d			# no
101562306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
101662306a36Sopenharmony_ci	bra.b		_L2_6d
101762306a36Sopenharmony_ci_L2_5d:
101862306a36Sopenharmony_ci	bsr.l		ssinhd			# operand is a DENORM
101962306a36Sopenharmony_ci_L2_6d:
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci#
102262306a36Sopenharmony_ci#	Result is now in FP0
102362306a36Sopenharmony_ci#
102462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
102562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
102662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
102762306a36Sopenharmony_ci	unlk		%a6
102862306a36Sopenharmony_ci	rts
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	global		_fsinhx_
103162306a36Sopenharmony_ci_fsinhx_:
103262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
103562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
103662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
103762306a36Sopenharmony_ci
103862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci#
104162306a36Sopenharmony_ci#	copy, convert, and tag input argument
104262306a36Sopenharmony_ci#
104362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
104462306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
104562306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
104662306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
104762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
104862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
104962306a36Sopenharmony_ci	mov.b		%d0,%d1
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci	clr.l		%d0
105462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
105562306a36Sopenharmony_ci
105662306a36Sopenharmony_ci	tst.b		%d1
105762306a36Sopenharmony_ci	bne.b		_L2_2x
105862306a36Sopenharmony_ci	bsr.l		ssinh			# operand is a NORM
105962306a36Sopenharmony_ci	bra.b		_L2_6x
106062306a36Sopenharmony_ci_L2_2x:
106162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
106262306a36Sopenharmony_ci	bne.b		_L2_3x			# no
106362306a36Sopenharmony_ci	bsr.l		src_zero			# yes
106462306a36Sopenharmony_ci	bra.b		_L2_6x
106562306a36Sopenharmony_ci_L2_3x:
106662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
106762306a36Sopenharmony_ci	bne.b		_L2_4x			# no
106862306a36Sopenharmony_ci	bsr.l		src_inf			# yes
106962306a36Sopenharmony_ci	bra.b		_L2_6x
107062306a36Sopenharmony_ci_L2_4x:
107162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
107262306a36Sopenharmony_ci	bne.b		_L2_5x			# no
107362306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
107462306a36Sopenharmony_ci	bra.b		_L2_6x
107562306a36Sopenharmony_ci_L2_5x:
107662306a36Sopenharmony_ci	bsr.l		ssinhd			# operand is a DENORM
107762306a36Sopenharmony_ci_L2_6x:
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ci#
108062306a36Sopenharmony_ci#	Result is now in FP0
108162306a36Sopenharmony_ci#
108262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
108362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
108462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
108562306a36Sopenharmony_ci	unlk		%a6
108662306a36Sopenharmony_ci	rts
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_ci#########################################################################
109062306a36Sopenharmony_ci# MONADIC TEMPLATE							#
109162306a36Sopenharmony_ci#########################################################################
109262306a36Sopenharmony_ci	global		_flognp1s_
109362306a36Sopenharmony_ci_flognp1s_:
109462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
109762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
109862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_ci#
110362306a36Sopenharmony_ci#	copy, convert, and tag input argument
110462306a36Sopenharmony_ci#
110562306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
110662306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
110762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
110862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
110962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
111062306a36Sopenharmony_ci	mov.b		%d0,%d1
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	clr.l		%d0
111562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_ci	tst.b		%d1
111862306a36Sopenharmony_ci	bne.b		_L3_2s
111962306a36Sopenharmony_ci	bsr.l		slognp1			# operand is a NORM
112062306a36Sopenharmony_ci	bra.b		_L3_6s
112162306a36Sopenharmony_ci_L3_2s:
112262306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
112362306a36Sopenharmony_ci	bne.b		_L3_3s			# no
112462306a36Sopenharmony_ci	bsr.l		src_zero			# yes
112562306a36Sopenharmony_ci	bra.b		_L3_6s
112662306a36Sopenharmony_ci_L3_3s:
112762306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
112862306a36Sopenharmony_ci	bne.b		_L3_4s			# no
112962306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
113062306a36Sopenharmony_ci	bra.b		_L3_6s
113162306a36Sopenharmony_ci_L3_4s:
113262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
113362306a36Sopenharmony_ci	bne.b		_L3_5s			# no
113462306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
113562306a36Sopenharmony_ci	bra.b		_L3_6s
113662306a36Sopenharmony_ci_L3_5s:
113762306a36Sopenharmony_ci	bsr.l		slognp1d			# operand is a DENORM
113862306a36Sopenharmony_ci_L3_6s:
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci#
114162306a36Sopenharmony_ci#	Result is now in FP0
114262306a36Sopenharmony_ci#
114362306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
114462306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
114562306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
114662306a36Sopenharmony_ci	unlk		%a6
114762306a36Sopenharmony_ci	rts
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	global		_flognp1d_
115062306a36Sopenharmony_ci_flognp1d_:
115162306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
115462306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
115562306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
115862306a36Sopenharmony_ci
115962306a36Sopenharmony_ci#
116062306a36Sopenharmony_ci#	copy, convert, and tag input argument
116162306a36Sopenharmony_ci#
116262306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
116362306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
116462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
116562306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
116662306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
116762306a36Sopenharmony_ci	mov.b		%d0,%d1
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci	clr.l		%d0
117262306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
117562306a36Sopenharmony_ci	tst.b		%d1
117662306a36Sopenharmony_ci	bne.b		_L3_2d
117762306a36Sopenharmony_ci	bsr.l		slognp1			# operand is a NORM
117862306a36Sopenharmony_ci	bra.b		_L3_6d
117962306a36Sopenharmony_ci_L3_2d:
118062306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
118162306a36Sopenharmony_ci	bne.b		_L3_3d			# no
118262306a36Sopenharmony_ci	bsr.l		src_zero			# yes
118362306a36Sopenharmony_ci	bra.b		_L3_6d
118462306a36Sopenharmony_ci_L3_3d:
118562306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
118662306a36Sopenharmony_ci	bne.b		_L3_4d			# no
118762306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
118862306a36Sopenharmony_ci	bra.b		_L3_6d
118962306a36Sopenharmony_ci_L3_4d:
119062306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
119162306a36Sopenharmony_ci	bne.b		_L3_5d			# no
119262306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
119362306a36Sopenharmony_ci	bra.b		_L3_6d
119462306a36Sopenharmony_ci_L3_5d:
119562306a36Sopenharmony_ci	bsr.l		slognp1d			# operand is a DENORM
119662306a36Sopenharmony_ci_L3_6d:
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci#
119962306a36Sopenharmony_ci#	Result is now in FP0
120062306a36Sopenharmony_ci#
120162306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
120262306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
120362306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
120462306a36Sopenharmony_ci	unlk		%a6
120562306a36Sopenharmony_ci	rts
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	global		_flognp1x_
120862306a36Sopenharmony_ci_flognp1x_:
120962306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
121062306a36Sopenharmony_ci
121162306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
121262306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
121362306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci#
121862306a36Sopenharmony_ci#	copy, convert, and tag input argument
121962306a36Sopenharmony_ci#
122062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
122162306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
122262306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
122362306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
122462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
122562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
122662306a36Sopenharmony_ci	mov.b		%d0,%d1
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci	clr.l		%d0
123162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_ci	tst.b		%d1
123462306a36Sopenharmony_ci	bne.b		_L3_2x
123562306a36Sopenharmony_ci	bsr.l		slognp1			# operand is a NORM
123662306a36Sopenharmony_ci	bra.b		_L3_6x
123762306a36Sopenharmony_ci_L3_2x:
123862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
123962306a36Sopenharmony_ci	bne.b		_L3_3x			# no
124062306a36Sopenharmony_ci	bsr.l		src_zero			# yes
124162306a36Sopenharmony_ci	bra.b		_L3_6x
124262306a36Sopenharmony_ci_L3_3x:
124362306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
124462306a36Sopenharmony_ci	bne.b		_L3_4x			# no
124562306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
124662306a36Sopenharmony_ci	bra.b		_L3_6x
124762306a36Sopenharmony_ci_L3_4x:
124862306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
124962306a36Sopenharmony_ci	bne.b		_L3_5x			# no
125062306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
125162306a36Sopenharmony_ci	bra.b		_L3_6x
125262306a36Sopenharmony_ci_L3_5x:
125362306a36Sopenharmony_ci	bsr.l		slognp1d			# operand is a DENORM
125462306a36Sopenharmony_ci_L3_6x:
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ci#
125762306a36Sopenharmony_ci#	Result is now in FP0
125862306a36Sopenharmony_ci#
125962306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
126062306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
126162306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
126262306a36Sopenharmony_ci	unlk		%a6
126362306a36Sopenharmony_ci	rts
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci
126662306a36Sopenharmony_ci#########################################################################
126762306a36Sopenharmony_ci# MONADIC TEMPLATE							#
126862306a36Sopenharmony_ci#########################################################################
126962306a36Sopenharmony_ci	global		_fetoxm1s_
127062306a36Sopenharmony_ci_fetoxm1s_:
127162306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
127462306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
127562306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci#
128062306a36Sopenharmony_ci#	copy, convert, and tag input argument
128162306a36Sopenharmony_ci#
128262306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
128362306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
128462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
128562306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
128662306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
128762306a36Sopenharmony_ci	mov.b		%d0,%d1
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	clr.l		%d0
129262306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci	tst.b		%d1
129562306a36Sopenharmony_ci	bne.b		_L4_2s
129662306a36Sopenharmony_ci	bsr.l		setoxm1			# operand is a NORM
129762306a36Sopenharmony_ci	bra.b		_L4_6s
129862306a36Sopenharmony_ci_L4_2s:
129962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
130062306a36Sopenharmony_ci	bne.b		_L4_3s			# no
130162306a36Sopenharmony_ci	bsr.l		src_zero			# yes
130262306a36Sopenharmony_ci	bra.b		_L4_6s
130362306a36Sopenharmony_ci_L4_3s:
130462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
130562306a36Sopenharmony_ci	bne.b		_L4_4s			# no
130662306a36Sopenharmony_ci	bsr.l		setoxm1i			# yes
130762306a36Sopenharmony_ci	bra.b		_L4_6s
130862306a36Sopenharmony_ci_L4_4s:
130962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
131062306a36Sopenharmony_ci	bne.b		_L4_5s			# no
131162306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
131262306a36Sopenharmony_ci	bra.b		_L4_6s
131362306a36Sopenharmony_ci_L4_5s:
131462306a36Sopenharmony_ci	bsr.l		setoxm1d			# operand is a DENORM
131562306a36Sopenharmony_ci_L4_6s:
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_ci#
131862306a36Sopenharmony_ci#	Result is now in FP0
131962306a36Sopenharmony_ci#
132062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
132162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
132262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
132362306a36Sopenharmony_ci	unlk		%a6
132462306a36Sopenharmony_ci	rts
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci	global		_fetoxm1d_
132762306a36Sopenharmony_ci_fetoxm1d_:
132862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
133162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
133262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
133362306a36Sopenharmony_ci
133462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci#
133762306a36Sopenharmony_ci#	copy, convert, and tag input argument
133862306a36Sopenharmony_ci#
133962306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
134062306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
134162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
134262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
134362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
134462306a36Sopenharmony_ci	mov.b		%d0,%d1
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci	clr.l		%d0
134962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
135262306a36Sopenharmony_ci	tst.b		%d1
135362306a36Sopenharmony_ci	bne.b		_L4_2d
135462306a36Sopenharmony_ci	bsr.l		setoxm1			# operand is a NORM
135562306a36Sopenharmony_ci	bra.b		_L4_6d
135662306a36Sopenharmony_ci_L4_2d:
135762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
135862306a36Sopenharmony_ci	bne.b		_L4_3d			# no
135962306a36Sopenharmony_ci	bsr.l		src_zero			# yes
136062306a36Sopenharmony_ci	bra.b		_L4_6d
136162306a36Sopenharmony_ci_L4_3d:
136262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
136362306a36Sopenharmony_ci	bne.b		_L4_4d			# no
136462306a36Sopenharmony_ci	bsr.l		setoxm1i			# yes
136562306a36Sopenharmony_ci	bra.b		_L4_6d
136662306a36Sopenharmony_ci_L4_4d:
136762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
136862306a36Sopenharmony_ci	bne.b		_L4_5d			# no
136962306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
137062306a36Sopenharmony_ci	bra.b		_L4_6d
137162306a36Sopenharmony_ci_L4_5d:
137262306a36Sopenharmony_ci	bsr.l		setoxm1d			# operand is a DENORM
137362306a36Sopenharmony_ci_L4_6d:
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci#
137662306a36Sopenharmony_ci#	Result is now in FP0
137762306a36Sopenharmony_ci#
137862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
137962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
138062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
138162306a36Sopenharmony_ci	unlk		%a6
138262306a36Sopenharmony_ci	rts
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci	global		_fetoxm1x_
138562306a36Sopenharmony_ci_fetoxm1x_:
138662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
138962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
139062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_ci#
139562306a36Sopenharmony_ci#	copy, convert, and tag input argument
139662306a36Sopenharmony_ci#
139762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
139862306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
139962306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
140062306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
140162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
140262306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
140362306a36Sopenharmony_ci	mov.b		%d0,%d1
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	clr.l		%d0
140862306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	tst.b		%d1
141162306a36Sopenharmony_ci	bne.b		_L4_2x
141262306a36Sopenharmony_ci	bsr.l		setoxm1			# operand is a NORM
141362306a36Sopenharmony_ci	bra.b		_L4_6x
141462306a36Sopenharmony_ci_L4_2x:
141562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
141662306a36Sopenharmony_ci	bne.b		_L4_3x			# no
141762306a36Sopenharmony_ci	bsr.l		src_zero			# yes
141862306a36Sopenharmony_ci	bra.b		_L4_6x
141962306a36Sopenharmony_ci_L4_3x:
142062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
142162306a36Sopenharmony_ci	bne.b		_L4_4x			# no
142262306a36Sopenharmony_ci	bsr.l		setoxm1i			# yes
142362306a36Sopenharmony_ci	bra.b		_L4_6x
142462306a36Sopenharmony_ci_L4_4x:
142562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
142662306a36Sopenharmony_ci	bne.b		_L4_5x			# no
142762306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
142862306a36Sopenharmony_ci	bra.b		_L4_6x
142962306a36Sopenharmony_ci_L4_5x:
143062306a36Sopenharmony_ci	bsr.l		setoxm1d			# operand is a DENORM
143162306a36Sopenharmony_ci_L4_6x:
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_ci#
143462306a36Sopenharmony_ci#	Result is now in FP0
143562306a36Sopenharmony_ci#
143662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
143762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
143862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
143962306a36Sopenharmony_ci	unlk		%a6
144062306a36Sopenharmony_ci	rts
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci#########################################################################
144462306a36Sopenharmony_ci# MONADIC TEMPLATE							#
144562306a36Sopenharmony_ci#########################################################################
144662306a36Sopenharmony_ci	global		_ftanhs_
144762306a36Sopenharmony_ci_ftanhs_:
144862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
145162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
145262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci#
145762306a36Sopenharmony_ci#	copy, convert, and tag input argument
145862306a36Sopenharmony_ci#
145962306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
146062306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
146162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
146262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
146362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
146462306a36Sopenharmony_ci	mov.b		%d0,%d1
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_ci	clr.l		%d0
146962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci	tst.b		%d1
147262306a36Sopenharmony_ci	bne.b		_L5_2s
147362306a36Sopenharmony_ci	bsr.l		stanh			# operand is a NORM
147462306a36Sopenharmony_ci	bra.b		_L5_6s
147562306a36Sopenharmony_ci_L5_2s:
147662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
147762306a36Sopenharmony_ci	bne.b		_L5_3s			# no
147862306a36Sopenharmony_ci	bsr.l		src_zero			# yes
147962306a36Sopenharmony_ci	bra.b		_L5_6s
148062306a36Sopenharmony_ci_L5_3s:
148162306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
148262306a36Sopenharmony_ci	bne.b		_L5_4s			# no
148362306a36Sopenharmony_ci	bsr.l		src_one			# yes
148462306a36Sopenharmony_ci	bra.b		_L5_6s
148562306a36Sopenharmony_ci_L5_4s:
148662306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
148762306a36Sopenharmony_ci	bne.b		_L5_5s			# no
148862306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
148962306a36Sopenharmony_ci	bra.b		_L5_6s
149062306a36Sopenharmony_ci_L5_5s:
149162306a36Sopenharmony_ci	bsr.l		stanhd			# operand is a DENORM
149262306a36Sopenharmony_ci_L5_6s:
149362306a36Sopenharmony_ci
149462306a36Sopenharmony_ci#
149562306a36Sopenharmony_ci#	Result is now in FP0
149662306a36Sopenharmony_ci#
149762306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
149862306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
149962306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
150062306a36Sopenharmony_ci	unlk		%a6
150162306a36Sopenharmony_ci	rts
150262306a36Sopenharmony_ci
150362306a36Sopenharmony_ci	global		_ftanhd_
150462306a36Sopenharmony_ci_ftanhd_:
150562306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
150862306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
150962306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
151262306a36Sopenharmony_ci
151362306a36Sopenharmony_ci#
151462306a36Sopenharmony_ci#	copy, convert, and tag input argument
151562306a36Sopenharmony_ci#
151662306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
151762306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
151862306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
151962306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
152062306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
152162306a36Sopenharmony_ci	mov.b		%d0,%d1
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ci	clr.l		%d0
152662306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
152962306a36Sopenharmony_ci	tst.b		%d1
153062306a36Sopenharmony_ci	bne.b		_L5_2d
153162306a36Sopenharmony_ci	bsr.l		stanh			# operand is a NORM
153262306a36Sopenharmony_ci	bra.b		_L5_6d
153362306a36Sopenharmony_ci_L5_2d:
153462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
153562306a36Sopenharmony_ci	bne.b		_L5_3d			# no
153662306a36Sopenharmony_ci	bsr.l		src_zero			# yes
153762306a36Sopenharmony_ci	bra.b		_L5_6d
153862306a36Sopenharmony_ci_L5_3d:
153962306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
154062306a36Sopenharmony_ci	bne.b		_L5_4d			# no
154162306a36Sopenharmony_ci	bsr.l		src_one			# yes
154262306a36Sopenharmony_ci	bra.b		_L5_6d
154362306a36Sopenharmony_ci_L5_4d:
154462306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
154562306a36Sopenharmony_ci	bne.b		_L5_5d			# no
154662306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
154762306a36Sopenharmony_ci	bra.b		_L5_6d
154862306a36Sopenharmony_ci_L5_5d:
154962306a36Sopenharmony_ci	bsr.l		stanhd			# operand is a DENORM
155062306a36Sopenharmony_ci_L5_6d:
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci#
155362306a36Sopenharmony_ci#	Result is now in FP0
155462306a36Sopenharmony_ci#
155562306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
155662306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
155762306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
155862306a36Sopenharmony_ci	unlk		%a6
155962306a36Sopenharmony_ci	rts
156062306a36Sopenharmony_ci
156162306a36Sopenharmony_ci	global		_ftanhx_
156262306a36Sopenharmony_ci_ftanhx_:
156362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
156662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
156762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
157062306a36Sopenharmony_ci
157162306a36Sopenharmony_ci#
157262306a36Sopenharmony_ci#	copy, convert, and tag input argument
157362306a36Sopenharmony_ci#
157462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
157562306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
157662306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
157762306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
157862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
157962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
158062306a36Sopenharmony_ci	mov.b		%d0,%d1
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	clr.l		%d0
158562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ci	tst.b		%d1
158862306a36Sopenharmony_ci	bne.b		_L5_2x
158962306a36Sopenharmony_ci	bsr.l		stanh			# operand is a NORM
159062306a36Sopenharmony_ci	bra.b		_L5_6x
159162306a36Sopenharmony_ci_L5_2x:
159262306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
159362306a36Sopenharmony_ci	bne.b		_L5_3x			# no
159462306a36Sopenharmony_ci	bsr.l		src_zero			# yes
159562306a36Sopenharmony_ci	bra.b		_L5_6x
159662306a36Sopenharmony_ci_L5_3x:
159762306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
159862306a36Sopenharmony_ci	bne.b		_L5_4x			# no
159962306a36Sopenharmony_ci	bsr.l		src_one			# yes
160062306a36Sopenharmony_ci	bra.b		_L5_6x
160162306a36Sopenharmony_ci_L5_4x:
160262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
160362306a36Sopenharmony_ci	bne.b		_L5_5x			# no
160462306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
160562306a36Sopenharmony_ci	bra.b		_L5_6x
160662306a36Sopenharmony_ci_L5_5x:
160762306a36Sopenharmony_ci	bsr.l		stanhd			# operand is a DENORM
160862306a36Sopenharmony_ci_L5_6x:
160962306a36Sopenharmony_ci
161062306a36Sopenharmony_ci#
161162306a36Sopenharmony_ci#	Result is now in FP0
161262306a36Sopenharmony_ci#
161362306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
161462306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
161562306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
161662306a36Sopenharmony_ci	unlk		%a6
161762306a36Sopenharmony_ci	rts
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci#########################################################################
162162306a36Sopenharmony_ci# MONADIC TEMPLATE							#
162262306a36Sopenharmony_ci#########################################################################
162362306a36Sopenharmony_ci	global		_fatans_
162462306a36Sopenharmony_ci_fatans_:
162562306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
162662306a36Sopenharmony_ci
162762306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
162862306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
162962306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
163062306a36Sopenharmony_ci
163162306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci#
163462306a36Sopenharmony_ci#	copy, convert, and tag input argument
163562306a36Sopenharmony_ci#
163662306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
163762306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
163862306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
163962306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
164062306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
164162306a36Sopenharmony_ci	mov.b		%d0,%d1
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci	clr.l		%d0
164662306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
164762306a36Sopenharmony_ci
164862306a36Sopenharmony_ci	tst.b		%d1
164962306a36Sopenharmony_ci	bne.b		_L6_2s
165062306a36Sopenharmony_ci	bsr.l		satan			# operand is a NORM
165162306a36Sopenharmony_ci	bra.b		_L6_6s
165262306a36Sopenharmony_ci_L6_2s:
165362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
165462306a36Sopenharmony_ci	bne.b		_L6_3s			# no
165562306a36Sopenharmony_ci	bsr.l		src_zero			# yes
165662306a36Sopenharmony_ci	bra.b		_L6_6s
165762306a36Sopenharmony_ci_L6_3s:
165862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
165962306a36Sopenharmony_ci	bne.b		_L6_4s			# no
166062306a36Sopenharmony_ci	bsr.l		spi_2			# yes
166162306a36Sopenharmony_ci	bra.b		_L6_6s
166262306a36Sopenharmony_ci_L6_4s:
166362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
166462306a36Sopenharmony_ci	bne.b		_L6_5s			# no
166562306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
166662306a36Sopenharmony_ci	bra.b		_L6_6s
166762306a36Sopenharmony_ci_L6_5s:
166862306a36Sopenharmony_ci	bsr.l		satand			# operand is a DENORM
166962306a36Sopenharmony_ci_L6_6s:
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci#
167262306a36Sopenharmony_ci#	Result is now in FP0
167362306a36Sopenharmony_ci#
167462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
167562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
167662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
167762306a36Sopenharmony_ci	unlk		%a6
167862306a36Sopenharmony_ci	rts
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	global		_fatand_
168162306a36Sopenharmony_ci_fatand_:
168262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
168362306a36Sopenharmony_ci
168462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
168562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
168662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
168962306a36Sopenharmony_ci
169062306a36Sopenharmony_ci#
169162306a36Sopenharmony_ci#	copy, convert, and tag input argument
169262306a36Sopenharmony_ci#
169362306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
169462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
169562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
169662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
169762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
169862306a36Sopenharmony_ci	mov.b		%d0,%d1
169962306a36Sopenharmony_ci
170062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
170162306a36Sopenharmony_ci
170262306a36Sopenharmony_ci	clr.l		%d0
170362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
170462306a36Sopenharmony_ci
170562306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
170662306a36Sopenharmony_ci	tst.b		%d1
170762306a36Sopenharmony_ci	bne.b		_L6_2d
170862306a36Sopenharmony_ci	bsr.l		satan			# operand is a NORM
170962306a36Sopenharmony_ci	bra.b		_L6_6d
171062306a36Sopenharmony_ci_L6_2d:
171162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
171262306a36Sopenharmony_ci	bne.b		_L6_3d			# no
171362306a36Sopenharmony_ci	bsr.l		src_zero			# yes
171462306a36Sopenharmony_ci	bra.b		_L6_6d
171562306a36Sopenharmony_ci_L6_3d:
171662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
171762306a36Sopenharmony_ci	bne.b		_L6_4d			# no
171862306a36Sopenharmony_ci	bsr.l		spi_2			# yes
171962306a36Sopenharmony_ci	bra.b		_L6_6d
172062306a36Sopenharmony_ci_L6_4d:
172162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
172262306a36Sopenharmony_ci	bne.b		_L6_5d			# no
172362306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
172462306a36Sopenharmony_ci	bra.b		_L6_6d
172562306a36Sopenharmony_ci_L6_5d:
172662306a36Sopenharmony_ci	bsr.l		satand			# operand is a DENORM
172762306a36Sopenharmony_ci_L6_6d:
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci#
173062306a36Sopenharmony_ci#	Result is now in FP0
173162306a36Sopenharmony_ci#
173262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
173362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
173462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
173562306a36Sopenharmony_ci	unlk		%a6
173662306a36Sopenharmony_ci	rts
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci	global		_fatanx_
173962306a36Sopenharmony_ci_fatanx_:
174062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
174162306a36Sopenharmony_ci
174262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
174362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
174462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci#
174962306a36Sopenharmony_ci#	copy, convert, and tag input argument
175062306a36Sopenharmony_ci#
175162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
175262306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
175362306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
175462306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
175562306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
175662306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
175762306a36Sopenharmony_ci	mov.b		%d0,%d1
175862306a36Sopenharmony_ci
175962306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_ci	clr.l		%d0
176262306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	tst.b		%d1
176562306a36Sopenharmony_ci	bne.b		_L6_2x
176662306a36Sopenharmony_ci	bsr.l		satan			# operand is a NORM
176762306a36Sopenharmony_ci	bra.b		_L6_6x
176862306a36Sopenharmony_ci_L6_2x:
176962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
177062306a36Sopenharmony_ci	bne.b		_L6_3x			# no
177162306a36Sopenharmony_ci	bsr.l		src_zero			# yes
177262306a36Sopenharmony_ci	bra.b		_L6_6x
177362306a36Sopenharmony_ci_L6_3x:
177462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
177562306a36Sopenharmony_ci	bne.b		_L6_4x			# no
177662306a36Sopenharmony_ci	bsr.l		spi_2			# yes
177762306a36Sopenharmony_ci	bra.b		_L6_6x
177862306a36Sopenharmony_ci_L6_4x:
177962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
178062306a36Sopenharmony_ci	bne.b		_L6_5x			# no
178162306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
178262306a36Sopenharmony_ci	bra.b		_L6_6x
178362306a36Sopenharmony_ci_L6_5x:
178462306a36Sopenharmony_ci	bsr.l		satand			# operand is a DENORM
178562306a36Sopenharmony_ci_L6_6x:
178662306a36Sopenharmony_ci
178762306a36Sopenharmony_ci#
178862306a36Sopenharmony_ci#	Result is now in FP0
178962306a36Sopenharmony_ci#
179062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
179162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
179262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
179362306a36Sopenharmony_ci	unlk		%a6
179462306a36Sopenharmony_ci	rts
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci
179762306a36Sopenharmony_ci#########################################################################
179862306a36Sopenharmony_ci# MONADIC TEMPLATE							#
179962306a36Sopenharmony_ci#########################################################################
180062306a36Sopenharmony_ci	global		_fasins_
180162306a36Sopenharmony_ci_fasins_:
180262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
180562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
180662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
180962306a36Sopenharmony_ci
181062306a36Sopenharmony_ci#
181162306a36Sopenharmony_ci#	copy, convert, and tag input argument
181262306a36Sopenharmony_ci#
181362306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
181462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
181562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
181662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
181762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
181862306a36Sopenharmony_ci	mov.b		%d0,%d1
181962306a36Sopenharmony_ci
182062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci	clr.l		%d0
182362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci	tst.b		%d1
182662306a36Sopenharmony_ci	bne.b		_L7_2s
182762306a36Sopenharmony_ci	bsr.l		sasin			# operand is a NORM
182862306a36Sopenharmony_ci	bra.b		_L7_6s
182962306a36Sopenharmony_ci_L7_2s:
183062306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
183162306a36Sopenharmony_ci	bne.b		_L7_3s			# no
183262306a36Sopenharmony_ci	bsr.l		src_zero			# yes
183362306a36Sopenharmony_ci	bra.b		_L7_6s
183462306a36Sopenharmony_ci_L7_3s:
183562306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
183662306a36Sopenharmony_ci	bne.b		_L7_4s			# no
183762306a36Sopenharmony_ci	bsr.l		t_operr			# yes
183862306a36Sopenharmony_ci	bra.b		_L7_6s
183962306a36Sopenharmony_ci_L7_4s:
184062306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
184162306a36Sopenharmony_ci	bne.b		_L7_5s			# no
184262306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
184362306a36Sopenharmony_ci	bra.b		_L7_6s
184462306a36Sopenharmony_ci_L7_5s:
184562306a36Sopenharmony_ci	bsr.l		sasind			# operand is a DENORM
184662306a36Sopenharmony_ci_L7_6s:
184762306a36Sopenharmony_ci
184862306a36Sopenharmony_ci#
184962306a36Sopenharmony_ci#	Result is now in FP0
185062306a36Sopenharmony_ci#
185162306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
185262306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
185362306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
185462306a36Sopenharmony_ci	unlk		%a6
185562306a36Sopenharmony_ci	rts
185662306a36Sopenharmony_ci
185762306a36Sopenharmony_ci	global		_fasind_
185862306a36Sopenharmony_ci_fasind_:
185962306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
186062306a36Sopenharmony_ci
186162306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
186262306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
186362306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
186462306a36Sopenharmony_ci
186562306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
186662306a36Sopenharmony_ci
186762306a36Sopenharmony_ci#
186862306a36Sopenharmony_ci#	copy, convert, and tag input argument
186962306a36Sopenharmony_ci#
187062306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
187162306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
187262306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
187362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
187462306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
187562306a36Sopenharmony_ci	mov.b		%d0,%d1
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
187862306a36Sopenharmony_ci
187962306a36Sopenharmony_ci	clr.l		%d0
188062306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
188162306a36Sopenharmony_ci
188262306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
188362306a36Sopenharmony_ci	tst.b		%d1
188462306a36Sopenharmony_ci	bne.b		_L7_2d
188562306a36Sopenharmony_ci	bsr.l		sasin			# operand is a NORM
188662306a36Sopenharmony_ci	bra.b		_L7_6d
188762306a36Sopenharmony_ci_L7_2d:
188862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
188962306a36Sopenharmony_ci	bne.b		_L7_3d			# no
189062306a36Sopenharmony_ci	bsr.l		src_zero			# yes
189162306a36Sopenharmony_ci	bra.b		_L7_6d
189262306a36Sopenharmony_ci_L7_3d:
189362306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
189462306a36Sopenharmony_ci	bne.b		_L7_4d			# no
189562306a36Sopenharmony_ci	bsr.l		t_operr			# yes
189662306a36Sopenharmony_ci	bra.b		_L7_6d
189762306a36Sopenharmony_ci_L7_4d:
189862306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
189962306a36Sopenharmony_ci	bne.b		_L7_5d			# no
190062306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
190162306a36Sopenharmony_ci	bra.b		_L7_6d
190262306a36Sopenharmony_ci_L7_5d:
190362306a36Sopenharmony_ci	bsr.l		sasind			# operand is a DENORM
190462306a36Sopenharmony_ci_L7_6d:
190562306a36Sopenharmony_ci
190662306a36Sopenharmony_ci#
190762306a36Sopenharmony_ci#	Result is now in FP0
190862306a36Sopenharmony_ci#
190962306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
191062306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
191162306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
191262306a36Sopenharmony_ci	unlk		%a6
191362306a36Sopenharmony_ci	rts
191462306a36Sopenharmony_ci
191562306a36Sopenharmony_ci	global		_fasinx_
191662306a36Sopenharmony_ci_fasinx_:
191762306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
191862306a36Sopenharmony_ci
191962306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
192062306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
192162306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci#
192662306a36Sopenharmony_ci#	copy, convert, and tag input argument
192762306a36Sopenharmony_ci#
192862306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
192962306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
193062306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
193162306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
193262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
193362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
193462306a36Sopenharmony_ci	mov.b		%d0,%d1
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
193762306a36Sopenharmony_ci
193862306a36Sopenharmony_ci	clr.l		%d0
193962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
194062306a36Sopenharmony_ci
194162306a36Sopenharmony_ci	tst.b		%d1
194262306a36Sopenharmony_ci	bne.b		_L7_2x
194362306a36Sopenharmony_ci	bsr.l		sasin			# operand is a NORM
194462306a36Sopenharmony_ci	bra.b		_L7_6x
194562306a36Sopenharmony_ci_L7_2x:
194662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
194762306a36Sopenharmony_ci	bne.b		_L7_3x			# no
194862306a36Sopenharmony_ci	bsr.l		src_zero			# yes
194962306a36Sopenharmony_ci	bra.b		_L7_6x
195062306a36Sopenharmony_ci_L7_3x:
195162306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
195262306a36Sopenharmony_ci	bne.b		_L7_4x			# no
195362306a36Sopenharmony_ci	bsr.l		t_operr			# yes
195462306a36Sopenharmony_ci	bra.b		_L7_6x
195562306a36Sopenharmony_ci_L7_4x:
195662306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
195762306a36Sopenharmony_ci	bne.b		_L7_5x			# no
195862306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
195962306a36Sopenharmony_ci	bra.b		_L7_6x
196062306a36Sopenharmony_ci_L7_5x:
196162306a36Sopenharmony_ci	bsr.l		sasind			# operand is a DENORM
196262306a36Sopenharmony_ci_L7_6x:
196362306a36Sopenharmony_ci
196462306a36Sopenharmony_ci#
196562306a36Sopenharmony_ci#	Result is now in FP0
196662306a36Sopenharmony_ci#
196762306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
196862306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
196962306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
197062306a36Sopenharmony_ci	unlk		%a6
197162306a36Sopenharmony_ci	rts
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_ci
197462306a36Sopenharmony_ci#########################################################################
197562306a36Sopenharmony_ci# MONADIC TEMPLATE							#
197662306a36Sopenharmony_ci#########################################################################
197762306a36Sopenharmony_ci	global		_fatanhs_
197862306a36Sopenharmony_ci_fatanhs_:
197962306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
198262306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
198362306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
198462306a36Sopenharmony_ci
198562306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
198662306a36Sopenharmony_ci
198762306a36Sopenharmony_ci#
198862306a36Sopenharmony_ci#	copy, convert, and tag input argument
198962306a36Sopenharmony_ci#
199062306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
199162306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
199262306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
199362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
199462306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
199562306a36Sopenharmony_ci	mov.b		%d0,%d1
199662306a36Sopenharmony_ci
199762306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
199862306a36Sopenharmony_ci
199962306a36Sopenharmony_ci	clr.l		%d0
200062306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
200162306a36Sopenharmony_ci
200262306a36Sopenharmony_ci	tst.b		%d1
200362306a36Sopenharmony_ci	bne.b		_L8_2s
200462306a36Sopenharmony_ci	bsr.l		satanh			# operand is a NORM
200562306a36Sopenharmony_ci	bra.b		_L8_6s
200662306a36Sopenharmony_ci_L8_2s:
200762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
200862306a36Sopenharmony_ci	bne.b		_L8_3s			# no
200962306a36Sopenharmony_ci	bsr.l		src_zero			# yes
201062306a36Sopenharmony_ci	bra.b		_L8_6s
201162306a36Sopenharmony_ci_L8_3s:
201262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
201362306a36Sopenharmony_ci	bne.b		_L8_4s			# no
201462306a36Sopenharmony_ci	bsr.l		t_operr			# yes
201562306a36Sopenharmony_ci	bra.b		_L8_6s
201662306a36Sopenharmony_ci_L8_4s:
201762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
201862306a36Sopenharmony_ci	bne.b		_L8_5s			# no
201962306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
202062306a36Sopenharmony_ci	bra.b		_L8_6s
202162306a36Sopenharmony_ci_L8_5s:
202262306a36Sopenharmony_ci	bsr.l		satanhd			# operand is a DENORM
202362306a36Sopenharmony_ci_L8_6s:
202462306a36Sopenharmony_ci
202562306a36Sopenharmony_ci#
202662306a36Sopenharmony_ci#	Result is now in FP0
202762306a36Sopenharmony_ci#
202862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
202962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
203062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
203162306a36Sopenharmony_ci	unlk		%a6
203262306a36Sopenharmony_ci	rts
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci	global		_fatanhd_
203562306a36Sopenharmony_ci_fatanhd_:
203662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
203762306a36Sopenharmony_ci
203862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
203962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
204062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
204162306a36Sopenharmony_ci
204262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
204362306a36Sopenharmony_ci
204462306a36Sopenharmony_ci#
204562306a36Sopenharmony_ci#	copy, convert, and tag input argument
204662306a36Sopenharmony_ci#
204762306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
204862306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
204962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
205062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
205162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
205262306a36Sopenharmony_ci	mov.b		%d0,%d1
205362306a36Sopenharmony_ci
205462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci	clr.l		%d0
205762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
205862306a36Sopenharmony_ci
205962306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
206062306a36Sopenharmony_ci	tst.b		%d1
206162306a36Sopenharmony_ci	bne.b		_L8_2d
206262306a36Sopenharmony_ci	bsr.l		satanh			# operand is a NORM
206362306a36Sopenharmony_ci	bra.b		_L8_6d
206462306a36Sopenharmony_ci_L8_2d:
206562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
206662306a36Sopenharmony_ci	bne.b		_L8_3d			# no
206762306a36Sopenharmony_ci	bsr.l		src_zero			# yes
206862306a36Sopenharmony_ci	bra.b		_L8_6d
206962306a36Sopenharmony_ci_L8_3d:
207062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
207162306a36Sopenharmony_ci	bne.b		_L8_4d			# no
207262306a36Sopenharmony_ci	bsr.l		t_operr			# yes
207362306a36Sopenharmony_ci	bra.b		_L8_6d
207462306a36Sopenharmony_ci_L8_4d:
207562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
207662306a36Sopenharmony_ci	bne.b		_L8_5d			# no
207762306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
207862306a36Sopenharmony_ci	bra.b		_L8_6d
207962306a36Sopenharmony_ci_L8_5d:
208062306a36Sopenharmony_ci	bsr.l		satanhd			# operand is a DENORM
208162306a36Sopenharmony_ci_L8_6d:
208262306a36Sopenharmony_ci
208362306a36Sopenharmony_ci#
208462306a36Sopenharmony_ci#	Result is now in FP0
208562306a36Sopenharmony_ci#
208662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
208762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
208862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
208962306a36Sopenharmony_ci	unlk		%a6
209062306a36Sopenharmony_ci	rts
209162306a36Sopenharmony_ci
209262306a36Sopenharmony_ci	global		_fatanhx_
209362306a36Sopenharmony_ci_fatanhx_:
209462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
209562306a36Sopenharmony_ci
209662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
209762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
209862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
209962306a36Sopenharmony_ci
210062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
210162306a36Sopenharmony_ci
210262306a36Sopenharmony_ci#
210362306a36Sopenharmony_ci#	copy, convert, and tag input argument
210462306a36Sopenharmony_ci#
210562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
210662306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
210762306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
210862306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
210962306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
211062306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
211162306a36Sopenharmony_ci	mov.b		%d0,%d1
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
211462306a36Sopenharmony_ci
211562306a36Sopenharmony_ci	clr.l		%d0
211662306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
211762306a36Sopenharmony_ci
211862306a36Sopenharmony_ci	tst.b		%d1
211962306a36Sopenharmony_ci	bne.b		_L8_2x
212062306a36Sopenharmony_ci	bsr.l		satanh			# operand is a NORM
212162306a36Sopenharmony_ci	bra.b		_L8_6x
212262306a36Sopenharmony_ci_L8_2x:
212362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
212462306a36Sopenharmony_ci	bne.b		_L8_3x			# no
212562306a36Sopenharmony_ci	bsr.l		src_zero			# yes
212662306a36Sopenharmony_ci	bra.b		_L8_6x
212762306a36Sopenharmony_ci_L8_3x:
212862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
212962306a36Sopenharmony_ci	bne.b		_L8_4x			# no
213062306a36Sopenharmony_ci	bsr.l		t_operr			# yes
213162306a36Sopenharmony_ci	bra.b		_L8_6x
213262306a36Sopenharmony_ci_L8_4x:
213362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
213462306a36Sopenharmony_ci	bne.b		_L8_5x			# no
213562306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
213662306a36Sopenharmony_ci	bra.b		_L8_6x
213762306a36Sopenharmony_ci_L8_5x:
213862306a36Sopenharmony_ci	bsr.l		satanhd			# operand is a DENORM
213962306a36Sopenharmony_ci_L8_6x:
214062306a36Sopenharmony_ci
214162306a36Sopenharmony_ci#
214262306a36Sopenharmony_ci#	Result is now in FP0
214362306a36Sopenharmony_ci#
214462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
214562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
214662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
214762306a36Sopenharmony_ci	unlk		%a6
214862306a36Sopenharmony_ci	rts
214962306a36Sopenharmony_ci
215062306a36Sopenharmony_ci
215162306a36Sopenharmony_ci#########################################################################
215262306a36Sopenharmony_ci# MONADIC TEMPLATE							#
215362306a36Sopenharmony_ci#########################################################################
215462306a36Sopenharmony_ci	global		_ftans_
215562306a36Sopenharmony_ci_ftans_:
215662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
215762306a36Sopenharmony_ci
215862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
215962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
216062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
216162306a36Sopenharmony_ci
216262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
216362306a36Sopenharmony_ci
216462306a36Sopenharmony_ci#
216562306a36Sopenharmony_ci#	copy, convert, and tag input argument
216662306a36Sopenharmony_ci#
216762306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
216862306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
216962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
217062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
217162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
217262306a36Sopenharmony_ci	mov.b		%d0,%d1
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
217562306a36Sopenharmony_ci
217662306a36Sopenharmony_ci	clr.l		%d0
217762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
217862306a36Sopenharmony_ci
217962306a36Sopenharmony_ci	tst.b		%d1
218062306a36Sopenharmony_ci	bne.b		_L9_2s
218162306a36Sopenharmony_ci	bsr.l		stan			# operand is a NORM
218262306a36Sopenharmony_ci	bra.b		_L9_6s
218362306a36Sopenharmony_ci_L9_2s:
218462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
218562306a36Sopenharmony_ci	bne.b		_L9_3s			# no
218662306a36Sopenharmony_ci	bsr.l		src_zero			# yes
218762306a36Sopenharmony_ci	bra.b		_L9_6s
218862306a36Sopenharmony_ci_L9_3s:
218962306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
219062306a36Sopenharmony_ci	bne.b		_L9_4s			# no
219162306a36Sopenharmony_ci	bsr.l		t_operr			# yes
219262306a36Sopenharmony_ci	bra.b		_L9_6s
219362306a36Sopenharmony_ci_L9_4s:
219462306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
219562306a36Sopenharmony_ci	bne.b		_L9_5s			# no
219662306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
219762306a36Sopenharmony_ci	bra.b		_L9_6s
219862306a36Sopenharmony_ci_L9_5s:
219962306a36Sopenharmony_ci	bsr.l		stand			# operand is a DENORM
220062306a36Sopenharmony_ci_L9_6s:
220162306a36Sopenharmony_ci
220262306a36Sopenharmony_ci#
220362306a36Sopenharmony_ci#	Result is now in FP0
220462306a36Sopenharmony_ci#
220562306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
220662306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
220762306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
220862306a36Sopenharmony_ci	unlk		%a6
220962306a36Sopenharmony_ci	rts
221062306a36Sopenharmony_ci
221162306a36Sopenharmony_ci	global		_ftand_
221262306a36Sopenharmony_ci_ftand_:
221362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
221462306a36Sopenharmony_ci
221562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
221662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
221762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
221862306a36Sopenharmony_ci
221962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
222062306a36Sopenharmony_ci
222162306a36Sopenharmony_ci#
222262306a36Sopenharmony_ci#	copy, convert, and tag input argument
222362306a36Sopenharmony_ci#
222462306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
222562306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
222662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
222762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
222862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
222962306a36Sopenharmony_ci	mov.b		%d0,%d1
223062306a36Sopenharmony_ci
223162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
223262306a36Sopenharmony_ci
223362306a36Sopenharmony_ci	clr.l		%d0
223462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
223562306a36Sopenharmony_ci
223662306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
223762306a36Sopenharmony_ci	tst.b		%d1
223862306a36Sopenharmony_ci	bne.b		_L9_2d
223962306a36Sopenharmony_ci	bsr.l		stan			# operand is a NORM
224062306a36Sopenharmony_ci	bra.b		_L9_6d
224162306a36Sopenharmony_ci_L9_2d:
224262306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
224362306a36Sopenharmony_ci	bne.b		_L9_3d			# no
224462306a36Sopenharmony_ci	bsr.l		src_zero			# yes
224562306a36Sopenharmony_ci	bra.b		_L9_6d
224662306a36Sopenharmony_ci_L9_3d:
224762306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
224862306a36Sopenharmony_ci	bne.b		_L9_4d			# no
224962306a36Sopenharmony_ci	bsr.l		t_operr			# yes
225062306a36Sopenharmony_ci	bra.b		_L9_6d
225162306a36Sopenharmony_ci_L9_4d:
225262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
225362306a36Sopenharmony_ci	bne.b		_L9_5d			# no
225462306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
225562306a36Sopenharmony_ci	bra.b		_L9_6d
225662306a36Sopenharmony_ci_L9_5d:
225762306a36Sopenharmony_ci	bsr.l		stand			# operand is a DENORM
225862306a36Sopenharmony_ci_L9_6d:
225962306a36Sopenharmony_ci
226062306a36Sopenharmony_ci#
226162306a36Sopenharmony_ci#	Result is now in FP0
226262306a36Sopenharmony_ci#
226362306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
226462306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
226562306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
226662306a36Sopenharmony_ci	unlk		%a6
226762306a36Sopenharmony_ci	rts
226862306a36Sopenharmony_ci
226962306a36Sopenharmony_ci	global		_ftanx_
227062306a36Sopenharmony_ci_ftanx_:
227162306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
227262306a36Sopenharmony_ci
227362306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
227462306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
227562306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
227662306a36Sopenharmony_ci
227762306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
227862306a36Sopenharmony_ci
227962306a36Sopenharmony_ci#
228062306a36Sopenharmony_ci#	copy, convert, and tag input argument
228162306a36Sopenharmony_ci#
228262306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
228362306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
228462306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
228562306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
228662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
228762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
228862306a36Sopenharmony_ci	mov.b		%d0,%d1
228962306a36Sopenharmony_ci
229062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
229162306a36Sopenharmony_ci
229262306a36Sopenharmony_ci	clr.l		%d0
229362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
229462306a36Sopenharmony_ci
229562306a36Sopenharmony_ci	tst.b		%d1
229662306a36Sopenharmony_ci	bne.b		_L9_2x
229762306a36Sopenharmony_ci	bsr.l		stan			# operand is a NORM
229862306a36Sopenharmony_ci	bra.b		_L9_6x
229962306a36Sopenharmony_ci_L9_2x:
230062306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
230162306a36Sopenharmony_ci	bne.b		_L9_3x			# no
230262306a36Sopenharmony_ci	bsr.l		src_zero			# yes
230362306a36Sopenharmony_ci	bra.b		_L9_6x
230462306a36Sopenharmony_ci_L9_3x:
230562306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
230662306a36Sopenharmony_ci	bne.b		_L9_4x			# no
230762306a36Sopenharmony_ci	bsr.l		t_operr			# yes
230862306a36Sopenharmony_ci	bra.b		_L9_6x
230962306a36Sopenharmony_ci_L9_4x:
231062306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
231162306a36Sopenharmony_ci	bne.b		_L9_5x			# no
231262306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
231362306a36Sopenharmony_ci	bra.b		_L9_6x
231462306a36Sopenharmony_ci_L9_5x:
231562306a36Sopenharmony_ci	bsr.l		stand			# operand is a DENORM
231662306a36Sopenharmony_ci_L9_6x:
231762306a36Sopenharmony_ci
231862306a36Sopenharmony_ci#
231962306a36Sopenharmony_ci#	Result is now in FP0
232062306a36Sopenharmony_ci#
232162306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
232262306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
232362306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
232462306a36Sopenharmony_ci	unlk		%a6
232562306a36Sopenharmony_ci	rts
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci
232862306a36Sopenharmony_ci#########################################################################
232962306a36Sopenharmony_ci# MONADIC TEMPLATE							#
233062306a36Sopenharmony_ci#########################################################################
233162306a36Sopenharmony_ci	global		_fetoxs_
233262306a36Sopenharmony_ci_fetoxs_:
233362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
233462306a36Sopenharmony_ci
233562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
233662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
233762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
233862306a36Sopenharmony_ci
233962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
234062306a36Sopenharmony_ci
234162306a36Sopenharmony_ci#
234262306a36Sopenharmony_ci#	copy, convert, and tag input argument
234362306a36Sopenharmony_ci#
234462306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
234562306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
234662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
234762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
234862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
234962306a36Sopenharmony_ci	mov.b		%d0,%d1
235062306a36Sopenharmony_ci
235162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
235262306a36Sopenharmony_ci
235362306a36Sopenharmony_ci	clr.l		%d0
235462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
235562306a36Sopenharmony_ci
235662306a36Sopenharmony_ci	tst.b		%d1
235762306a36Sopenharmony_ci	bne.b		_L10_2s
235862306a36Sopenharmony_ci	bsr.l		setox			# operand is a NORM
235962306a36Sopenharmony_ci	bra.b		_L10_6s
236062306a36Sopenharmony_ci_L10_2s:
236162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
236262306a36Sopenharmony_ci	bne.b		_L10_3s			# no
236362306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
236462306a36Sopenharmony_ci	bra.b		_L10_6s
236562306a36Sopenharmony_ci_L10_3s:
236662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
236762306a36Sopenharmony_ci	bne.b		_L10_4s			# no
236862306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
236962306a36Sopenharmony_ci	bra.b		_L10_6s
237062306a36Sopenharmony_ci_L10_4s:
237162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
237262306a36Sopenharmony_ci	bne.b		_L10_5s			# no
237362306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
237462306a36Sopenharmony_ci	bra.b		_L10_6s
237562306a36Sopenharmony_ci_L10_5s:
237662306a36Sopenharmony_ci	bsr.l		setoxd			# operand is a DENORM
237762306a36Sopenharmony_ci_L10_6s:
237862306a36Sopenharmony_ci
237962306a36Sopenharmony_ci#
238062306a36Sopenharmony_ci#	Result is now in FP0
238162306a36Sopenharmony_ci#
238262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
238362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
238462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
238562306a36Sopenharmony_ci	unlk		%a6
238662306a36Sopenharmony_ci	rts
238762306a36Sopenharmony_ci
238862306a36Sopenharmony_ci	global		_fetoxd_
238962306a36Sopenharmony_ci_fetoxd_:
239062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
239162306a36Sopenharmony_ci
239262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
239362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
239462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
239562306a36Sopenharmony_ci
239662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
239762306a36Sopenharmony_ci
239862306a36Sopenharmony_ci#
239962306a36Sopenharmony_ci#	copy, convert, and tag input argument
240062306a36Sopenharmony_ci#
240162306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
240262306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
240362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
240462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
240562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
240662306a36Sopenharmony_ci	mov.b		%d0,%d1
240762306a36Sopenharmony_ci
240862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
240962306a36Sopenharmony_ci
241062306a36Sopenharmony_ci	clr.l		%d0
241162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
241262306a36Sopenharmony_ci
241362306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
241462306a36Sopenharmony_ci	tst.b		%d1
241562306a36Sopenharmony_ci	bne.b		_L10_2d
241662306a36Sopenharmony_ci	bsr.l		setox			# operand is a NORM
241762306a36Sopenharmony_ci	bra.b		_L10_6d
241862306a36Sopenharmony_ci_L10_2d:
241962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
242062306a36Sopenharmony_ci	bne.b		_L10_3d			# no
242162306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
242262306a36Sopenharmony_ci	bra.b		_L10_6d
242362306a36Sopenharmony_ci_L10_3d:
242462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
242562306a36Sopenharmony_ci	bne.b		_L10_4d			# no
242662306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
242762306a36Sopenharmony_ci	bra.b		_L10_6d
242862306a36Sopenharmony_ci_L10_4d:
242962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
243062306a36Sopenharmony_ci	bne.b		_L10_5d			# no
243162306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
243262306a36Sopenharmony_ci	bra.b		_L10_6d
243362306a36Sopenharmony_ci_L10_5d:
243462306a36Sopenharmony_ci	bsr.l		setoxd			# operand is a DENORM
243562306a36Sopenharmony_ci_L10_6d:
243662306a36Sopenharmony_ci
243762306a36Sopenharmony_ci#
243862306a36Sopenharmony_ci#	Result is now in FP0
243962306a36Sopenharmony_ci#
244062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
244162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
244262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
244362306a36Sopenharmony_ci	unlk		%a6
244462306a36Sopenharmony_ci	rts
244562306a36Sopenharmony_ci
244662306a36Sopenharmony_ci	global		_fetoxx_
244762306a36Sopenharmony_ci_fetoxx_:
244862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
244962306a36Sopenharmony_ci
245062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
245162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
245262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
245362306a36Sopenharmony_ci
245462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
245562306a36Sopenharmony_ci
245662306a36Sopenharmony_ci#
245762306a36Sopenharmony_ci#	copy, convert, and tag input argument
245862306a36Sopenharmony_ci#
245962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
246062306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
246162306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
246262306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
246362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
246462306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
246562306a36Sopenharmony_ci	mov.b		%d0,%d1
246662306a36Sopenharmony_ci
246762306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
246862306a36Sopenharmony_ci
246962306a36Sopenharmony_ci	clr.l		%d0
247062306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
247162306a36Sopenharmony_ci
247262306a36Sopenharmony_ci	tst.b		%d1
247362306a36Sopenharmony_ci	bne.b		_L10_2x
247462306a36Sopenharmony_ci	bsr.l		setox			# operand is a NORM
247562306a36Sopenharmony_ci	bra.b		_L10_6x
247662306a36Sopenharmony_ci_L10_2x:
247762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
247862306a36Sopenharmony_ci	bne.b		_L10_3x			# no
247962306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
248062306a36Sopenharmony_ci	bra.b		_L10_6x
248162306a36Sopenharmony_ci_L10_3x:
248262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
248362306a36Sopenharmony_ci	bne.b		_L10_4x			# no
248462306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
248562306a36Sopenharmony_ci	bra.b		_L10_6x
248662306a36Sopenharmony_ci_L10_4x:
248762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
248862306a36Sopenharmony_ci	bne.b		_L10_5x			# no
248962306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
249062306a36Sopenharmony_ci	bra.b		_L10_6x
249162306a36Sopenharmony_ci_L10_5x:
249262306a36Sopenharmony_ci	bsr.l		setoxd			# operand is a DENORM
249362306a36Sopenharmony_ci_L10_6x:
249462306a36Sopenharmony_ci
249562306a36Sopenharmony_ci#
249662306a36Sopenharmony_ci#	Result is now in FP0
249762306a36Sopenharmony_ci#
249862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
249962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
250062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
250162306a36Sopenharmony_ci	unlk		%a6
250262306a36Sopenharmony_ci	rts
250362306a36Sopenharmony_ci
250462306a36Sopenharmony_ci
250562306a36Sopenharmony_ci#########################################################################
250662306a36Sopenharmony_ci# MONADIC TEMPLATE							#
250762306a36Sopenharmony_ci#########################################################################
250862306a36Sopenharmony_ci	global		_ftwotoxs_
250962306a36Sopenharmony_ci_ftwotoxs_:
251062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
251162306a36Sopenharmony_ci
251262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
251362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
251462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
251562306a36Sopenharmony_ci
251662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
251762306a36Sopenharmony_ci
251862306a36Sopenharmony_ci#
251962306a36Sopenharmony_ci#	copy, convert, and tag input argument
252062306a36Sopenharmony_ci#
252162306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
252262306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
252362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
252462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
252562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
252662306a36Sopenharmony_ci	mov.b		%d0,%d1
252762306a36Sopenharmony_ci
252862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
252962306a36Sopenharmony_ci
253062306a36Sopenharmony_ci	clr.l		%d0
253162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
253262306a36Sopenharmony_ci
253362306a36Sopenharmony_ci	tst.b		%d1
253462306a36Sopenharmony_ci	bne.b		_L11_2s
253562306a36Sopenharmony_ci	bsr.l		stwotox			# operand is a NORM
253662306a36Sopenharmony_ci	bra.b		_L11_6s
253762306a36Sopenharmony_ci_L11_2s:
253862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
253962306a36Sopenharmony_ci	bne.b		_L11_3s			# no
254062306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
254162306a36Sopenharmony_ci	bra.b		_L11_6s
254262306a36Sopenharmony_ci_L11_3s:
254362306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
254462306a36Sopenharmony_ci	bne.b		_L11_4s			# no
254562306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
254662306a36Sopenharmony_ci	bra.b		_L11_6s
254762306a36Sopenharmony_ci_L11_4s:
254862306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
254962306a36Sopenharmony_ci	bne.b		_L11_5s			# no
255062306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
255162306a36Sopenharmony_ci	bra.b		_L11_6s
255262306a36Sopenharmony_ci_L11_5s:
255362306a36Sopenharmony_ci	bsr.l		stwotoxd			# operand is a DENORM
255462306a36Sopenharmony_ci_L11_6s:
255562306a36Sopenharmony_ci
255662306a36Sopenharmony_ci#
255762306a36Sopenharmony_ci#	Result is now in FP0
255862306a36Sopenharmony_ci#
255962306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
256062306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
256162306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
256262306a36Sopenharmony_ci	unlk		%a6
256362306a36Sopenharmony_ci	rts
256462306a36Sopenharmony_ci
256562306a36Sopenharmony_ci	global		_ftwotoxd_
256662306a36Sopenharmony_ci_ftwotoxd_:
256762306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
256862306a36Sopenharmony_ci
256962306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
257062306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
257162306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
257262306a36Sopenharmony_ci
257362306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_ci#
257662306a36Sopenharmony_ci#	copy, convert, and tag input argument
257762306a36Sopenharmony_ci#
257862306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
257962306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
258062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
258162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
258262306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
258362306a36Sopenharmony_ci	mov.b		%d0,%d1
258462306a36Sopenharmony_ci
258562306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
258662306a36Sopenharmony_ci
258762306a36Sopenharmony_ci	clr.l		%d0
258862306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
258962306a36Sopenharmony_ci
259062306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
259162306a36Sopenharmony_ci	tst.b		%d1
259262306a36Sopenharmony_ci	bne.b		_L11_2d
259362306a36Sopenharmony_ci	bsr.l		stwotox			# operand is a NORM
259462306a36Sopenharmony_ci	bra.b		_L11_6d
259562306a36Sopenharmony_ci_L11_2d:
259662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
259762306a36Sopenharmony_ci	bne.b		_L11_3d			# no
259862306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
259962306a36Sopenharmony_ci	bra.b		_L11_6d
260062306a36Sopenharmony_ci_L11_3d:
260162306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
260262306a36Sopenharmony_ci	bne.b		_L11_4d			# no
260362306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
260462306a36Sopenharmony_ci	bra.b		_L11_6d
260562306a36Sopenharmony_ci_L11_4d:
260662306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
260762306a36Sopenharmony_ci	bne.b		_L11_5d			# no
260862306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
260962306a36Sopenharmony_ci	bra.b		_L11_6d
261062306a36Sopenharmony_ci_L11_5d:
261162306a36Sopenharmony_ci	bsr.l		stwotoxd			# operand is a DENORM
261262306a36Sopenharmony_ci_L11_6d:
261362306a36Sopenharmony_ci
261462306a36Sopenharmony_ci#
261562306a36Sopenharmony_ci#	Result is now in FP0
261662306a36Sopenharmony_ci#
261762306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
261862306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
261962306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
262062306a36Sopenharmony_ci	unlk		%a6
262162306a36Sopenharmony_ci	rts
262262306a36Sopenharmony_ci
262362306a36Sopenharmony_ci	global		_ftwotoxx_
262462306a36Sopenharmony_ci_ftwotoxx_:
262562306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
262662306a36Sopenharmony_ci
262762306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
262862306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
262962306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
263262306a36Sopenharmony_ci
263362306a36Sopenharmony_ci#
263462306a36Sopenharmony_ci#	copy, convert, and tag input argument
263562306a36Sopenharmony_ci#
263662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
263762306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
263862306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
263962306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
264062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
264162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
264262306a36Sopenharmony_ci	mov.b		%d0,%d1
264362306a36Sopenharmony_ci
264462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
264562306a36Sopenharmony_ci
264662306a36Sopenharmony_ci	clr.l		%d0
264762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
264862306a36Sopenharmony_ci
264962306a36Sopenharmony_ci	tst.b		%d1
265062306a36Sopenharmony_ci	bne.b		_L11_2x
265162306a36Sopenharmony_ci	bsr.l		stwotox			# operand is a NORM
265262306a36Sopenharmony_ci	bra.b		_L11_6x
265362306a36Sopenharmony_ci_L11_2x:
265462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
265562306a36Sopenharmony_ci	bne.b		_L11_3x			# no
265662306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
265762306a36Sopenharmony_ci	bra.b		_L11_6x
265862306a36Sopenharmony_ci_L11_3x:
265962306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
266062306a36Sopenharmony_ci	bne.b		_L11_4x			# no
266162306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
266262306a36Sopenharmony_ci	bra.b		_L11_6x
266362306a36Sopenharmony_ci_L11_4x:
266462306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
266562306a36Sopenharmony_ci	bne.b		_L11_5x			# no
266662306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
266762306a36Sopenharmony_ci	bra.b		_L11_6x
266862306a36Sopenharmony_ci_L11_5x:
266962306a36Sopenharmony_ci	bsr.l		stwotoxd			# operand is a DENORM
267062306a36Sopenharmony_ci_L11_6x:
267162306a36Sopenharmony_ci
267262306a36Sopenharmony_ci#
267362306a36Sopenharmony_ci#	Result is now in FP0
267462306a36Sopenharmony_ci#
267562306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
267662306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
267762306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
267862306a36Sopenharmony_ci	unlk		%a6
267962306a36Sopenharmony_ci	rts
268062306a36Sopenharmony_ci
268162306a36Sopenharmony_ci
268262306a36Sopenharmony_ci#########################################################################
268362306a36Sopenharmony_ci# MONADIC TEMPLATE							#
268462306a36Sopenharmony_ci#########################################################################
268562306a36Sopenharmony_ci	global		_ftentoxs_
268662306a36Sopenharmony_ci_ftentoxs_:
268762306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
268862306a36Sopenharmony_ci
268962306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
269062306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
269162306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
269262306a36Sopenharmony_ci
269362306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
269462306a36Sopenharmony_ci
269562306a36Sopenharmony_ci#
269662306a36Sopenharmony_ci#	copy, convert, and tag input argument
269762306a36Sopenharmony_ci#
269862306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
269962306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
270062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
270162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
270262306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
270362306a36Sopenharmony_ci	mov.b		%d0,%d1
270462306a36Sopenharmony_ci
270562306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
270662306a36Sopenharmony_ci
270762306a36Sopenharmony_ci	clr.l		%d0
270862306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
270962306a36Sopenharmony_ci
271062306a36Sopenharmony_ci	tst.b		%d1
271162306a36Sopenharmony_ci	bne.b		_L12_2s
271262306a36Sopenharmony_ci	bsr.l		stentox			# operand is a NORM
271362306a36Sopenharmony_ci	bra.b		_L12_6s
271462306a36Sopenharmony_ci_L12_2s:
271562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
271662306a36Sopenharmony_ci	bne.b		_L12_3s			# no
271762306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
271862306a36Sopenharmony_ci	bra.b		_L12_6s
271962306a36Sopenharmony_ci_L12_3s:
272062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
272162306a36Sopenharmony_ci	bne.b		_L12_4s			# no
272262306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
272362306a36Sopenharmony_ci	bra.b		_L12_6s
272462306a36Sopenharmony_ci_L12_4s:
272562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
272662306a36Sopenharmony_ci	bne.b		_L12_5s			# no
272762306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
272862306a36Sopenharmony_ci	bra.b		_L12_6s
272962306a36Sopenharmony_ci_L12_5s:
273062306a36Sopenharmony_ci	bsr.l		stentoxd			# operand is a DENORM
273162306a36Sopenharmony_ci_L12_6s:
273262306a36Sopenharmony_ci
273362306a36Sopenharmony_ci#
273462306a36Sopenharmony_ci#	Result is now in FP0
273562306a36Sopenharmony_ci#
273662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
273762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
273862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
273962306a36Sopenharmony_ci	unlk		%a6
274062306a36Sopenharmony_ci	rts
274162306a36Sopenharmony_ci
274262306a36Sopenharmony_ci	global		_ftentoxd_
274362306a36Sopenharmony_ci_ftentoxd_:
274462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
274562306a36Sopenharmony_ci
274662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
274762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
274862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
275162306a36Sopenharmony_ci
275262306a36Sopenharmony_ci#
275362306a36Sopenharmony_ci#	copy, convert, and tag input argument
275462306a36Sopenharmony_ci#
275562306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
275662306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
275762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
275862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
275962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
276062306a36Sopenharmony_ci	mov.b		%d0,%d1
276162306a36Sopenharmony_ci
276262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
276362306a36Sopenharmony_ci
276462306a36Sopenharmony_ci	clr.l		%d0
276562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
276662306a36Sopenharmony_ci
276762306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
276862306a36Sopenharmony_ci	tst.b		%d1
276962306a36Sopenharmony_ci	bne.b		_L12_2d
277062306a36Sopenharmony_ci	bsr.l		stentox			# operand is a NORM
277162306a36Sopenharmony_ci	bra.b		_L12_6d
277262306a36Sopenharmony_ci_L12_2d:
277362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
277462306a36Sopenharmony_ci	bne.b		_L12_3d			# no
277562306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
277662306a36Sopenharmony_ci	bra.b		_L12_6d
277762306a36Sopenharmony_ci_L12_3d:
277862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
277962306a36Sopenharmony_ci	bne.b		_L12_4d			# no
278062306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
278162306a36Sopenharmony_ci	bra.b		_L12_6d
278262306a36Sopenharmony_ci_L12_4d:
278362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
278462306a36Sopenharmony_ci	bne.b		_L12_5d			# no
278562306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
278662306a36Sopenharmony_ci	bra.b		_L12_6d
278762306a36Sopenharmony_ci_L12_5d:
278862306a36Sopenharmony_ci	bsr.l		stentoxd			# operand is a DENORM
278962306a36Sopenharmony_ci_L12_6d:
279062306a36Sopenharmony_ci
279162306a36Sopenharmony_ci#
279262306a36Sopenharmony_ci#	Result is now in FP0
279362306a36Sopenharmony_ci#
279462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
279562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
279662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
279762306a36Sopenharmony_ci	unlk		%a6
279862306a36Sopenharmony_ci	rts
279962306a36Sopenharmony_ci
280062306a36Sopenharmony_ci	global		_ftentoxx_
280162306a36Sopenharmony_ci_ftentoxx_:
280262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
280362306a36Sopenharmony_ci
280462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
280562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
280662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
280762306a36Sopenharmony_ci
280862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_ci#
281162306a36Sopenharmony_ci#	copy, convert, and tag input argument
281262306a36Sopenharmony_ci#
281362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
281462306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
281562306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
281662306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
281762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
281862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
281962306a36Sopenharmony_ci	mov.b		%d0,%d1
282062306a36Sopenharmony_ci
282162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
282262306a36Sopenharmony_ci
282362306a36Sopenharmony_ci	clr.l		%d0
282462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
282562306a36Sopenharmony_ci
282662306a36Sopenharmony_ci	tst.b		%d1
282762306a36Sopenharmony_ci	bne.b		_L12_2x
282862306a36Sopenharmony_ci	bsr.l		stentox			# operand is a NORM
282962306a36Sopenharmony_ci	bra.b		_L12_6x
283062306a36Sopenharmony_ci_L12_2x:
283162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
283262306a36Sopenharmony_ci	bne.b		_L12_3x			# no
283362306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
283462306a36Sopenharmony_ci	bra.b		_L12_6x
283562306a36Sopenharmony_ci_L12_3x:
283662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
283762306a36Sopenharmony_ci	bne.b		_L12_4x			# no
283862306a36Sopenharmony_ci	bsr.l		szr_inf			# yes
283962306a36Sopenharmony_ci	bra.b		_L12_6x
284062306a36Sopenharmony_ci_L12_4x:
284162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
284262306a36Sopenharmony_ci	bne.b		_L12_5x			# no
284362306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
284462306a36Sopenharmony_ci	bra.b		_L12_6x
284562306a36Sopenharmony_ci_L12_5x:
284662306a36Sopenharmony_ci	bsr.l		stentoxd			# operand is a DENORM
284762306a36Sopenharmony_ci_L12_6x:
284862306a36Sopenharmony_ci
284962306a36Sopenharmony_ci#
285062306a36Sopenharmony_ci#	Result is now in FP0
285162306a36Sopenharmony_ci#
285262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
285362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
285462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
285562306a36Sopenharmony_ci	unlk		%a6
285662306a36Sopenharmony_ci	rts
285762306a36Sopenharmony_ci
285862306a36Sopenharmony_ci
285962306a36Sopenharmony_ci#########################################################################
286062306a36Sopenharmony_ci# MONADIC TEMPLATE							#
286162306a36Sopenharmony_ci#########################################################################
286262306a36Sopenharmony_ci	global		_flogns_
286362306a36Sopenharmony_ci_flogns_:
286462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
286562306a36Sopenharmony_ci
286662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
286762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
286862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
286962306a36Sopenharmony_ci
287062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
287162306a36Sopenharmony_ci
287262306a36Sopenharmony_ci#
287362306a36Sopenharmony_ci#	copy, convert, and tag input argument
287462306a36Sopenharmony_ci#
287562306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
287662306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
287762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
287862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
287962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
288062306a36Sopenharmony_ci	mov.b		%d0,%d1
288162306a36Sopenharmony_ci
288262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
288362306a36Sopenharmony_ci
288462306a36Sopenharmony_ci	clr.l		%d0
288562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
288662306a36Sopenharmony_ci
288762306a36Sopenharmony_ci	tst.b		%d1
288862306a36Sopenharmony_ci	bne.b		_L13_2s
288962306a36Sopenharmony_ci	bsr.l		slogn			# operand is a NORM
289062306a36Sopenharmony_ci	bra.b		_L13_6s
289162306a36Sopenharmony_ci_L13_2s:
289262306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
289362306a36Sopenharmony_ci	bne.b		_L13_3s			# no
289462306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
289562306a36Sopenharmony_ci	bra.b		_L13_6s
289662306a36Sopenharmony_ci_L13_3s:
289762306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
289862306a36Sopenharmony_ci	bne.b		_L13_4s			# no
289962306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
290062306a36Sopenharmony_ci	bra.b		_L13_6s
290162306a36Sopenharmony_ci_L13_4s:
290262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
290362306a36Sopenharmony_ci	bne.b		_L13_5s			# no
290462306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
290562306a36Sopenharmony_ci	bra.b		_L13_6s
290662306a36Sopenharmony_ci_L13_5s:
290762306a36Sopenharmony_ci	bsr.l		slognd			# operand is a DENORM
290862306a36Sopenharmony_ci_L13_6s:
290962306a36Sopenharmony_ci
291062306a36Sopenharmony_ci#
291162306a36Sopenharmony_ci#	Result is now in FP0
291262306a36Sopenharmony_ci#
291362306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
291462306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
291562306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
291662306a36Sopenharmony_ci	unlk		%a6
291762306a36Sopenharmony_ci	rts
291862306a36Sopenharmony_ci
291962306a36Sopenharmony_ci	global		_flognd_
292062306a36Sopenharmony_ci_flognd_:
292162306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
292262306a36Sopenharmony_ci
292362306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
292462306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
292562306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
292662306a36Sopenharmony_ci
292762306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
292862306a36Sopenharmony_ci
292962306a36Sopenharmony_ci#
293062306a36Sopenharmony_ci#	copy, convert, and tag input argument
293162306a36Sopenharmony_ci#
293262306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
293362306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
293462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
293562306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
293662306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
293762306a36Sopenharmony_ci	mov.b		%d0,%d1
293862306a36Sopenharmony_ci
293962306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
294062306a36Sopenharmony_ci
294162306a36Sopenharmony_ci	clr.l		%d0
294262306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
294362306a36Sopenharmony_ci
294462306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
294562306a36Sopenharmony_ci	tst.b		%d1
294662306a36Sopenharmony_ci	bne.b		_L13_2d
294762306a36Sopenharmony_ci	bsr.l		slogn			# operand is a NORM
294862306a36Sopenharmony_ci	bra.b		_L13_6d
294962306a36Sopenharmony_ci_L13_2d:
295062306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
295162306a36Sopenharmony_ci	bne.b		_L13_3d			# no
295262306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
295362306a36Sopenharmony_ci	bra.b		_L13_6d
295462306a36Sopenharmony_ci_L13_3d:
295562306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
295662306a36Sopenharmony_ci	bne.b		_L13_4d			# no
295762306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
295862306a36Sopenharmony_ci	bra.b		_L13_6d
295962306a36Sopenharmony_ci_L13_4d:
296062306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
296162306a36Sopenharmony_ci	bne.b		_L13_5d			# no
296262306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
296362306a36Sopenharmony_ci	bra.b		_L13_6d
296462306a36Sopenharmony_ci_L13_5d:
296562306a36Sopenharmony_ci	bsr.l		slognd			# operand is a DENORM
296662306a36Sopenharmony_ci_L13_6d:
296762306a36Sopenharmony_ci
296862306a36Sopenharmony_ci#
296962306a36Sopenharmony_ci#	Result is now in FP0
297062306a36Sopenharmony_ci#
297162306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
297262306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
297362306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
297462306a36Sopenharmony_ci	unlk		%a6
297562306a36Sopenharmony_ci	rts
297662306a36Sopenharmony_ci
297762306a36Sopenharmony_ci	global		_flognx_
297862306a36Sopenharmony_ci_flognx_:
297962306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
298062306a36Sopenharmony_ci
298162306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
298262306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
298362306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
298462306a36Sopenharmony_ci
298562306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
298662306a36Sopenharmony_ci
298762306a36Sopenharmony_ci#
298862306a36Sopenharmony_ci#	copy, convert, and tag input argument
298962306a36Sopenharmony_ci#
299062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
299162306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
299262306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
299362306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
299462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
299562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
299662306a36Sopenharmony_ci	mov.b		%d0,%d1
299762306a36Sopenharmony_ci
299862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
299962306a36Sopenharmony_ci
300062306a36Sopenharmony_ci	clr.l		%d0
300162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
300262306a36Sopenharmony_ci
300362306a36Sopenharmony_ci	tst.b		%d1
300462306a36Sopenharmony_ci	bne.b		_L13_2x
300562306a36Sopenharmony_ci	bsr.l		slogn			# operand is a NORM
300662306a36Sopenharmony_ci	bra.b		_L13_6x
300762306a36Sopenharmony_ci_L13_2x:
300862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
300962306a36Sopenharmony_ci	bne.b		_L13_3x			# no
301062306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
301162306a36Sopenharmony_ci	bra.b		_L13_6x
301262306a36Sopenharmony_ci_L13_3x:
301362306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
301462306a36Sopenharmony_ci	bne.b		_L13_4x			# no
301562306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
301662306a36Sopenharmony_ci	bra.b		_L13_6x
301762306a36Sopenharmony_ci_L13_4x:
301862306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
301962306a36Sopenharmony_ci	bne.b		_L13_5x			# no
302062306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
302162306a36Sopenharmony_ci	bra.b		_L13_6x
302262306a36Sopenharmony_ci_L13_5x:
302362306a36Sopenharmony_ci	bsr.l		slognd			# operand is a DENORM
302462306a36Sopenharmony_ci_L13_6x:
302562306a36Sopenharmony_ci
302662306a36Sopenharmony_ci#
302762306a36Sopenharmony_ci#	Result is now in FP0
302862306a36Sopenharmony_ci#
302962306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
303062306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
303162306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
303262306a36Sopenharmony_ci	unlk		%a6
303362306a36Sopenharmony_ci	rts
303462306a36Sopenharmony_ci
303562306a36Sopenharmony_ci
303662306a36Sopenharmony_ci#########################################################################
303762306a36Sopenharmony_ci# MONADIC TEMPLATE							#
303862306a36Sopenharmony_ci#########################################################################
303962306a36Sopenharmony_ci	global		_flog10s_
304062306a36Sopenharmony_ci_flog10s_:
304162306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
304262306a36Sopenharmony_ci
304362306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
304462306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
304562306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
304662306a36Sopenharmony_ci
304762306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
304862306a36Sopenharmony_ci
304962306a36Sopenharmony_ci#
305062306a36Sopenharmony_ci#	copy, convert, and tag input argument
305162306a36Sopenharmony_ci#
305262306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
305362306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
305462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
305562306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
305662306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
305762306a36Sopenharmony_ci	mov.b		%d0,%d1
305862306a36Sopenharmony_ci
305962306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
306062306a36Sopenharmony_ci
306162306a36Sopenharmony_ci	clr.l		%d0
306262306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
306362306a36Sopenharmony_ci
306462306a36Sopenharmony_ci	tst.b		%d1
306562306a36Sopenharmony_ci	bne.b		_L14_2s
306662306a36Sopenharmony_ci	bsr.l		slog10			# operand is a NORM
306762306a36Sopenharmony_ci	bra.b		_L14_6s
306862306a36Sopenharmony_ci_L14_2s:
306962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
307062306a36Sopenharmony_ci	bne.b		_L14_3s			# no
307162306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
307262306a36Sopenharmony_ci	bra.b		_L14_6s
307362306a36Sopenharmony_ci_L14_3s:
307462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
307562306a36Sopenharmony_ci	bne.b		_L14_4s			# no
307662306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
307762306a36Sopenharmony_ci	bra.b		_L14_6s
307862306a36Sopenharmony_ci_L14_4s:
307962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
308062306a36Sopenharmony_ci	bne.b		_L14_5s			# no
308162306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
308262306a36Sopenharmony_ci	bra.b		_L14_6s
308362306a36Sopenharmony_ci_L14_5s:
308462306a36Sopenharmony_ci	bsr.l		slog10d			# operand is a DENORM
308562306a36Sopenharmony_ci_L14_6s:
308662306a36Sopenharmony_ci
308762306a36Sopenharmony_ci#
308862306a36Sopenharmony_ci#	Result is now in FP0
308962306a36Sopenharmony_ci#
309062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
309162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
309262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
309362306a36Sopenharmony_ci	unlk		%a6
309462306a36Sopenharmony_ci	rts
309562306a36Sopenharmony_ci
309662306a36Sopenharmony_ci	global		_flog10d_
309762306a36Sopenharmony_ci_flog10d_:
309862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
309962306a36Sopenharmony_ci
310062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
310162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
310262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
310362306a36Sopenharmony_ci
310462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
310562306a36Sopenharmony_ci
310662306a36Sopenharmony_ci#
310762306a36Sopenharmony_ci#	copy, convert, and tag input argument
310862306a36Sopenharmony_ci#
310962306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
311062306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
311162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
311262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
311362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
311462306a36Sopenharmony_ci	mov.b		%d0,%d1
311562306a36Sopenharmony_ci
311662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
311762306a36Sopenharmony_ci
311862306a36Sopenharmony_ci	clr.l		%d0
311962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
312062306a36Sopenharmony_ci
312162306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
312262306a36Sopenharmony_ci	tst.b		%d1
312362306a36Sopenharmony_ci	bne.b		_L14_2d
312462306a36Sopenharmony_ci	bsr.l		slog10			# operand is a NORM
312562306a36Sopenharmony_ci	bra.b		_L14_6d
312662306a36Sopenharmony_ci_L14_2d:
312762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
312862306a36Sopenharmony_ci	bne.b		_L14_3d			# no
312962306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
313062306a36Sopenharmony_ci	bra.b		_L14_6d
313162306a36Sopenharmony_ci_L14_3d:
313262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
313362306a36Sopenharmony_ci	bne.b		_L14_4d			# no
313462306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
313562306a36Sopenharmony_ci	bra.b		_L14_6d
313662306a36Sopenharmony_ci_L14_4d:
313762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
313862306a36Sopenharmony_ci	bne.b		_L14_5d			# no
313962306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
314062306a36Sopenharmony_ci	bra.b		_L14_6d
314162306a36Sopenharmony_ci_L14_5d:
314262306a36Sopenharmony_ci	bsr.l		slog10d			# operand is a DENORM
314362306a36Sopenharmony_ci_L14_6d:
314462306a36Sopenharmony_ci
314562306a36Sopenharmony_ci#
314662306a36Sopenharmony_ci#	Result is now in FP0
314762306a36Sopenharmony_ci#
314862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
314962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
315062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
315162306a36Sopenharmony_ci	unlk		%a6
315262306a36Sopenharmony_ci	rts
315362306a36Sopenharmony_ci
315462306a36Sopenharmony_ci	global		_flog10x_
315562306a36Sopenharmony_ci_flog10x_:
315662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
315762306a36Sopenharmony_ci
315862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
315962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
316062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
316162306a36Sopenharmony_ci
316262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
316362306a36Sopenharmony_ci
316462306a36Sopenharmony_ci#
316562306a36Sopenharmony_ci#	copy, convert, and tag input argument
316662306a36Sopenharmony_ci#
316762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
316862306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
316962306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
317062306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
317162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
317262306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
317362306a36Sopenharmony_ci	mov.b		%d0,%d1
317462306a36Sopenharmony_ci
317562306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
317662306a36Sopenharmony_ci
317762306a36Sopenharmony_ci	clr.l		%d0
317862306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
317962306a36Sopenharmony_ci
318062306a36Sopenharmony_ci	tst.b		%d1
318162306a36Sopenharmony_ci	bne.b		_L14_2x
318262306a36Sopenharmony_ci	bsr.l		slog10			# operand is a NORM
318362306a36Sopenharmony_ci	bra.b		_L14_6x
318462306a36Sopenharmony_ci_L14_2x:
318562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
318662306a36Sopenharmony_ci	bne.b		_L14_3x			# no
318762306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
318862306a36Sopenharmony_ci	bra.b		_L14_6x
318962306a36Sopenharmony_ci_L14_3x:
319062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
319162306a36Sopenharmony_ci	bne.b		_L14_4x			# no
319262306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
319362306a36Sopenharmony_ci	bra.b		_L14_6x
319462306a36Sopenharmony_ci_L14_4x:
319562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
319662306a36Sopenharmony_ci	bne.b		_L14_5x			# no
319762306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
319862306a36Sopenharmony_ci	bra.b		_L14_6x
319962306a36Sopenharmony_ci_L14_5x:
320062306a36Sopenharmony_ci	bsr.l		slog10d			# operand is a DENORM
320162306a36Sopenharmony_ci_L14_6x:
320262306a36Sopenharmony_ci
320362306a36Sopenharmony_ci#
320462306a36Sopenharmony_ci#	Result is now in FP0
320562306a36Sopenharmony_ci#
320662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
320762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
320862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
320962306a36Sopenharmony_ci	unlk		%a6
321062306a36Sopenharmony_ci	rts
321162306a36Sopenharmony_ci
321262306a36Sopenharmony_ci
321362306a36Sopenharmony_ci#########################################################################
321462306a36Sopenharmony_ci# MONADIC TEMPLATE							#
321562306a36Sopenharmony_ci#########################################################################
321662306a36Sopenharmony_ci	global		_flog2s_
321762306a36Sopenharmony_ci_flog2s_:
321862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
321962306a36Sopenharmony_ci
322062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
322162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
322262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
322362306a36Sopenharmony_ci
322462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_ci#
322762306a36Sopenharmony_ci#	copy, convert, and tag input argument
322862306a36Sopenharmony_ci#
322962306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
323062306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
323162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
323262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
323362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
323462306a36Sopenharmony_ci	mov.b		%d0,%d1
323562306a36Sopenharmony_ci
323662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
323762306a36Sopenharmony_ci
323862306a36Sopenharmony_ci	clr.l		%d0
323962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
324062306a36Sopenharmony_ci
324162306a36Sopenharmony_ci	tst.b		%d1
324262306a36Sopenharmony_ci	bne.b		_L15_2s
324362306a36Sopenharmony_ci	bsr.l		slog2			# operand is a NORM
324462306a36Sopenharmony_ci	bra.b		_L15_6s
324562306a36Sopenharmony_ci_L15_2s:
324662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
324762306a36Sopenharmony_ci	bne.b		_L15_3s			# no
324862306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
324962306a36Sopenharmony_ci	bra.b		_L15_6s
325062306a36Sopenharmony_ci_L15_3s:
325162306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
325262306a36Sopenharmony_ci	bne.b		_L15_4s			# no
325362306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
325462306a36Sopenharmony_ci	bra.b		_L15_6s
325562306a36Sopenharmony_ci_L15_4s:
325662306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
325762306a36Sopenharmony_ci	bne.b		_L15_5s			# no
325862306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
325962306a36Sopenharmony_ci	bra.b		_L15_6s
326062306a36Sopenharmony_ci_L15_5s:
326162306a36Sopenharmony_ci	bsr.l		slog2d			# operand is a DENORM
326262306a36Sopenharmony_ci_L15_6s:
326362306a36Sopenharmony_ci
326462306a36Sopenharmony_ci#
326562306a36Sopenharmony_ci#	Result is now in FP0
326662306a36Sopenharmony_ci#
326762306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
326862306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
326962306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
327062306a36Sopenharmony_ci	unlk		%a6
327162306a36Sopenharmony_ci	rts
327262306a36Sopenharmony_ci
327362306a36Sopenharmony_ci	global		_flog2d_
327462306a36Sopenharmony_ci_flog2d_:
327562306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
327662306a36Sopenharmony_ci
327762306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
327862306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
327962306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
328062306a36Sopenharmony_ci
328162306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
328262306a36Sopenharmony_ci
328362306a36Sopenharmony_ci#
328462306a36Sopenharmony_ci#	copy, convert, and tag input argument
328562306a36Sopenharmony_ci#
328662306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
328762306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
328862306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
328962306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
329062306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
329162306a36Sopenharmony_ci	mov.b		%d0,%d1
329262306a36Sopenharmony_ci
329362306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
329462306a36Sopenharmony_ci
329562306a36Sopenharmony_ci	clr.l		%d0
329662306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
329762306a36Sopenharmony_ci
329862306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
329962306a36Sopenharmony_ci	tst.b		%d1
330062306a36Sopenharmony_ci	bne.b		_L15_2d
330162306a36Sopenharmony_ci	bsr.l		slog2			# operand is a NORM
330262306a36Sopenharmony_ci	bra.b		_L15_6d
330362306a36Sopenharmony_ci_L15_2d:
330462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
330562306a36Sopenharmony_ci	bne.b		_L15_3d			# no
330662306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
330762306a36Sopenharmony_ci	bra.b		_L15_6d
330862306a36Sopenharmony_ci_L15_3d:
330962306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
331062306a36Sopenharmony_ci	bne.b		_L15_4d			# no
331162306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
331262306a36Sopenharmony_ci	bra.b		_L15_6d
331362306a36Sopenharmony_ci_L15_4d:
331462306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
331562306a36Sopenharmony_ci	bne.b		_L15_5d			# no
331662306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
331762306a36Sopenharmony_ci	bra.b		_L15_6d
331862306a36Sopenharmony_ci_L15_5d:
331962306a36Sopenharmony_ci	bsr.l		slog2d			# operand is a DENORM
332062306a36Sopenharmony_ci_L15_6d:
332162306a36Sopenharmony_ci
332262306a36Sopenharmony_ci#
332362306a36Sopenharmony_ci#	Result is now in FP0
332462306a36Sopenharmony_ci#
332562306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
332662306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
332762306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
332862306a36Sopenharmony_ci	unlk		%a6
332962306a36Sopenharmony_ci	rts
333062306a36Sopenharmony_ci
333162306a36Sopenharmony_ci	global		_flog2x_
333262306a36Sopenharmony_ci_flog2x_:
333362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
333462306a36Sopenharmony_ci
333562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
333662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
333762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
333862306a36Sopenharmony_ci
333962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
334062306a36Sopenharmony_ci
334162306a36Sopenharmony_ci#
334262306a36Sopenharmony_ci#	copy, convert, and tag input argument
334362306a36Sopenharmony_ci#
334462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
334562306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
334662306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
334762306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
334862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
334962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
335062306a36Sopenharmony_ci	mov.b		%d0,%d1
335162306a36Sopenharmony_ci
335262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
335362306a36Sopenharmony_ci
335462306a36Sopenharmony_ci	clr.l		%d0
335562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
335662306a36Sopenharmony_ci
335762306a36Sopenharmony_ci	tst.b		%d1
335862306a36Sopenharmony_ci	bne.b		_L15_2x
335962306a36Sopenharmony_ci	bsr.l		slog2			# operand is a NORM
336062306a36Sopenharmony_ci	bra.b		_L15_6x
336162306a36Sopenharmony_ci_L15_2x:
336262306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
336362306a36Sopenharmony_ci	bne.b		_L15_3x			# no
336462306a36Sopenharmony_ci	bsr.l		t_dz2			# yes
336562306a36Sopenharmony_ci	bra.b		_L15_6x
336662306a36Sopenharmony_ci_L15_3x:
336762306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
336862306a36Sopenharmony_ci	bne.b		_L15_4x			# no
336962306a36Sopenharmony_ci	bsr.l		sopr_inf			# yes
337062306a36Sopenharmony_ci	bra.b		_L15_6x
337162306a36Sopenharmony_ci_L15_4x:
337262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
337362306a36Sopenharmony_ci	bne.b		_L15_5x			# no
337462306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
337562306a36Sopenharmony_ci	bra.b		_L15_6x
337662306a36Sopenharmony_ci_L15_5x:
337762306a36Sopenharmony_ci	bsr.l		slog2d			# operand is a DENORM
337862306a36Sopenharmony_ci_L15_6x:
337962306a36Sopenharmony_ci
338062306a36Sopenharmony_ci#
338162306a36Sopenharmony_ci#	Result is now in FP0
338262306a36Sopenharmony_ci#
338362306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
338462306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
338562306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
338662306a36Sopenharmony_ci	unlk		%a6
338762306a36Sopenharmony_ci	rts
338862306a36Sopenharmony_ci
338962306a36Sopenharmony_ci
339062306a36Sopenharmony_ci#########################################################################
339162306a36Sopenharmony_ci# MONADIC TEMPLATE							#
339262306a36Sopenharmony_ci#########################################################################
339362306a36Sopenharmony_ci	global		_fcoshs_
339462306a36Sopenharmony_ci_fcoshs_:
339562306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
339662306a36Sopenharmony_ci
339762306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
339862306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
339962306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
340062306a36Sopenharmony_ci
340162306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
340262306a36Sopenharmony_ci
340362306a36Sopenharmony_ci#
340462306a36Sopenharmony_ci#	copy, convert, and tag input argument
340562306a36Sopenharmony_ci#
340662306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
340762306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
340862306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
340962306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
341062306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
341162306a36Sopenharmony_ci	mov.b		%d0,%d1
341262306a36Sopenharmony_ci
341362306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
341462306a36Sopenharmony_ci
341562306a36Sopenharmony_ci	clr.l		%d0
341662306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
341762306a36Sopenharmony_ci
341862306a36Sopenharmony_ci	tst.b		%d1
341962306a36Sopenharmony_ci	bne.b		_L16_2s
342062306a36Sopenharmony_ci	bsr.l		scosh			# operand is a NORM
342162306a36Sopenharmony_ci	bra.b		_L16_6s
342262306a36Sopenharmony_ci_L16_2s:
342362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
342462306a36Sopenharmony_ci	bne.b		_L16_3s			# no
342562306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
342662306a36Sopenharmony_ci	bra.b		_L16_6s
342762306a36Sopenharmony_ci_L16_3s:
342862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
342962306a36Sopenharmony_ci	bne.b		_L16_4s			# no
343062306a36Sopenharmony_ci	bsr.l		ld_pinf			# yes
343162306a36Sopenharmony_ci	bra.b		_L16_6s
343262306a36Sopenharmony_ci_L16_4s:
343362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
343462306a36Sopenharmony_ci	bne.b		_L16_5s			# no
343562306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
343662306a36Sopenharmony_ci	bra.b		_L16_6s
343762306a36Sopenharmony_ci_L16_5s:
343862306a36Sopenharmony_ci	bsr.l		scoshd			# operand is a DENORM
343962306a36Sopenharmony_ci_L16_6s:
344062306a36Sopenharmony_ci
344162306a36Sopenharmony_ci#
344262306a36Sopenharmony_ci#	Result is now in FP0
344362306a36Sopenharmony_ci#
344462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
344562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
344662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
344762306a36Sopenharmony_ci	unlk		%a6
344862306a36Sopenharmony_ci	rts
344962306a36Sopenharmony_ci
345062306a36Sopenharmony_ci	global		_fcoshd_
345162306a36Sopenharmony_ci_fcoshd_:
345262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
345362306a36Sopenharmony_ci
345462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
345562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
345662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
345762306a36Sopenharmony_ci
345862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
345962306a36Sopenharmony_ci
346062306a36Sopenharmony_ci#
346162306a36Sopenharmony_ci#	copy, convert, and tag input argument
346262306a36Sopenharmony_ci#
346362306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
346462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
346562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
346662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
346762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
346862306a36Sopenharmony_ci	mov.b		%d0,%d1
346962306a36Sopenharmony_ci
347062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
347162306a36Sopenharmony_ci
347262306a36Sopenharmony_ci	clr.l		%d0
347362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
347462306a36Sopenharmony_ci
347562306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
347662306a36Sopenharmony_ci	tst.b		%d1
347762306a36Sopenharmony_ci	bne.b		_L16_2d
347862306a36Sopenharmony_ci	bsr.l		scosh			# operand is a NORM
347962306a36Sopenharmony_ci	bra.b		_L16_6d
348062306a36Sopenharmony_ci_L16_2d:
348162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
348262306a36Sopenharmony_ci	bne.b		_L16_3d			# no
348362306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
348462306a36Sopenharmony_ci	bra.b		_L16_6d
348562306a36Sopenharmony_ci_L16_3d:
348662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
348762306a36Sopenharmony_ci	bne.b		_L16_4d			# no
348862306a36Sopenharmony_ci	bsr.l		ld_pinf			# yes
348962306a36Sopenharmony_ci	bra.b		_L16_6d
349062306a36Sopenharmony_ci_L16_4d:
349162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
349262306a36Sopenharmony_ci	bne.b		_L16_5d			# no
349362306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
349462306a36Sopenharmony_ci	bra.b		_L16_6d
349562306a36Sopenharmony_ci_L16_5d:
349662306a36Sopenharmony_ci	bsr.l		scoshd			# operand is a DENORM
349762306a36Sopenharmony_ci_L16_6d:
349862306a36Sopenharmony_ci
349962306a36Sopenharmony_ci#
350062306a36Sopenharmony_ci#	Result is now in FP0
350162306a36Sopenharmony_ci#
350262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
350362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
350462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
350562306a36Sopenharmony_ci	unlk		%a6
350662306a36Sopenharmony_ci	rts
350762306a36Sopenharmony_ci
350862306a36Sopenharmony_ci	global		_fcoshx_
350962306a36Sopenharmony_ci_fcoshx_:
351062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
351162306a36Sopenharmony_ci
351262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
351362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
351462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
351562306a36Sopenharmony_ci
351662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
351762306a36Sopenharmony_ci
351862306a36Sopenharmony_ci#
351962306a36Sopenharmony_ci#	copy, convert, and tag input argument
352062306a36Sopenharmony_ci#
352162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
352262306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
352362306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
352462306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
352562306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
352662306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
352762306a36Sopenharmony_ci	mov.b		%d0,%d1
352862306a36Sopenharmony_ci
352962306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
353062306a36Sopenharmony_ci
353162306a36Sopenharmony_ci	clr.l		%d0
353262306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
353362306a36Sopenharmony_ci
353462306a36Sopenharmony_ci	tst.b		%d1
353562306a36Sopenharmony_ci	bne.b		_L16_2x
353662306a36Sopenharmony_ci	bsr.l		scosh			# operand is a NORM
353762306a36Sopenharmony_ci	bra.b		_L16_6x
353862306a36Sopenharmony_ci_L16_2x:
353962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
354062306a36Sopenharmony_ci	bne.b		_L16_3x			# no
354162306a36Sopenharmony_ci	bsr.l		ld_pone			# yes
354262306a36Sopenharmony_ci	bra.b		_L16_6x
354362306a36Sopenharmony_ci_L16_3x:
354462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
354562306a36Sopenharmony_ci	bne.b		_L16_4x			# no
354662306a36Sopenharmony_ci	bsr.l		ld_pinf			# yes
354762306a36Sopenharmony_ci	bra.b		_L16_6x
354862306a36Sopenharmony_ci_L16_4x:
354962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
355062306a36Sopenharmony_ci	bne.b		_L16_5x			# no
355162306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
355262306a36Sopenharmony_ci	bra.b		_L16_6x
355362306a36Sopenharmony_ci_L16_5x:
355462306a36Sopenharmony_ci	bsr.l		scoshd			# operand is a DENORM
355562306a36Sopenharmony_ci_L16_6x:
355662306a36Sopenharmony_ci
355762306a36Sopenharmony_ci#
355862306a36Sopenharmony_ci#	Result is now in FP0
355962306a36Sopenharmony_ci#
356062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
356162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
356262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
356362306a36Sopenharmony_ci	unlk		%a6
356462306a36Sopenharmony_ci	rts
356562306a36Sopenharmony_ci
356662306a36Sopenharmony_ci
356762306a36Sopenharmony_ci#########################################################################
356862306a36Sopenharmony_ci# MONADIC TEMPLATE							#
356962306a36Sopenharmony_ci#########################################################################
357062306a36Sopenharmony_ci	global		_facoss_
357162306a36Sopenharmony_ci_facoss_:
357262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
357362306a36Sopenharmony_ci
357462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
357562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
357662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
357762306a36Sopenharmony_ci
357862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
357962306a36Sopenharmony_ci
358062306a36Sopenharmony_ci#
358162306a36Sopenharmony_ci#	copy, convert, and tag input argument
358262306a36Sopenharmony_ci#
358362306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
358462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
358562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
358662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
358762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
358862306a36Sopenharmony_ci	mov.b		%d0,%d1
358962306a36Sopenharmony_ci
359062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
359162306a36Sopenharmony_ci
359262306a36Sopenharmony_ci	clr.l		%d0
359362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
359462306a36Sopenharmony_ci
359562306a36Sopenharmony_ci	tst.b		%d1
359662306a36Sopenharmony_ci	bne.b		_L17_2s
359762306a36Sopenharmony_ci	bsr.l		sacos			# operand is a NORM
359862306a36Sopenharmony_ci	bra.b		_L17_6s
359962306a36Sopenharmony_ci_L17_2s:
360062306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
360162306a36Sopenharmony_ci	bne.b		_L17_3s			# no
360262306a36Sopenharmony_ci	bsr.l		ld_ppi2			# yes
360362306a36Sopenharmony_ci	bra.b		_L17_6s
360462306a36Sopenharmony_ci_L17_3s:
360562306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
360662306a36Sopenharmony_ci	bne.b		_L17_4s			# no
360762306a36Sopenharmony_ci	bsr.l		t_operr			# yes
360862306a36Sopenharmony_ci	bra.b		_L17_6s
360962306a36Sopenharmony_ci_L17_4s:
361062306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
361162306a36Sopenharmony_ci	bne.b		_L17_5s			# no
361262306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
361362306a36Sopenharmony_ci	bra.b		_L17_6s
361462306a36Sopenharmony_ci_L17_5s:
361562306a36Sopenharmony_ci	bsr.l		sacosd			# operand is a DENORM
361662306a36Sopenharmony_ci_L17_6s:
361762306a36Sopenharmony_ci
361862306a36Sopenharmony_ci#
361962306a36Sopenharmony_ci#	Result is now in FP0
362062306a36Sopenharmony_ci#
362162306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
362262306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
362362306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
362462306a36Sopenharmony_ci	unlk		%a6
362562306a36Sopenharmony_ci	rts
362662306a36Sopenharmony_ci
362762306a36Sopenharmony_ci	global		_facosd_
362862306a36Sopenharmony_ci_facosd_:
362962306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
363062306a36Sopenharmony_ci
363162306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
363262306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
363362306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
363462306a36Sopenharmony_ci
363562306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
363662306a36Sopenharmony_ci
363762306a36Sopenharmony_ci#
363862306a36Sopenharmony_ci#	copy, convert, and tag input argument
363962306a36Sopenharmony_ci#
364062306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
364162306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
364262306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
364362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
364462306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
364562306a36Sopenharmony_ci	mov.b		%d0,%d1
364662306a36Sopenharmony_ci
364762306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
364862306a36Sopenharmony_ci
364962306a36Sopenharmony_ci	clr.l		%d0
365062306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
365162306a36Sopenharmony_ci
365262306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
365362306a36Sopenharmony_ci	tst.b		%d1
365462306a36Sopenharmony_ci	bne.b		_L17_2d
365562306a36Sopenharmony_ci	bsr.l		sacos			# operand is a NORM
365662306a36Sopenharmony_ci	bra.b		_L17_6d
365762306a36Sopenharmony_ci_L17_2d:
365862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
365962306a36Sopenharmony_ci	bne.b		_L17_3d			# no
366062306a36Sopenharmony_ci	bsr.l		ld_ppi2			# yes
366162306a36Sopenharmony_ci	bra.b		_L17_6d
366262306a36Sopenharmony_ci_L17_3d:
366362306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
366462306a36Sopenharmony_ci	bne.b		_L17_4d			# no
366562306a36Sopenharmony_ci	bsr.l		t_operr			# yes
366662306a36Sopenharmony_ci	bra.b		_L17_6d
366762306a36Sopenharmony_ci_L17_4d:
366862306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
366962306a36Sopenharmony_ci	bne.b		_L17_5d			# no
367062306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
367162306a36Sopenharmony_ci	bra.b		_L17_6d
367262306a36Sopenharmony_ci_L17_5d:
367362306a36Sopenharmony_ci	bsr.l		sacosd			# operand is a DENORM
367462306a36Sopenharmony_ci_L17_6d:
367562306a36Sopenharmony_ci
367662306a36Sopenharmony_ci#
367762306a36Sopenharmony_ci#	Result is now in FP0
367862306a36Sopenharmony_ci#
367962306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
368062306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
368162306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
368262306a36Sopenharmony_ci	unlk		%a6
368362306a36Sopenharmony_ci	rts
368462306a36Sopenharmony_ci
368562306a36Sopenharmony_ci	global		_facosx_
368662306a36Sopenharmony_ci_facosx_:
368762306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
368862306a36Sopenharmony_ci
368962306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
369062306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
369162306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
369262306a36Sopenharmony_ci
369362306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
369462306a36Sopenharmony_ci
369562306a36Sopenharmony_ci#
369662306a36Sopenharmony_ci#	copy, convert, and tag input argument
369762306a36Sopenharmony_ci#
369862306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
369962306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
370062306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
370162306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
370262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
370362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
370462306a36Sopenharmony_ci	mov.b		%d0,%d1
370562306a36Sopenharmony_ci
370662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
370762306a36Sopenharmony_ci
370862306a36Sopenharmony_ci	clr.l		%d0
370962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
371062306a36Sopenharmony_ci
371162306a36Sopenharmony_ci	tst.b		%d1
371262306a36Sopenharmony_ci	bne.b		_L17_2x
371362306a36Sopenharmony_ci	bsr.l		sacos			# operand is a NORM
371462306a36Sopenharmony_ci	bra.b		_L17_6x
371562306a36Sopenharmony_ci_L17_2x:
371662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
371762306a36Sopenharmony_ci	bne.b		_L17_3x			# no
371862306a36Sopenharmony_ci	bsr.l		ld_ppi2			# yes
371962306a36Sopenharmony_ci	bra.b		_L17_6x
372062306a36Sopenharmony_ci_L17_3x:
372162306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
372262306a36Sopenharmony_ci	bne.b		_L17_4x			# no
372362306a36Sopenharmony_ci	bsr.l		t_operr			# yes
372462306a36Sopenharmony_ci	bra.b		_L17_6x
372562306a36Sopenharmony_ci_L17_4x:
372662306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
372762306a36Sopenharmony_ci	bne.b		_L17_5x			# no
372862306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
372962306a36Sopenharmony_ci	bra.b		_L17_6x
373062306a36Sopenharmony_ci_L17_5x:
373162306a36Sopenharmony_ci	bsr.l		sacosd			# operand is a DENORM
373262306a36Sopenharmony_ci_L17_6x:
373362306a36Sopenharmony_ci
373462306a36Sopenharmony_ci#
373562306a36Sopenharmony_ci#	Result is now in FP0
373662306a36Sopenharmony_ci#
373762306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
373862306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
373962306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
374062306a36Sopenharmony_ci	unlk		%a6
374162306a36Sopenharmony_ci	rts
374262306a36Sopenharmony_ci
374362306a36Sopenharmony_ci
374462306a36Sopenharmony_ci#########################################################################
374562306a36Sopenharmony_ci# MONADIC TEMPLATE							#
374662306a36Sopenharmony_ci#########################################################################
374762306a36Sopenharmony_ci	global		_fgetexps_
374862306a36Sopenharmony_ci_fgetexps_:
374962306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
375062306a36Sopenharmony_ci
375162306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
375262306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
375362306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
375462306a36Sopenharmony_ci
375562306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
375662306a36Sopenharmony_ci
375762306a36Sopenharmony_ci#
375862306a36Sopenharmony_ci#	copy, convert, and tag input argument
375962306a36Sopenharmony_ci#
376062306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
376162306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
376262306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
376362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
376462306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
376562306a36Sopenharmony_ci	mov.b		%d0,%d1
376662306a36Sopenharmony_ci
376762306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
376862306a36Sopenharmony_ci
376962306a36Sopenharmony_ci	clr.l		%d0
377062306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
377162306a36Sopenharmony_ci
377262306a36Sopenharmony_ci	tst.b		%d1
377362306a36Sopenharmony_ci	bne.b		_L18_2s
377462306a36Sopenharmony_ci	bsr.l		sgetexp			# operand is a NORM
377562306a36Sopenharmony_ci	bra.b		_L18_6s
377662306a36Sopenharmony_ci_L18_2s:
377762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
377862306a36Sopenharmony_ci	bne.b		_L18_3s			# no
377962306a36Sopenharmony_ci	bsr.l		src_zero			# yes
378062306a36Sopenharmony_ci	bra.b		_L18_6s
378162306a36Sopenharmony_ci_L18_3s:
378262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
378362306a36Sopenharmony_ci	bne.b		_L18_4s			# no
378462306a36Sopenharmony_ci	bsr.l		t_operr			# yes
378562306a36Sopenharmony_ci	bra.b		_L18_6s
378662306a36Sopenharmony_ci_L18_4s:
378762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
378862306a36Sopenharmony_ci	bne.b		_L18_5s			# no
378962306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
379062306a36Sopenharmony_ci	bra.b		_L18_6s
379162306a36Sopenharmony_ci_L18_5s:
379262306a36Sopenharmony_ci	bsr.l		sgetexpd			# operand is a DENORM
379362306a36Sopenharmony_ci_L18_6s:
379462306a36Sopenharmony_ci
379562306a36Sopenharmony_ci#
379662306a36Sopenharmony_ci#	Result is now in FP0
379762306a36Sopenharmony_ci#
379862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
379962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
380062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
380162306a36Sopenharmony_ci	unlk		%a6
380262306a36Sopenharmony_ci	rts
380362306a36Sopenharmony_ci
380462306a36Sopenharmony_ci	global		_fgetexpd_
380562306a36Sopenharmony_ci_fgetexpd_:
380662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
380762306a36Sopenharmony_ci
380862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
380962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
381062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
381162306a36Sopenharmony_ci
381262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
381362306a36Sopenharmony_ci
381462306a36Sopenharmony_ci#
381562306a36Sopenharmony_ci#	copy, convert, and tag input argument
381662306a36Sopenharmony_ci#
381762306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
381862306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
381962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
382062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
382162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
382262306a36Sopenharmony_ci	mov.b		%d0,%d1
382362306a36Sopenharmony_ci
382462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
382562306a36Sopenharmony_ci
382662306a36Sopenharmony_ci	clr.l		%d0
382762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
382862306a36Sopenharmony_ci
382962306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
383062306a36Sopenharmony_ci	tst.b		%d1
383162306a36Sopenharmony_ci	bne.b		_L18_2d
383262306a36Sopenharmony_ci	bsr.l		sgetexp			# operand is a NORM
383362306a36Sopenharmony_ci	bra.b		_L18_6d
383462306a36Sopenharmony_ci_L18_2d:
383562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
383662306a36Sopenharmony_ci	bne.b		_L18_3d			# no
383762306a36Sopenharmony_ci	bsr.l		src_zero			# yes
383862306a36Sopenharmony_ci	bra.b		_L18_6d
383962306a36Sopenharmony_ci_L18_3d:
384062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
384162306a36Sopenharmony_ci	bne.b		_L18_4d			# no
384262306a36Sopenharmony_ci	bsr.l		t_operr			# yes
384362306a36Sopenharmony_ci	bra.b		_L18_6d
384462306a36Sopenharmony_ci_L18_4d:
384562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
384662306a36Sopenharmony_ci	bne.b		_L18_5d			# no
384762306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
384862306a36Sopenharmony_ci	bra.b		_L18_6d
384962306a36Sopenharmony_ci_L18_5d:
385062306a36Sopenharmony_ci	bsr.l		sgetexpd			# operand is a DENORM
385162306a36Sopenharmony_ci_L18_6d:
385262306a36Sopenharmony_ci
385362306a36Sopenharmony_ci#
385462306a36Sopenharmony_ci#	Result is now in FP0
385562306a36Sopenharmony_ci#
385662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
385762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
385862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
385962306a36Sopenharmony_ci	unlk		%a6
386062306a36Sopenharmony_ci	rts
386162306a36Sopenharmony_ci
386262306a36Sopenharmony_ci	global		_fgetexpx_
386362306a36Sopenharmony_ci_fgetexpx_:
386462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
386562306a36Sopenharmony_ci
386662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
386762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
386862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
386962306a36Sopenharmony_ci
387062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
387162306a36Sopenharmony_ci
387262306a36Sopenharmony_ci#
387362306a36Sopenharmony_ci#	copy, convert, and tag input argument
387462306a36Sopenharmony_ci#
387562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
387662306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
387762306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
387862306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
387962306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
388062306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
388162306a36Sopenharmony_ci	mov.b		%d0,%d1
388262306a36Sopenharmony_ci
388362306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
388462306a36Sopenharmony_ci
388562306a36Sopenharmony_ci	clr.l		%d0
388662306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
388762306a36Sopenharmony_ci
388862306a36Sopenharmony_ci	tst.b		%d1
388962306a36Sopenharmony_ci	bne.b		_L18_2x
389062306a36Sopenharmony_ci	bsr.l		sgetexp			# operand is a NORM
389162306a36Sopenharmony_ci	bra.b		_L18_6x
389262306a36Sopenharmony_ci_L18_2x:
389362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
389462306a36Sopenharmony_ci	bne.b		_L18_3x			# no
389562306a36Sopenharmony_ci	bsr.l		src_zero			# yes
389662306a36Sopenharmony_ci	bra.b		_L18_6x
389762306a36Sopenharmony_ci_L18_3x:
389862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
389962306a36Sopenharmony_ci	bne.b		_L18_4x			# no
390062306a36Sopenharmony_ci	bsr.l		t_operr			# yes
390162306a36Sopenharmony_ci	bra.b		_L18_6x
390262306a36Sopenharmony_ci_L18_4x:
390362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
390462306a36Sopenharmony_ci	bne.b		_L18_5x			# no
390562306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
390662306a36Sopenharmony_ci	bra.b		_L18_6x
390762306a36Sopenharmony_ci_L18_5x:
390862306a36Sopenharmony_ci	bsr.l		sgetexpd			# operand is a DENORM
390962306a36Sopenharmony_ci_L18_6x:
391062306a36Sopenharmony_ci
391162306a36Sopenharmony_ci#
391262306a36Sopenharmony_ci#	Result is now in FP0
391362306a36Sopenharmony_ci#
391462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
391562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
391662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
391762306a36Sopenharmony_ci	unlk		%a6
391862306a36Sopenharmony_ci	rts
391962306a36Sopenharmony_ci
392062306a36Sopenharmony_ci
392162306a36Sopenharmony_ci#########################################################################
392262306a36Sopenharmony_ci# MONADIC TEMPLATE							#
392362306a36Sopenharmony_ci#########################################################################
392462306a36Sopenharmony_ci	global		_fgetmans_
392562306a36Sopenharmony_ci_fgetmans_:
392662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
392762306a36Sopenharmony_ci
392862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
392962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
393062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
393162306a36Sopenharmony_ci
393262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
393362306a36Sopenharmony_ci
393462306a36Sopenharmony_ci#
393562306a36Sopenharmony_ci#	copy, convert, and tag input argument
393662306a36Sopenharmony_ci#
393762306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
393862306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
393962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
394062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
394162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
394262306a36Sopenharmony_ci	mov.b		%d0,%d1
394362306a36Sopenharmony_ci
394462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
394562306a36Sopenharmony_ci
394662306a36Sopenharmony_ci	clr.l		%d0
394762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
394862306a36Sopenharmony_ci
394962306a36Sopenharmony_ci	tst.b		%d1
395062306a36Sopenharmony_ci	bne.b		_L19_2s
395162306a36Sopenharmony_ci	bsr.l		sgetman			# operand is a NORM
395262306a36Sopenharmony_ci	bra.b		_L19_6s
395362306a36Sopenharmony_ci_L19_2s:
395462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
395562306a36Sopenharmony_ci	bne.b		_L19_3s			# no
395662306a36Sopenharmony_ci	bsr.l		src_zero			# yes
395762306a36Sopenharmony_ci	bra.b		_L19_6s
395862306a36Sopenharmony_ci_L19_3s:
395962306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
396062306a36Sopenharmony_ci	bne.b		_L19_4s			# no
396162306a36Sopenharmony_ci	bsr.l		t_operr			# yes
396262306a36Sopenharmony_ci	bra.b		_L19_6s
396362306a36Sopenharmony_ci_L19_4s:
396462306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
396562306a36Sopenharmony_ci	bne.b		_L19_5s			# no
396662306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
396762306a36Sopenharmony_ci	bra.b		_L19_6s
396862306a36Sopenharmony_ci_L19_5s:
396962306a36Sopenharmony_ci	bsr.l		sgetmand			# operand is a DENORM
397062306a36Sopenharmony_ci_L19_6s:
397162306a36Sopenharmony_ci
397262306a36Sopenharmony_ci#
397362306a36Sopenharmony_ci#	Result is now in FP0
397462306a36Sopenharmony_ci#
397562306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
397662306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
397762306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
397862306a36Sopenharmony_ci	unlk		%a6
397962306a36Sopenharmony_ci	rts
398062306a36Sopenharmony_ci
398162306a36Sopenharmony_ci	global		_fgetmand_
398262306a36Sopenharmony_ci_fgetmand_:
398362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
398462306a36Sopenharmony_ci
398562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
398662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
398762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
398862306a36Sopenharmony_ci
398962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
399062306a36Sopenharmony_ci
399162306a36Sopenharmony_ci#
399262306a36Sopenharmony_ci#	copy, convert, and tag input argument
399362306a36Sopenharmony_ci#
399462306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
399562306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
399662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
399762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
399862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
399962306a36Sopenharmony_ci	mov.b		%d0,%d1
400062306a36Sopenharmony_ci
400162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
400262306a36Sopenharmony_ci
400362306a36Sopenharmony_ci	clr.l		%d0
400462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
400562306a36Sopenharmony_ci
400662306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
400762306a36Sopenharmony_ci	tst.b		%d1
400862306a36Sopenharmony_ci	bne.b		_L19_2d
400962306a36Sopenharmony_ci	bsr.l		sgetman			# operand is a NORM
401062306a36Sopenharmony_ci	bra.b		_L19_6d
401162306a36Sopenharmony_ci_L19_2d:
401262306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
401362306a36Sopenharmony_ci	bne.b		_L19_3d			# no
401462306a36Sopenharmony_ci	bsr.l		src_zero			# yes
401562306a36Sopenharmony_ci	bra.b		_L19_6d
401662306a36Sopenharmony_ci_L19_3d:
401762306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
401862306a36Sopenharmony_ci	bne.b		_L19_4d			# no
401962306a36Sopenharmony_ci	bsr.l		t_operr			# yes
402062306a36Sopenharmony_ci	bra.b		_L19_6d
402162306a36Sopenharmony_ci_L19_4d:
402262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
402362306a36Sopenharmony_ci	bne.b		_L19_5d			# no
402462306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
402562306a36Sopenharmony_ci	bra.b		_L19_6d
402662306a36Sopenharmony_ci_L19_5d:
402762306a36Sopenharmony_ci	bsr.l		sgetmand			# operand is a DENORM
402862306a36Sopenharmony_ci_L19_6d:
402962306a36Sopenharmony_ci
403062306a36Sopenharmony_ci#
403162306a36Sopenharmony_ci#	Result is now in FP0
403262306a36Sopenharmony_ci#
403362306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
403462306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
403562306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
403662306a36Sopenharmony_ci	unlk		%a6
403762306a36Sopenharmony_ci	rts
403862306a36Sopenharmony_ci
403962306a36Sopenharmony_ci	global		_fgetmanx_
404062306a36Sopenharmony_ci_fgetmanx_:
404162306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
404262306a36Sopenharmony_ci
404362306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
404462306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
404562306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
404662306a36Sopenharmony_ci
404762306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
404862306a36Sopenharmony_ci
404962306a36Sopenharmony_ci#
405062306a36Sopenharmony_ci#	copy, convert, and tag input argument
405162306a36Sopenharmony_ci#
405262306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
405362306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
405462306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
405562306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
405662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
405762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
405862306a36Sopenharmony_ci	mov.b		%d0,%d1
405962306a36Sopenharmony_ci
406062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
406162306a36Sopenharmony_ci
406262306a36Sopenharmony_ci	clr.l		%d0
406362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
406462306a36Sopenharmony_ci
406562306a36Sopenharmony_ci	tst.b		%d1
406662306a36Sopenharmony_ci	bne.b		_L19_2x
406762306a36Sopenharmony_ci	bsr.l		sgetman			# operand is a NORM
406862306a36Sopenharmony_ci	bra.b		_L19_6x
406962306a36Sopenharmony_ci_L19_2x:
407062306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
407162306a36Sopenharmony_ci	bne.b		_L19_3x			# no
407262306a36Sopenharmony_ci	bsr.l		src_zero			# yes
407362306a36Sopenharmony_ci	bra.b		_L19_6x
407462306a36Sopenharmony_ci_L19_3x:
407562306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
407662306a36Sopenharmony_ci	bne.b		_L19_4x			# no
407762306a36Sopenharmony_ci	bsr.l		t_operr			# yes
407862306a36Sopenharmony_ci	bra.b		_L19_6x
407962306a36Sopenharmony_ci_L19_4x:
408062306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
408162306a36Sopenharmony_ci	bne.b		_L19_5x			# no
408262306a36Sopenharmony_ci	bsr.l		src_qnan			# yes
408362306a36Sopenharmony_ci	bra.b		_L19_6x
408462306a36Sopenharmony_ci_L19_5x:
408562306a36Sopenharmony_ci	bsr.l		sgetmand			# operand is a DENORM
408662306a36Sopenharmony_ci_L19_6x:
408762306a36Sopenharmony_ci
408862306a36Sopenharmony_ci#
408962306a36Sopenharmony_ci#	Result is now in FP0
409062306a36Sopenharmony_ci#
409162306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
409262306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
409362306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
409462306a36Sopenharmony_ci	unlk		%a6
409562306a36Sopenharmony_ci	rts
409662306a36Sopenharmony_ci
409762306a36Sopenharmony_ci
409862306a36Sopenharmony_ci#########################################################################
409962306a36Sopenharmony_ci# MONADIC TEMPLATE							#
410062306a36Sopenharmony_ci#########################################################################
410162306a36Sopenharmony_ci	global		_fsincoss_
410262306a36Sopenharmony_ci_fsincoss_:
410362306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
410462306a36Sopenharmony_ci
410562306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
410662306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
410762306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
410862306a36Sopenharmony_ci
410962306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
411062306a36Sopenharmony_ci
411162306a36Sopenharmony_ci#
411262306a36Sopenharmony_ci#	copy, convert, and tag input argument
411362306a36Sopenharmony_ci#
411462306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl input
411562306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
411662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
411762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
411862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
411962306a36Sopenharmony_ci	mov.b		%d0,%d1
412062306a36Sopenharmony_ci
412162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
412262306a36Sopenharmony_ci
412362306a36Sopenharmony_ci	clr.l		%d0
412462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
412562306a36Sopenharmony_ci
412662306a36Sopenharmony_ci	tst.b		%d1
412762306a36Sopenharmony_ci	bne.b		_L20_2s
412862306a36Sopenharmony_ci	bsr.l		ssincos			# operand is a NORM
412962306a36Sopenharmony_ci	bra.b		_L20_6s
413062306a36Sopenharmony_ci_L20_2s:
413162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
413262306a36Sopenharmony_ci	bne.b		_L20_3s			# no
413362306a36Sopenharmony_ci	bsr.l		ssincosz			# yes
413462306a36Sopenharmony_ci	bra.b		_L20_6s
413562306a36Sopenharmony_ci_L20_3s:
413662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
413762306a36Sopenharmony_ci	bne.b		_L20_4s			# no
413862306a36Sopenharmony_ci	bsr.l		ssincosi			# yes
413962306a36Sopenharmony_ci	bra.b		_L20_6s
414062306a36Sopenharmony_ci_L20_4s:
414162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
414262306a36Sopenharmony_ci	bne.b		_L20_5s			# no
414362306a36Sopenharmony_ci	bsr.l		ssincosqnan			# yes
414462306a36Sopenharmony_ci	bra.b		_L20_6s
414562306a36Sopenharmony_ci_L20_5s:
414662306a36Sopenharmony_ci	bsr.l		ssincosd			# operand is a DENORM
414762306a36Sopenharmony_ci_L20_6s:
414862306a36Sopenharmony_ci
414962306a36Sopenharmony_ci#
415062306a36Sopenharmony_ci#	Result is now in FP0
415162306a36Sopenharmony_ci#
415262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
415362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
415462306a36Sopenharmony_ci	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
415562306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
415662306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
415762306a36Sopenharmony_ci	unlk		%a6
415862306a36Sopenharmony_ci	rts
415962306a36Sopenharmony_ci
416062306a36Sopenharmony_ci	global		_fsincosd_
416162306a36Sopenharmony_ci_fsincosd_:
416262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
416362306a36Sopenharmony_ci
416462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
416562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
416662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
416762306a36Sopenharmony_ci
416862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
416962306a36Sopenharmony_ci
417062306a36Sopenharmony_ci#
417162306a36Sopenharmony_ci#	copy, convert, and tag input argument
417262306a36Sopenharmony_ci#
417362306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl input
417462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
417562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
417662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
417762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
417862306a36Sopenharmony_ci	mov.b		%d0,%d1
417962306a36Sopenharmony_ci
418062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
418162306a36Sopenharmony_ci
418262306a36Sopenharmony_ci	clr.l		%d0
418362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
418462306a36Sopenharmony_ci
418562306a36Sopenharmony_ci	mov.b		%d1,STAG(%a6)
418662306a36Sopenharmony_ci	tst.b		%d1
418762306a36Sopenharmony_ci	bne.b		_L20_2d
418862306a36Sopenharmony_ci	bsr.l		ssincos			# operand is a NORM
418962306a36Sopenharmony_ci	bra.b		_L20_6d
419062306a36Sopenharmony_ci_L20_2d:
419162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
419262306a36Sopenharmony_ci	bne.b		_L20_3d			# no
419362306a36Sopenharmony_ci	bsr.l		ssincosz			# yes
419462306a36Sopenharmony_ci	bra.b		_L20_6d
419562306a36Sopenharmony_ci_L20_3d:
419662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
419762306a36Sopenharmony_ci	bne.b		_L20_4d			# no
419862306a36Sopenharmony_ci	bsr.l		ssincosi			# yes
419962306a36Sopenharmony_ci	bra.b		_L20_6d
420062306a36Sopenharmony_ci_L20_4d:
420162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
420262306a36Sopenharmony_ci	bne.b		_L20_5d			# no
420362306a36Sopenharmony_ci	bsr.l		ssincosqnan			# yes
420462306a36Sopenharmony_ci	bra.b		_L20_6d
420562306a36Sopenharmony_ci_L20_5d:
420662306a36Sopenharmony_ci	bsr.l		ssincosd			# operand is a DENORM
420762306a36Sopenharmony_ci_L20_6d:
420862306a36Sopenharmony_ci
420962306a36Sopenharmony_ci#
421062306a36Sopenharmony_ci#	Result is now in FP0
421162306a36Sopenharmony_ci#
421262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
421362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
421462306a36Sopenharmony_ci	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
421562306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
421662306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
421762306a36Sopenharmony_ci	unlk		%a6
421862306a36Sopenharmony_ci	rts
421962306a36Sopenharmony_ci
422062306a36Sopenharmony_ci	global		_fsincosx_
422162306a36Sopenharmony_ci_fsincosx_:
422262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
422362306a36Sopenharmony_ci
422462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
422562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
422662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
422762306a36Sopenharmony_ci
422862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
422962306a36Sopenharmony_ci
423062306a36Sopenharmony_ci#
423162306a36Sopenharmony_ci#	copy, convert, and tag input argument
423262306a36Sopenharmony_ci#
423362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
423462306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
423562306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
423662306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
423762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
423862306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
423962306a36Sopenharmony_ci	mov.b		%d0,%d1
424062306a36Sopenharmony_ci
424162306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
424262306a36Sopenharmony_ci
424362306a36Sopenharmony_ci	clr.l		%d0
424462306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
424562306a36Sopenharmony_ci
424662306a36Sopenharmony_ci	tst.b		%d1
424762306a36Sopenharmony_ci	bne.b		_L20_2x
424862306a36Sopenharmony_ci	bsr.l		ssincos			# operand is a NORM
424962306a36Sopenharmony_ci	bra.b		_L20_6x
425062306a36Sopenharmony_ci_L20_2x:
425162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
425262306a36Sopenharmony_ci	bne.b		_L20_3x			# no
425362306a36Sopenharmony_ci	bsr.l		ssincosz			# yes
425462306a36Sopenharmony_ci	bra.b		_L20_6x
425562306a36Sopenharmony_ci_L20_3x:
425662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
425762306a36Sopenharmony_ci	bne.b		_L20_4x			# no
425862306a36Sopenharmony_ci	bsr.l		ssincosi			# yes
425962306a36Sopenharmony_ci	bra.b		_L20_6x
426062306a36Sopenharmony_ci_L20_4x:
426162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
426262306a36Sopenharmony_ci	bne.b		_L20_5x			# no
426362306a36Sopenharmony_ci	bsr.l		ssincosqnan			# yes
426462306a36Sopenharmony_ci	bra.b		_L20_6x
426562306a36Sopenharmony_ci_L20_5x:
426662306a36Sopenharmony_ci	bsr.l		ssincosd			# operand is a DENORM
426762306a36Sopenharmony_ci_L20_6x:
426862306a36Sopenharmony_ci
426962306a36Sopenharmony_ci#
427062306a36Sopenharmony_ci#	Result is now in FP0
427162306a36Sopenharmony_ci#
427262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
427362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
427462306a36Sopenharmony_ci	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
427562306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
427662306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
427762306a36Sopenharmony_ci	unlk		%a6
427862306a36Sopenharmony_ci	rts
427962306a36Sopenharmony_ci
428062306a36Sopenharmony_ci
428162306a36Sopenharmony_ci#########################################################################
428262306a36Sopenharmony_ci# DYADIC TEMPLATE							#
428362306a36Sopenharmony_ci#########################################################################
428462306a36Sopenharmony_ci	global		_frems_
428562306a36Sopenharmony_ci_frems_:
428662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
428762306a36Sopenharmony_ci
428862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
428962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
429062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
429162306a36Sopenharmony_ci
429262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
429362306a36Sopenharmony_ci
429462306a36Sopenharmony_ci#
429562306a36Sopenharmony_ci#	copy, convert, and tag input argument
429662306a36Sopenharmony_ci#
429762306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl dst
429862306a36Sopenharmony_ci	fmov.x		%fp0,FP_DST(%a6)
429962306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
430062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
430162306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
430262306a36Sopenharmony_ci
430362306a36Sopenharmony_ci	fmov.s		0xc(%a6),%fp0		# load sgl src
430462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
430562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
430662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
430762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
430862306a36Sopenharmony_ci	mov.l		%d0,%d1
430962306a36Sopenharmony_ci
431062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
431162306a36Sopenharmony_ci
431262306a36Sopenharmony_ci	clr.l		%d0
431362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
431462306a36Sopenharmony_ci
431562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
431662306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
431762306a36Sopenharmony_ci
431862306a36Sopenharmony_ci	tst.b		%d1
431962306a36Sopenharmony_ci	bne.b		_L21_2s
432062306a36Sopenharmony_ci	bsr.l		srem_snorm			# operand is a NORM
432162306a36Sopenharmony_ci	bra.b		_L21_6s
432262306a36Sopenharmony_ci_L21_2s:
432362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
432462306a36Sopenharmony_ci	bne.b		_L21_3s			# no
432562306a36Sopenharmony_ci	bsr.l		srem_szero			# yes
432662306a36Sopenharmony_ci	bra.b		_L21_6s
432762306a36Sopenharmony_ci_L21_3s:
432862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
432962306a36Sopenharmony_ci	bne.b		_L21_4s			# no
433062306a36Sopenharmony_ci	bsr.l		srem_sinf			# yes
433162306a36Sopenharmony_ci	bra.b		_L21_6s
433262306a36Sopenharmony_ci_L21_4s:
433362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
433462306a36Sopenharmony_ci	bne.b		_L21_5s			# no
433562306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
433662306a36Sopenharmony_ci	bra.b		_L21_6s
433762306a36Sopenharmony_ci_L21_5s:
433862306a36Sopenharmony_ci	bsr.l		srem_sdnrm			# operand is a DENORM
433962306a36Sopenharmony_ci_L21_6s:
434062306a36Sopenharmony_ci
434162306a36Sopenharmony_ci#
434262306a36Sopenharmony_ci#	Result is now in FP0
434362306a36Sopenharmony_ci#
434462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
434562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
434662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
434762306a36Sopenharmony_ci	unlk		%a6
434862306a36Sopenharmony_ci	rts
434962306a36Sopenharmony_ci
435062306a36Sopenharmony_ci	global		_fremd_
435162306a36Sopenharmony_ci_fremd_:
435262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
435362306a36Sopenharmony_ci
435462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
435562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
435662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
435762306a36Sopenharmony_ci
435862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
435962306a36Sopenharmony_ci
436062306a36Sopenharmony_ci#
436162306a36Sopenharmony_ci#	copy, convert, and tag input argument
436262306a36Sopenharmony_ci#
436362306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl dst
436462306a36Sopenharmony_ci	fmov.x		%fp0,FP_DST(%a6)
436562306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
436662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
436762306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
436862306a36Sopenharmony_ci
436962306a36Sopenharmony_ci	fmov.d		0x10(%a6),%fp0		# load dbl src
437062306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
437162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
437262306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
437362306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
437462306a36Sopenharmony_ci	mov.l		%d0,%d1
437562306a36Sopenharmony_ci
437662306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
437762306a36Sopenharmony_ci
437862306a36Sopenharmony_ci	clr.l		%d0
437962306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
438062306a36Sopenharmony_ci
438162306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
438262306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
438362306a36Sopenharmony_ci
438462306a36Sopenharmony_ci	tst.b		%d1
438562306a36Sopenharmony_ci	bne.b		_L21_2d
438662306a36Sopenharmony_ci	bsr.l		srem_snorm			# operand is a NORM
438762306a36Sopenharmony_ci	bra.b		_L21_6d
438862306a36Sopenharmony_ci_L21_2d:
438962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
439062306a36Sopenharmony_ci	bne.b		_L21_3d			# no
439162306a36Sopenharmony_ci	bsr.l		srem_szero			# yes
439262306a36Sopenharmony_ci	bra.b		_L21_6d
439362306a36Sopenharmony_ci_L21_3d:
439462306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
439562306a36Sopenharmony_ci	bne.b		_L21_4d			# no
439662306a36Sopenharmony_ci	bsr.l		srem_sinf			# yes
439762306a36Sopenharmony_ci	bra.b		_L21_6d
439862306a36Sopenharmony_ci_L21_4d:
439962306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
440062306a36Sopenharmony_ci	bne.b		_L21_5d			# no
440162306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
440262306a36Sopenharmony_ci	bra.b		_L21_6d
440362306a36Sopenharmony_ci_L21_5d:
440462306a36Sopenharmony_ci	bsr.l		srem_sdnrm			# operand is a DENORM
440562306a36Sopenharmony_ci_L21_6d:
440662306a36Sopenharmony_ci
440762306a36Sopenharmony_ci#
440862306a36Sopenharmony_ci#	Result is now in FP0
440962306a36Sopenharmony_ci#
441062306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
441162306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
441262306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
441362306a36Sopenharmony_ci	unlk		%a6
441462306a36Sopenharmony_ci	rts
441562306a36Sopenharmony_ci
441662306a36Sopenharmony_ci	global		_fremx_
441762306a36Sopenharmony_ci_fremx_:
441862306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
441962306a36Sopenharmony_ci
442062306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
442162306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
442262306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
442362306a36Sopenharmony_ci
442462306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
442562306a36Sopenharmony_ci
442662306a36Sopenharmony_ci#
442762306a36Sopenharmony_ci#	copy, convert, and tag input argument
442862306a36Sopenharmony_ci#
442962306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
443062306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
443162306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
443262306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
443362306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
443462306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
443562306a36Sopenharmony_ci
443662306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
443762306a36Sopenharmony_ci	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
443862306a36Sopenharmony_ci	mov.l		0x14+0x4(%a6),0x4(%a0)
443962306a36Sopenharmony_ci	mov.l		0x14+0x8(%a6),0x8(%a0)
444062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
444162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
444262306a36Sopenharmony_ci	mov.l		%d0,%d1
444362306a36Sopenharmony_ci
444462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
444562306a36Sopenharmony_ci
444662306a36Sopenharmony_ci	clr.l		%d0
444762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
444862306a36Sopenharmony_ci
444962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
445062306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
445162306a36Sopenharmony_ci
445262306a36Sopenharmony_ci	tst.b		%d1
445362306a36Sopenharmony_ci	bne.b		_L21_2x
445462306a36Sopenharmony_ci	bsr.l		srem_snorm			# operand is a NORM
445562306a36Sopenharmony_ci	bra.b		_L21_6x
445662306a36Sopenharmony_ci_L21_2x:
445762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
445862306a36Sopenharmony_ci	bne.b		_L21_3x			# no
445962306a36Sopenharmony_ci	bsr.l		srem_szero			# yes
446062306a36Sopenharmony_ci	bra.b		_L21_6x
446162306a36Sopenharmony_ci_L21_3x:
446262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
446362306a36Sopenharmony_ci	bne.b		_L21_4x			# no
446462306a36Sopenharmony_ci	bsr.l		srem_sinf			# yes
446562306a36Sopenharmony_ci	bra.b		_L21_6x
446662306a36Sopenharmony_ci_L21_4x:
446762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
446862306a36Sopenharmony_ci	bne.b		_L21_5x			# no
446962306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
447062306a36Sopenharmony_ci	bra.b		_L21_6x
447162306a36Sopenharmony_ci_L21_5x:
447262306a36Sopenharmony_ci	bsr.l		srem_sdnrm			# operand is a DENORM
447362306a36Sopenharmony_ci_L21_6x:
447462306a36Sopenharmony_ci
447562306a36Sopenharmony_ci#
447662306a36Sopenharmony_ci#	Result is now in FP0
447762306a36Sopenharmony_ci#
447862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
447962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
448062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
448162306a36Sopenharmony_ci	unlk		%a6
448262306a36Sopenharmony_ci	rts
448362306a36Sopenharmony_ci
448462306a36Sopenharmony_ci
448562306a36Sopenharmony_ci#########################################################################
448662306a36Sopenharmony_ci# DYADIC TEMPLATE							#
448762306a36Sopenharmony_ci#########################################################################
448862306a36Sopenharmony_ci	global		_fmods_
448962306a36Sopenharmony_ci_fmods_:
449062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
449162306a36Sopenharmony_ci
449262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
449362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
449462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
449562306a36Sopenharmony_ci
449662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
449762306a36Sopenharmony_ci
449862306a36Sopenharmony_ci#
449962306a36Sopenharmony_ci#	copy, convert, and tag input argument
450062306a36Sopenharmony_ci#
450162306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl dst
450262306a36Sopenharmony_ci	fmov.x		%fp0,FP_DST(%a6)
450362306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
450462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
450562306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
450662306a36Sopenharmony_ci
450762306a36Sopenharmony_ci	fmov.s		0xc(%a6),%fp0		# load sgl src
450862306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
450962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
451062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
451162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
451262306a36Sopenharmony_ci	mov.l		%d0,%d1
451362306a36Sopenharmony_ci
451462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
451562306a36Sopenharmony_ci
451662306a36Sopenharmony_ci	clr.l		%d0
451762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
451862306a36Sopenharmony_ci
451962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
452062306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
452162306a36Sopenharmony_ci
452262306a36Sopenharmony_ci	tst.b		%d1
452362306a36Sopenharmony_ci	bne.b		_L22_2s
452462306a36Sopenharmony_ci	bsr.l		smod_snorm			# operand is a NORM
452562306a36Sopenharmony_ci	bra.b		_L22_6s
452662306a36Sopenharmony_ci_L22_2s:
452762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
452862306a36Sopenharmony_ci	bne.b		_L22_3s			# no
452962306a36Sopenharmony_ci	bsr.l		smod_szero			# yes
453062306a36Sopenharmony_ci	bra.b		_L22_6s
453162306a36Sopenharmony_ci_L22_3s:
453262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
453362306a36Sopenharmony_ci	bne.b		_L22_4s			# no
453462306a36Sopenharmony_ci	bsr.l		smod_sinf			# yes
453562306a36Sopenharmony_ci	bra.b		_L22_6s
453662306a36Sopenharmony_ci_L22_4s:
453762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
453862306a36Sopenharmony_ci	bne.b		_L22_5s			# no
453962306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
454062306a36Sopenharmony_ci	bra.b		_L22_6s
454162306a36Sopenharmony_ci_L22_5s:
454262306a36Sopenharmony_ci	bsr.l		smod_sdnrm			# operand is a DENORM
454362306a36Sopenharmony_ci_L22_6s:
454462306a36Sopenharmony_ci
454562306a36Sopenharmony_ci#
454662306a36Sopenharmony_ci#	Result is now in FP0
454762306a36Sopenharmony_ci#
454862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
454962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
455062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
455162306a36Sopenharmony_ci	unlk		%a6
455262306a36Sopenharmony_ci	rts
455362306a36Sopenharmony_ci
455462306a36Sopenharmony_ci	global		_fmodd_
455562306a36Sopenharmony_ci_fmodd_:
455662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
455762306a36Sopenharmony_ci
455862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
455962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
456062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
456162306a36Sopenharmony_ci
456262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
456362306a36Sopenharmony_ci
456462306a36Sopenharmony_ci#
456562306a36Sopenharmony_ci#	copy, convert, and tag input argument
456662306a36Sopenharmony_ci#
456762306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl dst
456862306a36Sopenharmony_ci	fmov.x		%fp0,FP_DST(%a6)
456962306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
457062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
457162306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
457262306a36Sopenharmony_ci
457362306a36Sopenharmony_ci	fmov.d		0x10(%a6),%fp0		# load dbl src
457462306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
457562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
457662306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
457762306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
457862306a36Sopenharmony_ci	mov.l		%d0,%d1
457962306a36Sopenharmony_ci
458062306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
458162306a36Sopenharmony_ci
458262306a36Sopenharmony_ci	clr.l		%d0
458362306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
458462306a36Sopenharmony_ci
458562306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
458662306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
458762306a36Sopenharmony_ci
458862306a36Sopenharmony_ci	tst.b		%d1
458962306a36Sopenharmony_ci	bne.b		_L22_2d
459062306a36Sopenharmony_ci	bsr.l		smod_snorm			# operand is a NORM
459162306a36Sopenharmony_ci	bra.b		_L22_6d
459262306a36Sopenharmony_ci_L22_2d:
459362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
459462306a36Sopenharmony_ci	bne.b		_L22_3d			# no
459562306a36Sopenharmony_ci	bsr.l		smod_szero			# yes
459662306a36Sopenharmony_ci	bra.b		_L22_6d
459762306a36Sopenharmony_ci_L22_3d:
459862306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
459962306a36Sopenharmony_ci	bne.b		_L22_4d			# no
460062306a36Sopenharmony_ci	bsr.l		smod_sinf			# yes
460162306a36Sopenharmony_ci	bra.b		_L22_6d
460262306a36Sopenharmony_ci_L22_4d:
460362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
460462306a36Sopenharmony_ci	bne.b		_L22_5d			# no
460562306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
460662306a36Sopenharmony_ci	bra.b		_L22_6d
460762306a36Sopenharmony_ci_L22_5d:
460862306a36Sopenharmony_ci	bsr.l		smod_sdnrm			# operand is a DENORM
460962306a36Sopenharmony_ci_L22_6d:
461062306a36Sopenharmony_ci
461162306a36Sopenharmony_ci#
461262306a36Sopenharmony_ci#	Result is now in FP0
461362306a36Sopenharmony_ci#
461462306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
461562306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
461662306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
461762306a36Sopenharmony_ci	unlk		%a6
461862306a36Sopenharmony_ci	rts
461962306a36Sopenharmony_ci
462062306a36Sopenharmony_ci	global		_fmodx_
462162306a36Sopenharmony_ci_fmodx_:
462262306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
462362306a36Sopenharmony_ci
462462306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
462562306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
462662306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
462762306a36Sopenharmony_ci
462862306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
462962306a36Sopenharmony_ci
463062306a36Sopenharmony_ci#
463162306a36Sopenharmony_ci#	copy, convert, and tag input argument
463262306a36Sopenharmony_ci#
463362306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
463462306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
463562306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
463662306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
463762306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
463862306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
463962306a36Sopenharmony_ci
464062306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
464162306a36Sopenharmony_ci	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
464262306a36Sopenharmony_ci	mov.l		0x14+0x4(%a6),0x4(%a0)
464362306a36Sopenharmony_ci	mov.l		0x14+0x8(%a6),0x8(%a0)
464462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
464562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
464662306a36Sopenharmony_ci	mov.l		%d0,%d1
464762306a36Sopenharmony_ci
464862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
464962306a36Sopenharmony_ci
465062306a36Sopenharmony_ci	clr.l		%d0
465162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
465262306a36Sopenharmony_ci
465362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
465462306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
465562306a36Sopenharmony_ci
465662306a36Sopenharmony_ci	tst.b		%d1
465762306a36Sopenharmony_ci	bne.b		_L22_2x
465862306a36Sopenharmony_ci	bsr.l		smod_snorm			# operand is a NORM
465962306a36Sopenharmony_ci	bra.b		_L22_6x
466062306a36Sopenharmony_ci_L22_2x:
466162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
466262306a36Sopenharmony_ci	bne.b		_L22_3x			# no
466362306a36Sopenharmony_ci	bsr.l		smod_szero			# yes
466462306a36Sopenharmony_ci	bra.b		_L22_6x
466562306a36Sopenharmony_ci_L22_3x:
466662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
466762306a36Sopenharmony_ci	bne.b		_L22_4x			# no
466862306a36Sopenharmony_ci	bsr.l		smod_sinf			# yes
466962306a36Sopenharmony_ci	bra.b		_L22_6x
467062306a36Sopenharmony_ci_L22_4x:
467162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
467262306a36Sopenharmony_ci	bne.b		_L22_5x			# no
467362306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
467462306a36Sopenharmony_ci	bra.b		_L22_6x
467562306a36Sopenharmony_ci_L22_5x:
467662306a36Sopenharmony_ci	bsr.l		smod_sdnrm			# operand is a DENORM
467762306a36Sopenharmony_ci_L22_6x:
467862306a36Sopenharmony_ci
467962306a36Sopenharmony_ci#
468062306a36Sopenharmony_ci#	Result is now in FP0
468162306a36Sopenharmony_ci#
468262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
468362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
468462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
468562306a36Sopenharmony_ci	unlk		%a6
468662306a36Sopenharmony_ci	rts
468762306a36Sopenharmony_ci
468862306a36Sopenharmony_ci
468962306a36Sopenharmony_ci#########################################################################
469062306a36Sopenharmony_ci# DYADIC TEMPLATE							#
469162306a36Sopenharmony_ci#########################################################################
469262306a36Sopenharmony_ci	global		_fscales_
469362306a36Sopenharmony_ci_fscales_:
469462306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
469562306a36Sopenharmony_ci
469662306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
469762306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
469862306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
469962306a36Sopenharmony_ci
470062306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
470162306a36Sopenharmony_ci
470262306a36Sopenharmony_ci#
470362306a36Sopenharmony_ci#	copy, convert, and tag input argument
470462306a36Sopenharmony_ci#
470562306a36Sopenharmony_ci	fmov.s		0x8(%a6),%fp0		# load sgl dst
470662306a36Sopenharmony_ci	fmov.x		%fp0,FP_DST(%a6)
470762306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
470862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
470962306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
471062306a36Sopenharmony_ci
471162306a36Sopenharmony_ci	fmov.s		0xc(%a6),%fp0		# load sgl src
471262306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
471362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
471462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
471562306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
471662306a36Sopenharmony_ci	mov.l		%d0,%d1
471762306a36Sopenharmony_ci
471862306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
471962306a36Sopenharmony_ci
472062306a36Sopenharmony_ci	clr.l		%d0
472162306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
472262306a36Sopenharmony_ci
472362306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
472462306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
472562306a36Sopenharmony_ci
472662306a36Sopenharmony_ci	tst.b		%d1
472762306a36Sopenharmony_ci	bne.b		_L23_2s
472862306a36Sopenharmony_ci	bsr.l		sscale_snorm			# operand is a NORM
472962306a36Sopenharmony_ci	bra.b		_L23_6s
473062306a36Sopenharmony_ci_L23_2s:
473162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
473262306a36Sopenharmony_ci	bne.b		_L23_3s			# no
473362306a36Sopenharmony_ci	bsr.l		sscale_szero			# yes
473462306a36Sopenharmony_ci	bra.b		_L23_6s
473562306a36Sopenharmony_ci_L23_3s:
473662306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
473762306a36Sopenharmony_ci	bne.b		_L23_4s			# no
473862306a36Sopenharmony_ci	bsr.l		sscale_sinf			# yes
473962306a36Sopenharmony_ci	bra.b		_L23_6s
474062306a36Sopenharmony_ci_L23_4s:
474162306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
474262306a36Sopenharmony_ci	bne.b		_L23_5s			# no
474362306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
474462306a36Sopenharmony_ci	bra.b		_L23_6s
474562306a36Sopenharmony_ci_L23_5s:
474662306a36Sopenharmony_ci	bsr.l		sscale_sdnrm			# operand is a DENORM
474762306a36Sopenharmony_ci_L23_6s:
474862306a36Sopenharmony_ci
474962306a36Sopenharmony_ci#
475062306a36Sopenharmony_ci#	Result is now in FP0
475162306a36Sopenharmony_ci#
475262306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
475362306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
475462306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
475562306a36Sopenharmony_ci	unlk		%a6
475662306a36Sopenharmony_ci	rts
475762306a36Sopenharmony_ci
475862306a36Sopenharmony_ci	global		_fscaled_
475962306a36Sopenharmony_ci_fscaled_:
476062306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
476162306a36Sopenharmony_ci
476262306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
476362306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
476462306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
476562306a36Sopenharmony_ci
476662306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
476762306a36Sopenharmony_ci
476862306a36Sopenharmony_ci#
476962306a36Sopenharmony_ci#	copy, convert, and tag input argument
477062306a36Sopenharmony_ci#
477162306a36Sopenharmony_ci	fmov.d		0x8(%a6),%fp0		# load dbl dst
477262306a36Sopenharmony_ci	fmov.x		%fp0,FP_DST(%a6)
477362306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
477462306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
477562306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
477662306a36Sopenharmony_ci
477762306a36Sopenharmony_ci	fmov.d		0x10(%a6),%fp0		# load dbl src
477862306a36Sopenharmony_ci	fmov.x		%fp0,FP_SRC(%a6)
477962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
478062306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
478162306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
478262306a36Sopenharmony_ci	mov.l		%d0,%d1
478362306a36Sopenharmony_ci
478462306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
478562306a36Sopenharmony_ci
478662306a36Sopenharmony_ci	clr.l		%d0
478762306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
478862306a36Sopenharmony_ci
478962306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
479062306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
479162306a36Sopenharmony_ci
479262306a36Sopenharmony_ci	tst.b		%d1
479362306a36Sopenharmony_ci	bne.b		_L23_2d
479462306a36Sopenharmony_ci	bsr.l		sscale_snorm			# operand is a NORM
479562306a36Sopenharmony_ci	bra.b		_L23_6d
479662306a36Sopenharmony_ci_L23_2d:
479762306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
479862306a36Sopenharmony_ci	bne.b		_L23_3d			# no
479962306a36Sopenharmony_ci	bsr.l		sscale_szero			# yes
480062306a36Sopenharmony_ci	bra.b		_L23_6d
480162306a36Sopenharmony_ci_L23_3d:
480262306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
480362306a36Sopenharmony_ci	bne.b		_L23_4d			# no
480462306a36Sopenharmony_ci	bsr.l		sscale_sinf			# yes
480562306a36Sopenharmony_ci	bra.b		_L23_6d
480662306a36Sopenharmony_ci_L23_4d:
480762306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
480862306a36Sopenharmony_ci	bne.b		_L23_5d			# no
480962306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
481062306a36Sopenharmony_ci	bra.b		_L23_6d
481162306a36Sopenharmony_ci_L23_5d:
481262306a36Sopenharmony_ci	bsr.l		sscale_sdnrm			# operand is a DENORM
481362306a36Sopenharmony_ci_L23_6d:
481462306a36Sopenharmony_ci
481562306a36Sopenharmony_ci#
481662306a36Sopenharmony_ci#	Result is now in FP0
481762306a36Sopenharmony_ci#
481862306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
481962306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
482062306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
482162306a36Sopenharmony_ci	unlk		%a6
482262306a36Sopenharmony_ci	rts
482362306a36Sopenharmony_ci
482462306a36Sopenharmony_ci	global		_fscalex_
482562306a36Sopenharmony_ci_fscalex_:
482662306a36Sopenharmony_ci	link		%a6,&-LOCAL_SIZE
482762306a36Sopenharmony_ci
482862306a36Sopenharmony_ci	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
482962306a36Sopenharmony_ci	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
483062306a36Sopenharmony_ci	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
483162306a36Sopenharmony_ci
483262306a36Sopenharmony_ci	fmov.l		&0x0,%fpcr		# zero FPCR
483362306a36Sopenharmony_ci
483462306a36Sopenharmony_ci#
483562306a36Sopenharmony_ci#	copy, convert, and tag input argument
483662306a36Sopenharmony_ci#
483762306a36Sopenharmony_ci	lea		FP_DST(%a6),%a0
483862306a36Sopenharmony_ci	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
483962306a36Sopenharmony_ci	mov.l		0x8+0x4(%a6),0x4(%a0)
484062306a36Sopenharmony_ci	mov.l		0x8+0x8(%a6),0x8(%a0)
484162306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
484262306a36Sopenharmony_ci	mov.b		%d0,DTAG(%a6)
484362306a36Sopenharmony_ci
484462306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0
484562306a36Sopenharmony_ci	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
484662306a36Sopenharmony_ci	mov.l		0x14+0x4(%a6),0x4(%a0)
484762306a36Sopenharmony_ci	mov.l		0x14+0x8(%a6),0x8(%a0)
484862306a36Sopenharmony_ci	bsr.l		tag			# fetch operand type
484962306a36Sopenharmony_ci	mov.b		%d0,STAG(%a6)
485062306a36Sopenharmony_ci	mov.l		%d0,%d1
485162306a36Sopenharmony_ci
485262306a36Sopenharmony_ci	andi.l		&0x00ff00ff,USER_FPSR(%a6)
485362306a36Sopenharmony_ci
485462306a36Sopenharmony_ci	clr.l		%d0
485562306a36Sopenharmony_ci	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
485662306a36Sopenharmony_ci
485762306a36Sopenharmony_ci	lea		FP_SRC(%a6),%a0		# pass ptr to src
485862306a36Sopenharmony_ci	lea		FP_DST(%a6),%a1		# pass ptr to dst
485962306a36Sopenharmony_ci
486062306a36Sopenharmony_ci	tst.b		%d1
486162306a36Sopenharmony_ci	bne.b		_L23_2x
486262306a36Sopenharmony_ci	bsr.l		sscale_snorm			# operand is a NORM
486362306a36Sopenharmony_ci	bra.b		_L23_6x
486462306a36Sopenharmony_ci_L23_2x:
486562306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO		# is operand a ZERO?
486662306a36Sopenharmony_ci	bne.b		_L23_3x			# no
486762306a36Sopenharmony_ci	bsr.l		sscale_szero			# yes
486862306a36Sopenharmony_ci	bra.b		_L23_6x
486962306a36Sopenharmony_ci_L23_3x:
487062306a36Sopenharmony_ci	cmpi.b		%d1,&INF		# is operand an INF?
487162306a36Sopenharmony_ci	bne.b		_L23_4x			# no
487262306a36Sopenharmony_ci	bsr.l		sscale_sinf			# yes
487362306a36Sopenharmony_ci	bra.b		_L23_6x
487462306a36Sopenharmony_ci_L23_4x:
487562306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN		# is operand a QNAN?
487662306a36Sopenharmony_ci	bne.b		_L23_5x			# no
487762306a36Sopenharmony_ci	bsr.l		sop_sqnan			# yes
487862306a36Sopenharmony_ci	bra.b		_L23_6x
487962306a36Sopenharmony_ci_L23_5x:
488062306a36Sopenharmony_ci	bsr.l		sscale_sdnrm			# operand is a DENORM
488162306a36Sopenharmony_ci_L23_6x:
488262306a36Sopenharmony_ci
488362306a36Sopenharmony_ci#
488462306a36Sopenharmony_ci#	Result is now in FP0
488562306a36Sopenharmony_ci#
488662306a36Sopenharmony_ci	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
488762306a36Sopenharmony_ci	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
488862306a36Sopenharmony_ci	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
488962306a36Sopenharmony_ci	unlk		%a6
489062306a36Sopenharmony_ci	rts
489162306a36Sopenharmony_ci
489262306a36Sopenharmony_ci
489362306a36Sopenharmony_ci#########################################################################
489462306a36Sopenharmony_ci# ssin():     computes the sine of a normalized input			#
489562306a36Sopenharmony_ci# ssind():    computes the sine of a denormalized input			#
489662306a36Sopenharmony_ci# scos():     computes the cosine of a normalized input			#
489762306a36Sopenharmony_ci# scosd():    computes the cosine of a denormalized input		#
489862306a36Sopenharmony_ci# ssincos():  computes the sine and cosine of a normalized input	#
489962306a36Sopenharmony_ci# ssincosd(): computes the sine and cosine of a denormalized input	#
490062306a36Sopenharmony_ci#									#
490162306a36Sopenharmony_ci# INPUT *************************************************************** #
490262306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
490362306a36Sopenharmony_ci#	d0 = round precision,mode					#
490462306a36Sopenharmony_ci#									#
490562306a36Sopenharmony_ci# OUTPUT ************************************************************** #
490662306a36Sopenharmony_ci#	fp0 = sin(X) or cos(X)						#
490762306a36Sopenharmony_ci#									#
490862306a36Sopenharmony_ci#    For ssincos(X):							#
490962306a36Sopenharmony_ci#	fp0 = sin(X)							#
491062306a36Sopenharmony_ci#	fp1 = cos(X)							#
491162306a36Sopenharmony_ci#									#
491262306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* #
491362306a36Sopenharmony_ci#	The returned result is within 1 ulp in 64 significant bit, i.e.	#
491462306a36Sopenharmony_ci#	within 0.5001 ulp to 53 bits if the result is subsequently	#
491562306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
491662306a36Sopenharmony_ci#	in double precision.						#
491762306a36Sopenharmony_ci#									#
491862306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
491962306a36Sopenharmony_ci#									#
492062306a36Sopenharmony_ci#	SIN and COS:							#
492162306a36Sopenharmony_ci#	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
492262306a36Sopenharmony_ci#									#
492362306a36Sopenharmony_ci#	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
492462306a36Sopenharmony_ci#									#
492562306a36Sopenharmony_ci#	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
492662306a36Sopenharmony_ci#		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
492762306a36Sopenharmony_ci#		Overwrite k by k := k + AdjN.				#
492862306a36Sopenharmony_ci#									#
492962306a36Sopenharmony_ci#	4. If k is even, go to 6.					#
493062306a36Sopenharmony_ci#									#
493162306a36Sopenharmony_ci#	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j.			#
493262306a36Sopenharmony_ci#		Return sgn*cos(r) where cos(r) is approximated by an	#
493362306a36Sopenharmony_ci#		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
493462306a36Sopenharmony_ci#		s = r*r.						#
493562306a36Sopenharmony_ci#		Exit.							#
493662306a36Sopenharmony_ci#									#
493762306a36Sopenharmony_ci#	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
493862306a36Sopenharmony_ci#		where sin(r) is approximated by an odd polynomial in r	#
493962306a36Sopenharmony_ci#		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
494062306a36Sopenharmony_ci#		Exit.							#
494162306a36Sopenharmony_ci#									#
494262306a36Sopenharmony_ci#	7. If |X| > 1, go to 9.						#
494362306a36Sopenharmony_ci#									#
494462306a36Sopenharmony_ci#	8. (|X|<2**(-40)) If SIN is invoked, return X;			#
494562306a36Sopenharmony_ci#		otherwise return 1.					#
494662306a36Sopenharmony_ci#									#
494762306a36Sopenharmony_ci#	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
494862306a36Sopenharmony_ci#		go back to 3.						#
494962306a36Sopenharmony_ci#									#
495062306a36Sopenharmony_ci#	SINCOS:								#
495162306a36Sopenharmony_ci#	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
495262306a36Sopenharmony_ci#									#
495362306a36Sopenharmony_ci#	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
495462306a36Sopenharmony_ci#		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
495562306a36Sopenharmony_ci#									#
495662306a36Sopenharmony_ci#	3. If k is even, go to 5.					#
495762306a36Sopenharmony_ci#									#
495862306a36Sopenharmony_ci#	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
495962306a36Sopenharmony_ci#		j1 exclusive or with the l.s.b. of k.			#
496062306a36Sopenharmony_ci#		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
496162306a36Sopenharmony_ci#		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
496262306a36Sopenharmony_ci#		sin(r) and cos(r) are computed as odd and even		#
496362306a36Sopenharmony_ci#		polynomials in r, respectively. Exit			#
496462306a36Sopenharmony_ci#									#
496562306a36Sopenharmony_ci#	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
496662306a36Sopenharmony_ci#		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
496762306a36Sopenharmony_ci#		sin(r) and cos(r) are computed as odd and even		#
496862306a36Sopenharmony_ci#		polynomials in r, respectively. Exit			#
496962306a36Sopenharmony_ci#									#
497062306a36Sopenharmony_ci#	6. If |X| > 1, go to 8.						#
497162306a36Sopenharmony_ci#									#
497262306a36Sopenharmony_ci#	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
497362306a36Sopenharmony_ci#									#
497462306a36Sopenharmony_ci#	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
497562306a36Sopenharmony_ci#		go back to 2.						#
497662306a36Sopenharmony_ci#									#
497762306a36Sopenharmony_ci#########################################################################
497862306a36Sopenharmony_ci
497962306a36Sopenharmony_ciSINA7:	long		0xBD6AAA77,0xCCC994F5
498062306a36Sopenharmony_ciSINA6:	long		0x3DE61209,0x7AAE8DA1
498162306a36Sopenharmony_ciSINA5:	long		0xBE5AE645,0x2A118AE4
498262306a36Sopenharmony_ciSINA4:	long		0x3EC71DE3,0xA5341531
498362306a36Sopenharmony_ciSINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
498462306a36Sopenharmony_ciSINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
498562306a36Sopenharmony_ciSINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
498662306a36Sopenharmony_ci
498762306a36Sopenharmony_ciCOSB8:	long		0x3D2AC4D0,0xD6011EE3
498862306a36Sopenharmony_ciCOSB7:	long		0xBDA9396F,0x9F45AC19
498962306a36Sopenharmony_ciCOSB6:	long		0x3E21EED9,0x0612C972
499062306a36Sopenharmony_ciCOSB5:	long		0xBE927E4F,0xB79D9FCF
499162306a36Sopenharmony_ciCOSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
499262306a36Sopenharmony_ciCOSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
499362306a36Sopenharmony_ciCOSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
499462306a36Sopenharmony_ciCOSB1:	long		0xBF000000
499562306a36Sopenharmony_ci
499662306a36Sopenharmony_ci	set		INARG,FP_SCR0
499762306a36Sopenharmony_ci
499862306a36Sopenharmony_ci	set		X,FP_SCR0
499962306a36Sopenharmony_ci#	set		XDCARE,X+2
500062306a36Sopenharmony_ci	set		XFRAC,X+4
500162306a36Sopenharmony_ci
500262306a36Sopenharmony_ci	set		RPRIME,FP_SCR0
500362306a36Sopenharmony_ci	set		SPRIME,FP_SCR1
500462306a36Sopenharmony_ci
500562306a36Sopenharmony_ci	set		POSNEG1,L_SCR1
500662306a36Sopenharmony_ci	set		TWOTO63,L_SCR1
500762306a36Sopenharmony_ci
500862306a36Sopenharmony_ci	set		ENDFLAG,L_SCR2
500962306a36Sopenharmony_ci	set		INT,L_SCR2
501062306a36Sopenharmony_ci
501162306a36Sopenharmony_ci	set		ADJN,L_SCR3
501262306a36Sopenharmony_ci
501362306a36Sopenharmony_ci############################################
501462306a36Sopenharmony_ci	global		ssin
501562306a36Sopenharmony_cissin:
501662306a36Sopenharmony_ci	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
501762306a36Sopenharmony_ci	bra.b		SINBGN
501862306a36Sopenharmony_ci
501962306a36Sopenharmony_ci############################################
502062306a36Sopenharmony_ci	global		scos
502162306a36Sopenharmony_ciscos:
502262306a36Sopenharmony_ci	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
502362306a36Sopenharmony_ci
502462306a36Sopenharmony_ci############################################
502562306a36Sopenharmony_ciSINBGN:
502662306a36Sopenharmony_ci#--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
502762306a36Sopenharmony_ci
502862306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
502962306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)		# save input at X
503062306a36Sopenharmony_ci
503162306a36Sopenharmony_ci# "COMPACTIFY" X
503262306a36Sopenharmony_ci	mov.l		(%a0),%d1		# put exp in hi word
503362306a36Sopenharmony_ci	mov.w		4(%a0),%d1		# fetch hi(man)
503462306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1		# strip sign
503562306a36Sopenharmony_ci
503662306a36Sopenharmony_ci	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
503762306a36Sopenharmony_ci	bge.b		SOK1			# no
503862306a36Sopenharmony_ci	bra.w		SINSM			# yes; input is very small
503962306a36Sopenharmony_ci
504062306a36Sopenharmony_ciSOK1:
504162306a36Sopenharmony_ci	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
504262306a36Sopenharmony_ci	blt.b		SINMAIN			# no
504362306a36Sopenharmony_ci	bra.w		SREDUCEX		# yes; input is very large
504462306a36Sopenharmony_ci
504562306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| <= 15 PI.
504662306a36Sopenharmony_ci#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
504762306a36Sopenharmony_ciSINMAIN:
504862306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
504962306a36Sopenharmony_ci	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
505062306a36Sopenharmony_ci
505162306a36Sopenharmony_ci	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
505262306a36Sopenharmony_ci
505362306a36Sopenharmony_ci	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
505462306a36Sopenharmony_ci
505562306a36Sopenharmony_ci	mov.l		INT(%a6),%d1		# make a copy of N
505662306a36Sopenharmony_ci	asl.l		&4,%d1			# N *= 16
505762306a36Sopenharmony_ci	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
505862306a36Sopenharmony_ci
505962306a36Sopenharmony_ci# A1 IS THE ADDRESS OF N*PIBY2
506062306a36Sopenharmony_ci# ...WHICH IS IN TWO PIECES Y1 & Y2
506162306a36Sopenharmony_ci	fsub.x		(%a1)+,%fp0		# X-Y1
506262306a36Sopenharmony_ci	fsub.s		(%a1),%fp0		# fp0 = R = (X-Y1)-Y2
506362306a36Sopenharmony_ci
506462306a36Sopenharmony_ciSINCONT:
506562306a36Sopenharmony_ci#--continuation from REDUCEX
506662306a36Sopenharmony_ci
506762306a36Sopenharmony_ci#--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
506862306a36Sopenharmony_ci	mov.l		INT(%a6),%d1
506962306a36Sopenharmony_ci	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
507062306a36Sopenharmony_ci	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
507162306a36Sopenharmony_ci	cmp.l		%d1,&0
507262306a36Sopenharmony_ci	blt.w		COSPOLY
507362306a36Sopenharmony_ci
507462306a36Sopenharmony_ci#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
507562306a36Sopenharmony_ci#--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
507662306a36Sopenharmony_ci#--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
507762306a36Sopenharmony_ci#--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
507862306a36Sopenharmony_ci#--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
507962306a36Sopenharmony_ci#--WHERE T=S*S.
508062306a36Sopenharmony_ci#--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
508162306a36Sopenharmony_ci#--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
508262306a36Sopenharmony_ciSINPOLY:
508362306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
508462306a36Sopenharmony_ci
508562306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)		# X IS R
508662306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FP0 IS S
508762306a36Sopenharmony_ci
508862306a36Sopenharmony_ci	fmov.d		SINA7(%pc),%fp3
508962306a36Sopenharmony_ci	fmov.d		SINA6(%pc),%fp2
509062306a36Sopenharmony_ci
509162306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
509262306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# FP1 IS T
509362306a36Sopenharmony_ci
509462306a36Sopenharmony_ci	ror.l		&1,%d1
509562306a36Sopenharmony_ci	and.l		&0x80000000,%d1
509662306a36Sopenharmony_ci# ...LEAST SIG. BIT OF D0 IN SIGN POSITION
509762306a36Sopenharmony_ci	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
509862306a36Sopenharmony_ci
509962306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# TA7
510062306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# TA6
510162306a36Sopenharmony_ci
510262306a36Sopenharmony_ci	fadd.d		SINA5(%pc),%fp3		# A5+TA7
510362306a36Sopenharmony_ci	fadd.d		SINA4(%pc),%fp2		# A4+TA6
510462306a36Sopenharmony_ci
510562306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# T(A5+TA7)
510662306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# T(A4+TA6)
510762306a36Sopenharmony_ci
510862306a36Sopenharmony_ci	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
510962306a36Sopenharmony_ci	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
511062306a36Sopenharmony_ci
511162306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
511262306a36Sopenharmony_ci
511362306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
511462306a36Sopenharmony_ci	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
511562306a36Sopenharmony_ci	fmul.x		X(%a6),%fp0		# R'*S
511662306a36Sopenharmony_ci
511762306a36Sopenharmony_ci	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
511862306a36Sopenharmony_ci
511962306a36Sopenharmony_ci	fmul.x		%fp1,%fp0		# SIN(R')-R'
512062306a36Sopenharmony_ci
512162306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
512262306a36Sopenharmony_ci
512362306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
512462306a36Sopenharmony_ci	fadd.x		X(%a6),%fp0		# last inst - possible exception set
512562306a36Sopenharmony_ci	bra		t_inx2
512662306a36Sopenharmony_ci
512762306a36Sopenharmony_ci#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
512862306a36Sopenharmony_ci#--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
512962306a36Sopenharmony_ci#--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
513062306a36Sopenharmony_ci#--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
513162306a36Sopenharmony_ci#--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
513262306a36Sopenharmony_ci#--WHERE T=S*S.
513362306a36Sopenharmony_ci#--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
513462306a36Sopenharmony_ci#--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
513562306a36Sopenharmony_ci#--AND IS THEREFORE STORED AS SINGLE PRECISION.
513662306a36Sopenharmony_ciCOSPOLY:
513762306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
513862306a36Sopenharmony_ci
513962306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FP0 IS S
514062306a36Sopenharmony_ci
514162306a36Sopenharmony_ci	fmov.d		COSB8(%pc),%fp2
514262306a36Sopenharmony_ci	fmov.d		COSB7(%pc),%fp3
514362306a36Sopenharmony_ci
514462306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
514562306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# FP1 IS T
514662306a36Sopenharmony_ci
514762306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)		# X IS S
514862306a36Sopenharmony_ci	ror.l		&1,%d1
514962306a36Sopenharmony_ci	and.l		&0x80000000,%d1
515062306a36Sopenharmony_ci# ...LEAST SIG. BIT OF D0 IN SIGN POSITION
515162306a36Sopenharmony_ci
515262306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# TB8
515362306a36Sopenharmony_ci
515462306a36Sopenharmony_ci	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
515562306a36Sopenharmony_ci	and.l		&0x80000000,%d1
515662306a36Sopenharmony_ci
515762306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# TB7
515862306a36Sopenharmony_ci
515962306a36Sopenharmony_ci	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
516062306a36Sopenharmony_ci	mov.l		%d1,POSNEG1(%a6)
516162306a36Sopenharmony_ci
516262306a36Sopenharmony_ci	fadd.d		COSB6(%pc),%fp2		# B6+TB8
516362306a36Sopenharmony_ci	fadd.d		COSB5(%pc),%fp3		# B5+TB7
516462306a36Sopenharmony_ci
516562306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# T(B6+TB8)
516662306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# T(B5+TB7)
516762306a36Sopenharmony_ci
516862306a36Sopenharmony_ci	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
516962306a36Sopenharmony_ci	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
517062306a36Sopenharmony_ci
517162306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
517262306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
517362306a36Sopenharmony_ci
517462306a36Sopenharmony_ci	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
517562306a36Sopenharmony_ci	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
517662306a36Sopenharmony_ci
517762306a36Sopenharmony_ci	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
517862306a36Sopenharmony_ci
517962306a36Sopenharmony_ci	fadd.x		%fp1,%fp0
518062306a36Sopenharmony_ci
518162306a36Sopenharmony_ci	fmul.x		X(%a6),%fp0
518262306a36Sopenharmony_ci
518362306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
518462306a36Sopenharmony_ci
518562306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
518662306a36Sopenharmony_ci	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
518762306a36Sopenharmony_ci	bra		t_inx2
518862306a36Sopenharmony_ci
518962306a36Sopenharmony_ci##############################################
519062306a36Sopenharmony_ci
519162306a36Sopenharmony_ci# SINe: Big OR Small?
519262306a36Sopenharmony_ci#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
519362306a36Sopenharmony_ci#--IF |X| < 2**(-40), RETURN X OR 1.
519462306a36Sopenharmony_ciSINBORS:
519562306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
519662306a36Sopenharmony_ci	bgt.l		SREDUCEX
519762306a36Sopenharmony_ci
519862306a36Sopenharmony_ciSINSM:
519962306a36Sopenharmony_ci	mov.l		ADJN(%a6),%d1
520062306a36Sopenharmony_ci	cmp.l		%d1,&0
520162306a36Sopenharmony_ci	bgt.b		COSTINY
520262306a36Sopenharmony_ci
520362306a36Sopenharmony_ci# here, the operation may underflow iff the precision is sgl or dbl.
520462306a36Sopenharmony_ci# extended denorms are handled through another entry point.
520562306a36Sopenharmony_ciSINTINY:
520662306a36Sopenharmony_ci#	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
520762306a36Sopenharmony_ci
520862306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
520962306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
521062306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0		# last inst - possible exception set
521162306a36Sopenharmony_ci	bra		t_catch
521262306a36Sopenharmony_ci
521362306a36Sopenharmony_ciCOSTINY:
521462306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
521562306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
521662306a36Sopenharmony_ci	fadd.s		&0x80800000,%fp0	# last inst - possible exception set
521762306a36Sopenharmony_ci	bra		t_pinx2
521862306a36Sopenharmony_ci
521962306a36Sopenharmony_ci################################################
522062306a36Sopenharmony_ci	global		ssind
522162306a36Sopenharmony_ci#--SIN(X) = X FOR DENORMALIZED X
522262306a36Sopenharmony_cissind:
522362306a36Sopenharmony_ci	bra		t_extdnrm
522462306a36Sopenharmony_ci
522562306a36Sopenharmony_ci############################################
522662306a36Sopenharmony_ci	global		scosd
522762306a36Sopenharmony_ci#--COS(X) = 1 FOR DENORMALIZED X
522862306a36Sopenharmony_ciscosd:
522962306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
523062306a36Sopenharmony_ci	bra		t_pinx2
523162306a36Sopenharmony_ci
523262306a36Sopenharmony_ci##################################################
523362306a36Sopenharmony_ci
523462306a36Sopenharmony_ci	global		ssincos
523562306a36Sopenharmony_cissincos:
523662306a36Sopenharmony_ci#--SET ADJN TO 4
523762306a36Sopenharmony_ci	mov.l		&4,ADJN(%a6)
523862306a36Sopenharmony_ci
523962306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
524062306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)
524162306a36Sopenharmony_ci
524262306a36Sopenharmony_ci	mov.l		(%a0),%d1
524362306a36Sopenharmony_ci	mov.w		4(%a0),%d1
524462306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
524562306a36Sopenharmony_ci
524662306a36Sopenharmony_ci	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
524762306a36Sopenharmony_ci	bge.b		SCOK1
524862306a36Sopenharmony_ci	bra.w		SCSM
524962306a36Sopenharmony_ci
525062306a36Sopenharmony_ciSCOK1:
525162306a36Sopenharmony_ci	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
525262306a36Sopenharmony_ci	blt.b		SCMAIN
525362306a36Sopenharmony_ci	bra.w		SREDUCEX
525462306a36Sopenharmony_ci
525562306a36Sopenharmony_ci
525662306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| <= 15 PI.
525762306a36Sopenharmony_ci#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
525862306a36Sopenharmony_ciSCMAIN:
525962306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
526062306a36Sopenharmony_ci
526162306a36Sopenharmony_ci	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
526262306a36Sopenharmony_ci
526362306a36Sopenharmony_ci	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
526462306a36Sopenharmony_ci
526562306a36Sopenharmony_ci	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
526662306a36Sopenharmony_ci
526762306a36Sopenharmony_ci	mov.l		INT(%a6),%d1
526862306a36Sopenharmony_ci	asl.l		&4,%d1
526962306a36Sopenharmony_ci	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
527062306a36Sopenharmony_ci
527162306a36Sopenharmony_ci	fsub.x		(%a1)+,%fp0		# X-Y1
527262306a36Sopenharmony_ci	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
527362306a36Sopenharmony_ci
527462306a36Sopenharmony_ciSCCONT:
527562306a36Sopenharmony_ci#--continuation point from REDUCEX
527662306a36Sopenharmony_ci
527762306a36Sopenharmony_ci	mov.l		INT(%a6),%d1
527862306a36Sopenharmony_ci	ror.l		&1,%d1
527962306a36Sopenharmony_ci	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
528062306a36Sopenharmony_ci	bge.w		NEVEN
528162306a36Sopenharmony_ci
528262306a36Sopenharmony_ciSNODD:
528362306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR: D0, A0, FP2.
528462306a36Sopenharmony_ci	fmovm.x		&0x04,-(%sp)		# save fp2
528562306a36Sopenharmony_ci
528662306a36Sopenharmony_ci	fmov.x		%fp0,RPRIME(%a6)
528762306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
528862306a36Sopenharmony_ci	fmov.d		SINA7(%pc),%fp1		# A7
528962306a36Sopenharmony_ci	fmov.d		COSB8(%pc),%fp2		# B8
529062306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# SA7
529162306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# SB8
529262306a36Sopenharmony_ci
529362306a36Sopenharmony_ci	mov.l		%d2,-(%sp)
529462306a36Sopenharmony_ci	mov.l		%d1,%d2
529562306a36Sopenharmony_ci	ror.l		&1,%d2
529662306a36Sopenharmony_ci	and.l		&0x80000000,%d2
529762306a36Sopenharmony_ci	eor.l		%d1,%d2
529862306a36Sopenharmony_ci	and.l		&0x80000000,%d2
529962306a36Sopenharmony_ci
530062306a36Sopenharmony_ci	fadd.d		SINA6(%pc),%fp1		# A6+SA7
530162306a36Sopenharmony_ci	fadd.d		COSB7(%pc),%fp2		# B7+SB8
530262306a36Sopenharmony_ci
530362306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(A6+SA7)
530462306a36Sopenharmony_ci	eor.l		%d2,RPRIME(%a6)
530562306a36Sopenharmony_ci	mov.l		(%sp)+,%d2
530662306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(B7+SB8)
530762306a36Sopenharmony_ci	ror.l		&1,%d1
530862306a36Sopenharmony_ci	and.l		&0x80000000,%d1
530962306a36Sopenharmony_ci	mov.l		&0x3F800000,POSNEG1(%a6)
531062306a36Sopenharmony_ci	eor.l		%d1,POSNEG1(%a6)
531162306a36Sopenharmony_ci
531262306a36Sopenharmony_ci	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
531362306a36Sopenharmony_ci	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
531462306a36Sopenharmony_ci
531562306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
531662306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
531762306a36Sopenharmony_ci	fmov.x		%fp0,SPRIME(%a6)
531862306a36Sopenharmony_ci
531962306a36Sopenharmony_ci	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
532062306a36Sopenharmony_ci	eor.l		%d1,SPRIME(%a6)
532162306a36Sopenharmony_ci	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
532262306a36Sopenharmony_ci
532362306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(A4+...)
532462306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(B5+...)
532562306a36Sopenharmony_ci
532662306a36Sopenharmony_ci	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
532762306a36Sopenharmony_ci	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
532862306a36Sopenharmony_ci
532962306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(A3+...)
533062306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(B4+...)
533162306a36Sopenharmony_ci
533262306a36Sopenharmony_ci	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
533362306a36Sopenharmony_ci	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
533462306a36Sopenharmony_ci
533562306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(A2+...)
533662306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(B3+...)
533762306a36Sopenharmony_ci
533862306a36Sopenharmony_ci	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
533962306a36Sopenharmony_ci	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
534062306a36Sopenharmony_ci
534162306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(A1+...)
534262306a36Sopenharmony_ci	fmul.x		%fp2,%fp0		# S(B2+...)
534362306a36Sopenharmony_ci
534462306a36Sopenharmony_ci	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
534562306a36Sopenharmony_ci	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
534662306a36Sopenharmony_ci	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
534762306a36Sopenharmony_ci
534862306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x20		# restore fp2
534962306a36Sopenharmony_ci
535062306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
535162306a36Sopenharmony_ci	fadd.x		RPRIME(%a6),%fp1	# COS(X)
535262306a36Sopenharmony_ci	bsr		sto_cos			# store cosine result
535362306a36Sopenharmony_ci	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
535462306a36Sopenharmony_ci	bra		t_inx2
535562306a36Sopenharmony_ci
535662306a36Sopenharmony_ciNEVEN:
535762306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR: FP2.
535862306a36Sopenharmony_ci	fmovm.x		&0x04,-(%sp)		# save fp2
535962306a36Sopenharmony_ci
536062306a36Sopenharmony_ci	fmov.x		%fp0,RPRIME(%a6)
536162306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
536262306a36Sopenharmony_ci
536362306a36Sopenharmony_ci	fmov.d		COSB8(%pc),%fp1		# B8
536462306a36Sopenharmony_ci	fmov.d		SINA7(%pc),%fp2		# A7
536562306a36Sopenharmony_ci
536662306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# SB8
536762306a36Sopenharmony_ci	fmov.x		%fp0,SPRIME(%a6)
536862306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# SA7
536962306a36Sopenharmony_ci
537062306a36Sopenharmony_ci	ror.l		&1,%d1
537162306a36Sopenharmony_ci	and.l		&0x80000000,%d1
537262306a36Sopenharmony_ci
537362306a36Sopenharmony_ci	fadd.d		COSB7(%pc),%fp1		# B7+SB8
537462306a36Sopenharmony_ci	fadd.d		SINA6(%pc),%fp2		# A6+SA7
537562306a36Sopenharmony_ci
537662306a36Sopenharmony_ci	eor.l		%d1,RPRIME(%a6)
537762306a36Sopenharmony_ci	eor.l		%d1,SPRIME(%a6)
537862306a36Sopenharmony_ci
537962306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(B7+SB8)
538062306a36Sopenharmony_ci
538162306a36Sopenharmony_ci	or.l		&0x3F800000,%d1
538262306a36Sopenharmony_ci	mov.l		%d1,POSNEG1(%a6)
538362306a36Sopenharmony_ci
538462306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(A6+SA7)
538562306a36Sopenharmony_ci
538662306a36Sopenharmony_ci	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
538762306a36Sopenharmony_ci	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
538862306a36Sopenharmony_ci
538962306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
539062306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
539162306a36Sopenharmony_ci
539262306a36Sopenharmony_ci	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
539362306a36Sopenharmony_ci	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
539462306a36Sopenharmony_ci
539562306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(B5+...)
539662306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(A4+...)
539762306a36Sopenharmony_ci
539862306a36Sopenharmony_ci	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
539962306a36Sopenharmony_ci	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
540062306a36Sopenharmony_ci
540162306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(B4+...)
540262306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(A3+...)
540362306a36Sopenharmony_ci
540462306a36Sopenharmony_ci	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
540562306a36Sopenharmony_ci	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
540662306a36Sopenharmony_ci
540762306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(B3+...)
540862306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(A2+...)
540962306a36Sopenharmony_ci
541062306a36Sopenharmony_ci	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
541162306a36Sopenharmony_ci	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
541262306a36Sopenharmony_ci
541362306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# S(B2+...)
541462306a36Sopenharmony_ci	fmul.x		%fp2,%fp0		# s(a1+...)
541562306a36Sopenharmony_ci
541662306a36Sopenharmony_ci
541762306a36Sopenharmony_ci	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
541862306a36Sopenharmony_ci	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
541962306a36Sopenharmony_ci	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
542062306a36Sopenharmony_ci
542162306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x20		# restore fp2
542262306a36Sopenharmony_ci
542362306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
542462306a36Sopenharmony_ci	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
542562306a36Sopenharmony_ci	bsr		sto_cos			# store cosine result
542662306a36Sopenharmony_ci	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
542762306a36Sopenharmony_ci	bra		t_inx2
542862306a36Sopenharmony_ci
542962306a36Sopenharmony_ci################################################
543062306a36Sopenharmony_ci
543162306a36Sopenharmony_ciSCBORS:
543262306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
543362306a36Sopenharmony_ci	bgt.w		SREDUCEX
543462306a36Sopenharmony_ci
543562306a36Sopenharmony_ci################################################
543662306a36Sopenharmony_ci
543762306a36Sopenharmony_ciSCSM:
543862306a36Sopenharmony_ci#	mov.w		&0x0000,XDCARE(%a6)
543962306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp1
544062306a36Sopenharmony_ci
544162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
544262306a36Sopenharmony_ci	fsub.s		&0x00800000,%fp1
544362306a36Sopenharmony_ci	bsr		sto_cos			# store cosine result
544462306a36Sopenharmony_ci	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
544562306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
544662306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0
544762306a36Sopenharmony_ci	bra		t_catch
544862306a36Sopenharmony_ci
544962306a36Sopenharmony_ci##############################################
545062306a36Sopenharmony_ci
545162306a36Sopenharmony_ci	global		ssincosd
545262306a36Sopenharmony_ci#--SIN AND COS OF X FOR DENORMALIZED X
545362306a36Sopenharmony_cissincosd:
545462306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save d0
545562306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp1
545662306a36Sopenharmony_ci	bsr		sto_cos			# store cosine result
545762306a36Sopenharmony_ci	mov.l		(%sp)+,%d0		# restore d0
545862306a36Sopenharmony_ci	bra		t_extdnrm
545962306a36Sopenharmony_ci
546062306a36Sopenharmony_ci############################################
546162306a36Sopenharmony_ci
546262306a36Sopenharmony_ci#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
546362306a36Sopenharmony_ci#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
546462306a36Sopenharmony_ci#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
546562306a36Sopenharmony_ciSREDUCEX:
546662306a36Sopenharmony_ci	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
546762306a36Sopenharmony_ci	mov.l		%d2,-(%sp)		# save d2
546862306a36Sopenharmony_ci	fmov.s		&0x00000000,%fp1	# fp1 = 0
546962306a36Sopenharmony_ci
547062306a36Sopenharmony_ci#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
547162306a36Sopenharmony_ci#--there is a danger of unwanted overflow in first LOOP iteration.  In this
547262306a36Sopenharmony_ci#--case, reduce argument by one remainder step to make subsequent reduction
547362306a36Sopenharmony_ci#--safe.
547462306a36Sopenharmony_ci	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
547562306a36Sopenharmony_ci	bne.b		SLOOP			# no
547662306a36Sopenharmony_ci
547762306a36Sopenharmony_ci# yes; create 2**16383*PI/2
547862306a36Sopenharmony_ci	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
547962306a36Sopenharmony_ci	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
548062306a36Sopenharmony_ci	clr.l		FP_SCR0_LO(%a6)
548162306a36Sopenharmony_ci
548262306a36Sopenharmony_ci# create low half of 2**16383*PI/2 at FP_SCR1
548362306a36Sopenharmony_ci	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
548462306a36Sopenharmony_ci	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
548562306a36Sopenharmony_ci	clr.l		FP_SCR1_LO(%a6)
548662306a36Sopenharmony_ci
548762306a36Sopenharmony_ci	ftest.x		%fp0			# test sign of argument
548862306a36Sopenharmony_ci	fblt.w		sred_neg
548962306a36Sopenharmony_ci
549062306a36Sopenharmony_ci	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
549162306a36Sopenharmony_ci	or.b		&0x80,FP_SCR1_EX(%a6)
549262306a36Sopenharmony_cisred_neg:
549362306a36Sopenharmony_ci	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
549462306a36Sopenharmony_ci	fmov.x		%fp0,%fp1		# save high result in fp1
549562306a36Sopenharmony_ci	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
549662306a36Sopenharmony_ci	fsub.x		%fp0,%fp1		# determine low component of result
549762306a36Sopenharmony_ci	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
549862306a36Sopenharmony_ci
549962306a36Sopenharmony_ci#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
550062306a36Sopenharmony_ci#--integer quotient will be stored in N
550162306a36Sopenharmony_ci#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
550262306a36Sopenharmony_ciSLOOP:
550362306a36Sopenharmony_ci	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
550462306a36Sopenharmony_ci	mov.w		INARG(%a6),%d1
550562306a36Sopenharmony_ci	mov.l		%d1,%a1			# save a copy of D0
550662306a36Sopenharmony_ci	and.l		&0x00007FFF,%d1
550762306a36Sopenharmony_ci	sub.l		&0x00003FFF,%d1		# d0 = K
550862306a36Sopenharmony_ci	cmp.l		%d1,&28
550962306a36Sopenharmony_ci	ble.b		SLASTLOOP
551062306a36Sopenharmony_ciSCONTLOOP:
551162306a36Sopenharmony_ci	sub.l		&27,%d1			# d0 = L := K-27
551262306a36Sopenharmony_ci	mov.b		&0,ENDFLAG(%a6)
551362306a36Sopenharmony_ci	bra.b		SWORK
551462306a36Sopenharmony_ciSLASTLOOP:
551562306a36Sopenharmony_ci	clr.l		%d1			# d0 = L := 0
551662306a36Sopenharmony_ci	mov.b		&1,ENDFLAG(%a6)
551762306a36Sopenharmony_ci
551862306a36Sopenharmony_ciSWORK:
551962306a36Sopenharmony_ci#--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
552062306a36Sopenharmony_ci#--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
552162306a36Sopenharmony_ci
552262306a36Sopenharmony_ci#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
552362306a36Sopenharmony_ci#--2**L * (PIby2_1), 2**L * (PIby2_2)
552462306a36Sopenharmony_ci
552562306a36Sopenharmony_ci	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
552662306a36Sopenharmony_ci	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
552762306a36Sopenharmony_ci
552862306a36Sopenharmony_ci	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
552962306a36Sopenharmony_ci	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
553062306a36Sopenharmony_ci	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
553162306a36Sopenharmony_ci
553262306a36Sopenharmony_ci	fmov.x		%fp0,%fp2
553362306a36Sopenharmony_ci	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
553462306a36Sopenharmony_ci
553562306a36Sopenharmony_ci#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
553662306a36Sopenharmony_ci#--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
553762306a36Sopenharmony_ci#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
553862306a36Sopenharmony_ci#--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
553962306a36Sopenharmony_ci#--US THE DESIRED VALUE IN FLOATING POINT.
554062306a36Sopenharmony_ci	mov.l		%a1,%d2
554162306a36Sopenharmony_ci	swap		%d2
554262306a36Sopenharmony_ci	and.l		&0x80000000,%d2
554362306a36Sopenharmony_ci	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
554462306a36Sopenharmony_ci	mov.l		%d2,TWOTO63(%a6)
554562306a36Sopenharmony_ci	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
554662306a36Sopenharmony_ci	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
554762306a36Sopenharmony_ci#	fint.x		%fp2
554862306a36Sopenharmony_ci
554962306a36Sopenharmony_ci#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
555062306a36Sopenharmony_ci	mov.l		%d1,%d2			# d2 = L
555162306a36Sopenharmony_ci
555262306a36Sopenharmony_ci	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
555362306a36Sopenharmony_ci	mov.w		%d2,FP_SCR0_EX(%a6)
555462306a36Sopenharmony_ci	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
555562306a36Sopenharmony_ci	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
555662306a36Sopenharmony_ci
555762306a36Sopenharmony_ci	add.l		&0x00003FDD,%d1
555862306a36Sopenharmony_ci	mov.w		%d1,FP_SCR1_EX(%a6)
555962306a36Sopenharmony_ci	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
556062306a36Sopenharmony_ci	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
556162306a36Sopenharmony_ci
556262306a36Sopenharmony_ci	mov.b		ENDFLAG(%a6),%d1
556362306a36Sopenharmony_ci
556462306a36Sopenharmony_ci#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
556562306a36Sopenharmony_ci#--P2 = 2**(L) * Piby2_2
556662306a36Sopenharmony_ci	fmov.x		%fp2,%fp4		# fp4 = N
556762306a36Sopenharmony_ci	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
556862306a36Sopenharmony_ci	fmov.x		%fp2,%fp5		# fp5 = N
556962306a36Sopenharmony_ci	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
557062306a36Sopenharmony_ci	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
557162306a36Sopenharmony_ci
557262306a36Sopenharmony_ci#--we want P+p = W+w  but  |p| <= half ulp of P
557362306a36Sopenharmony_ci#--Then, we need to compute  A := R-P   and  a := r-p
557462306a36Sopenharmony_ci	fadd.x		%fp5,%fp3		# fp3 = P
557562306a36Sopenharmony_ci	fsub.x		%fp3,%fp4		# fp4 = W-P
557662306a36Sopenharmony_ci
557762306a36Sopenharmony_ci	fsub.x		%fp3,%fp0		# fp0 = A := R - P
557862306a36Sopenharmony_ci	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
557962306a36Sopenharmony_ci
558062306a36Sopenharmony_ci	fmov.x		%fp0,%fp3		# fp3 = A
558162306a36Sopenharmony_ci	fsub.x		%fp4,%fp1		# fp1 = a := r - p
558262306a36Sopenharmony_ci
558362306a36Sopenharmony_ci#--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
558462306a36Sopenharmony_ci#--|r| <= half ulp of R.
558562306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# fp0 = R := A+a
558662306a36Sopenharmony_ci#--No need to calculate r if this is the last loop
558762306a36Sopenharmony_ci	cmp.b		%d1,&0
558862306a36Sopenharmony_ci	bgt.w		SRESTORE
558962306a36Sopenharmony_ci
559062306a36Sopenharmony_ci#--Need to calculate r
559162306a36Sopenharmony_ci	fsub.x		%fp0,%fp3		# fp3 = A-R
559262306a36Sopenharmony_ci	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
559362306a36Sopenharmony_ci	bra.w		SLOOP
559462306a36Sopenharmony_ci
559562306a36Sopenharmony_ciSRESTORE:
559662306a36Sopenharmony_ci	fmov.l		%fp2,INT(%a6)
559762306a36Sopenharmony_ci	mov.l		(%sp)+,%d2		# restore d2
559862306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
559962306a36Sopenharmony_ci
560062306a36Sopenharmony_ci	mov.l		ADJN(%a6),%d1
560162306a36Sopenharmony_ci	cmp.l		%d1,&4
560262306a36Sopenharmony_ci
560362306a36Sopenharmony_ci	blt.w		SINCONT
560462306a36Sopenharmony_ci	bra.w		SCCONT
560562306a36Sopenharmony_ci
560662306a36Sopenharmony_ci#########################################################################
560762306a36Sopenharmony_ci# stan():  computes the tangent of a normalized input			#
560862306a36Sopenharmony_ci# stand(): computes the tangent of a denormalized input			#
560962306a36Sopenharmony_ci#									#
561062306a36Sopenharmony_ci# INPUT *************************************************************** #
561162306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
561262306a36Sopenharmony_ci#	d0 = round precision,mode					#
561362306a36Sopenharmony_ci#									#
561462306a36Sopenharmony_ci# OUTPUT ************************************************************** #
561562306a36Sopenharmony_ci#	fp0 = tan(X)							#
561662306a36Sopenharmony_ci#									#
561762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* #
561862306a36Sopenharmony_ci#	The returned result is within 3 ulp in 64 significant bit, i.e. #
561962306a36Sopenharmony_ci#	within 0.5001 ulp to 53 bits if the result is subsequently	#
562062306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
562162306a36Sopenharmony_ci#	in double precision.						#
562262306a36Sopenharmony_ci#									#
562362306a36Sopenharmony_ci# ALGORITHM *********************************************************** #
562462306a36Sopenharmony_ci#									#
562562306a36Sopenharmony_ci#	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
562662306a36Sopenharmony_ci#									#
562762306a36Sopenharmony_ci#	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
562862306a36Sopenharmony_ci#		k = N mod 2, so in particular, k = 0 or 1.		#
562962306a36Sopenharmony_ci#									#
563062306a36Sopenharmony_ci#	3. If k is odd, go to 5.					#
563162306a36Sopenharmony_ci#									#
563262306a36Sopenharmony_ci#	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
563362306a36Sopenharmony_ci#		rational function U/V where				#
563462306a36Sopenharmony_ci#		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
563562306a36Sopenharmony_ci#		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
563662306a36Sopenharmony_ci#		Exit.							#
563762306a36Sopenharmony_ci#									#
563862306a36Sopenharmony_ci#	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
563962306a36Sopenharmony_ci#		a rational function U/V where				#
564062306a36Sopenharmony_ci#		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
564162306a36Sopenharmony_ci#		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
564262306a36Sopenharmony_ci#		-Cot(r) = -V/U. Exit.					#
564362306a36Sopenharmony_ci#									#
564462306a36Sopenharmony_ci#	6. If |X| > 1, go to 8.						#
564562306a36Sopenharmony_ci#									#
564662306a36Sopenharmony_ci#	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
564762306a36Sopenharmony_ci#									#
564862306a36Sopenharmony_ci#	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back	#
564962306a36Sopenharmony_ci#		to 2.							#
565062306a36Sopenharmony_ci#									#
565162306a36Sopenharmony_ci#########################################################################
565262306a36Sopenharmony_ci
565362306a36Sopenharmony_ciTANQ4:
565462306a36Sopenharmony_ci	long		0x3EA0B759,0xF50F8688
565562306a36Sopenharmony_ciTANP3:
565662306a36Sopenharmony_ci	long		0xBEF2BAA5,0xA8924F04
565762306a36Sopenharmony_ci
565862306a36Sopenharmony_ciTANQ3:
565962306a36Sopenharmony_ci	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
566062306a36Sopenharmony_ci
566162306a36Sopenharmony_ciTANP2:
566262306a36Sopenharmony_ci	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
566362306a36Sopenharmony_ci
566462306a36Sopenharmony_ciTANQ2:
566562306a36Sopenharmony_ci	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
566662306a36Sopenharmony_ci
566762306a36Sopenharmony_ciTANP1:
566862306a36Sopenharmony_ci	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
566962306a36Sopenharmony_ci
567062306a36Sopenharmony_ciTANQ1:
567162306a36Sopenharmony_ci	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
567262306a36Sopenharmony_ci
567362306a36Sopenharmony_ciINVTWOPI:
567462306a36Sopenharmony_ci	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
567562306a36Sopenharmony_ci
567662306a36Sopenharmony_ciTWOPI1:
567762306a36Sopenharmony_ci	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
567862306a36Sopenharmony_ciTWOPI2:
567962306a36Sopenharmony_ci	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
568062306a36Sopenharmony_ci
568162306a36Sopenharmony_ci#--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
568262306a36Sopenharmony_ci#--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
568362306a36Sopenharmony_ci#--MOST 69 BITS LONG.
568462306a36Sopenharmony_ci#	global		PITBL
568562306a36Sopenharmony_ciPITBL:
568662306a36Sopenharmony_ci	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
568762306a36Sopenharmony_ci	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
568862306a36Sopenharmony_ci	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
568962306a36Sopenharmony_ci	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
569062306a36Sopenharmony_ci	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
569162306a36Sopenharmony_ci	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
569262306a36Sopenharmony_ci	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
569362306a36Sopenharmony_ci	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
569462306a36Sopenharmony_ci	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
569562306a36Sopenharmony_ci	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
569662306a36Sopenharmony_ci	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
569762306a36Sopenharmony_ci	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
569862306a36Sopenharmony_ci	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
569962306a36Sopenharmony_ci	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
570062306a36Sopenharmony_ci	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
570162306a36Sopenharmony_ci	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
570262306a36Sopenharmony_ci	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
570362306a36Sopenharmony_ci	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
570462306a36Sopenharmony_ci	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
570562306a36Sopenharmony_ci	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
570662306a36Sopenharmony_ci	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
570762306a36Sopenharmony_ci	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
570862306a36Sopenharmony_ci	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
570962306a36Sopenharmony_ci	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
571062306a36Sopenharmony_ci	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
571162306a36Sopenharmony_ci	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
571262306a36Sopenharmony_ci	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
571362306a36Sopenharmony_ci	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
571462306a36Sopenharmony_ci	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
571562306a36Sopenharmony_ci	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
571662306a36Sopenharmony_ci	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
571762306a36Sopenharmony_ci	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
571862306a36Sopenharmony_ci	long		0x00000000,0x00000000,0x00000000,0x00000000
571962306a36Sopenharmony_ci	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
572062306a36Sopenharmony_ci	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
572162306a36Sopenharmony_ci	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
572262306a36Sopenharmony_ci	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
572362306a36Sopenharmony_ci	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
572462306a36Sopenharmony_ci	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
572562306a36Sopenharmony_ci	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
572662306a36Sopenharmony_ci	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
572762306a36Sopenharmony_ci	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
572862306a36Sopenharmony_ci	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
572962306a36Sopenharmony_ci	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
573062306a36Sopenharmony_ci	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
573162306a36Sopenharmony_ci	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
573262306a36Sopenharmony_ci	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
573362306a36Sopenharmony_ci	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
573462306a36Sopenharmony_ci	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
573562306a36Sopenharmony_ci	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
573662306a36Sopenharmony_ci	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
573762306a36Sopenharmony_ci	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
573862306a36Sopenharmony_ci	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
573962306a36Sopenharmony_ci	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
574062306a36Sopenharmony_ci	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
574162306a36Sopenharmony_ci	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
574262306a36Sopenharmony_ci	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
574362306a36Sopenharmony_ci	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
574462306a36Sopenharmony_ci	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
574562306a36Sopenharmony_ci	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
574662306a36Sopenharmony_ci	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
574762306a36Sopenharmony_ci	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
574862306a36Sopenharmony_ci	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
574962306a36Sopenharmony_ci	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
575062306a36Sopenharmony_ci	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
575162306a36Sopenharmony_ci
575262306a36Sopenharmony_ci	set		INARG,FP_SCR0
575362306a36Sopenharmony_ci
575462306a36Sopenharmony_ci	set		TWOTO63,L_SCR1
575562306a36Sopenharmony_ci	set		INT,L_SCR1
575662306a36Sopenharmony_ci	set		ENDFLAG,L_SCR2
575762306a36Sopenharmony_ci
575862306a36Sopenharmony_ci	global		stan
575962306a36Sopenharmony_cistan:
576062306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
576162306a36Sopenharmony_ci
576262306a36Sopenharmony_ci	mov.l		(%a0),%d1
576362306a36Sopenharmony_ci	mov.w		4(%a0),%d1
576462306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
576562306a36Sopenharmony_ci
576662306a36Sopenharmony_ci	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
576762306a36Sopenharmony_ci	bge.b		TANOK1
576862306a36Sopenharmony_ci	bra.w		TANSM
576962306a36Sopenharmony_ciTANOK1:
577062306a36Sopenharmony_ci	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
577162306a36Sopenharmony_ci	blt.b		TANMAIN
577262306a36Sopenharmony_ci	bra.w		REDUCEX
577362306a36Sopenharmony_ci
577462306a36Sopenharmony_ciTANMAIN:
577562306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| <= 15 PI.
577662306a36Sopenharmony_ci#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
577762306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
577862306a36Sopenharmony_ci	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
577962306a36Sopenharmony_ci
578062306a36Sopenharmony_ci	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
578162306a36Sopenharmony_ci
578262306a36Sopenharmony_ci	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
578362306a36Sopenharmony_ci
578462306a36Sopenharmony_ci	asl.l		&4,%d1
578562306a36Sopenharmony_ci	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
578662306a36Sopenharmony_ci
578762306a36Sopenharmony_ci	fsub.x		(%a1)+,%fp0		# X-Y1
578862306a36Sopenharmony_ci
578962306a36Sopenharmony_ci	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
579062306a36Sopenharmony_ci
579162306a36Sopenharmony_ci	ror.l		&5,%d1
579262306a36Sopenharmony_ci	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
579362306a36Sopenharmony_ci
579462306a36Sopenharmony_ciTANCONT:
579562306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
579662306a36Sopenharmony_ci
579762306a36Sopenharmony_ci	cmp.l		%d1,&0
579862306a36Sopenharmony_ci	blt.w		NODD
579962306a36Sopenharmony_ci
580062306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
580162306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# S = R*R
580262306a36Sopenharmony_ci
580362306a36Sopenharmony_ci	fmov.d		TANQ4(%pc),%fp3
580462306a36Sopenharmony_ci	fmov.d		TANP3(%pc),%fp2
580562306a36Sopenharmony_ci
580662306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# SQ4
580762306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# SP3
580862306a36Sopenharmony_ci
580962306a36Sopenharmony_ci	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
581062306a36Sopenharmony_ci	fadd.x		TANP2(%pc),%fp2		# P2+SP3
581162306a36Sopenharmony_ci
581262306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
581362306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# S(P2+SP3)
581462306a36Sopenharmony_ci
581562306a36Sopenharmony_ci	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
581662306a36Sopenharmony_ci	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
581762306a36Sopenharmony_ci
581862306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
581962306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
582062306a36Sopenharmony_ci
582162306a36Sopenharmony_ci	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
582262306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
582362306a36Sopenharmony_ci
582462306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
582562306a36Sopenharmony_ci
582662306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
582762306a36Sopenharmony_ci
582862306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
582962306a36Sopenharmony_ci
583062306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
583162306a36Sopenharmony_ci
583262306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
583362306a36Sopenharmony_ci	fdiv.x		%fp1,%fp0		# last inst - possible exception set
583462306a36Sopenharmony_ci	bra		t_inx2
583562306a36Sopenharmony_ci
583662306a36Sopenharmony_ciNODD:
583762306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
583862306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# S = R*R
583962306a36Sopenharmony_ci
584062306a36Sopenharmony_ci	fmov.d		TANQ4(%pc),%fp3
584162306a36Sopenharmony_ci	fmov.d		TANP3(%pc),%fp2
584262306a36Sopenharmony_ci
584362306a36Sopenharmony_ci	fmul.x		%fp0,%fp3		# SQ4
584462306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# SP3
584562306a36Sopenharmony_ci
584662306a36Sopenharmony_ci	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
584762306a36Sopenharmony_ci	fadd.x		TANP2(%pc),%fp2		# P2+SP3
584862306a36Sopenharmony_ci
584962306a36Sopenharmony_ci	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
585062306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(P2+SP3)
585162306a36Sopenharmony_ci
585262306a36Sopenharmony_ci	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
585362306a36Sopenharmony_ci	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
585462306a36Sopenharmony_ci
585562306a36Sopenharmony_ci	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
585662306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
585762306a36Sopenharmony_ci
585862306a36Sopenharmony_ci	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
585962306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
586062306a36Sopenharmony_ci
586162306a36Sopenharmony_ci	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
586262306a36Sopenharmony_ci
586362306a36Sopenharmony_ci	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
586462306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
586562306a36Sopenharmony_ci
586662306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
586762306a36Sopenharmony_ci
586862306a36Sopenharmony_ci	fmov.x		%fp1,-(%sp)
586962306a36Sopenharmony_ci	eor.l		&0x80000000,(%sp)
587062306a36Sopenharmony_ci
587162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
587262306a36Sopenharmony_ci	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
587362306a36Sopenharmony_ci	bra		t_inx2
587462306a36Sopenharmony_ci
587562306a36Sopenharmony_ciTANBORS:
587662306a36Sopenharmony_ci#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
587762306a36Sopenharmony_ci#--IF |X| < 2**(-40), RETURN X OR 1.
587862306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
587962306a36Sopenharmony_ci	bgt.b		REDUCEX
588062306a36Sopenharmony_ci
588162306a36Sopenharmony_ciTANSM:
588262306a36Sopenharmony_ci	fmov.x		%fp0,-(%sp)
588362306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round mode,prec
588462306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
588562306a36Sopenharmony_ci	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
588662306a36Sopenharmony_ci	bra		t_catch
588762306a36Sopenharmony_ci
588862306a36Sopenharmony_ci	global		stand
588962306a36Sopenharmony_ci#--TAN(X) = X FOR DENORMALIZED X
589062306a36Sopenharmony_cistand:
589162306a36Sopenharmony_ci	bra		t_extdnrm
589262306a36Sopenharmony_ci
589362306a36Sopenharmony_ci#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
589462306a36Sopenharmony_ci#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
589562306a36Sopenharmony_ci#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
589662306a36Sopenharmony_ciREDUCEX:
589762306a36Sopenharmony_ci	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
589862306a36Sopenharmony_ci	mov.l		%d2,-(%sp)		# save d2
589962306a36Sopenharmony_ci	fmov.s		&0x00000000,%fp1	# fp1 = 0
590062306a36Sopenharmony_ci
590162306a36Sopenharmony_ci#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
590262306a36Sopenharmony_ci#--there is a danger of unwanted overflow in first LOOP iteration.  In this
590362306a36Sopenharmony_ci#--case, reduce argument by one remainder step to make subsequent reduction
590462306a36Sopenharmony_ci#--safe.
590562306a36Sopenharmony_ci	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
590662306a36Sopenharmony_ci	bne.b		LOOP			# no
590762306a36Sopenharmony_ci
590862306a36Sopenharmony_ci# yes; create 2**16383*PI/2
590962306a36Sopenharmony_ci	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
591062306a36Sopenharmony_ci	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
591162306a36Sopenharmony_ci	clr.l		FP_SCR0_LO(%a6)
591262306a36Sopenharmony_ci
591362306a36Sopenharmony_ci# create low half of 2**16383*PI/2 at FP_SCR1
591462306a36Sopenharmony_ci	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
591562306a36Sopenharmony_ci	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
591662306a36Sopenharmony_ci	clr.l		FP_SCR1_LO(%a6)
591762306a36Sopenharmony_ci
591862306a36Sopenharmony_ci	ftest.x		%fp0			# test sign of argument
591962306a36Sopenharmony_ci	fblt.w		red_neg
592062306a36Sopenharmony_ci
592162306a36Sopenharmony_ci	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
592262306a36Sopenharmony_ci	or.b		&0x80,FP_SCR1_EX(%a6)
592362306a36Sopenharmony_cired_neg:
592462306a36Sopenharmony_ci	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
592562306a36Sopenharmony_ci	fmov.x		%fp0,%fp1		# save high result in fp1
592662306a36Sopenharmony_ci	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
592762306a36Sopenharmony_ci	fsub.x		%fp0,%fp1		# determine low component of result
592862306a36Sopenharmony_ci	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
592962306a36Sopenharmony_ci
593062306a36Sopenharmony_ci#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
593162306a36Sopenharmony_ci#--integer quotient will be stored in N
593262306a36Sopenharmony_ci#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
593362306a36Sopenharmony_ciLOOP:
593462306a36Sopenharmony_ci	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
593562306a36Sopenharmony_ci	mov.w		INARG(%a6),%d1
593662306a36Sopenharmony_ci	mov.l		%d1,%a1			# save a copy of D0
593762306a36Sopenharmony_ci	and.l		&0x00007FFF,%d1
593862306a36Sopenharmony_ci	sub.l		&0x00003FFF,%d1		# d0 = K
593962306a36Sopenharmony_ci	cmp.l		%d1,&28
594062306a36Sopenharmony_ci	ble.b		LASTLOOP
594162306a36Sopenharmony_ciCONTLOOP:
594262306a36Sopenharmony_ci	sub.l		&27,%d1			# d0 = L := K-27
594362306a36Sopenharmony_ci	mov.b		&0,ENDFLAG(%a6)
594462306a36Sopenharmony_ci	bra.b		WORK
594562306a36Sopenharmony_ciLASTLOOP:
594662306a36Sopenharmony_ci	clr.l		%d1			# d0 = L := 0
594762306a36Sopenharmony_ci	mov.b		&1,ENDFLAG(%a6)
594862306a36Sopenharmony_ci
594962306a36Sopenharmony_ciWORK:
595062306a36Sopenharmony_ci#--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
595162306a36Sopenharmony_ci#--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
595262306a36Sopenharmony_ci
595362306a36Sopenharmony_ci#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
595462306a36Sopenharmony_ci#--2**L * (PIby2_1), 2**L * (PIby2_2)
595562306a36Sopenharmony_ci
595662306a36Sopenharmony_ci	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
595762306a36Sopenharmony_ci	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
595862306a36Sopenharmony_ci
595962306a36Sopenharmony_ci	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
596062306a36Sopenharmony_ci	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
596162306a36Sopenharmony_ci	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
596262306a36Sopenharmony_ci
596362306a36Sopenharmony_ci	fmov.x		%fp0,%fp2
596462306a36Sopenharmony_ci	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
596562306a36Sopenharmony_ci
596662306a36Sopenharmony_ci#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
596762306a36Sopenharmony_ci#--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
596862306a36Sopenharmony_ci#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
596962306a36Sopenharmony_ci#--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
597062306a36Sopenharmony_ci#--US THE DESIRED VALUE IN FLOATING POINT.
597162306a36Sopenharmony_ci	mov.l		%a1,%d2
597262306a36Sopenharmony_ci	swap		%d2
597362306a36Sopenharmony_ci	and.l		&0x80000000,%d2
597462306a36Sopenharmony_ci	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
597562306a36Sopenharmony_ci	mov.l		%d2,TWOTO63(%a6)
597662306a36Sopenharmony_ci	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
597762306a36Sopenharmony_ci	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
597862306a36Sopenharmony_ci#	fintrz.x	%fp2,%fp2
597962306a36Sopenharmony_ci
598062306a36Sopenharmony_ci#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
598162306a36Sopenharmony_ci	mov.l		%d1,%d2			# d2 = L
598262306a36Sopenharmony_ci
598362306a36Sopenharmony_ci	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
598462306a36Sopenharmony_ci	mov.w		%d2,FP_SCR0_EX(%a6)
598562306a36Sopenharmony_ci	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
598662306a36Sopenharmony_ci	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
598762306a36Sopenharmony_ci
598862306a36Sopenharmony_ci	add.l		&0x00003FDD,%d1
598962306a36Sopenharmony_ci	mov.w		%d1,FP_SCR1_EX(%a6)
599062306a36Sopenharmony_ci	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
599162306a36Sopenharmony_ci	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
599262306a36Sopenharmony_ci
599362306a36Sopenharmony_ci	mov.b		ENDFLAG(%a6),%d1
599462306a36Sopenharmony_ci
599562306a36Sopenharmony_ci#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
599662306a36Sopenharmony_ci#--P2 = 2**(L) * Piby2_2
599762306a36Sopenharmony_ci	fmov.x		%fp2,%fp4		# fp4 = N
599862306a36Sopenharmony_ci	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
599962306a36Sopenharmony_ci	fmov.x		%fp2,%fp5		# fp5 = N
600062306a36Sopenharmony_ci	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
600162306a36Sopenharmony_ci	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
600262306a36Sopenharmony_ci
600362306a36Sopenharmony_ci#--we want P+p = W+w  but  |p| <= half ulp of P
600462306a36Sopenharmony_ci#--Then, we need to compute  A := R-P   and  a := r-p
600562306a36Sopenharmony_ci	fadd.x		%fp5,%fp3		# fp3 = P
600662306a36Sopenharmony_ci	fsub.x		%fp3,%fp4		# fp4 = W-P
600762306a36Sopenharmony_ci
600862306a36Sopenharmony_ci	fsub.x		%fp3,%fp0		# fp0 = A := R - P
600962306a36Sopenharmony_ci	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
601062306a36Sopenharmony_ci
601162306a36Sopenharmony_ci	fmov.x		%fp0,%fp3		# fp3 = A
601262306a36Sopenharmony_ci	fsub.x		%fp4,%fp1		# fp1 = a := r - p
601362306a36Sopenharmony_ci
601462306a36Sopenharmony_ci#--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
601562306a36Sopenharmony_ci#--|r| <= half ulp of R.
601662306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# fp0 = R := A+a
601762306a36Sopenharmony_ci#--No need to calculate r if this is the last loop
601862306a36Sopenharmony_ci	cmp.b		%d1,&0
601962306a36Sopenharmony_ci	bgt.w		RESTORE
602062306a36Sopenharmony_ci
602162306a36Sopenharmony_ci#--Need to calculate r
602262306a36Sopenharmony_ci	fsub.x		%fp0,%fp3		# fp3 = A-R
602362306a36Sopenharmony_ci	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
602462306a36Sopenharmony_ci	bra.w		LOOP
602562306a36Sopenharmony_ci
602662306a36Sopenharmony_ciRESTORE:
602762306a36Sopenharmony_ci	fmov.l		%fp2,INT(%a6)
602862306a36Sopenharmony_ci	mov.l		(%sp)+,%d2		# restore d2
602962306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
603062306a36Sopenharmony_ci
603162306a36Sopenharmony_ci	mov.l		INT(%a6),%d1
603262306a36Sopenharmony_ci	ror.l		&1,%d1
603362306a36Sopenharmony_ci
603462306a36Sopenharmony_ci	bra.w		TANCONT
603562306a36Sopenharmony_ci
603662306a36Sopenharmony_ci#########################################################################
603762306a36Sopenharmony_ci# satan():  computes the arctangent of a normalized number		#
603862306a36Sopenharmony_ci# satand(): computes the arctangent of a denormalized number		#
603962306a36Sopenharmony_ci#									#
604062306a36Sopenharmony_ci# INPUT	*************************************************************** #
604162306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
604262306a36Sopenharmony_ci#	d0 = round precision,mode					#
604362306a36Sopenharmony_ci#									#
604462306a36Sopenharmony_ci# OUTPUT ************************************************************** #
604562306a36Sopenharmony_ci#	fp0 = arctan(X)							#
604662306a36Sopenharmony_ci#									#
604762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* #
604862306a36Sopenharmony_ci#	The returned result is within 2 ulps in	64 significant bit,	#
604962306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
605062306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
605162306a36Sopenharmony_ci#	in double precision.						#
605262306a36Sopenharmony_ci#									#
605362306a36Sopenharmony_ci# ALGORITHM *********************************************************** #
605462306a36Sopenharmony_ci#	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
605562306a36Sopenharmony_ci#									#
605662306a36Sopenharmony_ci#	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x.			#
605762306a36Sopenharmony_ci#		Note that k = -4, -3,..., or 3.				#
605862306a36Sopenharmony_ci#		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5	#
605962306a36Sopenharmony_ci#		significant bits of X with a bit-1 attached at the 6-th	#
606062306a36Sopenharmony_ci#		bit position. Define u to be u = (X-F) / (1 + X*F).	#
606162306a36Sopenharmony_ci#									#
606262306a36Sopenharmony_ci#	Step 3. Approximate arctan(u) by a polynomial poly.		#
606362306a36Sopenharmony_ci#									#
606462306a36Sopenharmony_ci#	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a	#
606562306a36Sopenharmony_ci#		table of values calculated beforehand. Exit.		#
606662306a36Sopenharmony_ci#									#
606762306a36Sopenharmony_ci#	Step 5. If |X| >= 16, go to Step 7.				#
606862306a36Sopenharmony_ci#									#
606962306a36Sopenharmony_ci#	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
607062306a36Sopenharmony_ci#									#
607162306a36Sopenharmony_ci#	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd	#
607262306a36Sopenharmony_ci#		polynomial in X'.					#
607362306a36Sopenharmony_ci#		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
607462306a36Sopenharmony_ci#									#
607562306a36Sopenharmony_ci#########################################################################
607662306a36Sopenharmony_ci
607762306a36Sopenharmony_ciATANA3:	long		0xBFF6687E,0x314987D8
607862306a36Sopenharmony_ciATANA2:	long		0x4002AC69,0x34A26DB3
607962306a36Sopenharmony_ciATANA1:	long		0xBFC2476F,0x4E1DA28E
608062306a36Sopenharmony_ci
608162306a36Sopenharmony_ciATANB6:	long		0x3FB34444,0x7F876989
608262306a36Sopenharmony_ciATANB5:	long		0xBFB744EE,0x7FAF45DB
608362306a36Sopenharmony_ciATANB4:	long		0x3FBC71C6,0x46940220
608462306a36Sopenharmony_ciATANB3:	long		0xBFC24924,0x921872F9
608562306a36Sopenharmony_ciATANB2:	long		0x3FC99999,0x99998FA9
608662306a36Sopenharmony_ciATANB1:	long		0xBFD55555,0x55555555
608762306a36Sopenharmony_ci
608862306a36Sopenharmony_ciATANC5:	long		0xBFB70BF3,0x98539E6A
608962306a36Sopenharmony_ciATANC4:	long		0x3FBC7187,0x962D1D7D
609062306a36Sopenharmony_ciATANC3:	long		0xBFC24924,0x827107B8
609162306a36Sopenharmony_ciATANC2:	long		0x3FC99999,0x9996263E
609262306a36Sopenharmony_ciATANC1:	long		0xBFD55555,0x55555536
609362306a36Sopenharmony_ci
609462306a36Sopenharmony_ciPPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
609562306a36Sopenharmony_ciNPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
609662306a36Sopenharmony_ci
609762306a36Sopenharmony_ciPTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
609862306a36Sopenharmony_ciNTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
609962306a36Sopenharmony_ci
610062306a36Sopenharmony_ciATANTBL:
610162306a36Sopenharmony_ci	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
610262306a36Sopenharmony_ci	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
610362306a36Sopenharmony_ci	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
610462306a36Sopenharmony_ci	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
610562306a36Sopenharmony_ci	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
610662306a36Sopenharmony_ci	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
610762306a36Sopenharmony_ci	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
610862306a36Sopenharmony_ci	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
610962306a36Sopenharmony_ci	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
611062306a36Sopenharmony_ci	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
611162306a36Sopenharmony_ci	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
611262306a36Sopenharmony_ci	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
611362306a36Sopenharmony_ci	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
611462306a36Sopenharmony_ci	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
611562306a36Sopenharmony_ci	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
611662306a36Sopenharmony_ci	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
611762306a36Sopenharmony_ci	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
611862306a36Sopenharmony_ci	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
611962306a36Sopenharmony_ci	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
612062306a36Sopenharmony_ci	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
612162306a36Sopenharmony_ci	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
612262306a36Sopenharmony_ci	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
612362306a36Sopenharmony_ci	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
612462306a36Sopenharmony_ci	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
612562306a36Sopenharmony_ci	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
612662306a36Sopenharmony_ci	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
612762306a36Sopenharmony_ci	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
612862306a36Sopenharmony_ci	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
612962306a36Sopenharmony_ci	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
613062306a36Sopenharmony_ci	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
613162306a36Sopenharmony_ci	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
613262306a36Sopenharmony_ci	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
613362306a36Sopenharmony_ci	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
613462306a36Sopenharmony_ci	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
613562306a36Sopenharmony_ci	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
613662306a36Sopenharmony_ci	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
613762306a36Sopenharmony_ci	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
613862306a36Sopenharmony_ci	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
613962306a36Sopenharmony_ci	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
614062306a36Sopenharmony_ci	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
614162306a36Sopenharmony_ci	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
614262306a36Sopenharmony_ci	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
614362306a36Sopenharmony_ci	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
614462306a36Sopenharmony_ci	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
614562306a36Sopenharmony_ci	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
614662306a36Sopenharmony_ci	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
614762306a36Sopenharmony_ci	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
614862306a36Sopenharmony_ci	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
614962306a36Sopenharmony_ci	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
615062306a36Sopenharmony_ci	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
615162306a36Sopenharmony_ci	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
615262306a36Sopenharmony_ci	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
615362306a36Sopenharmony_ci	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
615462306a36Sopenharmony_ci	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
615562306a36Sopenharmony_ci	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
615662306a36Sopenharmony_ci	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
615762306a36Sopenharmony_ci	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
615862306a36Sopenharmony_ci	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
615962306a36Sopenharmony_ci	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
616062306a36Sopenharmony_ci	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
616162306a36Sopenharmony_ci	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
616262306a36Sopenharmony_ci	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
616362306a36Sopenharmony_ci	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
616462306a36Sopenharmony_ci	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
616562306a36Sopenharmony_ci	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
616662306a36Sopenharmony_ci	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
616762306a36Sopenharmony_ci	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
616862306a36Sopenharmony_ci	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
616962306a36Sopenharmony_ci	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
617062306a36Sopenharmony_ci	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
617162306a36Sopenharmony_ci	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
617262306a36Sopenharmony_ci	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
617362306a36Sopenharmony_ci	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
617462306a36Sopenharmony_ci	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
617562306a36Sopenharmony_ci	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
617662306a36Sopenharmony_ci	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
617762306a36Sopenharmony_ci	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
617862306a36Sopenharmony_ci	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
617962306a36Sopenharmony_ci	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
618062306a36Sopenharmony_ci	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
618162306a36Sopenharmony_ci	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
618262306a36Sopenharmony_ci	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
618362306a36Sopenharmony_ci	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
618462306a36Sopenharmony_ci	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
618562306a36Sopenharmony_ci	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
618662306a36Sopenharmony_ci	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
618762306a36Sopenharmony_ci	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
618862306a36Sopenharmony_ci	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
618962306a36Sopenharmony_ci	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
619062306a36Sopenharmony_ci	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
619162306a36Sopenharmony_ci	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
619262306a36Sopenharmony_ci	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
619362306a36Sopenharmony_ci	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
619462306a36Sopenharmony_ci	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
619562306a36Sopenharmony_ci	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
619662306a36Sopenharmony_ci	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
619762306a36Sopenharmony_ci	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
619862306a36Sopenharmony_ci	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
619962306a36Sopenharmony_ci	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
620062306a36Sopenharmony_ci	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
620162306a36Sopenharmony_ci	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
620262306a36Sopenharmony_ci	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
620362306a36Sopenharmony_ci	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
620462306a36Sopenharmony_ci	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
620562306a36Sopenharmony_ci	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
620662306a36Sopenharmony_ci	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
620762306a36Sopenharmony_ci	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
620862306a36Sopenharmony_ci	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
620962306a36Sopenharmony_ci	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
621062306a36Sopenharmony_ci	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
621162306a36Sopenharmony_ci	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
621262306a36Sopenharmony_ci	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
621362306a36Sopenharmony_ci	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
621462306a36Sopenharmony_ci	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
621562306a36Sopenharmony_ci	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
621662306a36Sopenharmony_ci	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
621762306a36Sopenharmony_ci	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
621862306a36Sopenharmony_ci	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
621962306a36Sopenharmony_ci	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
622062306a36Sopenharmony_ci	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
622162306a36Sopenharmony_ci	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
622262306a36Sopenharmony_ci	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
622362306a36Sopenharmony_ci	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
622462306a36Sopenharmony_ci	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
622562306a36Sopenharmony_ci	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
622662306a36Sopenharmony_ci	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
622762306a36Sopenharmony_ci	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
622862306a36Sopenharmony_ci	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
622962306a36Sopenharmony_ci
623062306a36Sopenharmony_ci	set		X,FP_SCR0
623162306a36Sopenharmony_ci	set		XDCARE,X+2
623262306a36Sopenharmony_ci	set		XFRAC,X+4
623362306a36Sopenharmony_ci	set		XFRACLO,X+8
623462306a36Sopenharmony_ci
623562306a36Sopenharmony_ci	set		ATANF,FP_SCR1
623662306a36Sopenharmony_ci	set		ATANFHI,ATANF+4
623762306a36Sopenharmony_ci	set		ATANFLO,ATANF+8
623862306a36Sopenharmony_ci
623962306a36Sopenharmony_ci	global		satan
624062306a36Sopenharmony_ci#--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
624162306a36Sopenharmony_cisatan:
624262306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
624362306a36Sopenharmony_ci
624462306a36Sopenharmony_ci	mov.l		(%a0),%d1
624562306a36Sopenharmony_ci	mov.w		4(%a0),%d1
624662306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)
624762306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
624862306a36Sopenharmony_ci
624962306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
625062306a36Sopenharmony_ci	bge.b		ATANOK1
625162306a36Sopenharmony_ci	bra.w		ATANSM
625262306a36Sopenharmony_ci
625362306a36Sopenharmony_ciATANOK1:
625462306a36Sopenharmony_ci	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
625562306a36Sopenharmony_ci	ble.b		ATANMAIN
625662306a36Sopenharmony_ci	bra.w		ATANBIG
625762306a36Sopenharmony_ci
625862306a36Sopenharmony_ci#--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
625962306a36Sopenharmony_ci#--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
626062306a36Sopenharmony_ci#--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
626162306a36Sopenharmony_ci#--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
626262306a36Sopenharmony_ci#--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
626362306a36Sopenharmony_ci#--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
626462306a36Sopenharmony_ci#--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
626562306a36Sopenharmony_ci#--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
626662306a36Sopenharmony_ci#--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
626762306a36Sopenharmony_ci#--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
626862306a36Sopenharmony_ci#--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
626962306a36Sopenharmony_ci#--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
627062306a36Sopenharmony_ci#--WILL INVOLVE A VERY LONG POLYNOMIAL.
627162306a36Sopenharmony_ci
627262306a36Sopenharmony_ci#--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
627362306a36Sopenharmony_ci#--WE CHOSE F TO BE +-2^K * 1.BBBB1
627462306a36Sopenharmony_ci#--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
627562306a36Sopenharmony_ci#--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
627662306a36Sopenharmony_ci#--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
627762306a36Sopenharmony_ci#-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
627862306a36Sopenharmony_ci
627962306a36Sopenharmony_ciATANMAIN:
628062306a36Sopenharmony_ci
628162306a36Sopenharmony_ci	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
628262306a36Sopenharmony_ci	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
628362306a36Sopenharmony_ci	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
628462306a36Sopenharmony_ci
628562306a36Sopenharmony_ci	fmov.x		%fp0,%fp1		# FP1 IS X
628662306a36Sopenharmony_ci	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
628762306a36Sopenharmony_ci	fsub.x		X(%a6),%fp0		# FP0 IS X-F
628862306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
628962306a36Sopenharmony_ci	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
629062306a36Sopenharmony_ci
629162306a36Sopenharmony_ci#--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
629262306a36Sopenharmony_ci#--CREATE ATAN(F) AND STORE IT IN ATANF, AND
629362306a36Sopenharmony_ci#--SAVE REGISTERS FP2.
629462306a36Sopenharmony_ci
629562306a36Sopenharmony_ci	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
629662306a36Sopenharmony_ci	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
629762306a36Sopenharmony_ci	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
629862306a36Sopenharmony_ci	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
629962306a36Sopenharmony_ci	sub.l		&0x3FFB0000,%d2		# K+4
630062306a36Sopenharmony_ci	asr.l		&1,%d2
630162306a36Sopenharmony_ci	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
630262306a36Sopenharmony_ci	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
630362306a36Sopenharmony_ci	lea		ATANTBL(%pc),%a1
630462306a36Sopenharmony_ci	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
630562306a36Sopenharmony_ci	mov.l		(%a1)+,ATANF(%a6)
630662306a36Sopenharmony_ci	mov.l		(%a1)+,ATANFHI(%a6)
630762306a36Sopenharmony_ci	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
630862306a36Sopenharmony_ci	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
630962306a36Sopenharmony_ci	and.l		&0x80000000,%d1		# SIGN(F)
631062306a36Sopenharmony_ci	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
631162306a36Sopenharmony_ci	mov.l		(%sp)+,%d2		# RESTORE d2
631262306a36Sopenharmony_ci
631362306a36Sopenharmony_ci#--THAT'S ALL I HAVE TO DO FOR NOW,
631462306a36Sopenharmony_ci#--BUT ALAS, THE DIVIDE IS STILL CRANKING!
631562306a36Sopenharmony_ci
631662306a36Sopenharmony_ci#--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
631762306a36Sopenharmony_ci#--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
631862306a36Sopenharmony_ci#--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
631962306a36Sopenharmony_ci#--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
632062306a36Sopenharmony_ci#--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
632162306a36Sopenharmony_ci#--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
632262306a36Sopenharmony_ci#--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
632362306a36Sopenharmony_ci
632462306a36Sopenharmony_ci	fmovm.x		&0x04,-(%sp)		# save fp2
632562306a36Sopenharmony_ci
632662306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
632762306a36Sopenharmony_ci	fmul.x		%fp1,%fp1
632862306a36Sopenharmony_ci	fmov.d		ATANA3(%pc),%fp2
632962306a36Sopenharmony_ci	fadd.x		%fp1,%fp2		# A3+V
633062306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# V*(A3+V)
633162306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# U*V
633262306a36Sopenharmony_ci	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
633362306a36Sopenharmony_ci	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
633462306a36Sopenharmony_ci	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
633562306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
633662306a36Sopenharmony_ci
633762306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x20		# restore fp2
633862306a36Sopenharmony_ci
633962306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
634062306a36Sopenharmony_ci	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
634162306a36Sopenharmony_ci	bra		t_inx2
634262306a36Sopenharmony_ci
634362306a36Sopenharmony_ciATANBORS:
634462306a36Sopenharmony_ci#--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
634562306a36Sopenharmony_ci#--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
634662306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
634762306a36Sopenharmony_ci	bgt.w		ATANBIG			# I.E. |X| >= 16
634862306a36Sopenharmony_ci
634962306a36Sopenharmony_ciATANSM:
635062306a36Sopenharmony_ci#--|X| <= 1/16
635162306a36Sopenharmony_ci#--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
635262306a36Sopenharmony_ci#--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
635362306a36Sopenharmony_ci#--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
635462306a36Sopenharmony_ci#--WHERE Y = X*X, AND Z = Y*Y.
635562306a36Sopenharmony_ci
635662306a36Sopenharmony_ci	cmp.l		%d1,&0x3FD78000
635762306a36Sopenharmony_ci	blt.w		ATANTINY
635862306a36Sopenharmony_ci
635962306a36Sopenharmony_ci#--COMPUTE POLYNOMIAL
636062306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
636162306a36Sopenharmony_ci
636262306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
636362306a36Sopenharmony_ci
636462306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
636562306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
636662306a36Sopenharmony_ci
636762306a36Sopenharmony_ci	fmov.d		ATANB6(%pc),%fp2
636862306a36Sopenharmony_ci	fmov.d		ATANB5(%pc),%fp3
636962306a36Sopenharmony_ci
637062306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# Z*B6
637162306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# Z*B5
637262306a36Sopenharmony_ci
637362306a36Sopenharmony_ci	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
637462306a36Sopenharmony_ci	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
637562306a36Sopenharmony_ci
637662306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
637762306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
637862306a36Sopenharmony_ci
637962306a36Sopenharmony_ci	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
638062306a36Sopenharmony_ci	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
638162306a36Sopenharmony_ci
638262306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
638362306a36Sopenharmony_ci	fmul.x		X(%a6),%fp0		# X*Y
638462306a36Sopenharmony_ci
638562306a36Sopenharmony_ci	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
638662306a36Sopenharmony_ci
638762306a36Sopenharmony_ci	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
638862306a36Sopenharmony_ci
638962306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
639062306a36Sopenharmony_ci
639162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
639262306a36Sopenharmony_ci	fadd.x		X(%a6),%fp0
639362306a36Sopenharmony_ci	bra		t_inx2
639462306a36Sopenharmony_ci
639562306a36Sopenharmony_ciATANTINY:
639662306a36Sopenharmony_ci#--|X| < 2^(-40), ATAN(X) = X
639762306a36Sopenharmony_ci
639862306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
639962306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
640062306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0		# last inst - possible exception set
640162306a36Sopenharmony_ci
640262306a36Sopenharmony_ci	bra		t_catch
640362306a36Sopenharmony_ci
640462306a36Sopenharmony_ciATANBIG:
640562306a36Sopenharmony_ci#--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
640662306a36Sopenharmony_ci#--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
640762306a36Sopenharmony_ci	cmp.l		%d1,&0x40638000
640862306a36Sopenharmony_ci	bgt.w		ATANHUGE
640962306a36Sopenharmony_ci
641062306a36Sopenharmony_ci#--APPROXIMATE ATAN(-1/X) BY
641162306a36Sopenharmony_ci#--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
641262306a36Sopenharmony_ci#--THIS CAN BE RE-WRITTEN AS
641362306a36Sopenharmony_ci#--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
641462306a36Sopenharmony_ci
641562306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
641662306a36Sopenharmony_ci
641762306a36Sopenharmony_ci	fmov.s		&0xBF800000,%fp1	# LOAD -1
641862306a36Sopenharmony_ci	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
641962306a36Sopenharmony_ci
642062306a36Sopenharmony_ci#--DIVIDE IS STILL CRANKING
642162306a36Sopenharmony_ci
642262306a36Sopenharmony_ci	fmov.x		%fp1,%fp0		# FP0 IS X'
642362306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
642462306a36Sopenharmony_ci	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
642562306a36Sopenharmony_ci
642662306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
642762306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
642862306a36Sopenharmony_ci
642962306a36Sopenharmony_ci	fmov.d		ATANC5(%pc),%fp3
643062306a36Sopenharmony_ci	fmov.d		ATANC4(%pc),%fp2
643162306a36Sopenharmony_ci
643262306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# Z*C5
643362306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# Z*B4
643462306a36Sopenharmony_ci
643562306a36Sopenharmony_ci	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
643662306a36Sopenharmony_ci	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
643762306a36Sopenharmony_ci
643862306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
643962306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
644062306a36Sopenharmony_ci
644162306a36Sopenharmony_ci	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
644262306a36Sopenharmony_ci	fmul.x		X(%a6),%fp0		# X'*Y
644362306a36Sopenharmony_ci
644462306a36Sopenharmony_ci	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
644562306a36Sopenharmony_ci
644662306a36Sopenharmony_ci	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
644762306a36Sopenharmony_ci#					...	+[Y*(B2+Z*(B4+Z*B6))])
644862306a36Sopenharmony_ci	fadd.x		X(%a6),%fp0
644962306a36Sopenharmony_ci
645062306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
645162306a36Sopenharmony_ci
645262306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
645362306a36Sopenharmony_ci	tst.b		(%a0)
645462306a36Sopenharmony_ci	bpl.b		pos_big
645562306a36Sopenharmony_ci
645662306a36Sopenharmony_cineg_big:
645762306a36Sopenharmony_ci	fadd.x		NPIBY2(%pc),%fp0
645862306a36Sopenharmony_ci	bra		t_minx2
645962306a36Sopenharmony_ci
646062306a36Sopenharmony_cipos_big:
646162306a36Sopenharmony_ci	fadd.x		PPIBY2(%pc),%fp0
646262306a36Sopenharmony_ci	bra		t_pinx2
646362306a36Sopenharmony_ci
646462306a36Sopenharmony_ciATANHUGE:
646562306a36Sopenharmony_ci#--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
646662306a36Sopenharmony_ci	tst.b		(%a0)
646762306a36Sopenharmony_ci	bpl.b		pos_huge
646862306a36Sopenharmony_ci
646962306a36Sopenharmony_cineg_huge:
647062306a36Sopenharmony_ci	fmov.x		NPIBY2(%pc),%fp0
647162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
647262306a36Sopenharmony_ci	fadd.x		PTINY(%pc),%fp0
647362306a36Sopenharmony_ci	bra		t_minx2
647462306a36Sopenharmony_ci
647562306a36Sopenharmony_cipos_huge:
647662306a36Sopenharmony_ci	fmov.x		PPIBY2(%pc),%fp0
647762306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
647862306a36Sopenharmony_ci	fadd.x		NTINY(%pc),%fp0
647962306a36Sopenharmony_ci	bra		t_pinx2
648062306a36Sopenharmony_ci
648162306a36Sopenharmony_ci	global		satand
648262306a36Sopenharmony_ci#--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
648362306a36Sopenharmony_cisatand:
648462306a36Sopenharmony_ci	bra		t_extdnrm
648562306a36Sopenharmony_ci
648662306a36Sopenharmony_ci#########################################################################
648762306a36Sopenharmony_ci# sasin():  computes the inverse sine of a normalized input		#
648862306a36Sopenharmony_ci# sasind(): computes the inverse sine of a denormalized input		#
648962306a36Sopenharmony_ci#									#
649062306a36Sopenharmony_ci# INPUT ***************************************************************	#
649162306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
649262306a36Sopenharmony_ci#	d0 = round precision,mode					#
649362306a36Sopenharmony_ci#									#
649462306a36Sopenharmony_ci# OUTPUT **************************************************************	#
649562306a36Sopenharmony_ci#	fp0 = arcsin(X)							#
649662306a36Sopenharmony_ci#									#
649762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
649862306a36Sopenharmony_ci#	The returned result is within 3 ulps in	64 significant bit,	#
649962306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
650062306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
650162306a36Sopenharmony_ci#	in double precision.						#
650262306a36Sopenharmony_ci#									#
650362306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
650462306a36Sopenharmony_ci#									#
650562306a36Sopenharmony_ci#	ASIN								#
650662306a36Sopenharmony_ci#	1. If |X| >= 1, go to 3.					#
650762306a36Sopenharmony_ci#									#
650862306a36Sopenharmony_ci#	2. (|X| < 1) Calculate asin(X) by				#
650962306a36Sopenharmony_ci#		z := sqrt( [1-X][1+X] )					#
651062306a36Sopenharmony_ci#		asin(X) = atan( x / z ).				#
651162306a36Sopenharmony_ci#		Exit.							#
651262306a36Sopenharmony_ci#									#
651362306a36Sopenharmony_ci#	3. If |X| > 1, go to 5.						#
651462306a36Sopenharmony_ci#									#
651562306a36Sopenharmony_ci#	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
651662306a36Sopenharmony_ci#									#
651762306a36Sopenharmony_ci#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
651862306a36Sopenharmony_ci#		Exit.							#
651962306a36Sopenharmony_ci#									#
652062306a36Sopenharmony_ci#########################################################################
652162306a36Sopenharmony_ci
652262306a36Sopenharmony_ci	global		sasin
652362306a36Sopenharmony_cisasin:
652462306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
652562306a36Sopenharmony_ci
652662306a36Sopenharmony_ci	mov.l		(%a0),%d1
652762306a36Sopenharmony_ci	mov.w		4(%a0),%d1
652862306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
652962306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
653062306a36Sopenharmony_ci	bge.b		ASINBIG
653162306a36Sopenharmony_ci
653262306a36Sopenharmony_ci# This catch is added here for the '060 QSP. Originally, the call to
653362306a36Sopenharmony_ci# satan() would handle this case by causing the exception which would
653462306a36Sopenharmony_ci# not be caught until gen_except(). Now, with the exceptions being
653562306a36Sopenharmony_ci# detected inside of satan(), the exception would have been handled there
653662306a36Sopenharmony_ci# instead of inside sasin() as expected.
653762306a36Sopenharmony_ci	cmp.l		%d1,&0x3FD78000
653862306a36Sopenharmony_ci	blt.w		ASINTINY
653962306a36Sopenharmony_ci
654062306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 1
654162306a36Sopenharmony_ci#--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
654262306a36Sopenharmony_ci
654362306a36Sopenharmony_ciASINMAIN:
654462306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp1
654562306a36Sopenharmony_ci	fsub.x		%fp0,%fp1		# 1-X
654662306a36Sopenharmony_ci	fmovm.x		&0x4,-(%sp)		#  {fp2}
654762306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp2
654862306a36Sopenharmony_ci	fadd.x		%fp0,%fp2		# 1+X
654962306a36Sopenharmony_ci	fmul.x		%fp2,%fp1		# (1+X)(1-X)
655062306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x20		#  {fp2}
655162306a36Sopenharmony_ci	fsqrt.x		%fp1			# SQRT([1-X][1+X])
655262306a36Sopenharmony_ci	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
655362306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
655462306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
655562306a36Sopenharmony_ci	bsr		satan
655662306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
655762306a36Sopenharmony_ci	bra		t_inx2
655862306a36Sopenharmony_ci
655962306a36Sopenharmony_ciASINBIG:
656062306a36Sopenharmony_ci	fabs.x		%fp0			# |X|
656162306a36Sopenharmony_ci	fcmp.s		%fp0,&0x3F800000
656262306a36Sopenharmony_ci	fbgt		t_operr			# cause an operr exception
656362306a36Sopenharmony_ci
656462306a36Sopenharmony_ci#--|X| = 1, ASIN(X) = +- PI/2.
656562306a36Sopenharmony_ciASINONE:
656662306a36Sopenharmony_ci	fmov.x		PIBY2(%pc),%fp0
656762306a36Sopenharmony_ci	mov.l		(%a0),%d1
656862306a36Sopenharmony_ci	and.l		&0x80000000,%d1		# SIGN BIT OF X
656962306a36Sopenharmony_ci	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
657062306a36Sopenharmony_ci	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
657162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
657262306a36Sopenharmony_ci	fmul.s		(%sp)+,%fp0
657362306a36Sopenharmony_ci	bra		t_inx2
657462306a36Sopenharmony_ci
657562306a36Sopenharmony_ci#--|X| < 2^(-40), ATAN(X) = X
657662306a36Sopenharmony_ciASINTINY:
657762306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
657862306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
657962306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# last inst - possible exception
658062306a36Sopenharmony_ci	bra		t_catch
658162306a36Sopenharmony_ci
658262306a36Sopenharmony_ci	global		sasind
658362306a36Sopenharmony_ci#--ASIN(X) = X FOR DENORMALIZED X
658462306a36Sopenharmony_cisasind:
658562306a36Sopenharmony_ci	bra		t_extdnrm
658662306a36Sopenharmony_ci
658762306a36Sopenharmony_ci#########################################################################
658862306a36Sopenharmony_ci# sacos():  computes the inverse cosine of a normalized input		#
658962306a36Sopenharmony_ci# sacosd(): computes the inverse cosine of a denormalized input		#
659062306a36Sopenharmony_ci#									#
659162306a36Sopenharmony_ci# INPUT ***************************************************************	#
659262306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
659362306a36Sopenharmony_ci#	d0 = round precision,mode					#
659462306a36Sopenharmony_ci#									#
659562306a36Sopenharmony_ci# OUTPUT ************************************************************** #
659662306a36Sopenharmony_ci#	fp0 = arccos(X)							#
659762306a36Sopenharmony_ci#									#
659862306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
659962306a36Sopenharmony_ci#	The returned result is within 3 ulps in	64 significant bit,	#
660062306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
660162306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
660262306a36Sopenharmony_ci#	in double precision.						#
660362306a36Sopenharmony_ci#									#
660462306a36Sopenharmony_ci# ALGORITHM *********************************************************** #
660562306a36Sopenharmony_ci#									#
660662306a36Sopenharmony_ci#	ACOS								#
660762306a36Sopenharmony_ci#	1. If |X| >= 1, go to 3.					#
660862306a36Sopenharmony_ci#									#
660962306a36Sopenharmony_ci#	2. (|X| < 1) Calculate acos(X) by				#
661062306a36Sopenharmony_ci#		z := (1-X) / (1+X)					#
661162306a36Sopenharmony_ci#		acos(X) = 2 * atan( sqrt(z) ).				#
661262306a36Sopenharmony_ci#		Exit.							#
661362306a36Sopenharmony_ci#									#
661462306a36Sopenharmony_ci#	3. If |X| > 1, go to 5.						#
661562306a36Sopenharmony_ci#									#
661662306a36Sopenharmony_ci#	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
661762306a36Sopenharmony_ci#									#
661862306a36Sopenharmony_ci#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
661962306a36Sopenharmony_ci#		Exit.							#
662062306a36Sopenharmony_ci#									#
662162306a36Sopenharmony_ci#########################################################################
662262306a36Sopenharmony_ci
662362306a36Sopenharmony_ci	global		sacos
662462306a36Sopenharmony_cisacos:
662562306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
662662306a36Sopenharmony_ci
662762306a36Sopenharmony_ci	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
662862306a36Sopenharmony_ci	mov.w		4(%a0),%d1
662962306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
663062306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
663162306a36Sopenharmony_ci	bge.b		ACOSBIG
663262306a36Sopenharmony_ci
663362306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 1
663462306a36Sopenharmony_ci#--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
663562306a36Sopenharmony_ci
663662306a36Sopenharmony_ciACOSMAIN:
663762306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp1
663862306a36Sopenharmony_ci	fadd.x		%fp0,%fp1		# 1+X
663962306a36Sopenharmony_ci	fneg.x		%fp0			# -X
664062306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp0	# 1-X
664162306a36Sopenharmony_ci	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
664262306a36Sopenharmony_ci	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
664362306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save original users fpcr
664462306a36Sopenharmony_ci	clr.l		%d0
664562306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
664662306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to sqrt
664762306a36Sopenharmony_ci	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
664862306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear SQRT(...) from stack
664962306a36Sopenharmony_ci
665062306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
665162306a36Sopenharmony_ci	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
665262306a36Sopenharmony_ci	bra		t_pinx2
665362306a36Sopenharmony_ci
665462306a36Sopenharmony_ciACOSBIG:
665562306a36Sopenharmony_ci	fabs.x		%fp0
665662306a36Sopenharmony_ci	fcmp.s		%fp0,&0x3F800000
665762306a36Sopenharmony_ci	fbgt		t_operr			# cause an operr exception
665862306a36Sopenharmony_ci
665962306a36Sopenharmony_ci#--|X| = 1, ACOS(X) = 0 OR PI
666062306a36Sopenharmony_ci	tst.b		(%a0)			# is X positive or negative?
666162306a36Sopenharmony_ci	bpl.b		ACOSP1
666262306a36Sopenharmony_ci
666362306a36Sopenharmony_ci#--X = -1
666462306a36Sopenharmony_ci#Returns PI and inexact exception
666562306a36Sopenharmony_ciACOSM1:
666662306a36Sopenharmony_ci	fmov.x		PI(%pc),%fp0		# load PI
666762306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# load round mode,prec
666862306a36Sopenharmony_ci	fadd.s		&0x00800000,%fp0	# add a small value
666962306a36Sopenharmony_ci	bra		t_pinx2
667062306a36Sopenharmony_ci
667162306a36Sopenharmony_ciACOSP1:
667262306a36Sopenharmony_ci	bra		ld_pzero		# answer is positive zero
667362306a36Sopenharmony_ci
667462306a36Sopenharmony_ci	global		sacosd
667562306a36Sopenharmony_ci#--ACOS(X) = PI/2 FOR DENORMALIZED X
667662306a36Sopenharmony_cisacosd:
667762306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
667862306a36Sopenharmony_ci	fmov.x		PIBY2(%pc),%fp0
667962306a36Sopenharmony_ci	bra		t_pinx2
668062306a36Sopenharmony_ci
668162306a36Sopenharmony_ci#########################################################################
668262306a36Sopenharmony_ci# setox():    computes the exponential for a normalized input		#
668362306a36Sopenharmony_ci# setoxd():   computes the exponential for a denormalized input		#
668462306a36Sopenharmony_ci# setoxm1():  computes the exponential minus 1 for a normalized input	#
668562306a36Sopenharmony_ci# setoxm1d(): computes the exponential minus 1 for a denormalized input	#
668662306a36Sopenharmony_ci#									#
668762306a36Sopenharmony_ci# INPUT	*************************************************************** #
668862306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
668962306a36Sopenharmony_ci#	d0 = round precision,mode					#
669062306a36Sopenharmony_ci#									#
669162306a36Sopenharmony_ci# OUTPUT ************************************************************** #
669262306a36Sopenharmony_ci#	fp0 = exp(X) or exp(X)-1					#
669362306a36Sopenharmony_ci#									#
669462306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* #
669562306a36Sopenharmony_ci#	The returned result is within 0.85 ulps in 64 significant bit,	#
669662306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
669762306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
669862306a36Sopenharmony_ci#	in double precision.						#
669962306a36Sopenharmony_ci#									#
670062306a36Sopenharmony_ci# ALGORITHM and IMPLEMENTATION **************************************** #
670162306a36Sopenharmony_ci#									#
670262306a36Sopenharmony_ci#	setoxd								#
670362306a36Sopenharmony_ci#	------								#
670462306a36Sopenharmony_ci#	Step 1.	Set ans := 1.0						#
670562306a36Sopenharmony_ci#									#
670662306a36Sopenharmony_ci#	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
670762306a36Sopenharmony_ci#	Notes:	This will always generate one exception -- inexact.	#
670862306a36Sopenharmony_ci#									#
670962306a36Sopenharmony_ci#									#
671062306a36Sopenharmony_ci#	setox								#
671162306a36Sopenharmony_ci#	-----								#
671262306a36Sopenharmony_ci#									#
671362306a36Sopenharmony_ci#	Step 1.	Filter out extreme cases of input argument.		#
671462306a36Sopenharmony_ci#		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
671562306a36Sopenharmony_ci#		1.2	Go to Step 7.					#
671662306a36Sopenharmony_ci#		1.3	If |X| < 16380 log(2), go to Step 2.		#
671762306a36Sopenharmony_ci#		1.4	Go to Step 8.					#
671862306a36Sopenharmony_ci#	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
671962306a36Sopenharmony_ci#		To avoid the use of floating-point comparisons, a	#
672062306a36Sopenharmony_ci#		compact representation of |X| is used. This format is a	#
672162306a36Sopenharmony_ci#		32-bit integer, the upper (more significant) 16 bits	#
672262306a36Sopenharmony_ci#		are the sign and biased exponent field of |X|; the	#
672362306a36Sopenharmony_ci#		lower 16 bits are the 16 most significant fraction	#
672462306a36Sopenharmony_ci#		(including the explicit bit) bits of |X|. Consequently,	#
672562306a36Sopenharmony_ci#		the comparisons in Steps 1.1 and 1.3 can be performed	#
672662306a36Sopenharmony_ci#		by integer comparison. Note also that the constant	#
672762306a36Sopenharmony_ci#		16380 log(2) used in Step 1.3 is also in the compact	#
672862306a36Sopenharmony_ci#		form. Thus taking the branch to Step 2 guarantees	#
672962306a36Sopenharmony_ci#		|X| < 16380 log(2). There is no harm to have a small	#
673062306a36Sopenharmony_ci#		number of cases where |X| is less than,	but close to,	#
673162306a36Sopenharmony_ci#		16380 log(2) and the branch to Step 9 is taken.		#
673262306a36Sopenharmony_ci#									#
673362306a36Sopenharmony_ci#	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
673462306a36Sopenharmony_ci#		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
673562306a36Sopenharmony_ci#			was taken)					#
673662306a36Sopenharmony_ci#		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
673762306a36Sopenharmony_ci#		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
673862306a36Sopenharmony_ci#			or 63.						#
673962306a36Sopenharmony_ci#		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
674062306a36Sopenharmony_ci#		2.5	Calculate the address of the stored value of	#
674162306a36Sopenharmony_ci#			2^(J/64).					#
674262306a36Sopenharmony_ci#		2.6	Create the value Scale = 2^M.			#
674362306a36Sopenharmony_ci#	Notes:	The calculation in 2.2 is really performed by		#
674462306a36Sopenharmony_ci#			Z := X * constant				#
674562306a36Sopenharmony_ci#			N := round-to-nearest-integer(Z)		#
674662306a36Sopenharmony_ci#		where							#
674762306a36Sopenharmony_ci#			constant := single-precision( 64/log 2 ).	#
674862306a36Sopenharmony_ci#									#
674962306a36Sopenharmony_ci#		Using a single-precision constant avoids memory		#
675062306a36Sopenharmony_ci#		access. Another effect of using a single-precision	#
675162306a36Sopenharmony_ci#		"constant" is that the calculated value Z is		#
675262306a36Sopenharmony_ci#									#
675362306a36Sopenharmony_ci#			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
675462306a36Sopenharmony_ci#									#
675562306a36Sopenharmony_ci#		This error has to be considered later in Steps 3 and 4.	#
675662306a36Sopenharmony_ci#									#
675762306a36Sopenharmony_ci#	Step 3.	Calculate X - N*log2/64.				#
675862306a36Sopenharmony_ci#		3.1	R := X + N*L1,					#
675962306a36Sopenharmony_ci#				where L1 := single-precision(-log2/64).	#
676062306a36Sopenharmony_ci#		3.2	R := R + N*L2,					#
676162306a36Sopenharmony_ci#				L2 := extended-precision(-log2/64 - L1).#
676262306a36Sopenharmony_ci#	Notes:	a) The way L1 and L2 are chosen ensures L1+L2		#
676362306a36Sopenharmony_ci#		approximate the value -log2/64 to 88 bits of accuracy.	#
676462306a36Sopenharmony_ci#		b) N*L1 is exact because N is no longer than 22 bits	#
676562306a36Sopenharmony_ci#		and L1 is no longer than 24 bits.			#
676662306a36Sopenharmony_ci#		c) The calculation X+N*L1 is also exact due to		#
676762306a36Sopenharmony_ci#		cancellation. Thus, R is practically X+N(L1+L2) to full	#
676862306a36Sopenharmony_ci#		64 bits.						#
676962306a36Sopenharmony_ci#		d) It is important to estimate how large can |R| be	#
677062306a36Sopenharmony_ci#		after Step 3.2.						#
677162306a36Sopenharmony_ci#									#
677262306a36Sopenharmony_ci#		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
677362306a36Sopenharmony_ci#		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
677462306a36Sopenharmony_ci#		X*64/log2 - N	=	f - eps*X 64/log2		#
677562306a36Sopenharmony_ci#		X - N*log2/64	=	f*log2/64 - eps*X		#
677662306a36Sopenharmony_ci#									#
677762306a36Sopenharmony_ci#									#
677862306a36Sopenharmony_ci#		Now |X| <= 16446 log2, thus				#
677962306a36Sopenharmony_ci#									#
678062306a36Sopenharmony_ci#			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
678162306a36Sopenharmony_ci#					<= 0.57 log2/64.		#
678262306a36Sopenharmony_ci#		 This bound will be used in Step 4.			#
678362306a36Sopenharmony_ci#									#
678462306a36Sopenharmony_ci#	Step 4.	Approximate exp(R)-1 by a polynomial			#
678562306a36Sopenharmony_ci#		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
678662306a36Sopenharmony_ci#	Notes:	a) In order to reduce memory access, the coefficients	#
678762306a36Sopenharmony_ci#		are made as "short" as possible: A1 (which is 1/2), A4	#
678862306a36Sopenharmony_ci#		and A5 are single precision; A2 and A3 are double	#
678962306a36Sopenharmony_ci#		precision.						#
679062306a36Sopenharmony_ci#		b) Even with the restrictions above,			#
679162306a36Sopenharmony_ci#		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
679262306a36Sopenharmony_ci#		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
679362306a36Sopenharmony_ci#		c) To fully utilize the pipeline, p is separated into	#
679462306a36Sopenharmony_ci#		two independent pieces of roughly equal complexities	#
679562306a36Sopenharmony_ci#			p = [ R + R*S*(A2 + S*A4) ]	+		#
679662306a36Sopenharmony_ci#				[ S*(A1 + S*(A3 + S*A5)) ]		#
679762306a36Sopenharmony_ci#		where S = R*R.						#
679862306a36Sopenharmony_ci#									#
679962306a36Sopenharmony_ci#	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
680062306a36Sopenharmony_ci#				ans := T + ( T*p + t)			#
680162306a36Sopenharmony_ci#		where T and t are the stored values for 2^(J/64).	#
680262306a36Sopenharmony_ci#	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
680362306a36Sopenharmony_ci#		2^(J/64) to roughly 85 bits; T is in extended precision	#
680462306a36Sopenharmony_ci#		and t is in single precision. Note also that T is	#
680562306a36Sopenharmony_ci#		rounded to 62 bits so that the last two bits of T are	#
680662306a36Sopenharmony_ci#		zero. The reason for such a special form is that T-1,	#
680762306a36Sopenharmony_ci#		T-2, and T-8 will all be exact --- a property that will	#
680862306a36Sopenharmony_ci#		give much more accurate computation of the function	#
680962306a36Sopenharmony_ci#		EXPM1.							#
681062306a36Sopenharmony_ci#									#
681162306a36Sopenharmony_ci#	Step 6.	Reconstruction of exp(X)				#
681262306a36Sopenharmony_ci#			exp(X) = 2^M * 2^(J/64) * exp(R).		#
681362306a36Sopenharmony_ci#		6.1	If AdjFlag = 0, go to 6.3			#
681462306a36Sopenharmony_ci#		6.2	ans := ans * AdjScale				#
681562306a36Sopenharmony_ci#		6.3	Restore the user FPCR				#
681662306a36Sopenharmony_ci#		6.4	Return ans := ans * Scale. Exit.		#
681762306a36Sopenharmony_ci#	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
681862306a36Sopenharmony_ci#		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
681962306a36Sopenharmony_ci#		neither overflow nor underflow. If AdjFlag = 1, that	#
682062306a36Sopenharmony_ci#		means that						#
682162306a36Sopenharmony_ci#			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
682262306a36Sopenharmony_ci#		Hence, exp(X) may overflow or underflow or neither.	#
682362306a36Sopenharmony_ci#		When that is the case, AdjScale = 2^(M1) where M1 is	#
682462306a36Sopenharmony_ci#		approximately M. Thus 6.2 will never cause		#
682562306a36Sopenharmony_ci#		over/underflow. Possible exception in 6.4 is overflow	#
682662306a36Sopenharmony_ci#		or underflow. The inexact exception is not generated in	#
682762306a36Sopenharmony_ci#		6.4. Although one can argue that the inexact flag	#
682862306a36Sopenharmony_ci#		should always be raised, to simulate that exception	#
682962306a36Sopenharmony_ci#		cost to much than the flag is worth in practical uses.	#
683062306a36Sopenharmony_ci#									#
683162306a36Sopenharmony_ci#	Step 7.	Return 1 + X.						#
683262306a36Sopenharmony_ci#		7.1	ans := X					#
683362306a36Sopenharmony_ci#		7.2	Restore user FPCR.				#
683462306a36Sopenharmony_ci#		7.3	Return ans := 1 + ans. Exit			#
683562306a36Sopenharmony_ci#	Notes:	For non-zero X, the inexact exception will always be	#
683662306a36Sopenharmony_ci#		raised by 7.3. That is the only exception raised by 7.3.#
683762306a36Sopenharmony_ci#		Note also that we use the FMOVEM instruction to move X	#
683862306a36Sopenharmony_ci#		in Step 7.1 to avoid unnecessary trapping. (Although	#
683962306a36Sopenharmony_ci#		the FMOVEM may not seem relevant since X is normalized,	#
684062306a36Sopenharmony_ci#		the precaution will be useful in the library version of	#
684162306a36Sopenharmony_ci#		this code where the separate entry for denormalized	#
684262306a36Sopenharmony_ci#		inputs will be done away with.)				#
684362306a36Sopenharmony_ci#									#
684462306a36Sopenharmony_ci#	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
684562306a36Sopenharmony_ci#		8.1	If |X| > 16480 log2, go to Step 9.		#
684662306a36Sopenharmony_ci#		(mimic 2.2 - 2.6)					#
684762306a36Sopenharmony_ci#		8.2	N := round-to-integer( X * 64/log2 )		#
684862306a36Sopenharmony_ci#		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
684962306a36Sopenharmony_ci#		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1,	#
685062306a36Sopenharmony_ci#			AdjFlag := 1.					#
685162306a36Sopenharmony_ci#		8.5	Calculate the address of the stored value	#
685262306a36Sopenharmony_ci#			2^(J/64).					#
685362306a36Sopenharmony_ci#		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
685462306a36Sopenharmony_ci#		8.7	Go to Step 3.					#
685562306a36Sopenharmony_ci#	Notes:	Refer to notes for 2.2 - 2.6.				#
685662306a36Sopenharmony_ci#									#
685762306a36Sopenharmony_ci#	Step 9.	Handle exp(X), |X| > 16480 log2.			#
685862306a36Sopenharmony_ci#		9.1	If X < 0, go to 9.3				#
685962306a36Sopenharmony_ci#		9.2	ans := Huge, go to 9.4				#
686062306a36Sopenharmony_ci#		9.3	ans := Tiny.					#
686162306a36Sopenharmony_ci#		9.4	Restore user FPCR.				#
686262306a36Sopenharmony_ci#		9.5	Return ans := ans * ans. Exit.			#
686362306a36Sopenharmony_ci#	Notes:	Exp(X) will surely overflow or underflow, depending on	#
686462306a36Sopenharmony_ci#		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
686562306a36Sopenharmony_ci#		extended-precision numbers whose square over/underflow	#
686662306a36Sopenharmony_ci#		with an inexact result. Thus, 9.5 always raises the	#
686762306a36Sopenharmony_ci#		inexact together with either overflow or underflow.	#
686862306a36Sopenharmony_ci#									#
686962306a36Sopenharmony_ci#	setoxm1d							#
687062306a36Sopenharmony_ci#	--------							#
687162306a36Sopenharmony_ci#									#
687262306a36Sopenharmony_ci#	Step 1.	Set ans := 0						#
687362306a36Sopenharmony_ci#									#
687462306a36Sopenharmony_ci#	Step 2.	Return	ans := X + ans. Exit.				#
687562306a36Sopenharmony_ci#	Notes:	This will return X with the appropriate rounding	#
687662306a36Sopenharmony_ci#		 precision prescribed by the user FPCR.			#
687762306a36Sopenharmony_ci#									#
687862306a36Sopenharmony_ci#	setoxm1								#
687962306a36Sopenharmony_ci#	-------								#
688062306a36Sopenharmony_ci#									#
688162306a36Sopenharmony_ci#	Step 1.	Check |X|						#
688262306a36Sopenharmony_ci#		1.1	If |X| >= 1/4, go to Step 1.3.			#
688362306a36Sopenharmony_ci#		1.2	Go to Step 7.					#
688462306a36Sopenharmony_ci#		1.3	If |X| < 70 log(2), go to Step 2.		#
688562306a36Sopenharmony_ci#		1.4	Go to Step 10.					#
688662306a36Sopenharmony_ci#	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
688762306a36Sopenharmony_ci#		However, it is conceivable |X| can be small very often	#
688862306a36Sopenharmony_ci#		because EXPM1 is intended to evaluate exp(X)-1		#
688962306a36Sopenharmony_ci#		accurately when |X| is small. For further details on	#
689062306a36Sopenharmony_ci#		the comparisons, see the notes on Step 1 of setox.	#
689162306a36Sopenharmony_ci#									#
689262306a36Sopenharmony_ci#	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
689362306a36Sopenharmony_ci#		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
689462306a36Sopenharmony_ci#		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
689562306a36Sopenharmony_ci#			or 63.						#
689662306a36Sopenharmony_ci#		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
689762306a36Sopenharmony_ci#		2.4	Calculate the address of the stored value of	#
689862306a36Sopenharmony_ci#			2^(J/64).					#
689962306a36Sopenharmony_ci#		2.5	Create the values Sc = 2^M and			#
690062306a36Sopenharmony_ci#			OnebySc := -2^(-M).				#
690162306a36Sopenharmony_ci#	Notes:	See the notes on Step 2 of setox.			#
690262306a36Sopenharmony_ci#									#
690362306a36Sopenharmony_ci#	Step 3.	Calculate X - N*log2/64.				#
690462306a36Sopenharmony_ci#		3.1	R := X + N*L1,					#
690562306a36Sopenharmony_ci#				where L1 := single-precision(-log2/64).	#
690662306a36Sopenharmony_ci#		3.2	R := R + N*L2,					#
690762306a36Sopenharmony_ci#				L2 := extended-precision(-log2/64 - L1).#
690862306a36Sopenharmony_ci#	Notes:	Applying the analysis of Step 3 of setox in this case	#
690962306a36Sopenharmony_ci#		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
691062306a36Sopenharmony_ci#		this case).						#
691162306a36Sopenharmony_ci#									#
691262306a36Sopenharmony_ci#	Step 4.	Approximate exp(R)-1 by a polynomial			#
691362306a36Sopenharmony_ci#			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
691462306a36Sopenharmony_ci#	Notes:	a) In order to reduce memory access, the coefficients	#
691562306a36Sopenharmony_ci#		are made as "short" as possible: A1 (which is 1/2), A5	#
691662306a36Sopenharmony_ci#		and A6 are single precision; A2, A3 and A4 are double	#
691762306a36Sopenharmony_ci#		precision.						#
691862306a36Sopenharmony_ci#		b) Even with the restriction above,			#
691962306a36Sopenharmony_ci#			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
692062306a36Sopenharmony_ci#		for all |R| <= 0.0055.					#
692162306a36Sopenharmony_ci#		c) To fully utilize the pipeline, p is separated into	#
692262306a36Sopenharmony_ci#		two independent pieces of roughly equal complexity	#
692362306a36Sopenharmony_ci#			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
692462306a36Sopenharmony_ci#				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
692562306a36Sopenharmony_ci#		where S = R*R.						#
692662306a36Sopenharmony_ci#									#
692762306a36Sopenharmony_ci#	Step 5.	Compute 2^(J/64)*p by					#
692862306a36Sopenharmony_ci#				p := T*p				#
692962306a36Sopenharmony_ci#		where T and t are the stored values for 2^(J/64).	#
693062306a36Sopenharmony_ci#	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
693162306a36Sopenharmony_ci#		2^(J/64) to roughly 85 bits; T is in extended precision	#
693262306a36Sopenharmony_ci#		and t is in single precision. Note also that T is	#
693362306a36Sopenharmony_ci#		rounded to 62 bits so that the last two bits of T are	#
693462306a36Sopenharmony_ci#		zero. The reason for such a special form is that T-1,	#
693562306a36Sopenharmony_ci#		T-2, and T-8 will all be exact --- a property that will	#
693662306a36Sopenharmony_ci#		be exploited in Step 6 below. The total relative error	#
693762306a36Sopenharmony_ci#		in p is no bigger than 2^(-67.7) compared to the final	#
693862306a36Sopenharmony_ci#		result.							#
693962306a36Sopenharmony_ci#									#
694062306a36Sopenharmony_ci#	Step 6.	Reconstruction of exp(X)-1				#
694162306a36Sopenharmony_ci#			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
694262306a36Sopenharmony_ci#		6.1	If M <= 63, go to Step 6.3.			#
694362306a36Sopenharmony_ci#		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
694462306a36Sopenharmony_ci#		6.3	If M >= -3, go to 6.5.				#
694562306a36Sopenharmony_ci#		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
694662306a36Sopenharmony_ci#		6.5	ans := (T + OnebySc) + (p + t).			#
694762306a36Sopenharmony_ci#		6.6	Restore user FPCR.				#
694862306a36Sopenharmony_ci#		6.7	Return ans := Sc * ans. Exit.			#
694962306a36Sopenharmony_ci#	Notes:	The various arrangements of the expressions give	#
695062306a36Sopenharmony_ci#		accurate evaluations.					#
695162306a36Sopenharmony_ci#									#
695262306a36Sopenharmony_ci#	Step 7.	exp(X)-1 for |X| < 1/4.					#
695362306a36Sopenharmony_ci#		7.1	If |X| >= 2^(-65), go to Step 9.		#
695462306a36Sopenharmony_ci#		7.2	Go to Step 8.					#
695562306a36Sopenharmony_ci#									#
695662306a36Sopenharmony_ci#	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
695762306a36Sopenharmony_ci#		8.1	If |X| < 2^(-16312), goto 8.3			#
695862306a36Sopenharmony_ci#		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
695962306a36Sopenharmony_ci#			Exit.						#
696062306a36Sopenharmony_ci#		8.3	X := X * 2^(140).				#
696162306a36Sopenharmony_ci#		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
696262306a36Sopenharmony_ci#		 Return ans := ans*2^(140). Exit			#
696362306a36Sopenharmony_ci#	Notes:	The idea is to return "X - tiny" under the user		#
696462306a36Sopenharmony_ci#		precision and rounding modes. To avoid unnecessary	#
696562306a36Sopenharmony_ci#		inefficiency, we stay away from denormalized numbers	#
696662306a36Sopenharmony_ci#		the best we can. For |X| >= 2^(-16312), the		#
696762306a36Sopenharmony_ci#		straightforward 8.2 generates the inexact exception as	#
696862306a36Sopenharmony_ci#		the case warrants.					#
696962306a36Sopenharmony_ci#									#
697062306a36Sopenharmony_ci#	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
697162306a36Sopenharmony_ci#			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
697262306a36Sopenharmony_ci#	Notes:	a) In order to reduce memory access, the coefficients	#
697362306a36Sopenharmony_ci#		are made as "short" as possible: B1 (which is 1/2), B9	#
697462306a36Sopenharmony_ci#		to B12 are single precision; B3 to B8 are double	#
697562306a36Sopenharmony_ci#		precision; and B2 is double extended.			#
697662306a36Sopenharmony_ci#		b) Even with the restriction above,			#
697762306a36Sopenharmony_ci#			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
697862306a36Sopenharmony_ci#		for all |X| <= 0.251.					#
697962306a36Sopenharmony_ci#		Note that 0.251 is slightly bigger than 1/4.		#
698062306a36Sopenharmony_ci#		c) To fully preserve accuracy, the polynomial is	#
698162306a36Sopenharmony_ci#		computed as						#
698262306a36Sopenharmony_ci#			X + ( S*B1 +	Q ) where S = X*X and		#
698362306a36Sopenharmony_ci#			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
698462306a36Sopenharmony_ci#		d) To fully utilize the pipeline, Q is separated into	#
698562306a36Sopenharmony_ci#		two independent pieces of roughly equal complexity	#
698662306a36Sopenharmony_ci#			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
698762306a36Sopenharmony_ci#				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
698862306a36Sopenharmony_ci#									#
698962306a36Sopenharmony_ci#	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
699062306a36Sopenharmony_ci#		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all	#
699162306a36Sopenharmony_ci#		practical purposes. Therefore, go to Step 1 of setox.	#
699262306a36Sopenharmony_ci#		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
699362306a36Sopenharmony_ci#		purposes.						#
699462306a36Sopenharmony_ci#		ans := -1						#
699562306a36Sopenharmony_ci#		Restore user FPCR					#
699662306a36Sopenharmony_ci#		Return ans := ans + 2^(-126). Exit.			#
699762306a36Sopenharmony_ci#	Notes:	10.2 will always create an inexact and return -1 + tiny	#
699862306a36Sopenharmony_ci#		in the user rounding precision and mode.		#
699962306a36Sopenharmony_ci#									#
700062306a36Sopenharmony_ci#########################################################################
700162306a36Sopenharmony_ci
700262306a36Sopenharmony_ciL2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
700362306a36Sopenharmony_ci
700462306a36Sopenharmony_ciEEXPA3:	long		0x3FA55555,0x55554CC1
700562306a36Sopenharmony_ciEEXPA2:	long		0x3FC55555,0x55554A54
700662306a36Sopenharmony_ci
700762306a36Sopenharmony_ciEM1A4:	long		0x3F811111,0x11174385
700862306a36Sopenharmony_ciEM1A3:	long		0x3FA55555,0x55554F5A
700962306a36Sopenharmony_ci
701062306a36Sopenharmony_ciEM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
701162306a36Sopenharmony_ci
701262306a36Sopenharmony_ciEM1B8:	long		0x3EC71DE3,0xA5774682
701362306a36Sopenharmony_ciEM1B7:	long		0x3EFA01A0,0x19D7CB68
701462306a36Sopenharmony_ci
701562306a36Sopenharmony_ciEM1B6:	long		0x3F2A01A0,0x1A019DF3
701662306a36Sopenharmony_ciEM1B5:	long		0x3F56C16C,0x16C170E2
701762306a36Sopenharmony_ci
701862306a36Sopenharmony_ciEM1B4:	long		0x3F811111,0x11111111
701962306a36Sopenharmony_ciEM1B3:	long		0x3FA55555,0x55555555
702062306a36Sopenharmony_ci
702162306a36Sopenharmony_ciEM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
702262306a36Sopenharmony_ci	long		0x00000000
702362306a36Sopenharmony_ci
702462306a36Sopenharmony_ciTWO140:	long		0x48B00000,0x00000000
702562306a36Sopenharmony_ciTWON140:
702662306a36Sopenharmony_ci	long		0x37300000,0x00000000
702762306a36Sopenharmony_ci
702862306a36Sopenharmony_ciEEXPTBL:
702962306a36Sopenharmony_ci	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
703062306a36Sopenharmony_ci	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
703162306a36Sopenharmony_ci	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
703262306a36Sopenharmony_ci	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
703362306a36Sopenharmony_ci	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
703462306a36Sopenharmony_ci	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
703562306a36Sopenharmony_ci	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
703662306a36Sopenharmony_ci	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
703762306a36Sopenharmony_ci	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
703862306a36Sopenharmony_ci	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
703962306a36Sopenharmony_ci	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
704062306a36Sopenharmony_ci	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
704162306a36Sopenharmony_ci	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
704262306a36Sopenharmony_ci	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
704362306a36Sopenharmony_ci	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
704462306a36Sopenharmony_ci	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
704562306a36Sopenharmony_ci	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
704662306a36Sopenharmony_ci	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
704762306a36Sopenharmony_ci	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
704862306a36Sopenharmony_ci	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
704962306a36Sopenharmony_ci	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
705062306a36Sopenharmony_ci	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
705162306a36Sopenharmony_ci	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
705262306a36Sopenharmony_ci	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
705362306a36Sopenharmony_ci	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
705462306a36Sopenharmony_ci	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
705562306a36Sopenharmony_ci	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
705662306a36Sopenharmony_ci	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
705762306a36Sopenharmony_ci	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
705862306a36Sopenharmony_ci	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
705962306a36Sopenharmony_ci	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
706062306a36Sopenharmony_ci	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
706162306a36Sopenharmony_ci	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
706262306a36Sopenharmony_ci	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
706362306a36Sopenharmony_ci	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
706462306a36Sopenharmony_ci	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
706562306a36Sopenharmony_ci	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
706662306a36Sopenharmony_ci	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
706762306a36Sopenharmony_ci	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
706862306a36Sopenharmony_ci	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
706962306a36Sopenharmony_ci	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
707062306a36Sopenharmony_ci	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
707162306a36Sopenharmony_ci	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
707262306a36Sopenharmony_ci	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
707362306a36Sopenharmony_ci	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
707462306a36Sopenharmony_ci	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
707562306a36Sopenharmony_ci	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
707662306a36Sopenharmony_ci	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
707762306a36Sopenharmony_ci	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
707862306a36Sopenharmony_ci	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
707962306a36Sopenharmony_ci	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
708062306a36Sopenharmony_ci	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
708162306a36Sopenharmony_ci	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
708262306a36Sopenharmony_ci	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
708362306a36Sopenharmony_ci	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
708462306a36Sopenharmony_ci	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
708562306a36Sopenharmony_ci	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
708662306a36Sopenharmony_ci	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
708762306a36Sopenharmony_ci	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
708862306a36Sopenharmony_ci	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
708962306a36Sopenharmony_ci	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
709062306a36Sopenharmony_ci	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
709162306a36Sopenharmony_ci	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
709262306a36Sopenharmony_ci	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
709362306a36Sopenharmony_ci
709462306a36Sopenharmony_ci	set		ADJFLAG,L_SCR2
709562306a36Sopenharmony_ci	set		SCALE,FP_SCR0
709662306a36Sopenharmony_ci	set		ADJSCALE,FP_SCR1
709762306a36Sopenharmony_ci	set		SC,FP_SCR0
709862306a36Sopenharmony_ci	set		ONEBYSC,FP_SCR1
709962306a36Sopenharmony_ci
710062306a36Sopenharmony_ci	global		setox
710162306a36Sopenharmony_cisetox:
710262306a36Sopenharmony_ci#--entry point for EXP(X), here X is finite, non-zero, and not NaN's
710362306a36Sopenharmony_ci
710462306a36Sopenharmony_ci#--Step 1.
710562306a36Sopenharmony_ci	mov.l		(%a0),%d1		# load part of input X
710662306a36Sopenharmony_ci	and.l		&0x7FFF0000,%d1		# biased expo. of X
710762306a36Sopenharmony_ci	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
710862306a36Sopenharmony_ci	bge.b		EXPC1			# normal case
710962306a36Sopenharmony_ci	bra		EXPSM
711062306a36Sopenharmony_ci
711162306a36Sopenharmony_ciEXPC1:
711262306a36Sopenharmony_ci#--The case |X| >= 2^(-65)
711362306a36Sopenharmony_ci	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
711462306a36Sopenharmony_ci	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
711562306a36Sopenharmony_ci	blt.b		EXPMAIN			# normal case
711662306a36Sopenharmony_ci	bra		EEXPBIG
711762306a36Sopenharmony_ci
711862306a36Sopenharmony_ciEXPMAIN:
711962306a36Sopenharmony_ci#--Step 2.
712062306a36Sopenharmony_ci#--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
712162306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# load input from (a0)
712262306a36Sopenharmony_ci
712362306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
712462306a36Sopenharmony_ci	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
712562306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
712662306a36Sopenharmony_ci	mov.l		&0,ADJFLAG(%a6)
712762306a36Sopenharmony_ci	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
712862306a36Sopenharmony_ci	lea		EEXPTBL(%pc),%a1
712962306a36Sopenharmony_ci	fmov.l		%d1,%fp0		# convert to floating-format
713062306a36Sopenharmony_ci
713162306a36Sopenharmony_ci	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
713262306a36Sopenharmony_ci	and.l		&0x3F,%d1		# D0 is J = N mod 64
713362306a36Sopenharmony_ci	lsl.l		&4,%d1
713462306a36Sopenharmony_ci	add.l		%d1,%a1			# address of 2^(J/64)
713562306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d1
713662306a36Sopenharmony_ci	asr.l		&6,%d1			# D0 is M
713762306a36Sopenharmony_ci	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
713862306a36Sopenharmony_ci	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
713962306a36Sopenharmony_ci
714062306a36Sopenharmony_ciEXPCONT1:
714162306a36Sopenharmony_ci#--Step 3.
714262306a36Sopenharmony_ci#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
714362306a36Sopenharmony_ci#--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
714462306a36Sopenharmony_ci	fmov.x		%fp0,%fp2
714562306a36Sopenharmony_ci	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
714662306a36Sopenharmony_ci	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
714762306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# X + N*L1
714862306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
714962306a36Sopenharmony_ci
715062306a36Sopenharmony_ci#--Step 4.
715162306a36Sopenharmony_ci#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
715262306a36Sopenharmony_ci#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
715362306a36Sopenharmony_ci#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
715462306a36Sopenharmony_ci#--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
715562306a36Sopenharmony_ci
715662306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
715762306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
715862306a36Sopenharmony_ci
715962306a36Sopenharmony_ci	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
716062306a36Sopenharmony_ci
716162306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# fp2 IS S*A5
716262306a36Sopenharmony_ci	fmov.x		%fp1,%fp3
716362306a36Sopenharmony_ci	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
716462306a36Sopenharmony_ci
716562306a36Sopenharmony_ci	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
716662306a36Sopenharmony_ci	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
716762306a36Sopenharmony_ci
716862306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
716962306a36Sopenharmony_ci	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
717062306a36Sopenharmony_ci	mov.l		&0x80000000,SCALE+4(%a6)
717162306a36Sopenharmony_ci	clr.l		SCALE+8(%a6)
717262306a36Sopenharmony_ci
717362306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
717462306a36Sopenharmony_ci
717562306a36Sopenharmony_ci	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
717662306a36Sopenharmony_ci	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
717762306a36Sopenharmony_ci
717862306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
717962306a36Sopenharmony_ci	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
718062306a36Sopenharmony_ci
718162306a36Sopenharmony_ci	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
718262306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
718362306a36Sopenharmony_ci
718462306a36Sopenharmony_ci#--Step 5
718562306a36Sopenharmony_ci#--final reconstruction process
718662306a36Sopenharmony_ci#--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
718762306a36Sopenharmony_ci
718862306a36Sopenharmony_ci	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
718962306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
719062306a36Sopenharmony_ci	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
719162306a36Sopenharmony_ci
719262306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
719362306a36Sopenharmony_ci	mov.l		ADJFLAG(%a6),%d1
719462306a36Sopenharmony_ci
719562306a36Sopenharmony_ci#--Step 6
719662306a36Sopenharmony_ci	tst.l		%d1
719762306a36Sopenharmony_ci	beq.b		NORMAL
719862306a36Sopenharmony_ciADJUST:
719962306a36Sopenharmony_ci	fmul.x		ADJSCALE(%a6),%fp0
720062306a36Sopenharmony_ciNORMAL:
720162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore user FPCR
720262306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
720362306a36Sopenharmony_ci	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
720462306a36Sopenharmony_ci	bra		t_catch
720562306a36Sopenharmony_ci
720662306a36Sopenharmony_ciEXPSM:
720762306a36Sopenharmony_ci#--Step 7
720862306a36Sopenharmony_ci	fmovm.x		(%a0),&0x80		# load X
720962306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
721062306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
721162306a36Sopenharmony_ci	bra		t_pinx2
721262306a36Sopenharmony_ci
721362306a36Sopenharmony_ciEEXPBIG:
721462306a36Sopenharmony_ci#--Step 8
721562306a36Sopenharmony_ci	cmp.l		%d1,&0x400CB27C		# 16480 log2
721662306a36Sopenharmony_ci	bgt.b		EXP2BIG
721762306a36Sopenharmony_ci#--Steps 8.2 -- 8.6
721862306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# load input from (a0)
721962306a36Sopenharmony_ci
722062306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
722162306a36Sopenharmony_ci	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
722262306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
722362306a36Sopenharmony_ci	mov.l		&1,ADJFLAG(%a6)
722462306a36Sopenharmony_ci	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
722562306a36Sopenharmony_ci	lea		EEXPTBL(%pc),%a1
722662306a36Sopenharmony_ci	fmov.l		%d1,%fp0		# convert to floating-format
722762306a36Sopenharmony_ci	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
722862306a36Sopenharmony_ci	and.l		&0x3F,%d1		# D0 is J = N mod 64
722962306a36Sopenharmony_ci	lsl.l		&4,%d1
723062306a36Sopenharmony_ci	add.l		%d1,%a1			# address of 2^(J/64)
723162306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d1
723262306a36Sopenharmony_ci	asr.l		&6,%d1			# D0 is K
723362306a36Sopenharmony_ci	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
723462306a36Sopenharmony_ci	asr.l		&1,%d1			# D0 is M1
723562306a36Sopenharmony_ci	sub.l		%d1,L_SCR1(%a6)		# a1 is M
723662306a36Sopenharmony_ci	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
723762306a36Sopenharmony_ci	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
723862306a36Sopenharmony_ci	mov.l		&0x80000000,ADJSCALE+4(%a6)
723962306a36Sopenharmony_ci	clr.l		ADJSCALE+8(%a6)
724062306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d1		# D0 is M
724162306a36Sopenharmony_ci	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
724262306a36Sopenharmony_ci	bra.w		EXPCONT1		# go back to Step 3
724362306a36Sopenharmony_ci
724462306a36Sopenharmony_ciEXP2BIG:
724562306a36Sopenharmony_ci#--Step 9
724662306a36Sopenharmony_ci	tst.b		(%a0)			# is X positive or negative?
724762306a36Sopenharmony_ci	bmi		t_unfl2
724862306a36Sopenharmony_ci	bra		t_ovfl2
724962306a36Sopenharmony_ci
725062306a36Sopenharmony_ci	global		setoxd
725162306a36Sopenharmony_cisetoxd:
725262306a36Sopenharmony_ci#--entry point for EXP(X), X is denormalized
725362306a36Sopenharmony_ci	mov.l		(%a0),-(%sp)
725462306a36Sopenharmony_ci	andi.l		&0x80000000,(%sp)
725562306a36Sopenharmony_ci	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
725662306a36Sopenharmony_ci
725762306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp0
725862306a36Sopenharmony_ci
725962306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
726062306a36Sopenharmony_ci	fadd.s		(%sp)+,%fp0
726162306a36Sopenharmony_ci	bra		t_pinx2
726262306a36Sopenharmony_ci
726362306a36Sopenharmony_ci	global		setoxm1
726462306a36Sopenharmony_cisetoxm1:
726562306a36Sopenharmony_ci#--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
726662306a36Sopenharmony_ci
726762306a36Sopenharmony_ci#--Step 1.
726862306a36Sopenharmony_ci#--Step 1.1
726962306a36Sopenharmony_ci	mov.l		(%a0),%d1		# load part of input X
727062306a36Sopenharmony_ci	and.l		&0x7FFF0000,%d1		# biased expo. of X
727162306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFD0000		# 1/4
727262306a36Sopenharmony_ci	bge.b		EM1CON1			# |X| >= 1/4
727362306a36Sopenharmony_ci	bra		EM1SM
727462306a36Sopenharmony_ci
727562306a36Sopenharmony_ciEM1CON1:
727662306a36Sopenharmony_ci#--Step 1.3
727762306a36Sopenharmony_ci#--The case |X| >= 1/4
727862306a36Sopenharmony_ci	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
727962306a36Sopenharmony_ci	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
728062306a36Sopenharmony_ci	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
728162306a36Sopenharmony_ci	bra		EM1BIG
728262306a36Sopenharmony_ci
728362306a36Sopenharmony_ciEM1MAIN:
728462306a36Sopenharmony_ci#--Step 2.
728562306a36Sopenharmony_ci#--This is the case:	1/4 <= |X| <= 70 log2.
728662306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# load input from (a0)
728762306a36Sopenharmony_ci
728862306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
728962306a36Sopenharmony_ci	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
729062306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
729162306a36Sopenharmony_ci	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
729262306a36Sopenharmony_ci	lea		EEXPTBL(%pc),%a1
729362306a36Sopenharmony_ci	fmov.l		%d1,%fp0		# convert to floating-format
729462306a36Sopenharmony_ci
729562306a36Sopenharmony_ci	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
729662306a36Sopenharmony_ci	and.l		&0x3F,%d1		# D0 is J = N mod 64
729762306a36Sopenharmony_ci	lsl.l		&4,%d1
729862306a36Sopenharmony_ci	add.l		%d1,%a1			# address of 2^(J/64)
729962306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d1
730062306a36Sopenharmony_ci	asr.l		&6,%d1			# D0 is M
730162306a36Sopenharmony_ci	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
730262306a36Sopenharmony_ci
730362306a36Sopenharmony_ci#--Step 3.
730462306a36Sopenharmony_ci#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
730562306a36Sopenharmony_ci#--a0 points to 2^(J/64), D0 and a1 both contain M
730662306a36Sopenharmony_ci	fmov.x		%fp0,%fp2
730762306a36Sopenharmony_ci	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
730862306a36Sopenharmony_ci	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
730962306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# X + N*L1
731062306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
731162306a36Sopenharmony_ci	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
731262306a36Sopenharmony_ci
731362306a36Sopenharmony_ci#--Step 4.
731462306a36Sopenharmony_ci#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
731562306a36Sopenharmony_ci#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
731662306a36Sopenharmony_ci#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
731762306a36Sopenharmony_ci#--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
731862306a36Sopenharmony_ci
731962306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
732062306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
732162306a36Sopenharmony_ci
732262306a36Sopenharmony_ci	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
732362306a36Sopenharmony_ci
732462306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# fp2 IS S*A6
732562306a36Sopenharmony_ci	fmov.x		%fp1,%fp3
732662306a36Sopenharmony_ci	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
732762306a36Sopenharmony_ci
732862306a36Sopenharmony_ci	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
732962306a36Sopenharmony_ci	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
733062306a36Sopenharmony_ci	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
733162306a36Sopenharmony_ci	mov.l		&0x80000000,SC+4(%a6)
733262306a36Sopenharmony_ci	clr.l		SC+8(%a6)
733362306a36Sopenharmony_ci
733462306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
733562306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d1		# D0 is	M
733662306a36Sopenharmony_ci	neg.w		%d1			# D0 is -M
733762306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
733862306a36Sopenharmony_ci	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
733962306a36Sopenharmony_ci	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
734062306a36Sopenharmony_ci	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
734162306a36Sopenharmony_ci
734262306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
734362306a36Sopenharmony_ci	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
734462306a36Sopenharmony_ci	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
734562306a36Sopenharmony_ci	mov.l		&0x80000000,ONEBYSC+4(%a6)
734662306a36Sopenharmony_ci	clr.l		ONEBYSC+8(%a6)
734762306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
734862306a36Sopenharmony_ci
734962306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
735062306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
735162306a36Sopenharmony_ci
735262306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
735362306a36Sopenharmony_ci
735462306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
735562306a36Sopenharmony_ci
735662306a36Sopenharmony_ci#--Step 5
735762306a36Sopenharmony_ci#--Compute 2^(J/64)*p
735862306a36Sopenharmony_ci
735962306a36Sopenharmony_ci	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
736062306a36Sopenharmony_ci
736162306a36Sopenharmony_ci#--Step 6
736262306a36Sopenharmony_ci#--Step 6.1
736362306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d1		# retrieve M
736462306a36Sopenharmony_ci	cmp.l		%d1,&63
736562306a36Sopenharmony_ci	ble.b		MLE63
736662306a36Sopenharmony_ci#--Step 6.2	M >= 64
736762306a36Sopenharmony_ci	fmov.s		12(%a1),%fp1		# fp1 is t
736862306a36Sopenharmony_ci	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
736962306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
737062306a36Sopenharmony_ci	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
737162306a36Sopenharmony_ci	bra		EM1SCALE
737262306a36Sopenharmony_ciMLE63:
737362306a36Sopenharmony_ci#--Step 6.3	M <= 63
737462306a36Sopenharmony_ci	cmp.l		%d1,&-3
737562306a36Sopenharmony_ci	bge.b		MGEN3
737662306a36Sopenharmony_ciMLTN3:
737762306a36Sopenharmony_ci#--Step 6.4	M <= -4
737862306a36Sopenharmony_ci	fadd.s		12(%a1),%fp0		# p+t
737962306a36Sopenharmony_ci	fadd.x		(%a1),%fp0		# T+(p+t)
738062306a36Sopenharmony_ci	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
738162306a36Sopenharmony_ci	bra		EM1SCALE
738262306a36Sopenharmony_ciMGEN3:
738362306a36Sopenharmony_ci#--Step 6.5	-3 <= M <= 63
738462306a36Sopenharmony_ci	fmov.x		(%a1)+,%fp1		# fp1 is T
738562306a36Sopenharmony_ci	fadd.s		(%a1),%fp0		# fp0 is p+t
738662306a36Sopenharmony_ci	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
738762306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
738862306a36Sopenharmony_ci
738962306a36Sopenharmony_ciEM1SCALE:
739062306a36Sopenharmony_ci#--Step 6.6
739162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
739262306a36Sopenharmony_ci	fmul.x		SC(%a6),%fp0
739362306a36Sopenharmony_ci	bra		t_inx2
739462306a36Sopenharmony_ci
739562306a36Sopenharmony_ciEM1SM:
739662306a36Sopenharmony_ci#--Step 7	|X| < 1/4.
739762306a36Sopenharmony_ci	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
739862306a36Sopenharmony_ci	bge.b		EM1POLY
739962306a36Sopenharmony_ci
740062306a36Sopenharmony_ciEM1TINY:
740162306a36Sopenharmony_ci#--Step 8	|X| < 2^(-65)
740262306a36Sopenharmony_ci	cmp.l		%d1,&0x00330000		# 2^(-16312)
740362306a36Sopenharmony_ci	blt.b		EM12TINY
740462306a36Sopenharmony_ci#--Step 8.2
740562306a36Sopenharmony_ci	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
740662306a36Sopenharmony_ci	mov.l		&0x80000000,SC+4(%a6)
740762306a36Sopenharmony_ci	clr.l		SC+8(%a6)
740862306a36Sopenharmony_ci	fmov.x		(%a0),%fp0
740962306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
741062306a36Sopenharmony_ci	mov.b		&FADD_OP,%d1		# last inst is ADD
741162306a36Sopenharmony_ci	fadd.x		SC(%a6),%fp0
741262306a36Sopenharmony_ci	bra		t_catch
741362306a36Sopenharmony_ci
741462306a36Sopenharmony_ciEM12TINY:
741562306a36Sopenharmony_ci#--Step 8.3
741662306a36Sopenharmony_ci	fmov.x		(%a0),%fp0
741762306a36Sopenharmony_ci	fmul.d		TWO140(%pc),%fp0
741862306a36Sopenharmony_ci	mov.l		&0x80010000,SC(%a6)
741962306a36Sopenharmony_ci	mov.l		&0x80000000,SC+4(%a6)
742062306a36Sopenharmony_ci	clr.l		SC+8(%a6)
742162306a36Sopenharmony_ci	fadd.x		SC(%a6),%fp0
742262306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
742362306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
742462306a36Sopenharmony_ci	fmul.d		TWON140(%pc),%fp0
742562306a36Sopenharmony_ci	bra		t_catch
742662306a36Sopenharmony_ci
742762306a36Sopenharmony_ciEM1POLY:
742862306a36Sopenharmony_ci#--Step 9	exp(X)-1 by a simple polynomial
742962306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# fp0 is X
743062306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# fp0 is S := X*X
743162306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
743262306a36Sopenharmony_ci	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
743362306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# fp1 is S*B12
743462306a36Sopenharmony_ci	fmov.s		&0x310F8290,%fp2	# fp2 is B11
743562306a36Sopenharmony_ci	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
743662306a36Sopenharmony_ci
743762306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 is S*B11
743862306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
743962306a36Sopenharmony_ci
744062306a36Sopenharmony_ci	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
744162306a36Sopenharmony_ci	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
744262306a36Sopenharmony_ci
744362306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
744462306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
744562306a36Sopenharmony_ci
744662306a36Sopenharmony_ci	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
744762306a36Sopenharmony_ci	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
744862306a36Sopenharmony_ci
744962306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
745062306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
745162306a36Sopenharmony_ci
745262306a36Sopenharmony_ci	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
745362306a36Sopenharmony_ci	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
745462306a36Sopenharmony_ci
745562306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
745662306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
745762306a36Sopenharmony_ci
745862306a36Sopenharmony_ci	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
745962306a36Sopenharmony_ci	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
746062306a36Sopenharmony_ci
746162306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
746262306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
746362306a36Sopenharmony_ci
746462306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
746562306a36Sopenharmony_ci	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
746662306a36Sopenharmony_ci
746762306a36Sopenharmony_ci	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
746862306a36Sopenharmony_ci	fadd.x		%fp2,%fp1		# fp1 is Q
746962306a36Sopenharmony_ci
747062306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
747162306a36Sopenharmony_ci
747262306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
747362306a36Sopenharmony_ci
747462306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
747562306a36Sopenharmony_ci	fadd.x		(%a0),%fp0
747662306a36Sopenharmony_ci	bra		t_inx2
747762306a36Sopenharmony_ci
747862306a36Sopenharmony_ciEM1BIG:
747962306a36Sopenharmony_ci#--Step 10	|X| > 70 log2
748062306a36Sopenharmony_ci	mov.l		(%a0),%d1
748162306a36Sopenharmony_ci	cmp.l		%d1,&0
748262306a36Sopenharmony_ci	bgt.w		EXPC1
748362306a36Sopenharmony_ci#--Step 10.2
748462306a36Sopenharmony_ci	fmov.s		&0xBF800000,%fp0	# fp0 is -1
748562306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
748662306a36Sopenharmony_ci	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
748762306a36Sopenharmony_ci	bra		t_minx2
748862306a36Sopenharmony_ci
748962306a36Sopenharmony_ci	global		setoxm1d
749062306a36Sopenharmony_cisetoxm1d:
749162306a36Sopenharmony_ci#--entry point for EXPM1(X), here X is denormalized
749262306a36Sopenharmony_ci#--Step 0.
749362306a36Sopenharmony_ci	bra		t_extdnrm
749462306a36Sopenharmony_ci
749562306a36Sopenharmony_ci#########################################################################
749662306a36Sopenharmony_ci# sgetexp():  returns the exponent portion of the input argument.	#
749762306a36Sopenharmony_ci#	      The exponent bias is removed and the exponent value is	#
749862306a36Sopenharmony_ci#	      returned as an extended precision number in fp0.		#
749962306a36Sopenharmony_ci# sgetexpd(): handles denormalized numbers.				#
750062306a36Sopenharmony_ci#									#
750162306a36Sopenharmony_ci# sgetman():  extracts the mantissa of the input argument. The		#
750262306a36Sopenharmony_ci#	      mantissa is converted to an extended precision number w/	#
750362306a36Sopenharmony_ci#	      an exponent of $3fff and is returned in fp0. The range of #
750462306a36Sopenharmony_ci#	      the result is [1.0 - 2.0).				#
750562306a36Sopenharmony_ci# sgetmand(): handles denormalized numbers.				#
750662306a36Sopenharmony_ci#									#
750762306a36Sopenharmony_ci# INPUT *************************************************************** #
750862306a36Sopenharmony_ci#	a0  = pointer to extended precision input			#
750962306a36Sopenharmony_ci#									#
751062306a36Sopenharmony_ci# OUTPUT ************************************************************** #
751162306a36Sopenharmony_ci#	fp0 = exponent(X) or mantissa(X)				#
751262306a36Sopenharmony_ci#									#
751362306a36Sopenharmony_ci#########################################################################
751462306a36Sopenharmony_ci
751562306a36Sopenharmony_ci	global		sgetexp
751662306a36Sopenharmony_cisgetexp:
751762306a36Sopenharmony_ci	mov.w		SRC_EX(%a0),%d0		# get the exponent
751862306a36Sopenharmony_ci	bclr		&0xf,%d0		# clear the sign bit
751962306a36Sopenharmony_ci	subi.w		&0x3fff,%d0		# subtract off the bias
752062306a36Sopenharmony_ci	fmov.w		%d0,%fp0		# return exp in fp0
752162306a36Sopenharmony_ci	blt.b		sgetexpn		# it's negative
752262306a36Sopenharmony_ci	rts
752362306a36Sopenharmony_ci
752462306a36Sopenharmony_cisgetexpn:
752562306a36Sopenharmony_ci	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
752662306a36Sopenharmony_ci	rts
752762306a36Sopenharmony_ci
752862306a36Sopenharmony_ci	global		sgetexpd
752962306a36Sopenharmony_cisgetexpd:
753062306a36Sopenharmony_ci	bsr.l		norm			# normalize
753162306a36Sopenharmony_ci	neg.w		%d0			# new exp = -(shft amt)
753262306a36Sopenharmony_ci	subi.w		&0x3fff,%d0		# subtract off the bias
753362306a36Sopenharmony_ci	fmov.w		%d0,%fp0		# return exp in fp0
753462306a36Sopenharmony_ci	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
753562306a36Sopenharmony_ci	rts
753662306a36Sopenharmony_ci
753762306a36Sopenharmony_ci	global		sgetman
753862306a36Sopenharmony_cisgetman:
753962306a36Sopenharmony_ci	mov.w		SRC_EX(%a0),%d0		# get the exp
754062306a36Sopenharmony_ci	ori.w		&0x7fff,%d0		# clear old exp
754162306a36Sopenharmony_ci	bclr		&0xe,%d0		# make it the new exp +-3fff
754262306a36Sopenharmony_ci
754362306a36Sopenharmony_ci# here, we build the result in a tmp location so as not to disturb the input
754462306a36Sopenharmony_ci	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
754562306a36Sopenharmony_ci	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
754662306a36Sopenharmony_ci	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
754762306a36Sopenharmony_ci	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
754862306a36Sopenharmony_ci	bmi.b		sgetmann		# it's negative
754962306a36Sopenharmony_ci	rts
755062306a36Sopenharmony_ci
755162306a36Sopenharmony_cisgetmann:
755262306a36Sopenharmony_ci	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
755362306a36Sopenharmony_ci	rts
755462306a36Sopenharmony_ci
755562306a36Sopenharmony_ci#
755662306a36Sopenharmony_ci# For denormalized numbers, shift the mantissa until the j-bit = 1,
755762306a36Sopenharmony_ci# then load the exponent with +/1 $3fff.
755862306a36Sopenharmony_ci#
755962306a36Sopenharmony_ci	global		sgetmand
756062306a36Sopenharmony_cisgetmand:
756162306a36Sopenharmony_ci	bsr.l		norm			# normalize exponent
756262306a36Sopenharmony_ci	bra.b		sgetman
756362306a36Sopenharmony_ci
756462306a36Sopenharmony_ci#########################################################################
756562306a36Sopenharmony_ci# scosh():  computes the hyperbolic cosine of a normalized input	#
756662306a36Sopenharmony_ci# scoshd(): computes the hyperbolic cosine of a denormalized input	#
756762306a36Sopenharmony_ci#									#
756862306a36Sopenharmony_ci# INPUT ***************************************************************	#
756962306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
757062306a36Sopenharmony_ci#	d0 = round precision,mode					#
757162306a36Sopenharmony_ci#									#
757262306a36Sopenharmony_ci# OUTPUT **************************************************************	#
757362306a36Sopenharmony_ci#	fp0 = cosh(X)							#
757462306a36Sopenharmony_ci#									#
757562306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
757662306a36Sopenharmony_ci#	The returned result is within 3 ulps in 64 significant bit,	#
757762306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
757862306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
757962306a36Sopenharmony_ci#	in double precision.						#
758062306a36Sopenharmony_ci#									#
758162306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
758262306a36Sopenharmony_ci#									#
758362306a36Sopenharmony_ci#	COSH								#
758462306a36Sopenharmony_ci#	1. If |X| > 16380 log2, go to 3.				#
758562306a36Sopenharmony_ci#									#
758662306a36Sopenharmony_ci#	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
758762306a36Sopenharmony_ci#		y = |X|, z = exp(Y), and				#
758862306a36Sopenharmony_ci#		cosh(X) = (1/2)*( z + 1/z ).				#
758962306a36Sopenharmony_ci#		Exit.							#
759062306a36Sopenharmony_ci#									#
759162306a36Sopenharmony_ci#	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
759262306a36Sopenharmony_ci#									#
759362306a36Sopenharmony_ci#	4. (16380 log2 < |X| <= 16480 log2)				#
759462306a36Sopenharmony_ci#		cosh(X) = sign(X) * exp(|X|)/2.				#
759562306a36Sopenharmony_ci#		However, invoking exp(|X|) may cause premature		#
759662306a36Sopenharmony_ci#		overflow. Thus, we calculate sinh(X) as follows:	#
759762306a36Sopenharmony_ci#		Y	:= |X|						#
759862306a36Sopenharmony_ci#		Fact	:=	2**(16380)				#
759962306a36Sopenharmony_ci#		Y'	:= Y - 16381 log2				#
760062306a36Sopenharmony_ci#		cosh(X) := Fact * exp(Y').				#
760162306a36Sopenharmony_ci#		Exit.							#
760262306a36Sopenharmony_ci#									#
760362306a36Sopenharmony_ci#	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
760462306a36Sopenharmony_ci#		Huge*Huge to generate overflow and an infinity with	#
760562306a36Sopenharmony_ci#		the appropriate sign. Huge is the largest finite number	#
760662306a36Sopenharmony_ci#		in extended format. Exit.				#
760762306a36Sopenharmony_ci#									#
760862306a36Sopenharmony_ci#########################################################################
760962306a36Sopenharmony_ci
761062306a36Sopenharmony_ciTWO16380:
761162306a36Sopenharmony_ci	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
761262306a36Sopenharmony_ci
761362306a36Sopenharmony_ci	global		scosh
761462306a36Sopenharmony_ciscosh:
761562306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
761662306a36Sopenharmony_ci
761762306a36Sopenharmony_ci	mov.l		(%a0),%d1
761862306a36Sopenharmony_ci	mov.w		4(%a0),%d1
761962306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
762062306a36Sopenharmony_ci	cmp.l		%d1,&0x400CB167
762162306a36Sopenharmony_ci	bgt.b		COSHBIG
762262306a36Sopenharmony_ci
762362306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 16380 LOG2
762462306a36Sopenharmony_ci#--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
762562306a36Sopenharmony_ci
762662306a36Sopenharmony_ci	fabs.x		%fp0			# |X|
762762306a36Sopenharmony_ci
762862306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
762962306a36Sopenharmony_ci	clr.l		%d0
763062306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save |X| to stack
763162306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to |X|
763262306a36Sopenharmony_ci	bsr		setox			# FP0 IS EXP(|X|)
763362306a36Sopenharmony_ci	add.l		&0xc,%sp		# erase |X| from stack
763462306a36Sopenharmony_ci	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
763562306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
763662306a36Sopenharmony_ci
763762306a36Sopenharmony_ci	fmov.s		&0x3E800000,%fp1	# (1/4)
763862306a36Sopenharmony_ci	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
763962306a36Sopenharmony_ci
764062306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
764162306a36Sopenharmony_ci	mov.b		&FADD_OP,%d1		# last inst is ADD
764262306a36Sopenharmony_ci	fadd.x		%fp1,%fp0
764362306a36Sopenharmony_ci	bra		t_catch
764462306a36Sopenharmony_ci
764562306a36Sopenharmony_ciCOSHBIG:
764662306a36Sopenharmony_ci	cmp.l		%d1,&0x400CB2B3
764762306a36Sopenharmony_ci	bgt.b		COSHHUGE
764862306a36Sopenharmony_ci
764962306a36Sopenharmony_ci	fabs.x		%fp0
765062306a36Sopenharmony_ci	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
765162306a36Sopenharmony_ci	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
765262306a36Sopenharmony_ci
765362306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
765462306a36Sopenharmony_ci	clr.l		%d0
765562306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
765662306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to fp0
765762306a36Sopenharmony_ci	bsr		setox
765862306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear fp0 from stack
765962306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
766062306a36Sopenharmony_ci
766162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
766262306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
766362306a36Sopenharmony_ci	fmul.x		TWO16380(%pc),%fp0
766462306a36Sopenharmony_ci	bra		t_catch
766562306a36Sopenharmony_ci
766662306a36Sopenharmony_ciCOSHHUGE:
766762306a36Sopenharmony_ci	bra		t_ovfl2
766862306a36Sopenharmony_ci
766962306a36Sopenharmony_ci	global		scoshd
767062306a36Sopenharmony_ci#--COSH(X) = 1 FOR DENORMALIZED X
767162306a36Sopenharmony_ciscoshd:
767262306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp0
767362306a36Sopenharmony_ci
767462306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
767562306a36Sopenharmony_ci	fadd.s		&0x00800000,%fp0
767662306a36Sopenharmony_ci	bra		t_pinx2
767762306a36Sopenharmony_ci
767862306a36Sopenharmony_ci#########################################################################
767962306a36Sopenharmony_ci# ssinh():  computes the hyperbolic sine of a normalized input		#
768062306a36Sopenharmony_ci# ssinhd(): computes the hyperbolic sine of a denormalized input	#
768162306a36Sopenharmony_ci#									#
768262306a36Sopenharmony_ci# INPUT *************************************************************** #
768362306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
768462306a36Sopenharmony_ci#	d0 = round precision,mode					#
768562306a36Sopenharmony_ci#									#
768662306a36Sopenharmony_ci# OUTPUT ************************************************************** #
768762306a36Sopenharmony_ci#	fp0 = sinh(X)							#
768862306a36Sopenharmony_ci#									#
768962306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
769062306a36Sopenharmony_ci#	The returned result is within 3 ulps in 64 significant bit,	#
769162306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
769262306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
769362306a36Sopenharmony_ci#	in double precision.						#
769462306a36Sopenharmony_ci#									#
769562306a36Sopenharmony_ci# ALGORITHM *********************************************************** #
769662306a36Sopenharmony_ci#									#
769762306a36Sopenharmony_ci#       SINH								#
769862306a36Sopenharmony_ci#       1. If |X| > 16380 log2, go to 3.				#
769962306a36Sopenharmony_ci#									#
770062306a36Sopenharmony_ci#       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
770162306a36Sopenharmony_ci#               y = |X|, sgn = sign(X), and z = expm1(Y),		#
770262306a36Sopenharmony_ci#               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
770362306a36Sopenharmony_ci#          Exit.							#
770462306a36Sopenharmony_ci#									#
770562306a36Sopenharmony_ci#       3. If |X| > 16480 log2, go to 5.				#
770662306a36Sopenharmony_ci#									#
770762306a36Sopenharmony_ci#       4. (16380 log2 < |X| <= 16480 log2)				#
770862306a36Sopenharmony_ci#               sinh(X) = sign(X) * exp(|X|)/2.				#
770962306a36Sopenharmony_ci#          However, invoking exp(|X|) may cause premature overflow.	#
771062306a36Sopenharmony_ci#          Thus, we calculate sinh(X) as follows:			#
771162306a36Sopenharmony_ci#             Y       := |X|						#
771262306a36Sopenharmony_ci#             sgn     := sign(X)					#
771362306a36Sopenharmony_ci#             sgnFact := sgn * 2**(16380)				#
771462306a36Sopenharmony_ci#             Y'      := Y - 16381 log2					#
771562306a36Sopenharmony_ci#             sinh(X) := sgnFact * exp(Y').				#
771662306a36Sopenharmony_ci#          Exit.							#
771762306a36Sopenharmony_ci#									#
771862306a36Sopenharmony_ci#       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
771962306a36Sopenharmony_ci#          sign(X)*Huge*Huge to generate overflow and an infinity with	#
772062306a36Sopenharmony_ci#          the appropriate sign. Huge is the largest finite number in	#
772162306a36Sopenharmony_ci#          extended format. Exit.					#
772262306a36Sopenharmony_ci#									#
772362306a36Sopenharmony_ci#########################################################################
772462306a36Sopenharmony_ci
772562306a36Sopenharmony_ci	global		ssinh
772662306a36Sopenharmony_cissinh:
772762306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
772862306a36Sopenharmony_ci
772962306a36Sopenharmony_ci	mov.l		(%a0),%d1
773062306a36Sopenharmony_ci	mov.w		4(%a0),%d1
773162306a36Sopenharmony_ci	mov.l		%d1,%a1			# save (compacted) operand
773262306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
773362306a36Sopenharmony_ci	cmp.l		%d1,&0x400CB167
773462306a36Sopenharmony_ci	bgt.b		SINHBIG
773562306a36Sopenharmony_ci
773662306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 16380 LOG2
773762306a36Sopenharmony_ci#--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
773862306a36Sopenharmony_ci
773962306a36Sopenharmony_ci	fabs.x		%fp0			# Y = |X|
774062306a36Sopenharmony_ci
774162306a36Sopenharmony_ci	movm.l		&0x8040,-(%sp)		# {a1/d0}
774262306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save Y on stack
774362306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to Y
774462306a36Sopenharmony_ci	clr.l		%d0
774562306a36Sopenharmony_ci	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
774662306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear Y from stack
774762306a36Sopenharmony_ci	fmov.l		&0,%fpcr
774862306a36Sopenharmony_ci	movm.l		(%sp)+,&0x0201		# {a1/d0}
774962306a36Sopenharmony_ci
775062306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
775162306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp1	# 1+Z
775262306a36Sopenharmony_ci	fmov.x		%fp0,-(%sp)
775362306a36Sopenharmony_ci	fdiv.x		%fp1,%fp0		# Z/(1+Z)
775462306a36Sopenharmony_ci	mov.l		%a1,%d1
775562306a36Sopenharmony_ci	and.l		&0x80000000,%d1
775662306a36Sopenharmony_ci	or.l		&0x3F000000,%d1
775762306a36Sopenharmony_ci	fadd.x		(%sp)+,%fp0
775862306a36Sopenharmony_ci	mov.l		%d1,-(%sp)
775962306a36Sopenharmony_ci
776062306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
776162306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
776262306a36Sopenharmony_ci	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
776362306a36Sopenharmony_ci	bra		t_catch
776462306a36Sopenharmony_ci
776562306a36Sopenharmony_ciSINHBIG:
776662306a36Sopenharmony_ci	cmp.l		%d1,&0x400CB2B3
776762306a36Sopenharmony_ci	bgt		t_ovfl
776862306a36Sopenharmony_ci	fabs.x		%fp0
776962306a36Sopenharmony_ci	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
777062306a36Sopenharmony_ci	mov.l		&0,-(%sp)
777162306a36Sopenharmony_ci	mov.l		&0x80000000,-(%sp)
777262306a36Sopenharmony_ci	mov.l		%a1,%d1
777362306a36Sopenharmony_ci	and.l		&0x80000000,%d1
777462306a36Sopenharmony_ci	or.l		&0x7FFB0000,%d1
777562306a36Sopenharmony_ci	mov.l		%d1,-(%sp)		# EXTENDED FMT
777662306a36Sopenharmony_ci	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
777762306a36Sopenharmony_ci
777862306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
777962306a36Sopenharmony_ci	clr.l		%d0
778062306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
778162306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to fp0
778262306a36Sopenharmony_ci	bsr		setox
778362306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear fp0 from stack
778462306a36Sopenharmony_ci
778562306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
778662306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
778762306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
778862306a36Sopenharmony_ci	fmul.x		(%sp)+,%fp0		# possible exception
778962306a36Sopenharmony_ci	bra		t_catch
779062306a36Sopenharmony_ci
779162306a36Sopenharmony_ci	global		ssinhd
779262306a36Sopenharmony_ci#--SINH(X) = X FOR DENORMALIZED X
779362306a36Sopenharmony_cissinhd:
779462306a36Sopenharmony_ci	bra		t_extdnrm
779562306a36Sopenharmony_ci
779662306a36Sopenharmony_ci#########################################################################
779762306a36Sopenharmony_ci# stanh():  computes the hyperbolic tangent of a normalized input	#
779862306a36Sopenharmony_ci# stanhd(): computes the hyperbolic tangent of a denormalized input	#
779962306a36Sopenharmony_ci#									#
780062306a36Sopenharmony_ci# INPUT ***************************************************************	#
780162306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
780262306a36Sopenharmony_ci#	d0 = round precision,mode					#
780362306a36Sopenharmony_ci#									#
780462306a36Sopenharmony_ci# OUTPUT **************************************************************	#
780562306a36Sopenharmony_ci#	fp0 = tanh(X)							#
780662306a36Sopenharmony_ci#									#
780762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
780862306a36Sopenharmony_ci#	The returned result is within 3 ulps in 64 significant bit,	#
780962306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
781062306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
781162306a36Sopenharmony_ci#	in double precision.						#
781262306a36Sopenharmony_ci#									#
781362306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
781462306a36Sopenharmony_ci#									#
781562306a36Sopenharmony_ci#	TANH								#
781662306a36Sopenharmony_ci#	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
781762306a36Sopenharmony_ci#									#
781862306a36Sopenharmony_ci#	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
781962306a36Sopenharmony_ci#		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
782062306a36Sopenharmony_ci#		tanh(X) = sgn*( z/(2+z) ).				#
782162306a36Sopenharmony_ci#		Exit.							#
782262306a36Sopenharmony_ci#									#
782362306a36Sopenharmony_ci#	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
782462306a36Sopenharmony_ci#		go to 7.						#
782562306a36Sopenharmony_ci#									#
782662306a36Sopenharmony_ci#	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
782762306a36Sopenharmony_ci#									#
782862306a36Sopenharmony_ci#	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
782962306a36Sopenharmony_ci#		sgn := sign(X), y := 2|X|, z := exp(Y),			#
783062306a36Sopenharmony_ci#		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
783162306a36Sopenharmony_ci#		Exit.							#
783262306a36Sopenharmony_ci#									#
783362306a36Sopenharmony_ci#	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
783462306a36Sopenharmony_ci#		calculate Tanh(X) by					#
783562306a36Sopenharmony_ci#		sgn := sign(X), Tiny := 2**(-126),			#
783662306a36Sopenharmony_ci#		tanh(X) := sgn - sgn*Tiny.				#
783762306a36Sopenharmony_ci#		Exit.							#
783862306a36Sopenharmony_ci#									#
783962306a36Sopenharmony_ci#	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
784062306a36Sopenharmony_ci#									#
784162306a36Sopenharmony_ci#########################################################################
784262306a36Sopenharmony_ci
784362306a36Sopenharmony_ci	set		X,FP_SCR0
784462306a36Sopenharmony_ci	set		XFRAC,X+4
784562306a36Sopenharmony_ci
784662306a36Sopenharmony_ci	set		SGN,L_SCR3
784762306a36Sopenharmony_ci
784862306a36Sopenharmony_ci	set		V,FP_SCR0
784962306a36Sopenharmony_ci
785062306a36Sopenharmony_ci	global		stanh
785162306a36Sopenharmony_cistanh:
785262306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
785362306a36Sopenharmony_ci
785462306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)
785562306a36Sopenharmony_ci	mov.l		(%a0),%d1
785662306a36Sopenharmony_ci	mov.w		4(%a0),%d1
785762306a36Sopenharmony_ci	mov.l		%d1,X(%a6)
785862306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
785962306a36Sopenharmony_ci	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
786062306a36Sopenharmony_ci	blt.w		TANHBORS		# yes
786162306a36Sopenharmony_ci	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
786262306a36Sopenharmony_ci	bgt.w		TANHBORS		# yes
786362306a36Sopenharmony_ci
786462306a36Sopenharmony_ci#--THIS IS THE USUAL CASE
786562306a36Sopenharmony_ci#--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
786662306a36Sopenharmony_ci
786762306a36Sopenharmony_ci	mov.l		X(%a6),%d1
786862306a36Sopenharmony_ci	mov.l		%d1,SGN(%a6)
786962306a36Sopenharmony_ci	and.l		&0x7FFF0000,%d1
787062306a36Sopenharmony_ci	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
787162306a36Sopenharmony_ci	mov.l		%d1,X(%a6)
787262306a36Sopenharmony_ci	and.l		&0x80000000,SGN(%a6)
787362306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
787462306a36Sopenharmony_ci
787562306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
787662306a36Sopenharmony_ci	clr.l		%d0
787762306a36Sopenharmony_ci	fmovm.x		&0x1,-(%sp)		# save Y on stack
787862306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to Y
787962306a36Sopenharmony_ci	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
788062306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear Y from stack
788162306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
788262306a36Sopenharmony_ci
788362306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
788462306a36Sopenharmony_ci	fadd.s		&0x40000000,%fp1	# Z+2
788562306a36Sopenharmony_ci	mov.l		SGN(%a6),%d1
788662306a36Sopenharmony_ci	fmov.x		%fp1,V(%a6)
788762306a36Sopenharmony_ci	eor.l		%d1,V(%a6)
788862306a36Sopenharmony_ci
788962306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round prec,mode
789062306a36Sopenharmony_ci	fdiv.x		V(%a6),%fp0
789162306a36Sopenharmony_ci	bra		t_inx2
789262306a36Sopenharmony_ci
789362306a36Sopenharmony_ciTANHBORS:
789462306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
789562306a36Sopenharmony_ci	blt.w		TANHSM
789662306a36Sopenharmony_ci
789762306a36Sopenharmony_ci	cmp.l		%d1,&0x40048AA1
789862306a36Sopenharmony_ci	bgt.w		TANHHUGE
789962306a36Sopenharmony_ci
790062306a36Sopenharmony_ci#-- (5/2) LOG2 < |X| < 50 LOG2,
790162306a36Sopenharmony_ci#--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
790262306a36Sopenharmony_ci#--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
790362306a36Sopenharmony_ci
790462306a36Sopenharmony_ci	mov.l		X(%a6),%d1
790562306a36Sopenharmony_ci	mov.l		%d1,SGN(%a6)
790662306a36Sopenharmony_ci	and.l		&0x7FFF0000,%d1
790762306a36Sopenharmony_ci	add.l		&0x00010000,%d1		# EXPO OF 2|X|
790862306a36Sopenharmony_ci	mov.l		%d1,X(%a6)		# Y = 2|X|
790962306a36Sopenharmony_ci	and.l		&0x80000000,SGN(%a6)
791062306a36Sopenharmony_ci	mov.l		SGN(%a6),%d1
791162306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0		# Y = 2|X|
791262306a36Sopenharmony_ci
791362306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
791462306a36Sopenharmony_ci	clr.l		%d0
791562306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save Y on stack
791662306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to Y
791762306a36Sopenharmony_ci	bsr		setox			# FP0 IS EXP(Y)
791862306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear Y from stack
791962306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
792062306a36Sopenharmony_ci	mov.l		SGN(%a6),%d1
792162306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
792262306a36Sopenharmony_ci
792362306a36Sopenharmony_ci	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
792462306a36Sopenharmony_ci	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
792562306a36Sopenharmony_ci	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
792662306a36Sopenharmony_ci
792762306a36Sopenharmony_ci	mov.l		SGN(%a6),%d1
792862306a36Sopenharmony_ci	or.l		&0x3F800000,%d1		# SGN
792962306a36Sopenharmony_ci	fmov.s		%d1,%fp0		# SGN IN SGL FMT
793062306a36Sopenharmony_ci
793162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round prec,mode
793262306a36Sopenharmony_ci	mov.b		&FADD_OP,%d1		# last inst is ADD
793362306a36Sopenharmony_ci	fadd.x		%fp1,%fp0
793462306a36Sopenharmony_ci	bra		t_inx2
793562306a36Sopenharmony_ci
793662306a36Sopenharmony_ciTANHSM:
793762306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round prec,mode
793862306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
793962306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0		# last inst - possible exception set
794062306a36Sopenharmony_ci	bra		t_catch
794162306a36Sopenharmony_ci
794262306a36Sopenharmony_ci#---RETURN SGN(X) - SGN(X)EPS
794362306a36Sopenharmony_ciTANHHUGE:
794462306a36Sopenharmony_ci	mov.l		X(%a6),%d1
794562306a36Sopenharmony_ci	and.l		&0x80000000,%d1
794662306a36Sopenharmony_ci	or.l		&0x3F800000,%d1
794762306a36Sopenharmony_ci	fmov.s		%d1,%fp0
794862306a36Sopenharmony_ci	and.l		&0x80000000,%d1
794962306a36Sopenharmony_ci	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
795062306a36Sopenharmony_ci
795162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round prec,mode
795262306a36Sopenharmony_ci	fadd.s		%d1,%fp0
795362306a36Sopenharmony_ci	bra		t_inx2
795462306a36Sopenharmony_ci
795562306a36Sopenharmony_ci	global		stanhd
795662306a36Sopenharmony_ci#--TANH(X) = X FOR DENORMALIZED X
795762306a36Sopenharmony_cistanhd:
795862306a36Sopenharmony_ci	bra		t_extdnrm
795962306a36Sopenharmony_ci
796062306a36Sopenharmony_ci#########################################################################
796162306a36Sopenharmony_ci# slogn():    computes the natural logarithm of a normalized input	#
796262306a36Sopenharmony_ci# slognd():   computes the natural logarithm of a denormalized input	#
796362306a36Sopenharmony_ci# slognp1():  computes the log(1+X) of a normalized input		#
796462306a36Sopenharmony_ci# slognp1d(): computes the log(1+X) of a denormalized input		#
796562306a36Sopenharmony_ci#									#
796662306a36Sopenharmony_ci# INPUT ***************************************************************	#
796762306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
796862306a36Sopenharmony_ci#	d0 = round precision,mode					#
796962306a36Sopenharmony_ci#									#
797062306a36Sopenharmony_ci# OUTPUT **************************************************************	#
797162306a36Sopenharmony_ci#	fp0 = log(X) or log(1+X)					#
797262306a36Sopenharmony_ci#									#
797362306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
797462306a36Sopenharmony_ci#	The returned result is within 2 ulps in 64 significant bit,	#
797562306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
797662306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
797762306a36Sopenharmony_ci#	in double precision.						#
797862306a36Sopenharmony_ci#									#
797962306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
798062306a36Sopenharmony_ci#	LOGN:								#
798162306a36Sopenharmony_ci#	Step 1. If |X-1| < 1/16, approximate log(X) by an odd		#
798262306a36Sopenharmony_ci#		polynomial in u, where u = 2(X-1)/(X+1). Otherwise,	#
798362306a36Sopenharmony_ci#		move on to Step 2.					#
798462306a36Sopenharmony_ci#									#
798562306a36Sopenharmony_ci#	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
798662306a36Sopenharmony_ci#		seven significant bits of Y plus 2**(-7), i.e.		#
798762306a36Sopenharmony_ci#		F = 1.xxxxxx1 in base 2 where the six "x" match those	#
798862306a36Sopenharmony_ci#		of Y. Note that |Y-F| <= 2**(-7).			#
798962306a36Sopenharmony_ci#									#
799062306a36Sopenharmony_ci#	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a		#
799162306a36Sopenharmony_ci#		polynomial in u, log(1+u) = poly.			#
799262306a36Sopenharmony_ci#									#
799362306a36Sopenharmony_ci#	Step 4. Reconstruct						#
799462306a36Sopenharmony_ci#		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
799562306a36Sopenharmony_ci#		by k*log(2) + (log(F) + poly). The values of log(F) are	#
799662306a36Sopenharmony_ci#		calculated beforehand and stored in the program.	#
799762306a36Sopenharmony_ci#									#
799862306a36Sopenharmony_ci#	lognp1:								#
799962306a36Sopenharmony_ci#	Step 1: If |X| < 1/16, approximate log(1+X) by an odd		#
800062306a36Sopenharmony_ci#		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
800162306a36Sopenharmony_ci#		to Step 2.						#
800262306a36Sopenharmony_ci#									#
800362306a36Sopenharmony_ci#	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
800462306a36Sopenharmony_ci#		in Step 2 of the algorithm for LOGN and compute		#
800562306a36Sopenharmony_ci#		log(1+X) as k*log(2) + log(F) + poly where poly		#
800662306a36Sopenharmony_ci#		approximates log(1+u), u = (Y-F)/F.			#
800762306a36Sopenharmony_ci#									#
800862306a36Sopenharmony_ci#	Implementation Notes:						#
800962306a36Sopenharmony_ci#	Note 1. There are 64 different possible values for F, thus 64	#
801062306a36Sopenharmony_ci#		log(F)'s need to be tabulated. Moreover, the values of	#
801162306a36Sopenharmony_ci#		1/F are also tabulated so that the division in (Y-F)/F	#
801262306a36Sopenharmony_ci#		can be performed by a multiplication.			#
801362306a36Sopenharmony_ci#									#
801462306a36Sopenharmony_ci#	Note 2. In Step 2 of lognp1, in order to preserved accuracy,	#
801562306a36Sopenharmony_ci#		the value Y-F has to be calculated carefully when	#
801662306a36Sopenharmony_ci#		1/2 <= X < 3/2.						#
801762306a36Sopenharmony_ci#									#
801862306a36Sopenharmony_ci#	Note 3. To fully exploit the pipeline, polynomials are usually	#
801962306a36Sopenharmony_ci#		separated into two parts evaluated independently before	#
802062306a36Sopenharmony_ci#		being added up.						#
802162306a36Sopenharmony_ci#									#
802262306a36Sopenharmony_ci#########################################################################
802362306a36Sopenharmony_ciLOGOF2:
802462306a36Sopenharmony_ci	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
802562306a36Sopenharmony_ci
802662306a36Sopenharmony_cione:
802762306a36Sopenharmony_ci	long		0x3F800000
802862306a36Sopenharmony_cizero:
802962306a36Sopenharmony_ci	long		0x00000000
803062306a36Sopenharmony_ciinfty:
803162306a36Sopenharmony_ci	long		0x7F800000
803262306a36Sopenharmony_cinegone:
803362306a36Sopenharmony_ci	long		0xBF800000
803462306a36Sopenharmony_ci
803562306a36Sopenharmony_ciLOGA6:
803662306a36Sopenharmony_ci	long		0x3FC2499A,0xB5E4040B
803762306a36Sopenharmony_ciLOGA5:
803862306a36Sopenharmony_ci	long		0xBFC555B5,0x848CB7DB
803962306a36Sopenharmony_ci
804062306a36Sopenharmony_ciLOGA4:
804162306a36Sopenharmony_ci	long		0x3FC99999,0x987D8730
804262306a36Sopenharmony_ciLOGA3:
804362306a36Sopenharmony_ci	long		0xBFCFFFFF,0xFF6F7E97
804462306a36Sopenharmony_ci
804562306a36Sopenharmony_ciLOGA2:
804662306a36Sopenharmony_ci	long		0x3FD55555,0x555555A4
804762306a36Sopenharmony_ciLOGA1:
804862306a36Sopenharmony_ci	long		0xBFE00000,0x00000008
804962306a36Sopenharmony_ci
805062306a36Sopenharmony_ciLOGB5:
805162306a36Sopenharmony_ci	long		0x3F175496,0xADD7DAD6
805262306a36Sopenharmony_ciLOGB4:
805362306a36Sopenharmony_ci	long		0x3F3C71C2,0xFE80C7E0
805462306a36Sopenharmony_ci
805562306a36Sopenharmony_ciLOGB3:
805662306a36Sopenharmony_ci	long		0x3F624924,0x928BCCFF
805762306a36Sopenharmony_ciLOGB2:
805862306a36Sopenharmony_ci	long		0x3F899999,0x999995EC
805962306a36Sopenharmony_ci
806062306a36Sopenharmony_ciLOGB1:
806162306a36Sopenharmony_ci	long		0x3FB55555,0x55555555
806262306a36Sopenharmony_ciTWO:
806362306a36Sopenharmony_ci	long		0x40000000,0x00000000
806462306a36Sopenharmony_ci
806562306a36Sopenharmony_ciLTHOLD:
806662306a36Sopenharmony_ci	long		0x3f990000,0x80000000,0x00000000,0x00000000
806762306a36Sopenharmony_ci
806862306a36Sopenharmony_ciLOGTBL:
806962306a36Sopenharmony_ci	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
807062306a36Sopenharmony_ci	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
807162306a36Sopenharmony_ci	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
807262306a36Sopenharmony_ci	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
807362306a36Sopenharmony_ci	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
807462306a36Sopenharmony_ci	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
807562306a36Sopenharmony_ci	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
807662306a36Sopenharmony_ci	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
807762306a36Sopenharmony_ci	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
807862306a36Sopenharmony_ci	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
807962306a36Sopenharmony_ci	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
808062306a36Sopenharmony_ci	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
808162306a36Sopenharmony_ci	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
808262306a36Sopenharmony_ci	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
808362306a36Sopenharmony_ci	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
808462306a36Sopenharmony_ci	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
808562306a36Sopenharmony_ci	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
808662306a36Sopenharmony_ci	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
808762306a36Sopenharmony_ci	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
808862306a36Sopenharmony_ci	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
808962306a36Sopenharmony_ci	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
809062306a36Sopenharmony_ci	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
809162306a36Sopenharmony_ci	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
809262306a36Sopenharmony_ci	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
809362306a36Sopenharmony_ci	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
809462306a36Sopenharmony_ci	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
809562306a36Sopenharmony_ci	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
809662306a36Sopenharmony_ci	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
809762306a36Sopenharmony_ci	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
809862306a36Sopenharmony_ci	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
809962306a36Sopenharmony_ci	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
810062306a36Sopenharmony_ci	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
810162306a36Sopenharmony_ci	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
810262306a36Sopenharmony_ci	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
810362306a36Sopenharmony_ci	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
810462306a36Sopenharmony_ci	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
810562306a36Sopenharmony_ci	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
810662306a36Sopenharmony_ci	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
810762306a36Sopenharmony_ci	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
810862306a36Sopenharmony_ci	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
810962306a36Sopenharmony_ci	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
811062306a36Sopenharmony_ci	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
811162306a36Sopenharmony_ci	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
811262306a36Sopenharmony_ci	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
811362306a36Sopenharmony_ci	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
811462306a36Sopenharmony_ci	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
811562306a36Sopenharmony_ci	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
811662306a36Sopenharmony_ci	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
811762306a36Sopenharmony_ci	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
811862306a36Sopenharmony_ci	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
811962306a36Sopenharmony_ci	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
812062306a36Sopenharmony_ci	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
812162306a36Sopenharmony_ci	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
812262306a36Sopenharmony_ci	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
812362306a36Sopenharmony_ci	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
812462306a36Sopenharmony_ci	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
812562306a36Sopenharmony_ci	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
812662306a36Sopenharmony_ci	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
812762306a36Sopenharmony_ci	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
812862306a36Sopenharmony_ci	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
812962306a36Sopenharmony_ci	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
813062306a36Sopenharmony_ci	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
813162306a36Sopenharmony_ci	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
813262306a36Sopenharmony_ci	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
813362306a36Sopenharmony_ci	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
813462306a36Sopenharmony_ci	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
813562306a36Sopenharmony_ci	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
813662306a36Sopenharmony_ci	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
813762306a36Sopenharmony_ci	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
813862306a36Sopenharmony_ci	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
813962306a36Sopenharmony_ci	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
814062306a36Sopenharmony_ci	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
814162306a36Sopenharmony_ci	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
814262306a36Sopenharmony_ci	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
814362306a36Sopenharmony_ci	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
814462306a36Sopenharmony_ci	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
814562306a36Sopenharmony_ci	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
814662306a36Sopenharmony_ci	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
814762306a36Sopenharmony_ci	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
814862306a36Sopenharmony_ci	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
814962306a36Sopenharmony_ci	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
815062306a36Sopenharmony_ci	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
815162306a36Sopenharmony_ci	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
815262306a36Sopenharmony_ci	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
815362306a36Sopenharmony_ci	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
815462306a36Sopenharmony_ci	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
815562306a36Sopenharmony_ci	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
815662306a36Sopenharmony_ci	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
815762306a36Sopenharmony_ci	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
815862306a36Sopenharmony_ci	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
815962306a36Sopenharmony_ci	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
816062306a36Sopenharmony_ci	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
816162306a36Sopenharmony_ci	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
816262306a36Sopenharmony_ci	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
816362306a36Sopenharmony_ci	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
816462306a36Sopenharmony_ci	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
816562306a36Sopenharmony_ci	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
816662306a36Sopenharmony_ci	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
816762306a36Sopenharmony_ci	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
816862306a36Sopenharmony_ci	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
816962306a36Sopenharmony_ci	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
817062306a36Sopenharmony_ci	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
817162306a36Sopenharmony_ci	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
817262306a36Sopenharmony_ci	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
817362306a36Sopenharmony_ci	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
817462306a36Sopenharmony_ci	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
817562306a36Sopenharmony_ci	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
817662306a36Sopenharmony_ci	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
817762306a36Sopenharmony_ci	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
817862306a36Sopenharmony_ci	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
817962306a36Sopenharmony_ci	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
818062306a36Sopenharmony_ci	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
818162306a36Sopenharmony_ci	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
818262306a36Sopenharmony_ci	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
818362306a36Sopenharmony_ci	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
818462306a36Sopenharmony_ci	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
818562306a36Sopenharmony_ci	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
818662306a36Sopenharmony_ci	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
818762306a36Sopenharmony_ci	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
818862306a36Sopenharmony_ci	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
818962306a36Sopenharmony_ci	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
819062306a36Sopenharmony_ci	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
819162306a36Sopenharmony_ci	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
819262306a36Sopenharmony_ci	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
819362306a36Sopenharmony_ci	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
819462306a36Sopenharmony_ci	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
819562306a36Sopenharmony_ci	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
819662306a36Sopenharmony_ci	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
819762306a36Sopenharmony_ci
819862306a36Sopenharmony_ci	set		ADJK,L_SCR1
819962306a36Sopenharmony_ci
820062306a36Sopenharmony_ci	set		X,FP_SCR0
820162306a36Sopenharmony_ci	set		XDCARE,X+2
820262306a36Sopenharmony_ci	set		XFRAC,X+4
820362306a36Sopenharmony_ci
820462306a36Sopenharmony_ci	set		F,FP_SCR1
820562306a36Sopenharmony_ci	set		FFRAC,F+4
820662306a36Sopenharmony_ci
820762306a36Sopenharmony_ci	set		KLOG2,FP_SCR0
820862306a36Sopenharmony_ci
820962306a36Sopenharmony_ci	set		SAVEU,FP_SCR0
821062306a36Sopenharmony_ci
821162306a36Sopenharmony_ci	global		slogn
821262306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
821362306a36Sopenharmony_cislogn:
821462306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
821562306a36Sopenharmony_ci	mov.l		&0x00000000,ADJK(%a6)
821662306a36Sopenharmony_ci
821762306a36Sopenharmony_ciLOGBGN:
821862306a36Sopenharmony_ci#--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
821962306a36Sopenharmony_ci#--A FINITE, NON-ZERO, NORMALIZED NUMBER.
822062306a36Sopenharmony_ci
822162306a36Sopenharmony_ci	mov.l		(%a0),%d1
822262306a36Sopenharmony_ci	mov.w		4(%a0),%d1
822362306a36Sopenharmony_ci
822462306a36Sopenharmony_ci	mov.l		(%a0),X(%a6)
822562306a36Sopenharmony_ci	mov.l		4(%a0),X+4(%a6)
822662306a36Sopenharmony_ci	mov.l		8(%a0),X+8(%a6)
822762306a36Sopenharmony_ci
822862306a36Sopenharmony_ci	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
822962306a36Sopenharmony_ci	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
823062306a36Sopenharmony_ci# X IS POSITIVE, CHECK IF X IS NEAR 1
823162306a36Sopenharmony_ci	cmp.l		%d1,&0x3ffef07d		# IS X < 15/16?
823262306a36Sopenharmony_ci	blt.b		LOGMAIN			# YES
823362306a36Sopenharmony_ci	cmp.l		%d1,&0x3fff8841		# IS X > 17/16?
823462306a36Sopenharmony_ci	ble.w		LOGNEAR1		# NO
823562306a36Sopenharmony_ci
823662306a36Sopenharmony_ciLOGMAIN:
823762306a36Sopenharmony_ci#--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
823862306a36Sopenharmony_ci
823962306a36Sopenharmony_ci#--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
824062306a36Sopenharmony_ci#--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
824162306a36Sopenharmony_ci#--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
824262306a36Sopenharmony_ci#--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
824362306a36Sopenharmony_ci#--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
824462306a36Sopenharmony_ci#--LOG(1+U) CAN BE VERY EFFICIENT.
824562306a36Sopenharmony_ci#--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
824662306a36Sopenharmony_ci#--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
824762306a36Sopenharmony_ci
824862306a36Sopenharmony_ci#--GET K, Y, F, AND ADDRESS OF 1/F.
824962306a36Sopenharmony_ci	asr.l		&8,%d1
825062306a36Sopenharmony_ci	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
825162306a36Sopenharmony_ci	sub.l		&0x3FFF,%d1		# THIS IS K
825262306a36Sopenharmony_ci	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
825362306a36Sopenharmony_ci	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
825462306a36Sopenharmony_ci	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
825562306a36Sopenharmony_ci
825662306a36Sopenharmony_ci#--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
825762306a36Sopenharmony_ci	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
825862306a36Sopenharmony_ci	mov.l		XFRAC(%a6),FFRAC(%a6)
825962306a36Sopenharmony_ci	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
826062306a36Sopenharmony_ci	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
826162306a36Sopenharmony_ci	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
826262306a36Sopenharmony_ci	and.l		&0x7E000000,%d1
826362306a36Sopenharmony_ci	asr.l		&8,%d1
826462306a36Sopenharmony_ci	asr.l		&8,%d1
826562306a36Sopenharmony_ci	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
826662306a36Sopenharmony_ci	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
826762306a36Sopenharmony_ci
826862306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0
826962306a36Sopenharmony_ci	mov.l		&0x3fff0000,F(%a6)
827062306a36Sopenharmony_ci	clr.l		F+8(%a6)
827162306a36Sopenharmony_ci	fsub.x		F(%a6),%fp0		# Y-F
827262306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
827362306a36Sopenharmony_ci#--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
827462306a36Sopenharmony_ci#--REGISTERS SAVED: FPCR, FP1, FP2
827562306a36Sopenharmony_ci
827662306a36Sopenharmony_ciLP1CONT1:
827762306a36Sopenharmony_ci#--AN RE-ENTRY POINT FOR LOGNP1
827862306a36Sopenharmony_ci	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
827962306a36Sopenharmony_ci	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
828062306a36Sopenharmony_ci	fmov.x		%fp0,%fp2
828162306a36Sopenharmony_ci	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
828262306a36Sopenharmony_ci	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
828362306a36Sopenharmony_ci
828462306a36Sopenharmony_ci#--LOG(1+U) IS APPROXIMATED BY
828562306a36Sopenharmony_ci#--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
828662306a36Sopenharmony_ci#--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
828762306a36Sopenharmony_ci
828862306a36Sopenharmony_ci	fmov.x		%fp2,%fp3
828962306a36Sopenharmony_ci	fmov.x		%fp2,%fp1
829062306a36Sopenharmony_ci
829162306a36Sopenharmony_ci	fmul.d		LOGA6(%pc),%fp1		# V*A6
829262306a36Sopenharmony_ci	fmul.d		LOGA5(%pc),%fp2		# V*A5
829362306a36Sopenharmony_ci
829462306a36Sopenharmony_ci	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
829562306a36Sopenharmony_ci	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
829662306a36Sopenharmony_ci
829762306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
829862306a36Sopenharmony_ci	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
829962306a36Sopenharmony_ci
830062306a36Sopenharmony_ci	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
830162306a36Sopenharmony_ci	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
830262306a36Sopenharmony_ci
830362306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
830462306a36Sopenharmony_ci	add.l		&16,%a0			# ADDRESS OF LOG(F)
830562306a36Sopenharmony_ci	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
830662306a36Sopenharmony_ci
830762306a36Sopenharmony_ci	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
830862306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
830962306a36Sopenharmony_ci
831062306a36Sopenharmony_ci	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
831162306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
831262306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
831362306a36Sopenharmony_ci
831462306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
831562306a36Sopenharmony_ci	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
831662306a36Sopenharmony_ci	bra		t_inx2
831762306a36Sopenharmony_ci
831862306a36Sopenharmony_ci
831962306a36Sopenharmony_ciLOGNEAR1:
832062306a36Sopenharmony_ci
832162306a36Sopenharmony_ci# if the input is exactly equal to one, then exit through ld_pzero.
832262306a36Sopenharmony_ci# if these 2 lines weren't here, the correct answer would be returned
832362306a36Sopenharmony_ci# but the INEX2 bit would be set.
832462306a36Sopenharmony_ci	fcmp.b		%fp0,&0x1		# is it equal to one?
832562306a36Sopenharmony_ci	fbeq.l		ld_pzero		# yes
832662306a36Sopenharmony_ci
832762306a36Sopenharmony_ci#--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
832862306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
832962306a36Sopenharmony_ci	fsub.s		one(%pc),%fp1		# FP1 IS X-1
833062306a36Sopenharmony_ci	fadd.s		one(%pc),%fp0		# FP0 IS X+1
833162306a36Sopenharmony_ci	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
833262306a36Sopenharmony_ci#--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
833362306a36Sopenharmony_ci#--IN U, U = 2(X-1)/(X+1) = FP1/FP0
833462306a36Sopenharmony_ci
833562306a36Sopenharmony_ciLP1CONT2:
833662306a36Sopenharmony_ci#--THIS IS AN RE-ENTRY POINT FOR LOGNP1
833762306a36Sopenharmony_ci	fdiv.x		%fp0,%fp1		# FP1 IS U
833862306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
833962306a36Sopenharmony_ci#--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
834062306a36Sopenharmony_ci#--LET V=U*U, W=V*V, CALCULATE
834162306a36Sopenharmony_ci#--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
834262306a36Sopenharmony_ci#--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
834362306a36Sopenharmony_ci	fmov.x		%fp1,%fp0
834462306a36Sopenharmony_ci	fmul.x		%fp0,%fp0		# FP0 IS V
834562306a36Sopenharmony_ci	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
834662306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
834762306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# FP1 IS W
834862306a36Sopenharmony_ci
834962306a36Sopenharmony_ci	fmov.d		LOGB5(%pc),%fp3
835062306a36Sopenharmony_ci	fmov.d		LOGB4(%pc),%fp2
835162306a36Sopenharmony_ci
835262306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# W*B5
835362306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# W*B4
835462306a36Sopenharmony_ci
835562306a36Sopenharmony_ci	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
835662306a36Sopenharmony_ci	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
835762306a36Sopenharmony_ci
835862306a36Sopenharmony_ci	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
835962306a36Sopenharmony_ci
836062306a36Sopenharmony_ci	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
836162306a36Sopenharmony_ci
836262306a36Sopenharmony_ci	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
836362306a36Sopenharmony_ci	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
836462306a36Sopenharmony_ci
836562306a36Sopenharmony_ci	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
836662306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
836762306a36Sopenharmony_ci
836862306a36Sopenharmony_ci	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
836962306a36Sopenharmony_ci
837062306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
837162306a36Sopenharmony_ci	fadd.x		SAVEU(%a6),%fp0
837262306a36Sopenharmony_ci	bra		t_inx2
837362306a36Sopenharmony_ci
837462306a36Sopenharmony_ci#--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
837562306a36Sopenharmony_ciLOGNEG:
837662306a36Sopenharmony_ci	bra		t_operr
837762306a36Sopenharmony_ci
837862306a36Sopenharmony_ci	global		slognd
837962306a36Sopenharmony_cislognd:
838062306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
838162306a36Sopenharmony_ci
838262306a36Sopenharmony_ci	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
838362306a36Sopenharmony_ci
838462306a36Sopenharmony_ci#----normalize the input value by left shifting k bits (k to be determined
838562306a36Sopenharmony_ci#----below), adjusting exponent and storing -k to  ADJK
838662306a36Sopenharmony_ci#----the value TWOTO100 is no longer needed.
838762306a36Sopenharmony_ci#----Note that this code assumes the denormalized input is NON-ZERO.
838862306a36Sopenharmony_ci
838962306a36Sopenharmony_ci	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
839062306a36Sopenharmony_ci	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
839162306a36Sopenharmony_ci	mov.l		4(%a0),%d4
839262306a36Sopenharmony_ci	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
839362306a36Sopenharmony_ci	clr.l		%d2			# D2 used for holding K
839462306a36Sopenharmony_ci
839562306a36Sopenharmony_ci	tst.l		%d4
839662306a36Sopenharmony_ci	bne.b		Hi_not0
839762306a36Sopenharmony_ci
839862306a36Sopenharmony_ciHi_0:
839962306a36Sopenharmony_ci	mov.l		%d5,%d4
840062306a36Sopenharmony_ci	clr.l		%d5
840162306a36Sopenharmony_ci	mov.l		&32,%d2
840262306a36Sopenharmony_ci	clr.l		%d6
840362306a36Sopenharmony_ci	bfffo		%d4{&0:&32},%d6
840462306a36Sopenharmony_ci	lsl.l		%d6,%d4
840562306a36Sopenharmony_ci	add.l		%d6,%d2			# (D3,D4,D5) is normalized
840662306a36Sopenharmony_ci
840762306a36Sopenharmony_ci	mov.l		%d3,X(%a6)
840862306a36Sopenharmony_ci	mov.l		%d4,XFRAC(%a6)
840962306a36Sopenharmony_ci	mov.l		%d5,XFRAC+4(%a6)
841062306a36Sopenharmony_ci	neg.l		%d2
841162306a36Sopenharmony_ci	mov.l		%d2,ADJK(%a6)
841262306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0
841362306a36Sopenharmony_ci	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
841462306a36Sopenharmony_ci	lea		X(%a6),%a0
841562306a36Sopenharmony_ci	bra.w		LOGBGN			# begin regular log(X)
841662306a36Sopenharmony_ci
841762306a36Sopenharmony_ciHi_not0:
841862306a36Sopenharmony_ci	clr.l		%d6
841962306a36Sopenharmony_ci	bfffo		%d4{&0:&32},%d6		# find first 1
842062306a36Sopenharmony_ci	mov.l		%d6,%d2			# get k
842162306a36Sopenharmony_ci	lsl.l		%d6,%d4
842262306a36Sopenharmony_ci	mov.l		%d5,%d7			# a copy of D5
842362306a36Sopenharmony_ci	lsl.l		%d6,%d5
842462306a36Sopenharmony_ci	neg.l		%d6
842562306a36Sopenharmony_ci	add.l		&32,%d6
842662306a36Sopenharmony_ci	lsr.l		%d6,%d7
842762306a36Sopenharmony_ci	or.l		%d7,%d4			# (D3,D4,D5) normalized
842862306a36Sopenharmony_ci
842962306a36Sopenharmony_ci	mov.l		%d3,X(%a6)
843062306a36Sopenharmony_ci	mov.l		%d4,XFRAC(%a6)
843162306a36Sopenharmony_ci	mov.l		%d5,XFRAC+4(%a6)
843262306a36Sopenharmony_ci	neg.l		%d2
843362306a36Sopenharmony_ci	mov.l		%d2,ADJK(%a6)
843462306a36Sopenharmony_ci	fmov.x		X(%a6),%fp0
843562306a36Sopenharmony_ci	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
843662306a36Sopenharmony_ci	lea		X(%a6),%a0
843762306a36Sopenharmony_ci	bra.w		LOGBGN			# begin regular log(X)
843862306a36Sopenharmony_ci
843962306a36Sopenharmony_ci	global		slognp1
844062306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
844162306a36Sopenharmony_cislognp1:
844262306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
844362306a36Sopenharmony_ci	fabs.x		%fp0			# test magnitude
844462306a36Sopenharmony_ci	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
844562306a36Sopenharmony_ci	fbgt.w		LP1REAL			# if greater, continue
844662306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
844762306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
844862306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# return signed argument
844962306a36Sopenharmony_ci	bra		t_catch
845062306a36Sopenharmony_ci
845162306a36Sopenharmony_ciLP1REAL:
845262306a36Sopenharmony_ci	fmov.x		(%a0),%fp0		# LOAD INPUT
845362306a36Sopenharmony_ci	mov.l		&0x00000000,ADJK(%a6)
845462306a36Sopenharmony_ci	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
845562306a36Sopenharmony_ci	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
845662306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)
845762306a36Sopenharmony_ci	mov.w		XFRAC(%a6),XDCARE(%a6)
845862306a36Sopenharmony_ci	mov.l		X(%a6),%d1
845962306a36Sopenharmony_ci	cmp.l		%d1,&0
846062306a36Sopenharmony_ci	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
846162306a36Sopenharmony_ci	cmp.l		%d1,&0x3ffe8000		# IS BOUNDS [1/2,3/2]?
846262306a36Sopenharmony_ci	blt.w		LOGMAIN
846362306a36Sopenharmony_ci	cmp.l		%d1,&0x3fffc000
846462306a36Sopenharmony_ci	bgt.w		LOGMAIN
846562306a36Sopenharmony_ci#--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
846662306a36Sopenharmony_ci#--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
846762306a36Sopenharmony_ci#--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
846862306a36Sopenharmony_ci
846962306a36Sopenharmony_ciLP1NEAR1:
847062306a36Sopenharmony_ci#--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
847162306a36Sopenharmony_ci	cmp.l		%d1,&0x3ffef07d
847262306a36Sopenharmony_ci	blt.w		LP1CARE
847362306a36Sopenharmony_ci	cmp.l		%d1,&0x3fff8841
847462306a36Sopenharmony_ci	bgt.w		LP1CARE
847562306a36Sopenharmony_ci
847662306a36Sopenharmony_ciLP1ONE16:
847762306a36Sopenharmony_ci#--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
847862306a36Sopenharmony_ci#--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
847962306a36Sopenharmony_ci	fadd.x		%fp1,%fp1		# FP1 IS 2Z
848062306a36Sopenharmony_ci	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
848162306a36Sopenharmony_ci#--U = FP1/FP0
848262306a36Sopenharmony_ci	bra.w		LP1CONT2
848362306a36Sopenharmony_ci
848462306a36Sopenharmony_ciLP1CARE:
848562306a36Sopenharmony_ci#--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
848662306a36Sopenharmony_ci#--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
848762306a36Sopenharmony_ci#--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
848862306a36Sopenharmony_ci#--THERE ARE ONLY TWO CASES.
848962306a36Sopenharmony_ci#--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
849062306a36Sopenharmony_ci#--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
849162306a36Sopenharmony_ci#--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
849262306a36Sopenharmony_ci#--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
849362306a36Sopenharmony_ci
849462306a36Sopenharmony_ci	mov.l		XFRAC(%a6),FFRAC(%a6)
849562306a36Sopenharmony_ci	and.l		&0xFE000000,FFRAC(%a6)
849662306a36Sopenharmony_ci	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
849762306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
849862306a36Sopenharmony_ci	bge.b		KISZERO
849962306a36Sopenharmony_ci
850062306a36Sopenharmony_ciKISNEG1:
850162306a36Sopenharmony_ci	fmov.s		TWO(%pc),%fp0
850262306a36Sopenharmony_ci	mov.l		&0x3fff0000,F(%a6)
850362306a36Sopenharmony_ci	clr.l		F+8(%a6)
850462306a36Sopenharmony_ci	fsub.x		F(%a6),%fp0		# 2-F
850562306a36Sopenharmony_ci	mov.l		FFRAC(%a6),%d1
850662306a36Sopenharmony_ci	and.l		&0x7E000000,%d1
850762306a36Sopenharmony_ci	asr.l		&8,%d1
850862306a36Sopenharmony_ci	asr.l		&8,%d1
850962306a36Sopenharmony_ci	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
851062306a36Sopenharmony_ci	fadd.x		%fp1,%fp1		# GET 2Z
851162306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
851262306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
851362306a36Sopenharmony_ci	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
851462306a36Sopenharmony_ci	add.l		%d1,%a0
851562306a36Sopenharmony_ci	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
851662306a36Sopenharmony_ci	bra.w		LP1CONT1
851762306a36Sopenharmony_ci
851862306a36Sopenharmony_ciKISZERO:
851962306a36Sopenharmony_ci	fmov.s		one(%pc),%fp0
852062306a36Sopenharmony_ci	mov.l		&0x3fff0000,F(%a6)
852162306a36Sopenharmony_ci	clr.l		F+8(%a6)
852262306a36Sopenharmony_ci	fsub.x		F(%a6),%fp0		# 1-F
852362306a36Sopenharmony_ci	mov.l		FFRAC(%a6),%d1
852462306a36Sopenharmony_ci	and.l		&0x7E000000,%d1
852562306a36Sopenharmony_ci	asr.l		&8,%d1
852662306a36Sopenharmony_ci	asr.l		&8,%d1
852762306a36Sopenharmony_ci	asr.l		&4,%d1
852862306a36Sopenharmony_ci	fadd.x		%fp1,%fp0		# FP0 IS Y-F
852962306a36Sopenharmony_ci	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
853062306a36Sopenharmony_ci	lea		LOGTBL(%pc),%a0
853162306a36Sopenharmony_ci	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
853262306a36Sopenharmony_ci	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
853362306a36Sopenharmony_ci	bra.w		LP1CONT1
853462306a36Sopenharmony_ci
853562306a36Sopenharmony_ciLP1NEG0:
853662306a36Sopenharmony_ci#--FPCR SAVED. D0 IS X IN COMPACT FORM.
853762306a36Sopenharmony_ci	cmp.l		%d1,&0
853862306a36Sopenharmony_ci	blt.b		LP1NEG
853962306a36Sopenharmony_ciLP1ZERO:
854062306a36Sopenharmony_ci	fmov.s		negone(%pc),%fp0
854162306a36Sopenharmony_ci
854262306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
854362306a36Sopenharmony_ci	bra		t_dz
854462306a36Sopenharmony_ci
854562306a36Sopenharmony_ciLP1NEG:
854662306a36Sopenharmony_ci	fmov.s		zero(%pc),%fp0
854762306a36Sopenharmony_ci
854862306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
854962306a36Sopenharmony_ci	bra		t_operr
855062306a36Sopenharmony_ci
855162306a36Sopenharmony_ci	global		slognp1d
855262306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
855362306a36Sopenharmony_ci# Simply return the denorm
855462306a36Sopenharmony_cislognp1d:
855562306a36Sopenharmony_ci	bra		t_extdnrm
855662306a36Sopenharmony_ci
855762306a36Sopenharmony_ci#########################################################################
855862306a36Sopenharmony_ci# satanh():  computes the inverse hyperbolic tangent of a norm input	#
855962306a36Sopenharmony_ci# satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
856062306a36Sopenharmony_ci#									#
856162306a36Sopenharmony_ci# INPUT ***************************************************************	#
856262306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
856362306a36Sopenharmony_ci#	d0 = round precision,mode					#
856462306a36Sopenharmony_ci#									#
856562306a36Sopenharmony_ci# OUTPUT **************************************************************	#
856662306a36Sopenharmony_ci#	fp0 = arctanh(X)						#
856762306a36Sopenharmony_ci#									#
856862306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
856962306a36Sopenharmony_ci#	The returned result is within 3 ulps in	64 significant bit,	#
857062306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
857162306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
857262306a36Sopenharmony_ci#	in double precision.						#
857362306a36Sopenharmony_ci#									#
857462306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
857562306a36Sopenharmony_ci#									#
857662306a36Sopenharmony_ci#	ATANH								#
857762306a36Sopenharmony_ci#	1. If |X| >= 1, go to 3.					#
857862306a36Sopenharmony_ci#									#
857962306a36Sopenharmony_ci#	2. (|X| < 1) Calculate atanh(X) by				#
858062306a36Sopenharmony_ci#		sgn := sign(X)						#
858162306a36Sopenharmony_ci#		y := |X|						#
858262306a36Sopenharmony_ci#		z := 2y/(1-y)						#
858362306a36Sopenharmony_ci#		atanh(X) := sgn * (1/2) * logp1(z)			#
858462306a36Sopenharmony_ci#		Exit.							#
858562306a36Sopenharmony_ci#									#
858662306a36Sopenharmony_ci#	3. If |X| > 1, go to 5.						#
858762306a36Sopenharmony_ci#									#
858862306a36Sopenharmony_ci#	4. (|X| = 1) Generate infinity with an appropriate sign and	#
858962306a36Sopenharmony_ci#		divide-by-zero by					#
859062306a36Sopenharmony_ci#		sgn := sign(X)						#
859162306a36Sopenharmony_ci#		atan(X) := sgn / (+0).					#
859262306a36Sopenharmony_ci#		Exit.							#
859362306a36Sopenharmony_ci#									#
859462306a36Sopenharmony_ci#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
859562306a36Sopenharmony_ci#		Exit.							#
859662306a36Sopenharmony_ci#									#
859762306a36Sopenharmony_ci#########################################################################
859862306a36Sopenharmony_ci
859962306a36Sopenharmony_ci	global		satanh
860062306a36Sopenharmony_cisatanh:
860162306a36Sopenharmony_ci	mov.l		(%a0),%d1
860262306a36Sopenharmony_ci	mov.w		4(%a0),%d1
860362306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
860462306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
860562306a36Sopenharmony_ci	bge.b		ATANHBIG
860662306a36Sopenharmony_ci
860762306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 1
860862306a36Sopenharmony_ci#--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
860962306a36Sopenharmony_ci
861062306a36Sopenharmony_ci	fabs.x		(%a0),%fp0		# Y = |X|
861162306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
861262306a36Sopenharmony_ci	fneg.x		%fp1			# -Y
861362306a36Sopenharmony_ci	fadd.x		%fp0,%fp0		# 2Y
861462306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp1	# 1-Y
861562306a36Sopenharmony_ci	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
861662306a36Sopenharmony_ci	mov.l		(%a0),%d1
861762306a36Sopenharmony_ci	and.l		&0x80000000,%d1
861862306a36Sopenharmony_ci	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
861962306a36Sopenharmony_ci	mov.l		%d1,-(%sp)
862062306a36Sopenharmony_ci
862162306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save rnd prec,mode
862262306a36Sopenharmony_ci	clr.l		%d0			# pass ext prec,RN
862362306a36Sopenharmony_ci	fmovm.x		&0x01,-(%sp)		# save Z on stack
862462306a36Sopenharmony_ci	lea		(%sp),%a0		# pass ptr to Z
862562306a36Sopenharmony_ci	bsr		slognp1			# LOG1P(Z)
862662306a36Sopenharmony_ci	add.l		&0xc,%sp		# clear Z from stack
862762306a36Sopenharmony_ci
862862306a36Sopenharmony_ci	mov.l		(%sp)+,%d0		# fetch old prec,mode
862962306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# load it
863062306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
863162306a36Sopenharmony_ci	fmul.s		(%sp)+,%fp0
863262306a36Sopenharmony_ci	bra		t_catch
863362306a36Sopenharmony_ci
863462306a36Sopenharmony_ciATANHBIG:
863562306a36Sopenharmony_ci	fabs.x		(%a0),%fp0		# |X|
863662306a36Sopenharmony_ci	fcmp.s		%fp0,&0x3F800000
863762306a36Sopenharmony_ci	fbgt		t_operr
863862306a36Sopenharmony_ci	bra		t_dz
863962306a36Sopenharmony_ci
864062306a36Sopenharmony_ci	global		satanhd
864162306a36Sopenharmony_ci#--ATANH(X) = X FOR DENORMALIZED X
864262306a36Sopenharmony_cisatanhd:
864362306a36Sopenharmony_ci	bra		t_extdnrm
864462306a36Sopenharmony_ci
864562306a36Sopenharmony_ci#########################################################################
864662306a36Sopenharmony_ci# slog10():  computes the base-10 logarithm of a normalized input	#
864762306a36Sopenharmony_ci# slog10d(): computes the base-10 logarithm of a denormalized input	#
864862306a36Sopenharmony_ci# slog2():   computes the base-2 logarithm of a normalized input	#
864962306a36Sopenharmony_ci# slog2d():  computes the base-2 logarithm of a denormalized input	#
865062306a36Sopenharmony_ci#									#
865162306a36Sopenharmony_ci# INPUT *************************************************************** #
865262306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
865362306a36Sopenharmony_ci#	d0 = round precision,mode					#
865462306a36Sopenharmony_ci#									#
865562306a36Sopenharmony_ci# OUTPUT **************************************************************	#
865662306a36Sopenharmony_ci#	fp0 = log_10(X) or log_2(X)					#
865762306a36Sopenharmony_ci#									#
865862306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
865962306a36Sopenharmony_ci#	The returned result is within 1.7 ulps in 64 significant bit,	#
866062306a36Sopenharmony_ci#	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
866162306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
866262306a36Sopenharmony_ci#	in double precision.						#
866362306a36Sopenharmony_ci#									#
866462306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
866562306a36Sopenharmony_ci#									#
866662306a36Sopenharmony_ci#       slog10d:							#
866762306a36Sopenharmony_ci#									#
866862306a36Sopenharmony_ci#       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
866962306a36Sopenharmony_ci#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
867062306a36Sopenharmony_ci#       Notes:  Default means round-to-nearest mode, no floating-point	#
867162306a36Sopenharmony_ci#               traps, and precision control = double extended.		#
867262306a36Sopenharmony_ci#									#
867362306a36Sopenharmony_ci#       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
867462306a36Sopenharmony_ci#       Notes:  Even if X is denormalized, log(X) is always normalized.	#
867562306a36Sopenharmony_ci#									#
867662306a36Sopenharmony_ci#       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
867762306a36Sopenharmony_ci#            2.1 Restore the user FPCR					#
867862306a36Sopenharmony_ci#            2.2 Return ans := Y * INV_L10.				#
867962306a36Sopenharmony_ci#									#
868062306a36Sopenharmony_ci#       slog10:								#
868162306a36Sopenharmony_ci#									#
868262306a36Sopenharmony_ci#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
868362306a36Sopenharmony_ci#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
868462306a36Sopenharmony_ci#       Notes:  Default means round-to-nearest mode, no floating-point	#
868562306a36Sopenharmony_ci#               traps, and precision control = double extended.		#
868662306a36Sopenharmony_ci#									#
868762306a36Sopenharmony_ci#       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
868862306a36Sopenharmony_ci#									#
868962306a36Sopenharmony_ci#       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
869062306a36Sopenharmony_ci#            2.1  Restore the user FPCR					#
869162306a36Sopenharmony_ci#            2.2  Return ans := Y * INV_L10.				#
869262306a36Sopenharmony_ci#									#
869362306a36Sopenharmony_ci#       sLog2d:								#
869462306a36Sopenharmony_ci#									#
869562306a36Sopenharmony_ci#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
869662306a36Sopenharmony_ci#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
869762306a36Sopenharmony_ci#       Notes:  Default means round-to-nearest mode, no floating-point	#
869862306a36Sopenharmony_ci#               traps, and precision control = double extended.		#
869962306a36Sopenharmony_ci#									#
870062306a36Sopenharmony_ci#       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
870162306a36Sopenharmony_ci#       Notes:  Even if X is denormalized, log(X) is always normalized.	#
870262306a36Sopenharmony_ci#									#
870362306a36Sopenharmony_ci#       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
870462306a36Sopenharmony_ci#            2.1  Restore the user FPCR					#
870562306a36Sopenharmony_ci#            2.2  Return ans := Y * INV_L2.				#
870662306a36Sopenharmony_ci#									#
870762306a36Sopenharmony_ci#       sLog2:								#
870862306a36Sopenharmony_ci#									#
870962306a36Sopenharmony_ci#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
871062306a36Sopenharmony_ci#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
871162306a36Sopenharmony_ci#       Notes:  Default means round-to-nearest mode, no floating-point	#
871262306a36Sopenharmony_ci#               traps, and precision control = double extended.		#
871362306a36Sopenharmony_ci#									#
871462306a36Sopenharmony_ci#       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
871562306a36Sopenharmony_ci#               go to Step 3.						#
871662306a36Sopenharmony_ci#									#
871762306a36Sopenharmony_ci#       Step 2.   Return k.						#
871862306a36Sopenharmony_ci#            2.1  Get integer k, X = 2^k.				#
871962306a36Sopenharmony_ci#            2.2  Restore the user FPCR.				#
872062306a36Sopenharmony_ci#            2.3  Return ans := convert-to-double-extended(k).		#
872162306a36Sopenharmony_ci#									#
872262306a36Sopenharmony_ci#       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
872362306a36Sopenharmony_ci#									#
872462306a36Sopenharmony_ci#       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
872562306a36Sopenharmony_ci#            4.1  Restore the user FPCR					#
872662306a36Sopenharmony_ci#            4.2  Return ans := Y * INV_L2.				#
872762306a36Sopenharmony_ci#									#
872862306a36Sopenharmony_ci#########################################################################
872962306a36Sopenharmony_ci
873062306a36Sopenharmony_ciINV_L10:
873162306a36Sopenharmony_ci	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
873262306a36Sopenharmony_ci
873362306a36Sopenharmony_ciINV_L2:
873462306a36Sopenharmony_ci	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
873562306a36Sopenharmony_ci
873662306a36Sopenharmony_ci	global		slog10
873762306a36Sopenharmony_ci#--entry point for Log10(X), X is normalized
873862306a36Sopenharmony_cislog10:
873962306a36Sopenharmony_ci	fmov.b		&0x1,%fp0
874062306a36Sopenharmony_ci	fcmp.x		%fp0,(%a0)		# if operand == 1,
874162306a36Sopenharmony_ci	fbeq.l		ld_pzero		# return an EXACT zero
874262306a36Sopenharmony_ci
874362306a36Sopenharmony_ci	mov.l		(%a0),%d1
874462306a36Sopenharmony_ci	blt.w		invalid
874562306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
874662306a36Sopenharmony_ci	clr.l		%d0
874762306a36Sopenharmony_ci	bsr		slogn			# log(X), X normal.
874862306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr
874962306a36Sopenharmony_ci	fmul.x		INV_L10(%pc),%fp0
875062306a36Sopenharmony_ci	bra		t_inx2
875162306a36Sopenharmony_ci
875262306a36Sopenharmony_ci	global		slog10d
875362306a36Sopenharmony_ci#--entry point for Log10(X), X is denormalized
875462306a36Sopenharmony_cislog10d:
875562306a36Sopenharmony_ci	mov.l		(%a0),%d1
875662306a36Sopenharmony_ci	blt.w		invalid
875762306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
875862306a36Sopenharmony_ci	clr.l		%d0
875962306a36Sopenharmony_ci	bsr		slognd			# log(X), X denorm.
876062306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr
876162306a36Sopenharmony_ci	fmul.x		INV_L10(%pc),%fp0
876262306a36Sopenharmony_ci	bra		t_minx2
876362306a36Sopenharmony_ci
876462306a36Sopenharmony_ci	global		slog2
876562306a36Sopenharmony_ci#--entry point for Log2(X), X is normalized
876662306a36Sopenharmony_cislog2:
876762306a36Sopenharmony_ci	mov.l		(%a0),%d1
876862306a36Sopenharmony_ci	blt.w		invalid
876962306a36Sopenharmony_ci
877062306a36Sopenharmony_ci	mov.l		8(%a0),%d1
877162306a36Sopenharmony_ci	bne.b		continue		# X is not 2^k
877262306a36Sopenharmony_ci
877362306a36Sopenharmony_ci	mov.l		4(%a0),%d1
877462306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
877562306a36Sopenharmony_ci	bne.b		continue
877662306a36Sopenharmony_ci
877762306a36Sopenharmony_ci#--X = 2^k.
877862306a36Sopenharmony_ci	mov.w		(%a0),%d1
877962306a36Sopenharmony_ci	and.l		&0x00007FFF,%d1
878062306a36Sopenharmony_ci	sub.l		&0x3FFF,%d1
878162306a36Sopenharmony_ci	beq.l		ld_pzero
878262306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
878362306a36Sopenharmony_ci	fmov.l		%d1,%fp0
878462306a36Sopenharmony_ci	bra		t_inx2
878562306a36Sopenharmony_ci
878662306a36Sopenharmony_cicontinue:
878762306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
878862306a36Sopenharmony_ci	clr.l		%d0
878962306a36Sopenharmony_ci	bsr		slogn			# log(X), X normal.
879062306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr
879162306a36Sopenharmony_ci	fmul.x		INV_L2(%pc),%fp0
879262306a36Sopenharmony_ci	bra		t_inx2
879362306a36Sopenharmony_ci
879462306a36Sopenharmony_ciinvalid:
879562306a36Sopenharmony_ci	bra		t_operr
879662306a36Sopenharmony_ci
879762306a36Sopenharmony_ci	global		slog2d
879862306a36Sopenharmony_ci#--entry point for Log2(X), X is denormalized
879962306a36Sopenharmony_cislog2d:
880062306a36Sopenharmony_ci	mov.l		(%a0),%d1
880162306a36Sopenharmony_ci	blt.w		invalid
880262306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
880362306a36Sopenharmony_ci	clr.l		%d0
880462306a36Sopenharmony_ci	bsr		slognd			# log(X), X denorm.
880562306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr
880662306a36Sopenharmony_ci	fmul.x		INV_L2(%pc),%fp0
880762306a36Sopenharmony_ci	bra		t_minx2
880862306a36Sopenharmony_ci
880962306a36Sopenharmony_ci#########################################################################
881062306a36Sopenharmony_ci# stwotox():  computes 2**X for a normalized input			#
881162306a36Sopenharmony_ci# stwotoxd(): computes 2**X for a denormalized input			#
881262306a36Sopenharmony_ci# stentox():  computes 10**X for a normalized input			#
881362306a36Sopenharmony_ci# stentoxd(): computes 10**X for a denormalized input			#
881462306a36Sopenharmony_ci#									#
881562306a36Sopenharmony_ci# INPUT ***************************************************************	#
881662306a36Sopenharmony_ci#	a0 = pointer to extended precision input			#
881762306a36Sopenharmony_ci#	d0 = round precision,mode					#
881862306a36Sopenharmony_ci#									#
881962306a36Sopenharmony_ci# OUTPUT **************************************************************	#
882062306a36Sopenharmony_ci#	fp0 = 2**X or 10**X						#
882162306a36Sopenharmony_ci#									#
882262306a36Sopenharmony_ci# ACCURACY and MONOTONICITY *******************************************	#
882362306a36Sopenharmony_ci#	The returned result is within 2 ulps in 64 significant bit,	#
882462306a36Sopenharmony_ci#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
882562306a36Sopenharmony_ci#	rounded to double precision. The result is provably monotonic	#
882662306a36Sopenharmony_ci#	in double precision.						#
882762306a36Sopenharmony_ci#									#
882862306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
882962306a36Sopenharmony_ci#									#
883062306a36Sopenharmony_ci#	twotox								#
883162306a36Sopenharmony_ci#	1. If |X| > 16480, go to ExpBig.				#
883262306a36Sopenharmony_ci#									#
883362306a36Sopenharmony_ci#	2. If |X| < 2**(-70), go to ExpSm.				#
883462306a36Sopenharmony_ci#									#
883562306a36Sopenharmony_ci#	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
883662306a36Sopenharmony_ci#		decompose N as						#
883762306a36Sopenharmony_ci#		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
883862306a36Sopenharmony_ci#									#
883962306a36Sopenharmony_ci#	4. Overwrite r := r * log2. Then				#
884062306a36Sopenharmony_ci#		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
884162306a36Sopenharmony_ci#		Go to expr to compute that expression.			#
884262306a36Sopenharmony_ci#									#
884362306a36Sopenharmony_ci#	tentox								#
884462306a36Sopenharmony_ci#	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
884562306a36Sopenharmony_ci#									#
884662306a36Sopenharmony_ci#	2. If |X| < 2**(-70), go to ExpSm.				#
884762306a36Sopenharmony_ci#									#
884862306a36Sopenharmony_ci#	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
884962306a36Sopenharmony_ci#		N := round-to-int(y). Decompose N as			#
885062306a36Sopenharmony_ci#		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
885162306a36Sopenharmony_ci#									#
885262306a36Sopenharmony_ci#	4. Define r as							#
885362306a36Sopenharmony_ci#		r := ((X - N*L1)-N*L2) * L10				#
885462306a36Sopenharmony_ci#		where L1, L2 are the leading and trailing parts of	#
885562306a36Sopenharmony_ci#		log_10(2)/64 and L10 is the natural log of 10. Then	#
885662306a36Sopenharmony_ci#		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
885762306a36Sopenharmony_ci#		Go to expr to compute that expression.			#
885862306a36Sopenharmony_ci#									#
885962306a36Sopenharmony_ci#	expr								#
886062306a36Sopenharmony_ci#	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
886162306a36Sopenharmony_ci#									#
886262306a36Sopenharmony_ci#	2. Overwrite Fact1 and Fact2 by					#
886362306a36Sopenharmony_ci#		Fact1 := 2**(M) * Fact1					#
886462306a36Sopenharmony_ci#		Fact2 := 2**(M) * Fact2					#
886562306a36Sopenharmony_ci#		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
886662306a36Sopenharmony_ci#									#
886762306a36Sopenharmony_ci#	3. Calculate P where 1 + P approximates exp(r):			#
886862306a36Sopenharmony_ci#		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
886962306a36Sopenharmony_ci#									#
887062306a36Sopenharmony_ci#	4. Let AdjFact := 2**(M'). Return				#
887162306a36Sopenharmony_ci#		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
887262306a36Sopenharmony_ci#		Exit.							#
887362306a36Sopenharmony_ci#									#
887462306a36Sopenharmony_ci#	ExpBig								#
887562306a36Sopenharmony_ci#	1. Generate overflow by Huge * Huge if X > 0; otherwise,	#
887662306a36Sopenharmony_ci#	        generate underflow by Tiny * Tiny.			#
887762306a36Sopenharmony_ci#									#
887862306a36Sopenharmony_ci#	ExpSm								#
887962306a36Sopenharmony_ci#	1. Return 1 + X.						#
888062306a36Sopenharmony_ci#									#
888162306a36Sopenharmony_ci#########################################################################
888262306a36Sopenharmony_ci
888362306a36Sopenharmony_ciL2TEN64:
888462306a36Sopenharmony_ci	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
888562306a36Sopenharmony_ciL10TWO1:
888662306a36Sopenharmony_ci	long		0x3F734413,0x509F8000	# LOG2/64LOG10
888762306a36Sopenharmony_ci
888862306a36Sopenharmony_ciL10TWO2:
888962306a36Sopenharmony_ci	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
889062306a36Sopenharmony_ci
889162306a36Sopenharmony_ciLOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
889262306a36Sopenharmony_ci
889362306a36Sopenharmony_ciLOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
889462306a36Sopenharmony_ci
889562306a36Sopenharmony_ciEXPA5:	long		0x3F56C16D,0x6F7BD0B2
889662306a36Sopenharmony_ciEXPA4:	long		0x3F811112,0x302C712C
889762306a36Sopenharmony_ciEXPA3:	long		0x3FA55555,0x55554CC1
889862306a36Sopenharmony_ciEXPA2:	long		0x3FC55555,0x55554A54
889962306a36Sopenharmony_ciEXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
890062306a36Sopenharmony_ci
890162306a36Sopenharmony_ciTEXPTBL:
890262306a36Sopenharmony_ci	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
890362306a36Sopenharmony_ci	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
890462306a36Sopenharmony_ci	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
890562306a36Sopenharmony_ci	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
890662306a36Sopenharmony_ci	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
890762306a36Sopenharmony_ci	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
890862306a36Sopenharmony_ci	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
890962306a36Sopenharmony_ci	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
891062306a36Sopenharmony_ci	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
891162306a36Sopenharmony_ci	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
891262306a36Sopenharmony_ci	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
891362306a36Sopenharmony_ci	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
891462306a36Sopenharmony_ci	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
891562306a36Sopenharmony_ci	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
891662306a36Sopenharmony_ci	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
891762306a36Sopenharmony_ci	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
891862306a36Sopenharmony_ci	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
891962306a36Sopenharmony_ci	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
892062306a36Sopenharmony_ci	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
892162306a36Sopenharmony_ci	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
892262306a36Sopenharmony_ci	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
892362306a36Sopenharmony_ci	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
892462306a36Sopenharmony_ci	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
892562306a36Sopenharmony_ci	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
892662306a36Sopenharmony_ci	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
892762306a36Sopenharmony_ci	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
892862306a36Sopenharmony_ci	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
892962306a36Sopenharmony_ci	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
893062306a36Sopenharmony_ci	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
893162306a36Sopenharmony_ci	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
893262306a36Sopenharmony_ci	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
893362306a36Sopenharmony_ci	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
893462306a36Sopenharmony_ci	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
893562306a36Sopenharmony_ci	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
893662306a36Sopenharmony_ci	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
893762306a36Sopenharmony_ci	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
893862306a36Sopenharmony_ci	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
893962306a36Sopenharmony_ci	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
894062306a36Sopenharmony_ci	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
894162306a36Sopenharmony_ci	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
894262306a36Sopenharmony_ci	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
894362306a36Sopenharmony_ci	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
894462306a36Sopenharmony_ci	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
894562306a36Sopenharmony_ci	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
894662306a36Sopenharmony_ci	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
894762306a36Sopenharmony_ci	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
894862306a36Sopenharmony_ci	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
894962306a36Sopenharmony_ci	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
895062306a36Sopenharmony_ci	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
895162306a36Sopenharmony_ci	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
895262306a36Sopenharmony_ci	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
895362306a36Sopenharmony_ci	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
895462306a36Sopenharmony_ci	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
895562306a36Sopenharmony_ci	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
895662306a36Sopenharmony_ci	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
895762306a36Sopenharmony_ci	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
895862306a36Sopenharmony_ci	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
895962306a36Sopenharmony_ci	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
896062306a36Sopenharmony_ci	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
896162306a36Sopenharmony_ci	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
896262306a36Sopenharmony_ci	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
896362306a36Sopenharmony_ci	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
896462306a36Sopenharmony_ci	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
896562306a36Sopenharmony_ci	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
896662306a36Sopenharmony_ci
896762306a36Sopenharmony_ci	set		INT,L_SCR1
896862306a36Sopenharmony_ci
896962306a36Sopenharmony_ci	set		X,FP_SCR0
897062306a36Sopenharmony_ci	set		XDCARE,X+2
897162306a36Sopenharmony_ci	set		XFRAC,X+4
897262306a36Sopenharmony_ci
897362306a36Sopenharmony_ci	set		ADJFACT,FP_SCR0
897462306a36Sopenharmony_ci
897562306a36Sopenharmony_ci	set		FACT1,FP_SCR0
897662306a36Sopenharmony_ci	set		FACT1HI,FACT1+4
897762306a36Sopenharmony_ci	set		FACT1LOW,FACT1+8
897862306a36Sopenharmony_ci
897962306a36Sopenharmony_ci	set		FACT2,FP_SCR1
898062306a36Sopenharmony_ci	set		FACT2HI,FACT2+4
898162306a36Sopenharmony_ci	set		FACT2LOW,FACT2+8
898262306a36Sopenharmony_ci
898362306a36Sopenharmony_ci	global		stwotox
898462306a36Sopenharmony_ci#--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
898562306a36Sopenharmony_cistwotox:
898662306a36Sopenharmony_ci	fmovm.x		(%a0),&0x80		# LOAD INPUT
898762306a36Sopenharmony_ci
898862306a36Sopenharmony_ci	mov.l		(%a0),%d1
898962306a36Sopenharmony_ci	mov.w		4(%a0),%d1
899062306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)
899162306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
899262306a36Sopenharmony_ci
899362306a36Sopenharmony_ci	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
899462306a36Sopenharmony_ci	bge.b		TWOOK1
899562306a36Sopenharmony_ci	bra.w		EXPBORS
899662306a36Sopenharmony_ci
899762306a36Sopenharmony_ciTWOOK1:
899862306a36Sopenharmony_ci	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
899962306a36Sopenharmony_ci	ble.b		TWOMAIN
900062306a36Sopenharmony_ci	bra.w		EXPBORS
900162306a36Sopenharmony_ci
900262306a36Sopenharmony_ciTWOMAIN:
900362306a36Sopenharmony_ci#--USUAL CASE, 2^(-70) <= |X| <= 16480
900462306a36Sopenharmony_ci
900562306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
900662306a36Sopenharmony_ci	fmul.s		&0x42800000,%fp1	# 64 * X
900762306a36Sopenharmony_ci	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
900862306a36Sopenharmony_ci	mov.l		%d2,-(%sp)
900962306a36Sopenharmony_ci	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
901062306a36Sopenharmony_ci	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
901162306a36Sopenharmony_ci	mov.l		INT(%a6),%d1
901262306a36Sopenharmony_ci	mov.l		%d1,%d2
901362306a36Sopenharmony_ci	and.l		&0x3F,%d1		# D0 IS J
901462306a36Sopenharmony_ci	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
901562306a36Sopenharmony_ci	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
901662306a36Sopenharmony_ci	asr.l		&6,%d2			# d2 IS L, N = 64L + J
901762306a36Sopenharmony_ci	mov.l		%d2,%d1
901862306a36Sopenharmony_ci	asr.l		&1,%d1			# D0 IS M
901962306a36Sopenharmony_ci	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
902062306a36Sopenharmony_ci	add.l		&0x3FFF,%d2
902162306a36Sopenharmony_ci
902262306a36Sopenharmony_ci#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
902362306a36Sopenharmony_ci#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
902462306a36Sopenharmony_ci#--ADJFACT = 2^(M').
902562306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
902662306a36Sopenharmony_ci
902762306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
902862306a36Sopenharmony_ci
902962306a36Sopenharmony_ci	fmul.s		&0x3C800000,%fp1	# (1/64)*N
903062306a36Sopenharmony_ci	mov.l		(%a1)+,FACT1(%a6)
903162306a36Sopenharmony_ci	mov.l		(%a1)+,FACT1HI(%a6)
903262306a36Sopenharmony_ci	mov.l		(%a1)+,FACT1LOW(%a6)
903362306a36Sopenharmony_ci	mov.w		(%a1)+,FACT2(%a6)
903462306a36Sopenharmony_ci
903562306a36Sopenharmony_ci	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
903662306a36Sopenharmony_ci
903762306a36Sopenharmony_ci	mov.w		(%a1)+,FACT2HI(%a6)
903862306a36Sopenharmony_ci	clr.w		FACT2HI+2(%a6)
903962306a36Sopenharmony_ci	clr.l		FACT2LOW(%a6)
904062306a36Sopenharmony_ci	add.w		%d1,FACT1(%a6)
904162306a36Sopenharmony_ci	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
904262306a36Sopenharmony_ci	add.w		%d1,FACT2(%a6)
904362306a36Sopenharmony_ci
904462306a36Sopenharmony_ci	bra.w		expr
904562306a36Sopenharmony_ci
904662306a36Sopenharmony_ciEXPBORS:
904762306a36Sopenharmony_ci#--FPCR, D0 SAVED
904862306a36Sopenharmony_ci	cmp.l		%d1,&0x3FFF8000
904962306a36Sopenharmony_ci	bgt.b		TEXPBIG
905062306a36Sopenharmony_ci
905162306a36Sopenharmony_ci#--|X| IS SMALL, RETURN 1 + X
905262306a36Sopenharmony_ci
905362306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round prec,mode
905462306a36Sopenharmony_ci	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
905562306a36Sopenharmony_ci	bra		t_pinx2
905662306a36Sopenharmony_ci
905762306a36Sopenharmony_ciTEXPBIG:
905862306a36Sopenharmony_ci#--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
905962306a36Sopenharmony_ci#--REGISTERS SAVE SO FAR ARE FPCR AND  D0
906062306a36Sopenharmony_ci	mov.l		X(%a6),%d1
906162306a36Sopenharmony_ci	cmp.l		%d1,&0
906262306a36Sopenharmony_ci	blt.b		EXPNEG
906362306a36Sopenharmony_ci
906462306a36Sopenharmony_ci	bra		t_ovfl2			# t_ovfl expects positive value
906562306a36Sopenharmony_ci
906662306a36Sopenharmony_ciEXPNEG:
906762306a36Sopenharmony_ci	bra		t_unfl2			# t_unfl expects positive value
906862306a36Sopenharmony_ci
906962306a36Sopenharmony_ci	global		stwotoxd
907062306a36Sopenharmony_cistwotoxd:
907162306a36Sopenharmony_ci#--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
907262306a36Sopenharmony_ci
907362306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
907462306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
907562306a36Sopenharmony_ci	mov.l		(%a0),%d1
907662306a36Sopenharmony_ci	or.l		&0x00800001,%d1
907762306a36Sopenharmony_ci	fadd.s		%d1,%fp0
907862306a36Sopenharmony_ci	bra		t_pinx2
907962306a36Sopenharmony_ci
908062306a36Sopenharmony_ci	global		stentox
908162306a36Sopenharmony_ci#--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
908262306a36Sopenharmony_cistentox:
908362306a36Sopenharmony_ci	fmovm.x		(%a0),&0x80		# LOAD INPUT
908462306a36Sopenharmony_ci
908562306a36Sopenharmony_ci	mov.l		(%a0),%d1
908662306a36Sopenharmony_ci	mov.w		4(%a0),%d1
908762306a36Sopenharmony_ci	fmov.x		%fp0,X(%a6)
908862306a36Sopenharmony_ci	and.l		&0x7FFFFFFF,%d1
908962306a36Sopenharmony_ci
909062306a36Sopenharmony_ci	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
909162306a36Sopenharmony_ci	bge.b		TENOK1
909262306a36Sopenharmony_ci	bra.w		EXPBORS
909362306a36Sopenharmony_ci
909462306a36Sopenharmony_ciTENOK1:
909562306a36Sopenharmony_ci	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
909662306a36Sopenharmony_ci	ble.b		TENMAIN
909762306a36Sopenharmony_ci	bra.w		EXPBORS
909862306a36Sopenharmony_ci
909962306a36Sopenharmony_ciTENMAIN:
910062306a36Sopenharmony_ci#--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
910162306a36Sopenharmony_ci
910262306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
910362306a36Sopenharmony_ci	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
910462306a36Sopenharmony_ci	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
910562306a36Sopenharmony_ci	mov.l		%d2,-(%sp)
910662306a36Sopenharmony_ci	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
910762306a36Sopenharmony_ci	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
910862306a36Sopenharmony_ci	mov.l		INT(%a6),%d1
910962306a36Sopenharmony_ci	mov.l		%d1,%d2
911062306a36Sopenharmony_ci	and.l		&0x3F,%d1		# D0 IS J
911162306a36Sopenharmony_ci	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
911262306a36Sopenharmony_ci	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
911362306a36Sopenharmony_ci	asr.l		&6,%d2			# d2 IS L, N = 64L + J
911462306a36Sopenharmony_ci	mov.l		%d2,%d1
911562306a36Sopenharmony_ci	asr.l		&1,%d1			# D0 IS M
911662306a36Sopenharmony_ci	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
911762306a36Sopenharmony_ci	add.l		&0x3FFF,%d2
911862306a36Sopenharmony_ci
911962306a36Sopenharmony_ci#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
912062306a36Sopenharmony_ci#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
912162306a36Sopenharmony_ci#--ADJFACT = 2^(M').
912262306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
912362306a36Sopenharmony_ci	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
912462306a36Sopenharmony_ci
912562306a36Sopenharmony_ci	fmov.x		%fp1,%fp2
912662306a36Sopenharmony_ci
912762306a36Sopenharmony_ci	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
912862306a36Sopenharmony_ci	mov.l		(%a1)+,FACT1(%a6)
912962306a36Sopenharmony_ci
913062306a36Sopenharmony_ci	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
913162306a36Sopenharmony_ci
913262306a36Sopenharmony_ci	mov.l		(%a1)+,FACT1HI(%a6)
913362306a36Sopenharmony_ci	mov.l		(%a1)+,FACT1LOW(%a6)
913462306a36Sopenharmony_ci	fsub.x		%fp1,%fp0		# X - N L_LEAD
913562306a36Sopenharmony_ci	mov.w		(%a1)+,FACT2(%a6)
913662306a36Sopenharmony_ci
913762306a36Sopenharmony_ci	fsub.x		%fp2,%fp0		# X - N L_TRAIL
913862306a36Sopenharmony_ci
913962306a36Sopenharmony_ci	mov.w		(%a1)+,FACT2HI(%a6)
914062306a36Sopenharmony_ci	clr.w		FACT2HI+2(%a6)
914162306a36Sopenharmony_ci	clr.l		FACT2LOW(%a6)
914262306a36Sopenharmony_ci
914362306a36Sopenharmony_ci	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
914462306a36Sopenharmony_ci	add.w		%d1,FACT1(%a6)
914562306a36Sopenharmony_ci	add.w		%d1,FACT2(%a6)
914662306a36Sopenharmony_ci
914762306a36Sopenharmony_ciexpr:
914862306a36Sopenharmony_ci#--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
914962306a36Sopenharmony_ci#--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
915062306a36Sopenharmony_ci#--FP0 IS R. THE FOLLOWING CODE COMPUTES
915162306a36Sopenharmony_ci#--	2**(M'+M) * 2**(J/64) * EXP(R)
915262306a36Sopenharmony_ci
915362306a36Sopenharmony_ci	fmov.x		%fp0,%fp1
915462306a36Sopenharmony_ci	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
915562306a36Sopenharmony_ci
915662306a36Sopenharmony_ci	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
915762306a36Sopenharmony_ci	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
915862306a36Sopenharmony_ci
915962306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# FP2 IS S*A5
916062306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# FP3 IS S*A4
916162306a36Sopenharmony_ci
916262306a36Sopenharmony_ci	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
916362306a36Sopenharmony_ci	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
916462306a36Sopenharmony_ci
916562306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
916662306a36Sopenharmony_ci	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
916762306a36Sopenharmony_ci
916862306a36Sopenharmony_ci	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
916962306a36Sopenharmony_ci	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
917062306a36Sopenharmony_ci
917162306a36Sopenharmony_ci	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
917262306a36Sopenharmony_ci	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
917362306a36Sopenharmony_ci	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
917462306a36Sopenharmony_ci
917562306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
917662306a36Sopenharmony_ci
917762306a36Sopenharmony_ci#--FINAL RECONSTRUCTION PROCESS
917862306a36Sopenharmony_ci#--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
917962306a36Sopenharmony_ci
918062306a36Sopenharmony_ci	fmul.x		FACT1(%a6),%fp0
918162306a36Sopenharmony_ci	fadd.x		FACT2(%a6),%fp0
918262306a36Sopenharmony_ci	fadd.x		FACT1(%a6),%fp0
918362306a36Sopenharmony_ci
918462306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# restore users round prec,mode
918562306a36Sopenharmony_ci	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
918662306a36Sopenharmony_ci	mov.l		(%sp)+,%d2
918762306a36Sopenharmony_ci	mov.l		&0x80000000,ADJFACT+4(%a6)
918862306a36Sopenharmony_ci	clr.l		ADJFACT+8(%a6)
918962306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
919062306a36Sopenharmony_ci	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
919162306a36Sopenharmony_ci	bra		t_catch
919262306a36Sopenharmony_ci
919362306a36Sopenharmony_ci	global		stentoxd
919462306a36Sopenharmony_cistentoxd:
919562306a36Sopenharmony_ci#--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
919662306a36Sopenharmony_ci
919762306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
919862306a36Sopenharmony_ci	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
919962306a36Sopenharmony_ci	mov.l		(%a0),%d1
920062306a36Sopenharmony_ci	or.l		&0x00800001,%d1
920162306a36Sopenharmony_ci	fadd.s		%d1,%fp0
920262306a36Sopenharmony_ci	bra		t_pinx2
920362306a36Sopenharmony_ci
920462306a36Sopenharmony_ci#########################################################################
920562306a36Sopenharmony_ci# sscale(): computes the destination operand scaled by the source	#
920662306a36Sopenharmony_ci#	    operand. If the absoulute value of the source operand is	#
920762306a36Sopenharmony_ci#	    >= 2^14, an overflow or underflow is returned.		#
920862306a36Sopenharmony_ci#									#
920962306a36Sopenharmony_ci# INPUT *************************************************************** #
921062306a36Sopenharmony_ci#	a0  = pointer to double-extended source operand X		#
921162306a36Sopenharmony_ci#	a1  = pointer to double-extended destination operand Y		#
921262306a36Sopenharmony_ci#									#
921362306a36Sopenharmony_ci# OUTPUT ************************************************************** #
921462306a36Sopenharmony_ci#	fp0 =  scale(X,Y)						#
921562306a36Sopenharmony_ci#									#
921662306a36Sopenharmony_ci#########################################################################
921762306a36Sopenharmony_ci
921862306a36Sopenharmony_ciset	SIGN,		L_SCR1
921962306a36Sopenharmony_ci
922062306a36Sopenharmony_ci	global		sscale
922162306a36Sopenharmony_cisscale:
922262306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# store off ctrl bits for now
922362306a36Sopenharmony_ci
922462306a36Sopenharmony_ci	mov.w		DST_EX(%a1),%d1		# get dst exponent
922562306a36Sopenharmony_ci	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
922662306a36Sopenharmony_ci	andi.l		&0x00007fff,%d1		# strip sign from dst exp
922762306a36Sopenharmony_ci
922862306a36Sopenharmony_ci	mov.w		SRC_EX(%a0),%d0		# check src bounds
922962306a36Sopenharmony_ci	andi.w		&0x7fff,%d0		# clr src sign bit
923062306a36Sopenharmony_ci	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
923162306a36Sopenharmony_ci	blt.w		src_small		# yes
923262306a36Sopenharmony_ci	cmpi.w		%d0,&0x400c		# no; is src too big?
923362306a36Sopenharmony_ci	bgt.w		src_out			# yes
923462306a36Sopenharmony_ci
923562306a36Sopenharmony_ci#
923662306a36Sopenharmony_ci# Source is within 2^14 range.
923762306a36Sopenharmony_ci#
923862306a36Sopenharmony_cisrc_ok:
923962306a36Sopenharmony_ci	fintrz.x	SRC(%a0),%fp0		# calc int of src
924062306a36Sopenharmony_ci	fmov.l		%fp0,%d0		# int src to d0
924162306a36Sopenharmony_ci# don't want any accrued bits from the fintrz showing up later since
924262306a36Sopenharmony_ci# we may need to read the fpsr for the last fp op in t_catch2().
924362306a36Sopenharmony_ci	fmov.l		&0x0,%fpsr
924462306a36Sopenharmony_ci
924562306a36Sopenharmony_ci	tst.b		DST_HI(%a1)		# is dst denormalized?
924662306a36Sopenharmony_ci	bmi.b		sok_norm
924762306a36Sopenharmony_ci
924862306a36Sopenharmony_ci# the dst is a DENORM. normalize the DENORM and add the adjustment to
924962306a36Sopenharmony_ci# the src value. then, jump to the norm part of the routine.
925062306a36Sopenharmony_cisok_dnrm:
925162306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save src for now
925262306a36Sopenharmony_ci
925362306a36Sopenharmony_ci	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
925462306a36Sopenharmony_ci	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
925562306a36Sopenharmony_ci	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
925662306a36Sopenharmony_ci
925762306a36Sopenharmony_ci	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
925862306a36Sopenharmony_ci	bsr.l		norm			# normalize the DENORM
925962306a36Sopenharmony_ci	neg.l		%d0
926062306a36Sopenharmony_ci	add.l		(%sp)+,%d0		# add adjustment to src
926162306a36Sopenharmony_ci
926262306a36Sopenharmony_ci	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
926362306a36Sopenharmony_ci
926462306a36Sopenharmony_ci	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
926562306a36Sopenharmony_ci	bge.b		sok_norm2		# thank goodness no
926662306a36Sopenharmony_ci
926762306a36Sopenharmony_ci# the multiply factor that we're trying to create should be a denorm
926862306a36Sopenharmony_ci# for the multiply to work. therefore, we're going to actually do a
926962306a36Sopenharmony_ci# multiply with a denorm which will cause an unimplemented data type
927062306a36Sopenharmony_ci# exception to be put into the machine which will be caught and corrected
927162306a36Sopenharmony_ci# later. we don't do this with the DENORMs above because this method
927262306a36Sopenharmony_ci# is slower. but, don't fret, I don't see it being used much either.
927362306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore user fpcr
927462306a36Sopenharmony_ci	mov.l		&0x80000000,%d1		# load normalized mantissa
927562306a36Sopenharmony_ci	subi.l		&-0x3fff,%d0		# how many should we shift?
927662306a36Sopenharmony_ci	neg.l		%d0			# make it positive
927762306a36Sopenharmony_ci	cmpi.b		%d0,&0x20		# is it > 32?
927862306a36Sopenharmony_ci	bge.b		sok_dnrm_32		# yes
927962306a36Sopenharmony_ci	lsr.l		%d0,%d1			# no; bit stays in upper lw
928062306a36Sopenharmony_ci	clr.l		-(%sp)			# insert zero low mantissa
928162306a36Sopenharmony_ci	mov.l		%d1,-(%sp)		# insert new high mantissa
928262306a36Sopenharmony_ci	clr.l		-(%sp)			# make zero exponent
928362306a36Sopenharmony_ci	bra.b		sok_norm_cont
928462306a36Sopenharmony_cisok_dnrm_32:
928562306a36Sopenharmony_ci	subi.b		&0x20,%d0		# get shift count
928662306a36Sopenharmony_ci	lsr.l		%d0,%d1			# make low mantissa longword
928762306a36Sopenharmony_ci	mov.l		%d1,-(%sp)		# insert new low mantissa
928862306a36Sopenharmony_ci	clr.l		-(%sp)			# insert zero high mantissa
928962306a36Sopenharmony_ci	clr.l		-(%sp)			# make zero exponent
929062306a36Sopenharmony_ci	bra.b		sok_norm_cont
929162306a36Sopenharmony_ci
929262306a36Sopenharmony_ci# the src will force the dst to a DENORM value or worse. so, let's
929362306a36Sopenharmony_ci# create an fp multiply that will create the result.
929462306a36Sopenharmony_cisok_norm:
929562306a36Sopenharmony_ci	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
929662306a36Sopenharmony_cisok_norm2:
929762306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore user fpcr
929862306a36Sopenharmony_ci
929962306a36Sopenharmony_ci	addi.w		&0x3fff,%d0		# turn src amt into exp value
930062306a36Sopenharmony_ci	swap		%d0			# put exponent in high word
930162306a36Sopenharmony_ci	clr.l		-(%sp)			# insert new exponent
930262306a36Sopenharmony_ci	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
930362306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# insert new lo mantissa
930462306a36Sopenharmony_ci
930562306a36Sopenharmony_cisok_norm_cont:
930662306a36Sopenharmony_ci	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
930762306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
930862306a36Sopenharmony_ci	fmul.x		(%sp)+,%fp0		# do the multiply
930962306a36Sopenharmony_ci	bra		t_catch2		# catch any exceptions
931062306a36Sopenharmony_ci
931162306a36Sopenharmony_ci#
931262306a36Sopenharmony_ci# Source is outside of 2^14 range.  Test the sign and branch
931362306a36Sopenharmony_ci# to the appropriate exception handler.
931462306a36Sopenharmony_ci#
931562306a36Sopenharmony_cisrc_out:
931662306a36Sopenharmony_ci	mov.l		(%sp)+,%d0		# restore ctrl bits
931762306a36Sopenharmony_ci	exg		%a0,%a1			# swap src,dst ptrs
931862306a36Sopenharmony_ci	tst.b		SRC_EX(%a1)		# is src negative?
931962306a36Sopenharmony_ci	bmi		t_unfl			# yes; underflow
932062306a36Sopenharmony_ci	bra		t_ovfl_sc		# no; overflow
932162306a36Sopenharmony_ci
932262306a36Sopenharmony_ci#
932362306a36Sopenharmony_ci# The source input is below 1, so we check for denormalized numbers
932462306a36Sopenharmony_ci# and set unfl.
932562306a36Sopenharmony_ci#
932662306a36Sopenharmony_cisrc_small:
932762306a36Sopenharmony_ci	tst.b		DST_HI(%a1)		# is dst denormalized?
932862306a36Sopenharmony_ci	bpl.b		ssmall_done		# yes
932962306a36Sopenharmony_ci
933062306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
933162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr		# no; load control bits
933262306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
933362306a36Sopenharmony_ci	fmov.x		DST(%a1),%fp0		# simply return dest
933462306a36Sopenharmony_ci	bra		t_catch2
933562306a36Sopenharmony_cissmall_done:
933662306a36Sopenharmony_ci	mov.l		(%sp)+,%d0		# load control bits into d1
933762306a36Sopenharmony_ci	mov.l		%a1,%a0			# pass ptr to dst
933862306a36Sopenharmony_ci	bra		t_resdnrm
933962306a36Sopenharmony_ci
934062306a36Sopenharmony_ci#########################################################################
934162306a36Sopenharmony_ci# smod(): computes the fp MOD of the input values X,Y.			#
934262306a36Sopenharmony_ci# srem(): computes the fp (IEEE) REM of the input values X,Y.		#
934362306a36Sopenharmony_ci#									#
934462306a36Sopenharmony_ci# INPUT *************************************************************** #
934562306a36Sopenharmony_ci#	a0 = pointer to extended precision input X			#
934662306a36Sopenharmony_ci#	a1 = pointer to extended precision input Y			#
934762306a36Sopenharmony_ci#	d0 = round precision,mode					#
934862306a36Sopenharmony_ci#									#
934962306a36Sopenharmony_ci#	The input operands X and Y can be either normalized or		#
935062306a36Sopenharmony_ci#	denormalized.							#
935162306a36Sopenharmony_ci#									#
935262306a36Sopenharmony_ci# OUTPUT ************************************************************** #
935362306a36Sopenharmony_ci#      fp0 = FREM(X,Y) or FMOD(X,Y)					#
935462306a36Sopenharmony_ci#									#
935562306a36Sopenharmony_ci# ALGORITHM *********************************************************** #
935662306a36Sopenharmony_ci#									#
935762306a36Sopenharmony_ci#       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
935862306a36Sopenharmony_ci#                signY := sign(Y), X := |X|, Y := |Y|,			#
935962306a36Sopenharmony_ci#                signQ := signX EOR signY. Record whether MOD or REM	#
936062306a36Sopenharmony_ci#                is requested.						#
936162306a36Sopenharmony_ci#									#
936262306a36Sopenharmony_ci#       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
936362306a36Sopenharmony_ci#                If (L < 0) then					#
936462306a36Sopenharmony_ci#                   R := X, go to Step 4.				#
936562306a36Sopenharmony_ci#                else							#
936662306a36Sopenharmony_ci#                   R := 2^(-L)X, j := L.				#
936762306a36Sopenharmony_ci#                endif							#
936862306a36Sopenharmony_ci#									#
936962306a36Sopenharmony_ci#       Step 3.  Perform MOD(X,Y)					#
937062306a36Sopenharmony_ci#            3.1 If R = Y, go to Step 9.				#
937162306a36Sopenharmony_ci#            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
937262306a36Sopenharmony_ci#            3.3 If j = 0, go to Step 4.				#
937362306a36Sopenharmony_ci#            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
937462306a36Sopenharmony_ci#                Step 3.1.						#
937562306a36Sopenharmony_ci#									#
937662306a36Sopenharmony_ci#       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
937762306a36Sopenharmony_ci#                Last_Subtract := false (used in Step 7 below). If	#
937862306a36Sopenharmony_ci#                MOD is requested, go to Step 6.			#
937962306a36Sopenharmony_ci#									#
938062306a36Sopenharmony_ci#       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
938162306a36Sopenharmony_ci#            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
938262306a36Sopenharmony_ci#                Step 6.						#
938362306a36Sopenharmony_ci#            5.2 If R > Y/2, then { set Last_Subtract := true,		#
938462306a36Sopenharmony_ci#                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
938562306a36Sopenharmony_ci#            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
938662306a36Sopenharmony_ci#                then { Q := Q + 1, signX := -signX }.			#
938762306a36Sopenharmony_ci#									#
938862306a36Sopenharmony_ci#       Step 6.  R := signX*R.						#
938962306a36Sopenharmony_ci#									#
939062306a36Sopenharmony_ci#       Step 7.  If Last_Subtract = true, R := R - Y.			#
939162306a36Sopenharmony_ci#									#
939262306a36Sopenharmony_ci#       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
939362306a36Sopenharmony_ci#									#
939462306a36Sopenharmony_ci#       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
939562306a36Sopenharmony_ci#                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
939662306a36Sopenharmony_ci#                R := 0. Return signQ, last 7 bits of Q, and R.		#
939762306a36Sopenharmony_ci#									#
939862306a36Sopenharmony_ci#########################################################################
939962306a36Sopenharmony_ci
940062306a36Sopenharmony_ci	set		Mod_Flag,L_SCR3
940162306a36Sopenharmony_ci	set		Sc_Flag,L_SCR3+1
940262306a36Sopenharmony_ci
940362306a36Sopenharmony_ci	set		SignY,L_SCR2
940462306a36Sopenharmony_ci	set		SignX,L_SCR2+2
940562306a36Sopenharmony_ci	set		SignQ,L_SCR3+2
940662306a36Sopenharmony_ci
940762306a36Sopenharmony_ci	set		Y,FP_SCR0
940862306a36Sopenharmony_ci	set		Y_Hi,Y+4
940962306a36Sopenharmony_ci	set		Y_Lo,Y+8
941062306a36Sopenharmony_ci
941162306a36Sopenharmony_ci	set		R,FP_SCR1
941262306a36Sopenharmony_ci	set		R_Hi,R+4
941362306a36Sopenharmony_ci	set		R_Lo,R+8
941462306a36Sopenharmony_ci
941562306a36Sopenharmony_ciScale:
941662306a36Sopenharmony_ci	long		0x00010000,0x80000000,0x00000000,0x00000000
941762306a36Sopenharmony_ci
941862306a36Sopenharmony_ci	global		smod
941962306a36Sopenharmony_cismod:
942062306a36Sopenharmony_ci	clr.b		FPSR_QBYTE(%a6)
942162306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save ctrl bits
942262306a36Sopenharmony_ci	clr.b		Mod_Flag(%a6)
942362306a36Sopenharmony_ci	bra.b		Mod_Rem
942462306a36Sopenharmony_ci
942562306a36Sopenharmony_ci	global		srem
942662306a36Sopenharmony_cisrem:
942762306a36Sopenharmony_ci	clr.b		FPSR_QBYTE(%a6)
942862306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save ctrl bits
942962306a36Sopenharmony_ci	mov.b		&0x1,Mod_Flag(%a6)
943062306a36Sopenharmony_ci
943162306a36Sopenharmony_ciMod_Rem:
943262306a36Sopenharmony_ci#..Save sign of X and Y
943362306a36Sopenharmony_ci	movm.l		&0x3f00,-(%sp)		# save data registers
943462306a36Sopenharmony_ci	mov.w		SRC_EX(%a0),%d3
943562306a36Sopenharmony_ci	mov.w		%d3,SignY(%a6)
943662306a36Sopenharmony_ci	and.l		&0x00007FFF,%d3		# Y := |Y|
943762306a36Sopenharmony_ci
943862306a36Sopenharmony_ci#
943962306a36Sopenharmony_ci	mov.l		SRC_HI(%a0),%d4
944062306a36Sopenharmony_ci	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
944162306a36Sopenharmony_ci
944262306a36Sopenharmony_ci	tst.l		%d3
944362306a36Sopenharmony_ci	bne.b		Y_Normal
944462306a36Sopenharmony_ci
944562306a36Sopenharmony_ci	mov.l		&0x00003FFE,%d3		# $3FFD + 1
944662306a36Sopenharmony_ci	tst.l		%d4
944762306a36Sopenharmony_ci	bne.b		HiY_not0
944862306a36Sopenharmony_ci
944962306a36Sopenharmony_ciHiY_0:
945062306a36Sopenharmony_ci	mov.l		%d5,%d4
945162306a36Sopenharmony_ci	clr.l		%d5
945262306a36Sopenharmony_ci	sub.l		&32,%d3
945362306a36Sopenharmony_ci	clr.l		%d6
945462306a36Sopenharmony_ci	bfffo		%d4{&0:&32},%d6
945562306a36Sopenharmony_ci	lsl.l		%d6,%d4
945662306a36Sopenharmony_ci	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
945762306a36Sopenharmony_ci#	                                        ...with bias $7FFD
945862306a36Sopenharmony_ci	bra.b		Chk_X
945962306a36Sopenharmony_ci
946062306a36Sopenharmony_ciHiY_not0:
946162306a36Sopenharmony_ci	clr.l		%d6
946262306a36Sopenharmony_ci	bfffo		%d4{&0:&32},%d6
946362306a36Sopenharmony_ci	sub.l		%d6,%d3
946462306a36Sopenharmony_ci	lsl.l		%d6,%d4
946562306a36Sopenharmony_ci	mov.l		%d5,%d7			# a copy of D5
946662306a36Sopenharmony_ci	lsl.l		%d6,%d5
946762306a36Sopenharmony_ci	neg.l		%d6
946862306a36Sopenharmony_ci	add.l		&32,%d6
946962306a36Sopenharmony_ci	lsr.l		%d6,%d7
947062306a36Sopenharmony_ci	or.l		%d7,%d4			# (D3,D4,D5) normalized
947162306a36Sopenharmony_ci#                                       ...with bias $7FFD
947262306a36Sopenharmony_ci	bra.b		Chk_X
947362306a36Sopenharmony_ci
947462306a36Sopenharmony_ciY_Normal:
947562306a36Sopenharmony_ci	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
947662306a36Sopenharmony_ci#                                       ...with bias $7FFD
947762306a36Sopenharmony_ci
947862306a36Sopenharmony_ciChk_X:
947962306a36Sopenharmony_ci	mov.w		DST_EX(%a1),%d0
948062306a36Sopenharmony_ci	mov.w		%d0,SignX(%a6)
948162306a36Sopenharmony_ci	mov.w		SignY(%a6),%d1
948262306a36Sopenharmony_ci	eor.l		%d0,%d1
948362306a36Sopenharmony_ci	and.l		&0x00008000,%d1
948462306a36Sopenharmony_ci	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
948562306a36Sopenharmony_ci	and.l		&0x00007FFF,%d0
948662306a36Sopenharmony_ci	mov.l		DST_HI(%a1),%d1
948762306a36Sopenharmony_ci	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
948862306a36Sopenharmony_ci	tst.l		%d0
948962306a36Sopenharmony_ci	bne.b		X_Normal
949062306a36Sopenharmony_ci	mov.l		&0x00003FFE,%d0
949162306a36Sopenharmony_ci	tst.l		%d1
949262306a36Sopenharmony_ci	bne.b		HiX_not0
949362306a36Sopenharmony_ci
949462306a36Sopenharmony_ciHiX_0:
949562306a36Sopenharmony_ci	mov.l		%d2,%d1
949662306a36Sopenharmony_ci	clr.l		%d2
949762306a36Sopenharmony_ci	sub.l		&32,%d0
949862306a36Sopenharmony_ci	clr.l		%d6
949962306a36Sopenharmony_ci	bfffo		%d1{&0:&32},%d6
950062306a36Sopenharmony_ci	lsl.l		%d6,%d1
950162306a36Sopenharmony_ci	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
950262306a36Sopenharmony_ci#                                       ...with bias $7FFD
950362306a36Sopenharmony_ci	bra.b		Init
950462306a36Sopenharmony_ci
950562306a36Sopenharmony_ciHiX_not0:
950662306a36Sopenharmony_ci	clr.l		%d6
950762306a36Sopenharmony_ci	bfffo		%d1{&0:&32},%d6
950862306a36Sopenharmony_ci	sub.l		%d6,%d0
950962306a36Sopenharmony_ci	lsl.l		%d6,%d1
951062306a36Sopenharmony_ci	mov.l		%d2,%d7			# a copy of D2
951162306a36Sopenharmony_ci	lsl.l		%d6,%d2
951262306a36Sopenharmony_ci	neg.l		%d6
951362306a36Sopenharmony_ci	add.l		&32,%d6
951462306a36Sopenharmony_ci	lsr.l		%d6,%d7
951562306a36Sopenharmony_ci	or.l		%d7,%d1			# (D0,D1,D2) normalized
951662306a36Sopenharmony_ci#                                       ...with bias $7FFD
951762306a36Sopenharmony_ci	bra.b		Init
951862306a36Sopenharmony_ci
951962306a36Sopenharmony_ciX_Normal:
952062306a36Sopenharmony_ci	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
952162306a36Sopenharmony_ci#                                       ...with bias $7FFD
952262306a36Sopenharmony_ci
952362306a36Sopenharmony_ciInit:
952462306a36Sopenharmony_ci#
952562306a36Sopenharmony_ci	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
952662306a36Sopenharmony_ci	mov.l		%d0,-(%sp)		# save biased exp(X)
952762306a36Sopenharmony_ci	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
952862306a36Sopenharmony_ci
952962306a36Sopenharmony_ci	clr.l		%d6			# D6 := carry <- 0
953062306a36Sopenharmony_ci	clr.l		%d3			# D3 is Q
953162306a36Sopenharmony_ci	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
953262306a36Sopenharmony_ci
953362306a36Sopenharmony_ci#..(Carry,D1,D2) is R
953462306a36Sopenharmony_ci	tst.l		%d0
953562306a36Sopenharmony_ci	bge.b		Mod_Loop_pre
953662306a36Sopenharmony_ci
953762306a36Sopenharmony_ci#..expo(X) < expo(Y). Thus X = mod(X,Y)
953862306a36Sopenharmony_ci#
953962306a36Sopenharmony_ci	mov.l		(%sp)+,%d0		# restore d0
954062306a36Sopenharmony_ci	bra.w		Get_Mod
954162306a36Sopenharmony_ci
954262306a36Sopenharmony_ciMod_Loop_pre:
954362306a36Sopenharmony_ci	addq.l		&0x4,%sp		# erase exp(X)
954462306a36Sopenharmony_ci#..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
954562306a36Sopenharmony_ciMod_Loop:
954662306a36Sopenharmony_ci	tst.l		%d6			# test carry bit
954762306a36Sopenharmony_ci	bgt.b		R_GT_Y
954862306a36Sopenharmony_ci
954962306a36Sopenharmony_ci#..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
955062306a36Sopenharmony_ci	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
955162306a36Sopenharmony_ci	bne.b		R_NE_Y
955262306a36Sopenharmony_ci	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
955362306a36Sopenharmony_ci	bne.b		R_NE_Y
955462306a36Sopenharmony_ci
955562306a36Sopenharmony_ci#..At this point, R = Y
955662306a36Sopenharmony_ci	bra.w		Rem_is_0
955762306a36Sopenharmony_ci
955862306a36Sopenharmony_ciR_NE_Y:
955962306a36Sopenharmony_ci#..use the borrow of the previous compare
956062306a36Sopenharmony_ci	bcs.b		R_LT_Y			# borrow is set iff R < Y
956162306a36Sopenharmony_ci
956262306a36Sopenharmony_ciR_GT_Y:
956362306a36Sopenharmony_ci#..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
956462306a36Sopenharmony_ci#..and Y < (D1,D2) < 2Y. Either way, perform R - Y
956562306a36Sopenharmony_ci	sub.l		%d5,%d2			# lo(R) - lo(Y)
956662306a36Sopenharmony_ci	subx.l		%d4,%d1			# hi(R) - hi(Y)
956762306a36Sopenharmony_ci	clr.l		%d6			# clear carry
956862306a36Sopenharmony_ci	addq.l		&1,%d3			# Q := Q + 1
956962306a36Sopenharmony_ci
957062306a36Sopenharmony_ciR_LT_Y:
957162306a36Sopenharmony_ci#..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
957262306a36Sopenharmony_ci	tst.l		%d0			# see if j = 0.
957362306a36Sopenharmony_ci	beq.b		PostLoop
957462306a36Sopenharmony_ci
957562306a36Sopenharmony_ci	add.l		%d3,%d3			# Q := 2Q
957662306a36Sopenharmony_ci	add.l		%d2,%d2			# lo(R) = 2lo(R)
957762306a36Sopenharmony_ci	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
957862306a36Sopenharmony_ci	scs		%d6			# set Carry if 2(R) overflows
957962306a36Sopenharmony_ci	addq.l		&1,%a1			# k := k+1
958062306a36Sopenharmony_ci	subq.l		&1,%d0			# j := j - 1
958162306a36Sopenharmony_ci#..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
958262306a36Sopenharmony_ci
958362306a36Sopenharmony_ci	bra.b		Mod_Loop
958462306a36Sopenharmony_ci
958562306a36Sopenharmony_ciPostLoop:
958662306a36Sopenharmony_ci#..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
958762306a36Sopenharmony_ci
958862306a36Sopenharmony_ci#..normalize R.
958962306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
959062306a36Sopenharmony_ci	tst.l		%d1
959162306a36Sopenharmony_ci	bne.b		HiR_not0
959262306a36Sopenharmony_ci
959362306a36Sopenharmony_ciHiR_0:
959462306a36Sopenharmony_ci	mov.l		%d2,%d1
959562306a36Sopenharmony_ci	clr.l		%d2
959662306a36Sopenharmony_ci	sub.l		&32,%d0
959762306a36Sopenharmony_ci	clr.l		%d6
959862306a36Sopenharmony_ci	bfffo		%d1{&0:&32},%d6
959962306a36Sopenharmony_ci	lsl.l		%d6,%d1
960062306a36Sopenharmony_ci	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
960162306a36Sopenharmony_ci#                                       ...with bias $7FFD
960262306a36Sopenharmony_ci	bra.b		Get_Mod
960362306a36Sopenharmony_ci
960462306a36Sopenharmony_ciHiR_not0:
960562306a36Sopenharmony_ci	clr.l		%d6
960662306a36Sopenharmony_ci	bfffo		%d1{&0:&32},%d6
960762306a36Sopenharmony_ci	bmi.b		Get_Mod			# already normalized
960862306a36Sopenharmony_ci	sub.l		%d6,%d0
960962306a36Sopenharmony_ci	lsl.l		%d6,%d1
961062306a36Sopenharmony_ci	mov.l		%d2,%d7			# a copy of D2
961162306a36Sopenharmony_ci	lsl.l		%d6,%d2
961262306a36Sopenharmony_ci	neg.l		%d6
961362306a36Sopenharmony_ci	add.l		&32,%d6
961462306a36Sopenharmony_ci	lsr.l		%d6,%d7
961562306a36Sopenharmony_ci	or.l		%d7,%d1			# (D0,D1,D2) normalized
961662306a36Sopenharmony_ci
961762306a36Sopenharmony_ci#
961862306a36Sopenharmony_ciGet_Mod:
961962306a36Sopenharmony_ci	cmp.l		%d0,&0x000041FE
962062306a36Sopenharmony_ci	bge.b		No_Scale
962162306a36Sopenharmony_ciDo_Scale:
962262306a36Sopenharmony_ci	mov.w		%d0,R(%a6)
962362306a36Sopenharmony_ci	mov.l		%d1,R_Hi(%a6)
962462306a36Sopenharmony_ci	mov.l		%d2,R_Lo(%a6)
962562306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d6
962662306a36Sopenharmony_ci	mov.w		%d6,Y(%a6)
962762306a36Sopenharmony_ci	mov.l		%d4,Y_Hi(%a6)
962862306a36Sopenharmony_ci	mov.l		%d5,Y_Lo(%a6)
962962306a36Sopenharmony_ci	fmov.x		R(%a6),%fp0		# no exception
963062306a36Sopenharmony_ci	mov.b		&1,Sc_Flag(%a6)
963162306a36Sopenharmony_ci	bra.b		ModOrRem
963262306a36Sopenharmony_ciNo_Scale:
963362306a36Sopenharmony_ci	mov.l		%d1,R_Hi(%a6)
963462306a36Sopenharmony_ci	mov.l		%d2,R_Lo(%a6)
963562306a36Sopenharmony_ci	sub.l		&0x3FFE,%d0
963662306a36Sopenharmony_ci	mov.w		%d0,R(%a6)
963762306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d6
963862306a36Sopenharmony_ci	sub.l		&0x3FFE,%d6
963962306a36Sopenharmony_ci	mov.l		%d6,L_SCR1(%a6)
964062306a36Sopenharmony_ci	fmov.x		R(%a6),%fp0
964162306a36Sopenharmony_ci	mov.w		%d6,Y(%a6)
964262306a36Sopenharmony_ci	mov.l		%d4,Y_Hi(%a6)
964362306a36Sopenharmony_ci	mov.l		%d5,Y_Lo(%a6)
964462306a36Sopenharmony_ci	clr.b		Sc_Flag(%a6)
964562306a36Sopenharmony_ci
964662306a36Sopenharmony_ci#
964762306a36Sopenharmony_ciModOrRem:
964862306a36Sopenharmony_ci	tst.b		Mod_Flag(%a6)
964962306a36Sopenharmony_ci	beq.b		Fix_Sign
965062306a36Sopenharmony_ci
965162306a36Sopenharmony_ci	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
965262306a36Sopenharmony_ci	subq.l		&1,%d6			# biased expo(Y/2)
965362306a36Sopenharmony_ci	cmp.l		%d0,%d6
965462306a36Sopenharmony_ci	blt.b		Fix_Sign
965562306a36Sopenharmony_ci	bgt.b		Last_Sub
965662306a36Sopenharmony_ci
965762306a36Sopenharmony_ci	cmp.l		%d1,%d4
965862306a36Sopenharmony_ci	bne.b		Not_EQ
965962306a36Sopenharmony_ci	cmp.l		%d2,%d5
966062306a36Sopenharmony_ci	bne.b		Not_EQ
966162306a36Sopenharmony_ci	bra.w		Tie_Case
966262306a36Sopenharmony_ci
966362306a36Sopenharmony_ciNot_EQ:
966462306a36Sopenharmony_ci	bcs.b		Fix_Sign
966562306a36Sopenharmony_ci
966662306a36Sopenharmony_ciLast_Sub:
966762306a36Sopenharmony_ci#
966862306a36Sopenharmony_ci	fsub.x		Y(%a6),%fp0		# no exceptions
966962306a36Sopenharmony_ci	addq.l		&1,%d3			# Q := Q + 1
967062306a36Sopenharmony_ci
967162306a36Sopenharmony_ci#
967262306a36Sopenharmony_ciFix_Sign:
967362306a36Sopenharmony_ci#..Get sign of X
967462306a36Sopenharmony_ci	mov.w		SignX(%a6),%d6
967562306a36Sopenharmony_ci	bge.b		Get_Q
967662306a36Sopenharmony_ci	fneg.x		%fp0
967762306a36Sopenharmony_ci
967862306a36Sopenharmony_ci#..Get Q
967962306a36Sopenharmony_ci#
968062306a36Sopenharmony_ciGet_Q:
968162306a36Sopenharmony_ci	clr.l		%d6
968262306a36Sopenharmony_ci	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
968362306a36Sopenharmony_ci	mov.l		&8,%d7
968462306a36Sopenharmony_ci	lsr.l		%d7,%d6
968562306a36Sopenharmony_ci	and.l		&0x0000007F,%d3		# 7 bits of Q
968662306a36Sopenharmony_ci	or.l		%d6,%d3			# sign and bits of Q
968762306a36Sopenharmony_ci#	swap		%d3
968862306a36Sopenharmony_ci#	fmov.l		%fpsr,%d6
968962306a36Sopenharmony_ci#	and.l		&0xFF00FFFF,%d6
969062306a36Sopenharmony_ci#	or.l		%d3,%d6
969162306a36Sopenharmony_ci#	fmov.l		%d6,%fpsr		# put Q in fpsr
969262306a36Sopenharmony_ci	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
969362306a36Sopenharmony_ci
969462306a36Sopenharmony_ci#
969562306a36Sopenharmony_ciRestore:
969662306a36Sopenharmony_ci	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
969762306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
969862306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
969962306a36Sopenharmony_ci	tst.b		Sc_Flag(%a6)
970062306a36Sopenharmony_ci	beq.b		Finish
970162306a36Sopenharmony_ci	mov.b		&FMUL_OP,%d1		# last inst is MUL
970262306a36Sopenharmony_ci	fmul.x		Scale(%pc),%fp0		# may cause underflow
970362306a36Sopenharmony_ci	bra		t_catch2
970462306a36Sopenharmony_ci# the '040 package did this apparently to see if the dst operand for the
970562306a36Sopenharmony_ci# preceding fmul was a denorm. but, it better not have been since the
970662306a36Sopenharmony_ci# algorithm just got done playing with fp0 and expected no exceptions
970762306a36Sopenharmony_ci# as a result. trust me...
970862306a36Sopenharmony_ci#	bra		t_avoid_unsupp		# check for denorm as a
970962306a36Sopenharmony_ci#						;result of the scaling
971062306a36Sopenharmony_ci
971162306a36Sopenharmony_ciFinish:
971262306a36Sopenharmony_ci	mov.b		&FMOV_OP,%d1		# last inst is MOVE
971362306a36Sopenharmony_ci	fmov.x		%fp0,%fp0		# capture exceptions & round
971462306a36Sopenharmony_ci	bra		t_catch2
971562306a36Sopenharmony_ci
971662306a36Sopenharmony_ciRem_is_0:
971762306a36Sopenharmony_ci#..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
971862306a36Sopenharmony_ci	addq.l		&1,%d3
971962306a36Sopenharmony_ci	cmp.l		%d0,&8			# D0 is j
972062306a36Sopenharmony_ci	bge.b		Q_Big
972162306a36Sopenharmony_ci
972262306a36Sopenharmony_ci	lsl.l		%d0,%d3
972362306a36Sopenharmony_ci	bra.b		Set_R_0
972462306a36Sopenharmony_ci
972562306a36Sopenharmony_ciQ_Big:
972662306a36Sopenharmony_ci	clr.l		%d3
972762306a36Sopenharmony_ci
972862306a36Sopenharmony_ciSet_R_0:
972962306a36Sopenharmony_ci	fmov.s		&0x00000000,%fp0
973062306a36Sopenharmony_ci	clr.b		Sc_Flag(%a6)
973162306a36Sopenharmony_ci	bra.w		Fix_Sign
973262306a36Sopenharmony_ci
973362306a36Sopenharmony_ciTie_Case:
973462306a36Sopenharmony_ci#..Check parity of Q
973562306a36Sopenharmony_ci	mov.l		%d3,%d6
973662306a36Sopenharmony_ci	and.l		&0x00000001,%d6
973762306a36Sopenharmony_ci	tst.l		%d6
973862306a36Sopenharmony_ci	beq.w		Fix_Sign		# Q is even
973962306a36Sopenharmony_ci
974062306a36Sopenharmony_ci#..Q is odd, Q := Q + 1, signX := -signX
974162306a36Sopenharmony_ci	addq.l		&1,%d3
974262306a36Sopenharmony_ci	mov.w		SignX(%a6),%d6
974362306a36Sopenharmony_ci	eor.l		&0x00008000,%d6
974462306a36Sopenharmony_ci	mov.w		%d6,SignX(%a6)
974562306a36Sopenharmony_ci	bra.w		Fix_Sign
974662306a36Sopenharmony_ci
974762306a36Sopenharmony_ci#########################################################################
974862306a36Sopenharmony_ci# XDEF ****************************************************************	#
974962306a36Sopenharmony_ci#	tag(): return the optype of the input ext fp number		#
975062306a36Sopenharmony_ci#									#
975162306a36Sopenharmony_ci#	This routine is used by the 060FPLSP.				#
975262306a36Sopenharmony_ci#									#
975362306a36Sopenharmony_ci# XREF ****************************************************************	#
975462306a36Sopenharmony_ci#	None								#
975562306a36Sopenharmony_ci#									#
975662306a36Sopenharmony_ci# INPUT ***************************************************************	#
975762306a36Sopenharmony_ci#	a0 = pointer to extended precision operand			#
975862306a36Sopenharmony_ci#									#
975962306a36Sopenharmony_ci# OUTPUT **************************************************************	#
976062306a36Sopenharmony_ci#	d0 = value of type tag						#
976162306a36Sopenharmony_ci#		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
976262306a36Sopenharmony_ci#									#
976362306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
976462306a36Sopenharmony_ci#	Simply test the exponent, j-bit, and mantissa values to		#
976562306a36Sopenharmony_ci# determine the type of operand.					#
976662306a36Sopenharmony_ci#	If it's an unnormalized zero, alter the operand and force it	#
976762306a36Sopenharmony_ci# to be a normal zero.							#
976862306a36Sopenharmony_ci#									#
976962306a36Sopenharmony_ci#########################################################################
977062306a36Sopenharmony_ci
977162306a36Sopenharmony_ci	global		tag
977262306a36Sopenharmony_citag:
977362306a36Sopenharmony_ci	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
977462306a36Sopenharmony_ci	andi.w		&0x7fff, %d0		# strip off sign
977562306a36Sopenharmony_ci	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
977662306a36Sopenharmony_ci	beq.b		inf_or_nan_x
977762306a36Sopenharmony_cinot_inf_or_nan_x:
977862306a36Sopenharmony_ci	btst		&0x7,FTEMP_HI(%a0)
977962306a36Sopenharmony_ci	beq.b		not_norm_x
978062306a36Sopenharmony_ciis_norm_x:
978162306a36Sopenharmony_ci	mov.b		&NORM, %d0
978262306a36Sopenharmony_ci	rts
978362306a36Sopenharmony_cinot_norm_x:
978462306a36Sopenharmony_ci	tst.w		%d0			# is exponent = 0?
978562306a36Sopenharmony_ci	bne.b		is_unnorm_x
978662306a36Sopenharmony_cinot_unnorm_x:
978762306a36Sopenharmony_ci	tst.l		FTEMP_HI(%a0)
978862306a36Sopenharmony_ci	bne.b		is_denorm_x
978962306a36Sopenharmony_ci	tst.l		FTEMP_LO(%a0)
979062306a36Sopenharmony_ci	bne.b		is_denorm_x
979162306a36Sopenharmony_ciis_zero_x:
979262306a36Sopenharmony_ci	mov.b		&ZERO, %d0
979362306a36Sopenharmony_ci	rts
979462306a36Sopenharmony_ciis_denorm_x:
979562306a36Sopenharmony_ci	mov.b		&DENORM, %d0
979662306a36Sopenharmony_ci	rts
979762306a36Sopenharmony_ciis_unnorm_x:
979862306a36Sopenharmony_ci	bsr.l		unnorm_fix		# convert to norm,denorm,or zero
979962306a36Sopenharmony_ci	rts
980062306a36Sopenharmony_ciis_unnorm_reg_x:
980162306a36Sopenharmony_ci	mov.b		&UNNORM, %d0
980262306a36Sopenharmony_ci	rts
980362306a36Sopenharmony_ciinf_or_nan_x:
980462306a36Sopenharmony_ci	tst.l		FTEMP_LO(%a0)
980562306a36Sopenharmony_ci	bne.b		is_nan_x
980662306a36Sopenharmony_ci	mov.l		FTEMP_HI(%a0), %d0
980762306a36Sopenharmony_ci	and.l		&0x7fffffff, %d0	# msb is a don't care!
980862306a36Sopenharmony_ci	bne.b		is_nan_x
980962306a36Sopenharmony_ciis_inf_x:
981062306a36Sopenharmony_ci	mov.b		&INF, %d0
981162306a36Sopenharmony_ci	rts
981262306a36Sopenharmony_ciis_nan_x:
981362306a36Sopenharmony_ci	mov.b		&QNAN, %d0
981462306a36Sopenharmony_ci	rts
981562306a36Sopenharmony_ci
981662306a36Sopenharmony_ci#############################################################
981762306a36Sopenharmony_ci
981862306a36Sopenharmony_ciqnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
981962306a36Sopenharmony_ci
982062306a36Sopenharmony_ci#########################################################################
982162306a36Sopenharmony_ci# XDEF ****************************************************************	#
982262306a36Sopenharmony_ci#	t_dz(): Handle 060FPLSP dz exception for "flogn" emulation.	#
982362306a36Sopenharmony_ci#	t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation.	#
982462306a36Sopenharmony_ci#									#
982562306a36Sopenharmony_ci#	These rouitnes are used by the 060FPLSP package.		#
982662306a36Sopenharmony_ci#									#
982762306a36Sopenharmony_ci# XREF ****************************************************************	#
982862306a36Sopenharmony_ci#	None								#
982962306a36Sopenharmony_ci#									#
983062306a36Sopenharmony_ci# INPUT ***************************************************************	#
983162306a36Sopenharmony_ci#	a0 = pointer to extended precision source operand.		#
983262306a36Sopenharmony_ci#									#
983362306a36Sopenharmony_ci# OUTPUT **************************************************************	#
983462306a36Sopenharmony_ci#	fp0 = default DZ result.					#
983562306a36Sopenharmony_ci#									#
983662306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
983762306a36Sopenharmony_ci#	Transcendental emulation for the 060FPLSP has detected that	#
983862306a36Sopenharmony_ci# a DZ exception should occur for the instruction. If DZ is disabled,	#
983962306a36Sopenharmony_ci# return the default result.						#
984062306a36Sopenharmony_ci#	If DZ is enabled, the dst operand should be returned unscathed	#
984162306a36Sopenharmony_ci# in fp0 while fp1 is used to create a DZ exception so that the		#
984262306a36Sopenharmony_ci# operating system can log that such an event occurred.			#
984362306a36Sopenharmony_ci#									#
984462306a36Sopenharmony_ci#########################################################################
984562306a36Sopenharmony_ci
984662306a36Sopenharmony_ci	global		t_dz
984762306a36Sopenharmony_cit_dz:
984862306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# check sign for neg or pos
984962306a36Sopenharmony_ci	bpl.b		dz_pinf			# branch if pos sign
985062306a36Sopenharmony_ci
985162306a36Sopenharmony_ci	global		t_dz2
985262306a36Sopenharmony_cit_dz2:
985362306a36Sopenharmony_ci	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
985462306a36Sopenharmony_ci
985562306a36Sopenharmony_ci	btst		&dz_bit,FPCR_ENABLE(%a6)
985662306a36Sopenharmony_ci	bne.b		dz_minf_ena
985762306a36Sopenharmony_ci
985862306a36Sopenharmony_ci# dz is disabled. return a -INF.
985962306a36Sopenharmony_ci	fmov.s		&0xff800000,%fp0	# return -INF
986062306a36Sopenharmony_ci	rts
986162306a36Sopenharmony_ci
986262306a36Sopenharmony_ci# dz is enabled. create a dz exception so the user can record it
986362306a36Sopenharmony_ci# but use fp1 instead. return the dst operand unscathed in fp0.
986462306a36Sopenharmony_cidz_minf_ena:
986562306a36Sopenharmony_ci	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
986662306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
986762306a36Sopenharmony_ci	fmov.s		&0xbf800000,%fp1	# load -1
986862306a36Sopenharmony_ci	fdiv.s		&0x00000000,%fp1	# -1 / 0
986962306a36Sopenharmony_ci	rts
987062306a36Sopenharmony_ci
987162306a36Sopenharmony_cidz_pinf:
987262306a36Sopenharmony_ci	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
987362306a36Sopenharmony_ci
987462306a36Sopenharmony_ci	btst		&dz_bit,FPCR_ENABLE(%a6)
987562306a36Sopenharmony_ci	bne.b		dz_pinf_ena
987662306a36Sopenharmony_ci
987762306a36Sopenharmony_ci# dz is disabled. return a +INF.
987862306a36Sopenharmony_ci	fmov.s		&0x7f800000,%fp0	# return +INF
987962306a36Sopenharmony_ci	rts
988062306a36Sopenharmony_ci
988162306a36Sopenharmony_ci# dz is enabled. create a dz exception so the user can record it
988262306a36Sopenharmony_ci# but use fp1 instead. return the dst operand unscathed in fp0.
988362306a36Sopenharmony_cidz_pinf_ena:
988462306a36Sopenharmony_ci	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
988562306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
988662306a36Sopenharmony_ci	fmov.s		&0x3f800000,%fp1	# load +1
988762306a36Sopenharmony_ci	fdiv.s		&0x00000000,%fp1	# +1 / 0
988862306a36Sopenharmony_ci	rts
988962306a36Sopenharmony_ci
989062306a36Sopenharmony_ci#########################################################################
989162306a36Sopenharmony_ci# XDEF ****************************************************************	#
989262306a36Sopenharmony_ci#	t_operr(): Handle 060FPLSP OPERR exception during emulation.	#
989362306a36Sopenharmony_ci#									#
989462306a36Sopenharmony_ci#	This routine is used by the 060FPLSP package.			#
989562306a36Sopenharmony_ci#									#
989662306a36Sopenharmony_ci# XREF ****************************************************************	#
989762306a36Sopenharmony_ci#	None.								#
989862306a36Sopenharmony_ci#									#
989962306a36Sopenharmony_ci# INPUT ***************************************************************	#
990062306a36Sopenharmony_ci#	fp1 = source operand						#
990162306a36Sopenharmony_ci#									#
990262306a36Sopenharmony_ci# OUTPUT **************************************************************	#
990362306a36Sopenharmony_ci#	fp0 = default result						#
990462306a36Sopenharmony_ci#	fp1 = unchanged							#
990562306a36Sopenharmony_ci#									#
990662306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
990762306a36Sopenharmony_ci#	An operand error should occur as the result of transcendental	#
990862306a36Sopenharmony_ci# emulation in the 060FPLSP. If OPERR is disabled, just return a NAN	#
990962306a36Sopenharmony_ci# in fp0. If OPERR is enabled, return the dst operand unscathed in fp0	#
991062306a36Sopenharmony_ci# and the source operand in fp1. Use fp2 to create an OPERR exception	#
991162306a36Sopenharmony_ci# so that the operating system can log the event.			#
991262306a36Sopenharmony_ci#									#
991362306a36Sopenharmony_ci#########################################################################
991462306a36Sopenharmony_ci
991562306a36Sopenharmony_ci	global		t_operr
991662306a36Sopenharmony_cit_operr:
991762306a36Sopenharmony_ci	ori.l		&opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
991862306a36Sopenharmony_ci
991962306a36Sopenharmony_ci	btst		&operr_bit,FPCR_ENABLE(%a6)
992062306a36Sopenharmony_ci	bne.b		operr_ena
992162306a36Sopenharmony_ci
992262306a36Sopenharmony_ci# operr is disabled. return a QNAN in fp0
992362306a36Sopenharmony_ci	fmovm.x		qnan(%pc),&0x80		# return QNAN
992462306a36Sopenharmony_ci	rts
992562306a36Sopenharmony_ci
992662306a36Sopenharmony_ci# operr is enabled. create an operr exception so the user can record it
992762306a36Sopenharmony_ci# but use fp2 instead. return the dst operand unscathed in fp0.
992862306a36Sopenharmony_cioperr_ena:
992962306a36Sopenharmony_ci	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
993062306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
993162306a36Sopenharmony_ci	fmovm.x		&0x04,-(%sp)		# save fp2
993262306a36Sopenharmony_ci	fmov.s		&0x7f800000,%fp2	# load +INF
993362306a36Sopenharmony_ci	fmul.s		&0x00000000,%fp2	# +INF x 0
993462306a36Sopenharmony_ci	fmovm.x		(%sp)+,&0x20		# restore fp2
993562306a36Sopenharmony_ci	rts
993662306a36Sopenharmony_ci
993762306a36Sopenharmony_cipls_huge:
993862306a36Sopenharmony_ci	long		0x7ffe0000,0xffffffff,0xffffffff
993962306a36Sopenharmony_cimns_huge:
994062306a36Sopenharmony_ci	long		0xfffe0000,0xffffffff,0xffffffff
994162306a36Sopenharmony_cipls_tiny:
994262306a36Sopenharmony_ci	long		0x00000000,0x80000000,0x00000000
994362306a36Sopenharmony_cimns_tiny:
994462306a36Sopenharmony_ci	long		0x80000000,0x80000000,0x00000000
994562306a36Sopenharmony_ci
994662306a36Sopenharmony_ci#########################################################################
994762306a36Sopenharmony_ci# XDEF ****************************************************************	#
994862306a36Sopenharmony_ci#	t_unfl(): Handle 060FPLSP underflow exception during emulation.	#
994962306a36Sopenharmony_ci#	t_unfl2(): Handle 060FPLSP underflow exception during		#
995062306a36Sopenharmony_ci#	           emulation. result always positive.			#
995162306a36Sopenharmony_ci#									#
995262306a36Sopenharmony_ci#	This routine is used by the 060FPLSP package.			#
995362306a36Sopenharmony_ci#									#
995462306a36Sopenharmony_ci# XREF ****************************************************************	#
995562306a36Sopenharmony_ci#	None.								#
995662306a36Sopenharmony_ci#									#
995762306a36Sopenharmony_ci# INPUT ***************************************************************	#
995862306a36Sopenharmony_ci#	a0 = pointer to extended precision source operand		#
995962306a36Sopenharmony_ci#									#
996062306a36Sopenharmony_ci# OUTPUT **************************************************************	#
996162306a36Sopenharmony_ci#	fp0 = default underflow result					#
996262306a36Sopenharmony_ci#									#
996362306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
996462306a36Sopenharmony_ci#	An underflow should occur as the result of transcendental	#
996562306a36Sopenharmony_ci# emulation in the 060FPLSP. Create an underflow by using "fmul"	#
996662306a36Sopenharmony_ci# and two very small numbers of appropriate sign so the operating	#
996762306a36Sopenharmony_ci# system can log the event.						#
996862306a36Sopenharmony_ci#									#
996962306a36Sopenharmony_ci#########################################################################
997062306a36Sopenharmony_ci
997162306a36Sopenharmony_ci	global		t_unfl
997262306a36Sopenharmony_cit_unfl:
997362306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)
997462306a36Sopenharmony_ci	bpl.b		unf_pos
997562306a36Sopenharmony_ci
997662306a36Sopenharmony_ci	global		t_unfl2
997762306a36Sopenharmony_cit_unfl2:
997862306a36Sopenharmony_ci	ori.l		&unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
997962306a36Sopenharmony_ci
998062306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
998162306a36Sopenharmony_ci	fmovm.x		mns_tiny(%pc),&0x80
998262306a36Sopenharmony_ci	fmul.x		pls_tiny(%pc),%fp0
998362306a36Sopenharmony_ci
998462306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
998562306a36Sopenharmony_ci	rol.l		&0x8,%d0
998662306a36Sopenharmony_ci	mov.b		%d0,FPSR_CC(%a6)
998762306a36Sopenharmony_ci	rts
998862306a36Sopenharmony_ciunf_pos:
998962306a36Sopenharmony_ci	ori.w		&unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
999062306a36Sopenharmony_ci
999162306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
999262306a36Sopenharmony_ci	fmovm.x		pls_tiny(%pc),&0x80
999362306a36Sopenharmony_ci	fmul.x		%fp0,%fp0
999462306a36Sopenharmony_ci
999562306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
999662306a36Sopenharmony_ci	rol.l		&0x8,%d0
999762306a36Sopenharmony_ci	mov.b		%d0,FPSR_CC(%a6)
999862306a36Sopenharmony_ci	rts
999962306a36Sopenharmony_ci
1000062306a36Sopenharmony_ci#########################################################################
1000162306a36Sopenharmony_ci# XDEF ****************************************************************	#
1000262306a36Sopenharmony_ci#	t_ovfl(): Handle 060FPLSP overflow exception during emulation.	#
1000362306a36Sopenharmony_ci#		  (monadic)						#
1000462306a36Sopenharmony_ci#	t_ovfl2(): Handle 060FPLSP overflow exception during		#
1000562306a36Sopenharmony_ci#	           emulation. result always positive. (dyadic)		#
1000662306a36Sopenharmony_ci#	t_ovfl_sc(): Handle 060FPLSP overflow exception during		#
1000762306a36Sopenharmony_ci#	             emulation for "fscale".				#
1000862306a36Sopenharmony_ci#									#
1000962306a36Sopenharmony_ci#	This routine is used by the 060FPLSP package.			#
1001062306a36Sopenharmony_ci#									#
1001162306a36Sopenharmony_ci# XREF ****************************************************************	#
1001262306a36Sopenharmony_ci#	None.								#
1001362306a36Sopenharmony_ci#									#
1001462306a36Sopenharmony_ci# INPUT ***************************************************************	#
1001562306a36Sopenharmony_ci#	a0 = pointer to extended precision source operand		#
1001662306a36Sopenharmony_ci#									#
1001762306a36Sopenharmony_ci# OUTPUT **************************************************************	#
1001862306a36Sopenharmony_ci#	fp0 = default underflow result					#
1001962306a36Sopenharmony_ci#									#
1002062306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
1002162306a36Sopenharmony_ci#	An overflow should occur as the result of transcendental	#
1002262306a36Sopenharmony_ci# emulation in the 060FPLSP. Create an overflow by using "fmul"		#
1002362306a36Sopenharmony_ci# and two very lareg numbers of appropriate sign so the operating	#
1002462306a36Sopenharmony_ci# system can log the event.						#
1002562306a36Sopenharmony_ci#	For t_ovfl_sc() we take special care not to lose the INEX2 bit.	#
1002662306a36Sopenharmony_ci#									#
1002762306a36Sopenharmony_ci#########################################################################
1002862306a36Sopenharmony_ci
1002962306a36Sopenharmony_ci	global		t_ovfl_sc
1003062306a36Sopenharmony_cit_ovfl_sc:
1003162306a36Sopenharmony_ci	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
1003262306a36Sopenharmony_ci
1003362306a36Sopenharmony_ci	mov.b		%d0,%d1			# fetch rnd prec,mode
1003462306a36Sopenharmony_ci	andi.b		&0xc0,%d1		# extract prec
1003562306a36Sopenharmony_ci	beq.w		ovfl_work
1003662306a36Sopenharmony_ci
1003762306a36Sopenharmony_ci# dst op is a DENORM. we have to normalize the mantissa to see if the
1003862306a36Sopenharmony_ci# result would be inexact for the given precision. make a copy of the
1003962306a36Sopenharmony_ci# dst so we don't screw up the version passed to us.
1004062306a36Sopenharmony_ci	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
1004162306a36Sopenharmony_ci	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
1004262306a36Sopenharmony_ci	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
1004362306a36Sopenharmony_ci	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
1004462306a36Sopenharmony_ci	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
1004562306a36Sopenharmony_ci	bsr.l		norm			# normalize mantissa
1004662306a36Sopenharmony_ci	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
1004762306a36Sopenharmony_ci
1004862306a36Sopenharmony_ci	cmpi.b		%d1,&0x40		# is precision sgl?
1004962306a36Sopenharmony_ci	bne.b		ovfl_sc_dbl		# no; dbl
1005062306a36Sopenharmony_ciovfl_sc_sgl:
1005162306a36Sopenharmony_ci	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
1005262306a36Sopenharmony_ci	bne.b		ovfl_sc_inx		# yes
1005362306a36Sopenharmony_ci	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
1005462306a36Sopenharmony_ci	bne.b		ovfl_sc_inx		# yes
1005562306a36Sopenharmony_ci	bra.w		ovfl_work		# don't set INEX2
1005662306a36Sopenharmony_ciovfl_sc_dbl:
1005762306a36Sopenharmony_ci	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
1005862306a36Sopenharmony_ci	andi.l		&0x7ff,%d1		# dbl mantissa set?
1005962306a36Sopenharmony_ci	beq.w		ovfl_work		# no; don't set INEX2
1006062306a36Sopenharmony_ciovfl_sc_inx:
1006162306a36Sopenharmony_ci	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
1006262306a36Sopenharmony_ci	bra.b		ovfl_work		# continue
1006362306a36Sopenharmony_ci
1006462306a36Sopenharmony_ci	global		t_ovfl
1006562306a36Sopenharmony_cit_ovfl:
1006662306a36Sopenharmony_ci	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
1006762306a36Sopenharmony_ciovfl_work:
1006862306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)
1006962306a36Sopenharmony_ci	bpl.b		ovfl_p
1007062306a36Sopenharmony_ciovfl_m:
1007162306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
1007262306a36Sopenharmony_ci	fmovm.x		mns_huge(%pc),&0x80
1007362306a36Sopenharmony_ci	fmul.x		pls_huge(%pc),%fp0
1007462306a36Sopenharmony_ci
1007562306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1007662306a36Sopenharmony_ci	rol.l		&0x8,%d0
1007762306a36Sopenharmony_ci	ori.b		&neg_mask,%d0
1007862306a36Sopenharmony_ci	mov.b		%d0,FPSR_CC(%a6)
1007962306a36Sopenharmony_ci	rts
1008062306a36Sopenharmony_ciovfl_p:
1008162306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
1008262306a36Sopenharmony_ci	fmovm.x		pls_huge(%pc),&0x80
1008362306a36Sopenharmony_ci	fmul.x		pls_huge(%pc),%fp0
1008462306a36Sopenharmony_ci
1008562306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1008662306a36Sopenharmony_ci	rol.l		&0x8,%d0
1008762306a36Sopenharmony_ci	mov.b		%d0,FPSR_CC(%a6)
1008862306a36Sopenharmony_ci	rts
1008962306a36Sopenharmony_ci
1009062306a36Sopenharmony_ci	global		t_ovfl2
1009162306a36Sopenharmony_cit_ovfl2:
1009262306a36Sopenharmony_ci	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
1009362306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
1009462306a36Sopenharmony_ci	fmovm.x		pls_huge(%pc),&0x80
1009562306a36Sopenharmony_ci	fmul.x		pls_huge(%pc),%fp0
1009662306a36Sopenharmony_ci
1009762306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1009862306a36Sopenharmony_ci	rol.l		&0x8,%d0
1009962306a36Sopenharmony_ci	mov.b		%d0,FPSR_CC(%a6)
1010062306a36Sopenharmony_ci	rts
1010162306a36Sopenharmony_ci
1010262306a36Sopenharmony_ci#########################################################################
1010362306a36Sopenharmony_ci# XDEF ****************************************************************	#
1010462306a36Sopenharmony_ci#	t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
1010562306a36Sopenharmony_ci#		   emulation.						#
1010662306a36Sopenharmony_ci#	t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
1010762306a36Sopenharmony_ci#		    emulation.						#
1010862306a36Sopenharmony_ci#									#
1010962306a36Sopenharmony_ci#	These routines are used by the 060FPLSP package.		#
1011062306a36Sopenharmony_ci#									#
1011162306a36Sopenharmony_ci# XREF ****************************************************************	#
1011262306a36Sopenharmony_ci#	None.								#
1011362306a36Sopenharmony_ci#									#
1011462306a36Sopenharmony_ci# INPUT ***************************************************************	#
1011562306a36Sopenharmony_ci#	fp0 = default underflow or overflow result			#
1011662306a36Sopenharmony_ci#									#
1011762306a36Sopenharmony_ci# OUTPUT **************************************************************	#
1011862306a36Sopenharmony_ci#	fp0 = default result						#
1011962306a36Sopenharmony_ci#									#
1012062306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
1012162306a36Sopenharmony_ci#	If an overflow or underflow occurred during the last		#
1012262306a36Sopenharmony_ci# instruction of transcendental 060FPLSP emulation, then it has already	#
1012362306a36Sopenharmony_ci# occurred and has been logged. Now we need to see if an inexact	#
1012462306a36Sopenharmony_ci# exception should occur.						#
1012562306a36Sopenharmony_ci#									#
1012662306a36Sopenharmony_ci#########################################################################
1012762306a36Sopenharmony_ci
1012862306a36Sopenharmony_ci	global		t_catch2
1012962306a36Sopenharmony_cit_catch2:
1013062306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1013162306a36Sopenharmony_ci	or.l		%d0,USER_FPSR(%a6)
1013262306a36Sopenharmony_ci	bra.b		inx2_work
1013362306a36Sopenharmony_ci
1013462306a36Sopenharmony_ci	global		t_catch
1013562306a36Sopenharmony_cit_catch:
1013662306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1013762306a36Sopenharmony_ci	or.l		%d0,USER_FPSR(%a6)
1013862306a36Sopenharmony_ci
1013962306a36Sopenharmony_ci#########################################################################
1014062306a36Sopenharmony_ci# XDEF ****************************************************************	#
1014162306a36Sopenharmony_ci#	t_inx2(): Handle inexact 060FPLSP exception during emulation.	#
1014262306a36Sopenharmony_ci#	t_pinx2(): Handle inexact 060FPLSP exception for "+" results.	#
1014362306a36Sopenharmony_ci#	t_minx2(): Handle inexact 060FPLSP exception for "-" results.	#
1014462306a36Sopenharmony_ci#									#
1014562306a36Sopenharmony_ci# XREF ****************************************************************	#
1014662306a36Sopenharmony_ci#	None.								#
1014762306a36Sopenharmony_ci#									#
1014862306a36Sopenharmony_ci# INPUT ***************************************************************	#
1014962306a36Sopenharmony_ci#	fp0 = default result						#
1015062306a36Sopenharmony_ci#									#
1015162306a36Sopenharmony_ci# OUTPUT **************************************************************	#
1015262306a36Sopenharmony_ci#	fp0 = default result						#
1015362306a36Sopenharmony_ci#									#
1015462306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
1015562306a36Sopenharmony_ci#	The last instruction of transcendental emulation for the	#
1015662306a36Sopenharmony_ci# 060FPLSP should be inexact. So, if inexact is enabled, then we create	#
1015762306a36Sopenharmony_ci# the event here by adding a large and very small number together	#
1015862306a36Sopenharmony_ci# so that the operating system can log the event.			#
1015962306a36Sopenharmony_ci#	Must check, too, if the result was zero, in which case we just	#
1016062306a36Sopenharmony_ci# set the FPSR bits and return.						#
1016162306a36Sopenharmony_ci#									#
1016262306a36Sopenharmony_ci#########################################################################
1016362306a36Sopenharmony_ci
1016462306a36Sopenharmony_ci	global		t_inx2
1016562306a36Sopenharmony_cit_inx2:
1016662306a36Sopenharmony_ci	fblt.w		t_minx2
1016762306a36Sopenharmony_ci	fbeq.w		inx2_zero
1016862306a36Sopenharmony_ci
1016962306a36Sopenharmony_ci	global		t_pinx2
1017062306a36Sopenharmony_cit_pinx2:
1017162306a36Sopenharmony_ci	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
1017262306a36Sopenharmony_ci	bra.b		inx2_work
1017362306a36Sopenharmony_ci
1017462306a36Sopenharmony_ci	global		t_minx2
1017562306a36Sopenharmony_cit_minx2:
1017662306a36Sopenharmony_ci	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6)
1017762306a36Sopenharmony_ci
1017862306a36Sopenharmony_ciinx2_work:
1017962306a36Sopenharmony_ci	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
1018062306a36Sopenharmony_ci	bne.b		inx2_work_ena		# yes
1018162306a36Sopenharmony_ci	rts
1018262306a36Sopenharmony_ciinx2_work_ena:
1018362306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr	# insert user's exceptions
1018462306a36Sopenharmony_ci	fmov.s		&0x3f800000,%fp1	# load +1
1018562306a36Sopenharmony_ci	fadd.x		pls_tiny(%pc),%fp1	# cause exception
1018662306a36Sopenharmony_ci	rts
1018762306a36Sopenharmony_ci
1018862306a36Sopenharmony_ciinx2_zero:
1018962306a36Sopenharmony_ci	mov.b		&z_bmask,FPSR_CC(%a6)
1019062306a36Sopenharmony_ci	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
1019162306a36Sopenharmony_ci	rts
1019262306a36Sopenharmony_ci
1019362306a36Sopenharmony_ci#########################################################################
1019462306a36Sopenharmony_ci# XDEF ****************************************************************	#
1019562306a36Sopenharmony_ci#	t_extdnrm(): Handle DENORM inputs in 060FPLSP.			#
1019662306a36Sopenharmony_ci#	t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale".	#
1019762306a36Sopenharmony_ci#									#
1019862306a36Sopenharmony_ci#	This routine is used by the 060FPLSP package.			#
1019962306a36Sopenharmony_ci#									#
1020062306a36Sopenharmony_ci# XREF ****************************************************************	#
1020162306a36Sopenharmony_ci#	None.								#
1020262306a36Sopenharmony_ci#									#
1020362306a36Sopenharmony_ci# INPUT ***************************************************************	#
1020462306a36Sopenharmony_ci#	a0 = pointer to extended precision input operand		#
1020562306a36Sopenharmony_ci#									#
1020662306a36Sopenharmony_ci# OUTPUT **************************************************************	#
1020762306a36Sopenharmony_ci#	fp0 = default result						#
1020862306a36Sopenharmony_ci#									#
1020962306a36Sopenharmony_ci# ALGORITHM ***********************************************************	#
1021062306a36Sopenharmony_ci#	For all functions that have a denormalized input and that	#
1021162306a36Sopenharmony_ci# f(x)=x, this is the entry point.					#
1021262306a36Sopenharmony_ci#	DENORM value is moved using "fmove" which triggers an exception	#
1021362306a36Sopenharmony_ci# if enabled so the operating system can log the event.			#
1021462306a36Sopenharmony_ci#									#
1021562306a36Sopenharmony_ci#########################################################################
1021662306a36Sopenharmony_ci
1021762306a36Sopenharmony_ci	global		t_extdnrm
1021862306a36Sopenharmony_cit_extdnrm:
1021962306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
1022062306a36Sopenharmony_ci	fmov.x		SRC_EX(%a0),%fp0
1022162306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1022262306a36Sopenharmony_ci	ori.l		&unfinx_mask,%d0
1022362306a36Sopenharmony_ci	or.l		%d0,USER_FPSR(%a6)
1022462306a36Sopenharmony_ci	rts
1022562306a36Sopenharmony_ci
1022662306a36Sopenharmony_ci	global		t_resdnrm
1022762306a36Sopenharmony_cit_resdnrm:
1022862306a36Sopenharmony_ci	fmov.l		USER_FPCR(%a6),%fpcr
1022962306a36Sopenharmony_ci	fmov.x		SRC_EX(%a0),%fp0
1023062306a36Sopenharmony_ci	fmov.l		%fpsr,%d0
1023162306a36Sopenharmony_ci	or.l		%d0,USER_FPSR(%a6)
1023262306a36Sopenharmony_ci	rts
1023362306a36Sopenharmony_ci
1023462306a36Sopenharmony_ci##########################################
1023562306a36Sopenharmony_ci
1023662306a36Sopenharmony_ci#
1023762306a36Sopenharmony_ci# sto_cos:
1023862306a36Sopenharmony_ci#	This is used by fsincos library emulation. The correct
1023962306a36Sopenharmony_ci# values are already in fp0 and fp1 so we do nothing here.
1024062306a36Sopenharmony_ci#
1024162306a36Sopenharmony_ci	global		sto_cos
1024262306a36Sopenharmony_cisto_cos:
1024362306a36Sopenharmony_ci	rts
1024462306a36Sopenharmony_ci
1024562306a36Sopenharmony_ci##########################################
1024662306a36Sopenharmony_ci
1024762306a36Sopenharmony_ci#
1024862306a36Sopenharmony_ci#	dst_qnan --- force result when destination is a NaN
1024962306a36Sopenharmony_ci#
1025062306a36Sopenharmony_ci	global		dst_qnan
1025162306a36Sopenharmony_cidst_qnan:
1025262306a36Sopenharmony_ci	fmov.x		DST(%a1),%fp0
1025362306a36Sopenharmony_ci	tst.b		DST_EX(%a1)
1025462306a36Sopenharmony_ci	bmi.b		dst_qnan_m
1025562306a36Sopenharmony_cidst_qnan_p:
1025662306a36Sopenharmony_ci	mov.b		&nan_bmask,FPSR_CC(%a6)
1025762306a36Sopenharmony_ci	rts
1025862306a36Sopenharmony_cidst_qnan_m:
1025962306a36Sopenharmony_ci	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
1026062306a36Sopenharmony_ci	rts
1026162306a36Sopenharmony_ci
1026262306a36Sopenharmony_ci#
1026362306a36Sopenharmony_ci#	src_qnan --- force result when source is a NaN
1026462306a36Sopenharmony_ci#
1026562306a36Sopenharmony_ci	global		src_qnan
1026662306a36Sopenharmony_cisrc_qnan:
1026762306a36Sopenharmony_ci	fmov.x		SRC(%a0),%fp0
1026862306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)
1026962306a36Sopenharmony_ci	bmi.b		src_qnan_m
1027062306a36Sopenharmony_cisrc_qnan_p:
1027162306a36Sopenharmony_ci	mov.b		&nan_bmask,FPSR_CC(%a6)
1027262306a36Sopenharmony_ci	rts
1027362306a36Sopenharmony_cisrc_qnan_m:
1027462306a36Sopenharmony_ci	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
1027562306a36Sopenharmony_ci	rts
1027662306a36Sopenharmony_ci
1027762306a36Sopenharmony_ci##########################################
1027862306a36Sopenharmony_ci
1027962306a36Sopenharmony_ci#
1028062306a36Sopenharmony_ci#	Native instruction support
1028162306a36Sopenharmony_ci#
1028262306a36Sopenharmony_ci#	Some systems may need entry points even for 68060 native
1028362306a36Sopenharmony_ci#	instructions.  These routines are provided for
1028462306a36Sopenharmony_ci#	convenience.
1028562306a36Sopenharmony_ci#
1028662306a36Sopenharmony_ci	global		_fadds_
1028762306a36Sopenharmony_ci_fadds_:
1028862306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1028962306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1029062306a36Sopenharmony_ci	fmov.s		0x8(%sp),%fp0		# load sgl dst
1029162306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1029262306a36Sopenharmony_ci	fadd.s		0x8(%sp),%fp0		# fadd w/ sgl src
1029362306a36Sopenharmony_ci	rts
1029462306a36Sopenharmony_ci
1029562306a36Sopenharmony_ci	global		_faddd_
1029662306a36Sopenharmony_ci_faddd_:
1029762306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1029862306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1029962306a36Sopenharmony_ci	fmov.d		0x8(%sp),%fp0		# load dbl dst
1030062306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1030162306a36Sopenharmony_ci	fadd.d		0xc(%sp),%fp0		# fadd w/ dbl src
1030262306a36Sopenharmony_ci	rts
1030362306a36Sopenharmony_ci
1030462306a36Sopenharmony_ci	global		_faddx_
1030562306a36Sopenharmony_ci_faddx_:
1030662306a36Sopenharmony_ci	fmovm.x		0x4(%sp),&0x80		# load ext dst
1030762306a36Sopenharmony_ci	fadd.x		0x10(%sp),%fp0		# fadd w/ ext src
1030862306a36Sopenharmony_ci	rts
1030962306a36Sopenharmony_ci
1031062306a36Sopenharmony_ci	global		_fsubs_
1031162306a36Sopenharmony_ci_fsubs_:
1031262306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1031362306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1031462306a36Sopenharmony_ci	fmov.s		0x8(%sp),%fp0		# load sgl dst
1031562306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1031662306a36Sopenharmony_ci	fsub.s		0x8(%sp),%fp0		# fsub w/ sgl src
1031762306a36Sopenharmony_ci	rts
1031862306a36Sopenharmony_ci
1031962306a36Sopenharmony_ci	global		_fsubd_
1032062306a36Sopenharmony_ci_fsubd_:
1032162306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1032262306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1032362306a36Sopenharmony_ci	fmov.d		0x8(%sp),%fp0		# load dbl dst
1032462306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1032562306a36Sopenharmony_ci	fsub.d		0xc(%sp),%fp0		# fsub w/ dbl src
1032662306a36Sopenharmony_ci	rts
1032762306a36Sopenharmony_ci
1032862306a36Sopenharmony_ci	global		_fsubx_
1032962306a36Sopenharmony_ci_fsubx_:
1033062306a36Sopenharmony_ci	fmovm.x		0x4(%sp),&0x80		# load ext dst
1033162306a36Sopenharmony_ci	fsub.x		0x10(%sp),%fp0		# fsub w/ ext src
1033262306a36Sopenharmony_ci	rts
1033362306a36Sopenharmony_ci
1033462306a36Sopenharmony_ci	global		_fmuls_
1033562306a36Sopenharmony_ci_fmuls_:
1033662306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1033762306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1033862306a36Sopenharmony_ci	fmov.s		0x8(%sp),%fp0		# load sgl dst
1033962306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1034062306a36Sopenharmony_ci	fmul.s		0x8(%sp),%fp0		# fmul w/ sgl src
1034162306a36Sopenharmony_ci	rts
1034262306a36Sopenharmony_ci
1034362306a36Sopenharmony_ci	global		_fmuld_
1034462306a36Sopenharmony_ci_fmuld_:
1034562306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1034662306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1034762306a36Sopenharmony_ci	fmov.d		0x8(%sp),%fp0		# load dbl dst
1034862306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1034962306a36Sopenharmony_ci	fmul.d		0xc(%sp),%fp0		# fmul w/ dbl src
1035062306a36Sopenharmony_ci	rts
1035162306a36Sopenharmony_ci
1035262306a36Sopenharmony_ci	global		_fmulx_
1035362306a36Sopenharmony_ci_fmulx_:
1035462306a36Sopenharmony_ci	fmovm.x		0x4(%sp),&0x80		# load ext dst
1035562306a36Sopenharmony_ci	fmul.x		0x10(%sp),%fp0		# fmul w/ ext src
1035662306a36Sopenharmony_ci	rts
1035762306a36Sopenharmony_ci
1035862306a36Sopenharmony_ci	global		_fdivs_
1035962306a36Sopenharmony_ci_fdivs_:
1036062306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1036162306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1036262306a36Sopenharmony_ci	fmov.s		0x8(%sp),%fp0		# load sgl dst
1036362306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1036462306a36Sopenharmony_ci	fdiv.s		0x8(%sp),%fp0		# fdiv w/ sgl src
1036562306a36Sopenharmony_ci	rts
1036662306a36Sopenharmony_ci
1036762306a36Sopenharmony_ci	global		_fdivd_
1036862306a36Sopenharmony_ci_fdivd_:
1036962306a36Sopenharmony_ci	fmov.l		%fpcr,-(%sp)		# save fpcr
1037062306a36Sopenharmony_ci	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
1037162306a36Sopenharmony_ci	fmov.d		0x8(%sp),%fp0		# load dbl dst
1037262306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr		# restore fpcr
1037362306a36Sopenharmony_ci	fdiv.d		0xc(%sp),%fp0		# fdiv w/ dbl src
1037462306a36Sopenharmony_ci	rts
1037562306a36Sopenharmony_ci
1037662306a36Sopenharmony_ci	global		_fdivx_
1037762306a36Sopenharmony_ci_fdivx_:
1037862306a36Sopenharmony_ci	fmovm.x		0x4(%sp),&0x80		# load ext dst
1037962306a36Sopenharmony_ci	fdiv.x		0x10(%sp),%fp0		# fdiv w/ ext src
1038062306a36Sopenharmony_ci	rts
1038162306a36Sopenharmony_ci
1038262306a36Sopenharmony_ci	global		_fabss_
1038362306a36Sopenharmony_ci_fabss_:
1038462306a36Sopenharmony_ci	fabs.s		0x4(%sp),%fp0		# fabs w/ sgl src
1038562306a36Sopenharmony_ci	rts
1038662306a36Sopenharmony_ci
1038762306a36Sopenharmony_ci	global		_fabsd_
1038862306a36Sopenharmony_ci_fabsd_:
1038962306a36Sopenharmony_ci	fabs.d		0x4(%sp),%fp0		# fabs w/ dbl src
1039062306a36Sopenharmony_ci	rts
1039162306a36Sopenharmony_ci
1039262306a36Sopenharmony_ci	global		_fabsx_
1039362306a36Sopenharmony_ci_fabsx_:
1039462306a36Sopenharmony_ci	fabs.x		0x4(%sp),%fp0		# fabs w/ ext src
1039562306a36Sopenharmony_ci	rts
1039662306a36Sopenharmony_ci
1039762306a36Sopenharmony_ci	global		_fnegs_
1039862306a36Sopenharmony_ci_fnegs_:
1039962306a36Sopenharmony_ci	fneg.s		0x4(%sp),%fp0		# fneg w/ sgl src
1040062306a36Sopenharmony_ci	rts
1040162306a36Sopenharmony_ci
1040262306a36Sopenharmony_ci	global		_fnegd_
1040362306a36Sopenharmony_ci_fnegd_:
1040462306a36Sopenharmony_ci	fneg.d		0x4(%sp),%fp0		# fneg w/ dbl src
1040562306a36Sopenharmony_ci	rts
1040662306a36Sopenharmony_ci
1040762306a36Sopenharmony_ci	global		_fnegx_
1040862306a36Sopenharmony_ci_fnegx_:
1040962306a36Sopenharmony_ci	fneg.x		0x4(%sp),%fp0		# fneg w/ ext src
1041062306a36Sopenharmony_ci	rts
1041162306a36Sopenharmony_ci
1041262306a36Sopenharmony_ci	global		_fsqrts_
1041362306a36Sopenharmony_ci_fsqrts_:
1041462306a36Sopenharmony_ci	fsqrt.s		0x4(%sp),%fp0		# fsqrt w/ sgl src
1041562306a36Sopenharmony_ci	rts
1041662306a36Sopenharmony_ci
1041762306a36Sopenharmony_ci	global		_fsqrtd_
1041862306a36Sopenharmony_ci_fsqrtd_:
1041962306a36Sopenharmony_ci	fsqrt.d		0x4(%sp),%fp0		# fsqrt w/ dbl src
1042062306a36Sopenharmony_ci	rts
1042162306a36Sopenharmony_ci
1042262306a36Sopenharmony_ci	global		_fsqrtx_
1042362306a36Sopenharmony_ci_fsqrtx_:
1042462306a36Sopenharmony_ci	fsqrt.x		0x4(%sp),%fp0		# fsqrt w/ ext src
1042562306a36Sopenharmony_ci	rts
1042662306a36Sopenharmony_ci
1042762306a36Sopenharmony_ci	global		_fints_
1042862306a36Sopenharmony_ci_fints_:
1042962306a36Sopenharmony_ci	fint.s		0x4(%sp),%fp0		# fint w/ sgl src
1043062306a36Sopenharmony_ci	rts
1043162306a36Sopenharmony_ci
1043262306a36Sopenharmony_ci	global		_fintd_
1043362306a36Sopenharmony_ci_fintd_:
1043462306a36Sopenharmony_ci	fint.d		0x4(%sp),%fp0		# fint w/ dbl src
1043562306a36Sopenharmony_ci	rts
1043662306a36Sopenharmony_ci
1043762306a36Sopenharmony_ci	global		_fintx_
1043862306a36Sopenharmony_ci_fintx_:
1043962306a36Sopenharmony_ci	fint.x		0x4(%sp),%fp0		# fint w/ ext src
1044062306a36Sopenharmony_ci	rts
1044162306a36Sopenharmony_ci
1044262306a36Sopenharmony_ci	global		_fintrzs_
1044362306a36Sopenharmony_ci_fintrzs_:
1044462306a36Sopenharmony_ci	fintrz.s	0x4(%sp),%fp0		# fintrz w/ sgl src
1044562306a36Sopenharmony_ci	rts
1044662306a36Sopenharmony_ci
1044762306a36Sopenharmony_ci	global		_fintrzd_
1044862306a36Sopenharmony_ci_fintrzd_:
1044962306a36Sopenharmony_ci	fintrz.d	0x4(%sp),%fp0		# fintrx w/ dbl src
1045062306a36Sopenharmony_ci	rts
1045162306a36Sopenharmony_ci
1045262306a36Sopenharmony_ci	global		_fintrzx_
1045362306a36Sopenharmony_ci_fintrzx_:
1045462306a36Sopenharmony_ci	fintrz.x	0x4(%sp),%fp0		# fintrz w/ ext src
1045562306a36Sopenharmony_ci	rts
1045662306a36Sopenharmony_ci
1045762306a36Sopenharmony_ci########################################################################
1045862306a36Sopenharmony_ci
1045962306a36Sopenharmony_ci#########################################################################
1046062306a36Sopenharmony_ci# src_zero(): Return signed zero according to sign of src operand.	#
1046162306a36Sopenharmony_ci#########################################################################
1046262306a36Sopenharmony_ci	global		src_zero
1046362306a36Sopenharmony_cisrc_zero:
1046462306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# get sign of src operand
1046562306a36Sopenharmony_ci	bmi.b		ld_mzero		# if neg, load neg zero
1046662306a36Sopenharmony_ci
1046762306a36Sopenharmony_ci#
1046862306a36Sopenharmony_ci# ld_pzero(): return a positive zero.
1046962306a36Sopenharmony_ci#
1047062306a36Sopenharmony_ci	global		ld_pzero
1047162306a36Sopenharmony_cild_pzero:
1047262306a36Sopenharmony_ci	fmov.s		&0x00000000,%fp0	# load +0
1047362306a36Sopenharmony_ci	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
1047462306a36Sopenharmony_ci	rts
1047562306a36Sopenharmony_ci
1047662306a36Sopenharmony_ci# ld_mzero(): return a negative zero.
1047762306a36Sopenharmony_ci	global		ld_mzero
1047862306a36Sopenharmony_cild_mzero:
1047962306a36Sopenharmony_ci	fmov.s		&0x80000000,%fp0	# load -0
1048062306a36Sopenharmony_ci	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
1048162306a36Sopenharmony_ci	rts
1048262306a36Sopenharmony_ci
1048362306a36Sopenharmony_ci#########################################################################
1048462306a36Sopenharmony_ci# dst_zero(): Return signed zero according to sign of dst operand.	#
1048562306a36Sopenharmony_ci#########################################################################
1048662306a36Sopenharmony_ci	global		dst_zero
1048762306a36Sopenharmony_cidst_zero:
1048862306a36Sopenharmony_ci	tst.b		DST_EX(%a1)		# get sign of dst operand
1048962306a36Sopenharmony_ci	bmi.b		ld_mzero		# if neg, load neg zero
1049062306a36Sopenharmony_ci	bra.b		ld_pzero		# load positive zero
1049162306a36Sopenharmony_ci
1049262306a36Sopenharmony_ci#########################################################################
1049362306a36Sopenharmony_ci# src_inf(): Return signed inf according to sign of src operand.	#
1049462306a36Sopenharmony_ci#########################################################################
1049562306a36Sopenharmony_ci	global		src_inf
1049662306a36Sopenharmony_cisrc_inf:
1049762306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# get sign of src operand
1049862306a36Sopenharmony_ci	bmi.b		ld_minf			# if negative branch
1049962306a36Sopenharmony_ci
1050062306a36Sopenharmony_ci#
1050162306a36Sopenharmony_ci# ld_pinf(): return a positive infinity.
1050262306a36Sopenharmony_ci#
1050362306a36Sopenharmony_ci	global		ld_pinf
1050462306a36Sopenharmony_cild_pinf:
1050562306a36Sopenharmony_ci	fmov.s		&0x7f800000,%fp0	# load +INF
1050662306a36Sopenharmony_ci	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
1050762306a36Sopenharmony_ci	rts
1050862306a36Sopenharmony_ci
1050962306a36Sopenharmony_ci#
1051062306a36Sopenharmony_ci# ld_minf():return a negative infinity.
1051162306a36Sopenharmony_ci#
1051262306a36Sopenharmony_ci	global		ld_minf
1051362306a36Sopenharmony_cild_minf:
1051462306a36Sopenharmony_ci	fmov.s		&0xff800000,%fp0	# load -INF
1051562306a36Sopenharmony_ci	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
1051662306a36Sopenharmony_ci	rts
1051762306a36Sopenharmony_ci
1051862306a36Sopenharmony_ci#########################################################################
1051962306a36Sopenharmony_ci# dst_inf(): Return signed inf according to sign of dst operand.	#
1052062306a36Sopenharmony_ci#########################################################################
1052162306a36Sopenharmony_ci	global		dst_inf
1052262306a36Sopenharmony_cidst_inf:
1052362306a36Sopenharmony_ci	tst.b		DST_EX(%a1)		# get sign of dst operand
1052462306a36Sopenharmony_ci	bmi.b		ld_minf			# if negative branch
1052562306a36Sopenharmony_ci	bra.b		ld_pinf
1052662306a36Sopenharmony_ci
1052762306a36Sopenharmony_ci	global		szr_inf
1052862306a36Sopenharmony_ci#################################################################
1052962306a36Sopenharmony_ci# szr_inf(): Return +ZERO for a negative src operand or		#
1053062306a36Sopenharmony_ci#	            +INF for a positive src operand.		#
1053162306a36Sopenharmony_ci#	     Routine used for fetox, ftwotox, and ftentox.	#
1053262306a36Sopenharmony_ci#################################################################
1053362306a36Sopenharmony_ciszr_inf:
1053462306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# check sign of source
1053562306a36Sopenharmony_ci	bmi.b		ld_pzero
1053662306a36Sopenharmony_ci	bra.b		ld_pinf
1053762306a36Sopenharmony_ci
1053862306a36Sopenharmony_ci#########################################################################
1053962306a36Sopenharmony_ci# sopr_inf(): Return +INF for a positive src operand or			#
1054062306a36Sopenharmony_ci#	      jump to operand error routine for a negative src operand.	#
1054162306a36Sopenharmony_ci#	      Routine used for flogn, flognp1, flog10, and flog2.	#
1054262306a36Sopenharmony_ci#########################################################################
1054362306a36Sopenharmony_ci	global		sopr_inf
1054462306a36Sopenharmony_cisopr_inf:
1054562306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# check sign of source
1054662306a36Sopenharmony_ci	bmi.w		t_operr
1054762306a36Sopenharmony_ci	bra.b		ld_pinf
1054862306a36Sopenharmony_ci
1054962306a36Sopenharmony_ci#################################################################
1055062306a36Sopenharmony_ci# setoxm1i(): Return minus one for a negative src operand or	#
1055162306a36Sopenharmony_ci#	      positive infinity for a positive src operand.	#
1055262306a36Sopenharmony_ci#	      Routine used for fetoxm1.				#
1055362306a36Sopenharmony_ci#################################################################
1055462306a36Sopenharmony_ci	global		setoxm1i
1055562306a36Sopenharmony_cisetoxm1i:
1055662306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# check sign of source
1055762306a36Sopenharmony_ci	bmi.b		ld_mone
1055862306a36Sopenharmony_ci	bra.b		ld_pinf
1055962306a36Sopenharmony_ci
1056062306a36Sopenharmony_ci#########################################################################
1056162306a36Sopenharmony_ci# src_one(): Return signed one according to sign of src operand.	#
1056262306a36Sopenharmony_ci#########################################################################
1056362306a36Sopenharmony_ci	global		src_one
1056462306a36Sopenharmony_cisrc_one:
1056562306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# check sign of source
1056662306a36Sopenharmony_ci	bmi.b		ld_mone
1056762306a36Sopenharmony_ci
1056862306a36Sopenharmony_ci#
1056962306a36Sopenharmony_ci# ld_pone(): return positive one.
1057062306a36Sopenharmony_ci#
1057162306a36Sopenharmony_ci	global		ld_pone
1057262306a36Sopenharmony_cild_pone:
1057362306a36Sopenharmony_ci	fmov.s		&0x3f800000,%fp0	# load +1
1057462306a36Sopenharmony_ci	clr.b		FPSR_CC(%a6)
1057562306a36Sopenharmony_ci	rts
1057662306a36Sopenharmony_ci
1057762306a36Sopenharmony_ci#
1057862306a36Sopenharmony_ci# ld_mone(): return negative one.
1057962306a36Sopenharmony_ci#
1058062306a36Sopenharmony_ci	global		ld_mone
1058162306a36Sopenharmony_cild_mone:
1058262306a36Sopenharmony_ci	fmov.s		&0xbf800000,%fp0	# load -1
1058362306a36Sopenharmony_ci	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
1058462306a36Sopenharmony_ci	rts
1058562306a36Sopenharmony_ci
1058662306a36Sopenharmony_cippiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
1058762306a36Sopenharmony_cimpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
1058862306a36Sopenharmony_ci
1058962306a36Sopenharmony_ci#################################################################
1059062306a36Sopenharmony_ci# spi_2(): Return signed PI/2 according to sign of src operand.	#
1059162306a36Sopenharmony_ci#################################################################
1059262306a36Sopenharmony_ci	global		spi_2
1059362306a36Sopenharmony_cispi_2:
1059462306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# check sign of source
1059562306a36Sopenharmony_ci	bmi.b		ld_mpi2
1059662306a36Sopenharmony_ci
1059762306a36Sopenharmony_ci#
1059862306a36Sopenharmony_ci# ld_ppi2(): return positive PI/2.
1059962306a36Sopenharmony_ci#
1060062306a36Sopenharmony_ci	global		ld_ppi2
1060162306a36Sopenharmony_cild_ppi2:
1060262306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
1060362306a36Sopenharmony_ci	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
1060462306a36Sopenharmony_ci	bra.w		t_pinx2			# set INEX2
1060562306a36Sopenharmony_ci
1060662306a36Sopenharmony_ci#
1060762306a36Sopenharmony_ci# ld_mpi2(): return negative PI/2.
1060862306a36Sopenharmony_ci#
1060962306a36Sopenharmony_ci	global		ld_mpi2
1061062306a36Sopenharmony_cild_mpi2:
1061162306a36Sopenharmony_ci	fmov.l		%d0,%fpcr
1061262306a36Sopenharmony_ci	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
1061362306a36Sopenharmony_ci	bra.w		t_minx2			# set INEX2
1061462306a36Sopenharmony_ci
1061562306a36Sopenharmony_ci####################################################
1061662306a36Sopenharmony_ci# The following routines give support for fsincos. #
1061762306a36Sopenharmony_ci####################################################
1061862306a36Sopenharmony_ci
1061962306a36Sopenharmony_ci#
1062062306a36Sopenharmony_ci# ssincosz(): When the src operand is ZERO, store a one in the
1062162306a36Sopenharmony_ci#	      cosine register and return a ZERO in fp0 w/ the same sign
1062262306a36Sopenharmony_ci#	      as the src operand.
1062362306a36Sopenharmony_ci#
1062462306a36Sopenharmony_ci	global		ssincosz
1062562306a36Sopenharmony_cissincosz:
1062662306a36Sopenharmony_ci	fmov.s		&0x3f800000,%fp1
1062762306a36Sopenharmony_ci	tst.b		SRC_EX(%a0)		# test sign
1062862306a36Sopenharmony_ci	bpl.b		sincoszp
1062962306a36Sopenharmony_ci	fmov.s		&0x80000000,%fp0	# return sin result in fp0
1063062306a36Sopenharmony_ci	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
1063162306a36Sopenharmony_ci	rts
1063262306a36Sopenharmony_cisincoszp:
1063362306a36Sopenharmony_ci	fmov.s		&0x00000000,%fp0	# return sin result in fp0
1063462306a36Sopenharmony_ci	mov.b		&z_bmask,FPSR_CC(%a6)
1063562306a36Sopenharmony_ci	rts
1063662306a36Sopenharmony_ci
1063762306a36Sopenharmony_ci#
1063862306a36Sopenharmony_ci# ssincosi(): When the src operand is INF, store a QNAN in the cosine
1063962306a36Sopenharmony_ci#	      register and jump to the operand error routine for negative
1064062306a36Sopenharmony_ci#	      src operands.
1064162306a36Sopenharmony_ci#
1064262306a36Sopenharmony_ci	global		ssincosi
1064362306a36Sopenharmony_cissincosi:
1064462306a36Sopenharmony_ci	fmov.x		qnan(%pc),%fp1		# load NAN
1064562306a36Sopenharmony_ci	bra.w		t_operr
1064662306a36Sopenharmony_ci
1064762306a36Sopenharmony_ci#
1064862306a36Sopenharmony_ci# ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
1064962306a36Sopenharmony_ci#		 register and branch to the src QNAN routine.
1065062306a36Sopenharmony_ci#
1065162306a36Sopenharmony_ci	global		ssincosqnan
1065262306a36Sopenharmony_cissincosqnan:
1065362306a36Sopenharmony_ci	fmov.x		LOCAL_EX(%a0),%fp1
1065462306a36Sopenharmony_ci	bra.w		src_qnan
1065562306a36Sopenharmony_ci
1065662306a36Sopenharmony_ci########################################################################
1065762306a36Sopenharmony_ci
1065862306a36Sopenharmony_ci	global		smod_sdnrm
1065962306a36Sopenharmony_ci	global		smod_snorm
1066062306a36Sopenharmony_cismod_sdnrm:
1066162306a36Sopenharmony_cismod_snorm:
1066262306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1066362306a36Sopenharmony_ci	beq.l		smod
1066462306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1066562306a36Sopenharmony_ci	beq.w		smod_zro
1066662306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1066762306a36Sopenharmony_ci	beq.l		t_operr
1066862306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1066962306a36Sopenharmony_ci	beq.l		smod
1067062306a36Sopenharmony_ci	bra.l		dst_qnan
1067162306a36Sopenharmony_ci
1067262306a36Sopenharmony_ci	global		smod_szero
1067362306a36Sopenharmony_cismod_szero:
1067462306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1067562306a36Sopenharmony_ci	beq.l		t_operr
1067662306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1067762306a36Sopenharmony_ci	beq.l		t_operr
1067862306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1067962306a36Sopenharmony_ci	beq.l		t_operr
1068062306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1068162306a36Sopenharmony_ci	beq.l		t_operr
1068262306a36Sopenharmony_ci	bra.l		dst_qnan
1068362306a36Sopenharmony_ci
1068462306a36Sopenharmony_ci	global		smod_sinf
1068562306a36Sopenharmony_cismod_sinf:
1068662306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1068762306a36Sopenharmony_ci	beq.l		smod_fpn
1068862306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1068962306a36Sopenharmony_ci	beq.l		smod_zro
1069062306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1069162306a36Sopenharmony_ci	beq.l		t_operr
1069262306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1069362306a36Sopenharmony_ci	beq.l		smod_fpn
1069462306a36Sopenharmony_ci	bra.l		dst_qnan
1069562306a36Sopenharmony_ci
1069662306a36Sopenharmony_cismod_zro:
1069762306a36Sopenharmony_cisrem_zro:
1069862306a36Sopenharmony_ci	mov.b		SRC_EX(%a0),%d1		# get src sign
1069962306a36Sopenharmony_ci	mov.b		DST_EX(%a1),%d0		# get dst sign
1070062306a36Sopenharmony_ci	eor.b		%d0,%d1			# get qbyte sign
1070162306a36Sopenharmony_ci	andi.b		&0x80,%d1
1070262306a36Sopenharmony_ci	mov.b		%d1,FPSR_QBYTE(%a6)
1070362306a36Sopenharmony_ci	tst.b		%d0
1070462306a36Sopenharmony_ci	bpl.w		ld_pzero
1070562306a36Sopenharmony_ci	bra.w		ld_mzero
1070662306a36Sopenharmony_ci
1070762306a36Sopenharmony_cismod_fpn:
1070862306a36Sopenharmony_cisrem_fpn:
1070962306a36Sopenharmony_ci	clr.b		FPSR_QBYTE(%a6)
1071062306a36Sopenharmony_ci	mov.l		%d0,-(%sp)
1071162306a36Sopenharmony_ci	mov.b		SRC_EX(%a0),%d1		# get src sign
1071262306a36Sopenharmony_ci	mov.b		DST_EX(%a1),%d0		# get dst sign
1071362306a36Sopenharmony_ci	eor.b		%d0,%d1			# get qbyte sign
1071462306a36Sopenharmony_ci	andi.b		&0x80,%d1
1071562306a36Sopenharmony_ci	mov.b		%d1,FPSR_QBYTE(%a6)
1071662306a36Sopenharmony_ci	cmpi.b		DTAG(%a6),&DENORM
1071762306a36Sopenharmony_ci	bne.b		smod_nrm
1071862306a36Sopenharmony_ci	lea		DST(%a1),%a0
1071962306a36Sopenharmony_ci	mov.l		(%sp)+,%d0
1072062306a36Sopenharmony_ci	bra		t_resdnrm
1072162306a36Sopenharmony_cismod_nrm:
1072262306a36Sopenharmony_ci	fmov.l		(%sp)+,%fpcr
1072362306a36Sopenharmony_ci	fmov.x		DST(%a1),%fp0
1072462306a36Sopenharmony_ci	tst.b		DST_EX(%a1)
1072562306a36Sopenharmony_ci	bmi.b		smod_nrm_neg
1072662306a36Sopenharmony_ci	rts
1072762306a36Sopenharmony_ci
1072862306a36Sopenharmony_cismod_nrm_neg:
1072962306a36Sopenharmony_ci	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' code
1073062306a36Sopenharmony_ci	rts
1073162306a36Sopenharmony_ci
1073262306a36Sopenharmony_ci#########################################################################
1073362306a36Sopenharmony_ci	global		srem_snorm
1073462306a36Sopenharmony_ci	global		srem_sdnrm
1073562306a36Sopenharmony_cisrem_sdnrm:
1073662306a36Sopenharmony_cisrem_snorm:
1073762306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1073862306a36Sopenharmony_ci	beq.l		srem
1073962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1074062306a36Sopenharmony_ci	beq.w		srem_zro
1074162306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1074262306a36Sopenharmony_ci	beq.l		t_operr
1074362306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1074462306a36Sopenharmony_ci	beq.l		srem
1074562306a36Sopenharmony_ci	bra.l		dst_qnan
1074662306a36Sopenharmony_ci
1074762306a36Sopenharmony_ci	global		srem_szero
1074862306a36Sopenharmony_cisrem_szero:
1074962306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1075062306a36Sopenharmony_ci	beq.l		t_operr
1075162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1075262306a36Sopenharmony_ci	beq.l		t_operr
1075362306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1075462306a36Sopenharmony_ci	beq.l		t_operr
1075562306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1075662306a36Sopenharmony_ci	beq.l		t_operr
1075762306a36Sopenharmony_ci	bra.l		dst_qnan
1075862306a36Sopenharmony_ci
1075962306a36Sopenharmony_ci	global		srem_sinf
1076062306a36Sopenharmony_cisrem_sinf:
1076162306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1076262306a36Sopenharmony_ci	beq.w		srem_fpn
1076362306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1076462306a36Sopenharmony_ci	beq.w		srem_zro
1076562306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1076662306a36Sopenharmony_ci	beq.l		t_operr
1076762306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1076862306a36Sopenharmony_ci	beq.l		srem_fpn
1076962306a36Sopenharmony_ci	bra.l		dst_qnan
1077062306a36Sopenharmony_ci
1077162306a36Sopenharmony_ci#########################################################################
1077262306a36Sopenharmony_ci
1077362306a36Sopenharmony_ci	global		sscale_snorm
1077462306a36Sopenharmony_ci	global		sscale_sdnrm
1077562306a36Sopenharmony_cisscale_snorm:
1077662306a36Sopenharmony_cisscale_sdnrm:
1077762306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1077862306a36Sopenharmony_ci	beq.l		sscale
1077962306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1078062306a36Sopenharmony_ci	beq.l		dst_zero
1078162306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1078262306a36Sopenharmony_ci	beq.l		dst_inf
1078362306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1078462306a36Sopenharmony_ci	beq.l		sscale
1078562306a36Sopenharmony_ci	bra.l		dst_qnan
1078662306a36Sopenharmony_ci
1078762306a36Sopenharmony_ci	global		sscale_szero
1078862306a36Sopenharmony_cisscale_szero:
1078962306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1079062306a36Sopenharmony_ci	beq.l		sscale
1079162306a36Sopenharmony_ci	cmpi.b		%d1,&ZERO
1079262306a36Sopenharmony_ci	beq.l		dst_zero
1079362306a36Sopenharmony_ci	cmpi.b		%d1,&INF
1079462306a36Sopenharmony_ci	beq.l		dst_inf
1079562306a36Sopenharmony_ci	cmpi.b		%d1,&DENORM
1079662306a36Sopenharmony_ci	beq.l		sscale
1079762306a36Sopenharmony_ci	bra.l		dst_qnan
1079862306a36Sopenharmony_ci
1079962306a36Sopenharmony_ci	global		sscale_sinf
1080062306a36Sopenharmony_cisscale_sinf:
1080162306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1080262306a36Sopenharmony_ci	beq.l		t_operr
1080362306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN
1080462306a36Sopenharmony_ci	beq.l		dst_qnan
1080562306a36Sopenharmony_ci	bra.l		t_operr
1080662306a36Sopenharmony_ci
1080762306a36Sopenharmony_ci########################################################################
1080862306a36Sopenharmony_ci
1080962306a36Sopenharmony_ci	global		sop_sqnan
1081062306a36Sopenharmony_cisop_sqnan:
1081162306a36Sopenharmony_ci	mov.b		DTAG(%a6),%d1
1081262306a36Sopenharmony_ci	cmpi.b		%d1,&QNAN
1081362306a36Sopenharmony_ci	beq.l		dst_qnan
1081462306a36Sopenharmony_ci	bra.l		src_qnan
1081562306a36Sopenharmony_ci
1081662306a36Sopenharmony_ci#########################################################################
1081762306a36Sopenharmony_ci# norm(): normalize the mantissa of an extended precision input. the	#
1081862306a36Sopenharmony_ci#	  input operand should not be normalized already.		#
1081962306a36Sopenharmony_ci#									#
1082062306a36Sopenharmony_ci# XDEF ****************************************************************	#
1082162306a36Sopenharmony_ci#	norm()								#
1082262306a36Sopenharmony_ci#									#
1082362306a36Sopenharmony_ci# XREF **************************************************************** #
1082462306a36Sopenharmony_ci#	none								#
1082562306a36Sopenharmony_ci#									#
1082662306a36Sopenharmony_ci# INPUT *************************************************************** #
1082762306a36Sopenharmony_ci#	a0 = pointer fp extended precision operand to normalize		#
1082862306a36Sopenharmony_ci#									#
1082962306a36Sopenharmony_ci# OUTPUT ************************************************************** #
1083062306a36Sopenharmony_ci#	d0 = number of bit positions the mantissa was shifted		#
1083162306a36Sopenharmony_ci#	a0 = the input operand's mantissa is normalized; the exponent	#
1083262306a36Sopenharmony_ci#	     is unchanged.						#
1083362306a36Sopenharmony_ci#									#
1083462306a36Sopenharmony_ci#########################################################################
1083562306a36Sopenharmony_ci	global		norm
1083662306a36Sopenharmony_cinorm:
1083762306a36Sopenharmony_ci	mov.l		%d2, -(%sp)		# create some temp regs
1083862306a36Sopenharmony_ci	mov.l		%d3, -(%sp)
1083962306a36Sopenharmony_ci
1084062306a36Sopenharmony_ci	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
1084162306a36Sopenharmony_ci	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
1084262306a36Sopenharmony_ci
1084362306a36Sopenharmony_ci	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
1084462306a36Sopenharmony_ci	beq.b		norm_lo			# hi(man) is all zeroes!
1084562306a36Sopenharmony_ci
1084662306a36Sopenharmony_cinorm_hi:
1084762306a36Sopenharmony_ci	lsl.l		%d2, %d0		# left shift hi(man)
1084862306a36Sopenharmony_ci	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
1084962306a36Sopenharmony_ci
1085062306a36Sopenharmony_ci	or.l		%d3, %d0		# create hi(man)
1085162306a36Sopenharmony_ci	lsl.l		%d2, %d1		# create lo(man)
1085262306a36Sopenharmony_ci
1085362306a36Sopenharmony_ci	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
1085462306a36Sopenharmony_ci	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
1085562306a36Sopenharmony_ci
1085662306a36Sopenharmony_ci	mov.l		%d2, %d0		# return shift amount
1085762306a36Sopenharmony_ci
1085862306a36Sopenharmony_ci	mov.l		(%sp)+, %d3		# restore temp regs
1085962306a36Sopenharmony_ci	mov.l		(%sp)+, %d2
1086062306a36Sopenharmony_ci
1086162306a36Sopenharmony_ci	rts
1086262306a36Sopenharmony_ci
1086362306a36Sopenharmony_cinorm_lo:
1086462306a36Sopenharmony_ci	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
1086562306a36Sopenharmony_ci	lsl.l		%d2, %d1		# shift lo(man)
1086662306a36Sopenharmony_ci	add.l		&32, %d2		# add 32 to shft amount
1086762306a36Sopenharmony_ci
1086862306a36Sopenharmony_ci	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
1086962306a36Sopenharmony_ci	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
1087062306a36Sopenharmony_ci
1087162306a36Sopenharmony_ci	mov.l		%d2, %d0		# return shift amount
1087262306a36Sopenharmony_ci
1087362306a36Sopenharmony_ci	mov.l		(%sp)+, %d3		# restore temp regs
1087462306a36Sopenharmony_ci	mov.l		(%sp)+, %d2
1087562306a36Sopenharmony_ci
1087662306a36Sopenharmony_ci	rts
1087762306a36Sopenharmony_ci
1087862306a36Sopenharmony_ci#########################################################################
1087962306a36Sopenharmony_ci# unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
1088062306a36Sopenharmony_ci#		- returns corresponding optype tag			#
1088162306a36Sopenharmony_ci#									#
1088262306a36Sopenharmony_ci# XDEF ****************************************************************	#
1088362306a36Sopenharmony_ci#	unnorm_fix()							#
1088462306a36Sopenharmony_ci#									#
1088562306a36Sopenharmony_ci# XREF **************************************************************** #
1088662306a36Sopenharmony_ci#	norm() - normalize the mantissa					#
1088762306a36Sopenharmony_ci#									#
1088862306a36Sopenharmony_ci# INPUT *************************************************************** #
1088962306a36Sopenharmony_ci#	a0 = pointer to unnormalized extended precision number		#
1089062306a36Sopenharmony_ci#									#
1089162306a36Sopenharmony_ci# OUTPUT ************************************************************** #
1089262306a36Sopenharmony_ci#	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
1089362306a36Sopenharmony_ci#	a0 = input operand has been converted to a norm, denorm, or	#
1089462306a36Sopenharmony_ci#	     zero; both the exponent and mantissa are changed.		#
1089562306a36Sopenharmony_ci#									#
1089662306a36Sopenharmony_ci#########################################################################
1089762306a36Sopenharmony_ci
1089862306a36Sopenharmony_ci	global		unnorm_fix
1089962306a36Sopenharmony_ciunnorm_fix:
1090062306a36Sopenharmony_ci	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
1090162306a36Sopenharmony_ci	bne.b		unnorm_shift		# hi(man) is not all zeroes
1090262306a36Sopenharmony_ci
1090362306a36Sopenharmony_ci#
1090462306a36Sopenharmony_ci# hi(man) is all zeroes so see if any bits in lo(man) are set
1090562306a36Sopenharmony_ci#
1090662306a36Sopenharmony_ciunnorm_chk_lo:
1090762306a36Sopenharmony_ci	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
1090862306a36Sopenharmony_ci	beq.w		unnorm_zero		# yes
1090962306a36Sopenharmony_ci
1091062306a36Sopenharmony_ci	add.w		&32, %d0		# no; fix shift distance
1091162306a36Sopenharmony_ci
1091262306a36Sopenharmony_ci#
1091362306a36Sopenharmony_ci# d0 = # shifts needed for complete normalization
1091462306a36Sopenharmony_ci#
1091562306a36Sopenharmony_ciunnorm_shift:
1091662306a36Sopenharmony_ci	clr.l		%d1			# clear top word
1091762306a36Sopenharmony_ci	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
1091862306a36Sopenharmony_ci	and.w		&0x7fff, %d1		# strip off sgn
1091962306a36Sopenharmony_ci
1092062306a36Sopenharmony_ci	cmp.w		%d0, %d1		# will denorm push exp < 0?
1092162306a36Sopenharmony_ci	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
1092262306a36Sopenharmony_ci
1092362306a36Sopenharmony_ci#
1092462306a36Sopenharmony_ci# exponent would not go < 0. therefore, number stays normalized
1092562306a36Sopenharmony_ci#
1092662306a36Sopenharmony_ci	sub.w		%d0, %d1		# shift exponent value
1092762306a36Sopenharmony_ci	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
1092862306a36Sopenharmony_ci	and.w		&0x8000, %d0		# save old sign
1092962306a36Sopenharmony_ci	or.w		%d0, %d1		# {sgn,new exp}
1093062306a36Sopenharmony_ci	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
1093162306a36Sopenharmony_ci
1093262306a36Sopenharmony_ci	bsr.l		norm			# normalize UNNORM
1093362306a36Sopenharmony_ci
1093462306a36Sopenharmony_ci	mov.b		&NORM, %d0		# return new optype tag
1093562306a36Sopenharmony_ci	rts
1093662306a36Sopenharmony_ci
1093762306a36Sopenharmony_ci#
1093862306a36Sopenharmony_ci# exponent would go < 0, so only denormalize until exp = 0
1093962306a36Sopenharmony_ci#
1094062306a36Sopenharmony_ciunnorm_nrm_zero:
1094162306a36Sopenharmony_ci	cmp.b		%d1, &32		# is exp <= 32?
1094262306a36Sopenharmony_ci	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
1094362306a36Sopenharmony_ci
1094462306a36Sopenharmony_ci	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
1094562306a36Sopenharmony_ci	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
1094662306a36Sopenharmony_ci
1094762306a36Sopenharmony_ci	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
1094862306a36Sopenharmony_ci	lsl.l		%d1, %d0		# extract new lo(man)
1094962306a36Sopenharmony_ci	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
1095062306a36Sopenharmony_ci
1095162306a36Sopenharmony_ci	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
1095262306a36Sopenharmony_ci
1095362306a36Sopenharmony_ci	mov.b		&DENORM, %d0		# return new optype tag
1095462306a36Sopenharmony_ci	rts
1095562306a36Sopenharmony_ci
1095662306a36Sopenharmony_ci#
1095762306a36Sopenharmony_ci# only mantissa bits set are in lo(man)
1095862306a36Sopenharmony_ci#
1095962306a36Sopenharmony_ciunnorm_nrm_zero_lrg:
1096062306a36Sopenharmony_ci	sub.w		&32, %d1		# adjust shft amt by 32
1096162306a36Sopenharmony_ci
1096262306a36Sopenharmony_ci	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
1096362306a36Sopenharmony_ci	lsl.l		%d1, %d0		# left shift lo(man)
1096462306a36Sopenharmony_ci
1096562306a36Sopenharmony_ci	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
1096662306a36Sopenharmony_ci	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
1096762306a36Sopenharmony_ci
1096862306a36Sopenharmony_ci	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
1096962306a36Sopenharmony_ci
1097062306a36Sopenharmony_ci	mov.b		&DENORM, %d0		# return new optype tag
1097162306a36Sopenharmony_ci	rts
1097262306a36Sopenharmony_ci
1097362306a36Sopenharmony_ci#
1097462306a36Sopenharmony_ci# whole mantissa is zero so this UNNORM is actually a zero
1097562306a36Sopenharmony_ci#
1097662306a36Sopenharmony_ciunnorm_zero:
1097762306a36Sopenharmony_ci	and.w		&0x8000, FTEMP_EX(%a0)	# force exponent to zero
1097862306a36Sopenharmony_ci
1097962306a36Sopenharmony_ci	mov.b		&ZERO, %d0		# fix optype tag
1098062306a36Sopenharmony_ci	rts
10981