| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 | MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP | 
 | M68000 Hi-Performance Microprocessor Division | 
 | M68060 Software Package | 
 | Production Release P1.00 -- October 10, 1994 | 
 |  | 
 | M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved. | 
 |  | 
 | THE SOFTWARE is provided on an "AS IS" basis and without warranty. | 
 | To the maximum extent permitted by applicable law, | 
 | MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, | 
 | INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE | 
 | and any warranty against infringement with regard to the SOFTWARE | 
 | (INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials. | 
 |  | 
 | To the maximum extent permitted by applicable law, | 
 | IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER | 
 | (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, | 
 | BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) | 
 | ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. | 
 | Motorola assumes no responsibility for the maintenance and support of the SOFTWARE. | 
 |  | 
 | You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE | 
 | so long as this entire notice is retained without alteration in any modified and/or | 
 | redistributed versions, and that such modified versions are clearly identified as such. | 
 | No licenses are granted by implication, estoppel or otherwise under any patents | 
 | or trademarks of Motorola, Inc. | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 | # | 
 | # lfptop.s: | 
 | #	This file is appended to the top of the 060ILSP package | 
 | # and contains the entry points into the package. The user, in | 
 | # effect, branches to one of the branch table entries located here. | 
 | # | 
 |  | 
 | 	bra.l	_facoss_ | 
 | 	short	0x0000 | 
 | 	bra.l	_facosd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_facosx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fasins_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fasind_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fasinx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fatans_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fatand_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fatanx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fatanhs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fatanhd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fatanhx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fcoss_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fcosd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fcosx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fcoshs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fcoshd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fcoshx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fetoxs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fetoxd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fetoxx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fetoxm1s_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fetoxm1d_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fetoxm1x_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fgetexps_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fgetexpd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fgetexpx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fgetmans_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fgetmand_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fgetmanx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_flog10s_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flog10d_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flog10x_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_flog2s_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flog2d_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flog2x_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_flogns_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flognd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flognx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_flognp1s_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flognp1d_ | 
 | 	short	0x0000 | 
 | 	bra.l	_flognp1x_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fmods_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fmodd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fmodx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_frems_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fremd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fremx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fscales_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fscaled_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fscalex_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fsins_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsind_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsinx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fsincoss_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsincosd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsincosx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fsinhs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsinhd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsinhx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_ftans_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftand_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftanx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_ftanhs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftanhd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftanhx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_ftentoxs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftentoxd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftentoxx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_ftwotoxs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftwotoxd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_ftwotoxx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fabss_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fabsd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fabsx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fadds_ | 
 | 	short	0x0000 | 
 | 	bra.l	_faddd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_faddx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fdivs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fdivd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fdivx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fints_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fintd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fintx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fintrzs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fintrzd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fintrzx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fmuls_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fmuld_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fmulx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fnegs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fnegd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fnegx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fsqrts_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsqrtd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsqrtx_ | 
 | 	short	0x0000 | 
 |  | 
 | 	bra.l	_fsubs_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsubd_ | 
 | 	short	0x0000 | 
 | 	bra.l	_fsubx_ | 
 | 	short	0x0000 | 
 |  | 
 | # leave room for future possible additions | 
 | 	align	0x400 | 
 |  | 
 | # | 
 | # This file contains a set of define statements for constants | 
 | # in order to promote readability within the corecode itself. | 
 | # | 
 |  | 
 | set LOCAL_SIZE,		192			# stack frame size(bytes) | 
 | set LV,			-LOCAL_SIZE		# stack offset | 
 |  | 
 | set EXC_SR,		0x4			# stack status register | 
 | set EXC_PC,		0x6			# stack pc | 
 | set EXC_VOFF,		0xa			# stacked vector offset | 
 | set EXC_EA,		0xc			# stacked <ea> | 
 |  | 
 | set EXC_FP,		0x0			# frame pointer | 
 |  | 
 | set EXC_AREGS,		-68			# offset of all address regs | 
 | set EXC_DREGS,		-100			# offset of all data regs | 
 | set EXC_FPREGS,		-36			# offset of all fp regs | 
 |  | 
 | set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7 | 
 | set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7 | 
 | set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6 | 
 | set EXC_A5,		EXC_AREGS+(5*4) | 
 | set EXC_A4,		EXC_AREGS+(4*4) | 
 | set EXC_A3,		EXC_AREGS+(3*4) | 
 | set EXC_A2,		EXC_AREGS+(2*4) | 
 | set EXC_A1,		EXC_AREGS+(1*4) | 
 | set EXC_A0,		EXC_AREGS+(0*4) | 
 | set EXC_D7,		EXC_DREGS+(7*4) | 
 | set EXC_D6,		EXC_DREGS+(6*4) | 
 | set EXC_D5,		EXC_DREGS+(5*4) | 
 | set EXC_D4,		EXC_DREGS+(4*4) | 
 | set EXC_D3,		EXC_DREGS+(3*4) | 
 | set EXC_D2,		EXC_DREGS+(2*4) | 
 | set EXC_D1,		EXC_DREGS+(1*4) | 
 | set EXC_D0,		EXC_DREGS+(0*4) | 
 |  | 
 | set EXC_FP0,		EXC_FPREGS+(0*12)	# offset of saved fp0 | 
 | set EXC_FP1,		EXC_FPREGS+(1*12)	# offset of saved fp1 | 
 | set EXC_FP2,		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used) | 
 |  | 
 | set FP_SCR1,		LV+80			# fp scratch 1 | 
 | set FP_SCR1_EX,		FP_SCR1+0 | 
 | set FP_SCR1_SGN,	FP_SCR1+2 | 
 | set FP_SCR1_HI,		FP_SCR1+4 | 
 | set FP_SCR1_LO,		FP_SCR1+8 | 
 |  | 
 | set FP_SCR0,		LV+68			# fp scratch 0 | 
 | set FP_SCR0_EX,		FP_SCR0+0 | 
 | set FP_SCR0_SGN,	FP_SCR0+2 | 
 | set FP_SCR0_HI,		FP_SCR0+4 | 
 | set FP_SCR0_LO,		FP_SCR0+8 | 
 |  | 
 | set FP_DST,		LV+56			# fp destination operand | 
 | set FP_DST_EX,		FP_DST+0 | 
 | set FP_DST_SGN,		FP_DST+2 | 
 | set FP_DST_HI,		FP_DST+4 | 
 | set FP_DST_LO,		FP_DST+8 | 
 |  | 
 | set FP_SRC,		LV+44			# fp source operand | 
 | set FP_SRC_EX,		FP_SRC+0 | 
 | set FP_SRC_SGN,		FP_SRC+2 | 
 | set FP_SRC_HI,		FP_SRC+4 | 
 | set FP_SRC_LO,		FP_SRC+8 | 
 |  | 
 | set USER_FPIAR,		LV+40			# FP instr address register | 
 |  | 
 | set USER_FPSR,		LV+36			# FP status register | 
 | set FPSR_CC,		USER_FPSR+0		# FPSR condition codes | 
 | set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte | 
 | set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte | 
 | set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte | 
 |  | 
 | set USER_FPCR,		LV+32			# FP control register | 
 | set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable | 
 | set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control | 
 |  | 
 | set L_SCR3,		LV+28			# integer scratch 3 | 
 | set L_SCR2,		LV+24			# integer scratch 2 | 
 | set L_SCR1,		LV+20			# integer scratch 1 | 
 |  | 
 | set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst) | 
 |  | 
 | set EXC_TEMP2,		LV+24			# temporary space | 
 | set EXC_TEMP,		LV+16			# temporary space | 
 |  | 
 | set DTAG,		LV+15			# destination operand type | 
 | set STAG,		LV+14			# source operand type | 
 |  | 
 | set SPCOND_FLG,		LV+10			# flag: special case (see below) | 
 |  | 
 | set EXC_CC,		LV+8			# saved condition codes | 
 | set EXC_EXTWPTR,	LV+4			# saved current PC (active) | 
 | set EXC_EXTWORD,	LV+2			# saved extension word | 
 | set EXC_CMDREG,		LV+2			# saved extension word | 
 | set EXC_OPWORD,		LV+0			# saved operation word | 
 |  | 
 | ################################ | 
 |  | 
 | # Helpful macros | 
 |  | 
 | set FTEMP,		0			# offsets within an | 
 | set FTEMP_EX,		0			# extended precision | 
 | set FTEMP_SGN,		2			# value saved in memory. | 
 | set FTEMP_HI,		4 | 
 | set FTEMP_LO,		8 | 
 | set FTEMP_GRS,		12 | 
 |  | 
 | set LOCAL,		0			# offsets within an | 
 | set LOCAL_EX,		0			# extended precision | 
 | set LOCAL_SGN,		2			# value saved in memory. | 
 | set LOCAL_HI,		4 | 
 | set LOCAL_LO,		8 | 
 | set LOCAL_GRS,		12 | 
 |  | 
 | set DST,		0			# offsets within an | 
 | set DST_EX,		0			# extended precision | 
 | set DST_HI,		4			# value saved in memory. | 
 | set DST_LO,		8 | 
 |  | 
 | set SRC,		0			# offsets within an | 
 | set SRC_EX,		0			# extended precision | 
 | set SRC_HI,		4			# value saved in memory. | 
 | set SRC_LO,		8 | 
 |  | 
 | set SGL_LO,		0x3f81			# min sgl prec exponent | 
 | set SGL_HI,		0x407e			# max sgl prec exponent | 
 | set DBL_LO,		0x3c01			# min dbl prec exponent | 
 | set DBL_HI,		0x43fe			# max dbl prec exponent | 
 | set EXT_LO,		0x0			# min ext prec exponent | 
 | set EXT_HI,		0x7ffe			# max ext prec exponent | 
 |  | 
 | set EXT_BIAS,		0x3fff			# extended precision bias | 
 | set SGL_BIAS,		0x007f			# single precision bias | 
 | set DBL_BIAS,		0x03ff			# double precision bias | 
 |  | 
 | set NORM,		0x00			# operand type for STAG/DTAG | 
 | set ZERO,		0x01			# operand type for STAG/DTAG | 
 | set INF,		0x02			# operand type for STAG/DTAG | 
 | set QNAN,		0x03			# operand type for STAG/DTAG | 
 | set DENORM,		0x04			# operand type for STAG/DTAG | 
 | set SNAN,		0x05			# operand type for STAG/DTAG | 
 | set UNNORM,		0x06			# operand type for STAG/DTAG | 
 |  | 
 | ################## | 
 | # FPSR/FPCR bits # | 
 | ################## | 
 | set neg_bit,		0x3			# negative result | 
 | set z_bit,		0x2			# zero result | 
 | set inf_bit,		0x1			# infinite result | 
 | set nan_bit,		0x0			# NAN result | 
 |  | 
 | set q_sn_bit,		0x7			# sign bit of quotient byte | 
 |  | 
 | set bsun_bit,		7			# branch on unordered | 
 | set snan_bit,		6			# signalling NAN | 
 | set operr_bit,		5			# operand error | 
 | set ovfl_bit,		4			# overflow | 
 | set unfl_bit,		3			# underflow | 
 | set dz_bit,		2			# divide by zero | 
 | set inex2_bit,		1			# inexact result 2 | 
 | set inex1_bit,		0			# inexact result 1 | 
 |  | 
 | set aiop_bit,		7			# accrued inexact operation bit | 
 | set aovfl_bit,		6			# accrued overflow bit | 
 | set aunfl_bit,		5			# accrued underflow bit | 
 | set adz_bit,		4			# accrued dz bit | 
 | set ainex_bit,		3			# accrued inexact bit | 
 |  | 
 | ############################# | 
 | # FPSR individual bit masks # | 
 | ############################# | 
 | set neg_mask,		0x08000000		# negative bit mask (lw) | 
 | set inf_mask,		0x02000000		# infinity bit mask (lw) | 
 | set z_mask,		0x04000000		# zero bit mask (lw) | 
 | set nan_mask,		0x01000000		# nan bit mask (lw) | 
 |  | 
 | set neg_bmask,		0x08			# negative bit mask (byte) | 
 | set inf_bmask,		0x02			# infinity bit mask (byte) | 
 | set z_bmask,		0x04			# zero bit mask (byte) | 
 | set nan_bmask,		0x01			# nan bit mask (byte) | 
 |  | 
 | set bsun_mask,		0x00008000		# bsun exception mask | 
 | set snan_mask,		0x00004000		# snan exception mask | 
 | set operr_mask,		0x00002000		# operr exception mask | 
 | set ovfl_mask,		0x00001000		# overflow exception mask | 
 | set unfl_mask,		0x00000800		# underflow exception mask | 
 | set dz_mask,		0x00000400		# dz exception mask | 
 | set inex2_mask,		0x00000200		# inex2 exception mask | 
 | set inex1_mask,		0x00000100		# inex1 exception mask | 
 |  | 
 | set aiop_mask,		0x00000080		# accrued illegal operation | 
 | set aovfl_mask,		0x00000040		# accrued overflow | 
 | set aunfl_mask,		0x00000020		# accrued underflow | 
 | set adz_mask,		0x00000010		# accrued divide by zero | 
 | set ainex_mask,		0x00000008		# accrued inexact | 
 |  | 
 | ###################################### | 
 | # FPSR combinations used in the FPSP # | 
 | ###################################### | 
 | set dzinf_mask,		inf_mask+dz_mask+adz_mask | 
 | set opnan_mask,		nan_mask+operr_mask+aiop_mask | 
 | set nzi_mask,		0x01ffffff		#clears N, Z, and I | 
 | set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask | 
 | set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask | 
 | set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask | 
 | set inx1a_mask,		inex1_mask+ainex_mask | 
 | set inx2a_mask,		inex2_mask+ainex_mask | 
 | set snaniop_mask,	nan_mask+snan_mask+aiop_mask | 
 | set snaniop2_mask,	snan_mask+aiop_mask | 
 | set naniop_mask,	nan_mask+aiop_mask | 
 | set neginf_mask,	neg_mask+inf_mask | 
 | set infaiop_mask,	inf_mask+aiop_mask | 
 | set negz_mask,		neg_mask+z_mask | 
 | set opaop_mask,		operr_mask+aiop_mask | 
 | set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask | 
 | set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask | 
 |  | 
 | ######### | 
 | # misc. # | 
 | ######### | 
 | set rnd_stky_bit,	29			# stky bit pos in longword | 
 |  | 
 | set sign_bit,		0x7			# sign bit | 
 | set signan_bit,		0x6			# signalling nan bit | 
 |  | 
 | set sgl_thresh,		0x3f81			# minimum sgl exponent | 
 | set dbl_thresh,		0x3c01			# minimum dbl exponent | 
 |  | 
 | set x_mode,		0x0			# extended precision | 
 | set s_mode,		0x4			# single precision | 
 | set d_mode,		0x8			# double precision | 
 |  | 
 | set rn_mode,		0x0			# round-to-nearest | 
 | set rz_mode,		0x1			# round-to-zero | 
 | set rm_mode,		0x2			# round-tp-minus-infinity | 
 | set rp_mode,		0x3			# round-to-plus-infinity | 
 |  | 
 | set mantissalen,	64			# length of mantissa in bits | 
 |  | 
 | set BYTE,		1			# len(byte) == 1 byte | 
 | set WORD,		2			# len(word) == 2 bytes | 
 | set LONG,		4			# len(longword) == 2 bytes | 
 |  | 
 | set BSUN_VEC,		0xc0			# bsun    vector offset | 
 | set INEX_VEC,		0xc4			# inexact vector offset | 
 | set DZ_VEC,		0xc8			# dz      vector offset | 
 | set UNFL_VEC,		0xcc			# unfl    vector offset | 
 | set OPERR_VEC,		0xd0			# operr   vector offset | 
 | set OVFL_VEC,		0xd4			# ovfl    vector offset | 
 | set SNAN_VEC,		0xd8			# snan    vector offset | 
 |  | 
 | ########################### | 
 | # SPecial CONDition FLaGs # | 
 | ########################### | 
 | set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception | 
 | set fbsun_flg,		0x02			# flag bit: bsun exception | 
 | set mia7_flg,		0x04			# flag bit: (a7)+ <ea> | 
 | set mda7_flg,		0x08			# flag bit: -(a7) <ea> | 
 | set fmovm_flg,		0x40			# flag bit: fmovm instruction | 
 | set immed_flg,		0x80			# flag bit: &<data> <ea> | 
 |  | 
 | set ftrapcc_bit,	0x0 | 
 | set fbsun_bit,		0x1 | 
 | set mia7_bit,		0x2 | 
 | set mda7_bit,		0x3 | 
 | set immed_bit,		0x7 | 
 |  | 
 | ################################## | 
 | # TRANSCENDENTAL "LAST-OP" FLAGS # | 
 | ################################## | 
 | set FMUL_OP,		0x0			# fmul instr performed last | 
 | set FDIV_OP,		0x1			# fdiv performed last | 
 | set FADD_OP,		0x2			# fadd performed last | 
 | set FMOV_OP,		0x3			# fmov performed last | 
 |  | 
 | ############# | 
 | # CONSTANTS # | 
 | ############# | 
 | T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD | 
 | T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL | 
 |  | 
 | PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000 | 
 | PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 | 
 |  | 
 | TWOBYPI: | 
 | 	long		0x3FE45F30,0x6DC9C883 | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fsins_ | 
 | _fsins_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L0_2s | 
 | 	bsr.l		ssin			# operand is a NORM | 
 | 	bra.b		_L0_6s | 
 | _L0_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L0_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L0_6s | 
 | _L0_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L0_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L0_6s | 
 | _L0_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L0_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L0_6s | 
 | _L0_5s: | 
 | 	bsr.l		ssind			# operand is a DENORM | 
 | _L0_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fsind_ | 
 | _fsind_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L0_2d | 
 | 	bsr.l		ssin			# operand is a NORM | 
 | 	bra.b		_L0_6d | 
 | _L0_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L0_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L0_6d | 
 | _L0_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L0_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L0_6d | 
 | _L0_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L0_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L0_6d | 
 | _L0_5d: | 
 | 	bsr.l		ssind			# operand is a DENORM | 
 | _L0_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fsinx_ | 
 | _fsinx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L0_2x | 
 | 	bsr.l		ssin			# operand is a NORM | 
 | 	bra.b		_L0_6x | 
 | _L0_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L0_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L0_6x | 
 | _L0_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L0_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L0_6x | 
 | _L0_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L0_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L0_6x | 
 | _L0_5x: | 
 | 	bsr.l		ssind			# operand is a DENORM | 
 | _L0_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fcoss_ | 
 | _fcoss_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L1_2s | 
 | 	bsr.l		scos			# operand is a NORM | 
 | 	bra.b		_L1_6s | 
 | _L1_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L1_3s			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L1_6s | 
 | _L1_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L1_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L1_6s | 
 | _L1_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L1_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L1_6s | 
 | _L1_5s: | 
 | 	bsr.l		scosd			# operand is a DENORM | 
 | _L1_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fcosd_ | 
 | _fcosd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L1_2d | 
 | 	bsr.l		scos			# operand is a NORM | 
 | 	bra.b		_L1_6d | 
 | _L1_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L1_3d			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L1_6d | 
 | _L1_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L1_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L1_6d | 
 | _L1_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L1_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L1_6d | 
 | _L1_5d: | 
 | 	bsr.l		scosd			# operand is a DENORM | 
 | _L1_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fcosx_ | 
 | _fcosx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L1_2x | 
 | 	bsr.l		scos			# operand is a NORM | 
 | 	bra.b		_L1_6x | 
 | _L1_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L1_3x			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L1_6x | 
 | _L1_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L1_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L1_6x | 
 | _L1_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L1_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L1_6x | 
 | _L1_5x: | 
 | 	bsr.l		scosd			# operand is a DENORM | 
 | _L1_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fsinhs_ | 
 | _fsinhs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L2_2s | 
 | 	bsr.l		ssinh			# operand is a NORM | 
 | 	bra.b		_L2_6s | 
 | _L2_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L2_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L2_6s | 
 | _L2_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L2_4s			# no | 
 | 	bsr.l		src_inf			# yes | 
 | 	bra.b		_L2_6s | 
 | _L2_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L2_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L2_6s | 
 | _L2_5s: | 
 | 	bsr.l		ssinhd			# operand is a DENORM | 
 | _L2_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fsinhd_ | 
 | _fsinhd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L2_2d | 
 | 	bsr.l		ssinh			# operand is a NORM | 
 | 	bra.b		_L2_6d | 
 | _L2_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L2_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L2_6d | 
 | _L2_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L2_4d			# no | 
 | 	bsr.l		src_inf			# yes | 
 | 	bra.b		_L2_6d | 
 | _L2_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L2_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L2_6d | 
 | _L2_5d: | 
 | 	bsr.l		ssinhd			# operand is a DENORM | 
 | _L2_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fsinhx_ | 
 | _fsinhx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L2_2x | 
 | 	bsr.l		ssinh			# operand is a NORM | 
 | 	bra.b		_L2_6x | 
 | _L2_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L2_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L2_6x | 
 | _L2_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L2_4x			# no | 
 | 	bsr.l		src_inf			# yes | 
 | 	bra.b		_L2_6x | 
 | _L2_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L2_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L2_6x | 
 | _L2_5x: | 
 | 	bsr.l		ssinhd			# operand is a DENORM | 
 | _L2_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_flognp1s_ | 
 | _flognp1s_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L3_2s | 
 | 	bsr.l		slognp1			# operand is a NORM | 
 | 	bra.b		_L3_6s | 
 | _L3_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L3_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L3_6s | 
 | _L3_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L3_4s			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L3_6s | 
 | _L3_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L3_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L3_6s | 
 | _L3_5s: | 
 | 	bsr.l		slognp1d			# operand is a DENORM | 
 | _L3_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flognp1d_ | 
 | _flognp1d_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L3_2d | 
 | 	bsr.l		slognp1			# operand is a NORM | 
 | 	bra.b		_L3_6d | 
 | _L3_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L3_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L3_6d | 
 | _L3_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L3_4d			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L3_6d | 
 | _L3_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L3_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L3_6d | 
 | _L3_5d: | 
 | 	bsr.l		slognp1d			# operand is a DENORM | 
 | _L3_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flognp1x_ | 
 | _flognp1x_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L3_2x | 
 | 	bsr.l		slognp1			# operand is a NORM | 
 | 	bra.b		_L3_6x | 
 | _L3_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L3_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L3_6x | 
 | _L3_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L3_4x			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L3_6x | 
 | _L3_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L3_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L3_6x | 
 | _L3_5x: | 
 | 	bsr.l		slognp1d			# operand is a DENORM | 
 | _L3_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fetoxm1s_ | 
 | _fetoxm1s_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L4_2s | 
 | 	bsr.l		setoxm1			# operand is a NORM | 
 | 	bra.b		_L4_6s | 
 | _L4_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L4_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L4_6s | 
 | _L4_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L4_4s			# no | 
 | 	bsr.l		setoxm1i			# yes | 
 | 	bra.b		_L4_6s | 
 | _L4_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L4_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L4_6s | 
 | _L4_5s: | 
 | 	bsr.l		setoxm1d			# operand is a DENORM | 
 | _L4_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fetoxm1d_ | 
 | _fetoxm1d_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L4_2d | 
 | 	bsr.l		setoxm1			# operand is a NORM | 
 | 	bra.b		_L4_6d | 
 | _L4_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L4_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L4_6d | 
 | _L4_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L4_4d			# no | 
 | 	bsr.l		setoxm1i			# yes | 
 | 	bra.b		_L4_6d | 
 | _L4_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L4_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L4_6d | 
 | _L4_5d: | 
 | 	bsr.l		setoxm1d			# operand is a DENORM | 
 | _L4_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fetoxm1x_ | 
 | _fetoxm1x_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L4_2x | 
 | 	bsr.l		setoxm1			# operand is a NORM | 
 | 	bra.b		_L4_6x | 
 | _L4_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L4_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L4_6x | 
 | _L4_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L4_4x			# no | 
 | 	bsr.l		setoxm1i			# yes | 
 | 	bra.b		_L4_6x | 
 | _L4_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L4_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L4_6x | 
 | _L4_5x: | 
 | 	bsr.l		setoxm1d			# operand is a DENORM | 
 | _L4_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_ftanhs_ | 
 | _ftanhs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L5_2s | 
 | 	bsr.l		stanh			# operand is a NORM | 
 | 	bra.b		_L5_6s | 
 | _L5_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L5_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L5_6s | 
 | _L5_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L5_4s			# no | 
 | 	bsr.l		src_one			# yes | 
 | 	bra.b		_L5_6s | 
 | _L5_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L5_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L5_6s | 
 | _L5_5s: | 
 | 	bsr.l		stanhd			# operand is a DENORM | 
 | _L5_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftanhd_ | 
 | _ftanhd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L5_2d | 
 | 	bsr.l		stanh			# operand is a NORM | 
 | 	bra.b		_L5_6d | 
 | _L5_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L5_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L5_6d | 
 | _L5_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L5_4d			# no | 
 | 	bsr.l		src_one			# yes | 
 | 	bra.b		_L5_6d | 
 | _L5_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L5_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L5_6d | 
 | _L5_5d: | 
 | 	bsr.l		stanhd			# operand is a DENORM | 
 | _L5_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftanhx_ | 
 | _ftanhx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L5_2x | 
 | 	bsr.l		stanh			# operand is a NORM | 
 | 	bra.b		_L5_6x | 
 | _L5_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L5_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L5_6x | 
 | _L5_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L5_4x			# no | 
 | 	bsr.l		src_one			# yes | 
 | 	bra.b		_L5_6x | 
 | _L5_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L5_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L5_6x | 
 | _L5_5x: | 
 | 	bsr.l		stanhd			# operand is a DENORM | 
 | _L5_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fatans_ | 
 | _fatans_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L6_2s | 
 | 	bsr.l		satan			# operand is a NORM | 
 | 	bra.b		_L6_6s | 
 | _L6_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L6_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L6_6s | 
 | _L6_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L6_4s			# no | 
 | 	bsr.l		spi_2			# yes | 
 | 	bra.b		_L6_6s | 
 | _L6_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L6_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L6_6s | 
 | _L6_5s: | 
 | 	bsr.l		satand			# operand is a DENORM | 
 | _L6_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fatand_ | 
 | _fatand_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L6_2d | 
 | 	bsr.l		satan			# operand is a NORM | 
 | 	bra.b		_L6_6d | 
 | _L6_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L6_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L6_6d | 
 | _L6_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L6_4d			# no | 
 | 	bsr.l		spi_2			# yes | 
 | 	bra.b		_L6_6d | 
 | _L6_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L6_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L6_6d | 
 | _L6_5d: | 
 | 	bsr.l		satand			# operand is a DENORM | 
 | _L6_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fatanx_ | 
 | _fatanx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L6_2x | 
 | 	bsr.l		satan			# operand is a NORM | 
 | 	bra.b		_L6_6x | 
 | _L6_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L6_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L6_6x | 
 | _L6_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L6_4x			# no | 
 | 	bsr.l		spi_2			# yes | 
 | 	bra.b		_L6_6x | 
 | _L6_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L6_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L6_6x | 
 | _L6_5x: | 
 | 	bsr.l		satand			# operand is a DENORM | 
 | _L6_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fasins_ | 
 | _fasins_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L7_2s | 
 | 	bsr.l		sasin			# operand is a NORM | 
 | 	bra.b		_L7_6s | 
 | _L7_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L7_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L7_6s | 
 | _L7_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L7_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L7_6s | 
 | _L7_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L7_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L7_6s | 
 | _L7_5s: | 
 | 	bsr.l		sasind			# operand is a DENORM | 
 | _L7_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fasind_ | 
 | _fasind_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L7_2d | 
 | 	bsr.l		sasin			# operand is a NORM | 
 | 	bra.b		_L7_6d | 
 | _L7_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L7_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L7_6d | 
 | _L7_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L7_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L7_6d | 
 | _L7_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L7_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L7_6d | 
 | _L7_5d: | 
 | 	bsr.l		sasind			# operand is a DENORM | 
 | _L7_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fasinx_ | 
 | _fasinx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L7_2x | 
 | 	bsr.l		sasin			# operand is a NORM | 
 | 	bra.b		_L7_6x | 
 | _L7_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L7_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L7_6x | 
 | _L7_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L7_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L7_6x | 
 | _L7_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L7_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L7_6x | 
 | _L7_5x: | 
 | 	bsr.l		sasind			# operand is a DENORM | 
 | _L7_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fatanhs_ | 
 | _fatanhs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L8_2s | 
 | 	bsr.l		satanh			# operand is a NORM | 
 | 	bra.b		_L8_6s | 
 | _L8_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L8_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L8_6s | 
 | _L8_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L8_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L8_6s | 
 | _L8_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L8_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L8_6s | 
 | _L8_5s: | 
 | 	bsr.l		satanhd			# operand is a DENORM | 
 | _L8_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fatanhd_ | 
 | _fatanhd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L8_2d | 
 | 	bsr.l		satanh			# operand is a NORM | 
 | 	bra.b		_L8_6d | 
 | _L8_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L8_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L8_6d | 
 | _L8_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L8_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L8_6d | 
 | _L8_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L8_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L8_6d | 
 | _L8_5d: | 
 | 	bsr.l		satanhd			# operand is a DENORM | 
 | _L8_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fatanhx_ | 
 | _fatanhx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L8_2x | 
 | 	bsr.l		satanh			# operand is a NORM | 
 | 	bra.b		_L8_6x | 
 | _L8_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L8_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L8_6x | 
 | _L8_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L8_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L8_6x | 
 | _L8_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L8_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L8_6x | 
 | _L8_5x: | 
 | 	bsr.l		satanhd			# operand is a DENORM | 
 | _L8_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_ftans_ | 
 | _ftans_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L9_2s | 
 | 	bsr.l		stan			# operand is a NORM | 
 | 	bra.b		_L9_6s | 
 | _L9_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L9_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L9_6s | 
 | _L9_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L9_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L9_6s | 
 | _L9_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L9_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L9_6s | 
 | _L9_5s: | 
 | 	bsr.l		stand			# operand is a DENORM | 
 | _L9_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftand_ | 
 | _ftand_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L9_2d | 
 | 	bsr.l		stan			# operand is a NORM | 
 | 	bra.b		_L9_6d | 
 | _L9_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L9_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L9_6d | 
 | _L9_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L9_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L9_6d | 
 | _L9_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L9_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L9_6d | 
 | _L9_5d: | 
 | 	bsr.l		stand			# operand is a DENORM | 
 | _L9_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftanx_ | 
 | _ftanx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L9_2x | 
 | 	bsr.l		stan			# operand is a NORM | 
 | 	bra.b		_L9_6x | 
 | _L9_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L9_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L9_6x | 
 | _L9_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L9_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L9_6x | 
 | _L9_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L9_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L9_6x | 
 | _L9_5x: | 
 | 	bsr.l		stand			# operand is a DENORM | 
 | _L9_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fetoxs_ | 
 | _fetoxs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L10_2s | 
 | 	bsr.l		setox			# operand is a NORM | 
 | 	bra.b		_L10_6s | 
 | _L10_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L10_3s			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L10_6s | 
 | _L10_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L10_4s			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L10_6s | 
 | _L10_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L10_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L10_6s | 
 | _L10_5s: | 
 | 	bsr.l		setoxd			# operand is a DENORM | 
 | _L10_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fetoxd_ | 
 | _fetoxd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L10_2d | 
 | 	bsr.l		setox			# operand is a NORM | 
 | 	bra.b		_L10_6d | 
 | _L10_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L10_3d			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L10_6d | 
 | _L10_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L10_4d			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L10_6d | 
 | _L10_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L10_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L10_6d | 
 | _L10_5d: | 
 | 	bsr.l		setoxd			# operand is a DENORM | 
 | _L10_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fetoxx_ | 
 | _fetoxx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L10_2x | 
 | 	bsr.l		setox			# operand is a NORM | 
 | 	bra.b		_L10_6x | 
 | _L10_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L10_3x			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L10_6x | 
 | _L10_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L10_4x			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L10_6x | 
 | _L10_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L10_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L10_6x | 
 | _L10_5x: | 
 | 	bsr.l		setoxd			# operand is a DENORM | 
 | _L10_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_ftwotoxs_ | 
 | _ftwotoxs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L11_2s | 
 | 	bsr.l		stwotox			# operand is a NORM | 
 | 	bra.b		_L11_6s | 
 | _L11_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L11_3s			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L11_6s | 
 | _L11_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L11_4s			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L11_6s | 
 | _L11_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L11_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L11_6s | 
 | _L11_5s: | 
 | 	bsr.l		stwotoxd			# operand is a DENORM | 
 | _L11_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftwotoxd_ | 
 | _ftwotoxd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L11_2d | 
 | 	bsr.l		stwotox			# operand is a NORM | 
 | 	bra.b		_L11_6d | 
 | _L11_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L11_3d			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L11_6d | 
 | _L11_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L11_4d			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L11_6d | 
 | _L11_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L11_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L11_6d | 
 | _L11_5d: | 
 | 	bsr.l		stwotoxd			# operand is a DENORM | 
 | _L11_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftwotoxx_ | 
 | _ftwotoxx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L11_2x | 
 | 	bsr.l		stwotox			# operand is a NORM | 
 | 	bra.b		_L11_6x | 
 | _L11_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L11_3x			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L11_6x | 
 | _L11_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L11_4x			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L11_6x | 
 | _L11_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L11_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L11_6x | 
 | _L11_5x: | 
 | 	bsr.l		stwotoxd			# operand is a DENORM | 
 | _L11_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_ftentoxs_ | 
 | _ftentoxs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L12_2s | 
 | 	bsr.l		stentox			# operand is a NORM | 
 | 	bra.b		_L12_6s | 
 | _L12_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L12_3s			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L12_6s | 
 | _L12_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L12_4s			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L12_6s | 
 | _L12_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L12_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L12_6s | 
 | _L12_5s: | 
 | 	bsr.l		stentoxd			# operand is a DENORM | 
 | _L12_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftentoxd_ | 
 | _ftentoxd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L12_2d | 
 | 	bsr.l		stentox			# operand is a NORM | 
 | 	bra.b		_L12_6d | 
 | _L12_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L12_3d			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L12_6d | 
 | _L12_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L12_4d			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L12_6d | 
 | _L12_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L12_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L12_6d | 
 | _L12_5d: | 
 | 	bsr.l		stentoxd			# operand is a DENORM | 
 | _L12_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_ftentoxx_ | 
 | _ftentoxx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L12_2x | 
 | 	bsr.l		stentox			# operand is a NORM | 
 | 	bra.b		_L12_6x | 
 | _L12_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L12_3x			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L12_6x | 
 | _L12_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L12_4x			# no | 
 | 	bsr.l		szr_inf			# yes | 
 | 	bra.b		_L12_6x | 
 | _L12_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L12_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L12_6x | 
 | _L12_5x: | 
 | 	bsr.l		stentoxd			# operand is a DENORM | 
 | _L12_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_flogns_ | 
 | _flogns_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L13_2s | 
 | 	bsr.l		slogn			# operand is a NORM | 
 | 	bra.b		_L13_6s | 
 | _L13_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L13_3s			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L13_6s | 
 | _L13_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L13_4s			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L13_6s | 
 | _L13_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L13_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L13_6s | 
 | _L13_5s: | 
 | 	bsr.l		slognd			# operand is a DENORM | 
 | _L13_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flognd_ | 
 | _flognd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L13_2d | 
 | 	bsr.l		slogn			# operand is a NORM | 
 | 	bra.b		_L13_6d | 
 | _L13_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L13_3d			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L13_6d | 
 | _L13_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L13_4d			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L13_6d | 
 | _L13_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L13_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L13_6d | 
 | _L13_5d: | 
 | 	bsr.l		slognd			# operand is a DENORM | 
 | _L13_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flognx_ | 
 | _flognx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L13_2x | 
 | 	bsr.l		slogn			# operand is a NORM | 
 | 	bra.b		_L13_6x | 
 | _L13_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L13_3x			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L13_6x | 
 | _L13_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L13_4x			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L13_6x | 
 | _L13_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L13_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L13_6x | 
 | _L13_5x: | 
 | 	bsr.l		slognd			# operand is a DENORM | 
 | _L13_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_flog10s_ | 
 | _flog10s_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L14_2s | 
 | 	bsr.l		slog10			# operand is a NORM | 
 | 	bra.b		_L14_6s | 
 | _L14_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L14_3s			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L14_6s | 
 | _L14_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L14_4s			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L14_6s | 
 | _L14_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L14_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L14_6s | 
 | _L14_5s: | 
 | 	bsr.l		slog10d			# operand is a DENORM | 
 | _L14_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flog10d_ | 
 | _flog10d_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L14_2d | 
 | 	bsr.l		slog10			# operand is a NORM | 
 | 	bra.b		_L14_6d | 
 | _L14_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L14_3d			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L14_6d | 
 | _L14_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L14_4d			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L14_6d | 
 | _L14_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L14_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L14_6d | 
 | _L14_5d: | 
 | 	bsr.l		slog10d			# operand is a DENORM | 
 | _L14_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flog10x_ | 
 | _flog10x_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L14_2x | 
 | 	bsr.l		slog10			# operand is a NORM | 
 | 	bra.b		_L14_6x | 
 | _L14_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L14_3x			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L14_6x | 
 | _L14_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L14_4x			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L14_6x | 
 | _L14_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L14_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L14_6x | 
 | _L14_5x: | 
 | 	bsr.l		slog10d			# operand is a DENORM | 
 | _L14_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_flog2s_ | 
 | _flog2s_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L15_2s | 
 | 	bsr.l		slog2			# operand is a NORM | 
 | 	bra.b		_L15_6s | 
 | _L15_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L15_3s			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L15_6s | 
 | _L15_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L15_4s			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L15_6s | 
 | _L15_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L15_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L15_6s | 
 | _L15_5s: | 
 | 	bsr.l		slog2d			# operand is a DENORM | 
 | _L15_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flog2d_ | 
 | _flog2d_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L15_2d | 
 | 	bsr.l		slog2			# operand is a NORM | 
 | 	bra.b		_L15_6d | 
 | _L15_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L15_3d			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L15_6d | 
 | _L15_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L15_4d			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L15_6d | 
 | _L15_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L15_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L15_6d | 
 | _L15_5d: | 
 | 	bsr.l		slog2d			# operand is a DENORM | 
 | _L15_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_flog2x_ | 
 | _flog2x_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L15_2x | 
 | 	bsr.l		slog2			# operand is a NORM | 
 | 	bra.b		_L15_6x | 
 | _L15_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L15_3x			# no | 
 | 	bsr.l		t_dz2			# yes | 
 | 	bra.b		_L15_6x | 
 | _L15_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L15_4x			# no | 
 | 	bsr.l		sopr_inf			# yes | 
 | 	bra.b		_L15_6x | 
 | _L15_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L15_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L15_6x | 
 | _L15_5x: | 
 | 	bsr.l		slog2d			# operand is a DENORM | 
 | _L15_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fcoshs_ | 
 | _fcoshs_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L16_2s | 
 | 	bsr.l		scosh			# operand is a NORM | 
 | 	bra.b		_L16_6s | 
 | _L16_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L16_3s			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L16_6s | 
 | _L16_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L16_4s			# no | 
 | 	bsr.l		ld_pinf			# yes | 
 | 	bra.b		_L16_6s | 
 | _L16_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L16_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L16_6s | 
 | _L16_5s: | 
 | 	bsr.l		scoshd			# operand is a DENORM | 
 | _L16_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fcoshd_ | 
 | _fcoshd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L16_2d | 
 | 	bsr.l		scosh			# operand is a NORM | 
 | 	bra.b		_L16_6d | 
 | _L16_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L16_3d			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L16_6d | 
 | _L16_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L16_4d			# no | 
 | 	bsr.l		ld_pinf			# yes | 
 | 	bra.b		_L16_6d | 
 | _L16_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L16_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L16_6d | 
 | _L16_5d: | 
 | 	bsr.l		scoshd			# operand is a DENORM | 
 | _L16_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fcoshx_ | 
 | _fcoshx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L16_2x | 
 | 	bsr.l		scosh			# operand is a NORM | 
 | 	bra.b		_L16_6x | 
 | _L16_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L16_3x			# no | 
 | 	bsr.l		ld_pone			# yes | 
 | 	bra.b		_L16_6x | 
 | _L16_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L16_4x			# no | 
 | 	bsr.l		ld_pinf			# yes | 
 | 	bra.b		_L16_6x | 
 | _L16_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L16_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L16_6x | 
 | _L16_5x: | 
 | 	bsr.l		scoshd			# operand is a DENORM | 
 | _L16_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_facoss_ | 
 | _facoss_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L17_2s | 
 | 	bsr.l		sacos			# operand is a NORM | 
 | 	bra.b		_L17_6s | 
 | _L17_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L17_3s			# no | 
 | 	bsr.l		ld_ppi2			# yes | 
 | 	bra.b		_L17_6s | 
 | _L17_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L17_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L17_6s | 
 | _L17_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L17_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L17_6s | 
 | _L17_5s: | 
 | 	bsr.l		sacosd			# operand is a DENORM | 
 | _L17_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_facosd_ | 
 | _facosd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L17_2d | 
 | 	bsr.l		sacos			# operand is a NORM | 
 | 	bra.b		_L17_6d | 
 | _L17_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L17_3d			# no | 
 | 	bsr.l		ld_ppi2			# yes | 
 | 	bra.b		_L17_6d | 
 | _L17_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L17_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L17_6d | 
 | _L17_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L17_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L17_6d | 
 | _L17_5d: | 
 | 	bsr.l		sacosd			# operand is a DENORM | 
 | _L17_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_facosx_ | 
 | _facosx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L17_2x | 
 | 	bsr.l		sacos			# operand is a NORM | 
 | 	bra.b		_L17_6x | 
 | _L17_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L17_3x			# no | 
 | 	bsr.l		ld_ppi2			# yes | 
 | 	bra.b		_L17_6x | 
 | _L17_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L17_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L17_6x | 
 | _L17_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L17_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L17_6x | 
 | _L17_5x: | 
 | 	bsr.l		sacosd			# operand is a DENORM | 
 | _L17_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fgetexps_ | 
 | _fgetexps_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L18_2s | 
 | 	bsr.l		sgetexp			# operand is a NORM | 
 | 	bra.b		_L18_6s | 
 | _L18_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L18_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L18_6s | 
 | _L18_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L18_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L18_6s | 
 | _L18_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L18_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L18_6s | 
 | _L18_5s: | 
 | 	bsr.l		sgetexpd			# operand is a DENORM | 
 | _L18_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fgetexpd_ | 
 | _fgetexpd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L18_2d | 
 | 	bsr.l		sgetexp			# operand is a NORM | 
 | 	bra.b		_L18_6d | 
 | _L18_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L18_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L18_6d | 
 | _L18_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L18_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L18_6d | 
 | _L18_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L18_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L18_6d | 
 | _L18_5d: | 
 | 	bsr.l		sgetexpd			# operand is a DENORM | 
 | _L18_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fgetexpx_ | 
 | _fgetexpx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L18_2x | 
 | 	bsr.l		sgetexp			# operand is a NORM | 
 | 	bra.b		_L18_6x | 
 | _L18_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L18_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L18_6x | 
 | _L18_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L18_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L18_6x | 
 | _L18_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L18_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L18_6x | 
 | _L18_5x: | 
 | 	bsr.l		sgetexpd			# operand is a DENORM | 
 | _L18_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fgetmans_ | 
 | _fgetmans_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L19_2s | 
 | 	bsr.l		sgetman			# operand is a NORM | 
 | 	bra.b		_L19_6s | 
 | _L19_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L19_3s			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L19_6s | 
 | _L19_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L19_4s			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L19_6s | 
 | _L19_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L19_5s			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L19_6s | 
 | _L19_5s: | 
 | 	bsr.l		sgetmand			# operand is a DENORM | 
 | _L19_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fgetmand_ | 
 | _fgetmand_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L19_2d | 
 | 	bsr.l		sgetman			# operand is a NORM | 
 | 	bra.b		_L19_6d | 
 | _L19_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L19_3d			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L19_6d | 
 | _L19_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L19_4d			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L19_6d | 
 | _L19_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L19_5d			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L19_6d | 
 | _L19_5d: | 
 | 	bsr.l		sgetmand			# operand is a DENORM | 
 | _L19_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fgetmanx_ | 
 | _fgetmanx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L19_2x | 
 | 	bsr.l		sgetman			# operand is a NORM | 
 | 	bra.b		_L19_6x | 
 | _L19_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L19_3x			# no | 
 | 	bsr.l		src_zero			# yes | 
 | 	bra.b		_L19_6x | 
 | _L19_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L19_4x			# no | 
 | 	bsr.l		t_operr			# yes | 
 | 	bra.b		_L19_6x | 
 | _L19_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L19_5x			# no | 
 | 	bsr.l		src_qnan			# yes | 
 | 	bra.b		_L19_6x | 
 | _L19_5x: | 
 | 	bsr.l		sgetmand			# operand is a DENORM | 
 | _L19_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # MONADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fsincoss_ | 
 | _fsincoss_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L20_2s | 
 | 	bsr.l		ssincos			# operand is a NORM | 
 | 	bra.b		_L20_6s | 
 | _L20_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L20_3s			# no | 
 | 	bsr.l		ssincosz			# yes | 
 | 	bra.b		_L20_6s | 
 | _L20_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L20_4s			# no | 
 | 	bsr.l		ssincosi			# yes | 
 | 	bra.b		_L20_6s | 
 | _L20_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L20_5s			# no | 
 | 	bsr.l		ssincosqnan			# yes | 
 | 	bra.b		_L20_6s | 
 | _L20_5s: | 
 | 	bsr.l		ssincosd			# operand is a DENORM | 
 | _L20_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1 | 
 | 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1 | 
 | 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fsincosd_ | 
 | _fsincosd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl input | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	mov.b		%d1,STAG(%a6) | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L20_2d | 
 | 	bsr.l		ssincos			# operand is a NORM | 
 | 	bra.b		_L20_6d | 
 | _L20_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L20_3d			# no | 
 | 	bsr.l		ssincosz			# yes | 
 | 	bra.b		_L20_6d | 
 | _L20_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L20_4d			# no | 
 | 	bsr.l		ssincosi			# yes | 
 | 	bra.b		_L20_6d | 
 | _L20_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L20_5d			# no | 
 | 	bsr.l		ssincosqnan			# yes | 
 | 	bra.b		_L20_6d | 
 | _L20_5d: | 
 | 	bsr.l		ssincosd			# operand is a DENORM | 
 | _L20_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1 | 
 | 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1 | 
 | 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fsincosx_ | 
 | _fsincosx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.b		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L20_2x | 
 | 	bsr.l		ssincos			# operand is a NORM | 
 | 	bra.b		_L20_6x | 
 | _L20_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L20_3x			# no | 
 | 	bsr.l		ssincosz			# yes | 
 | 	bra.b		_L20_6x | 
 | _L20_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L20_4x			# no | 
 | 	bsr.l		ssincosi			# yes | 
 | 	bra.b		_L20_6x | 
 | _L20_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L20_5x			# no | 
 | 	bsr.l		ssincosqnan			# yes | 
 | 	bra.b		_L20_6x | 
 | _L20_5x: | 
 | 	bsr.l		ssincosd			# operand is a DENORM | 
 | _L20_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1 | 
 | 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1 | 
 | 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # DYADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_frems_ | 
 | _frems_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl dst | 
 | 	fmov.x		%fp0,FP_DST(%a6) | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	fmov.s		0xc(%a6),%fp0		# load sgl src | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L21_2s | 
 | 	bsr.l		srem_snorm			# operand is a NORM | 
 | 	bra.b		_L21_6s | 
 | _L21_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L21_3s			# no | 
 | 	bsr.l		srem_szero			# yes | 
 | 	bra.b		_L21_6s | 
 | _L21_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L21_4s			# no | 
 | 	bsr.l		srem_sinf			# yes | 
 | 	bra.b		_L21_6s | 
 | _L21_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L21_5s			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L21_6s | 
 | _L21_5s: | 
 | 	bsr.l		srem_sdnrm			# operand is a DENORM | 
 | _L21_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fremd_ | 
 | _fremd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl dst | 
 | 	fmov.x		%fp0,FP_DST(%a6) | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	fmov.d		0x10(%a6),%fp0		# load dbl src | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L21_2d | 
 | 	bsr.l		srem_snorm			# operand is a NORM | 
 | 	bra.b		_L21_6d | 
 | _L21_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L21_3d			# no | 
 | 	bsr.l		srem_szero			# yes | 
 | 	bra.b		_L21_6d | 
 | _L21_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L21_4d			# no | 
 | 	bsr.l		srem_sinf			# yes | 
 | 	bra.b		_L21_6d | 
 | _L21_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L21_5d			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L21_6d | 
 | _L21_5d: | 
 | 	bsr.l		srem_sdnrm			# operand is a DENORM | 
 | _L21_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fremx_ | 
 | _fremx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src | 
 | 	mov.l		0x14+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x14+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L21_2x | 
 | 	bsr.l		srem_snorm			# operand is a NORM | 
 | 	bra.b		_L21_6x | 
 | _L21_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L21_3x			# no | 
 | 	bsr.l		srem_szero			# yes | 
 | 	bra.b		_L21_6x | 
 | _L21_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L21_4x			# no | 
 | 	bsr.l		srem_sinf			# yes | 
 | 	bra.b		_L21_6x | 
 | _L21_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L21_5x			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L21_6x | 
 | _L21_5x: | 
 | 	bsr.l		srem_sdnrm			# operand is a DENORM | 
 | _L21_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # DYADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fmods_ | 
 | _fmods_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl dst | 
 | 	fmov.x		%fp0,FP_DST(%a6) | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	fmov.s		0xc(%a6),%fp0		# load sgl src | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L22_2s | 
 | 	bsr.l		smod_snorm			# operand is a NORM | 
 | 	bra.b		_L22_6s | 
 | _L22_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L22_3s			# no | 
 | 	bsr.l		smod_szero			# yes | 
 | 	bra.b		_L22_6s | 
 | _L22_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L22_4s			# no | 
 | 	bsr.l		smod_sinf			# yes | 
 | 	bra.b		_L22_6s | 
 | _L22_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L22_5s			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L22_6s | 
 | _L22_5s: | 
 | 	bsr.l		smod_sdnrm			# operand is a DENORM | 
 | _L22_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fmodd_ | 
 | _fmodd_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl dst | 
 | 	fmov.x		%fp0,FP_DST(%a6) | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	fmov.d		0x10(%a6),%fp0		# load dbl src | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L22_2d | 
 | 	bsr.l		smod_snorm			# operand is a NORM | 
 | 	bra.b		_L22_6d | 
 | _L22_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L22_3d			# no | 
 | 	bsr.l		smod_szero			# yes | 
 | 	bra.b		_L22_6d | 
 | _L22_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L22_4d			# no | 
 | 	bsr.l		smod_sinf			# yes | 
 | 	bra.b		_L22_6d | 
 | _L22_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L22_5d			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L22_6d | 
 | _L22_5d: | 
 | 	bsr.l		smod_sdnrm			# operand is a DENORM | 
 | _L22_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fmodx_ | 
 | _fmodx_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src | 
 | 	mov.l		0x14+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x14+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L22_2x | 
 | 	bsr.l		smod_snorm			# operand is a NORM | 
 | 	bra.b		_L22_6x | 
 | _L22_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L22_3x			# no | 
 | 	bsr.l		smod_szero			# yes | 
 | 	bra.b		_L22_6x | 
 | _L22_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L22_4x			# no | 
 | 	bsr.l		smod_sinf			# yes | 
 | 	bra.b		_L22_6x | 
 | _L22_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L22_5x			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L22_6x | 
 | _L22_5x: | 
 | 	bsr.l		smod_sdnrm			# operand is a DENORM | 
 | _L22_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # DYADIC TEMPLATE							# | 
 | ######################################################################### | 
 | 	global		_fscales_ | 
 | _fscales_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.s		0x8(%a6),%fp0		# load sgl dst | 
 | 	fmov.x		%fp0,FP_DST(%a6) | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	fmov.s		0xc(%a6),%fp0		# load sgl src | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L23_2s | 
 | 	bsr.l		sscale_snorm			# operand is a NORM | 
 | 	bra.b		_L23_6s | 
 | _L23_2s: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L23_3s			# no | 
 | 	bsr.l		sscale_szero			# yes | 
 | 	bra.b		_L23_6s | 
 | _L23_3s: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L23_4s			# no | 
 | 	bsr.l		sscale_sinf			# yes | 
 | 	bra.b		_L23_6s | 
 | _L23_4s: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L23_5s			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L23_6s | 
 | _L23_5s: | 
 | 	bsr.l		sscale_sdnrm			# operand is a DENORM | 
 | _L23_6s: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fscaled_ | 
 | _fscaled_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	fmov.d		0x8(%a6),%fp0		# load dbl dst | 
 | 	fmov.x		%fp0,FP_DST(%a6) | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	fmov.d		0x10(%a6),%fp0		# load dbl src | 
 | 	fmov.x		%fp0,FP_SRC(%a6) | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L23_2d | 
 | 	bsr.l		sscale_snorm			# operand is a NORM | 
 | 	bra.b		_L23_6d | 
 | _L23_2d: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L23_3d			# no | 
 | 	bsr.l		sscale_szero			# yes | 
 | 	bra.b		_L23_6d | 
 | _L23_3d: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L23_4d			# no | 
 | 	bsr.l		sscale_sinf			# yes | 
 | 	bra.b		_L23_6d | 
 | _L23_4d: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L23_5d			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L23_6d | 
 | _L23_5d: | 
 | 	bsr.l		sscale_sdnrm			# operand is a DENORM | 
 | _L23_6d: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 | 	global		_fscalex_ | 
 | _fscalex_: | 
 | 	link		%a6,&-LOCAL_SIZE | 
 |  | 
 | 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1 | 
 | 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs | 
 | 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1 | 
 |  | 
 | 	fmov.l		&0x0,%fpcr		# zero FPCR | 
 |  | 
 | # | 
 | #	copy, convert, and tag input argument | 
 | # | 
 | 	lea		FP_DST(%a6),%a0 | 
 | 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst | 
 | 	mov.l		0x8+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x8+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,DTAG(%a6) | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0 | 
 | 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src | 
 | 	mov.l		0x14+0x4(%a6),0x4(%a0) | 
 | 	mov.l		0x14+0x8(%a6),0x8(%a0) | 
 | 	bsr.l		tag			# fetch operand type | 
 | 	mov.b		%d0,STAG(%a6) | 
 | 	mov.l		%d0,%d1 | 
 |  | 
 | 	andi.l		&0x00ff00ff,USER_FPSR(%a6) | 
 |  | 
 | 	clr.l		%d0 | 
 | 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec | 
 |  | 
 | 	lea		FP_SRC(%a6),%a0		# pass ptr to src | 
 | 	lea		FP_DST(%a6),%a1		# pass ptr to dst | 
 |  | 
 | 	tst.b		%d1 | 
 | 	bne.b		_L23_2x | 
 | 	bsr.l		sscale_snorm			# operand is a NORM | 
 | 	bra.b		_L23_6x | 
 | _L23_2x: | 
 | 	cmpi.b		%d1,&ZERO		# is operand a ZERO? | 
 | 	bne.b		_L23_3x			# no | 
 | 	bsr.l		sscale_szero			# yes | 
 | 	bra.b		_L23_6x | 
 | _L23_3x: | 
 | 	cmpi.b		%d1,&INF		# is operand an INF? | 
 | 	bne.b		_L23_4x			# no | 
 | 	bsr.l		sscale_sinf			# yes | 
 | 	bra.b		_L23_6x | 
 | _L23_4x: | 
 | 	cmpi.b		%d1,&QNAN		# is operand a QNAN? | 
 | 	bne.b		_L23_5x			# no | 
 | 	bsr.l		sop_sqnan			# yes | 
 | 	bra.b		_L23_6x | 
 | _L23_5x: | 
 | 	bsr.l		sscale_sdnrm			# operand is a DENORM | 
 | _L23_6x: | 
 |  | 
 | # | 
 | #	Result is now in FP0 | 
 | # | 
 | 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1 | 
 | 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs | 
 | 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1 | 
 | 	unlk		%a6 | 
 | 	rts | 
 |  | 
 |  | 
 | ######################################################################### | 
 | # ssin():     computes the sine of a normalized input			# | 
 | # ssind():    computes the sine of a denormalized input			# | 
 | # scos():     computes the cosine of a normalized input			# | 
 | # scosd():    computes the cosine of a denormalized input		# | 
 | # ssincos():  computes the sine and cosine of a normalized input	# | 
 | # ssincosd(): computes the sine and cosine of a denormalized input	# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = sin(X) or cos(X)						# | 
 | #									# | 
 | #    For ssincos(X):							# | 
 | #	fp0 = sin(X)							# | 
 | #	fp1 = cos(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY ******************************************* # | 
 | #	The returned result is within 1 ulp in 64 significant bit, i.e.	# | 
 | #	within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #	SIN and COS:							# | 
 | #	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	# | 
 | #									# | 
 | #	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			# | 
 | #									# | 
 | #	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	# | 
 | #		k = N mod 4, so in particular, k = 0,1,2,or 3.		# | 
 | #		Overwrite k by k := k + AdjN.				# | 
 | #									# | 
 | #	4. If k is even, go to 6.					# | 
 | #									# | 
 | #	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j.			# | 
 | #		Return sgn*cos(r) where cos(r) is approximated by an	# | 
 | #		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	# | 
 | #		s = r*r.						# | 
 | #		Exit.							# | 
 | #									# | 
 | #	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	# | 
 | #		where sin(r) is approximated by an odd polynomial in r	# | 
 | #		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	# | 
 | #		Exit.							# | 
 | #									# | 
 | #	7. If |X| > 1, go to 9.						# | 
 | #									# | 
 | #	8. (|X|<2**(-40)) If SIN is invoked, return X;			# | 
 | #		otherwise return 1.					# | 
 | #									# | 
 | #	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		# | 
 | #		go back to 3.						# | 
 | #									# | 
 | #	SINCOS:								# | 
 | #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			# | 
 | #									# | 
 | #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	# | 
 | #		k = N mod 4, so in particular, k = 0,1,2,or 3.		# | 
 | #									# | 
 | #	3. If k is even, go to 5.					# | 
 | #									# | 
 | #	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	# | 
 | #		j1 exclusive or with the l.s.b. of k.			# | 
 | #		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			# | 
 | #		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	# | 
 | #		sin(r) and cos(r) are computed as odd and even		# | 
 | #		polynomials in r, respectively. Exit			# | 
 | #									# | 
 | #	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			# | 
 | #		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	# | 
 | #		sin(r) and cos(r) are computed as odd and even		# | 
 | #		polynomials in r, respectively. Exit			# | 
 | #									# | 
 | #	6. If |X| > 1, go to 8.						# | 
 | #									# | 
 | #	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		# | 
 | #									# | 
 | #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		# | 
 | #		go back to 2.						# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | SINA7:	long		0xBD6AAA77,0xCCC994F5 | 
 | SINA6:	long		0x3DE61209,0x7AAE8DA1 | 
 | SINA5:	long		0xBE5AE645,0x2A118AE4 | 
 | SINA4:	long		0x3EC71DE3,0xA5341531 | 
 | SINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000 | 
 | SINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000 | 
 | SINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000 | 
 |  | 
 | COSB8:	long		0x3D2AC4D0,0xD6011EE3 | 
 | COSB7:	long		0xBDA9396F,0x9F45AC19 | 
 | COSB6:	long		0x3E21EED9,0x0612C972 | 
 | COSB5:	long		0xBE927E4F,0xB79D9FCF | 
 | COSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000 | 
 | COSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000 | 
 | COSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E | 
 | COSB1:	long		0xBF000000 | 
 |  | 
 | 	set		INARG,FP_SCR0 | 
 |  | 
 | 	set		X,FP_SCR0 | 
 | #	set		XDCARE,X+2 | 
 | 	set		XFRAC,X+4 | 
 |  | 
 | 	set		RPRIME,FP_SCR0 | 
 | 	set		SPRIME,FP_SCR1 | 
 |  | 
 | 	set		POSNEG1,L_SCR1 | 
 | 	set		TWOTO63,L_SCR1 | 
 |  | 
 | 	set		ENDFLAG,L_SCR2 | 
 | 	set		INT,L_SCR2 | 
 |  | 
 | 	set		ADJN,L_SCR3 | 
 |  | 
 | ############################################ | 
 | 	global		ssin | 
 | ssin: | 
 | 	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0 | 
 | 	bra.b		SINBGN | 
 |  | 
 | ############################################ | 
 | 	global		scos | 
 | scos: | 
 | 	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1 | 
 |  | 
 | ############################################ | 
 | SINBGN: | 
 | #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE | 
 |  | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 | 	fmov.x		%fp0,X(%a6)		# save input at X | 
 |  | 
 | # "COMPACTIFY" X | 
 | 	mov.l		(%a0),%d1		# put exp in hi word | 
 | 	mov.w		4(%a0),%d1		# fetch hi(man) | 
 | 	and.l		&0x7FFFFFFF,%d1		# strip sign | 
 |  | 
 | 	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)? | 
 | 	bge.b		SOK1			# no | 
 | 	bra.w		SINSM			# yes; input is very small | 
 |  | 
 | SOK1: | 
 | 	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI? | 
 | 	blt.b		SINMAIN			# no | 
 | 	bra.w		SREDUCEX		# yes; input is very large | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| <= 15 PI. | 
 | #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. | 
 | SINMAIN: | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI | 
 |  | 
 | 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32 | 
 |  | 
 | 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER | 
 |  | 
 | 	mov.l		INT(%a6),%d1		# make a copy of N | 
 | 	asl.l		&4,%d1			# N *= 16 | 
 | 	add.l		%d1,%a1			# tbl_addr = a1 + (N*16) | 
 |  | 
 | # A1 IS THE ADDRESS OF N*PIBY2 | 
 | # ...WHICH IS IN TWO PIECES Y1 & Y2 | 
 | 	fsub.x		(%a1)+,%fp0		# X-Y1 | 
 | 	fsub.s		(%a1),%fp0		# fp0 = R = (X-Y1)-Y2 | 
 |  | 
 | SINCONT: | 
 | #--continuation from REDUCEX | 
 |  | 
 | #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED | 
 | 	mov.l		INT(%a6),%d1 | 
 | 	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN | 
 | 	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE | 
 | 	cmp.l		%d1,&0 | 
 | 	blt.w		COSPOLY | 
 |  | 
 | #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. | 
 | #--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY | 
 | #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE | 
 | #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS | 
 | #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))]) | 
 | #--WHERE T=S*S. | 
 | #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION | 
 | #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT. | 
 | SINPOLY: | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3 | 
 |  | 
 | 	fmov.x		%fp0,X(%a6)		# X IS R | 
 | 	fmul.x		%fp0,%fp0		# FP0 IS S | 
 |  | 
 | 	fmov.d		SINA7(%pc),%fp3 | 
 | 	fmov.d		SINA6(%pc),%fp2 | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# FP1 IS T | 
 |  | 
 | 	ror.l		&1,%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | # ...LEAST SIG. BIT OF D0 IN SIGN POSITION | 
 | 	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# TA7 | 
 | 	fmul.x		%fp1,%fp2		# TA6 | 
 |  | 
 | 	fadd.d		SINA5(%pc),%fp3		# A5+TA7 | 
 | 	fadd.d		SINA4(%pc),%fp2		# A4+TA6 | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# T(A5+TA7) | 
 | 	fmul.x		%fp1,%fp2		# T(A4+TA6) | 
 |  | 
 | 	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7) | 
 | 	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6) | 
 |  | 
 | 	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7)) | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6)) | 
 | 	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7)) | 
 | 	fmul.x		X(%a6),%fp0		# R'*S | 
 |  | 
 | 	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))] | 
 |  | 
 | 	fmul.x		%fp1,%fp0		# SIN(R')-R' | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	fadd.x		X(%a6),%fp0		# last inst - possible exception set | 
 | 	bra		t_inx2 | 
 |  | 
 | #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. | 
 | #--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY | 
 | #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE | 
 | #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS | 
 | #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))]) | 
 | #--WHERE T=S*S. | 
 | #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION | 
 | #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2 | 
 | #--AND IS THEREFORE STORED AS SINGLE PRECISION. | 
 | COSPOLY: | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3 | 
 |  | 
 | 	fmul.x		%fp0,%fp0		# FP0 IS S | 
 |  | 
 | 	fmov.d		COSB8(%pc),%fp2 | 
 | 	fmov.d		COSB7(%pc),%fp3 | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# FP1 IS T | 
 |  | 
 | 	fmov.x		%fp0,X(%a6)		# X IS S | 
 | 	ror.l		&1,%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | # ...LEAST SIG. BIT OF D0 IN SIGN POSITION | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# TB8 | 
 |  | 
 | 	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S | 
 | 	and.l		&0x80000000,%d1 | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# TB7 | 
 |  | 
 | 	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE | 
 | 	mov.l		%d1,POSNEG1(%a6) | 
 |  | 
 | 	fadd.d		COSB6(%pc),%fp2		# B6+TB8 | 
 | 	fadd.d		COSB5(%pc),%fp3		# B5+TB7 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# T(B6+TB8) | 
 | 	fmul.x		%fp1,%fp3		# T(B5+TB7) | 
 |  | 
 | 	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8) | 
 | 	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7) | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8)) | 
 | 	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7)) | 
 |  | 
 | 	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8)) | 
 | 	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7)) | 
 |  | 
 | 	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8))) | 
 |  | 
 | 	fadd.x		%fp1,%fp0 | 
 |  | 
 | 	fmul.x		X(%a6),%fp0 | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set | 
 | 	bra		t_inx2 | 
 |  | 
 | ############################################## | 
 |  | 
 | # SINe: Big OR Small? | 
 | #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. | 
 | #--IF |X| < 2**(-40), RETURN X OR 1. | 
 | SINBORS: | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bgt.l		SREDUCEX | 
 |  | 
 | SINSM: | 
 | 	mov.l		ADJN(%a6),%d1 | 
 | 	cmp.l		%d1,&0 | 
 | 	bgt.b		COSTINY | 
 |  | 
 | # here, the operation may underflow iff the precision is sgl or dbl. | 
 | # extended denorms are handled through another entry point. | 
 | SINTINY: | 
 | #	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		X(%a6),%fp0		# last inst - possible exception set | 
 | 	bra		t_catch | 
 |  | 
 | COSTINY: | 
 | 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0 | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	fadd.s		&0x80800000,%fp0	# last inst - possible exception set | 
 | 	bra		t_pinx2 | 
 |  | 
 | ################################################ | 
 | 	global		ssind | 
 | #--SIN(X) = X FOR DENORMALIZED X | 
 | ssind: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ############################################ | 
 | 	global		scosd | 
 | #--COS(X) = 1 FOR DENORMALIZED X | 
 | scosd: | 
 | 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | ################################################## | 
 |  | 
 | 	global		ssincos | 
 | ssincos: | 
 | #--SET ADJN TO 4 | 
 | 	mov.l		&4,ADJN(%a6) | 
 |  | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 | 	fmov.x		%fp0,X(%a6) | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X | 
 |  | 
 | 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)? | 
 | 	bge.b		SCOK1 | 
 | 	bra.w		SCSM | 
 |  | 
 | SCOK1: | 
 | 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI? | 
 | 	blt.b		SCMAIN | 
 | 	bra.w		SREDUCEX | 
 |  | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| <= 15 PI. | 
 | #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. | 
 | SCMAIN: | 
 | 	fmov.x		%fp0,%fp1 | 
 |  | 
 | 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI | 
 |  | 
 | 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32 | 
 |  | 
 | 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER | 
 |  | 
 | 	mov.l		INT(%a6),%d1 | 
 | 	asl.l		&4,%d1 | 
 | 	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2 | 
 |  | 
 | 	fsub.x		(%a1)+,%fp0		# X-Y1 | 
 | 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2 | 
 |  | 
 | SCCONT: | 
 | #--continuation point from REDUCEX | 
 |  | 
 | 	mov.l		INT(%a6),%d1 | 
 | 	ror.l		&1,%d1 | 
 | 	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD | 
 | 	bge.w		NEVEN | 
 |  | 
 | SNODD: | 
 | #--REGISTERS SAVED SO FAR: D0, A0, FP2. | 
 | 	fmovm.x		&0x04,-(%sp)		# save fp2 | 
 |  | 
 | 	fmov.x		%fp0,RPRIME(%a6) | 
 | 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R | 
 | 	fmov.d		SINA7(%pc),%fp1		# A7 | 
 | 	fmov.d		COSB8(%pc),%fp2		# B8 | 
 | 	fmul.x		%fp0,%fp1		# SA7 | 
 | 	fmul.x		%fp0,%fp2		# SB8 | 
 |  | 
 | 	mov.l		%d2,-(%sp) | 
 | 	mov.l		%d1,%d2 | 
 | 	ror.l		&1,%d2 | 
 | 	and.l		&0x80000000,%d2 | 
 | 	eor.l		%d1,%d2 | 
 | 	and.l		&0x80000000,%d2 | 
 |  | 
 | 	fadd.d		SINA6(%pc),%fp1		# A6+SA7 | 
 | 	fadd.d		COSB7(%pc),%fp2		# B7+SB8 | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(A6+SA7) | 
 | 	eor.l		%d2,RPRIME(%a6) | 
 | 	mov.l		(%sp)+,%d2 | 
 | 	fmul.x		%fp0,%fp2		# S(B7+SB8) | 
 | 	ror.l		&1,%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | 	mov.l		&0x3F800000,POSNEG1(%a6) | 
 | 	eor.l		%d1,POSNEG1(%a6) | 
 |  | 
 | 	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7) | 
 | 	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7)) | 
 | 	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8)) | 
 | 	fmov.x		%fp0,SPRIME(%a6) | 
 |  | 
 | 	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7)) | 
 | 	eor.l		%d1,SPRIME(%a6) | 
 | 	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8)) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(A4+...) | 
 | 	fmul.x		%fp0,%fp2		# S(B5+...) | 
 |  | 
 | 	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...) | 
 | 	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(A3+...) | 
 | 	fmul.x		%fp0,%fp2		# S(B4+...) | 
 |  | 
 | 	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...) | 
 | 	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(A2+...) | 
 | 	fmul.x		%fp0,%fp2		# S(B3+...) | 
 |  | 
 | 	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...) | 
 | 	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(A1+...) | 
 | 	fmul.x		%fp2,%fp0		# S(B2+...) | 
 |  | 
 | 	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...) | 
 | 	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...) | 
 | 	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...)) | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x20		# restore fp2 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.x		RPRIME(%a6),%fp1	# COS(X) | 
 | 	bsr		sto_cos			# store cosine result | 
 | 	fadd.s		POSNEG1(%a6),%fp0	# SIN(X) | 
 | 	bra		t_inx2 | 
 |  | 
 | NEVEN: | 
 | #--REGISTERS SAVED SO FAR: FP2. | 
 | 	fmovm.x		&0x04,-(%sp)		# save fp2 | 
 |  | 
 | 	fmov.x		%fp0,RPRIME(%a6) | 
 | 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R | 
 |  | 
 | 	fmov.d		COSB8(%pc),%fp1		# B8 | 
 | 	fmov.d		SINA7(%pc),%fp2		# A7 | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# SB8 | 
 | 	fmov.x		%fp0,SPRIME(%a6) | 
 | 	fmul.x		%fp0,%fp2		# SA7 | 
 |  | 
 | 	ror.l		&1,%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 |  | 
 | 	fadd.d		COSB7(%pc),%fp1		# B7+SB8 | 
 | 	fadd.d		SINA6(%pc),%fp2		# A6+SA7 | 
 |  | 
 | 	eor.l		%d1,RPRIME(%a6) | 
 | 	eor.l		%d1,SPRIME(%a6) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(B7+SB8) | 
 |  | 
 | 	or.l		&0x3F800000,%d1 | 
 | 	mov.l		%d1,POSNEG1(%a6) | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# S(A6+SA7) | 
 |  | 
 | 	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8) | 
 | 	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8)) | 
 | 	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7)) | 
 |  | 
 | 	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8)) | 
 | 	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7)) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(B5+...) | 
 | 	fmul.x		%fp0,%fp2		# S(A4+...) | 
 |  | 
 | 	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...) | 
 | 	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(B4+...) | 
 | 	fmul.x		%fp0,%fp2		# S(A3+...) | 
 |  | 
 | 	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...) | 
 | 	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(B3+...) | 
 | 	fmul.x		%fp0,%fp2		# S(A2+...) | 
 |  | 
 | 	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...) | 
 | 	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# S(B2+...) | 
 | 	fmul.x		%fp2,%fp0		# s(a1+...) | 
 |  | 
 |  | 
 | 	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...) | 
 | 	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...) | 
 | 	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...)) | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x20		# restore fp2 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.s		POSNEG1(%a6),%fp1	# COS(X) | 
 | 	bsr		sto_cos			# store cosine result | 
 | 	fadd.x		RPRIME(%a6),%fp0	# SIN(X) | 
 | 	bra		t_inx2 | 
 |  | 
 | ################################################ | 
 |  | 
 | SCBORS: | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bgt.w		SREDUCEX | 
 |  | 
 | ################################################ | 
 |  | 
 | SCSM: | 
 | #	mov.w		&0x0000,XDCARE(%a6) | 
 | 	fmov.s		&0x3F800000,%fp1 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fsub.s		&0x00800000,%fp1 | 
 | 	bsr		sto_cos			# store cosine result | 
 | 	fmov.l		%fpcr,%d0		# d0 must have fpcr,too | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		X(%a6),%fp0 | 
 | 	bra		t_catch | 
 |  | 
 | ############################################## | 
 |  | 
 | 	global		ssincosd | 
 | #--SIN AND COS OF X FOR DENORMALIZED X | 
 | ssincosd: | 
 | 	mov.l		%d0,-(%sp)		# save d0 | 
 | 	fmov.s		&0x3F800000,%fp1 | 
 | 	bsr		sto_cos			# store cosine result | 
 | 	mov.l		(%sp)+,%d0		# restore d0 | 
 | 	bra		t_extdnrm | 
 |  | 
 | ############################################ | 
 |  | 
 | #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. | 
 | #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING | 
 | #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. | 
 | SREDUCEX: | 
 | 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5} | 
 | 	mov.l		%d2,-(%sp)		# save d2 | 
 | 	fmov.s		&0x00000000,%fp1	# fp1 = 0 | 
 |  | 
 | #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that | 
 | #--there is a danger of unwanted overflow in first LOOP iteration.  In this | 
 | #--case, reduce argument by one remainder step to make subsequent reduction | 
 | #--safe. | 
 | 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large? | 
 | 	bne.b		SLOOP			# no | 
 |  | 
 | # yes; create 2**16383*PI/2 | 
 | 	mov.w		&0x7ffe,FP_SCR0_EX(%a6) | 
 | 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6) | 
 | 	clr.l		FP_SCR0_LO(%a6) | 
 |  | 
 | # create low half of 2**16383*PI/2 at FP_SCR1 | 
 | 	mov.w		&0x7fdc,FP_SCR1_EX(%a6) | 
 | 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6) | 
 | 	clr.l		FP_SCR1_LO(%a6) | 
 |  | 
 | 	ftest.x		%fp0			# test sign of argument | 
 | 	fblt.w		sred_neg | 
 |  | 
 | 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg | 
 | 	or.b		&0x80,FP_SCR1_EX(%a6) | 
 | sred_neg: | 
 | 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact | 
 | 	fmov.x		%fp0,%fp1		# save high result in fp1 | 
 | 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction | 
 | 	fsub.x		%fp0,%fp1		# determine low component of result | 
 | 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument. | 
 |  | 
 | #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. | 
 | #--integer quotient will be stored in N | 
 | #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) | 
 | SLOOP: | 
 | 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2 | 
 | 	mov.w		INARG(%a6),%d1 | 
 | 	mov.l		%d1,%a1			# save a copy of D0 | 
 | 	and.l		&0x00007FFF,%d1 | 
 | 	sub.l		&0x00003FFF,%d1		# d0 = K | 
 | 	cmp.l		%d1,&28 | 
 | 	ble.b		SLASTLOOP | 
 | SCONTLOOP: | 
 | 	sub.l		&27,%d1			# d0 = L := K-27 | 
 | 	mov.b		&0,ENDFLAG(%a6) | 
 | 	bra.b		SWORK | 
 | SLASTLOOP: | 
 | 	clr.l		%d1			# d0 = L := 0 | 
 | 	mov.b		&1,ENDFLAG(%a6) | 
 |  | 
 | SWORK: | 
 | #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN | 
 | #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29. | 
 |  | 
 | #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), | 
 | #--2**L * (PIby2_1), 2**L * (PIby2_2) | 
 |  | 
 | 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI | 
 | 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI) | 
 |  | 
 | 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6) | 
 | 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6) | 
 | 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI) | 
 |  | 
 | 	fmov.x		%fp0,%fp2 | 
 | 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI) | 
 |  | 
 | #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN | 
 | #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N | 
 | #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT | 
 | #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE | 
 | #--US THE DESIRED VALUE IN FLOATING POINT. | 
 | 	mov.l		%a1,%d2 | 
 | 	swap		%d2 | 
 | 	and.l		&0x80000000,%d2 | 
 | 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL | 
 | 	mov.l		%d2,TWOTO63(%a6) | 
 | 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED | 
 | 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N | 
 | #	fint.x		%fp2 | 
 |  | 
 | #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 | 
 | 	mov.l		%d1,%d2			# d2 = L | 
 |  | 
 | 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2) | 
 | 	mov.w		%d2,FP_SCR0_EX(%a6) | 
 | 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6) | 
 | 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1 | 
 |  | 
 | 	add.l		&0x00003FDD,%d1 | 
 | 	mov.w		%d1,FP_SCR1_EX(%a6) | 
 | 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6) | 
 | 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2 | 
 |  | 
 | 	mov.b		ENDFLAG(%a6),%d1 | 
 |  | 
 | #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and | 
 | #--P2 = 2**(L) * Piby2_2 | 
 | 	fmov.x		%fp2,%fp4		# fp4 = N | 
 | 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1 | 
 | 	fmov.x		%fp2,%fp5		# fp5 = N | 
 | 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2 | 
 | 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1 | 
 |  | 
 | #--we want P+p = W+w  but  |p| <= half ulp of P | 
 | #--Then, we need to compute  A := R-P   and  a := r-p | 
 | 	fadd.x		%fp5,%fp3		# fp3 = P | 
 | 	fsub.x		%fp3,%fp4		# fp4 = W-P | 
 |  | 
 | 	fsub.x		%fp3,%fp0		# fp0 = A := R - P | 
 | 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w | 
 |  | 
 | 	fmov.x		%fp0,%fp3		# fp3 = A | 
 | 	fsub.x		%fp4,%fp1		# fp1 = a := r - p | 
 |  | 
 | #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but | 
 | #--|r| <= half ulp of R. | 
 | 	fadd.x		%fp1,%fp0		# fp0 = R := A+a | 
 | #--No need to calculate r if this is the last loop | 
 | 	cmp.b		%d1,&0 | 
 | 	bgt.w		SRESTORE | 
 |  | 
 | #--Need to calculate r | 
 | 	fsub.x		%fp0,%fp3		# fp3 = A-R | 
 | 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a | 
 | 	bra.w		SLOOP | 
 |  | 
 | SRESTORE: | 
 | 	fmov.l		%fp2,INT(%a6) | 
 | 	mov.l		(%sp)+,%d2		# restore d2 | 
 | 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5} | 
 |  | 
 | 	mov.l		ADJN(%a6),%d1 | 
 | 	cmp.l		%d1,&4 | 
 |  | 
 | 	blt.w		SINCONT | 
 | 	bra.w		SCCONT | 
 |  | 
 | ######################################################################### | 
 | # stan():  computes the tangent of a normalized input			# | 
 | # stand(): computes the tangent of a denormalized input			# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = tan(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY ******************************************* # | 
 | #	The returned result is within 3 ulp in 64 significant bit, i.e. # | 
 | #	within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM *********************************************************** # | 
 | #									# | 
 | #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			# | 
 | #									# | 
 | #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	# | 
 | #		k = N mod 2, so in particular, k = 0 or 1.		# | 
 | #									# | 
 | #	3. If k is odd, go to 5.					# | 
 | #									# | 
 | #	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	# | 
 | #		rational function U/V where				# | 
 | #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			# | 
 | #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	# | 
 | #		Exit.							# | 
 | #									# | 
 | #	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by # | 
 | #		a rational function U/V where				# | 
 | #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			# | 
 | #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	# | 
 | #		-Cot(r) = -V/U. Exit.					# | 
 | #									# | 
 | #	6. If |X| > 1, go to 8.						# | 
 | #									# | 
 | #	7. (|X|<2**(-40)) Tan(X) = X. Exit.				# | 
 | #									# | 
 | #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back	# | 
 | #		to 2.							# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | TANQ4: | 
 | 	long		0x3EA0B759,0xF50F8688 | 
 | TANP3: | 
 | 	long		0xBEF2BAA5,0xA8924F04 | 
 |  | 
 | TANQ3: | 
 | 	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000 | 
 |  | 
 | TANP2: | 
 | 	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000 | 
 |  | 
 | TANQ2: | 
 | 	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000 | 
 |  | 
 | TANP1: | 
 | 	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000 | 
 |  | 
 | TANQ1: | 
 | 	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000 | 
 |  | 
 | INVTWOPI: | 
 | 	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000 | 
 |  | 
 | TWOPI1: | 
 | 	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000 | 
 | TWOPI2: | 
 | 	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000 | 
 |  | 
 | #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING | 
 | #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT | 
 | #--MOST 69 BITS LONG. | 
 | #	global		PITBL | 
 | PITBL: | 
 | 	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000 | 
 | 	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000 | 
 | 	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000 | 
 | 	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000 | 
 | 	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000 | 
 | 	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000 | 
 | 	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000 | 
 | 	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000 | 
 | 	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000 | 
 | 	long		0xC0040000,0x90836524,0x88034B96,0x20B00000 | 
 | 	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000 | 
 | 	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000 | 
 | 	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000 | 
 | 	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000 | 
 | 	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000 | 
 | 	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000 | 
 | 	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000 | 
 | 	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000 | 
 | 	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000 | 
 | 	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000 | 
 | 	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000 | 
 | 	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000 | 
 | 	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000 | 
 | 	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000 | 
 | 	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000 | 
 | 	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000 | 
 | 	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000 | 
 | 	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000 | 
 | 	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000 | 
 | 	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000 | 
 | 	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000 | 
 | 	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000 | 
 | 	long		0x00000000,0x00000000,0x00000000,0x00000000 | 
 | 	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000 | 
 | 	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000 | 
 | 	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000 | 
 | 	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000 | 
 | 	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000 | 
 | 	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000 | 
 | 	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000 | 
 | 	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000 | 
 | 	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000 | 
 | 	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000 | 
 | 	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000 | 
 | 	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000 | 
 | 	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000 | 
 | 	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000 | 
 | 	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000 | 
 | 	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000 | 
 | 	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000 | 
 | 	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000 | 
 | 	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000 | 
 | 	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000 | 
 | 	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000 | 
 | 	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000 | 
 | 	long		0x40040000,0x90836524,0x88034B96,0xA0B00000 | 
 | 	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000 | 
 | 	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000 | 
 | 	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000 | 
 | 	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000 | 
 | 	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000 | 
 | 	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000 | 
 | 	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000 | 
 | 	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000 | 
 | 	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000 | 
 |  | 
 | 	set		INARG,FP_SCR0 | 
 |  | 
 | 	set		TWOTO63,L_SCR1 | 
 | 	set		INT,L_SCR1 | 
 | 	set		ENDFLAG,L_SCR2 | 
 |  | 
 | 	global		stan | 
 | stan: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 |  | 
 | 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)? | 
 | 	bge.b		TANOK1 | 
 | 	bra.w		TANSM | 
 | TANOK1: | 
 | 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI? | 
 | 	blt.b		TANMAIN | 
 | 	bra.w		REDUCEX | 
 |  | 
 | TANMAIN: | 
 | #--THIS IS THE USUAL CASE, |X| <= 15 PI. | 
 | #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI | 
 |  | 
 | 	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32 | 
 |  | 
 | 	fmov.l		%fp1,%d1		# CONVERT TO INTEGER | 
 |  | 
 | 	asl.l		&4,%d1 | 
 | 	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2 | 
 |  | 
 | 	fsub.x		(%a1)+,%fp0		# X-Y1 | 
 |  | 
 | 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2 | 
 |  | 
 | 	ror.l		&5,%d1 | 
 | 	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0 | 
 |  | 
 | TANCONT: | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3 | 
 |  | 
 | 	cmp.l		%d1,&0 | 
 | 	blt.w		NODD | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# S = R*R | 
 |  | 
 | 	fmov.d		TANQ4(%pc),%fp3 | 
 | 	fmov.d		TANP3(%pc),%fp2 | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# SQ4 | 
 | 	fmul.x		%fp1,%fp2		# SP3 | 
 |  | 
 | 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4 | 
 | 	fadd.x		TANP2(%pc),%fp2		# P2+SP3 | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# S(Q3+SQ4) | 
 | 	fmul.x		%fp1,%fp2		# S(P2+SP3) | 
 |  | 
 | 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4) | 
 | 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3) | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4)) | 
 | 	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3)) | 
 |  | 
 | 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4)) | 
 | 	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3)) | 
 |  | 
 | 	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4))) | 
 |  | 
 | 	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3)) | 
 |  | 
 | 	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...) | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	fdiv.x		%fp1,%fp0		# last inst - possible exception set | 
 | 	bra		t_inx2 | 
 |  | 
 | NODD: | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp0,%fp0		# S = R*R | 
 |  | 
 | 	fmov.d		TANQ4(%pc),%fp3 | 
 | 	fmov.d		TANP3(%pc),%fp2 | 
 |  | 
 | 	fmul.x		%fp0,%fp3		# SQ4 | 
 | 	fmul.x		%fp0,%fp2		# SP3 | 
 |  | 
 | 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4 | 
 | 	fadd.x		TANP2(%pc),%fp2		# P2+SP3 | 
 |  | 
 | 	fmul.x		%fp0,%fp3		# S(Q3+SQ4) | 
 | 	fmul.x		%fp0,%fp2		# S(P2+SP3) | 
 |  | 
 | 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4) | 
 | 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3) | 
 |  | 
 | 	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4)) | 
 | 	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3)) | 
 |  | 
 | 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4)) | 
 | 	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3)) | 
 |  | 
 | 	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4))) | 
 |  | 
 | 	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3)) | 
 | 	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...) | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3 | 
 |  | 
 | 	fmov.x		%fp1,-(%sp) | 
 | 	eor.l		&0x80000000,(%sp) | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set | 
 | 	bra		t_inx2 | 
 |  | 
 | TANBORS: | 
 | #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. | 
 | #--IF |X| < 2**(-40), RETURN X OR 1. | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bgt.b		REDUCEX | 
 |  | 
 | TANSM: | 
 | 	fmov.x		%fp0,-(%sp) | 
 | 	fmov.l		%d0,%fpcr		# restore users round mode,prec | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set | 
 | 	bra		t_catch | 
 |  | 
 | 	global		stand | 
 | #--TAN(X) = X FOR DENORMALIZED X | 
 | stand: | 
 | 	bra		t_extdnrm | 
 |  | 
 | #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. | 
 | #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING | 
 | #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. | 
 | REDUCEX: | 
 | 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5} | 
 | 	mov.l		%d2,-(%sp)		# save d2 | 
 | 	fmov.s		&0x00000000,%fp1	# fp1 = 0 | 
 |  | 
 | #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that | 
 | #--there is a danger of unwanted overflow in first LOOP iteration.  In this | 
 | #--case, reduce argument by one remainder step to make subsequent reduction | 
 | #--safe. | 
 | 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large? | 
 | 	bne.b		LOOP			# no | 
 |  | 
 | # yes; create 2**16383*PI/2 | 
 | 	mov.w		&0x7ffe,FP_SCR0_EX(%a6) | 
 | 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6) | 
 | 	clr.l		FP_SCR0_LO(%a6) | 
 |  | 
 | # create low half of 2**16383*PI/2 at FP_SCR1 | 
 | 	mov.w		&0x7fdc,FP_SCR1_EX(%a6) | 
 | 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6) | 
 | 	clr.l		FP_SCR1_LO(%a6) | 
 |  | 
 | 	ftest.x		%fp0			# test sign of argument | 
 | 	fblt.w		red_neg | 
 |  | 
 | 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg | 
 | 	or.b		&0x80,FP_SCR1_EX(%a6) | 
 | red_neg: | 
 | 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact | 
 | 	fmov.x		%fp0,%fp1		# save high result in fp1 | 
 | 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction | 
 | 	fsub.x		%fp0,%fp1		# determine low component of result | 
 | 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument. | 
 |  | 
 | #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. | 
 | #--integer quotient will be stored in N | 
 | #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) | 
 | LOOP: | 
 | 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2 | 
 | 	mov.w		INARG(%a6),%d1 | 
 | 	mov.l		%d1,%a1			# save a copy of D0 | 
 | 	and.l		&0x00007FFF,%d1 | 
 | 	sub.l		&0x00003FFF,%d1		# d0 = K | 
 | 	cmp.l		%d1,&28 | 
 | 	ble.b		LASTLOOP | 
 | CONTLOOP: | 
 | 	sub.l		&27,%d1			# d0 = L := K-27 | 
 | 	mov.b		&0,ENDFLAG(%a6) | 
 | 	bra.b		WORK | 
 | LASTLOOP: | 
 | 	clr.l		%d1			# d0 = L := 0 | 
 | 	mov.b		&1,ENDFLAG(%a6) | 
 |  | 
 | WORK: | 
 | #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN | 
 | #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29. | 
 |  | 
 | #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), | 
 | #--2**L * (PIby2_1), 2**L * (PIby2_2) | 
 |  | 
 | 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI | 
 | 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI) | 
 |  | 
 | 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6) | 
 | 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6) | 
 | 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI) | 
 |  | 
 | 	fmov.x		%fp0,%fp2 | 
 | 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI) | 
 |  | 
 | #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN | 
 | #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N | 
 | #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT | 
 | #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE | 
 | #--US THE DESIRED VALUE IN FLOATING POINT. | 
 | 	mov.l		%a1,%d2 | 
 | 	swap		%d2 | 
 | 	and.l		&0x80000000,%d2 | 
 | 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL | 
 | 	mov.l		%d2,TWOTO63(%a6) | 
 | 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED | 
 | 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N | 
 | #	fintrz.x	%fp2,%fp2 | 
 |  | 
 | #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 | 
 | 	mov.l		%d1,%d2			# d2 = L | 
 |  | 
 | 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2) | 
 | 	mov.w		%d2,FP_SCR0_EX(%a6) | 
 | 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6) | 
 | 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1 | 
 |  | 
 | 	add.l		&0x00003FDD,%d1 | 
 | 	mov.w		%d1,FP_SCR1_EX(%a6) | 
 | 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6) | 
 | 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2 | 
 |  | 
 | 	mov.b		ENDFLAG(%a6),%d1 | 
 |  | 
 | #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and | 
 | #--P2 = 2**(L) * Piby2_2 | 
 | 	fmov.x		%fp2,%fp4		# fp4 = N | 
 | 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1 | 
 | 	fmov.x		%fp2,%fp5		# fp5 = N | 
 | 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2 | 
 | 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1 | 
 |  | 
 | #--we want P+p = W+w  but  |p| <= half ulp of P | 
 | #--Then, we need to compute  A := R-P   and  a := r-p | 
 | 	fadd.x		%fp5,%fp3		# fp3 = P | 
 | 	fsub.x		%fp3,%fp4		# fp4 = W-P | 
 |  | 
 | 	fsub.x		%fp3,%fp0		# fp0 = A := R - P | 
 | 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w | 
 |  | 
 | 	fmov.x		%fp0,%fp3		# fp3 = A | 
 | 	fsub.x		%fp4,%fp1		# fp1 = a := r - p | 
 |  | 
 | #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but | 
 | #--|r| <= half ulp of R. | 
 | 	fadd.x		%fp1,%fp0		# fp0 = R := A+a | 
 | #--No need to calculate r if this is the last loop | 
 | 	cmp.b		%d1,&0 | 
 | 	bgt.w		RESTORE | 
 |  | 
 | #--Need to calculate r | 
 | 	fsub.x		%fp0,%fp3		# fp3 = A-R | 
 | 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a | 
 | 	bra.w		LOOP | 
 |  | 
 | RESTORE: | 
 | 	fmov.l		%fp2,INT(%a6) | 
 | 	mov.l		(%sp)+,%d2		# restore d2 | 
 | 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5} | 
 |  | 
 | 	mov.l		INT(%a6),%d1 | 
 | 	ror.l		&1,%d1 | 
 |  | 
 | 	bra.w		TANCONT | 
 |  | 
 | ######################################################################### | 
 | # satan():  computes the arctangent of a normalized number		# | 
 | # satand(): computes the arctangent of a denormalized number		# | 
 | #									# | 
 | # INPUT	*************************************************************** # | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = arctan(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY ******************************************* # | 
 | #	The returned result is within 2 ulps in	64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM *********************************************************** # | 
 | #	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		# | 
 | #									# | 
 | #	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x.			# | 
 | #		Note that k = -4, -3,..., or 3.				# | 
 | #		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5	# | 
 | #		significant bits of X with a bit-1 attached at the 6-th	# | 
 | #		bit position. Define u to be u = (X-F) / (1 + X*F).	# | 
 | #									# | 
 | #	Step 3. Approximate arctan(u) by a polynomial poly.		# | 
 | #									# | 
 | #	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a	# | 
 | #		table of values calculated beforehand. Exit.		# | 
 | #									# | 
 | #	Step 5. If |X| >= 16, go to Step 7.				# | 
 | #									# | 
 | #	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	# | 
 | #									# | 
 | #	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd	# | 
 | #		polynomial in X'.					# | 
 | #		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | ATANA3:	long		0xBFF6687E,0x314987D8 | 
 | ATANA2:	long		0x4002AC69,0x34A26DB3 | 
 | ATANA1:	long		0xBFC2476F,0x4E1DA28E | 
 |  | 
 | ATANB6:	long		0x3FB34444,0x7F876989 | 
 | ATANB5:	long		0xBFB744EE,0x7FAF45DB | 
 | ATANB4:	long		0x3FBC71C6,0x46940220 | 
 | ATANB3:	long		0xBFC24924,0x921872F9 | 
 | ATANB2:	long		0x3FC99999,0x99998FA9 | 
 | ATANB1:	long		0xBFD55555,0x55555555 | 
 |  | 
 | ATANC5:	long		0xBFB70BF3,0x98539E6A | 
 | ATANC4:	long		0x3FBC7187,0x962D1D7D | 
 | ATANC3:	long		0xBFC24924,0x827107B8 | 
 | ATANC2:	long		0x3FC99999,0x9996263E | 
 | ATANC1:	long		0xBFD55555,0x55555536 | 
 |  | 
 | PPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 | 
 | NPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000 | 
 |  | 
 | PTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000 | 
 | NTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000 | 
 |  | 
 | ATANTBL: | 
 | 	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000 | 
 | 	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000 | 
 | 	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000 | 
 | 	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000 | 
 | 	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000 | 
 | 	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000 | 
 | 	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000 | 
 | 	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000 | 
 | 	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000 | 
 | 	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000 | 
 | 	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000 | 
 | 	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000 | 
 | 	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000 | 
 | 	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000 | 
 | 	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000 | 
 | 	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000 | 
 | 	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000 | 
 | 	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000 | 
 | 	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000 | 
 | 	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000 | 
 | 	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000 | 
 | 	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000 | 
 | 	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000 | 
 | 	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000 | 
 | 	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000 | 
 | 	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000 | 
 | 	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000 | 
 | 	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000 | 
 | 	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000 | 
 | 	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000 | 
 | 	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000 | 
 | 	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000 | 
 | 	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000 | 
 | 	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000 | 
 | 	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000 | 
 | 	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000 | 
 | 	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000 | 
 | 	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000 | 
 | 	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000 | 
 | 	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000 | 
 | 	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000 | 
 | 	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000 | 
 | 	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000 | 
 | 	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000 | 
 | 	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000 | 
 | 	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000 | 
 | 	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000 | 
 | 	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000 | 
 | 	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000 | 
 | 	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000 | 
 | 	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000 | 
 | 	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000 | 
 | 	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000 | 
 | 	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000 | 
 | 	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000 | 
 | 	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000 | 
 | 	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000 | 
 | 	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000 | 
 | 	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000 | 
 | 	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000 | 
 | 	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000 | 
 | 	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000 | 
 | 	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000 | 
 | 	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000 | 
 | 	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000 | 
 | 	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000 | 
 | 	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000 | 
 | 	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000 | 
 | 	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000 | 
 | 	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000 | 
 | 	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000 | 
 | 	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000 | 
 | 	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000 | 
 | 	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000 | 
 | 	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000 | 
 | 	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000 | 
 | 	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000 | 
 | 	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000 | 
 | 	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000 | 
 | 	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000 | 
 | 	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000 | 
 | 	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000 | 
 | 	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000 | 
 | 	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000 | 
 | 	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000 | 
 | 	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000 | 
 | 	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000 | 
 | 	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000 | 
 | 	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000 | 
 | 	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000 | 
 | 	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000 | 
 | 	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000 | 
 | 	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000 | 
 | 	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000 | 
 | 	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000 | 
 | 	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000 | 
 | 	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000 | 
 | 	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000 | 
 | 	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000 | 
 | 	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000 | 
 | 	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000 | 
 | 	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000 | 
 | 	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000 | 
 | 	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000 | 
 | 	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000 | 
 | 	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000 | 
 | 	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000 | 
 | 	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000 | 
 | 	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000 | 
 | 	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000 | 
 | 	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000 | 
 | 	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000 | 
 | 	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000 | 
 | 	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000 | 
 | 	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000 | 
 | 	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000 | 
 | 	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000 | 
 | 	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000 | 
 | 	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000 | 
 | 	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000 | 
 | 	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000 | 
 | 	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000 | 
 | 	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000 | 
 | 	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000 | 
 | 	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000 | 
 | 	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000 | 
 | 	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000 | 
 | 	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000 | 
 |  | 
 | 	set		X,FP_SCR0 | 
 | 	set		XDCARE,X+2 | 
 | 	set		XFRAC,X+4 | 
 | 	set		XFRACLO,X+8 | 
 |  | 
 | 	set		ATANF,FP_SCR1 | 
 | 	set		ATANFHI,ATANF+4 | 
 | 	set		ATANFLO,ATANF+8 | 
 |  | 
 | 	global		satan | 
 | #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S | 
 | satan: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	fmov.x		%fp0,X(%a6) | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 |  | 
 | 	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16? | 
 | 	bge.b		ATANOK1 | 
 | 	bra.w		ATANSM | 
 |  | 
 | ATANOK1: | 
 | 	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ? | 
 | 	ble.b		ATANMAIN | 
 | 	bra.w		ATANBIG | 
 |  | 
 | #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE | 
 | #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ). | 
 | #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN | 
 | #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE | 
 | #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS | 
 | #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR | 
 | #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO | 
 | #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE | 
 | #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL | 
 | #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE | 
 | #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION | 
 | #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION | 
 | #--WILL INVOLVE A VERY LONG POLYNOMIAL. | 
 |  | 
 | #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS | 
 | #--WE CHOSE F TO BE +-2^K * 1.BBBB1 | 
 | #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE | 
 | #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE | 
 | #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS | 
 | #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|). | 
 |  | 
 | ATANMAIN: | 
 |  | 
 | 	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS | 
 | 	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1 | 
 | 	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F | 
 |  | 
 | 	fmov.x		%fp0,%fp1		# FP1 IS X | 
 | 	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0 | 
 | 	fsub.x		X(%a6),%fp0		# FP0 IS X-F | 
 | 	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F | 
 | 	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F) | 
 |  | 
 | #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|) | 
 | #--CREATE ATAN(F) AND STORE IT IN ATANF, AND | 
 | #--SAVE REGISTERS FP2. | 
 |  | 
 | 	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY | 
 | 	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X | 
 | 	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION | 
 | 	and.l		&0x7FFF0000,%d2		# EXPONENT OF F | 
 | 	sub.l		&0x3FFB0000,%d2		# K+4 | 
 | 	asr.l		&1,%d2 | 
 | 	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F | 
 | 	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|) | 
 | 	lea		ATANTBL(%pc),%a1 | 
 | 	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|) | 
 | 	mov.l		(%a1)+,ATANF(%a6) | 
 | 	mov.l		(%a1)+,ATANFHI(%a6) | 
 | 	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|) | 
 | 	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN | 
 | 	and.l		&0x80000000,%d1		# SIGN(F) | 
 | 	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|) | 
 | 	mov.l		(%sp)+,%d2		# RESTORE d2 | 
 |  | 
 | #--THAT'S ALL I HAVE TO DO FOR NOW, | 
 | #--BUT ALAS, THE DIVIDE IS STILL CRANKING! | 
 |  | 
 | #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS | 
 | #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U | 
 | #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT. | 
 | #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3)) | 
 | #--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3. | 
 | #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT | 
 | #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED | 
 |  | 
 | 	fmovm.x		&0x04,-(%sp)		# save fp2 | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1 | 
 | 	fmov.d		ATANA3(%pc),%fp2 | 
 | 	fadd.x		%fp1,%fp2		# A3+V | 
 | 	fmul.x		%fp1,%fp2		# V*(A3+V) | 
 | 	fmul.x		%fp0,%fp1		# U*V | 
 | 	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V) | 
 | 	fmul.d		ATANA1(%pc),%fp1	# A1*U*V | 
 | 	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V)) | 
 | 	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x20		# restore fp2 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec | 
 | 	fadd.x		ATANF(%a6),%fp0		# ATAN(X) | 
 | 	bra		t_inx2 | 
 |  | 
 | ATANBORS: | 
 | #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED. | 
 | #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16. | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bgt.w		ATANBIG			# I.E. |X| >= 16 | 
 |  | 
 | ATANSM: | 
 | #--|X| <= 1/16 | 
 | #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE | 
 | #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6))))) | 
 | #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] ) | 
 | #--WHERE Y = X*X, AND Z = Y*Y. | 
 |  | 
 | 	cmp.l		%d1,&0x3FD78000 | 
 | 	blt.w		ATANTINY | 
 |  | 
 | #--COMPUTE POLYNOMIAL | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3 | 
 |  | 
 | 	fmul.x		%fp0,%fp0		# FPO IS Y = X*X | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y | 
 |  | 
 | 	fmov.d		ATANB6(%pc),%fp2 | 
 | 	fmov.d		ATANB5(%pc),%fp3 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# Z*B6 | 
 | 	fmul.x		%fp1,%fp3		# Z*B5 | 
 |  | 
 | 	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6 | 
 | 	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6) | 
 | 	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5) | 
 |  | 
 | 	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6) | 
 | 	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5) | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6)) | 
 | 	fmul.x		X(%a6),%fp0		# X*Y | 
 |  | 
 | 	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))] | 
 |  | 
 | 	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]) | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec | 
 | 	fadd.x		X(%a6),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | ATANTINY: | 
 | #--|X| < 2^(-40), ATAN(X) = X | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		X(%a6),%fp0		# last inst - possible exception set | 
 |  | 
 | 	bra		t_catch | 
 |  | 
 | ATANBIG: | 
 | #--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE, | 
 | #--RETURN SIGN(X)*PI/2 + ATAN(-1/X). | 
 | 	cmp.l		%d1,&0x40638000 | 
 | 	bgt.w		ATANHUGE | 
 |  | 
 | #--APPROXIMATE ATAN(-1/X) BY | 
 | #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X' | 
 | #--THIS CAN BE RE-WRITTEN AS | 
 | #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y. | 
 |  | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3 | 
 |  | 
 | 	fmov.s		&0xBF800000,%fp1	# LOAD -1 | 
 | 	fdiv.x		%fp0,%fp1		# FP1 IS -1/X | 
 |  | 
 | #--DIVIDE IS STILL CRANKING | 
 |  | 
 | 	fmov.x		%fp1,%fp0		# FP0 IS X' | 
 | 	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X' | 
 | 	fmov.x		%fp1,X(%a6)		# X IS REALLY X' | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y | 
 |  | 
 | 	fmov.d		ATANC5(%pc),%fp3 | 
 | 	fmov.d		ATANC4(%pc),%fp2 | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# Z*C5 | 
 | 	fmul.x		%fp1,%fp2		# Z*B4 | 
 |  | 
 | 	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5 | 
 | 	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4 | 
 |  | 
 | 	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED | 
 | 	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4) | 
 |  | 
 | 	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5) | 
 | 	fmul.x		X(%a6),%fp0		# X'*Y | 
 |  | 
 | 	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)] | 
 |  | 
 | 	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)] | 
 | #					...	+[Y*(B2+Z*(B4+Z*B6))]) | 
 | 	fadd.x		X(%a6),%fp0 | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec | 
 | 	tst.b		(%a0) | 
 | 	bpl.b		pos_big | 
 |  | 
 | neg_big: | 
 | 	fadd.x		NPIBY2(%pc),%fp0 | 
 | 	bra		t_minx2 | 
 |  | 
 | pos_big: | 
 | 	fadd.x		PPIBY2(%pc),%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | ATANHUGE: | 
 | #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY | 
 | 	tst.b		(%a0) | 
 | 	bpl.b		pos_huge | 
 |  | 
 | neg_huge: | 
 | 	fmov.x		NPIBY2(%pc),%fp0 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.x		PTINY(%pc),%fp0 | 
 | 	bra		t_minx2 | 
 |  | 
 | pos_huge: | 
 | 	fmov.x		PPIBY2(%pc),%fp0 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.x		NTINY(%pc),%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | 	global		satand | 
 | #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT | 
 | satand: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # sasin():  computes the inverse sine of a normalized input		# | 
 | # sasind(): computes the inverse sine of a denormalized input		# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = arcsin(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 3 ulps in	64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #	ASIN								# | 
 | #	1. If |X| >= 1, go to 3.					# | 
 | #									# | 
 | #	2. (|X| < 1) Calculate asin(X) by				# | 
 | #		z := sqrt( [1-X][1+X] )					# | 
 | #		asin(X) = atan( x / z ).				# | 
 | #		Exit.							# | 
 | #									# | 
 | #	3. If |X| > 1, go to 5.						# | 
 | #									# | 
 | #	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.# | 
 | #									# | 
 | #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	# | 
 | #		Exit.							# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		sasin | 
 | sasin: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bge.b		ASINBIG | 
 |  | 
 | # This catch is added here for the '060 QSP. Originally, the call to | 
 | # satan() would handle this case by causing the exception which would | 
 | # not be caught until gen_except(). Now, with the exceptions being | 
 | # detected inside of satan(), the exception would have been handled there | 
 | # instead of inside sasin() as expected. | 
 | 	cmp.l		%d1,&0x3FD78000 | 
 | 	blt.w		ASINTINY | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| < 1 | 
 | #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) ) | 
 |  | 
 | ASINMAIN: | 
 | 	fmov.s		&0x3F800000,%fp1 | 
 | 	fsub.x		%fp0,%fp1		# 1-X | 
 | 	fmovm.x		&0x4,-(%sp)		#  {fp2} | 
 | 	fmov.s		&0x3F800000,%fp2 | 
 | 	fadd.x		%fp0,%fp2		# 1+X | 
 | 	fmul.x		%fp2,%fp1		# (1+X)(1-X) | 
 | 	fmovm.x		(%sp)+,&0x20		#  {fp2} | 
 | 	fsqrt.x		%fp1			# SQRT([1-X][1+X]) | 
 | 	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X]) | 
 | 	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...) | 
 | 	lea		(%sp),%a0		# pass ptr to X/SQRT(...) | 
 | 	bsr		satan | 
 | 	add.l		&0xc,%sp		# clear X/SQRT(...) from stack | 
 | 	bra		t_inx2 | 
 |  | 
 | ASINBIG: | 
 | 	fabs.x		%fp0			# |X| | 
 | 	fcmp.s		%fp0,&0x3F800000 | 
 | 	fbgt		t_operr			# cause an operr exception | 
 |  | 
 | #--|X| = 1, ASIN(X) = +- PI/2. | 
 | ASINONE: | 
 | 	fmov.x		PIBY2(%pc),%fp0 | 
 | 	mov.l		(%a0),%d1 | 
 | 	and.l		&0x80000000,%d1		# SIGN BIT OF X | 
 | 	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT | 
 | 	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fmul.s		(%sp)+,%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | #--|X| < 2^(-40), ATAN(X) = X | 
 | ASINTINY: | 
 | 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		(%a0),%fp0		# last inst - possible exception | 
 | 	bra		t_catch | 
 |  | 
 | 	global		sasind | 
 | #--ASIN(X) = X FOR DENORMALIZED X | 
 | sasind: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # sacos():  computes the inverse cosine of a normalized input		# | 
 | # sacosd(): computes the inverse cosine of a denormalized input		# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = arccos(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 3 ulps in	64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM *********************************************************** # | 
 | #									# | 
 | #	ACOS								# | 
 | #	1. If |X| >= 1, go to 3.					# | 
 | #									# | 
 | #	2. (|X| < 1) Calculate acos(X) by				# | 
 | #		z := (1-X) / (1+X)					# | 
 | #		acos(X) = 2 * atan( sqrt(z) ).				# | 
 | #		Exit.							# | 
 | #									# | 
 | #	3. If |X| > 1, go to 5.						# | 
 | #									# | 
 | #	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	# | 
 | #									# | 
 | #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	# | 
 | #		Exit.							# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		sacos | 
 | sacos: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction | 
 | 	mov.w		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bge.b		ACOSBIG | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| < 1 | 
 | #--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) ) | 
 |  | 
 | ACOSMAIN: | 
 | 	fmov.s		&0x3F800000,%fp1 | 
 | 	fadd.x		%fp0,%fp1		# 1+X | 
 | 	fneg.x		%fp0			# -X | 
 | 	fadd.s		&0x3F800000,%fp0	# 1-X | 
 | 	fdiv.x		%fp1,%fp0		# (1-X)/(1+X) | 
 | 	fsqrt.x		%fp0			# SQRT((1-X)/(1+X)) | 
 | 	mov.l		%d0,-(%sp)		# save original users fpcr | 
 | 	clr.l		%d0 | 
 | 	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack | 
 | 	lea		(%sp),%a0		# pass ptr to sqrt | 
 | 	bsr		satan			# ATAN(SQRT([1-X]/[1+X])) | 
 | 	add.l		&0xc,%sp		# clear SQRT(...) from stack | 
 |  | 
 | 	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode | 
 | 	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF ) | 
 | 	bra		t_pinx2 | 
 |  | 
 | ACOSBIG: | 
 | 	fabs.x		%fp0 | 
 | 	fcmp.s		%fp0,&0x3F800000 | 
 | 	fbgt		t_operr			# cause an operr exception | 
 |  | 
 | #--|X| = 1, ACOS(X) = 0 OR PI | 
 | 	tst.b		(%a0)			# is X positive or negative? | 
 | 	bpl.b		ACOSP1 | 
 |  | 
 | #--X = -1 | 
 | #Returns PI and inexact exception | 
 | ACOSM1: | 
 | 	fmov.x		PI(%pc),%fp0		# load PI | 
 | 	fmov.l		%d0,%fpcr		# load round mode,prec | 
 | 	fadd.s		&0x00800000,%fp0	# add a small value | 
 | 	bra		t_pinx2 | 
 |  | 
 | ACOSP1: | 
 | 	bra		ld_pzero		# answer is positive zero | 
 |  | 
 | 	global		sacosd | 
 | #--ACOS(X) = PI/2 FOR DENORMALIZED X | 
 | sacosd: | 
 | 	fmov.l		%d0,%fpcr		# load user's rnd mode/prec | 
 | 	fmov.x		PIBY2(%pc),%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | ######################################################################### | 
 | # setox():    computes the exponential for a normalized input		# | 
 | # setoxd():   computes the exponential for a denormalized input		# | 
 | # setoxm1():  computes the exponential minus 1 for a normalized input	# | 
 | # setoxm1d(): computes the exponential minus 1 for a denormalized input	# | 
 | #									# | 
 | # INPUT	*************************************************************** # | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = exp(X) or exp(X)-1					# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY ******************************************* # | 
 | #	The returned result is within 0.85 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently # | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM and IMPLEMENTATION **************************************** # | 
 | #									# | 
 | #	setoxd								# | 
 | #	------								# | 
 | #	Step 1.	Set ans := 1.0						# | 
 | #									# | 
 | #	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		# | 
 | #	Notes:	This will always generate one exception -- inexact.	# | 
 | #									# | 
 | #									# | 
 | #	setox								# | 
 | #	-----								# | 
 | #									# | 
 | #	Step 1.	Filter out extreme cases of input argument.		# | 
 | #		1.1	If |X| >= 2^(-65), go to Step 1.3.		# | 
 | #		1.2	Go to Step 7.					# | 
 | #		1.3	If |X| < 16380 log(2), go to Step 2.		# | 
 | #		1.4	Go to Step 8.					# | 
 | #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.# | 
 | #		To avoid the use of floating-point comparisons, a	# | 
 | #		compact representation of |X| is used. This format is a	# | 
 | #		32-bit integer, the upper (more significant) 16 bits	# | 
 | #		are the sign and biased exponent field of |X|; the	# | 
 | #		lower 16 bits are the 16 most significant fraction	# | 
 | #		(including the explicit bit) bits of |X|. Consequently,	# | 
 | #		the comparisons in Steps 1.1 and 1.3 can be performed	# | 
 | #		by integer comparison. Note also that the constant	# | 
 | #		16380 log(2) used in Step 1.3 is also in the compact	# | 
 | #		form. Thus taking the branch to Step 2 guarantees	# | 
 | #		|X| < 16380 log(2). There is no harm to have a small	# | 
 | #		number of cases where |X| is less than,	but close to,	# | 
 | #		16380 log(2) and the branch to Step 9 is taken.		# | 
 | #									# | 
 | #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	# | 
 | #		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 # | 
 | #			was taken)					# | 
 | #		2.2	N := round-to-nearest-integer( X * 64/log2 ).	# | 
 | #		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., # | 
 | #			or 63.						# | 
 | #		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	# | 
 | #		2.5	Calculate the address of the stored value of	# | 
 | #			2^(J/64).					# | 
 | #		2.6	Create the value Scale = 2^M.			# | 
 | #	Notes:	The calculation in 2.2 is really performed by		# | 
 | #			Z := X * constant				# | 
 | #			N := round-to-nearest-integer(Z)		# | 
 | #		where							# | 
 | #			constant := single-precision( 64/log 2 ).	# | 
 | #									# | 
 | #		Using a single-precision constant avoids memory		# | 
 | #		access. Another effect of using a single-precision	# | 
 | #		"constant" is that the calculated value Z is		# | 
 | #									# | 
 | #			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	# | 
 | #									# | 
 | #		This error has to be considered later in Steps 3 and 4.	# | 
 | #									# | 
 | #	Step 3.	Calculate X - N*log2/64.				# | 
 | #		3.1	R := X + N*L1,					# | 
 | #				where L1 := single-precision(-log2/64).	# | 
 | #		3.2	R := R + N*L2,					# | 
 | #				L2 := extended-precision(-log2/64 - L1).# | 
 | #	Notes:	a) The way L1 and L2 are chosen ensures L1+L2		# | 
 | #		approximate the value -log2/64 to 88 bits of accuracy.	# | 
 | #		b) N*L1 is exact because N is no longer than 22 bits	# | 
 | #		and L1 is no longer than 24 bits.			# | 
 | #		c) The calculation X+N*L1 is also exact due to		# | 
 | #		cancellation. Thus, R is practically X+N(L1+L2) to full	# | 
 | #		64 bits.						# | 
 | #		d) It is important to estimate how large can |R| be	# | 
 | #		after Step 3.2.						# | 
 | #									# | 
 | #		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	# | 
 | #		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	# | 
 | #		X*64/log2 - N	=	f - eps*X 64/log2		# | 
 | #		X - N*log2/64	=	f*log2/64 - eps*X		# | 
 | #									# | 
 | #									# | 
 | #		Now |X| <= 16446 log2, thus				# | 
 | #									# | 
 | #			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	# | 
 | #					<= 0.57 log2/64.		# | 
 | #		 This bound will be used in Step 4.			# | 
 | #									# | 
 | #	Step 4.	Approximate exp(R)-1 by a polynomial			# | 
 | #		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	# | 
 | #	Notes:	a) In order to reduce memory access, the coefficients	# | 
 | #		are made as "short" as possible: A1 (which is 1/2), A4	# | 
 | #		and A5 are single precision; A2 and A3 are double	# | 
 | #		precision.						# | 
 | #		b) Even with the restrictions above,			# | 
 | #		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	# | 
 | #		Note that 0.0062 is slightly bigger than 0.57 log2/64.	# | 
 | #		c) To fully utilize the pipeline, p is separated into	# | 
 | #		two independent pieces of roughly equal complexities	# | 
 | #			p = [ R + R*S*(A2 + S*A4) ]	+		# | 
 | #				[ S*(A1 + S*(A3 + S*A5)) ]		# | 
 | #		where S = R*R.						# | 
 | #									# | 
 | #	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		# | 
 | #				ans := T + ( T*p + t)			# | 
 | #		where T and t are the stored values for 2^(J/64).	# | 
 | #	Notes:	2^(J/64) is stored as T and t where T+t approximates	# | 
 | #		2^(J/64) to roughly 85 bits; T is in extended precision	# | 
 | #		and t is in single precision. Note also that T is	# | 
 | #		rounded to 62 bits so that the last two bits of T are	# | 
 | #		zero. The reason for such a special form is that T-1,	# | 
 | #		T-2, and T-8 will all be exact --- a property that will	# | 
 | #		give much more accurate computation of the function	# | 
 | #		EXPM1.							# | 
 | #									# | 
 | #	Step 6.	Reconstruction of exp(X)				# | 
 | #			exp(X) = 2^M * 2^(J/64) * exp(R).		# | 
 | #		6.1	If AdjFlag = 0, go to 6.3			# | 
 | #		6.2	ans := ans * AdjScale				# | 
 | #		6.3	Restore the user FPCR				# | 
 | #		6.4	Return ans := ans * Scale. Exit.		# | 
 | #	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	# | 
 | #		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	# | 
 | #		neither overflow nor underflow. If AdjFlag = 1, that	# | 
 | #		means that						# | 
 | #			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	# | 
 | #		Hence, exp(X) may overflow or underflow or neither.	# | 
 | #		When that is the case, AdjScale = 2^(M1) where M1 is	# | 
 | #		approximately M. Thus 6.2 will never cause		# | 
 | #		over/underflow. Possible exception in 6.4 is overflow	# | 
 | #		or underflow. The inexact exception is not generated in	# | 
 | #		6.4. Although one can argue that the inexact flag	# | 
 | #		should always be raised, to simulate that exception	# | 
 | #		cost to much than the flag is worth in practical uses.	# | 
 | #									# | 
 | #	Step 7.	Return 1 + X.						# | 
 | #		7.1	ans := X					# | 
 | #		7.2	Restore user FPCR.				# | 
 | #		7.3	Return ans := 1 + ans. Exit			# | 
 | #	Notes:	For non-zero X, the inexact exception will always be	# | 
 | #		raised by 7.3. That is the only exception raised by 7.3.# | 
 | #		Note also that we use the FMOVEM instruction to move X	# | 
 | #		in Step 7.1 to avoid unnecessary trapping. (Although	# | 
 | #		the FMOVEM may not seem relevant since X is normalized,	# | 
 | #		the precaution will be useful in the library version of	# | 
 | #		this code where the separate entry for denormalized	# | 
 | #		inputs will be done away with.)				# | 
 | #									# | 
 | #	Step 8.	Handle exp(X) where |X| >= 16380log2.			# | 
 | #		8.1	If |X| > 16480 log2, go to Step 9.		# | 
 | #		(mimic 2.2 - 2.6)					# | 
 | #		8.2	N := round-to-integer( X * 64/log2 )		# | 
 | #		8.3	Calculate J = N mod 64, J = 0,1,...,63		# | 
 | #		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1,	# | 
 | #			AdjFlag := 1.					# | 
 | #		8.5	Calculate the address of the stored value	# | 
 | #			2^(J/64).					# | 
 | #		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	# | 
 | #		8.7	Go to Step 3.					# | 
 | #	Notes:	Refer to notes for 2.2 - 2.6.				# | 
 | #									# | 
 | #	Step 9.	Handle exp(X), |X| > 16480 log2.			# | 
 | #		9.1	If X < 0, go to 9.3				# | 
 | #		9.2	ans := Huge, go to 9.4				# | 
 | #		9.3	ans := Tiny.					# | 
 | #		9.4	Restore user FPCR.				# | 
 | #		9.5	Return ans := ans * ans. Exit.			# | 
 | #	Notes:	Exp(X) will surely overflow or underflow, depending on	# | 
 | #		X's sign. "Huge" and "Tiny" are respectively large/tiny	# | 
 | #		extended-precision numbers whose square over/underflow	# | 
 | #		with an inexact result. Thus, 9.5 always raises the	# | 
 | #		inexact together with either overflow or underflow.	# | 
 | #									# | 
 | #	setoxm1d							# | 
 | #	--------							# | 
 | #									# | 
 | #	Step 1.	Set ans := 0						# | 
 | #									# | 
 | #	Step 2.	Return	ans := X + ans. Exit.				# | 
 | #	Notes:	This will return X with the appropriate rounding	# | 
 | #		 precision prescribed by the user FPCR.			# | 
 | #									# | 
 | #	setoxm1								# | 
 | #	-------								# | 
 | #									# | 
 | #	Step 1.	Check |X|						# | 
 | #		1.1	If |X| >= 1/4, go to Step 1.3.			# | 
 | #		1.2	Go to Step 7.					# | 
 | #		1.3	If |X| < 70 log(2), go to Step 2.		# | 
 | #		1.4	Go to Step 10.					# | 
 | #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.# | 
 | #		However, it is conceivable |X| can be small very often	# | 
 | #		because EXPM1 is intended to evaluate exp(X)-1		# | 
 | #		accurately when |X| is small. For further details on	# | 
 | #		the comparisons, see the notes on Step 1 of setox.	# | 
 | #									# | 
 | #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	# | 
 | #		2.1	N := round-to-nearest-integer( X * 64/log2 ).	# | 
 | #		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., # | 
 | #			or 63.						# | 
 | #		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	# | 
 | #		2.4	Calculate the address of the stored value of	# | 
 | #			2^(J/64).					# | 
 | #		2.5	Create the values Sc = 2^M and			# | 
 | #			OnebySc := -2^(-M).				# | 
 | #	Notes:	See the notes on Step 2 of setox.			# | 
 | #									# | 
 | #	Step 3.	Calculate X - N*log2/64.				# | 
 | #		3.1	R := X + N*L1,					# | 
 | #				where L1 := single-precision(-log2/64).	# | 
 | #		3.2	R := R + N*L2,					# | 
 | #				L2 := extended-precision(-log2/64 - L1).# | 
 | #	Notes:	Applying the analysis of Step 3 of setox in this case	# | 
 | #		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	# | 
 | #		this case).						# | 
 | #									# | 
 | #	Step 4.	Approximate exp(R)-1 by a polynomial			# | 
 | #			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	# | 
 | #	Notes:	a) In order to reduce memory access, the coefficients	# | 
 | #		are made as "short" as possible: A1 (which is 1/2), A5	# | 
 | #		and A6 are single precision; A2, A3 and A4 are double	# | 
 | #		precision.						# | 
 | #		b) Even with the restriction above,			# | 
 | #			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		# | 
 | #		for all |R| <= 0.0055.					# | 
 | #		c) To fully utilize the pipeline, p is separated into	# | 
 | #		two independent pieces of roughly equal complexity	# | 
 | #			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	# | 
 | #				[ R + S*(A1 + S*(A3 + S*A5)) ]		# | 
 | #		where S = R*R.						# | 
 | #									# | 
 | #	Step 5.	Compute 2^(J/64)*p by					# | 
 | #				p := T*p				# | 
 | #		where T and t are the stored values for 2^(J/64).	# | 
 | #	Notes:	2^(J/64) is stored as T and t where T+t approximates	# | 
 | #		2^(J/64) to roughly 85 bits; T is in extended precision	# | 
 | #		and t is in single precision. Note also that T is	# | 
 | #		rounded to 62 bits so that the last two bits of T are	# | 
 | #		zero. The reason for such a special form is that T-1,	# | 
 | #		T-2, and T-8 will all be exact --- a property that will	# | 
 | #		be exploited in Step 6 below. The total relative error	# | 
 | #		in p is no bigger than 2^(-67.7) compared to the final	# | 
 | #		result.							# | 
 | #									# | 
 | #	Step 6.	Reconstruction of exp(X)-1				# | 
 | #			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	# | 
 | #		6.1	If M <= 63, go to Step 6.3.			# | 
 | #		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	# | 
 | #		6.3	If M >= -3, go to 6.5.				# | 
 | #		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	# | 
 | #		6.5	ans := (T + OnebySc) + (p + t).			# | 
 | #		6.6	Restore user FPCR.				# | 
 | #		6.7	Return ans := Sc * ans. Exit.			# | 
 | #	Notes:	The various arrangements of the expressions give	# | 
 | #		accurate evaluations.					# | 
 | #									# | 
 | #	Step 7.	exp(X)-1 for |X| < 1/4.					# | 
 | #		7.1	If |X| >= 2^(-65), go to Step 9.		# | 
 | #		7.2	Go to Step 8.					# | 
 | #									# | 
 | #	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			# | 
 | #		8.1	If |X| < 2^(-16312), goto 8.3			# | 
 | #		8.2	Restore FPCR; return ans := X - 2^(-16382).	# | 
 | #			Exit.						# | 
 | #		8.3	X := X * 2^(140).				# | 
 | #		8.4	Restore FPCR; ans := ans - 2^(-16382).		# | 
 | #		 Return ans := ans*2^(140). Exit			# | 
 | #	Notes:	The idea is to return "X - tiny" under the user		# | 
 | #		precision and rounding modes. To avoid unnecessary	# | 
 | #		inefficiency, we stay away from denormalized numbers	# | 
 | #		the best we can. For |X| >= 2^(-16312), the		# | 
 | #		straightforward 8.2 generates the inexact exception as	# | 
 | #		the case warrants.					# | 
 | #									# | 
 | #	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		# | 
 | #			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		# | 
 | #	Notes:	a) In order to reduce memory access, the coefficients	# | 
 | #		are made as "short" as possible: B1 (which is 1/2), B9	# | 
 | #		to B12 are single precision; B3 to B8 are double	# | 
 | #		precision; and B2 is double extended.			# | 
 | #		b) Even with the restriction above,			# | 
 | #			|p - (exp(X)-1)| < |X| 2^(-70.6)		# | 
 | #		for all |X| <= 0.251.					# | 
 | #		Note that 0.251 is slightly bigger than 1/4.		# | 
 | #		c) To fully preserve accuracy, the polynomial is	# | 
 | #		computed as						# | 
 | #			X + ( S*B1 +	Q ) where S = X*X and		# | 
 | #			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	# | 
 | #		d) To fully utilize the pipeline, Q is separated into	# | 
 | #		two independent pieces of roughly equal complexity	# | 
 | #			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	# | 
 | #				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	# | 
 | #									# | 
 | #	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		# | 
 | #		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all	# | 
 | #		practical purposes. Therefore, go to Step 1 of setox.	# | 
 | #		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	# | 
 | #		purposes.						# | 
 | #		ans := -1						# | 
 | #		Restore user FPCR					# | 
 | #		Return ans := ans + 2^(-126). Exit.			# | 
 | #	Notes:	10.2 will always create an inexact and return -1 + tiny	# | 
 | #		in the user rounding precision and mode.		# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | L2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000 | 
 |  | 
 | EEXPA3:	long		0x3FA55555,0x55554CC1 | 
 | EEXPA2:	long		0x3FC55555,0x55554A54 | 
 |  | 
 | EM1A4:	long		0x3F811111,0x11174385 | 
 | EM1A3:	long		0x3FA55555,0x55554F5A | 
 |  | 
 | EM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000 | 
 |  | 
 | EM1B8:	long		0x3EC71DE3,0xA5774682 | 
 | EM1B7:	long		0x3EFA01A0,0x19D7CB68 | 
 |  | 
 | EM1B6:	long		0x3F2A01A0,0x1A019DF3 | 
 | EM1B5:	long		0x3F56C16C,0x16C170E2 | 
 |  | 
 | EM1B4:	long		0x3F811111,0x11111111 | 
 | EM1B3:	long		0x3FA55555,0x55555555 | 
 |  | 
 | EM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB | 
 | 	long		0x00000000 | 
 |  | 
 | TWO140:	long		0x48B00000,0x00000000 | 
 | TWON140: | 
 | 	long		0x37300000,0x00000000 | 
 |  | 
 | EEXPTBL: | 
 | 	long		0x3FFF0000,0x80000000,0x00000000,0x00000000 | 
 | 	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B | 
 | 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9 | 
 | 	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369 | 
 | 	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C | 
 | 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F | 
 | 	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729 | 
 | 	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF | 
 | 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF | 
 | 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA | 
 | 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051 | 
 | 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029 | 
 | 	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494 | 
 | 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0 | 
 | 	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D | 
 | 	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537 | 
 | 	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD | 
 | 	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087 | 
 | 	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818 | 
 | 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D | 
 | 	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890 | 
 | 	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C | 
 | 	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05 | 
 | 	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126 | 
 | 	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140 | 
 | 	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA | 
 | 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A | 
 | 	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC | 
 | 	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC | 
 | 	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610 | 
 | 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90 | 
 | 	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A | 
 | 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13 | 
 | 	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30 | 
 | 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC | 
 | 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6 | 
 | 	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70 | 
 | 	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518 | 
 | 	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41 | 
 | 	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B | 
 | 	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568 | 
 | 	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E | 
 | 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03 | 
 | 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D | 
 | 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4 | 
 | 	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C | 
 | 	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9 | 
 | 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21 | 
 | 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F | 
 | 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F | 
 | 	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207 | 
 | 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175 | 
 | 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B | 
 | 	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5 | 
 | 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A | 
 | 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22 | 
 | 	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945 | 
 | 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B | 
 | 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3 | 
 | 	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05 | 
 | 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19 | 
 | 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5 | 
 | 	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22 | 
 | 	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A | 
 |  | 
 | 	set		ADJFLAG,L_SCR2 | 
 | 	set		SCALE,FP_SCR0 | 
 | 	set		ADJSCALE,FP_SCR1 | 
 | 	set		SC,FP_SCR0 | 
 | 	set		ONEBYSC,FP_SCR1 | 
 |  | 
 | 	global		setox | 
 | setox: | 
 | #--entry point for EXP(X), here X is finite, non-zero, and not NaN's | 
 |  | 
 | #--Step 1. | 
 | 	mov.l		(%a0),%d1		# load part of input X | 
 | 	and.l		&0x7FFF0000,%d1		# biased expo. of X | 
 | 	cmp.l		%d1,&0x3FBE0000		# 2^(-65) | 
 | 	bge.b		EXPC1			# normal case | 
 | 	bra		EXPSM | 
 |  | 
 | EXPC1: | 
 | #--The case |X| >= 2^(-65) | 
 | 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X| | 
 | 	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits | 
 | 	blt.b		EXPMAIN			# normal case | 
 | 	bra		EEXPBIG | 
 |  | 
 | EXPMAIN: | 
 | #--Step 2. | 
 | #--This is the normal branch:	2^(-65) <= |X| < 16380 log2. | 
 | 	fmov.x		(%a0),%fp0		# load input from (a0) | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X | 
 | 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3} | 
 | 	mov.l		&0,ADJFLAG(%a6) | 
 | 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 ) | 
 | 	lea		EEXPTBL(%pc),%a1 | 
 | 	fmov.l		%d1,%fp0		# convert to floating-format | 
 |  | 
 | 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily | 
 | 	and.l		&0x3F,%d1		# D0 is J = N mod 64 | 
 | 	lsl.l		&4,%d1 | 
 | 	add.l		%d1,%a1			# address of 2^(J/64) | 
 | 	mov.l		L_SCR1(%a6),%d1 | 
 | 	asr.l		&6,%d1			# D0 is M | 
 | 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M) | 
 | 	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB | 
 |  | 
 | EXPCONT1: | 
 | #--Step 3. | 
 | #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, | 
 | #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M) | 
 | 	fmov.x		%fp0,%fp2 | 
 | 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64) | 
 | 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64 | 
 | 	fadd.x		%fp1,%fp0		# X + N*L1 | 
 | 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg. | 
 |  | 
 | #--Step 4. | 
 | #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL | 
 | #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) | 
 | #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R | 
 | #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))] | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R | 
 |  | 
 | 	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# fp2 IS S*A5 | 
 | 	fmov.x		%fp1,%fp3 | 
 | 	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4 | 
 |  | 
 | 	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5 | 
 | 	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5) | 
 | 	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended | 
 | 	mov.l		&0x80000000,SCALE+4(%a6) | 
 | 	clr.l		SCALE+8(%a6) | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4) | 
 |  | 
 | 	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5) | 
 | 	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4) | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5)) | 
 | 	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4), | 
 |  | 
 | 	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64) | 
 | 	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1 | 
 |  | 
 | #--Step 5 | 
 | #--final reconstruction process | 
 | #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) ) | 
 |  | 
 | 	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1) | 
 | 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3} | 
 | 	fadd.s		(%a1),%fp0		# accurate 2^(J/64) | 
 |  | 
 | 	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*... | 
 | 	mov.l		ADJFLAG(%a6),%d1 | 
 |  | 
 | #--Step 6 | 
 | 	tst.l		%d1 | 
 | 	beq.b		NORMAL | 
 | ADJUST: | 
 | 	fmul.x		ADJSCALE(%a6),%fp0 | 
 | NORMAL: | 
 | 	fmov.l		%d0,%fpcr		# restore user FPCR | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M) | 
 | 	bra		t_catch | 
 |  | 
 | EXPSM: | 
 | #--Step 7 | 
 | 	fmovm.x		(%a0),&0x80		# load X | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.s		&0x3F800000,%fp0	# 1+X in user mode | 
 | 	bra		t_pinx2 | 
 |  | 
 | EEXPBIG: | 
 | #--Step 8 | 
 | 	cmp.l		%d1,&0x400CB27C		# 16480 log2 | 
 | 	bgt.b		EXP2BIG | 
 | #--Steps 8.2 -- 8.6 | 
 | 	fmov.x		(%a0),%fp0		# load input from (a0) | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X | 
 | 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3} | 
 | 	mov.l		&1,ADJFLAG(%a6) | 
 | 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 ) | 
 | 	lea		EEXPTBL(%pc),%a1 | 
 | 	fmov.l		%d1,%fp0		# convert to floating-format | 
 | 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily | 
 | 	and.l		&0x3F,%d1		# D0 is J = N mod 64 | 
 | 	lsl.l		&4,%d1 | 
 | 	add.l		%d1,%a1			# address of 2^(J/64) | 
 | 	mov.l		L_SCR1(%a6),%d1 | 
 | 	asr.l		&6,%d1			# D0 is K | 
 | 	mov.l		%d1,L_SCR1(%a6)		# save K temporarily | 
 | 	asr.l		&1,%d1			# D0 is M1 | 
 | 	sub.l		%d1,L_SCR1(%a6)		# a1 is M | 
 | 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1) | 
 | 	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1) | 
 | 	mov.l		&0x80000000,ADJSCALE+4(%a6) | 
 | 	clr.l		ADJSCALE+8(%a6) | 
 | 	mov.l		L_SCR1(%a6),%d1		# D0 is M | 
 | 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M) | 
 | 	bra.w		EXPCONT1		# go back to Step 3 | 
 |  | 
 | EXP2BIG: | 
 | #--Step 9 | 
 | 	tst.b		(%a0)			# is X positive or negative? | 
 | 	bmi		t_unfl2 | 
 | 	bra		t_ovfl2 | 
 |  | 
 | 	global		setoxd | 
 | setoxd: | 
 | #--entry point for EXP(X), X is denormalized | 
 | 	mov.l		(%a0),-(%sp) | 
 | 	andi.l		&0x80000000,(%sp) | 
 | 	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126) | 
 |  | 
 | 	fmov.s		&0x3F800000,%fp0 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.s		(%sp)+,%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | 	global		setoxm1 | 
 | setoxm1: | 
 | #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN | 
 |  | 
 | #--Step 1. | 
 | #--Step 1.1 | 
 | 	mov.l		(%a0),%d1		# load part of input X | 
 | 	and.l		&0x7FFF0000,%d1		# biased expo. of X | 
 | 	cmp.l		%d1,&0x3FFD0000		# 1/4 | 
 | 	bge.b		EM1CON1			# |X| >= 1/4 | 
 | 	bra		EM1SM | 
 |  | 
 | EM1CON1: | 
 | #--Step 1.3 | 
 | #--The case |X| >= 1/4 | 
 | 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X| | 
 | 	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits | 
 | 	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2 | 
 | 	bra		EM1BIG | 
 |  | 
 | EM1MAIN: | 
 | #--Step 2. | 
 | #--This is the case:	1/4 <= |X| <= 70 log2. | 
 | 	fmov.x		(%a0),%fp0		# load input from (a0) | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X | 
 | 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3} | 
 | 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 ) | 
 | 	lea		EEXPTBL(%pc),%a1 | 
 | 	fmov.l		%d1,%fp0		# convert to floating-format | 
 |  | 
 | 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily | 
 | 	and.l		&0x3F,%d1		# D0 is J = N mod 64 | 
 | 	lsl.l		&4,%d1 | 
 | 	add.l		%d1,%a1			# address of 2^(J/64) | 
 | 	mov.l		L_SCR1(%a6),%d1 | 
 | 	asr.l		&6,%d1			# D0 is M | 
 | 	mov.l		%d1,L_SCR1(%a6)		# save a copy of M | 
 |  | 
 | #--Step 3. | 
 | #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, | 
 | #--a0 points to 2^(J/64), D0 and a1 both contain M | 
 | 	fmov.x		%fp0,%fp2 | 
 | 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64) | 
 | 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64 | 
 | 	fadd.x		%fp1,%fp0		# X + N*L1 | 
 | 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg. | 
 | 	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M | 
 |  | 
 | #--Step 4. | 
 | #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL | 
 | #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6))))) | 
 | #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R | 
 | #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))] | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R | 
 |  | 
 | 	fmov.s		&0x3950097B,%fp2	# fp2 IS a6 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# fp2 IS S*A6 | 
 | 	fmov.x		%fp1,%fp3 | 
 | 	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5 | 
 |  | 
 | 	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6 | 
 | 	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5 | 
 | 	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended | 
 | 	mov.l		&0x80000000,SC+4(%a6) | 
 | 	clr.l		SC+8(%a6) | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6) | 
 | 	mov.l		L_SCR1(%a6),%d1		# D0 is	M | 
 | 	neg.w		%d1			# D0 is -M | 
 | 	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5) | 
 | 	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M) | 
 | 	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6) | 
 | 	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5) | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6)) | 
 | 	or.w		&0x8000,%d1		# signed/expo. of -2^(-M) | 
 | 	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M) | 
 | 	mov.l		&0x80000000,ONEBYSC+4(%a6) | 
 | 	clr.l		ONEBYSC+8(%a6) | 
 | 	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5)) | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6)) | 
 | 	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5)) | 
 |  | 
 | 	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1 | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3} | 
 |  | 
 | #--Step 5 | 
 | #--Compute 2^(J/64)*p | 
 |  | 
 | 	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1) | 
 |  | 
 | #--Step 6 | 
 | #--Step 6.1 | 
 | 	mov.l		L_SCR1(%a6),%d1		# retrieve M | 
 | 	cmp.l		%d1,&63 | 
 | 	ble.b		MLE63 | 
 | #--Step 6.2	M >= 64 | 
 | 	fmov.s		12(%a1),%fp1		# fp1 is t | 
 | 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc | 
 | 	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released | 
 | 	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc)) | 
 | 	bra		EM1SCALE | 
 | MLE63: | 
 | #--Step 6.3	M <= 63 | 
 | 	cmp.l		%d1,&-3 | 
 | 	bge.b		MGEN3 | 
 | MLTN3: | 
 | #--Step 6.4	M <= -4 | 
 | 	fadd.s		12(%a1),%fp0		# p+t | 
 | 	fadd.x		(%a1),%fp0		# T+(p+t) | 
 | 	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t)) | 
 | 	bra		EM1SCALE | 
 | MGEN3: | 
 | #--Step 6.5	-3 <= M <= 63 | 
 | 	fmov.x		(%a1)+,%fp1		# fp1 is T | 
 | 	fadd.s		(%a1),%fp0		# fp0 is p+t | 
 | 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc | 
 | 	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t) | 
 |  | 
 | EM1SCALE: | 
 | #--Step 6.6 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fmul.x		SC(%a6),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | EM1SM: | 
 | #--Step 7	|X| < 1/4. | 
 | 	cmp.l		%d1,&0x3FBE0000		# 2^(-65) | 
 | 	bge.b		EM1POLY | 
 |  | 
 | EM1TINY: | 
 | #--Step 8	|X| < 2^(-65) | 
 | 	cmp.l		%d1,&0x00330000		# 2^(-16312) | 
 | 	blt.b		EM12TINY | 
 | #--Step 8.2 | 
 | 	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382) | 
 | 	mov.l		&0x80000000,SC+4(%a6) | 
 | 	clr.l		SC+8(%a6) | 
 | 	fmov.x		(%a0),%fp0 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FADD_OP,%d1		# last inst is ADD | 
 | 	fadd.x		SC(%a6),%fp0 | 
 | 	bra		t_catch | 
 |  | 
 | EM12TINY: | 
 | #--Step 8.3 | 
 | 	fmov.x		(%a0),%fp0 | 
 | 	fmul.d		TWO140(%pc),%fp0 | 
 | 	mov.l		&0x80010000,SC(%a6) | 
 | 	mov.l		&0x80000000,SC+4(%a6) | 
 | 	clr.l		SC+8(%a6) | 
 | 	fadd.x		SC(%a6),%fp0 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.d		TWON140(%pc),%fp0 | 
 | 	bra		t_catch | 
 |  | 
 | EM1POLY: | 
 | #--Step 9	exp(X)-1 by a simple polynomial | 
 | 	fmov.x		(%a0),%fp0		# fp0 is X | 
 | 	fmul.x		%fp0,%fp0		# fp0 is S := X*X | 
 | 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3} | 
 | 	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12 | 
 | 	fmul.x		%fp0,%fp1		# fp1 is S*B12 | 
 | 	fmov.s		&0x310F8290,%fp2	# fp2 is B11 | 
 | 	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12 | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 is S*B11 | 
 | 	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ... | 
 |  | 
 | 	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*... | 
 | 	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*... | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 is S*(B9+... | 
 | 	fmul.x		%fp0,%fp1		# fp1 is S*(B8+... | 
 |  | 
 | 	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*... | 
 | 	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*... | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 is S*(B7+... | 
 | 	fmul.x		%fp0,%fp1		# fp1 is S*(B6+... | 
 |  | 
 | 	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*... | 
 | 	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*... | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 is S*(B5+... | 
 | 	fmul.x		%fp0,%fp1		# fp1 is S*(B4+... | 
 |  | 
 | 	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*... | 
 | 	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*... | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 is S*(B3+... | 
 | 	fmul.x		%fp0,%fp1		# fp1 is S*(B2+... | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...) | 
 | 	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2... | 
 |  | 
 | 	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1 | 
 | 	fadd.x		%fp2,%fp1		# fp1 is Q | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3} | 
 |  | 
 | 	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.x		(%a0),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | EM1BIG: | 
 | #--Step 10	|X| > 70 log2 | 
 | 	mov.l		(%a0),%d1 | 
 | 	cmp.l		%d1,&0 | 
 | 	bgt.w		EXPC1 | 
 | #--Step 10.2 | 
 | 	fmov.s		&0xBF800000,%fp0	# fp0 is -1 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126) | 
 | 	bra		t_minx2 | 
 |  | 
 | 	global		setoxm1d | 
 | setoxm1d: | 
 | #--entry point for EXPM1(X), here X is denormalized | 
 | #--Step 0. | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # sgetexp():  returns the exponent portion of the input argument.	# | 
 | #	      The exponent bias is removed and the exponent value is	# | 
 | #	      returned as an extended precision number in fp0.		# | 
 | # sgetexpd(): handles denormalized numbers.				# | 
 | #									# | 
 | # sgetman():  extracts the mantissa of the input argument. The		# | 
 | #	      mantissa is converted to an extended precision number w/	# | 
 | #	      an exponent of $3fff and is returned in fp0. The range of # | 
 | #	      the result is [1.0 - 2.0).				# | 
 | # sgetmand(): handles denormalized numbers.				# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0  = pointer to extended precision input			# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = exponent(X) or mantissa(X)				# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		sgetexp | 
 | sgetexp: | 
 | 	mov.w		SRC_EX(%a0),%d0		# get the exponent | 
 | 	bclr		&0xf,%d0		# clear the sign bit | 
 | 	subi.w		&0x3fff,%d0		# subtract off the bias | 
 | 	fmov.w		%d0,%fp0		# return exp in fp0 | 
 | 	blt.b		sgetexpn		# it's negative | 
 | 	rts | 
 |  | 
 | sgetexpn: | 
 | 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit | 
 | 	rts | 
 |  | 
 | 	global		sgetexpd | 
 | sgetexpd: | 
 | 	bsr.l		norm			# normalize | 
 | 	neg.w		%d0			# new exp = -(shft amt) | 
 | 	subi.w		&0x3fff,%d0		# subtract off the bias | 
 | 	fmov.w		%d0,%fp0		# return exp in fp0 | 
 | 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit | 
 | 	rts | 
 |  | 
 | 	global		sgetman | 
 | sgetman: | 
 | 	mov.w		SRC_EX(%a0),%d0		# get the exp | 
 | 	ori.w		&0x7fff,%d0		# clear old exp | 
 | 	bclr		&0xe,%d0		# make it the new exp +-3fff | 
 |  | 
 | # here, we build the result in a tmp location so as not to disturb the input | 
 | 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc | 
 | 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc | 
 | 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent | 
 | 	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0 | 
 | 	bmi.b		sgetmann		# it's negative | 
 | 	rts | 
 |  | 
 | sgetmann: | 
 | 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit | 
 | 	rts | 
 |  | 
 | # | 
 | # For denormalized numbers, shift the mantissa until the j-bit = 1, | 
 | # then load the exponent with +/1 $3fff. | 
 | # | 
 | 	global		sgetmand | 
 | sgetmand: | 
 | 	bsr.l		norm			# normalize exponent | 
 | 	bra.b		sgetman | 
 |  | 
 | ######################################################################### | 
 | # scosh():  computes the hyperbolic cosine of a normalized input	# | 
 | # scoshd(): computes the hyperbolic cosine of a denormalized input	# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = cosh(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 3 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #	COSH								# | 
 | #	1. If |X| > 16380 log2, go to 3.				# | 
 | #									# | 
 | #	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	# | 
 | #		y = |X|, z = exp(Y), and				# | 
 | #		cosh(X) = (1/2)*( z + 1/z ).				# | 
 | #		Exit.							# | 
 | #									# | 
 | #	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		# | 
 | #									# | 
 | #	4. (16380 log2 < |X| <= 16480 log2)				# | 
 | #		cosh(X) = sign(X) * exp(|X|)/2.				# | 
 | #		However, invoking exp(|X|) may cause premature		# | 
 | #		overflow. Thus, we calculate sinh(X) as follows:	# | 
 | #		Y	:= |X|						# | 
 | #		Fact	:=	2**(16380)				# | 
 | #		Y'	:= Y - 16381 log2				# | 
 | #		cosh(X) := Fact * exp(Y').				# | 
 | #		Exit.							# | 
 | #									# | 
 | #	5. (|X| > 16480 log2) sinh(X) must overflow. Return		# | 
 | #		Huge*Huge to generate overflow and an infinity with	# | 
 | #		the appropriate sign. Huge is the largest finite number	# | 
 | #		in extended format. Exit.				# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | TWO16380: | 
 | 	long		0x7FFB0000,0x80000000,0x00000000,0x00000000 | 
 |  | 
 | 	global		scosh | 
 | scosh: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	cmp.l		%d1,&0x400CB167 | 
 | 	bgt.b		COSHBIG | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 | 
 | #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) ) | 
 |  | 
 | 	fabs.x		%fp0			# |X| | 
 |  | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	fmovm.x		&0x01,-(%sp)		# save |X| to stack | 
 | 	lea		(%sp),%a0		# pass ptr to |X| | 
 | 	bsr		setox			# FP0 IS EXP(|X|) | 
 | 	add.l		&0xc,%sp		# erase |X| from stack | 
 | 	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|) | 
 | 	mov.l		(%sp)+,%d0 | 
 |  | 
 | 	fmov.s		&0x3E800000,%fp1	# (1/4) | 
 | 	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|)) | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FADD_OP,%d1		# last inst is ADD | 
 | 	fadd.x		%fp1,%fp0 | 
 | 	bra		t_catch | 
 |  | 
 | COSHBIG: | 
 | 	cmp.l		%d1,&0x400CB2B3 | 
 | 	bgt.b		COSHHUGE | 
 |  | 
 | 	fabs.x		%fp0 | 
 | 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD) | 
 | 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE | 
 |  | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	fmovm.x		&0x01,-(%sp)		# save fp0 to stack | 
 | 	lea		(%sp),%a0		# pass ptr to fp0 | 
 | 	bsr		setox | 
 | 	add.l		&0xc,%sp		# clear fp0 from stack | 
 | 	mov.l		(%sp)+,%d0 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.x		TWO16380(%pc),%fp0 | 
 | 	bra		t_catch | 
 |  | 
 | COSHHUGE: | 
 | 	bra		t_ovfl2 | 
 |  | 
 | 	global		scoshd | 
 | #--COSH(X) = 1 FOR DENORMALIZED X | 
 | scoshd: | 
 | 	fmov.s		&0x3F800000,%fp0 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.s		&0x00800000,%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | ######################################################################### | 
 | # ssinh():  computes the hyperbolic sine of a normalized input		# | 
 | # ssinhd(): computes the hyperbolic sine of a denormalized input	# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 = sinh(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 3 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently # | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM *********************************************************** # | 
 | #									# | 
 | #       SINH								# | 
 | #       1. If |X| > 16380 log2, go to 3.				# | 
 | #									# | 
 | #       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	# | 
 | #               y = |X|, sgn = sign(X), and z = expm1(Y),		# | 
 | #               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			# | 
 | #          Exit.							# | 
 | #									# | 
 | #       3. If |X| > 16480 log2, go to 5.				# | 
 | #									# | 
 | #       4. (16380 log2 < |X| <= 16480 log2)				# | 
 | #               sinh(X) = sign(X) * exp(|X|)/2.				# | 
 | #          However, invoking exp(|X|) may cause premature overflow.	# | 
 | #          Thus, we calculate sinh(X) as follows:			# | 
 | #             Y       := |X|						# | 
 | #             sgn     := sign(X)					# | 
 | #             sgnFact := sgn * 2**(16380)				# | 
 | #             Y'      := Y - 16381 log2					# | 
 | #             sinh(X) := sgnFact * exp(Y').				# | 
 | #          Exit.							# | 
 | #									# | 
 | #       5. (|X| > 16480 log2) sinh(X) must overflow. Return		# | 
 | #          sign(X)*Huge*Huge to generate overflow and an infinity with	# | 
 | #          the appropriate sign. Huge is the largest finite number in	# | 
 | #          extended format. Exit.					# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		ssinh | 
 | ssinh: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	mov.l		%d1,%a1			# save (compacted) operand | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	cmp.l		%d1,&0x400CB167 | 
 | 	bgt.b		SINHBIG | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 | 
 | #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) ) | 
 |  | 
 | 	fabs.x		%fp0			# Y = |X| | 
 |  | 
 | 	movm.l		&0x8040,-(%sp)		# {a1/d0} | 
 | 	fmovm.x		&0x01,-(%sp)		# save Y on stack | 
 | 	lea		(%sp),%a0		# pass ptr to Y | 
 | 	clr.l		%d0 | 
 | 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y) | 
 | 	add.l		&0xc,%sp		# clear Y from stack | 
 | 	fmov.l		&0,%fpcr | 
 | 	movm.l		(%sp)+,&0x0201		# {a1/d0} | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fadd.s		&0x3F800000,%fp1	# 1+Z | 
 | 	fmov.x		%fp0,-(%sp) | 
 | 	fdiv.x		%fp1,%fp0		# Z/(1+Z) | 
 | 	mov.l		%a1,%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | 	or.l		&0x3F000000,%d1 | 
 | 	fadd.x		(%sp)+,%fp0 | 
 | 	mov.l		%d1,-(%sp) | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set | 
 | 	bra		t_catch | 
 |  | 
 | SINHBIG: | 
 | 	cmp.l		%d1,&0x400CB2B3 | 
 | 	bgt		t_ovfl | 
 | 	fabs.x		%fp0 | 
 | 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD) | 
 | 	mov.l		&0,-(%sp) | 
 | 	mov.l		&0x80000000,-(%sp) | 
 | 	mov.l		%a1,%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | 	or.l		&0x7FFB0000,%d1 | 
 | 	mov.l		%d1,-(%sp)		# EXTENDED FMT | 
 | 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE | 
 |  | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	fmovm.x		&0x01,-(%sp)		# save fp0 on stack | 
 | 	lea		(%sp),%a0		# pass ptr to fp0 | 
 | 	bsr		setox | 
 | 	add.l		&0xc,%sp		# clear fp0 from stack | 
 |  | 
 | 	mov.l		(%sp)+,%d0 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.x		(%sp)+,%fp0		# possible exception | 
 | 	bra		t_catch | 
 |  | 
 | 	global		ssinhd | 
 | #--SINH(X) = X FOR DENORMALIZED X | 
 | ssinhd: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # stanh():  computes the hyperbolic tangent of a normalized input	# | 
 | # stanhd(): computes the hyperbolic tangent of a denormalized input	# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = tanh(X)							# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 3 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently # | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #	TANH								# | 
 | #	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		# | 
 | #									# | 
 | #	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		# | 
 | #		sgn := sign(X), y := 2|X|, z := expm1(Y), and		# | 
 | #		tanh(X) = sgn*( z/(2+z) ).				# | 
 | #		Exit.							# | 
 | #									# | 
 | #	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		# | 
 | #		go to 7.						# | 
 | #									# | 
 | #	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		# | 
 | #									# | 
 | #	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		# | 
 | #		sgn := sign(X), y := 2|X|, z := exp(Y),			# | 
 | #		tanh(X) = sgn - [ sgn*2/(1+z) ].			# | 
 | #		Exit.							# | 
 | #									# | 
 | #	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	# | 
 | #		calculate Tanh(X) by					# | 
 | #		sgn := sign(X), Tiny := 2**(-126),			# | 
 | #		tanh(X) := sgn - sgn*Tiny.				# | 
 | #		Exit.							# | 
 | #									# | 
 | #	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	set		X,FP_SCR0 | 
 | 	set		XFRAC,X+4 | 
 |  | 
 | 	set		SGN,L_SCR3 | 
 |  | 
 | 	set		V,FP_SCR0 | 
 |  | 
 | 	global		stanh | 
 | stanh: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 |  | 
 | 	fmov.x		%fp0,X(%a6) | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	mov.l		%d1,X(%a6) | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)? | 
 | 	blt.w		TANHBORS		# yes | 
 | 	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2? | 
 | 	bgt.w		TANHBORS		# yes | 
 |  | 
 | #--THIS IS THE USUAL CASE | 
 | #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2). | 
 |  | 
 | 	mov.l		X(%a6),%d1 | 
 | 	mov.l		%d1,SGN(%a6) | 
 | 	and.l		&0x7FFF0000,%d1 | 
 | 	add.l		&0x00010000,%d1		# EXPONENT OF 2|X| | 
 | 	mov.l		%d1,X(%a6) | 
 | 	and.l		&0x80000000,SGN(%a6) | 
 | 	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X| | 
 |  | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	fmovm.x		&0x1,-(%sp)		# save Y on stack | 
 | 	lea		(%sp),%a0		# pass ptr to Y | 
 | 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y) | 
 | 	add.l		&0xc,%sp		# clear Y from stack | 
 | 	mov.l		(%sp)+,%d0 | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fadd.s		&0x40000000,%fp1	# Z+2 | 
 | 	mov.l		SGN(%a6),%d1 | 
 | 	fmov.x		%fp1,V(%a6) | 
 | 	eor.l		%d1,V(%a6) | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round prec,mode | 
 | 	fdiv.x		V(%a6),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | TANHBORS: | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	blt.w		TANHSM | 
 |  | 
 | 	cmp.l		%d1,&0x40048AA1 | 
 | 	bgt.w		TANHHUGE | 
 |  | 
 | #-- (5/2) LOG2 < |X| < 50 LOG2, | 
 | #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X), | 
 | #--TANH(X) = SGN -	SGN*2/[EXP(Y)+1]. | 
 |  | 
 | 	mov.l		X(%a6),%d1 | 
 | 	mov.l		%d1,SGN(%a6) | 
 | 	and.l		&0x7FFF0000,%d1 | 
 | 	add.l		&0x00010000,%d1		# EXPO OF 2|X| | 
 | 	mov.l		%d1,X(%a6)		# Y = 2|X| | 
 | 	and.l		&0x80000000,SGN(%a6) | 
 | 	mov.l		SGN(%a6),%d1 | 
 | 	fmov.x		X(%a6),%fp0		# Y = 2|X| | 
 |  | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	fmovm.x		&0x01,-(%sp)		# save Y on stack | 
 | 	lea		(%sp),%a0		# pass ptr to Y | 
 | 	bsr		setox			# FP0 IS EXP(Y) | 
 | 	add.l		&0xc,%sp		# clear Y from stack | 
 | 	mov.l		(%sp)+,%d0 | 
 | 	mov.l		SGN(%a6),%d1 | 
 | 	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1 | 
 |  | 
 | 	eor.l		&0xC0000000,%d1		# -SIGN(X)*2 | 
 | 	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT | 
 | 	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ] | 
 |  | 
 | 	mov.l		SGN(%a6),%d1 | 
 | 	or.l		&0x3F800000,%d1		# SGN | 
 | 	fmov.s		%d1,%fp0		# SGN IN SGL FMT | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round prec,mode | 
 | 	mov.b		&FADD_OP,%d1		# last inst is ADD | 
 | 	fadd.x		%fp1,%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | TANHSM: | 
 | 	fmov.l		%d0,%fpcr		# restore users round prec,mode | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		X(%a6),%fp0		# last inst - possible exception set | 
 | 	bra		t_catch | 
 |  | 
 | #---RETURN SGN(X) - SGN(X)EPS | 
 | TANHHUGE: | 
 | 	mov.l		X(%a6),%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | 	or.l		&0x3F800000,%d1 | 
 | 	fmov.s		%d1,%fp0 | 
 | 	and.l		&0x80000000,%d1 | 
 | 	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round prec,mode | 
 | 	fadd.s		%d1,%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | 	global		stanhd | 
 | #--TANH(X) = X FOR DENORMALIZED X | 
 | stanhd: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # slogn():    computes the natural logarithm of a normalized input	# | 
 | # slognd():   computes the natural logarithm of a denormalized input	# | 
 | # slognp1():  computes the log(1+X) of a normalized input		# | 
 | # slognp1d(): computes the log(1+X) of a denormalized input		# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = log(X) or log(1+X)					# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 2 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	LOGN:								# | 
 | #	Step 1. If |X-1| < 1/16, approximate log(X) by an odd		# | 
 | #		polynomial in u, where u = 2(X-1)/(X+1). Otherwise,	# | 
 | #		move on to Step 2.					# | 
 | #									# | 
 | #	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	# | 
 | #		seven significant bits of Y plus 2**(-7), i.e.		# | 
 | #		F = 1.xxxxxx1 in base 2 where the six "x" match those	# | 
 | #		of Y. Note that |Y-F| <= 2**(-7).			# | 
 | #									# | 
 | #	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a		# | 
 | #		polynomial in u, log(1+u) = poly.			# | 
 | #									# | 
 | #	Step 4. Reconstruct						# | 
 | #		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	# | 
 | #		by k*log(2) + (log(F) + poly). The values of log(F) are	# | 
 | #		calculated beforehand and stored in the program.	# | 
 | #									# | 
 | #	lognp1:								# | 
 | #	Step 1: If |X| < 1/16, approximate log(1+X) by an odd		# | 
 | #		polynomial in u where u = 2X/(2+X). Otherwise, move on	# | 
 | #		to Step 2.						# | 
 | #									# | 
 | #	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	# | 
 | #		in Step 2 of the algorithm for LOGN and compute		# | 
 | #		log(1+X) as k*log(2) + log(F) + poly where poly		# | 
 | #		approximates log(1+u), u = (Y-F)/F.			# | 
 | #									# | 
 | #	Implementation Notes:						# | 
 | #	Note 1. There are 64 different possible values for F, thus 64	# | 
 | #		log(F)'s need to be tabulated. Moreover, the values of	# | 
 | #		1/F are also tabulated so that the division in (Y-F)/F	# | 
 | #		can be performed by a multiplication.			# | 
 | #									# | 
 | #	Note 2. In Step 2 of lognp1, in order to preserved accuracy,	# | 
 | #		the value Y-F has to be calculated carefully when	# | 
 | #		1/2 <= X < 3/2.						# | 
 | #									# | 
 | #	Note 3. To fully exploit the pipeline, polynomials are usually	# | 
 | #		separated into two parts evaluated independently before	# | 
 | #		being added up.						# | 
 | #									# | 
 | ######################################################################### | 
 | LOGOF2: | 
 | 	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 | 
 |  | 
 | one: | 
 | 	long		0x3F800000 | 
 | zero: | 
 | 	long		0x00000000 | 
 | infty: | 
 | 	long		0x7F800000 | 
 | negone: | 
 | 	long		0xBF800000 | 
 |  | 
 | LOGA6: | 
 | 	long		0x3FC2499A,0xB5E4040B | 
 | LOGA5: | 
 | 	long		0xBFC555B5,0x848CB7DB | 
 |  | 
 | LOGA4: | 
 | 	long		0x3FC99999,0x987D8730 | 
 | LOGA3: | 
 | 	long		0xBFCFFFFF,0xFF6F7E97 | 
 |  | 
 | LOGA2: | 
 | 	long		0x3FD55555,0x555555A4 | 
 | LOGA1: | 
 | 	long		0xBFE00000,0x00000008 | 
 |  | 
 | LOGB5: | 
 | 	long		0x3F175496,0xADD7DAD6 | 
 | LOGB4: | 
 | 	long		0x3F3C71C2,0xFE80C7E0 | 
 |  | 
 | LOGB3: | 
 | 	long		0x3F624924,0x928BCCFF | 
 | LOGB2: | 
 | 	long		0x3F899999,0x999995EC | 
 |  | 
 | LOGB1: | 
 | 	long		0x3FB55555,0x55555555 | 
 | TWO: | 
 | 	long		0x40000000,0x00000000 | 
 |  | 
 | LTHOLD: | 
 | 	long		0x3f990000,0x80000000,0x00000000,0x00000000 | 
 |  | 
 | LOGTBL: | 
 | 	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000 | 
 | 	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000 | 
 | 	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000 | 
 | 	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000 | 
 | 	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000 | 
 | 	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000 | 
 | 	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000 | 
 | 	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000 | 
 | 	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000 | 
 | 	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000 | 
 | 	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000 | 
 | 	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000 | 
 | 	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000 | 
 | 	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000 | 
 | 	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000 | 
 | 	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000 | 
 | 	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000 | 
 | 	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000 | 
 | 	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000 | 
 | 	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000 | 
 | 	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000 | 
 | 	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000 | 
 | 	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000 | 
 | 	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000 | 
 | 	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000 | 
 | 	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000 | 
 | 	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000 | 
 | 	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000 | 
 | 	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000 | 
 | 	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000 | 
 | 	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000 | 
 | 	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000 | 
 | 	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000 | 
 | 	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000 | 
 | 	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000 | 
 | 	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000 | 
 | 	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000 | 
 | 	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000 | 
 | 	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000 | 
 | 	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000 | 
 | 	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000 | 
 | 	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000 | 
 | 	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000 | 
 | 	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000 | 
 | 	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000 | 
 | 	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000 | 
 | 	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000 | 
 | 	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000 | 
 | 	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000 | 
 | 	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000 | 
 | 	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000 | 
 | 	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000 | 
 | 	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000 | 
 | 	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000 | 
 | 	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000 | 
 | 	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000 | 
 | 	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000 | 
 | 	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000 | 
 | 	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000 | 
 | 	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000 | 
 | 	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000 | 
 | 	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000 | 
 | 	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000 | 
 | 	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000 | 
 | 	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000 | 
 | 	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000 | 
 | 	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000 | 
 | 	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000 | 
 | 	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000 | 
 | 	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000 | 
 | 	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000 | 
 | 	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000 | 
 | 	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000 | 
 | 	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000 | 
 | 	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000 | 
 | 	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000 | 
 | 	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000 | 
 | 	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000 | 
 | 	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000 | 
 | 	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000 | 
 | 	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000 | 
 | 	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000 | 
 | 	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000 | 
 | 	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000 | 
 | 	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000 | 
 | 	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000 | 
 | 	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000 | 
 | 	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000 | 
 | 	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000 | 
 | 	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000 | 
 | 	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000 | 
 | 	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000 | 
 | 	long		0x3FFE0000,0x94458094,0x45809446,0x00000000 | 
 | 	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000 | 
 | 	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000 | 
 | 	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000 | 
 | 	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000 | 
 | 	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000 | 
 | 	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000 | 
 | 	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000 | 
 | 	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000 | 
 | 	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000 | 
 | 	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000 | 
 | 	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000 | 
 | 	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000 | 
 | 	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000 | 
 | 	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000 | 
 | 	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000 | 
 | 	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000 | 
 | 	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000 | 
 | 	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000 | 
 | 	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000 | 
 | 	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000 | 
 | 	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000 | 
 | 	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000 | 
 | 	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000 | 
 | 	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000 | 
 | 	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000 | 
 | 	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000 | 
 | 	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000 | 
 | 	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000 | 
 | 	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000 | 
 | 	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000 | 
 | 	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000 | 
 | 	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000 | 
 | 	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000 | 
 | 	long		0x3FFE0000,0x80808080,0x80808081,0x00000000 | 
 | 	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000 | 
 |  | 
 | 	set		ADJK,L_SCR1 | 
 |  | 
 | 	set		X,FP_SCR0 | 
 | 	set		XDCARE,X+2 | 
 | 	set		XFRAC,X+4 | 
 |  | 
 | 	set		F,FP_SCR1 | 
 | 	set		FFRAC,F+4 | 
 |  | 
 | 	set		KLOG2,FP_SCR0 | 
 |  | 
 | 	set		SAVEU,FP_SCR0 | 
 |  | 
 | 	global		slogn | 
 | #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S | 
 | slogn: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 | 	mov.l		&0x00000000,ADJK(%a6) | 
 |  | 
 | LOGBGN: | 
 | #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS | 
 | #--A FINITE, NON-ZERO, NORMALIZED NUMBER. | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 |  | 
 | 	mov.l		(%a0),X(%a6) | 
 | 	mov.l		4(%a0),X+4(%a6) | 
 | 	mov.l		8(%a0),X+8(%a6) | 
 |  | 
 | 	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE | 
 | 	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID | 
 | # X IS POSITIVE, CHECK IF X IS NEAR 1 | 
 | 	cmp.l		%d1,&0x3ffef07d		# IS X < 15/16? | 
 | 	blt.b		LOGMAIN			# YES | 
 | 	cmp.l		%d1,&0x3fff8841		# IS X > 17/16? | 
 | 	ble.w		LOGNEAR1		# NO | 
 |  | 
 | LOGMAIN: | 
 | #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1 | 
 |  | 
 | #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY. | 
 | #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1. | 
 | #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y) | 
 | #--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F). | 
 | #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING | 
 | #--LOG(1+U) CAN BE VERY EFFICIENT. | 
 | #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO | 
 | #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F. | 
 |  | 
 | #--GET K, Y, F, AND ADDRESS OF 1/F. | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X | 
 | 	sub.l		&0x3FFF,%d1		# THIS IS K | 
 | 	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM. | 
 | 	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F) | 
 | 	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT | 
 |  | 
 | #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F | 
 | 	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X | 
 | 	mov.l		XFRAC(%a6),FFRAC(%a6) | 
 | 	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y | 
 | 	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT | 
 | 	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F | 
 | 	and.l		&0x7E000000,%d1 | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT | 
 | 	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F | 
 |  | 
 | 	fmov.x		X(%a6),%fp0 | 
 | 	mov.l		&0x3fff0000,F(%a6) | 
 | 	clr.l		F+8(%a6) | 
 | 	fsub.x		F(%a6),%fp0		# Y-F | 
 | 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY | 
 | #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K | 
 | #--REGISTERS SAVED: FPCR, FP1, FP2 | 
 |  | 
 | LP1CONT1: | 
 | #--AN RE-ENTRY POINT FOR LOGNP1 | 
 | 	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F | 
 | 	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY | 
 | 	fmov.x		%fp0,%fp2 | 
 | 	fmul.x		%fp2,%fp2		# FP2 IS V=U*U | 
 | 	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1 | 
 |  | 
 | #--LOG(1+U) IS APPROXIMATED BY | 
 | #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS | 
 | #--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))] | 
 |  | 
 | 	fmov.x		%fp2,%fp3 | 
 | 	fmov.x		%fp2,%fp1 | 
 |  | 
 | 	fmul.d		LOGA6(%pc),%fp1		# V*A6 | 
 | 	fmul.d		LOGA5(%pc),%fp2		# V*A5 | 
 |  | 
 | 	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6 | 
 | 	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5 | 
 |  | 
 | 	fmul.x		%fp3,%fp1		# V*(A4+V*A6) | 
 | 	fmul.x		%fp3,%fp2		# V*(A3+V*A5) | 
 |  | 
 | 	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6) | 
 | 	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5) | 
 |  | 
 | 	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6)) | 
 | 	add.l		&16,%a0			# ADDRESS OF LOG(F) | 
 | 	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5)) | 
 |  | 
 | 	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6)) | 
 | 	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5)) | 
 |  | 
 | 	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6)) | 
 | 	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3 | 
 | 	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U) | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD | 
 | 	bra		t_inx2 | 
 |  | 
 |  | 
 | LOGNEAR1: | 
 |  | 
 | # if the input is exactly equal to one, then exit through ld_pzero. | 
 | # if these 2 lines weren't here, the correct answer would be returned | 
 | # but the INEX2 bit would be set. | 
 | 	fcmp.b		%fp0,&0x1		# is it equal to one? | 
 | 	fbeq.l		ld_pzero		# yes | 
 |  | 
 | #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT. | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fsub.s		one(%pc),%fp1		# FP1 IS X-1 | 
 | 	fadd.s		one(%pc),%fp0		# FP0 IS X+1 | 
 | 	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1) | 
 | #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL | 
 | #--IN U, U = 2(X-1)/(X+1) = FP1/FP0 | 
 |  | 
 | LP1CONT2: | 
 | #--THIS IS AN RE-ENTRY POINT FOR LOGNP1 | 
 | 	fdiv.x		%fp0,%fp1		# FP1 IS U | 
 | 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 | 
 | #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3 | 
 | #--LET V=U*U, W=V*V, CALCULATE | 
 | #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY | 
 | #--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  ) | 
 | 	fmov.x		%fp1,%fp0 | 
 | 	fmul.x		%fp0,%fp0		# FP0 IS V | 
 | 	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1 | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# FP1 IS W | 
 |  | 
 | 	fmov.d		LOGB5(%pc),%fp3 | 
 | 	fmov.d		LOGB4(%pc),%fp2 | 
 |  | 
 | 	fmul.x		%fp1,%fp3		# W*B5 | 
 | 	fmul.x		%fp1,%fp2		# W*B4 | 
 |  | 
 | 	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5 | 
 | 	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4 | 
 |  | 
 | 	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED | 
 |  | 
 | 	fmul.x		%fp0,%fp2		# V*(B2+W*B4) | 
 |  | 
 | 	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5) | 
 | 	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V | 
 |  | 
 | 	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED | 
 | 	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED | 
 |  | 
 | 	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] ) | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fadd.x		SAVEU(%a6),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID | 
 | LOGNEG: | 
 | 	bra		t_operr | 
 |  | 
 | 	global		slognd | 
 | slognd: | 
 | #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT | 
 |  | 
 | 	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0 | 
 |  | 
 | #----normalize the input value by left shifting k bits (k to be determined | 
 | #----below), adjusting exponent and storing -k to  ADJK | 
 | #----the value TWOTO100 is no longer needed. | 
 | #----Note that this code assumes the denormalized input is NON-ZERO. | 
 |  | 
 | 	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7} | 
 | 	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. # | 
 | 	mov.l		4(%a0),%d4 | 
 | 	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X) | 
 | 	clr.l		%d2			# D2 used for holding K | 
 |  | 
 | 	tst.l		%d4 | 
 | 	bne.b		Hi_not0 | 
 |  | 
 | Hi_0: | 
 | 	mov.l		%d5,%d4 | 
 | 	clr.l		%d5 | 
 | 	mov.l		&32,%d2 | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d4{&0:&32},%d6 | 
 | 	lsl.l		%d6,%d4 | 
 | 	add.l		%d6,%d2			# (D3,D4,D5) is normalized | 
 |  | 
 | 	mov.l		%d3,X(%a6) | 
 | 	mov.l		%d4,XFRAC(%a6) | 
 | 	mov.l		%d5,XFRAC+4(%a6) | 
 | 	neg.l		%d2 | 
 | 	mov.l		%d2,ADJK(%a6) | 
 | 	fmov.x		X(%a6),%fp0 | 
 | 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7} | 
 | 	lea		X(%a6),%a0 | 
 | 	bra.w		LOGBGN			# begin regular log(X) | 
 |  | 
 | Hi_not0: | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d4{&0:&32},%d6		# find first 1 | 
 | 	mov.l		%d6,%d2			# get k | 
 | 	lsl.l		%d6,%d4 | 
 | 	mov.l		%d5,%d7			# a copy of D5 | 
 | 	lsl.l		%d6,%d5 | 
 | 	neg.l		%d6 | 
 | 	add.l		&32,%d6 | 
 | 	lsr.l		%d6,%d7 | 
 | 	or.l		%d7,%d4			# (D3,D4,D5) normalized | 
 |  | 
 | 	mov.l		%d3,X(%a6) | 
 | 	mov.l		%d4,XFRAC(%a6) | 
 | 	mov.l		%d5,XFRAC+4(%a6) | 
 | 	neg.l		%d2 | 
 | 	mov.l		%d2,ADJK(%a6) | 
 | 	fmov.x		X(%a6),%fp0 | 
 | 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7} | 
 | 	lea		X(%a6),%a0 | 
 | 	bra.w		LOGBGN			# begin regular log(X) | 
 |  | 
 | 	global		slognp1 | 
 | #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S | 
 | slognp1: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 | 	fabs.x		%fp0			# test magnitude | 
 | 	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold | 
 | 	fbgt.w		LP1REAL			# if greater, continue | 
 | 	fmov.l		%d0,%fpcr | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		(%a0),%fp0		# return signed argument | 
 | 	bra		t_catch | 
 |  | 
 | LP1REAL: | 
 | 	fmov.x		(%a0),%fp0		# LOAD INPUT | 
 | 	mov.l		&0x00000000,ADJK(%a6) | 
 | 	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z | 
 | 	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z) | 
 | 	fmov.x		%fp0,X(%a6) | 
 | 	mov.w		XFRAC(%a6),XDCARE(%a6) | 
 | 	mov.l		X(%a6),%d1 | 
 | 	cmp.l		%d1,&0 | 
 | 	ble.w		LP1NEG0			# LOG OF ZERO OR -VE | 
 | 	cmp.l		%d1,&0x3ffe8000		# IS BOUNDS [1/2,3/2]? | 
 | 	blt.w		LOGMAIN | 
 | 	cmp.l		%d1,&0x3fffc000 | 
 | 	bgt.w		LOGMAIN | 
 | #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z, | 
 | #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE, | 
 | #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z). | 
 |  | 
 | LP1NEAR1: | 
 | #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16) | 
 | 	cmp.l		%d1,&0x3ffef07d | 
 | 	blt.w		LP1CARE | 
 | 	cmp.l		%d1,&0x3fff8841 | 
 | 	bgt.w		LP1CARE | 
 |  | 
 | LP1ONE16: | 
 | #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2) | 
 | #--WHERE U = 2Z/(2+Z) = 2Z/(1+X). | 
 | 	fadd.x		%fp1,%fp1		# FP1 IS 2Z | 
 | 	fadd.s		one(%pc),%fp0		# FP0 IS 1+X | 
 | #--U = FP1/FP0 | 
 | 	bra.w		LP1CONT2 | 
 |  | 
 | LP1CARE: | 
 | #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE | 
 | #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST | 
 | #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2], | 
 | #--THERE ARE ONLY TWO CASES. | 
 | #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z | 
 | #--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z | 
 | #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF | 
 | #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED. | 
 |  | 
 | 	mov.l		XFRAC(%a6),FFRAC(%a6) | 
 | 	and.l		&0xFE000000,FFRAC(%a6) | 
 | 	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED | 
 | 	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1 | 
 | 	bge.b		KISZERO | 
 |  | 
 | KISNEG1: | 
 | 	fmov.s		TWO(%pc),%fp0 | 
 | 	mov.l		&0x3fff0000,F(%a6) | 
 | 	clr.l		F+8(%a6) | 
 | 	fsub.x		F(%a6),%fp0		# 2-F | 
 | 	mov.l		FFRAC(%a6),%d1 | 
 | 	and.l		&0x7E000000,%d1 | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F | 
 | 	fadd.x		%fp1,%fp1		# GET 2Z | 
 | 	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3} | 
 | 	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z | 
 | 	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F | 
 | 	add.l		%d1,%a0 | 
 | 	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1 | 
 | 	bra.w		LP1CONT1 | 
 |  | 
 | KISZERO: | 
 | 	fmov.s		one(%pc),%fp0 | 
 | 	mov.l		&0x3fff0000,F(%a6) | 
 | 	clr.l		F+8(%a6) | 
 | 	fsub.x		F(%a6),%fp0		# 1-F | 
 | 	mov.l		FFRAC(%a6),%d1 | 
 | 	and.l		&0x7E000000,%d1 | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&8,%d1 | 
 | 	asr.l		&4,%d1 | 
 | 	fadd.x		%fp1,%fp0		# FP0 IS Y-F | 
 | 	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3} | 
 | 	lea		LOGTBL(%pc),%a0 | 
 | 	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F | 
 | 	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0 | 
 | 	bra.w		LP1CONT1 | 
 |  | 
 | LP1NEG0: | 
 | #--FPCR SAVED. D0 IS X IN COMPACT FORM. | 
 | 	cmp.l		%d1,&0 | 
 | 	blt.b		LP1NEG | 
 | LP1ZERO: | 
 | 	fmov.s		negone(%pc),%fp0 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	bra		t_dz | 
 |  | 
 | LP1NEG: | 
 | 	fmov.s		zero(%pc),%fp0 | 
 |  | 
 | 	fmov.l		%d0,%fpcr | 
 | 	bra		t_operr | 
 |  | 
 | 	global		slognp1d | 
 | #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT | 
 | # Simply return the denorm | 
 | slognp1d: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # satanh():  computes the inverse hyperbolic tangent of a norm input	# | 
 | # satanhd(): computes the inverse hyperbolic tangent of a denorm input	# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = arctanh(X)						# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 3 ulps in	64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #	ATANH								# | 
 | #	1. If |X| >= 1, go to 3.					# | 
 | #									# | 
 | #	2. (|X| < 1) Calculate atanh(X) by				# | 
 | #		sgn := sign(X)						# | 
 | #		y := |X|						# | 
 | #		z := 2y/(1-y)						# | 
 | #		atanh(X) := sgn * (1/2) * logp1(z)			# | 
 | #		Exit.							# | 
 | #									# | 
 | #	3. If |X| > 1, go to 5.						# | 
 | #									# | 
 | #	4. (|X| = 1) Generate infinity with an appropriate sign and	# | 
 | #		divide-by-zero by					# | 
 | #		sgn := sign(X)						# | 
 | #		atan(X) := sgn / (+0).					# | 
 | #		Exit.							# | 
 | #									# | 
 | #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	# | 
 | #		Exit.							# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		satanh | 
 | satanh: | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bge.b		ATANHBIG | 
 |  | 
 | #--THIS IS THE USUAL CASE, |X| < 1 | 
 | #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z). | 
 |  | 
 | 	fabs.x		(%a0),%fp0		# Y = |X| | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fneg.x		%fp1			# -Y | 
 | 	fadd.x		%fp0,%fp0		# 2Y | 
 | 	fadd.s		&0x3F800000,%fp1	# 1-Y | 
 | 	fdiv.x		%fp1,%fp0		# 2Y/(1-Y) | 
 | 	mov.l		(%a0),%d1 | 
 | 	and.l		&0x80000000,%d1 | 
 | 	or.l		&0x3F000000,%d1		# SIGN(X)*HALF | 
 | 	mov.l		%d1,-(%sp) | 
 |  | 
 | 	mov.l		%d0,-(%sp)		# save rnd prec,mode | 
 | 	clr.l		%d0			# pass ext prec,RN | 
 | 	fmovm.x		&0x01,-(%sp)		# save Z on stack | 
 | 	lea		(%sp),%a0		# pass ptr to Z | 
 | 	bsr		slognp1			# LOG1P(Z) | 
 | 	add.l		&0xc,%sp		# clear Z from stack | 
 |  | 
 | 	mov.l		(%sp)+,%d0		# fetch old prec,mode | 
 | 	fmov.l		%d0,%fpcr		# load it | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.s		(%sp)+,%fp0 | 
 | 	bra		t_catch | 
 |  | 
 | ATANHBIG: | 
 | 	fabs.x		(%a0),%fp0		# |X| | 
 | 	fcmp.s		%fp0,&0x3F800000 | 
 | 	fbgt		t_operr | 
 | 	bra		t_dz | 
 |  | 
 | 	global		satanhd | 
 | #--ATANH(X) = X FOR DENORMALIZED X | 
 | satanhd: | 
 | 	bra		t_extdnrm | 
 |  | 
 | ######################################################################### | 
 | # slog10():  computes the base-10 logarithm of a normalized input	# | 
 | # slog10d(): computes the base-10 logarithm of a denormalized input	# | 
 | # slog2():   computes the base-2 logarithm of a normalized input	# | 
 | # slog2d():  computes the base-2 logarithm of a denormalized input	# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = log_10(X) or log_2(X)					# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 1.7 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #       slog10d:							# | 
 | #									# | 
 | #       Step 0.	If X < 0, create a NaN and raise the invalid operation	# | 
 | #               flag. Otherwise, save FPCR in D1; set FpCR to default.	# | 
 | #       Notes:  Default means round-to-nearest mode, no floating-point	# | 
 | #               traps, and precision control = double extended.		# | 
 | #									# | 
 | #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	# | 
 | #       Notes:  Even if X is denormalized, log(X) is always normalized.	# | 
 | #									# | 
 | #       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		# | 
 | #            2.1 Restore the user FPCR					# | 
 | #            2.2 Return ans := Y * INV_L10.				# | 
 | #									# | 
 | #       slog10:								# | 
 | #									# | 
 | #       Step 0. If X < 0, create a NaN and raise the invalid operation	# | 
 | #               flag. Otherwise, save FPCR in D1; set FpCR to default.	# | 
 | #       Notes:  Default means round-to-nearest mode, no floating-point	# | 
 | #               traps, and precision control = double extended.		# | 
 | #									# | 
 | #       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	# | 
 | #									# | 
 | #       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		# | 
 | #            2.1  Restore the user FPCR					# | 
 | #            2.2  Return ans := Y * INV_L10.				# | 
 | #									# | 
 | #       sLog2d:								# | 
 | #									# | 
 | #       Step 0. If X < 0, create a NaN and raise the invalid operation	# | 
 | #               flag. Otherwise, save FPCR in D1; set FpCR to default.	# | 
 | #       Notes:  Default means round-to-nearest mode, no floating-point	# | 
 | #               traps, and precision control = double extended.		# | 
 | #									# | 
 | #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	# | 
 | #       Notes:  Even if X is denormalized, log(X) is always normalized.	# | 
 | #									# | 
 | #       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		# | 
 | #            2.1  Restore the user FPCR					# | 
 | #            2.2  Return ans := Y * INV_L2.				# | 
 | #									# | 
 | #       sLog2:								# | 
 | #									# | 
 | #       Step 0. If X < 0, create a NaN and raise the invalid operation	# | 
 | #               flag. Otherwise, save FPCR in D1; set FpCR to default.	# | 
 | #       Notes:  Default means round-to-nearest mode, no floating-point	# | 
 | #               traps, and precision control = double extended.		# | 
 | #									# | 
 | #       Step 1. If X is not an integer power of two, i.e., X != 2^k,	# | 
 | #               go to Step 3.						# | 
 | #									# | 
 | #       Step 2.   Return k.						# | 
 | #            2.1  Get integer k, X = 2^k.				# | 
 | #            2.2  Restore the user FPCR.				# | 
 | #            2.3  Return ans := convert-to-double-extended(k).		# | 
 | #									# | 
 | #       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	# | 
 | #									# | 
 | #       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		# | 
 | #            4.1  Restore the user FPCR					# | 
 | #            4.2  Return ans := Y * INV_L2.				# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | INV_L10: | 
 | 	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 | 
 |  | 
 | INV_L2: | 
 | 	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 | 
 |  | 
 | 	global		slog10 | 
 | #--entry point for Log10(X), X is normalized | 
 | slog10: | 
 | 	fmov.b		&0x1,%fp0 | 
 | 	fcmp.x		%fp0,(%a0)		# if operand == 1, | 
 | 	fbeq.l		ld_pzero		# return an EXACT zero | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	blt.w		invalid | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	bsr		slogn			# log(X), X normal. | 
 | 	fmov.l		(%sp)+,%fpcr | 
 | 	fmul.x		INV_L10(%pc),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | 	global		slog10d | 
 | #--entry point for Log10(X), X is denormalized | 
 | slog10d: | 
 | 	mov.l		(%a0),%d1 | 
 | 	blt.w		invalid | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	bsr		slognd			# log(X), X denorm. | 
 | 	fmov.l		(%sp)+,%fpcr | 
 | 	fmul.x		INV_L10(%pc),%fp0 | 
 | 	bra		t_minx2 | 
 |  | 
 | 	global		slog2 | 
 | #--entry point for Log2(X), X is normalized | 
 | slog2: | 
 | 	mov.l		(%a0),%d1 | 
 | 	blt.w		invalid | 
 |  | 
 | 	mov.l		8(%a0),%d1 | 
 | 	bne.b		continue		# X is not 2^k | 
 |  | 
 | 	mov.l		4(%a0),%d1 | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 | 	bne.b		continue | 
 |  | 
 | #--X = 2^k. | 
 | 	mov.w		(%a0),%d1 | 
 | 	and.l		&0x00007FFF,%d1 | 
 | 	sub.l		&0x3FFF,%d1 | 
 | 	beq.l		ld_pzero | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fmov.l		%d1,%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | continue: | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	bsr		slogn			# log(X), X normal. | 
 | 	fmov.l		(%sp)+,%fpcr | 
 | 	fmul.x		INV_L2(%pc),%fp0 | 
 | 	bra		t_inx2 | 
 |  | 
 | invalid: | 
 | 	bra		t_operr | 
 |  | 
 | 	global		slog2d | 
 | #--entry point for Log2(X), X is denormalized | 
 | slog2d: | 
 | 	mov.l		(%a0),%d1 | 
 | 	blt.w		invalid | 
 | 	mov.l		%d0,-(%sp) | 
 | 	clr.l		%d0 | 
 | 	bsr		slognd			# log(X), X denorm. | 
 | 	fmov.l		(%sp)+,%fpcr | 
 | 	fmul.x		INV_L2(%pc),%fp0 | 
 | 	bra		t_minx2 | 
 |  | 
 | ######################################################################### | 
 | # stwotox():  computes 2**X for a normalized input			# | 
 | # stwotoxd(): computes 2**X for a denormalized input			# | 
 | # stentox():  computes 10**X for a normalized input			# | 
 | # stentoxd(): computes 10**X for a denormalized input			# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = 2**X or 10**X						# | 
 | #									# | 
 | # ACCURACY and MONOTONICITY *******************************************	# | 
 | #	The returned result is within 2 ulps in 64 significant bit,	# | 
 | #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	# | 
 | #	rounded to double precision. The result is provably monotonic	# | 
 | #	in double precision.						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #									# | 
 | #	twotox								# | 
 | #	1. If |X| > 16480, go to ExpBig.				# | 
 | #									# | 
 | #	2. If |X| < 2**(-70), go to ExpSm.				# | 
 | #									# | 
 | #	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	# | 
 | #		decompose N as						# | 
 | #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			# | 
 | #									# | 
 | #	4. Overwrite r := r * log2. Then				# | 
 | #		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		# | 
 | #		Go to expr to compute that expression.			# | 
 | #									# | 
 | #	tentox								# | 
 | #	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	# | 
 | #									# | 
 | #	2. If |X| < 2**(-70), go to ExpSm.				# | 
 | #									# | 
 | #	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		# | 
 | #		N := round-to-int(y). Decompose N as			# | 
 | #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			# | 
 | #									# | 
 | #	4. Define r as							# | 
 | #		r := ((X - N*L1)-N*L2) * L10				# | 
 | #		where L1, L2 are the leading and trailing parts of	# | 
 | #		log_10(2)/64 and L10 is the natural log of 10. Then	# | 
 | #		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		# | 
 | #		Go to expr to compute that expression.			# | 
 | #									# | 
 | #	expr								# | 
 | #	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		# | 
 | #									# | 
 | #	2. Overwrite Fact1 and Fact2 by					# | 
 | #		Fact1 := 2**(M) * Fact1					# | 
 | #		Fact2 := 2**(M) * Fact2					# | 
 | #		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		# | 
 | #									# | 
 | #	3. Calculate P where 1 + P approximates exp(r):			# | 
 | #		P = r + r*r*(A1+r*(A2+...+r*A5)).			# | 
 | #									# | 
 | #	4. Let AdjFact := 2**(M'). Return				# | 
 | #		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		# | 
 | #		Exit.							# | 
 | #									# | 
 | #	ExpBig								# | 
 | #	1. Generate overflow by Huge * Huge if X > 0; otherwise,	# | 
 | #	        generate underflow by Tiny * Tiny.			# | 
 | #									# | 
 | #	ExpSm								# | 
 | #	1. Return 1 + X.						# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | L2TEN64: | 
 | 	long		0x406A934F,0x0979A371	# 64LOG10/LOG2 | 
 | L10TWO1: | 
 | 	long		0x3F734413,0x509F8000	# LOG2/64LOG10 | 
 |  | 
 | L10TWO2: | 
 | 	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000 | 
 |  | 
 | LOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000 | 
 |  | 
 | LOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 | 
 |  | 
 | EXPA5:	long		0x3F56C16D,0x6F7BD0B2 | 
 | EXPA4:	long		0x3F811112,0x302C712C | 
 | EXPA3:	long		0x3FA55555,0x55554CC1 | 
 | EXPA2:	long		0x3FC55555,0x55554A54 | 
 | EXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000 | 
 |  | 
 | TEXPTBL: | 
 | 	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000 | 
 | 	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA | 
 | 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9 | 
 | 	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9 | 
 | 	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA | 
 | 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C | 
 | 	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1 | 
 | 	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA | 
 | 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373 | 
 | 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670 | 
 | 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700 | 
 | 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0 | 
 | 	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D | 
 | 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319 | 
 | 	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B | 
 | 	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5 | 
 | 	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A | 
 | 	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B | 
 | 	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF | 
 | 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA | 
 | 	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD | 
 | 	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E | 
 | 	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B | 
 | 	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB | 
 | 	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB | 
 | 	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274 | 
 | 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C | 
 | 	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00 | 
 | 	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301 | 
 | 	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367 | 
 | 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F | 
 | 	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C | 
 | 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB | 
 | 	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB | 
 | 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C | 
 | 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA | 
 | 	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD | 
 | 	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51 | 
 | 	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A | 
 | 	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2 | 
 | 	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB | 
 | 	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17 | 
 | 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C | 
 | 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8 | 
 | 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53 | 
 | 	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE | 
 | 	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124 | 
 | 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243 | 
 | 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A | 
 | 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61 | 
 | 	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610 | 
 | 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1 | 
 | 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12 | 
 | 	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE | 
 | 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4 | 
 | 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F | 
 | 	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A | 
 | 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A | 
 | 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC | 
 | 	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F | 
 | 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A | 
 | 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795 | 
 | 	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B | 
 | 	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581 | 
 |  | 
 | 	set		INT,L_SCR1 | 
 |  | 
 | 	set		X,FP_SCR0 | 
 | 	set		XDCARE,X+2 | 
 | 	set		XFRAC,X+4 | 
 |  | 
 | 	set		ADJFACT,FP_SCR0 | 
 |  | 
 | 	set		FACT1,FP_SCR0 | 
 | 	set		FACT1HI,FACT1+4 | 
 | 	set		FACT1LOW,FACT1+8 | 
 |  | 
 | 	set		FACT2,FP_SCR1 | 
 | 	set		FACT2HI,FACT2+4 | 
 | 	set		FACT2LOW,FACT2+8 | 
 |  | 
 | 	global		stwotox | 
 | #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S | 
 | stwotox: | 
 | 	fmovm.x		(%a0),&0x80		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	fmov.x		%fp0,X(%a6) | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 |  | 
 | 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)? | 
 | 	bge.b		TWOOK1 | 
 | 	bra.w		EXPBORS | 
 |  | 
 | TWOOK1: | 
 | 	cmp.l		%d1,&0x400D80C0		# |X| > 16480? | 
 | 	ble.b		TWOMAIN | 
 | 	bra.w		EXPBORS | 
 |  | 
 | TWOMAIN: | 
 | #--USUAL CASE, 2^(-70) <= |X| <= 16480 | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.s		&0x42800000,%fp1	# 64 * X | 
 | 	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X) | 
 | 	mov.l		%d2,-(%sp) | 
 | 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64) | 
 | 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT | 
 | 	mov.l		INT(%a6),%d1 | 
 | 	mov.l		%d1,%d2 | 
 | 	and.l		&0x3F,%d1		# D0 IS J | 
 | 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64) | 
 | 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64) | 
 | 	asr.l		&6,%d2			# d2 IS L, N = 64L + J | 
 | 	mov.l		%d2,%d1 | 
 | 	asr.l		&1,%d1			# D0 IS M | 
 | 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J | 
 | 	add.l		&0x3FFF,%d2 | 
 |  | 
 | #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), | 
 | #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. | 
 | #--ADJFACT = 2^(M'). | 
 | #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. | 
 |  | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3 | 
 |  | 
 | 	fmul.s		&0x3C800000,%fp1	# (1/64)*N | 
 | 	mov.l		(%a1)+,FACT1(%a6) | 
 | 	mov.l		(%a1)+,FACT1HI(%a6) | 
 | 	mov.l		(%a1)+,FACT1LOW(%a6) | 
 | 	mov.w		(%a1)+,FACT2(%a6) | 
 |  | 
 | 	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X) | 
 |  | 
 | 	mov.w		(%a1)+,FACT2HI(%a6) | 
 | 	clr.w		FACT2HI+2(%a6) | 
 | 	clr.l		FACT2LOW(%a6) | 
 | 	add.w		%d1,FACT1(%a6) | 
 | 	fmul.x		LOG2(%pc),%fp0		# FP0 IS R | 
 | 	add.w		%d1,FACT2(%a6) | 
 |  | 
 | 	bra.w		expr | 
 |  | 
 | EXPBORS: | 
 | #--FPCR, D0 SAVED | 
 | 	cmp.l		%d1,&0x3FFF8000 | 
 | 	bgt.b		TEXPBIG | 
 |  | 
 | #--|X| IS SMALL, RETURN 1 + X | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round prec,mode | 
 | 	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X | 
 | 	bra		t_pinx2 | 
 |  | 
 | TEXPBIG: | 
 | #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW | 
 | #--REGISTERS SAVE SO FAR ARE FPCR AND  D0 | 
 | 	mov.l		X(%a6),%d1 | 
 | 	cmp.l		%d1,&0 | 
 | 	blt.b		EXPNEG | 
 |  | 
 | 	bra		t_ovfl2			# t_ovfl expects positive value | 
 |  | 
 | EXPNEG: | 
 | 	bra		t_unfl2			# t_unfl expects positive value | 
 |  | 
 | 	global		stwotoxd | 
 | stwotoxd: | 
 | #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision | 
 | 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X | 
 | 	mov.l		(%a0),%d1 | 
 | 	or.l		&0x00800001,%d1 | 
 | 	fadd.s		%d1,%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | 	global		stentox | 
 | #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S | 
 | stentox: | 
 | 	fmovm.x		(%a0),&0x80		# LOAD INPUT | 
 |  | 
 | 	mov.l		(%a0),%d1 | 
 | 	mov.w		4(%a0),%d1 | 
 | 	fmov.x		%fp0,X(%a6) | 
 | 	and.l		&0x7FFFFFFF,%d1 | 
 |  | 
 | 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)? | 
 | 	bge.b		TENOK1 | 
 | 	bra.w		EXPBORS | 
 |  | 
 | TENOK1: | 
 | 	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ? | 
 | 	ble.b		TENMAIN | 
 | 	bra.w		EXPBORS | 
 |  | 
 | TENMAIN: | 
 | #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10 | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2 | 
 | 	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2) | 
 | 	mov.l		%d2,-(%sp) | 
 | 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64) | 
 | 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT | 
 | 	mov.l		INT(%a6),%d1 | 
 | 	mov.l		%d1,%d2 | 
 | 	and.l		&0x3F,%d1		# D0 IS J | 
 | 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64) | 
 | 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64) | 
 | 	asr.l		&6,%d2			# d2 IS L, N = 64L + J | 
 | 	mov.l		%d2,%d1 | 
 | 	asr.l		&1,%d1			# D0 IS M | 
 | 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J | 
 | 	add.l		&0x3FFF,%d2 | 
 |  | 
 | #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), | 
 | #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. | 
 | #--ADJFACT = 2^(M'). | 
 | #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. | 
 | 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3 | 
 |  | 
 | 	fmov.x		%fp1,%fp2 | 
 |  | 
 | 	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD | 
 | 	mov.l		(%a1)+,FACT1(%a6) | 
 |  | 
 | 	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL | 
 |  | 
 | 	mov.l		(%a1)+,FACT1HI(%a6) | 
 | 	mov.l		(%a1)+,FACT1LOW(%a6) | 
 | 	fsub.x		%fp1,%fp0		# X - N L_LEAD | 
 | 	mov.w		(%a1)+,FACT2(%a6) | 
 |  | 
 | 	fsub.x		%fp2,%fp0		# X - N L_TRAIL | 
 |  | 
 | 	mov.w		(%a1)+,FACT2HI(%a6) | 
 | 	clr.w		FACT2HI+2(%a6) | 
 | 	clr.l		FACT2LOW(%a6) | 
 |  | 
 | 	fmul.x		LOG10(%pc),%fp0		# FP0 IS R | 
 | 	add.w		%d1,FACT1(%a6) | 
 | 	add.w		%d1,FACT2(%a6) | 
 |  | 
 | expr: | 
 | #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN. | 
 | #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64). | 
 | #--FP0 IS R. THE FOLLOWING CODE COMPUTES | 
 | #--	2**(M'+M) * 2**(J/64) * EXP(R) | 
 |  | 
 | 	fmov.x		%fp0,%fp1 | 
 | 	fmul.x		%fp1,%fp1		# FP1 IS S = R*R | 
 |  | 
 | 	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5 | 
 | 	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# FP2 IS S*A5 | 
 | 	fmul.x		%fp1,%fp3		# FP3 IS S*A4 | 
 |  | 
 | 	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5 | 
 | 	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4 | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5) | 
 | 	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4) | 
 |  | 
 | 	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5) | 
 | 	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4) | 
 |  | 
 | 	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5)) | 
 | 	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4) | 
 | 	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1 | 
 |  | 
 | 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3 | 
 |  | 
 | #--FINAL RECONSTRUCTION PROCESS | 
 | #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0) | 
 |  | 
 | 	fmul.x		FACT1(%a6),%fp0 | 
 | 	fadd.x		FACT2(%a6),%fp0 | 
 | 	fadd.x		FACT1(%a6),%fp0 | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# restore users round prec,mode | 
 | 	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT | 
 | 	mov.l		(%sp)+,%d2 | 
 | 	mov.l		&0x80000000,ADJFACT+4(%a6) | 
 | 	clr.l		ADJFACT+8(%a6) | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT | 
 | 	bra		t_catch | 
 |  | 
 | 	global		stentoxd | 
 | stentoxd: | 
 | #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT | 
 |  | 
 | 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision | 
 | 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X | 
 | 	mov.l		(%a0),%d1 | 
 | 	or.l		&0x00800001,%d1 | 
 | 	fadd.s		%d1,%fp0 | 
 | 	bra		t_pinx2 | 
 |  | 
 | ######################################################################### | 
 | # sscale(): computes the destination operand scaled by the source	# | 
 | #	    operand. If the absoulute value of the source operand is	# | 
 | #	    >= 2^14, an overflow or underflow is returned.		# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0  = pointer to double-extended source operand X		# | 
 | #	a1  = pointer to double-extended destination operand Y		# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	fp0 =  scale(X,Y)						# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | set	SIGN,		L_SCR1 | 
 |  | 
 | 	global		sscale | 
 | sscale: | 
 | 	mov.l		%d0,-(%sp)		# store off ctrl bits for now | 
 |  | 
 | 	mov.w		DST_EX(%a1),%d1		# get dst exponent | 
 | 	smi.b		SIGN(%a6)		# use SIGN to hold dst sign | 
 | 	andi.l		&0x00007fff,%d1		# strip sign from dst exp | 
 |  | 
 | 	mov.w		SRC_EX(%a0),%d0		# check src bounds | 
 | 	andi.w		&0x7fff,%d0		# clr src sign bit | 
 | 	cmpi.w		%d0,&0x3fff		# is src ~ ZERO? | 
 | 	blt.w		src_small		# yes | 
 | 	cmpi.w		%d0,&0x400c		# no; is src too big? | 
 | 	bgt.w		src_out			# yes | 
 |  | 
 | # | 
 | # Source is within 2^14 range. | 
 | # | 
 | src_ok: | 
 | 	fintrz.x	SRC(%a0),%fp0		# calc int of src | 
 | 	fmov.l		%fp0,%d0		# int src to d0 | 
 | # don't want any accrued bits from the fintrz showing up later since | 
 | # we may need to read the fpsr for the last fp op in t_catch2(). | 
 | 	fmov.l		&0x0,%fpsr | 
 |  | 
 | 	tst.b		DST_HI(%a1)		# is dst denormalized? | 
 | 	bmi.b		sok_norm | 
 |  | 
 | # the dst is a DENORM. normalize the DENORM and add the adjustment to | 
 | # the src value. then, jump to the norm part of the routine. | 
 | sok_dnrm: | 
 | 	mov.l		%d0,-(%sp)		# save src for now | 
 |  | 
 | 	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy | 
 | 	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6) | 
 | 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6) | 
 |  | 
 | 	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM | 
 | 	bsr.l		norm			# normalize the DENORM | 
 | 	neg.l		%d0 | 
 | 	add.l		(%sp)+,%d0		# add adjustment to src | 
 |  | 
 | 	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM | 
 |  | 
 | 	cmpi.w		%d0,&-0x3fff		# is the shft amt really low? | 
 | 	bge.b		sok_norm2		# thank goodness no | 
 |  | 
 | # the multiply factor that we're trying to create should be a denorm | 
 | # for the multiply to work. therefore, we're going to actually do a | 
 | # multiply with a denorm which will cause an unimplemented data type | 
 | # exception to be put into the machine which will be caught and corrected | 
 | # later. we don't do this with the DENORMs above because this method | 
 | # is slower. but, don't fret, I don't see it being used much either. | 
 | 	fmov.l		(%sp)+,%fpcr		# restore user fpcr | 
 | 	mov.l		&0x80000000,%d1		# load normalized mantissa | 
 | 	subi.l		&-0x3fff,%d0		# how many should we shift? | 
 | 	neg.l		%d0			# make it positive | 
 | 	cmpi.b		%d0,&0x20		# is it > 32? | 
 | 	bge.b		sok_dnrm_32		# yes | 
 | 	lsr.l		%d0,%d1			# no; bit stays in upper lw | 
 | 	clr.l		-(%sp)			# insert zero low mantissa | 
 | 	mov.l		%d1,-(%sp)		# insert new high mantissa | 
 | 	clr.l		-(%sp)			# make zero exponent | 
 | 	bra.b		sok_norm_cont | 
 | sok_dnrm_32: | 
 | 	subi.b		&0x20,%d0		# get shift count | 
 | 	lsr.l		%d0,%d1			# make low mantissa longword | 
 | 	mov.l		%d1,-(%sp)		# insert new low mantissa | 
 | 	clr.l		-(%sp)			# insert zero high mantissa | 
 | 	clr.l		-(%sp)			# make zero exponent | 
 | 	bra.b		sok_norm_cont | 
 |  | 
 | # the src will force the dst to a DENORM value or worse. so, let's | 
 | # create an fp multiply that will create the result. | 
 | sok_norm: | 
 | 	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src | 
 | sok_norm2: | 
 | 	fmov.l		(%sp)+,%fpcr		# restore user fpcr | 
 |  | 
 | 	addi.w		&0x3fff,%d0		# turn src amt into exp value | 
 | 	swap		%d0			# put exponent in high word | 
 | 	clr.l		-(%sp)			# insert new exponent | 
 | 	mov.l		&0x80000000,-(%sp)	# insert new high mantissa | 
 | 	mov.l		%d0,-(%sp)		# insert new lo mantissa | 
 |  | 
 | sok_norm_cont: | 
 | 	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2 | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.x		(%sp)+,%fp0		# do the multiply | 
 | 	bra		t_catch2		# catch any exceptions | 
 |  | 
 | # | 
 | # Source is outside of 2^14 range.  Test the sign and branch | 
 | # to the appropriate exception handler. | 
 | # | 
 | src_out: | 
 | 	mov.l		(%sp)+,%d0		# restore ctrl bits | 
 | 	exg		%a0,%a1			# swap src,dst ptrs | 
 | 	tst.b		SRC_EX(%a1)		# is src negative? | 
 | 	bmi		t_unfl			# yes; underflow | 
 | 	bra		t_ovfl_sc		# no; overflow | 
 |  | 
 | # | 
 | # The source input is below 1, so we check for denormalized numbers | 
 | # and set unfl. | 
 | # | 
 | src_small: | 
 | 	tst.b		DST_HI(%a1)		# is dst denormalized? | 
 | 	bpl.b		ssmall_done		# yes | 
 |  | 
 | 	mov.l		(%sp)+,%d0 | 
 | 	fmov.l		%d0,%fpcr		# no; load control bits | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		DST(%a1),%fp0		# simply return dest | 
 | 	bra		t_catch2 | 
 | ssmall_done: | 
 | 	mov.l		(%sp)+,%d0		# load control bits into d1 | 
 | 	mov.l		%a1,%a0			# pass ptr to dst | 
 | 	bra		t_resdnrm | 
 |  | 
 | ######################################################################### | 
 | # smod(): computes the fp MOD of the input values X,Y.			# | 
 | # srem(): computes the fp (IEEE) REM of the input values X,Y.		# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer to extended precision input X			# | 
 | #	a1 = pointer to extended precision input Y			# | 
 | #	d0 = round precision,mode					# | 
 | #									# | 
 | #	The input operands X and Y can be either normalized or		# | 
 | #	denormalized.							# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #      fp0 = FREM(X,Y) or FMOD(X,Y)					# | 
 | #									# | 
 | # ALGORITHM *********************************************************** # | 
 | #									# | 
 | #       Step 1.  Save and strip signs of X and Y: signX := sign(X),	# | 
 | #                signY := sign(Y), X := |X|, Y := |Y|,			# | 
 | #                signQ := signX EOR signY. Record whether MOD or REM	# | 
 | #                is requested.						# | 
 | #									# | 
 | #       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		# | 
 | #                If (L < 0) then					# | 
 | #                   R := X, go to Step 4.				# | 
 | #                else							# | 
 | #                   R := 2^(-L)X, j := L.				# | 
 | #                endif							# | 
 | #									# | 
 | #       Step 3.  Perform MOD(X,Y)					# | 
 | #            3.1 If R = Y, go to Step 9.				# | 
 | #            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		# | 
 | #            3.3 If j = 0, go to Step 4.				# | 
 | #            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	# | 
 | #                Step 3.1.						# | 
 | #									# | 
 | #       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		# | 
 | #                Last_Subtract := false (used in Step 7 below). If	# | 
 | #                MOD is requested, go to Step 6.			# | 
 | #									# | 
 | #       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		# | 
 | #            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	# | 
 | #                Step 6.						# | 
 | #            5.2 If R > Y/2, then { set Last_Subtract := true,		# | 
 | #                Q := Q + 1, Y := signY*Y }. Go to Step 6.		# | 
 | #            5.3 This is the tricky case of R = Y/2. If Q is odd,	# | 
 | #                then { Q := Q + 1, signX := -signX }.			# | 
 | #									# | 
 | #       Step 6.  R := signX*R.						# | 
 | #									# | 
 | #       Step 7.  If Last_Subtract = true, R := R - Y.			# | 
 | #									# | 
 | #       Step 8.  Return signQ, last 7 bits of Q, and R as required.	# | 
 | #									# | 
 | #       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		# | 
 | #                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		# | 
 | #                R := 0. Return signQ, last 7 bits of Q, and R.		# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	set		Mod_Flag,L_SCR3 | 
 | 	set		Sc_Flag,L_SCR3+1 | 
 |  | 
 | 	set		SignY,L_SCR2 | 
 | 	set		SignX,L_SCR2+2 | 
 | 	set		SignQ,L_SCR3+2 | 
 |  | 
 | 	set		Y,FP_SCR0 | 
 | 	set		Y_Hi,Y+4 | 
 | 	set		Y_Lo,Y+8 | 
 |  | 
 | 	set		R,FP_SCR1 | 
 | 	set		R_Hi,R+4 | 
 | 	set		R_Lo,R+8 | 
 |  | 
 | Scale: | 
 | 	long		0x00010000,0x80000000,0x00000000,0x00000000 | 
 |  | 
 | 	global		smod | 
 | smod: | 
 | 	clr.b		FPSR_QBYTE(%a6) | 
 | 	mov.l		%d0,-(%sp)		# save ctrl bits | 
 | 	clr.b		Mod_Flag(%a6) | 
 | 	bra.b		Mod_Rem | 
 |  | 
 | 	global		srem | 
 | srem: | 
 | 	clr.b		FPSR_QBYTE(%a6) | 
 | 	mov.l		%d0,-(%sp)		# save ctrl bits | 
 | 	mov.b		&0x1,Mod_Flag(%a6) | 
 |  | 
 | Mod_Rem: | 
 | #..Save sign of X and Y | 
 | 	movm.l		&0x3f00,-(%sp)		# save data registers | 
 | 	mov.w		SRC_EX(%a0),%d3 | 
 | 	mov.w		%d3,SignY(%a6) | 
 | 	and.l		&0x00007FFF,%d3		# Y := |Y| | 
 |  | 
 | # | 
 | 	mov.l		SRC_HI(%a0),%d4 | 
 | 	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y| | 
 |  | 
 | 	tst.l		%d3 | 
 | 	bne.b		Y_Normal | 
 |  | 
 | 	mov.l		&0x00003FFE,%d3		# $3FFD + 1 | 
 | 	tst.l		%d4 | 
 | 	bne.b		HiY_not0 | 
 |  | 
 | HiY_0: | 
 | 	mov.l		%d5,%d4 | 
 | 	clr.l		%d5 | 
 | 	sub.l		&32,%d3 | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d4{&0:&32},%d6 | 
 | 	lsl.l		%d6,%d4 | 
 | 	sub.l		%d6,%d3			# (D3,D4,D5) is normalized | 
 | #	                                        ...with bias $7FFD | 
 | 	bra.b		Chk_X | 
 |  | 
 | HiY_not0: | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d4{&0:&32},%d6 | 
 | 	sub.l		%d6,%d3 | 
 | 	lsl.l		%d6,%d4 | 
 | 	mov.l		%d5,%d7			# a copy of D5 | 
 | 	lsl.l		%d6,%d5 | 
 | 	neg.l		%d6 | 
 | 	add.l		&32,%d6 | 
 | 	lsr.l		%d6,%d7 | 
 | 	or.l		%d7,%d4			# (D3,D4,D5) normalized | 
 | #                                       ...with bias $7FFD | 
 | 	bra.b		Chk_X | 
 |  | 
 | Y_Normal: | 
 | 	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized | 
 | #                                       ...with bias $7FFD | 
 |  | 
 | Chk_X: | 
 | 	mov.w		DST_EX(%a1),%d0 | 
 | 	mov.w		%d0,SignX(%a6) | 
 | 	mov.w		SignY(%a6),%d1 | 
 | 	eor.l		%d0,%d1 | 
 | 	and.l		&0x00008000,%d1 | 
 | 	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained | 
 | 	and.l		&0x00007FFF,%d0 | 
 | 	mov.l		DST_HI(%a1),%d1 | 
 | 	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X| | 
 | 	tst.l		%d0 | 
 | 	bne.b		X_Normal | 
 | 	mov.l		&0x00003FFE,%d0 | 
 | 	tst.l		%d1 | 
 | 	bne.b		HiX_not0 | 
 |  | 
 | HiX_0: | 
 | 	mov.l		%d2,%d1 | 
 | 	clr.l		%d2 | 
 | 	sub.l		&32,%d0 | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d1{&0:&32},%d6 | 
 | 	lsl.l		%d6,%d1 | 
 | 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized | 
 | #                                       ...with bias $7FFD | 
 | 	bra.b		Init | 
 |  | 
 | HiX_not0: | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d1{&0:&32},%d6 | 
 | 	sub.l		%d6,%d0 | 
 | 	lsl.l		%d6,%d1 | 
 | 	mov.l		%d2,%d7			# a copy of D2 | 
 | 	lsl.l		%d6,%d2 | 
 | 	neg.l		%d6 | 
 | 	add.l		&32,%d6 | 
 | 	lsr.l		%d6,%d7 | 
 | 	or.l		%d7,%d1			# (D0,D1,D2) normalized | 
 | #                                       ...with bias $7FFD | 
 | 	bra.b		Init | 
 |  | 
 | X_Normal: | 
 | 	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized | 
 | #                                       ...with bias $7FFD | 
 |  | 
 | Init: | 
 | # | 
 | 	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y) | 
 | 	mov.l		%d0,-(%sp)		# save biased exp(X) | 
 | 	sub.l		%d3,%d0			# L := expo(X)-expo(Y) | 
 |  | 
 | 	clr.l		%d6			# D6 := carry <- 0 | 
 | 	clr.l		%d3			# D3 is Q | 
 | 	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0 | 
 |  | 
 | #..(Carry,D1,D2) is R | 
 | 	tst.l		%d0 | 
 | 	bge.b		Mod_Loop_pre | 
 |  | 
 | #..expo(X) < expo(Y). Thus X = mod(X,Y) | 
 | # | 
 | 	mov.l		(%sp)+,%d0		# restore d0 | 
 | 	bra.w		Get_Mod | 
 |  | 
 | Mod_Loop_pre: | 
 | 	addq.l		&0x4,%sp		# erase exp(X) | 
 | #..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L | 
 | Mod_Loop: | 
 | 	tst.l		%d6			# test carry bit | 
 | 	bgt.b		R_GT_Y | 
 |  | 
 | #..At this point carry = 0, R = (D1,D2), Y = (D4,D5) | 
 | 	cmp.l		%d1,%d4			# compare hi(R) and hi(Y) | 
 | 	bne.b		R_NE_Y | 
 | 	cmp.l		%d2,%d5			# compare lo(R) and lo(Y) | 
 | 	bne.b		R_NE_Y | 
 |  | 
 | #..At this point, R = Y | 
 | 	bra.w		Rem_is_0 | 
 |  | 
 | R_NE_Y: | 
 | #..use the borrow of the previous compare | 
 | 	bcs.b		R_LT_Y			# borrow is set iff R < Y | 
 |  | 
 | R_GT_Y: | 
 | #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0 | 
 | #..and Y < (D1,D2) < 2Y. Either way, perform R - Y | 
 | 	sub.l		%d5,%d2			# lo(R) - lo(Y) | 
 | 	subx.l		%d4,%d1			# hi(R) - hi(Y) | 
 | 	clr.l		%d6			# clear carry | 
 | 	addq.l		&1,%d3			# Q := Q + 1 | 
 |  | 
 | R_LT_Y: | 
 | #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0. | 
 | 	tst.l		%d0			# see if j = 0. | 
 | 	beq.b		PostLoop | 
 |  | 
 | 	add.l		%d3,%d3			# Q := 2Q | 
 | 	add.l		%d2,%d2			# lo(R) = 2lo(R) | 
 | 	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry | 
 | 	scs		%d6			# set Carry if 2(R) overflows | 
 | 	addq.l		&1,%a1			# k := k+1 | 
 | 	subq.l		&1,%d0			# j := j - 1 | 
 | #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y. | 
 |  | 
 | 	bra.b		Mod_Loop | 
 |  | 
 | PostLoop: | 
 | #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y. | 
 |  | 
 | #..normalize R. | 
 | 	mov.l		L_SCR1(%a6),%d0		# new biased expo of R | 
 | 	tst.l		%d1 | 
 | 	bne.b		HiR_not0 | 
 |  | 
 | HiR_0: | 
 | 	mov.l		%d2,%d1 | 
 | 	clr.l		%d2 | 
 | 	sub.l		&32,%d0 | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d1{&0:&32},%d6 | 
 | 	lsl.l		%d6,%d1 | 
 | 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized | 
 | #                                       ...with bias $7FFD | 
 | 	bra.b		Get_Mod | 
 |  | 
 | HiR_not0: | 
 | 	clr.l		%d6 | 
 | 	bfffo		%d1{&0:&32},%d6 | 
 | 	bmi.b		Get_Mod			# already normalized | 
 | 	sub.l		%d6,%d0 | 
 | 	lsl.l		%d6,%d1 | 
 | 	mov.l		%d2,%d7			# a copy of D2 | 
 | 	lsl.l		%d6,%d2 | 
 | 	neg.l		%d6 | 
 | 	add.l		&32,%d6 | 
 | 	lsr.l		%d6,%d7 | 
 | 	or.l		%d7,%d1			# (D0,D1,D2) normalized | 
 |  | 
 | # | 
 | Get_Mod: | 
 | 	cmp.l		%d0,&0x000041FE | 
 | 	bge.b		No_Scale | 
 | Do_Scale: | 
 | 	mov.w		%d0,R(%a6) | 
 | 	mov.l		%d1,R_Hi(%a6) | 
 | 	mov.l		%d2,R_Lo(%a6) | 
 | 	mov.l		L_SCR1(%a6),%d6 | 
 | 	mov.w		%d6,Y(%a6) | 
 | 	mov.l		%d4,Y_Hi(%a6) | 
 | 	mov.l		%d5,Y_Lo(%a6) | 
 | 	fmov.x		R(%a6),%fp0		# no exception | 
 | 	mov.b		&1,Sc_Flag(%a6) | 
 | 	bra.b		ModOrRem | 
 | No_Scale: | 
 | 	mov.l		%d1,R_Hi(%a6) | 
 | 	mov.l		%d2,R_Lo(%a6) | 
 | 	sub.l		&0x3FFE,%d0 | 
 | 	mov.w		%d0,R(%a6) | 
 | 	mov.l		L_SCR1(%a6),%d6 | 
 | 	sub.l		&0x3FFE,%d6 | 
 | 	mov.l		%d6,L_SCR1(%a6) | 
 | 	fmov.x		R(%a6),%fp0 | 
 | 	mov.w		%d6,Y(%a6) | 
 | 	mov.l		%d4,Y_Hi(%a6) | 
 | 	mov.l		%d5,Y_Lo(%a6) | 
 | 	clr.b		Sc_Flag(%a6) | 
 |  | 
 | # | 
 | ModOrRem: | 
 | 	tst.b		Mod_Flag(%a6) | 
 | 	beq.b		Fix_Sign | 
 |  | 
 | 	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y) | 
 | 	subq.l		&1,%d6			# biased expo(Y/2) | 
 | 	cmp.l		%d0,%d6 | 
 | 	blt.b		Fix_Sign | 
 | 	bgt.b		Last_Sub | 
 |  | 
 | 	cmp.l		%d1,%d4 | 
 | 	bne.b		Not_EQ | 
 | 	cmp.l		%d2,%d5 | 
 | 	bne.b		Not_EQ | 
 | 	bra.w		Tie_Case | 
 |  | 
 | Not_EQ: | 
 | 	bcs.b		Fix_Sign | 
 |  | 
 | Last_Sub: | 
 | # | 
 | 	fsub.x		Y(%a6),%fp0		# no exceptions | 
 | 	addq.l		&1,%d3			# Q := Q + 1 | 
 |  | 
 | # | 
 | Fix_Sign: | 
 | #..Get sign of X | 
 | 	mov.w		SignX(%a6),%d6 | 
 | 	bge.b		Get_Q | 
 | 	fneg.x		%fp0 | 
 |  | 
 | #..Get Q | 
 | # | 
 | Get_Q: | 
 | 	clr.l		%d6 | 
 | 	mov.w		SignQ(%a6),%d6		# D6 is sign(Q) | 
 | 	mov.l		&8,%d7 | 
 | 	lsr.l		%d7,%d6 | 
 | 	and.l		&0x0000007F,%d3		# 7 bits of Q | 
 | 	or.l		%d6,%d3			# sign and bits of Q | 
 | #	swap		%d3 | 
 | #	fmov.l		%fpsr,%d6 | 
 | #	and.l		&0xFF00FFFF,%d6 | 
 | #	or.l		%d3,%d6 | 
 | #	fmov.l		%d6,%fpsr		# put Q in fpsr | 
 | 	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr | 
 |  | 
 | # | 
 | Restore: | 
 | 	movm.l		(%sp)+,&0xfc		#  {%d2-%d7} | 
 | 	mov.l		(%sp)+,%d0 | 
 | 	fmov.l		%d0,%fpcr | 
 | 	tst.b		Sc_Flag(%a6) | 
 | 	beq.b		Finish | 
 | 	mov.b		&FMUL_OP,%d1		# last inst is MUL | 
 | 	fmul.x		Scale(%pc),%fp0		# may cause underflow | 
 | 	bra		t_catch2 | 
 | # the '040 package did this apparently to see if the dst operand for the | 
 | # preceding fmul was a denorm. but, it better not have been since the | 
 | # algorithm just got done playing with fp0 and expected no exceptions | 
 | # as a result. trust me... | 
 | #	bra		t_avoid_unsupp		# check for denorm as a | 
 | #						;result of the scaling | 
 |  | 
 | Finish: | 
 | 	mov.b		&FMOV_OP,%d1		# last inst is MOVE | 
 | 	fmov.x		%fp0,%fp0		# capture exceptions & round | 
 | 	bra		t_catch2 | 
 |  | 
 | Rem_is_0: | 
 | #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1) | 
 | 	addq.l		&1,%d3 | 
 | 	cmp.l		%d0,&8			# D0 is j | 
 | 	bge.b		Q_Big | 
 |  | 
 | 	lsl.l		%d0,%d3 | 
 | 	bra.b		Set_R_0 | 
 |  | 
 | Q_Big: | 
 | 	clr.l		%d3 | 
 |  | 
 | Set_R_0: | 
 | 	fmov.s		&0x00000000,%fp0 | 
 | 	clr.b		Sc_Flag(%a6) | 
 | 	bra.w		Fix_Sign | 
 |  | 
 | Tie_Case: | 
 | #..Check parity of Q | 
 | 	mov.l		%d3,%d6 | 
 | 	and.l		&0x00000001,%d6 | 
 | 	tst.l		%d6 | 
 | 	beq.w		Fix_Sign		# Q is even | 
 |  | 
 | #..Q is odd, Q := Q + 1, signX := -signX | 
 | 	addq.l		&1,%d3 | 
 | 	mov.w		SignX(%a6),%d6 | 
 | 	eor.l		&0x00008000,%d6 | 
 | 	mov.w		%d6,SignX(%a6) | 
 | 	bra.w		Fix_Sign | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	tag(): return the optype of the input ext fp number		# | 
 | #									# | 
 | #	This routine is used by the 060FPLSP.				# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision operand			# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	d0 = value of type tag						# | 
 | #		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	Simply test the exponent, j-bit, and mantissa values to		# | 
 | # determine the type of operand.					# | 
 | #	If it's an unnormalized zero, alter the operand and force it	# | 
 | # to be a normal zero.							# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		tag | 
 | tag: | 
 | 	mov.w		FTEMP_EX(%a0), %d0	# extract exponent | 
 | 	andi.w		&0x7fff, %d0		# strip off sign | 
 | 	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)? | 
 | 	beq.b		inf_or_nan_x | 
 | not_inf_or_nan_x: | 
 | 	btst		&0x7,FTEMP_HI(%a0) | 
 | 	beq.b		not_norm_x | 
 | is_norm_x: | 
 | 	mov.b		&NORM, %d0 | 
 | 	rts | 
 | not_norm_x: | 
 | 	tst.w		%d0			# is exponent = 0? | 
 | 	bne.b		is_unnorm_x | 
 | not_unnorm_x: | 
 | 	tst.l		FTEMP_HI(%a0) | 
 | 	bne.b		is_denorm_x | 
 | 	tst.l		FTEMP_LO(%a0) | 
 | 	bne.b		is_denorm_x | 
 | is_zero_x: | 
 | 	mov.b		&ZERO, %d0 | 
 | 	rts | 
 | is_denorm_x: | 
 | 	mov.b		&DENORM, %d0 | 
 | 	rts | 
 | is_unnorm_x: | 
 | 	bsr.l		unnorm_fix		# convert to norm,denorm,or zero | 
 | 	rts | 
 | is_unnorm_reg_x: | 
 | 	mov.b		&UNNORM, %d0 | 
 | 	rts | 
 | inf_or_nan_x: | 
 | 	tst.l		FTEMP_LO(%a0) | 
 | 	bne.b		is_nan_x | 
 | 	mov.l		FTEMP_HI(%a0), %d0 | 
 | 	and.l		&0x7fffffff, %d0	# msb is a don't care! | 
 | 	bne.b		is_nan_x | 
 | is_inf_x: | 
 | 	mov.b		&INF, %d0 | 
 | 	rts | 
 | is_nan_x: | 
 | 	mov.b		&QNAN, %d0 | 
 | 	rts | 
 |  | 
 | ############################################################# | 
 |  | 
 | qnan:	long		0x7fff0000, 0xffffffff, 0xffffffff | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_dz(): Handle 060FPLSP dz exception for "flogn" emulation.	# | 
 | #	t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation.	# | 
 | #									# | 
 | #	These rouitnes are used by the 060FPLSP package.		# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision source operand.		# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default DZ result.					# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	Transcendental emulation for the 060FPLSP has detected that	# | 
 | # a DZ exception should occur for the instruction. If DZ is disabled,	# | 
 | # return the default result.						# | 
 | #	If DZ is enabled, the dst operand should be returned unscathed	# | 
 | # in fp0 while fp1 is used to create a DZ exception so that the		# | 
 | # operating system can log that such an event occurred.			# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_dz | 
 | t_dz: | 
 | 	tst.b		SRC_EX(%a0)		# check sign for neg or pos | 
 | 	bpl.b		dz_pinf			# branch if pos sign | 
 |  | 
 | 	global		t_dz2 | 
 | t_dz2: | 
 | 	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ | 
 |  | 
 | 	btst		&dz_bit,FPCR_ENABLE(%a6) | 
 | 	bne.b		dz_minf_ena | 
 |  | 
 | # dz is disabled. return a -INF. | 
 | 	fmov.s		&0xff800000,%fp0	# return -INF | 
 | 	rts | 
 |  | 
 | # dz is enabled. create a dz exception so the user can record it | 
 | # but use fp1 instead. return the dst operand unscathed in fp0. | 
 | dz_minf_ena: | 
 | 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmov.s		&0xbf800000,%fp1	# load -1 | 
 | 	fdiv.s		&0x00000000,%fp1	# -1 / 0 | 
 | 	rts | 
 |  | 
 | dz_pinf: | 
 | 	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ | 
 |  | 
 | 	btst		&dz_bit,FPCR_ENABLE(%a6) | 
 | 	bne.b		dz_pinf_ena | 
 |  | 
 | # dz is disabled. return a +INF. | 
 | 	fmov.s		&0x7f800000,%fp0	# return +INF | 
 | 	rts | 
 |  | 
 | # dz is enabled. create a dz exception so the user can record it | 
 | # but use fp1 instead. return the dst operand unscathed in fp0. | 
 | dz_pinf_ena: | 
 | 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmov.s		&0x3f800000,%fp1	# load +1 | 
 | 	fdiv.s		&0x00000000,%fp1	# +1 / 0 | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_operr(): Handle 060FPLSP OPERR exception during emulation.	# | 
 | #									# | 
 | #	This routine is used by the 060FPLSP package.			# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None.								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	fp1 = source operand						# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default result						# | 
 | #	fp1 = unchanged							# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	An operand error should occur as the result of transcendental	# | 
 | # emulation in the 060FPLSP. If OPERR is disabled, just return a NAN	# | 
 | # in fp0. If OPERR is enabled, return the dst operand unscathed in fp0	# | 
 | # and the source operand in fp1. Use fp2 to create an OPERR exception	# | 
 | # so that the operating system can log the event.			# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_operr | 
 | t_operr: | 
 | 	ori.l		&opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP | 
 |  | 
 | 	btst		&operr_bit,FPCR_ENABLE(%a6) | 
 | 	bne.b		operr_ena | 
 |  | 
 | # operr is disabled. return a QNAN in fp0 | 
 | 	fmovm.x		qnan(%pc),&0x80		# return QNAN | 
 | 	rts | 
 |  | 
 | # operr is enabled. create an operr exception so the user can record it | 
 | # but use fp2 instead. return the dst operand unscathed in fp0. | 
 | operr_ena: | 
 | 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmovm.x		&0x04,-(%sp)		# save fp2 | 
 | 	fmov.s		&0x7f800000,%fp2	# load +INF | 
 | 	fmul.s		&0x00000000,%fp2	# +INF x 0 | 
 | 	fmovm.x		(%sp)+,&0x20		# restore fp2 | 
 | 	rts | 
 |  | 
 | pls_huge: | 
 | 	long		0x7ffe0000,0xffffffff,0xffffffff | 
 | mns_huge: | 
 | 	long		0xfffe0000,0xffffffff,0xffffffff | 
 | pls_tiny: | 
 | 	long		0x00000000,0x80000000,0x00000000 | 
 | mns_tiny: | 
 | 	long		0x80000000,0x80000000,0x00000000 | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_unfl(): Handle 060FPLSP underflow exception during emulation.	# | 
 | #	t_unfl2(): Handle 060FPLSP underflow exception during		# | 
 | #	           emulation. result always positive.			# | 
 | #									# | 
 | #	This routine is used by the 060FPLSP package.			# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None.								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision source operand		# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default underflow result					# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	An underflow should occur as the result of transcendental	# | 
 | # emulation in the 060FPLSP. Create an underflow by using "fmul"	# | 
 | # and two very small numbers of appropriate sign so the operating	# | 
 | # system can log the event.						# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_unfl | 
 | t_unfl: | 
 | 	tst.b		SRC_EX(%a0) | 
 | 	bpl.b		unf_pos | 
 |  | 
 | 	global		t_unfl2 | 
 | t_unfl2: | 
 | 	ori.l		&unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX | 
 |  | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmovm.x		mns_tiny(%pc),&0x80 | 
 | 	fmul.x		pls_tiny(%pc),%fp0 | 
 |  | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	rol.l		&0x8,%d0 | 
 | 	mov.b		%d0,FPSR_CC(%a6) | 
 | 	rts | 
 | unf_pos: | 
 | 	ori.w		&unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX | 
 |  | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmovm.x		pls_tiny(%pc),&0x80 | 
 | 	fmul.x		%fp0,%fp0 | 
 |  | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	rol.l		&0x8,%d0 | 
 | 	mov.b		%d0,FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_ovfl(): Handle 060FPLSP overflow exception during emulation.	# | 
 | #		  (monadic)						# | 
 | #	t_ovfl2(): Handle 060FPLSP overflow exception during		# | 
 | #	           emulation. result always positive. (dyadic)		# | 
 | #	t_ovfl_sc(): Handle 060FPLSP overflow exception during		# | 
 | #	             emulation for "fscale".				# | 
 | #									# | 
 | #	This routine is used by the 060FPLSP package.			# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None.								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision source operand		# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default underflow result					# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	An overflow should occur as the result of transcendental	# | 
 | # emulation in the 060FPLSP. Create an overflow by using "fmul"		# | 
 | # and two very lareg numbers of appropriate sign so the operating	# | 
 | # system can log the event.						# | 
 | #	For t_ovfl_sc() we take special care not to lose the INEX2 bit.	# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_ovfl_sc | 
 | t_ovfl_sc: | 
 | 	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX | 
 |  | 
 | 	mov.b		%d0,%d1			# fetch rnd prec,mode | 
 | 	andi.b		&0xc0,%d1		# extract prec | 
 | 	beq.w		ovfl_work | 
 |  | 
 | # dst op is a DENORM. we have to normalize the mantissa to see if the | 
 | # result would be inexact for the given precision. make a copy of the | 
 | # dst so we don't screw up the version passed to us. | 
 | 	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6) | 
 | 	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6) | 
 | 	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6) | 
 | 	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0 | 
 | 	movm.l		&0xc080,-(%sp)		# save d0-d1/a0 | 
 | 	bsr.l		norm			# normalize mantissa | 
 | 	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0 | 
 |  | 
 | 	cmpi.b		%d1,&0x40		# is precision sgl? | 
 | 	bne.b		ovfl_sc_dbl		# no; dbl | 
 | ovfl_sc_sgl: | 
 | 	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set? | 
 | 	bne.b		ovfl_sc_inx		# yes | 
 | 	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set? | 
 | 	bne.b		ovfl_sc_inx		# yes | 
 | 	bra.w		ovfl_work		# don't set INEX2 | 
 | ovfl_sc_dbl: | 
 | 	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of | 
 | 	andi.l		&0x7ff,%d1		# dbl mantissa set? | 
 | 	beq.w		ovfl_work		# no; don't set INEX2 | 
 | ovfl_sc_inx: | 
 | 	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2 | 
 | 	bra.b		ovfl_work		# continue | 
 |  | 
 | 	global		t_ovfl | 
 | t_ovfl: | 
 | 	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX | 
 | ovfl_work: | 
 | 	tst.b		SRC_EX(%a0) | 
 | 	bpl.b		ovfl_p | 
 | ovfl_m: | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmovm.x		mns_huge(%pc),&0x80 | 
 | 	fmul.x		pls_huge(%pc),%fp0 | 
 |  | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	rol.l		&0x8,%d0 | 
 | 	ori.b		&neg_mask,%d0 | 
 | 	mov.b		%d0,FPSR_CC(%a6) | 
 | 	rts | 
 | ovfl_p: | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmovm.x		pls_huge(%pc),&0x80 | 
 | 	fmul.x		pls_huge(%pc),%fp0 | 
 |  | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	rol.l		&0x8,%d0 | 
 | 	mov.b		%d0,FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | 	global		t_ovfl2 | 
 | t_ovfl2: | 
 | 	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmovm.x		pls_huge(%pc),&0x80 | 
 | 	fmul.x		pls_huge(%pc),%fp0 | 
 |  | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	rol.l		&0x8,%d0 | 
 | 	mov.b		%d0,FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	# | 
 | #		   emulation.						# | 
 | #	t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	# | 
 | #		    emulation.						# | 
 | #									# | 
 | #	These routines are used by the 060FPLSP package.		# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None.								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	fp0 = default underflow or overflow result			# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default result						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	If an overflow or underflow occurred during the last		# | 
 | # instruction of transcendental 060FPLSP emulation, then it has already	# | 
 | # occurred and has been logged. Now we need to see if an inexact	# | 
 | # exception should occur.						# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_catch2 | 
 | t_catch2: | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	or.l		%d0,USER_FPSR(%a6) | 
 | 	bra.b		inx2_work | 
 |  | 
 | 	global		t_catch | 
 | t_catch: | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	or.l		%d0,USER_FPSR(%a6) | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_inx2(): Handle inexact 060FPLSP exception during emulation.	# | 
 | #	t_pinx2(): Handle inexact 060FPLSP exception for "+" results.	# | 
 | #	t_minx2(): Handle inexact 060FPLSP exception for "-" results.	# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None.								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	fp0 = default result						# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default result						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	The last instruction of transcendental emulation for the	# | 
 | # 060FPLSP should be inexact. So, if inexact is enabled, then we create	# | 
 | # the event here by adding a large and very small number together	# | 
 | # so that the operating system can log the event.			# | 
 | #	Must check, too, if the result was zero, in which case we just	# | 
 | # set the FPSR bits and return.						# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_inx2 | 
 | t_inx2: | 
 | 	fblt.w		t_minx2 | 
 | 	fbeq.w		inx2_zero | 
 |  | 
 | 	global		t_pinx2 | 
 | t_pinx2: | 
 | 	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX | 
 | 	bra.b		inx2_work | 
 |  | 
 | 	global		t_minx2 | 
 | t_minx2: | 
 | 	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6) | 
 |  | 
 | inx2_work: | 
 | 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled? | 
 | 	bne.b		inx2_work_ena		# yes | 
 | 	rts | 
 | inx2_work_ena: | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr	# insert user's exceptions | 
 | 	fmov.s		&0x3f800000,%fp1	# load +1 | 
 | 	fadd.x		pls_tiny(%pc),%fp1	# cause exception | 
 | 	rts | 
 |  | 
 | inx2_zero: | 
 | 	mov.b		&z_bmask,FPSR_CC(%a6) | 
 | 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # XDEF ****************************************************************	# | 
 | #	t_extdnrm(): Handle DENORM inputs in 060FPLSP.			# | 
 | #	t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale".	# | 
 | #									# | 
 | #	This routine is used by the 060FPLSP package.			# | 
 | #									# | 
 | # XREF ****************************************************************	# | 
 | #	None.								# | 
 | #									# | 
 | # INPUT ***************************************************************	# | 
 | #	a0 = pointer to extended precision input operand		# | 
 | #									# | 
 | # OUTPUT **************************************************************	# | 
 | #	fp0 = default result						# | 
 | #									# | 
 | # ALGORITHM ***********************************************************	# | 
 | #	For all functions that have a denormalized input and that	# | 
 | # f(x)=x, this is the entry point.					# | 
 | #	DENORM value is moved using "fmove" which triggers an exception	# | 
 | # if enabled so the operating system can log the event.			# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		t_extdnrm | 
 | t_extdnrm: | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmov.x		SRC_EX(%a0),%fp0 | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	ori.l		&unfinx_mask,%d0 | 
 | 	or.l		%d0,USER_FPSR(%a6) | 
 | 	rts | 
 |  | 
 | 	global		t_resdnrm | 
 | t_resdnrm: | 
 | 	fmov.l		USER_FPCR(%a6),%fpcr | 
 | 	fmov.x		SRC_EX(%a0),%fp0 | 
 | 	fmov.l		%fpsr,%d0 | 
 | 	or.l		%d0,USER_FPSR(%a6) | 
 | 	rts | 
 |  | 
 | ########################################## | 
 |  | 
 | # | 
 | # sto_cos: | 
 | #	This is used by fsincos library emulation. The correct | 
 | # values are already in fp0 and fp1 so we do nothing here. | 
 | # | 
 | 	global		sto_cos | 
 | sto_cos: | 
 | 	rts | 
 |  | 
 | ########################################## | 
 |  | 
 | # | 
 | #	dst_qnan --- force result when destination is a NaN | 
 | # | 
 | 	global		dst_qnan | 
 | dst_qnan: | 
 | 	fmov.x		DST(%a1),%fp0 | 
 | 	tst.b		DST_EX(%a1) | 
 | 	bmi.b		dst_qnan_m | 
 | dst_qnan_p: | 
 | 	mov.b		&nan_bmask,FPSR_CC(%a6) | 
 | 	rts | 
 | dst_qnan_m: | 
 | 	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | # | 
 | #	src_qnan --- force result when source is a NaN | 
 | # | 
 | 	global		src_qnan | 
 | src_qnan: | 
 | 	fmov.x		SRC(%a0),%fp0 | 
 | 	tst.b		SRC_EX(%a0) | 
 | 	bmi.b		src_qnan_m | 
 | src_qnan_p: | 
 | 	mov.b		&nan_bmask,FPSR_CC(%a6) | 
 | 	rts | 
 | src_qnan_m: | 
 | 	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | ########################################## | 
 |  | 
 | # | 
 | #	Native instruction support | 
 | # | 
 | #	Some systems may need entry points even for 68060 native | 
 | #	instructions.  These routines are provided for | 
 | #	convenience. | 
 | # | 
 | 	global		_fadds_ | 
 | _fadds_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.s		0x8(%sp),%fp0		# load sgl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fadd.s		0x8(%sp),%fp0		# fadd w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_faddd_ | 
 | _faddd_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.d		0x8(%sp),%fp0		# load dbl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fadd.d		0xc(%sp),%fp0		# fadd w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_faddx_ | 
 | _faddx_: | 
 | 	fmovm.x		0x4(%sp),&0x80		# load ext dst | 
 | 	fadd.x		0x10(%sp),%fp0		# fadd w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fsubs_ | 
 | _fsubs_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.s		0x8(%sp),%fp0		# load sgl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fsub.s		0x8(%sp),%fp0		# fsub w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fsubd_ | 
 | _fsubd_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.d		0x8(%sp),%fp0		# load dbl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fsub.d		0xc(%sp),%fp0		# fsub w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fsubx_ | 
 | _fsubx_: | 
 | 	fmovm.x		0x4(%sp),&0x80		# load ext dst | 
 | 	fsub.x		0x10(%sp),%fp0		# fsub w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fmuls_ | 
 | _fmuls_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.s		0x8(%sp),%fp0		# load sgl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fmul.s		0x8(%sp),%fp0		# fmul w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fmuld_ | 
 | _fmuld_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.d		0x8(%sp),%fp0		# load dbl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fmul.d		0xc(%sp),%fp0		# fmul w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fmulx_ | 
 | _fmulx_: | 
 | 	fmovm.x		0x4(%sp),&0x80		# load ext dst | 
 | 	fmul.x		0x10(%sp),%fp0		# fmul w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fdivs_ | 
 | _fdivs_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.s		0x8(%sp),%fp0		# load sgl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fdiv.s		0x8(%sp),%fp0		# fdiv w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fdivd_ | 
 | _fdivd_: | 
 | 	fmov.l		%fpcr,-(%sp)		# save fpcr | 
 | 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load | 
 | 	fmov.d		0x8(%sp),%fp0		# load dbl dst | 
 | 	fmov.l		(%sp)+,%fpcr		# restore fpcr | 
 | 	fdiv.d		0xc(%sp),%fp0		# fdiv w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fdivx_ | 
 | _fdivx_: | 
 | 	fmovm.x		0x4(%sp),&0x80		# load ext dst | 
 | 	fdiv.x		0x10(%sp),%fp0		# fdiv w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fabss_ | 
 | _fabss_: | 
 | 	fabs.s		0x4(%sp),%fp0		# fabs w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fabsd_ | 
 | _fabsd_: | 
 | 	fabs.d		0x4(%sp),%fp0		# fabs w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fabsx_ | 
 | _fabsx_: | 
 | 	fabs.x		0x4(%sp),%fp0		# fabs w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fnegs_ | 
 | _fnegs_: | 
 | 	fneg.s		0x4(%sp),%fp0		# fneg w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fnegd_ | 
 | _fnegd_: | 
 | 	fneg.d		0x4(%sp),%fp0		# fneg w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fnegx_ | 
 | _fnegx_: | 
 | 	fneg.x		0x4(%sp),%fp0		# fneg w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fsqrts_ | 
 | _fsqrts_: | 
 | 	fsqrt.s		0x4(%sp),%fp0		# fsqrt w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fsqrtd_ | 
 | _fsqrtd_: | 
 | 	fsqrt.d		0x4(%sp),%fp0		# fsqrt w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fsqrtx_ | 
 | _fsqrtx_: | 
 | 	fsqrt.x		0x4(%sp),%fp0		# fsqrt w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fints_ | 
 | _fints_: | 
 | 	fint.s		0x4(%sp),%fp0		# fint w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fintd_ | 
 | _fintd_: | 
 | 	fint.d		0x4(%sp),%fp0		# fint w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fintx_ | 
 | _fintx_: | 
 | 	fint.x		0x4(%sp),%fp0		# fint w/ ext src | 
 | 	rts | 
 |  | 
 | 	global		_fintrzs_ | 
 | _fintrzs_: | 
 | 	fintrz.s	0x4(%sp),%fp0		# fintrz w/ sgl src | 
 | 	rts | 
 |  | 
 | 	global		_fintrzd_ | 
 | _fintrzd_: | 
 | 	fintrz.d	0x4(%sp),%fp0		# fintrx w/ dbl src | 
 | 	rts | 
 |  | 
 | 	global		_fintrzx_ | 
 | _fintrzx_: | 
 | 	fintrz.x	0x4(%sp),%fp0		# fintrz w/ ext src | 
 | 	rts | 
 |  | 
 | ######################################################################## | 
 |  | 
 | ######################################################################### | 
 | # src_zero(): Return signed zero according to sign of src operand.	# | 
 | ######################################################################### | 
 | 	global		src_zero | 
 | src_zero: | 
 | 	tst.b		SRC_EX(%a0)		# get sign of src operand | 
 | 	bmi.b		ld_mzero		# if neg, load neg zero | 
 |  | 
 | # | 
 | # ld_pzero(): return a positive zero. | 
 | # | 
 | 	global		ld_pzero | 
 | ld_pzero: | 
 | 	fmov.s		&0x00000000,%fp0	# load +0 | 
 | 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit | 
 | 	rts | 
 |  | 
 | # ld_mzero(): return a negative zero. | 
 | 	global		ld_mzero | 
 | ld_mzero: | 
 | 	fmov.s		&0x80000000,%fp0	# load -0 | 
 | 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # dst_zero(): Return signed zero according to sign of dst operand.	# | 
 | ######################################################################### | 
 | 	global		dst_zero | 
 | dst_zero: | 
 | 	tst.b		DST_EX(%a1)		# get sign of dst operand | 
 | 	bmi.b		ld_mzero		# if neg, load neg zero | 
 | 	bra.b		ld_pzero		# load positive zero | 
 |  | 
 | ######################################################################### | 
 | # src_inf(): Return signed inf according to sign of src operand.	# | 
 | ######################################################################### | 
 | 	global		src_inf | 
 | src_inf: | 
 | 	tst.b		SRC_EX(%a0)		# get sign of src operand | 
 | 	bmi.b		ld_minf			# if negative branch | 
 |  | 
 | # | 
 | # ld_pinf(): return a positive infinity. | 
 | # | 
 | 	global		ld_pinf | 
 | ld_pinf: | 
 | 	fmov.s		&0x7f800000,%fp0	# load +INF | 
 | 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit | 
 | 	rts | 
 |  | 
 | # | 
 | # ld_minf():return a negative infinity. | 
 | # | 
 | 	global		ld_minf | 
 | ld_minf: | 
 | 	fmov.s		&0xff800000,%fp0	# load -INF | 
 | 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # dst_inf(): Return signed inf according to sign of dst operand.	# | 
 | ######################################################################### | 
 | 	global		dst_inf | 
 | dst_inf: | 
 | 	tst.b		DST_EX(%a1)		# get sign of dst operand | 
 | 	bmi.b		ld_minf			# if negative branch | 
 | 	bra.b		ld_pinf | 
 |  | 
 | 	global		szr_inf | 
 | ################################################################# | 
 | # szr_inf(): Return +ZERO for a negative src operand or		# | 
 | #	            +INF for a positive src operand.		# | 
 | #	     Routine used for fetox, ftwotox, and ftentox.	# | 
 | ################################################################# | 
 | szr_inf: | 
 | 	tst.b		SRC_EX(%a0)		# check sign of source | 
 | 	bmi.b		ld_pzero | 
 | 	bra.b		ld_pinf | 
 |  | 
 | ######################################################################### | 
 | # sopr_inf(): Return +INF for a positive src operand or			# | 
 | #	      jump to operand error routine for a negative src operand.	# | 
 | #	      Routine used for flogn, flognp1, flog10, and flog2.	# | 
 | ######################################################################### | 
 | 	global		sopr_inf | 
 | sopr_inf: | 
 | 	tst.b		SRC_EX(%a0)		# check sign of source | 
 | 	bmi.w		t_operr | 
 | 	bra.b		ld_pinf | 
 |  | 
 | ################################################################# | 
 | # setoxm1i(): Return minus one for a negative src operand or	# | 
 | #	      positive infinity for a positive src operand.	# | 
 | #	      Routine used for fetoxm1.				# | 
 | ################################################################# | 
 | 	global		setoxm1i | 
 | setoxm1i: | 
 | 	tst.b		SRC_EX(%a0)		# check sign of source | 
 | 	bmi.b		ld_mone | 
 | 	bra.b		ld_pinf | 
 |  | 
 | ######################################################################### | 
 | # src_one(): Return signed one according to sign of src operand.	# | 
 | ######################################################################### | 
 | 	global		src_one | 
 | src_one: | 
 | 	tst.b		SRC_EX(%a0)		# check sign of source | 
 | 	bmi.b		ld_mone | 
 |  | 
 | # | 
 | # ld_pone(): return positive one. | 
 | # | 
 | 	global		ld_pone | 
 | ld_pone: | 
 | 	fmov.s		&0x3f800000,%fp0	# load +1 | 
 | 	clr.b		FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | # | 
 | # ld_mone(): return negative one. | 
 | # | 
 | 	global		ld_mone | 
 | ld_mone: | 
 | 	fmov.s		&0xbf800000,%fp0	# load -1 | 
 | 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit | 
 | 	rts | 
 |  | 
 | ppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235 | 
 | mpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235 | 
 |  | 
 | ################################################################# | 
 | # spi_2(): Return signed PI/2 according to sign of src operand.	# | 
 | ################################################################# | 
 | 	global		spi_2 | 
 | spi_2: | 
 | 	tst.b		SRC_EX(%a0)		# check sign of source | 
 | 	bmi.b		ld_mpi2 | 
 |  | 
 | # | 
 | # ld_ppi2(): return positive PI/2. | 
 | # | 
 | 	global		ld_ppi2 | 
 | ld_ppi2: | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fmov.x		ppiby2(%pc),%fp0	# load +pi/2 | 
 | 	bra.w		t_pinx2			# set INEX2 | 
 |  | 
 | # | 
 | # ld_mpi2(): return negative PI/2. | 
 | # | 
 | 	global		ld_mpi2 | 
 | ld_mpi2: | 
 | 	fmov.l		%d0,%fpcr | 
 | 	fmov.x		mpiby2(%pc),%fp0	# load -pi/2 | 
 | 	bra.w		t_minx2			# set INEX2 | 
 |  | 
 | #################################################### | 
 | # The following routines give support for fsincos. # | 
 | #################################################### | 
 |  | 
 | # | 
 | # ssincosz(): When the src operand is ZERO, store a one in the | 
 | #	      cosine register and return a ZERO in fp0 w/ the same sign | 
 | #	      as the src operand. | 
 | # | 
 | 	global		ssincosz | 
 | ssincosz: | 
 | 	fmov.s		&0x3f800000,%fp1 | 
 | 	tst.b		SRC_EX(%a0)		# test sign | 
 | 	bpl.b		sincoszp | 
 | 	fmov.s		&0x80000000,%fp0	# return sin result in fp0 | 
 | 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) | 
 | 	rts | 
 | sincoszp: | 
 | 	fmov.s		&0x00000000,%fp0	# return sin result in fp0 | 
 | 	mov.b		&z_bmask,FPSR_CC(%a6) | 
 | 	rts | 
 |  | 
 | # | 
 | # ssincosi(): When the src operand is INF, store a QNAN in the cosine | 
 | #	      register and jump to the operand error routine for negative | 
 | #	      src operands. | 
 | # | 
 | 	global		ssincosi | 
 | ssincosi: | 
 | 	fmov.x		qnan(%pc),%fp1		# load NAN | 
 | 	bra.w		t_operr | 
 |  | 
 | # | 
 | # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine | 
 | #		 register and branch to the src QNAN routine. | 
 | # | 
 | 	global		ssincosqnan | 
 | ssincosqnan: | 
 | 	fmov.x		LOCAL_EX(%a0),%fp1 | 
 | 	bra.w		src_qnan | 
 |  | 
 | ######################################################################## | 
 |  | 
 | 	global		smod_sdnrm | 
 | 	global		smod_snorm | 
 | smod_sdnrm: | 
 | smod_snorm: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		smod | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.w		smod_zro | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		smod | 
 | 	bra.l		dst_qnan | 
 |  | 
 | 	global		smod_szero | 
 | smod_szero: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		t_operr | 
 | 	bra.l		dst_qnan | 
 |  | 
 | 	global		smod_sinf | 
 | smod_sinf: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		smod_fpn | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.l		smod_zro | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		smod_fpn | 
 | 	bra.l		dst_qnan | 
 |  | 
 | smod_zro: | 
 | srem_zro: | 
 | 	mov.b		SRC_EX(%a0),%d1		# get src sign | 
 | 	mov.b		DST_EX(%a1),%d0		# get dst sign | 
 | 	eor.b		%d0,%d1			# get qbyte sign | 
 | 	andi.b		&0x80,%d1 | 
 | 	mov.b		%d1,FPSR_QBYTE(%a6) | 
 | 	tst.b		%d0 | 
 | 	bpl.w		ld_pzero | 
 | 	bra.w		ld_mzero | 
 |  | 
 | smod_fpn: | 
 | srem_fpn: | 
 | 	clr.b		FPSR_QBYTE(%a6) | 
 | 	mov.l		%d0,-(%sp) | 
 | 	mov.b		SRC_EX(%a0),%d1		# get src sign | 
 | 	mov.b		DST_EX(%a1),%d0		# get dst sign | 
 | 	eor.b		%d0,%d1			# get qbyte sign | 
 | 	andi.b		&0x80,%d1 | 
 | 	mov.b		%d1,FPSR_QBYTE(%a6) | 
 | 	cmpi.b		DTAG(%a6),&DENORM | 
 | 	bne.b		smod_nrm | 
 | 	lea		DST(%a1),%a0 | 
 | 	mov.l		(%sp)+,%d0 | 
 | 	bra		t_resdnrm | 
 | smod_nrm: | 
 | 	fmov.l		(%sp)+,%fpcr | 
 | 	fmov.x		DST(%a1),%fp0 | 
 | 	tst.b		DST_EX(%a1) | 
 | 	bmi.b		smod_nrm_neg | 
 | 	rts | 
 |  | 
 | smod_nrm_neg: | 
 | 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' code | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | 	global		srem_snorm | 
 | 	global		srem_sdnrm | 
 | srem_sdnrm: | 
 | srem_snorm: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		srem | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.w		srem_zro | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		srem | 
 | 	bra.l		dst_qnan | 
 |  | 
 | 	global		srem_szero | 
 | srem_szero: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		t_operr | 
 | 	bra.l		dst_qnan | 
 |  | 
 | 	global		srem_sinf | 
 | srem_sinf: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.w		srem_fpn | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.w		srem_zro | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		srem_fpn | 
 | 	bra.l		dst_qnan | 
 |  | 
 | ######################################################################### | 
 |  | 
 | 	global		sscale_snorm | 
 | 	global		sscale_sdnrm | 
 | sscale_snorm: | 
 | sscale_sdnrm: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		sscale | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.l		dst_zero | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		dst_inf | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		sscale | 
 | 	bra.l		dst_qnan | 
 |  | 
 | 	global		sscale_szero | 
 | sscale_szero: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		sscale | 
 | 	cmpi.b		%d1,&ZERO | 
 | 	beq.l		dst_zero | 
 | 	cmpi.b		%d1,&INF | 
 | 	beq.l		dst_inf | 
 | 	cmpi.b		%d1,&DENORM | 
 | 	beq.l		sscale | 
 | 	bra.l		dst_qnan | 
 |  | 
 | 	global		sscale_sinf | 
 | sscale_sinf: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	beq.l		t_operr | 
 | 	cmpi.b		%d1,&QNAN | 
 | 	beq.l		dst_qnan | 
 | 	bra.l		t_operr | 
 |  | 
 | ######################################################################## | 
 |  | 
 | 	global		sop_sqnan | 
 | sop_sqnan: | 
 | 	mov.b		DTAG(%a6),%d1 | 
 | 	cmpi.b		%d1,&QNAN | 
 | 	beq.l		dst_qnan | 
 | 	bra.l		src_qnan | 
 |  | 
 | ######################################################################### | 
 | # norm(): normalize the mantissa of an extended precision input. the	# | 
 | #	  input operand should not be normalized already.		# | 
 | #									# | 
 | # XDEF ****************************************************************	# | 
 | #	norm()								# | 
 | #									# | 
 | # XREF **************************************************************** # | 
 | #	none								# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer fp extended precision operand to normalize		# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	d0 = number of bit positions the mantissa was shifted		# | 
 | #	a0 = the input operand's mantissa is normalized; the exponent	# | 
 | #	     is unchanged.						# | 
 | #									# | 
 | ######################################################################### | 
 | 	global		norm | 
 | norm: | 
 | 	mov.l		%d2, -(%sp)		# create some temp regs | 
 | 	mov.l		%d3, -(%sp) | 
 |  | 
 | 	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa) | 
 | 	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa) | 
 |  | 
 | 	bfffo		%d0{&0:&32}, %d2	# how many places to shift? | 
 | 	beq.b		norm_lo			# hi(man) is all zeroes! | 
 |  | 
 | norm_hi: | 
 | 	lsl.l		%d2, %d0		# left shift hi(man) | 
 | 	bfextu		%d1{&0:%d2}, %d3	# extract lo bits | 
 |  | 
 | 	or.l		%d3, %d0		# create hi(man) | 
 | 	lsl.l		%d2, %d1		# create lo(man) | 
 |  | 
 | 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man) | 
 | 	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man) | 
 |  | 
 | 	mov.l		%d2, %d0		# return shift amount | 
 |  | 
 | 	mov.l		(%sp)+, %d3		# restore temp regs | 
 | 	mov.l		(%sp)+, %d2 | 
 |  | 
 | 	rts | 
 |  | 
 | norm_lo: | 
 | 	bfffo		%d1{&0:&32}, %d2	# how many places to shift? | 
 | 	lsl.l		%d2, %d1		# shift lo(man) | 
 | 	add.l		&32, %d2		# add 32 to shft amount | 
 |  | 
 | 	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man) | 
 | 	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero | 
 |  | 
 | 	mov.l		%d2, %d0		# return shift amount | 
 |  | 
 | 	mov.l		(%sp)+, %d3		# restore temp regs | 
 | 	mov.l		(%sp)+, %d2 | 
 |  | 
 | 	rts | 
 |  | 
 | ######################################################################### | 
 | # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	# | 
 | #		- returns corresponding optype tag			# | 
 | #									# | 
 | # XDEF ****************************************************************	# | 
 | #	unnorm_fix()							# | 
 | #									# | 
 | # XREF **************************************************************** # | 
 | #	norm() - normalize the mantissa					# | 
 | #									# | 
 | # INPUT *************************************************************** # | 
 | #	a0 = pointer to unnormalized extended precision number		# | 
 | #									# | 
 | # OUTPUT ************************************************************** # | 
 | #	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	# | 
 | #	a0 = input operand has been converted to a norm, denorm, or	# | 
 | #	     zero; both the exponent and mantissa are changed.		# | 
 | #									# | 
 | ######################################################################### | 
 |  | 
 | 	global		unnorm_fix | 
 | unnorm_fix: | 
 | 	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed? | 
 | 	bne.b		unnorm_shift		# hi(man) is not all zeroes | 
 |  | 
 | # | 
 | # hi(man) is all zeroes so see if any bits in lo(man) are set | 
 | # | 
 | unnorm_chk_lo: | 
 | 	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero? | 
 | 	beq.w		unnorm_zero		# yes | 
 |  | 
 | 	add.w		&32, %d0		# no; fix shift distance | 
 |  | 
 | # | 
 | # d0 = # shifts needed for complete normalization | 
 | # | 
 | unnorm_shift: | 
 | 	clr.l		%d1			# clear top word | 
 | 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent | 
 | 	and.w		&0x7fff, %d1		# strip off sgn | 
 |  | 
 | 	cmp.w		%d0, %d1		# will denorm push exp < 0? | 
 | 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0 | 
 |  | 
 | # | 
 | # exponent would not go < 0. therefore, number stays normalized | 
 | # | 
 | 	sub.w		%d0, %d1		# shift exponent value | 
 | 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent | 
 | 	and.w		&0x8000, %d0		# save old sign | 
 | 	or.w		%d0, %d1		# {sgn,new exp} | 
 | 	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent | 
 |  | 
 | 	bsr.l		norm			# normalize UNNORM | 
 |  | 
 | 	mov.b		&NORM, %d0		# return new optype tag | 
 | 	rts | 
 |  | 
 | # | 
 | # exponent would go < 0, so only denormalize until exp = 0 | 
 | # | 
 | unnorm_nrm_zero: | 
 | 	cmp.b		%d1, &32		# is exp <= 32? | 
 | 	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent | 
 |  | 
 | 	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man) | 
 | 	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man) | 
 |  | 
 | 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man) | 
 | 	lsl.l		%d1, %d0		# extract new lo(man) | 
 | 	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man) | 
 |  | 
 | 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0 | 
 |  | 
 | 	mov.b		&DENORM, %d0		# return new optype tag | 
 | 	rts | 
 |  | 
 | # | 
 | # only mantissa bits set are in lo(man) | 
 | # | 
 | unnorm_nrm_zero_lrg: | 
 | 	sub.w		&32, %d1		# adjust shft amt by 32 | 
 |  | 
 | 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man) | 
 | 	lsl.l		%d1, %d0		# left shift lo(man) | 
 |  | 
 | 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man) | 
 | 	clr.l		FTEMP_LO(%a0)		# lo(man) = 0 | 
 |  | 
 | 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0 | 
 |  | 
 | 	mov.b		&DENORM, %d0		# return new optype tag | 
 | 	rts | 
 |  | 
 | # | 
 | # whole mantissa is zero so this UNNORM is actually a zero | 
 | # | 
 | unnorm_zero: | 
 | 	and.w		&0x8000, FTEMP_EX(%a0)	# force exponent to zero | 
 |  | 
 | 	mov.b		&ZERO, %d0		# fix optype tag | 
 | 	rts |