File Index
Files and directories
Sign in
FILE

fplsp.S

File preview with syntax highlighting.

linux-6.19.14/arch/m68k/ifpsp060/src/fplsp.S S
    1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
    3M68000 Hi-Performance Microprocessor Division
    4M68060 Software Package
    5Production Release P1.00 -- October 10, 1994
    6
    7M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
    8
    9THE SOFTWARE is provided on an "AS IS" basis and without warranty.
   10To the maximum extent permitted by applicable law,
   11MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
   12INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
   13and any warranty against infringement with regard to the SOFTWARE
   14(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
   15
   16To the maximum extent permitted by applicable law,
   17IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
   18(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
   19BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
   20ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
   21Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
   22
   23You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
   24so long as this entire notice is retained without alteration in any modified and/or
   25redistributed versions, and that such modified versions are clearly identified as such.
   26No licenses are granted by implication, estoppel or otherwise under any patents
   27or trademarks of Motorola, Inc.
   28~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   29#
   30# lfptop.s:
   31#	This file is appended to the top of the 060ILSP package
   32# and contains the entry points into the package. The user, in
   33# effect, branches to one of the branch table entries located here.
   34#
   35
   36	bra.l	_facoss_
   37	short	0x0000
   38	bra.l	_facosd_
   39	short	0x0000
   40	bra.l	_facosx_
   41	short	0x0000
   42
   43	bra.l	_fasins_
   44	short	0x0000
   45	bra.l	_fasind_
   46	short	0x0000
   47	bra.l	_fasinx_
   48	short	0x0000
   49
   50	bra.l	_fatans_
   51	short	0x0000
   52	bra.l	_fatand_
   53	short	0x0000
   54	bra.l	_fatanx_
   55	short	0x0000
   56
   57	bra.l	_fatanhs_
   58	short	0x0000
   59	bra.l	_fatanhd_
   60	short	0x0000
   61	bra.l	_fatanhx_
   62	short	0x0000
   63
   64	bra.l	_fcoss_
   65	short	0x0000
   66	bra.l	_fcosd_
   67	short	0x0000
   68	bra.l	_fcosx_
   69	short	0x0000
   70
   71	bra.l	_fcoshs_
   72	short	0x0000
   73	bra.l	_fcoshd_
   74	short	0x0000
   75	bra.l	_fcoshx_
   76	short	0x0000
   77
   78	bra.l	_fetoxs_
   79	short	0x0000
   80	bra.l	_fetoxd_
   81	short	0x0000
   82	bra.l	_fetoxx_
   83	short	0x0000
   84
   85	bra.l	_fetoxm1s_
   86	short	0x0000
   87	bra.l	_fetoxm1d_
   88	short	0x0000
   89	bra.l	_fetoxm1x_
   90	short	0x0000
   91
   92	bra.l	_fgetexps_
   93	short	0x0000
   94	bra.l	_fgetexpd_
   95	short	0x0000
   96	bra.l	_fgetexpx_
   97	short	0x0000
   98
   99	bra.l	_fgetmans_
  100	short	0x0000
  101	bra.l	_fgetmand_
  102	short	0x0000
  103	bra.l	_fgetmanx_
  104	short	0x0000
  105
  106	bra.l	_flog10s_
  107	short	0x0000
  108	bra.l	_flog10d_
  109	short	0x0000
  110	bra.l	_flog10x_
  111	short	0x0000
  112
  113	bra.l	_flog2s_
  114	short	0x0000
  115	bra.l	_flog2d_
  116	short	0x0000
  117	bra.l	_flog2x_
  118	short	0x0000
  119
  120	bra.l	_flogns_
  121	short	0x0000
  122	bra.l	_flognd_
  123	short	0x0000
  124	bra.l	_flognx_
  125	short	0x0000
  126
  127	bra.l	_flognp1s_
  128	short	0x0000
  129	bra.l	_flognp1d_
  130	short	0x0000
  131	bra.l	_flognp1x_
  132	short	0x0000
  133
  134	bra.l	_fmods_
  135	short	0x0000
  136	bra.l	_fmodd_
  137	short	0x0000
  138	bra.l	_fmodx_
  139	short	0x0000
  140
  141	bra.l	_frems_
  142	short	0x0000
  143	bra.l	_fremd_
  144	short	0x0000
  145	bra.l	_fremx_
  146	short	0x0000
  147
  148	bra.l	_fscales_
  149	short	0x0000
  150	bra.l	_fscaled_
  151	short	0x0000
  152	bra.l	_fscalex_
  153	short	0x0000
  154
  155	bra.l	_fsins_
  156	short	0x0000
  157	bra.l	_fsind_
  158	short	0x0000
  159	bra.l	_fsinx_
  160	short	0x0000
  161
  162	bra.l	_fsincoss_
  163	short	0x0000
  164	bra.l	_fsincosd_
  165	short	0x0000
  166	bra.l	_fsincosx_
  167	short	0x0000
  168
  169	bra.l	_fsinhs_
  170	short	0x0000
  171	bra.l	_fsinhd_
  172	short	0x0000
  173	bra.l	_fsinhx_
  174	short	0x0000
  175
  176	bra.l	_ftans_
  177	short	0x0000
  178	bra.l	_ftand_
  179	short	0x0000
  180	bra.l	_ftanx_
  181	short	0x0000
  182
  183	bra.l	_ftanhs_
  184	short	0x0000
  185	bra.l	_ftanhd_
  186	short	0x0000
  187	bra.l	_ftanhx_
  188	short	0x0000
  189
  190	bra.l	_ftentoxs_
  191	short	0x0000
  192	bra.l	_ftentoxd_
  193	short	0x0000
  194	bra.l	_ftentoxx_
  195	short	0x0000
  196
  197	bra.l	_ftwotoxs_
  198	short	0x0000
  199	bra.l	_ftwotoxd_
  200	short	0x0000
  201	bra.l	_ftwotoxx_
  202	short	0x0000
  203
  204	bra.l	_fabss_
  205	short	0x0000
  206	bra.l	_fabsd_
  207	short	0x0000
  208	bra.l	_fabsx_
  209	short	0x0000
  210
  211	bra.l	_fadds_
  212	short	0x0000
  213	bra.l	_faddd_
  214	short	0x0000
  215	bra.l	_faddx_
  216	short	0x0000
  217
  218	bra.l	_fdivs_
  219	short	0x0000
  220	bra.l	_fdivd_
  221	short	0x0000
  222	bra.l	_fdivx_
  223	short	0x0000
  224
  225	bra.l	_fints_
  226	short	0x0000
  227	bra.l	_fintd_
  228	short	0x0000
  229	bra.l	_fintx_
  230	short	0x0000
  231
  232	bra.l	_fintrzs_
  233	short	0x0000
  234	bra.l	_fintrzd_
  235	short	0x0000
  236	bra.l	_fintrzx_
  237	short	0x0000
  238
  239	bra.l	_fmuls_
  240	short	0x0000
  241	bra.l	_fmuld_
  242	short	0x0000
  243	bra.l	_fmulx_
  244	short	0x0000
  245
  246	bra.l	_fnegs_
  247	short	0x0000
  248	bra.l	_fnegd_
  249	short	0x0000
  250	bra.l	_fnegx_
  251	short	0x0000
  252
  253	bra.l	_fsqrts_
  254	short	0x0000
  255	bra.l	_fsqrtd_
  256	short	0x0000
  257	bra.l	_fsqrtx_
  258	short	0x0000
  259
  260	bra.l	_fsubs_
  261	short	0x0000
  262	bra.l	_fsubd_
  263	short	0x0000
  264	bra.l	_fsubx_
  265	short	0x0000
  266
  267# leave room for future possible additions
  268	align	0x400
  269
  270#
  271# This file contains a set of define statements for constants
  272# in order to promote readability within the corecode itself.
  273#
  274
  275set LOCAL_SIZE,		192			# stack frame size(bytes)
  276set LV,			-LOCAL_SIZE		# stack offset
  277
  278set EXC_SR,		0x4			# stack status register
  279set EXC_PC,		0x6			# stack pc
  280set EXC_VOFF,		0xa			# stacked vector offset
  281set EXC_EA,		0xc			# stacked <ea>
  282
  283set EXC_FP,		0x0			# frame pointer
  284
  285set EXC_AREGS,		-68			# offset of all address regs
  286set EXC_DREGS,		-100			# offset of all data regs
  287set EXC_FPREGS,		-36			# offset of all fp regs
  288
  289set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
  290set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
  291set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
  292set EXC_A5,		EXC_AREGS+(5*4)
  293set EXC_A4,		EXC_AREGS+(4*4)
  294set EXC_A3,		EXC_AREGS+(3*4)
  295set EXC_A2,		EXC_AREGS+(2*4)
  296set EXC_A1,		EXC_AREGS+(1*4)
  297set EXC_A0,		EXC_AREGS+(0*4)
  298set EXC_D7,		EXC_DREGS+(7*4)
  299set EXC_D6,		EXC_DREGS+(6*4)
  300set EXC_D5,		EXC_DREGS+(5*4)
  301set EXC_D4,		EXC_DREGS+(4*4)
  302set EXC_D3,		EXC_DREGS+(3*4)
  303set EXC_D2,		EXC_DREGS+(2*4)
  304set EXC_D1,		EXC_DREGS+(1*4)
  305set EXC_D0,		EXC_DREGS+(0*4)
  306
  307set EXC_FP0,		EXC_FPREGS+(0*12)	# offset of saved fp0
  308set EXC_FP1,		EXC_FPREGS+(1*12)	# offset of saved fp1
  309set EXC_FP2,		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
  310
  311set FP_SCR1,		LV+80			# fp scratch 1
  312set FP_SCR1_EX,		FP_SCR1+0
  313set FP_SCR1_SGN,	FP_SCR1+2
  314set FP_SCR1_HI,		FP_SCR1+4
  315set FP_SCR1_LO,		FP_SCR1+8
  316
  317set FP_SCR0,		LV+68			# fp scratch 0
  318set FP_SCR0_EX,		FP_SCR0+0
  319set FP_SCR0_SGN,	FP_SCR0+2
  320set FP_SCR0_HI,		FP_SCR0+4
  321set FP_SCR0_LO,		FP_SCR0+8
  322
  323set FP_DST,		LV+56			# fp destination operand
  324set FP_DST_EX,		FP_DST+0
  325set FP_DST_SGN,		FP_DST+2
  326set FP_DST_HI,		FP_DST+4
  327set FP_DST_LO,		FP_DST+8
  328
  329set FP_SRC,		LV+44			# fp source operand
  330set FP_SRC_EX,		FP_SRC+0
  331set FP_SRC_SGN,		FP_SRC+2
  332set FP_SRC_HI,		FP_SRC+4
  333set FP_SRC_LO,		FP_SRC+8
  334
  335set USER_FPIAR,		LV+40			# FP instr address register
  336
  337set USER_FPSR,		LV+36			# FP status register
  338set FPSR_CC,		USER_FPSR+0		# FPSR condition codes
  339set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
  340set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
  341set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
  342
  343set USER_FPCR,		LV+32			# FP control register
  344set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
  345set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
  346
  347set L_SCR3,		LV+28			# integer scratch 3
  348set L_SCR2,		LV+24			# integer scratch 2
  349set L_SCR1,		LV+20			# integer scratch 1
  350
  351set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
  352
  353set EXC_TEMP2,		LV+24			# temporary space
  354set EXC_TEMP,		LV+16			# temporary space
  355
  356set DTAG,		LV+15			# destination operand type
  357set STAG,		LV+14			# source operand type
  358
  359set SPCOND_FLG,		LV+10			# flag: special case (see below)
  360
  361set EXC_CC,		LV+8			# saved condition codes
  362set EXC_EXTWPTR,	LV+4			# saved current PC (active)
  363set EXC_EXTWORD,	LV+2			# saved extension word
  364set EXC_CMDREG,		LV+2			# saved extension word
  365set EXC_OPWORD,		LV+0			# saved operation word
  366
  367################################
  368
  369# Helpful macros
  370
  371set FTEMP,		0			# offsets within an
  372set FTEMP_EX,		0			# extended precision
  373set FTEMP_SGN,		2			# value saved in memory.
  374set FTEMP_HI,		4
  375set FTEMP_LO,		8
  376set FTEMP_GRS,		12
  377
  378set LOCAL,		0			# offsets within an
  379set LOCAL_EX,		0			# extended precision
  380set LOCAL_SGN,		2			# value saved in memory.
  381set LOCAL_HI,		4
  382set LOCAL_LO,		8
  383set LOCAL_GRS,		12
  384
  385set DST,		0			# offsets within an
  386set DST_EX,		0			# extended precision
  387set DST_HI,		4			# value saved in memory.
  388set DST_LO,		8
  389
  390set SRC,		0			# offsets within an
  391set SRC_EX,		0			# extended precision
  392set SRC_HI,		4			# value saved in memory.
  393set SRC_LO,		8
  394
  395set SGL_LO,		0x3f81			# min sgl prec exponent
  396set SGL_HI,		0x407e			# max sgl prec exponent
  397set DBL_LO,		0x3c01			# min dbl prec exponent
  398set DBL_HI,		0x43fe			# max dbl prec exponent
  399set EXT_LO,		0x0			# min ext prec exponent
  400set EXT_HI,		0x7ffe			# max ext prec exponent
  401
  402set EXT_BIAS,		0x3fff			# extended precision bias
  403set SGL_BIAS,		0x007f			# single precision bias
  404set DBL_BIAS,		0x03ff			# double precision bias
  405
  406set NORM,		0x00			# operand type for STAG/DTAG
  407set ZERO,		0x01			# operand type for STAG/DTAG
  408set INF,		0x02			# operand type for STAG/DTAG
  409set QNAN,		0x03			# operand type for STAG/DTAG
  410set DENORM,		0x04			# operand type for STAG/DTAG
  411set SNAN,		0x05			# operand type for STAG/DTAG
  412set UNNORM,		0x06			# operand type for STAG/DTAG
  413
  414##################
  415# FPSR/FPCR bits #
  416##################
  417set neg_bit,		0x3			# negative result
  418set z_bit,		0x2			# zero result
  419set inf_bit,		0x1			# infinite result
  420set nan_bit,		0x0			# NAN result
  421
  422set q_sn_bit,		0x7			# sign bit of quotient byte
  423
  424set bsun_bit,		7			# branch on unordered
  425set snan_bit,		6			# signalling NAN
  426set operr_bit,		5			# operand error
  427set ovfl_bit,		4			# overflow
  428set unfl_bit,		3			# underflow
  429set dz_bit,		2			# divide by zero
  430set inex2_bit,		1			# inexact result 2
  431set inex1_bit,		0			# inexact result 1
  432
  433set aiop_bit,		7			# accrued inexact operation bit
  434set aovfl_bit,		6			# accrued overflow bit
  435set aunfl_bit,		5			# accrued underflow bit
  436set adz_bit,		4			# accrued dz bit
  437set ainex_bit,		3			# accrued inexact bit
  438
  439#############################
  440# FPSR individual bit masks #
  441#############################
  442set neg_mask,		0x08000000		# negative bit mask (lw)
  443set inf_mask,		0x02000000		# infinity bit mask (lw)
  444set z_mask,		0x04000000		# zero bit mask (lw)
  445set nan_mask,		0x01000000		# nan bit mask (lw)
  446
  447set neg_bmask,		0x08			# negative bit mask (byte)
  448set inf_bmask,		0x02			# infinity bit mask (byte)
  449set z_bmask,		0x04			# zero bit mask (byte)
  450set nan_bmask,		0x01			# nan bit mask (byte)
  451
  452set bsun_mask,		0x00008000		# bsun exception mask
  453set snan_mask,		0x00004000		# snan exception mask
  454set operr_mask,		0x00002000		# operr exception mask
  455set ovfl_mask,		0x00001000		# overflow exception mask
  456set unfl_mask,		0x00000800		# underflow exception mask
  457set dz_mask,		0x00000400		# dz exception mask
  458set inex2_mask,		0x00000200		# inex2 exception mask
  459set inex1_mask,		0x00000100		# inex1 exception mask
  460
  461set aiop_mask,		0x00000080		# accrued illegal operation
  462set aovfl_mask,		0x00000040		# accrued overflow
  463set aunfl_mask,		0x00000020		# accrued underflow
  464set adz_mask,		0x00000010		# accrued divide by zero
  465set ainex_mask,		0x00000008		# accrued inexact
  466
  467######################################
  468# FPSR combinations used in the FPSP #
  469######################################
  470set dzinf_mask,		inf_mask+dz_mask+adz_mask
  471set opnan_mask,		nan_mask+operr_mask+aiop_mask
  472set nzi_mask,		0x01ffffff		#clears N, Z, and I
  473set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
  474set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
  475set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
  476set inx1a_mask,		inex1_mask+ainex_mask
  477set inx2a_mask,		inex2_mask+ainex_mask
  478set snaniop_mask,	nan_mask+snan_mask+aiop_mask
  479set snaniop2_mask,	snan_mask+aiop_mask
  480set naniop_mask,	nan_mask+aiop_mask
  481set neginf_mask,	neg_mask+inf_mask
  482set infaiop_mask,	inf_mask+aiop_mask
  483set negz_mask,		neg_mask+z_mask
  484set opaop_mask,		operr_mask+aiop_mask
  485set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
  486set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
  487
  488#########
  489# misc. #
  490#########
  491set rnd_stky_bit,	29			# stky bit pos in longword
  492
  493set sign_bit,		0x7			# sign bit
  494set signan_bit,		0x6			# signalling nan bit
  495
  496set sgl_thresh,		0x3f81			# minimum sgl exponent
  497set dbl_thresh,		0x3c01			# minimum dbl exponent
  498
  499set x_mode,		0x0			# extended precision
  500set s_mode,		0x4			# single precision
  501set d_mode,		0x8			# double precision
  502
  503set rn_mode,		0x0			# round-to-nearest
  504set rz_mode,		0x1			# round-to-zero
  505set rm_mode,		0x2			# round-tp-minus-infinity
  506set rp_mode,		0x3			# round-to-plus-infinity
  507
  508set mantissalen,	64			# length of mantissa in bits
  509
  510set BYTE,		1			# len(byte) == 1 byte
  511set WORD,		2			# len(word) == 2 bytes
  512set LONG,		4			# len(longword) == 2 bytes
  513
  514set BSUN_VEC,		0xc0			# bsun    vector offset
  515set INEX_VEC,		0xc4			# inexact vector offset
  516set DZ_VEC,		0xc8			# dz      vector offset
  517set UNFL_VEC,		0xcc			# unfl    vector offset
  518set OPERR_VEC,		0xd0			# operr   vector offset
  519set OVFL_VEC,		0xd4			# ovfl    vector offset
  520set SNAN_VEC,		0xd8			# snan    vector offset
  521
  522###########################
  523# SPecial CONDition FLaGs #
  524###########################
  525set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
  526set fbsun_flg,		0x02			# flag bit: bsun exception
  527set mia7_flg,		0x04			# flag bit: (a7)+ <ea>
  528set mda7_flg,		0x08			# flag bit: -(a7) <ea>
  529set fmovm_flg,		0x40			# flag bit: fmovm instruction
  530set immed_flg,		0x80			# flag bit: &<data> <ea>
  531
  532set ftrapcc_bit,	0x0
  533set fbsun_bit,		0x1
  534set mia7_bit,		0x2
  535set mda7_bit,		0x3
  536set immed_bit,		0x7
  537
  538##################################
  539# TRANSCENDENTAL "LAST-OP" FLAGS #
  540##################################
  541set FMUL_OP,		0x0			# fmul instr performed last
  542set FDIV_OP,		0x1			# fdiv performed last
  543set FADD_OP,		0x2			# fadd performed last
  544set FMOV_OP,		0x3			# fmov performed last
  545
  546#############
  547# CONSTANTS #
  548#############
  549T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
  550T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
  551
  552PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
  553PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
  554
  555TWOBYPI:
  556	long		0x3FE45F30,0x6DC9C883
  557
  558#########################################################################
  559# MONADIC TEMPLATE							#
  560#########################################################################
  561	global		_fsins_
  562_fsins_:
  563	link		%a6,&-LOCAL_SIZE
  564
  565	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  566	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  567	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  568
  569	fmov.l		&0x0,%fpcr		# zero FPCR
  570
  571#
  572#	copy, convert, and tag input argument
  573#
  574	fmov.s		0x8(%a6),%fp0		# load sgl input
  575	fmov.x		%fp0,FP_SRC(%a6)
  576	lea		FP_SRC(%a6),%a0
  577	bsr.l		tag			# fetch operand type
  578	mov.b		%d0,STAG(%a6)
  579	mov.b		%d0,%d1
  580
  581	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  582
  583	clr.l		%d0
  584	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  585
  586	tst.b		%d1
  587	bne.b		_L0_2s
  588	bsr.l		ssin			# operand is a NORM
  589	bra.b		_L0_6s
  590_L0_2s:
  591	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  592	bne.b		_L0_3s			# no
  593	bsr.l		src_zero			# yes
  594	bra.b		_L0_6s
  595_L0_3s:
  596	cmpi.b		%d1,&INF		# is operand an INF?
  597	bne.b		_L0_4s			# no
  598	bsr.l		t_operr			# yes
  599	bra.b		_L0_6s
  600_L0_4s:
  601	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  602	bne.b		_L0_5s			# no
  603	bsr.l		src_qnan			# yes
  604	bra.b		_L0_6s
  605_L0_5s:
  606	bsr.l		ssind			# operand is a DENORM
  607_L0_6s:
  608
  609#
  610#	Result is now in FP0
  611#
  612	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  613	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  614	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  615	unlk		%a6
  616	rts
  617
  618	global		_fsind_
  619_fsind_:
  620	link		%a6,&-LOCAL_SIZE
  621
  622	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  623	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  624	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  625
  626	fmov.l		&0x0,%fpcr		# zero FPCR
  627
  628#
  629#	copy, convert, and tag input argument
  630#
  631	fmov.d		0x8(%a6),%fp0		# load dbl input
  632	fmov.x		%fp0,FP_SRC(%a6)
  633	lea		FP_SRC(%a6),%a0
  634	bsr.l		tag			# fetch operand type
  635	mov.b		%d0,STAG(%a6)
  636	mov.b		%d0,%d1
  637
  638	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  639
  640	clr.l		%d0
  641	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  642
  643	mov.b		%d1,STAG(%a6)
  644	tst.b		%d1
  645	bne.b		_L0_2d
  646	bsr.l		ssin			# operand is a NORM
  647	bra.b		_L0_6d
  648_L0_2d:
  649	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  650	bne.b		_L0_3d			# no
  651	bsr.l		src_zero			# yes
  652	bra.b		_L0_6d
  653_L0_3d:
  654	cmpi.b		%d1,&INF		# is operand an INF?
  655	bne.b		_L0_4d			# no
  656	bsr.l		t_operr			# yes
  657	bra.b		_L0_6d
  658_L0_4d:
  659	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  660	bne.b		_L0_5d			# no
  661	bsr.l		src_qnan			# yes
  662	bra.b		_L0_6d
  663_L0_5d:
  664	bsr.l		ssind			# operand is a DENORM
  665_L0_6d:
  666
  667#
  668#	Result is now in FP0
  669#
  670	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  671	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  672	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  673	unlk		%a6
  674	rts
  675
  676	global		_fsinx_
  677_fsinx_:
  678	link		%a6,&-LOCAL_SIZE
  679
  680	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  681	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  682	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  683
  684	fmov.l		&0x0,%fpcr		# zero FPCR
  685
  686#
  687#	copy, convert, and tag input argument
  688#
  689	lea		FP_SRC(%a6),%a0
  690	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
  691	mov.l		0x8+0x4(%a6),0x4(%a0)
  692	mov.l		0x8+0x8(%a6),0x8(%a0)
  693	bsr.l		tag			# fetch operand type
  694	mov.b		%d0,STAG(%a6)
  695	mov.b		%d0,%d1
  696
  697	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  698
  699	clr.l		%d0
  700	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  701
  702	tst.b		%d1
  703	bne.b		_L0_2x
  704	bsr.l		ssin			# operand is a NORM
  705	bra.b		_L0_6x
  706_L0_2x:
  707	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  708	bne.b		_L0_3x			# no
  709	bsr.l		src_zero			# yes
  710	bra.b		_L0_6x
  711_L0_3x:
  712	cmpi.b		%d1,&INF		# is operand an INF?
  713	bne.b		_L0_4x			# no
  714	bsr.l		t_operr			# yes
  715	bra.b		_L0_6x
  716_L0_4x:
  717	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  718	bne.b		_L0_5x			# no
  719	bsr.l		src_qnan			# yes
  720	bra.b		_L0_6x
  721_L0_5x:
  722	bsr.l		ssind			# operand is a DENORM
  723_L0_6x:
  724
  725#
  726#	Result is now in FP0
  727#
  728	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  729	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  730	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  731	unlk		%a6
  732	rts
  733
  734
  735#########################################################################
  736# MONADIC TEMPLATE							#
  737#########################################################################
  738	global		_fcoss_
  739_fcoss_:
  740	link		%a6,&-LOCAL_SIZE
  741
  742	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  743	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  744	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  745
  746	fmov.l		&0x0,%fpcr		# zero FPCR
  747
  748#
  749#	copy, convert, and tag input argument
  750#
  751	fmov.s		0x8(%a6),%fp0		# load sgl input
  752	fmov.x		%fp0,FP_SRC(%a6)
  753	lea		FP_SRC(%a6),%a0
  754	bsr.l		tag			# fetch operand type
  755	mov.b		%d0,STAG(%a6)
  756	mov.b		%d0,%d1
  757
  758	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  759
  760	clr.l		%d0
  761	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  762
  763	tst.b		%d1
  764	bne.b		_L1_2s
  765	bsr.l		scos			# operand is a NORM
  766	bra.b		_L1_6s
  767_L1_2s:
  768	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  769	bne.b		_L1_3s			# no
  770	bsr.l		ld_pone			# yes
  771	bra.b		_L1_6s
  772_L1_3s:
  773	cmpi.b		%d1,&INF		# is operand an INF?
  774	bne.b		_L1_4s			# no
  775	bsr.l		t_operr			# yes
  776	bra.b		_L1_6s
  777_L1_4s:
  778	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  779	bne.b		_L1_5s			# no
  780	bsr.l		src_qnan			# yes
  781	bra.b		_L1_6s
  782_L1_5s:
  783	bsr.l		scosd			# operand is a DENORM
  784_L1_6s:
  785
  786#
  787#	Result is now in FP0
  788#
  789	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  790	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  791	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  792	unlk		%a6
  793	rts
  794
  795	global		_fcosd_
  796_fcosd_:
  797	link		%a6,&-LOCAL_SIZE
  798
  799	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  800	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  801	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  802
  803	fmov.l		&0x0,%fpcr		# zero FPCR
  804
  805#
  806#	copy, convert, and tag input argument
  807#
  808	fmov.d		0x8(%a6),%fp0		# load dbl input
  809	fmov.x		%fp0,FP_SRC(%a6)
  810	lea		FP_SRC(%a6),%a0
  811	bsr.l		tag			# fetch operand type
  812	mov.b		%d0,STAG(%a6)
  813	mov.b		%d0,%d1
  814
  815	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  816
  817	clr.l		%d0
  818	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  819
  820	mov.b		%d1,STAG(%a6)
  821	tst.b		%d1
  822	bne.b		_L1_2d
  823	bsr.l		scos			# operand is a NORM
  824	bra.b		_L1_6d
  825_L1_2d:
  826	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  827	bne.b		_L1_3d			# no
  828	bsr.l		ld_pone			# yes
  829	bra.b		_L1_6d
  830_L1_3d:
  831	cmpi.b		%d1,&INF		# is operand an INF?
  832	bne.b		_L1_4d			# no
  833	bsr.l		t_operr			# yes
  834	bra.b		_L1_6d
  835_L1_4d:
  836	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  837	bne.b		_L1_5d			# no
  838	bsr.l		src_qnan			# yes
  839	bra.b		_L1_6d
  840_L1_5d:
  841	bsr.l		scosd			# operand is a DENORM
  842_L1_6d:
  843
  844#
  845#	Result is now in FP0
  846#
  847	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  848	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  849	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  850	unlk		%a6
  851	rts
  852
  853	global		_fcosx_
  854_fcosx_:
  855	link		%a6,&-LOCAL_SIZE
  856
  857	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  858	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  859	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  860
  861	fmov.l		&0x0,%fpcr		# zero FPCR
  862
  863#
  864#	copy, convert, and tag input argument
  865#
  866	lea		FP_SRC(%a6),%a0
  867	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
  868	mov.l		0x8+0x4(%a6),0x4(%a0)
  869	mov.l		0x8+0x8(%a6),0x8(%a0)
  870	bsr.l		tag			# fetch operand type
  871	mov.b		%d0,STAG(%a6)
  872	mov.b		%d0,%d1
  873
  874	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  875
  876	clr.l		%d0
  877	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  878
  879	tst.b		%d1
  880	bne.b		_L1_2x
  881	bsr.l		scos			# operand is a NORM
  882	bra.b		_L1_6x
  883_L1_2x:
  884	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  885	bne.b		_L1_3x			# no
  886	bsr.l		ld_pone			# yes
  887	bra.b		_L1_6x
  888_L1_3x:
  889	cmpi.b		%d1,&INF		# is operand an INF?
  890	bne.b		_L1_4x			# no
  891	bsr.l		t_operr			# yes
  892	bra.b		_L1_6x
  893_L1_4x:
  894	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  895	bne.b		_L1_5x			# no
  896	bsr.l		src_qnan			# yes
  897	bra.b		_L1_6x
  898_L1_5x:
  899	bsr.l		scosd			# operand is a DENORM
  900_L1_6x:
  901
  902#
  903#	Result is now in FP0
  904#
  905	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  906	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  907	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  908	unlk		%a6
  909	rts
  910
  911
  912#########################################################################
  913# MONADIC TEMPLATE							#
  914#########################################################################
  915	global		_fsinhs_
  916_fsinhs_:
  917	link		%a6,&-LOCAL_SIZE
  918
  919	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  920	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  921	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  922
  923	fmov.l		&0x0,%fpcr		# zero FPCR
  924
  925#
  926#	copy, convert, and tag input argument
  927#
  928	fmov.s		0x8(%a6),%fp0		# load sgl input
  929	fmov.x		%fp0,FP_SRC(%a6)
  930	lea		FP_SRC(%a6),%a0
  931	bsr.l		tag			# fetch operand type
  932	mov.b		%d0,STAG(%a6)
  933	mov.b		%d0,%d1
  934
  935	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  936
  937	clr.l		%d0
  938	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  939
  940	tst.b		%d1
  941	bne.b		_L2_2s
  942	bsr.l		ssinh			# operand is a NORM
  943	bra.b		_L2_6s
  944_L2_2s:
  945	cmpi.b		%d1,&ZERO		# is operand a ZERO?
  946	bne.b		_L2_3s			# no
  947	bsr.l		src_zero			# yes
  948	bra.b		_L2_6s
  949_L2_3s:
  950	cmpi.b		%d1,&INF		# is operand an INF?
  951	bne.b		_L2_4s			# no
  952	bsr.l		src_inf			# yes
  953	bra.b		_L2_6s
  954_L2_4s:
  955	cmpi.b		%d1,&QNAN		# is operand a QNAN?
  956	bne.b		_L2_5s			# no
  957	bsr.l		src_qnan			# yes
  958	bra.b		_L2_6s
  959_L2_5s:
  960	bsr.l		ssinhd			# operand is a DENORM
  961_L2_6s:
  962
  963#
  964#	Result is now in FP0
  965#
  966	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
  967	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
  968	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
  969	unlk		%a6
  970	rts
  971
  972	global		_fsinhd_
  973_fsinhd_:
  974	link		%a6,&-LOCAL_SIZE
  975
  976	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
  977	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
  978	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
  979
  980	fmov.l		&0x0,%fpcr		# zero FPCR
  981
  982#
  983#	copy, convert, and tag input argument
  984#
  985	fmov.d		0x8(%a6),%fp0		# load dbl input
  986	fmov.x		%fp0,FP_SRC(%a6)
  987	lea		FP_SRC(%a6),%a0
  988	bsr.l		tag			# fetch operand type
  989	mov.b		%d0,STAG(%a6)
  990	mov.b		%d0,%d1
  991
  992	andi.l		&0x00ff00ff,USER_FPSR(%a6)
  993
  994	clr.l		%d0
  995	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
  996
  997	mov.b		%d1,STAG(%a6)
  998	tst.b		%d1
  999	bne.b		_L2_2d
 1000	bsr.l		ssinh			# operand is a NORM
 1001	bra.b		_L2_6d
 1002_L2_2d:
 1003	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1004	bne.b		_L2_3d			# no
 1005	bsr.l		src_zero			# yes
 1006	bra.b		_L2_6d
 1007_L2_3d:
 1008	cmpi.b		%d1,&INF		# is operand an INF?
 1009	bne.b		_L2_4d			# no
 1010	bsr.l		src_inf			# yes
 1011	bra.b		_L2_6d
 1012_L2_4d:
 1013	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1014	bne.b		_L2_5d			# no
 1015	bsr.l		src_qnan			# yes
 1016	bra.b		_L2_6d
 1017_L2_5d:
 1018	bsr.l		ssinhd			# operand is a DENORM
 1019_L2_6d:
 1020
 1021#
 1022#	Result is now in FP0
 1023#
 1024	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1025	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1026	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1027	unlk		%a6
 1028	rts
 1029
 1030	global		_fsinhx_
 1031_fsinhx_:
 1032	link		%a6,&-LOCAL_SIZE
 1033
 1034	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1035	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1036	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1037
 1038	fmov.l		&0x0,%fpcr		# zero FPCR
 1039
 1040#
 1041#	copy, convert, and tag input argument
 1042#
 1043	lea		FP_SRC(%a6),%a0
 1044	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 1045	mov.l		0x8+0x4(%a6),0x4(%a0)
 1046	mov.l		0x8+0x8(%a6),0x8(%a0)
 1047	bsr.l		tag			# fetch operand type
 1048	mov.b		%d0,STAG(%a6)
 1049	mov.b		%d0,%d1
 1050
 1051	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1052
 1053	clr.l		%d0
 1054	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1055
 1056	tst.b		%d1
 1057	bne.b		_L2_2x
 1058	bsr.l		ssinh			# operand is a NORM
 1059	bra.b		_L2_6x
 1060_L2_2x:
 1061	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1062	bne.b		_L2_3x			# no
 1063	bsr.l		src_zero			# yes
 1064	bra.b		_L2_6x
 1065_L2_3x:
 1066	cmpi.b		%d1,&INF		# is operand an INF?
 1067	bne.b		_L2_4x			# no
 1068	bsr.l		src_inf			# yes
 1069	bra.b		_L2_6x
 1070_L2_4x:
 1071	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1072	bne.b		_L2_5x			# no
 1073	bsr.l		src_qnan			# yes
 1074	bra.b		_L2_6x
 1075_L2_5x:
 1076	bsr.l		ssinhd			# operand is a DENORM
 1077_L2_6x:
 1078
 1079#
 1080#	Result is now in FP0
 1081#
 1082	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1083	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1084	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1085	unlk		%a6
 1086	rts
 1087
 1088
 1089#########################################################################
 1090# MONADIC TEMPLATE							#
 1091#########################################################################
 1092	global		_flognp1s_
 1093_flognp1s_:
 1094	link		%a6,&-LOCAL_SIZE
 1095
 1096	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1097	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1098	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1099
 1100	fmov.l		&0x0,%fpcr		# zero FPCR
 1101
 1102#
 1103#	copy, convert, and tag input argument
 1104#
 1105	fmov.s		0x8(%a6),%fp0		# load sgl input
 1106	fmov.x		%fp0,FP_SRC(%a6)
 1107	lea		FP_SRC(%a6),%a0
 1108	bsr.l		tag			# fetch operand type
 1109	mov.b		%d0,STAG(%a6)
 1110	mov.b		%d0,%d1
 1111
 1112	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1113
 1114	clr.l		%d0
 1115	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1116
 1117	tst.b		%d1
 1118	bne.b		_L3_2s
 1119	bsr.l		slognp1			# operand is a NORM
 1120	bra.b		_L3_6s
 1121_L3_2s:
 1122	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1123	bne.b		_L3_3s			# no
 1124	bsr.l		src_zero			# yes
 1125	bra.b		_L3_6s
 1126_L3_3s:
 1127	cmpi.b		%d1,&INF		# is operand an INF?
 1128	bne.b		_L3_4s			# no
 1129	bsr.l		sopr_inf			# yes
 1130	bra.b		_L3_6s
 1131_L3_4s:
 1132	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1133	bne.b		_L3_5s			# no
 1134	bsr.l		src_qnan			# yes
 1135	bra.b		_L3_6s
 1136_L3_5s:
 1137	bsr.l		slognp1d			# operand is a DENORM
 1138_L3_6s:
 1139
 1140#
 1141#	Result is now in FP0
 1142#
 1143	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1144	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1145	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1146	unlk		%a6
 1147	rts
 1148
 1149	global		_flognp1d_
 1150_flognp1d_:
 1151	link		%a6,&-LOCAL_SIZE
 1152
 1153	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1154	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1155	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1156
 1157	fmov.l		&0x0,%fpcr		# zero FPCR
 1158
 1159#
 1160#	copy, convert, and tag input argument
 1161#
 1162	fmov.d		0x8(%a6),%fp0		# load dbl input
 1163	fmov.x		%fp0,FP_SRC(%a6)
 1164	lea		FP_SRC(%a6),%a0
 1165	bsr.l		tag			# fetch operand type
 1166	mov.b		%d0,STAG(%a6)
 1167	mov.b		%d0,%d1
 1168
 1169	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1170
 1171	clr.l		%d0
 1172	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1173
 1174	mov.b		%d1,STAG(%a6)
 1175	tst.b		%d1
 1176	bne.b		_L3_2d
 1177	bsr.l		slognp1			# operand is a NORM
 1178	bra.b		_L3_6d
 1179_L3_2d:
 1180	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1181	bne.b		_L3_3d			# no
 1182	bsr.l		src_zero			# yes
 1183	bra.b		_L3_6d
 1184_L3_3d:
 1185	cmpi.b		%d1,&INF		# is operand an INF?
 1186	bne.b		_L3_4d			# no
 1187	bsr.l		sopr_inf			# yes
 1188	bra.b		_L3_6d
 1189_L3_4d:
 1190	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1191	bne.b		_L3_5d			# no
 1192	bsr.l		src_qnan			# yes
 1193	bra.b		_L3_6d
 1194_L3_5d:
 1195	bsr.l		slognp1d			# operand is a DENORM
 1196_L3_6d:
 1197
 1198#
 1199#	Result is now in FP0
 1200#
 1201	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1202	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1203	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1204	unlk		%a6
 1205	rts
 1206
 1207	global		_flognp1x_
 1208_flognp1x_:
 1209	link		%a6,&-LOCAL_SIZE
 1210
 1211	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1212	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1213	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1214
 1215	fmov.l		&0x0,%fpcr		# zero FPCR
 1216
 1217#
 1218#	copy, convert, and tag input argument
 1219#
 1220	lea		FP_SRC(%a6),%a0
 1221	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 1222	mov.l		0x8+0x4(%a6),0x4(%a0)
 1223	mov.l		0x8+0x8(%a6),0x8(%a0)
 1224	bsr.l		tag			# fetch operand type
 1225	mov.b		%d0,STAG(%a6)
 1226	mov.b		%d0,%d1
 1227
 1228	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1229
 1230	clr.l		%d0
 1231	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1232
 1233	tst.b		%d1
 1234	bne.b		_L3_2x
 1235	bsr.l		slognp1			# operand is a NORM
 1236	bra.b		_L3_6x
 1237_L3_2x:
 1238	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1239	bne.b		_L3_3x			# no
 1240	bsr.l		src_zero			# yes
 1241	bra.b		_L3_6x
 1242_L3_3x:
 1243	cmpi.b		%d1,&INF		# is operand an INF?
 1244	bne.b		_L3_4x			# no
 1245	bsr.l		sopr_inf			# yes
 1246	bra.b		_L3_6x
 1247_L3_4x:
 1248	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1249	bne.b		_L3_5x			# no
 1250	bsr.l		src_qnan			# yes
 1251	bra.b		_L3_6x
 1252_L3_5x:
 1253	bsr.l		slognp1d			# operand is a DENORM
 1254_L3_6x:
 1255
 1256#
 1257#	Result is now in FP0
 1258#
 1259	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1260	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1261	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1262	unlk		%a6
 1263	rts
 1264
 1265
 1266#########################################################################
 1267# MONADIC TEMPLATE							#
 1268#########################################################################
 1269	global		_fetoxm1s_
 1270_fetoxm1s_:
 1271	link		%a6,&-LOCAL_SIZE
 1272
 1273	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1274	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1275	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1276
 1277	fmov.l		&0x0,%fpcr		# zero FPCR
 1278
 1279#
 1280#	copy, convert, and tag input argument
 1281#
 1282	fmov.s		0x8(%a6),%fp0		# load sgl input
 1283	fmov.x		%fp0,FP_SRC(%a6)
 1284	lea		FP_SRC(%a6),%a0
 1285	bsr.l		tag			# fetch operand type
 1286	mov.b		%d0,STAG(%a6)
 1287	mov.b		%d0,%d1
 1288
 1289	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1290
 1291	clr.l		%d0
 1292	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1293
 1294	tst.b		%d1
 1295	bne.b		_L4_2s
 1296	bsr.l		setoxm1			# operand is a NORM
 1297	bra.b		_L4_6s
 1298_L4_2s:
 1299	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1300	bne.b		_L4_3s			# no
 1301	bsr.l		src_zero			# yes
 1302	bra.b		_L4_6s
 1303_L4_3s:
 1304	cmpi.b		%d1,&INF		# is operand an INF?
 1305	bne.b		_L4_4s			# no
 1306	bsr.l		setoxm1i			# yes
 1307	bra.b		_L4_6s
 1308_L4_4s:
 1309	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1310	bne.b		_L4_5s			# no
 1311	bsr.l		src_qnan			# yes
 1312	bra.b		_L4_6s
 1313_L4_5s:
 1314	bsr.l		setoxm1d			# operand is a DENORM
 1315_L4_6s:
 1316
 1317#
 1318#	Result is now in FP0
 1319#
 1320	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1321	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1322	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1323	unlk		%a6
 1324	rts
 1325
 1326	global		_fetoxm1d_
 1327_fetoxm1d_:
 1328	link		%a6,&-LOCAL_SIZE
 1329
 1330	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1331	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1332	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1333
 1334	fmov.l		&0x0,%fpcr		# zero FPCR
 1335
 1336#
 1337#	copy, convert, and tag input argument
 1338#
 1339	fmov.d		0x8(%a6),%fp0		# load dbl input
 1340	fmov.x		%fp0,FP_SRC(%a6)
 1341	lea		FP_SRC(%a6),%a0
 1342	bsr.l		tag			# fetch operand type
 1343	mov.b		%d0,STAG(%a6)
 1344	mov.b		%d0,%d1
 1345
 1346	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1347
 1348	clr.l		%d0
 1349	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1350
 1351	mov.b		%d1,STAG(%a6)
 1352	tst.b		%d1
 1353	bne.b		_L4_2d
 1354	bsr.l		setoxm1			# operand is a NORM
 1355	bra.b		_L4_6d
 1356_L4_2d:
 1357	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1358	bne.b		_L4_3d			# no
 1359	bsr.l		src_zero			# yes
 1360	bra.b		_L4_6d
 1361_L4_3d:
 1362	cmpi.b		%d1,&INF		# is operand an INF?
 1363	bne.b		_L4_4d			# no
 1364	bsr.l		setoxm1i			# yes
 1365	bra.b		_L4_6d
 1366_L4_4d:
 1367	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1368	bne.b		_L4_5d			# no
 1369	bsr.l		src_qnan			# yes
 1370	bra.b		_L4_6d
 1371_L4_5d:
 1372	bsr.l		setoxm1d			# operand is a DENORM
 1373_L4_6d:
 1374
 1375#
 1376#	Result is now in FP0
 1377#
 1378	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1379	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1380	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1381	unlk		%a6
 1382	rts
 1383
 1384	global		_fetoxm1x_
 1385_fetoxm1x_:
 1386	link		%a6,&-LOCAL_SIZE
 1387
 1388	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1389	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1390	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1391
 1392	fmov.l		&0x0,%fpcr		# zero FPCR
 1393
 1394#
 1395#	copy, convert, and tag input argument
 1396#
 1397	lea		FP_SRC(%a6),%a0
 1398	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 1399	mov.l		0x8+0x4(%a6),0x4(%a0)
 1400	mov.l		0x8+0x8(%a6),0x8(%a0)
 1401	bsr.l		tag			# fetch operand type
 1402	mov.b		%d0,STAG(%a6)
 1403	mov.b		%d0,%d1
 1404
 1405	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1406
 1407	clr.l		%d0
 1408	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1409
 1410	tst.b		%d1
 1411	bne.b		_L4_2x
 1412	bsr.l		setoxm1			# operand is a NORM
 1413	bra.b		_L4_6x
 1414_L4_2x:
 1415	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1416	bne.b		_L4_3x			# no
 1417	bsr.l		src_zero			# yes
 1418	bra.b		_L4_6x
 1419_L4_3x:
 1420	cmpi.b		%d1,&INF		# is operand an INF?
 1421	bne.b		_L4_4x			# no
 1422	bsr.l		setoxm1i			# yes
 1423	bra.b		_L4_6x
 1424_L4_4x:
 1425	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1426	bne.b		_L4_5x			# no
 1427	bsr.l		src_qnan			# yes
 1428	bra.b		_L4_6x
 1429_L4_5x:
 1430	bsr.l		setoxm1d			# operand is a DENORM
 1431_L4_6x:
 1432
 1433#
 1434#	Result is now in FP0
 1435#
 1436	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1437	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1438	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1439	unlk		%a6
 1440	rts
 1441
 1442
 1443#########################################################################
 1444# MONADIC TEMPLATE							#
 1445#########################################################################
 1446	global		_ftanhs_
 1447_ftanhs_:
 1448	link		%a6,&-LOCAL_SIZE
 1449
 1450	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1451	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1452	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1453
 1454	fmov.l		&0x0,%fpcr		# zero FPCR
 1455
 1456#
 1457#	copy, convert, and tag input argument
 1458#
 1459	fmov.s		0x8(%a6),%fp0		# load sgl input
 1460	fmov.x		%fp0,FP_SRC(%a6)
 1461	lea		FP_SRC(%a6),%a0
 1462	bsr.l		tag			# fetch operand type
 1463	mov.b		%d0,STAG(%a6)
 1464	mov.b		%d0,%d1
 1465
 1466	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1467
 1468	clr.l		%d0
 1469	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1470
 1471	tst.b		%d1
 1472	bne.b		_L5_2s
 1473	bsr.l		stanh			# operand is a NORM
 1474	bra.b		_L5_6s
 1475_L5_2s:
 1476	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1477	bne.b		_L5_3s			# no
 1478	bsr.l		src_zero			# yes
 1479	bra.b		_L5_6s
 1480_L5_3s:
 1481	cmpi.b		%d1,&INF		# is operand an INF?
 1482	bne.b		_L5_4s			# no
 1483	bsr.l		src_one			# yes
 1484	bra.b		_L5_6s
 1485_L5_4s:
 1486	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1487	bne.b		_L5_5s			# no
 1488	bsr.l		src_qnan			# yes
 1489	bra.b		_L5_6s
 1490_L5_5s:
 1491	bsr.l		stanhd			# operand is a DENORM
 1492_L5_6s:
 1493
 1494#
 1495#	Result is now in FP0
 1496#
 1497	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1498	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1499	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1500	unlk		%a6
 1501	rts
 1502
 1503	global		_ftanhd_
 1504_ftanhd_:
 1505	link		%a6,&-LOCAL_SIZE
 1506
 1507	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1508	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1509	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1510
 1511	fmov.l		&0x0,%fpcr		# zero FPCR
 1512
 1513#
 1514#	copy, convert, and tag input argument
 1515#
 1516	fmov.d		0x8(%a6),%fp0		# load dbl input
 1517	fmov.x		%fp0,FP_SRC(%a6)
 1518	lea		FP_SRC(%a6),%a0
 1519	bsr.l		tag			# fetch operand type
 1520	mov.b		%d0,STAG(%a6)
 1521	mov.b		%d0,%d1
 1522
 1523	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1524
 1525	clr.l		%d0
 1526	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1527
 1528	mov.b		%d1,STAG(%a6)
 1529	tst.b		%d1
 1530	bne.b		_L5_2d
 1531	bsr.l		stanh			# operand is a NORM
 1532	bra.b		_L5_6d
 1533_L5_2d:
 1534	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1535	bne.b		_L5_3d			# no
 1536	bsr.l		src_zero			# yes
 1537	bra.b		_L5_6d
 1538_L5_3d:
 1539	cmpi.b		%d1,&INF		# is operand an INF?
 1540	bne.b		_L5_4d			# no
 1541	bsr.l		src_one			# yes
 1542	bra.b		_L5_6d
 1543_L5_4d:
 1544	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1545	bne.b		_L5_5d			# no
 1546	bsr.l		src_qnan			# yes
 1547	bra.b		_L5_6d
 1548_L5_5d:
 1549	bsr.l		stanhd			# operand is a DENORM
 1550_L5_6d:
 1551
 1552#
 1553#	Result is now in FP0
 1554#
 1555	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1556	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1557	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1558	unlk		%a6
 1559	rts
 1560
 1561	global		_ftanhx_
 1562_ftanhx_:
 1563	link		%a6,&-LOCAL_SIZE
 1564
 1565	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1566	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1567	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1568
 1569	fmov.l		&0x0,%fpcr		# zero FPCR
 1570
 1571#
 1572#	copy, convert, and tag input argument
 1573#
 1574	lea		FP_SRC(%a6),%a0
 1575	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 1576	mov.l		0x8+0x4(%a6),0x4(%a0)
 1577	mov.l		0x8+0x8(%a6),0x8(%a0)
 1578	bsr.l		tag			# fetch operand type
 1579	mov.b		%d0,STAG(%a6)
 1580	mov.b		%d0,%d1
 1581
 1582	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1583
 1584	clr.l		%d0
 1585	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1586
 1587	tst.b		%d1
 1588	bne.b		_L5_2x
 1589	bsr.l		stanh			# operand is a NORM
 1590	bra.b		_L5_6x
 1591_L5_2x:
 1592	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1593	bne.b		_L5_3x			# no
 1594	bsr.l		src_zero			# yes
 1595	bra.b		_L5_6x
 1596_L5_3x:
 1597	cmpi.b		%d1,&INF		# is operand an INF?
 1598	bne.b		_L5_4x			# no
 1599	bsr.l		src_one			# yes
 1600	bra.b		_L5_6x
 1601_L5_4x:
 1602	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1603	bne.b		_L5_5x			# no
 1604	bsr.l		src_qnan			# yes
 1605	bra.b		_L5_6x
 1606_L5_5x:
 1607	bsr.l		stanhd			# operand is a DENORM
 1608_L5_6x:
 1609
 1610#
 1611#	Result is now in FP0
 1612#
 1613	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1614	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1615	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1616	unlk		%a6
 1617	rts
 1618
 1619
 1620#########################################################################
 1621# MONADIC TEMPLATE							#
 1622#########################################################################
 1623	global		_fatans_
 1624_fatans_:
 1625	link		%a6,&-LOCAL_SIZE
 1626
 1627	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1628	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1629	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1630
 1631	fmov.l		&0x0,%fpcr		# zero FPCR
 1632
 1633#
 1634#	copy, convert, and tag input argument
 1635#
 1636	fmov.s		0x8(%a6),%fp0		# load sgl input
 1637	fmov.x		%fp0,FP_SRC(%a6)
 1638	lea		FP_SRC(%a6),%a0
 1639	bsr.l		tag			# fetch operand type
 1640	mov.b		%d0,STAG(%a6)
 1641	mov.b		%d0,%d1
 1642
 1643	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1644
 1645	clr.l		%d0
 1646	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1647
 1648	tst.b		%d1
 1649	bne.b		_L6_2s
 1650	bsr.l		satan			# operand is a NORM
 1651	bra.b		_L6_6s
 1652_L6_2s:
 1653	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1654	bne.b		_L6_3s			# no
 1655	bsr.l		src_zero			# yes
 1656	bra.b		_L6_6s
 1657_L6_3s:
 1658	cmpi.b		%d1,&INF		# is operand an INF?
 1659	bne.b		_L6_4s			# no
 1660	bsr.l		spi_2			# yes
 1661	bra.b		_L6_6s
 1662_L6_4s:
 1663	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1664	bne.b		_L6_5s			# no
 1665	bsr.l		src_qnan			# yes
 1666	bra.b		_L6_6s
 1667_L6_5s:
 1668	bsr.l		satand			# operand is a DENORM
 1669_L6_6s:
 1670
 1671#
 1672#	Result is now in FP0
 1673#
 1674	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1675	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1676	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1677	unlk		%a6
 1678	rts
 1679
 1680	global		_fatand_
 1681_fatand_:
 1682	link		%a6,&-LOCAL_SIZE
 1683
 1684	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1685	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1686	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1687
 1688	fmov.l		&0x0,%fpcr		# zero FPCR
 1689
 1690#
 1691#	copy, convert, and tag input argument
 1692#
 1693	fmov.d		0x8(%a6),%fp0		# load dbl input
 1694	fmov.x		%fp0,FP_SRC(%a6)
 1695	lea		FP_SRC(%a6),%a0
 1696	bsr.l		tag			# fetch operand type
 1697	mov.b		%d0,STAG(%a6)
 1698	mov.b		%d0,%d1
 1699
 1700	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1701
 1702	clr.l		%d0
 1703	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1704
 1705	mov.b		%d1,STAG(%a6)
 1706	tst.b		%d1
 1707	bne.b		_L6_2d
 1708	bsr.l		satan			# operand is a NORM
 1709	bra.b		_L6_6d
 1710_L6_2d:
 1711	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1712	bne.b		_L6_3d			# no
 1713	bsr.l		src_zero			# yes
 1714	bra.b		_L6_6d
 1715_L6_3d:
 1716	cmpi.b		%d1,&INF		# is operand an INF?
 1717	bne.b		_L6_4d			# no
 1718	bsr.l		spi_2			# yes
 1719	bra.b		_L6_6d
 1720_L6_4d:
 1721	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1722	bne.b		_L6_5d			# no
 1723	bsr.l		src_qnan			# yes
 1724	bra.b		_L6_6d
 1725_L6_5d:
 1726	bsr.l		satand			# operand is a DENORM
 1727_L6_6d:
 1728
 1729#
 1730#	Result is now in FP0
 1731#
 1732	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1733	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1734	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1735	unlk		%a6
 1736	rts
 1737
 1738	global		_fatanx_
 1739_fatanx_:
 1740	link		%a6,&-LOCAL_SIZE
 1741
 1742	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1743	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1744	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1745
 1746	fmov.l		&0x0,%fpcr		# zero FPCR
 1747
 1748#
 1749#	copy, convert, and tag input argument
 1750#
 1751	lea		FP_SRC(%a6),%a0
 1752	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 1753	mov.l		0x8+0x4(%a6),0x4(%a0)
 1754	mov.l		0x8+0x8(%a6),0x8(%a0)
 1755	bsr.l		tag			# fetch operand type
 1756	mov.b		%d0,STAG(%a6)
 1757	mov.b		%d0,%d1
 1758
 1759	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1760
 1761	clr.l		%d0
 1762	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1763
 1764	tst.b		%d1
 1765	bne.b		_L6_2x
 1766	bsr.l		satan			# operand is a NORM
 1767	bra.b		_L6_6x
 1768_L6_2x:
 1769	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1770	bne.b		_L6_3x			# no
 1771	bsr.l		src_zero			# yes
 1772	bra.b		_L6_6x
 1773_L6_3x:
 1774	cmpi.b		%d1,&INF		# is operand an INF?
 1775	bne.b		_L6_4x			# no
 1776	bsr.l		spi_2			# yes
 1777	bra.b		_L6_6x
 1778_L6_4x:
 1779	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1780	bne.b		_L6_5x			# no
 1781	bsr.l		src_qnan			# yes
 1782	bra.b		_L6_6x
 1783_L6_5x:
 1784	bsr.l		satand			# operand is a DENORM
 1785_L6_6x:
 1786
 1787#
 1788#	Result is now in FP0
 1789#
 1790	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1791	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1792	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1793	unlk		%a6
 1794	rts
 1795
 1796
 1797#########################################################################
 1798# MONADIC TEMPLATE							#
 1799#########################################################################
 1800	global		_fasins_
 1801_fasins_:
 1802	link		%a6,&-LOCAL_SIZE
 1803
 1804	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1805	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1806	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1807
 1808	fmov.l		&0x0,%fpcr		# zero FPCR
 1809
 1810#
 1811#	copy, convert, and tag input argument
 1812#
 1813	fmov.s		0x8(%a6),%fp0		# load sgl input
 1814	fmov.x		%fp0,FP_SRC(%a6)
 1815	lea		FP_SRC(%a6),%a0
 1816	bsr.l		tag			# fetch operand type
 1817	mov.b		%d0,STAG(%a6)
 1818	mov.b		%d0,%d1
 1819
 1820	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1821
 1822	clr.l		%d0
 1823	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1824
 1825	tst.b		%d1
 1826	bne.b		_L7_2s
 1827	bsr.l		sasin			# operand is a NORM
 1828	bra.b		_L7_6s
 1829_L7_2s:
 1830	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1831	bne.b		_L7_3s			# no
 1832	bsr.l		src_zero			# yes
 1833	bra.b		_L7_6s
 1834_L7_3s:
 1835	cmpi.b		%d1,&INF		# is operand an INF?
 1836	bne.b		_L7_4s			# no
 1837	bsr.l		t_operr			# yes
 1838	bra.b		_L7_6s
 1839_L7_4s:
 1840	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1841	bne.b		_L7_5s			# no
 1842	bsr.l		src_qnan			# yes
 1843	bra.b		_L7_6s
 1844_L7_5s:
 1845	bsr.l		sasind			# operand is a DENORM
 1846_L7_6s:
 1847
 1848#
 1849#	Result is now in FP0
 1850#
 1851	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1852	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1853	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1854	unlk		%a6
 1855	rts
 1856
 1857	global		_fasind_
 1858_fasind_:
 1859	link		%a6,&-LOCAL_SIZE
 1860
 1861	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1862	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1863	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1864
 1865	fmov.l		&0x0,%fpcr		# zero FPCR
 1866
 1867#
 1868#	copy, convert, and tag input argument
 1869#
 1870	fmov.d		0x8(%a6),%fp0		# load dbl input
 1871	fmov.x		%fp0,FP_SRC(%a6)
 1872	lea		FP_SRC(%a6),%a0
 1873	bsr.l		tag			# fetch operand type
 1874	mov.b		%d0,STAG(%a6)
 1875	mov.b		%d0,%d1
 1876
 1877	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1878
 1879	clr.l		%d0
 1880	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1881
 1882	mov.b		%d1,STAG(%a6)
 1883	tst.b		%d1
 1884	bne.b		_L7_2d
 1885	bsr.l		sasin			# operand is a NORM
 1886	bra.b		_L7_6d
 1887_L7_2d:
 1888	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1889	bne.b		_L7_3d			# no
 1890	bsr.l		src_zero			# yes
 1891	bra.b		_L7_6d
 1892_L7_3d:
 1893	cmpi.b		%d1,&INF		# is operand an INF?
 1894	bne.b		_L7_4d			# no
 1895	bsr.l		t_operr			# yes
 1896	bra.b		_L7_6d
 1897_L7_4d:
 1898	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1899	bne.b		_L7_5d			# no
 1900	bsr.l		src_qnan			# yes
 1901	bra.b		_L7_6d
 1902_L7_5d:
 1903	bsr.l		sasind			# operand is a DENORM
 1904_L7_6d:
 1905
 1906#
 1907#	Result is now in FP0
 1908#
 1909	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1910	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1911	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1912	unlk		%a6
 1913	rts
 1914
 1915	global		_fasinx_
 1916_fasinx_:
 1917	link		%a6,&-LOCAL_SIZE
 1918
 1919	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1920	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1921	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1922
 1923	fmov.l		&0x0,%fpcr		# zero FPCR
 1924
 1925#
 1926#	copy, convert, and tag input argument
 1927#
 1928	lea		FP_SRC(%a6),%a0
 1929	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 1930	mov.l		0x8+0x4(%a6),0x4(%a0)
 1931	mov.l		0x8+0x8(%a6),0x8(%a0)
 1932	bsr.l		tag			# fetch operand type
 1933	mov.b		%d0,STAG(%a6)
 1934	mov.b		%d0,%d1
 1935
 1936	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1937
 1938	clr.l		%d0
 1939	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 1940
 1941	tst.b		%d1
 1942	bne.b		_L7_2x
 1943	bsr.l		sasin			# operand is a NORM
 1944	bra.b		_L7_6x
 1945_L7_2x:
 1946	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 1947	bne.b		_L7_3x			# no
 1948	bsr.l		src_zero			# yes
 1949	bra.b		_L7_6x
 1950_L7_3x:
 1951	cmpi.b		%d1,&INF		# is operand an INF?
 1952	bne.b		_L7_4x			# no
 1953	bsr.l		t_operr			# yes
 1954	bra.b		_L7_6x
 1955_L7_4x:
 1956	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 1957	bne.b		_L7_5x			# no
 1958	bsr.l		src_qnan			# yes
 1959	bra.b		_L7_6x
 1960_L7_5x:
 1961	bsr.l		sasind			# operand is a DENORM
 1962_L7_6x:
 1963
 1964#
 1965#	Result is now in FP0
 1966#
 1967	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 1968	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 1969	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 1970	unlk		%a6
 1971	rts
 1972
 1973
 1974#########################################################################
 1975# MONADIC TEMPLATE							#
 1976#########################################################################
 1977	global		_fatanhs_
 1978_fatanhs_:
 1979	link		%a6,&-LOCAL_SIZE
 1980
 1981	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 1982	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 1983	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 1984
 1985	fmov.l		&0x0,%fpcr		# zero FPCR
 1986
 1987#
 1988#	copy, convert, and tag input argument
 1989#
 1990	fmov.s		0x8(%a6),%fp0		# load sgl input
 1991	fmov.x		%fp0,FP_SRC(%a6)
 1992	lea		FP_SRC(%a6),%a0
 1993	bsr.l		tag			# fetch operand type
 1994	mov.b		%d0,STAG(%a6)
 1995	mov.b		%d0,%d1
 1996
 1997	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 1998
 1999	clr.l		%d0
 2000	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2001
 2002	tst.b		%d1
 2003	bne.b		_L8_2s
 2004	bsr.l		satanh			# operand is a NORM
 2005	bra.b		_L8_6s
 2006_L8_2s:
 2007	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2008	bne.b		_L8_3s			# no
 2009	bsr.l		src_zero			# yes
 2010	bra.b		_L8_6s
 2011_L8_3s:
 2012	cmpi.b		%d1,&INF		# is operand an INF?
 2013	bne.b		_L8_4s			# no
 2014	bsr.l		t_operr			# yes
 2015	bra.b		_L8_6s
 2016_L8_4s:
 2017	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2018	bne.b		_L8_5s			# no
 2019	bsr.l		src_qnan			# yes
 2020	bra.b		_L8_6s
 2021_L8_5s:
 2022	bsr.l		satanhd			# operand is a DENORM
 2023_L8_6s:
 2024
 2025#
 2026#	Result is now in FP0
 2027#
 2028	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2029	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2030	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2031	unlk		%a6
 2032	rts
 2033
 2034	global		_fatanhd_
 2035_fatanhd_:
 2036	link		%a6,&-LOCAL_SIZE
 2037
 2038	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2039	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2040	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2041
 2042	fmov.l		&0x0,%fpcr		# zero FPCR
 2043
 2044#
 2045#	copy, convert, and tag input argument
 2046#
 2047	fmov.d		0x8(%a6),%fp0		# load dbl input
 2048	fmov.x		%fp0,FP_SRC(%a6)
 2049	lea		FP_SRC(%a6),%a0
 2050	bsr.l		tag			# fetch operand type
 2051	mov.b		%d0,STAG(%a6)
 2052	mov.b		%d0,%d1
 2053
 2054	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2055
 2056	clr.l		%d0
 2057	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2058
 2059	mov.b		%d1,STAG(%a6)
 2060	tst.b		%d1
 2061	bne.b		_L8_2d
 2062	bsr.l		satanh			# operand is a NORM
 2063	bra.b		_L8_6d
 2064_L8_2d:
 2065	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2066	bne.b		_L8_3d			# no
 2067	bsr.l		src_zero			# yes
 2068	bra.b		_L8_6d
 2069_L8_3d:
 2070	cmpi.b		%d1,&INF		# is operand an INF?
 2071	bne.b		_L8_4d			# no
 2072	bsr.l		t_operr			# yes
 2073	bra.b		_L8_6d
 2074_L8_4d:
 2075	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2076	bne.b		_L8_5d			# no
 2077	bsr.l		src_qnan			# yes
 2078	bra.b		_L8_6d
 2079_L8_5d:
 2080	bsr.l		satanhd			# operand is a DENORM
 2081_L8_6d:
 2082
 2083#
 2084#	Result is now in FP0
 2085#
 2086	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2087	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2088	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2089	unlk		%a6
 2090	rts
 2091
 2092	global		_fatanhx_
 2093_fatanhx_:
 2094	link		%a6,&-LOCAL_SIZE
 2095
 2096	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2097	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2098	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2099
 2100	fmov.l		&0x0,%fpcr		# zero FPCR
 2101
 2102#
 2103#	copy, convert, and tag input argument
 2104#
 2105	lea		FP_SRC(%a6),%a0
 2106	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 2107	mov.l		0x8+0x4(%a6),0x4(%a0)
 2108	mov.l		0x8+0x8(%a6),0x8(%a0)
 2109	bsr.l		tag			# fetch operand type
 2110	mov.b		%d0,STAG(%a6)
 2111	mov.b		%d0,%d1
 2112
 2113	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2114
 2115	clr.l		%d0
 2116	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2117
 2118	tst.b		%d1
 2119	bne.b		_L8_2x
 2120	bsr.l		satanh			# operand is a NORM
 2121	bra.b		_L8_6x
 2122_L8_2x:
 2123	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2124	bne.b		_L8_3x			# no
 2125	bsr.l		src_zero			# yes
 2126	bra.b		_L8_6x
 2127_L8_3x:
 2128	cmpi.b		%d1,&INF		# is operand an INF?
 2129	bne.b		_L8_4x			# no
 2130	bsr.l		t_operr			# yes
 2131	bra.b		_L8_6x
 2132_L8_4x:
 2133	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2134	bne.b		_L8_5x			# no
 2135	bsr.l		src_qnan			# yes
 2136	bra.b		_L8_6x
 2137_L8_5x:
 2138	bsr.l		satanhd			# operand is a DENORM
 2139_L8_6x:
 2140
 2141#
 2142#	Result is now in FP0
 2143#
 2144	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2145	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2146	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2147	unlk		%a6
 2148	rts
 2149
 2150
 2151#########################################################################
 2152# MONADIC TEMPLATE							#
 2153#########################################################################
 2154	global		_ftans_
 2155_ftans_:
 2156	link		%a6,&-LOCAL_SIZE
 2157
 2158	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2159	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2160	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2161
 2162	fmov.l		&0x0,%fpcr		# zero FPCR
 2163
 2164#
 2165#	copy, convert, and tag input argument
 2166#
 2167	fmov.s		0x8(%a6),%fp0		# load sgl input
 2168	fmov.x		%fp0,FP_SRC(%a6)
 2169	lea		FP_SRC(%a6),%a0
 2170	bsr.l		tag			# fetch operand type
 2171	mov.b		%d0,STAG(%a6)
 2172	mov.b		%d0,%d1
 2173
 2174	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2175
 2176	clr.l		%d0
 2177	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2178
 2179	tst.b		%d1
 2180	bne.b		_L9_2s
 2181	bsr.l		stan			# operand is a NORM
 2182	bra.b		_L9_6s
 2183_L9_2s:
 2184	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2185	bne.b		_L9_3s			# no
 2186	bsr.l		src_zero			# yes
 2187	bra.b		_L9_6s
 2188_L9_3s:
 2189	cmpi.b		%d1,&INF		# is operand an INF?
 2190	bne.b		_L9_4s			# no
 2191	bsr.l		t_operr			# yes
 2192	bra.b		_L9_6s
 2193_L9_4s:
 2194	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2195	bne.b		_L9_5s			# no
 2196	bsr.l		src_qnan			# yes
 2197	bra.b		_L9_6s
 2198_L9_5s:
 2199	bsr.l		stand			# operand is a DENORM
 2200_L9_6s:
 2201
 2202#
 2203#	Result is now in FP0
 2204#
 2205	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2206	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2207	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2208	unlk		%a6
 2209	rts
 2210
 2211	global		_ftand_
 2212_ftand_:
 2213	link		%a6,&-LOCAL_SIZE
 2214
 2215	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2216	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2217	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2218
 2219	fmov.l		&0x0,%fpcr		# zero FPCR
 2220
 2221#
 2222#	copy, convert, and tag input argument
 2223#
 2224	fmov.d		0x8(%a6),%fp0		# load dbl input
 2225	fmov.x		%fp0,FP_SRC(%a6)
 2226	lea		FP_SRC(%a6),%a0
 2227	bsr.l		tag			# fetch operand type
 2228	mov.b		%d0,STAG(%a6)
 2229	mov.b		%d0,%d1
 2230
 2231	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2232
 2233	clr.l		%d0
 2234	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2235
 2236	mov.b		%d1,STAG(%a6)
 2237	tst.b		%d1
 2238	bne.b		_L9_2d
 2239	bsr.l		stan			# operand is a NORM
 2240	bra.b		_L9_6d
 2241_L9_2d:
 2242	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2243	bne.b		_L9_3d			# no
 2244	bsr.l		src_zero			# yes
 2245	bra.b		_L9_6d
 2246_L9_3d:
 2247	cmpi.b		%d1,&INF		# is operand an INF?
 2248	bne.b		_L9_4d			# no
 2249	bsr.l		t_operr			# yes
 2250	bra.b		_L9_6d
 2251_L9_4d:
 2252	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2253	bne.b		_L9_5d			# no
 2254	bsr.l		src_qnan			# yes
 2255	bra.b		_L9_6d
 2256_L9_5d:
 2257	bsr.l		stand			# operand is a DENORM
 2258_L9_6d:
 2259
 2260#
 2261#	Result is now in FP0
 2262#
 2263	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2264	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2265	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2266	unlk		%a6
 2267	rts
 2268
 2269	global		_ftanx_
 2270_ftanx_:
 2271	link		%a6,&-LOCAL_SIZE
 2272
 2273	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2274	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2275	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2276
 2277	fmov.l		&0x0,%fpcr		# zero FPCR
 2278
 2279#
 2280#	copy, convert, and tag input argument
 2281#
 2282	lea		FP_SRC(%a6),%a0
 2283	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 2284	mov.l		0x8+0x4(%a6),0x4(%a0)
 2285	mov.l		0x8+0x8(%a6),0x8(%a0)
 2286	bsr.l		tag			# fetch operand type
 2287	mov.b		%d0,STAG(%a6)
 2288	mov.b		%d0,%d1
 2289
 2290	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2291
 2292	clr.l		%d0
 2293	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2294
 2295	tst.b		%d1
 2296	bne.b		_L9_2x
 2297	bsr.l		stan			# operand is a NORM
 2298	bra.b		_L9_6x
 2299_L9_2x:
 2300	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2301	bne.b		_L9_3x			# no
 2302	bsr.l		src_zero			# yes
 2303	bra.b		_L9_6x
 2304_L9_3x:
 2305	cmpi.b		%d1,&INF		# is operand an INF?
 2306	bne.b		_L9_4x			# no
 2307	bsr.l		t_operr			# yes
 2308	bra.b		_L9_6x
 2309_L9_4x:
 2310	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2311	bne.b		_L9_5x			# no
 2312	bsr.l		src_qnan			# yes
 2313	bra.b		_L9_6x
 2314_L9_5x:
 2315	bsr.l		stand			# operand is a DENORM
 2316_L9_6x:
 2317
 2318#
 2319#	Result is now in FP0
 2320#
 2321	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2322	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2323	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2324	unlk		%a6
 2325	rts
 2326
 2327
 2328#########################################################################
 2329# MONADIC TEMPLATE							#
 2330#########################################################################
 2331	global		_fetoxs_
 2332_fetoxs_:
 2333	link		%a6,&-LOCAL_SIZE
 2334
 2335	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2336	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2337	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2338
 2339	fmov.l		&0x0,%fpcr		# zero FPCR
 2340
 2341#
 2342#	copy, convert, and tag input argument
 2343#
 2344	fmov.s		0x8(%a6),%fp0		# load sgl input
 2345	fmov.x		%fp0,FP_SRC(%a6)
 2346	lea		FP_SRC(%a6),%a0
 2347	bsr.l		tag			# fetch operand type
 2348	mov.b		%d0,STAG(%a6)
 2349	mov.b		%d0,%d1
 2350
 2351	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2352
 2353	clr.l		%d0
 2354	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2355
 2356	tst.b		%d1
 2357	bne.b		_L10_2s
 2358	bsr.l		setox			# operand is a NORM
 2359	bra.b		_L10_6s
 2360_L10_2s:
 2361	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2362	bne.b		_L10_3s			# no
 2363	bsr.l		ld_pone			# yes
 2364	bra.b		_L10_6s
 2365_L10_3s:
 2366	cmpi.b		%d1,&INF		# is operand an INF?
 2367	bne.b		_L10_4s			# no
 2368	bsr.l		szr_inf			# yes
 2369	bra.b		_L10_6s
 2370_L10_4s:
 2371	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2372	bne.b		_L10_5s			# no
 2373	bsr.l		src_qnan			# yes
 2374	bra.b		_L10_6s
 2375_L10_5s:
 2376	bsr.l		setoxd			# operand is a DENORM
 2377_L10_6s:
 2378
 2379#
 2380#	Result is now in FP0
 2381#
 2382	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2383	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2384	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2385	unlk		%a6
 2386	rts
 2387
 2388	global		_fetoxd_
 2389_fetoxd_:
 2390	link		%a6,&-LOCAL_SIZE
 2391
 2392	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2393	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2394	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2395
 2396	fmov.l		&0x0,%fpcr		# zero FPCR
 2397
 2398#
 2399#	copy, convert, and tag input argument
 2400#
 2401	fmov.d		0x8(%a6),%fp0		# load dbl input
 2402	fmov.x		%fp0,FP_SRC(%a6)
 2403	lea		FP_SRC(%a6),%a0
 2404	bsr.l		tag			# fetch operand type
 2405	mov.b		%d0,STAG(%a6)
 2406	mov.b		%d0,%d1
 2407
 2408	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2409
 2410	clr.l		%d0
 2411	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2412
 2413	mov.b		%d1,STAG(%a6)
 2414	tst.b		%d1
 2415	bne.b		_L10_2d
 2416	bsr.l		setox			# operand is a NORM
 2417	bra.b		_L10_6d
 2418_L10_2d:
 2419	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2420	bne.b		_L10_3d			# no
 2421	bsr.l		ld_pone			# yes
 2422	bra.b		_L10_6d
 2423_L10_3d:
 2424	cmpi.b		%d1,&INF		# is operand an INF?
 2425	bne.b		_L10_4d			# no
 2426	bsr.l		szr_inf			# yes
 2427	bra.b		_L10_6d
 2428_L10_4d:
 2429	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2430	bne.b		_L10_5d			# no
 2431	bsr.l		src_qnan			# yes
 2432	bra.b		_L10_6d
 2433_L10_5d:
 2434	bsr.l		setoxd			# operand is a DENORM
 2435_L10_6d:
 2436
 2437#
 2438#	Result is now in FP0
 2439#
 2440	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2441	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2442	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2443	unlk		%a6
 2444	rts
 2445
 2446	global		_fetoxx_
 2447_fetoxx_:
 2448	link		%a6,&-LOCAL_SIZE
 2449
 2450	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2451	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2452	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2453
 2454	fmov.l		&0x0,%fpcr		# zero FPCR
 2455
 2456#
 2457#	copy, convert, and tag input argument
 2458#
 2459	lea		FP_SRC(%a6),%a0
 2460	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 2461	mov.l		0x8+0x4(%a6),0x4(%a0)
 2462	mov.l		0x8+0x8(%a6),0x8(%a0)
 2463	bsr.l		tag			# fetch operand type
 2464	mov.b		%d0,STAG(%a6)
 2465	mov.b		%d0,%d1
 2466
 2467	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2468
 2469	clr.l		%d0
 2470	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2471
 2472	tst.b		%d1
 2473	bne.b		_L10_2x
 2474	bsr.l		setox			# operand is a NORM
 2475	bra.b		_L10_6x
 2476_L10_2x:
 2477	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2478	bne.b		_L10_3x			# no
 2479	bsr.l		ld_pone			# yes
 2480	bra.b		_L10_6x
 2481_L10_3x:
 2482	cmpi.b		%d1,&INF		# is operand an INF?
 2483	bne.b		_L10_4x			# no
 2484	bsr.l		szr_inf			# yes
 2485	bra.b		_L10_6x
 2486_L10_4x:
 2487	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2488	bne.b		_L10_5x			# no
 2489	bsr.l		src_qnan			# yes
 2490	bra.b		_L10_6x
 2491_L10_5x:
 2492	bsr.l		setoxd			# operand is a DENORM
 2493_L10_6x:
 2494
 2495#
 2496#	Result is now in FP0
 2497#
 2498	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2499	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2500	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2501	unlk		%a6
 2502	rts
 2503
 2504
 2505#########################################################################
 2506# MONADIC TEMPLATE							#
 2507#########################################################################
 2508	global		_ftwotoxs_
 2509_ftwotoxs_:
 2510	link		%a6,&-LOCAL_SIZE
 2511
 2512	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2513	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2514	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2515
 2516	fmov.l		&0x0,%fpcr		# zero FPCR
 2517
 2518#
 2519#	copy, convert, and tag input argument
 2520#
 2521	fmov.s		0x8(%a6),%fp0		# load sgl input
 2522	fmov.x		%fp0,FP_SRC(%a6)
 2523	lea		FP_SRC(%a6),%a0
 2524	bsr.l		tag			# fetch operand type
 2525	mov.b		%d0,STAG(%a6)
 2526	mov.b		%d0,%d1
 2527
 2528	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2529
 2530	clr.l		%d0
 2531	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2532
 2533	tst.b		%d1
 2534	bne.b		_L11_2s
 2535	bsr.l		stwotox			# operand is a NORM
 2536	bra.b		_L11_6s
 2537_L11_2s:
 2538	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2539	bne.b		_L11_3s			# no
 2540	bsr.l		ld_pone			# yes
 2541	bra.b		_L11_6s
 2542_L11_3s:
 2543	cmpi.b		%d1,&INF		# is operand an INF?
 2544	bne.b		_L11_4s			# no
 2545	bsr.l		szr_inf			# yes
 2546	bra.b		_L11_6s
 2547_L11_4s:
 2548	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2549	bne.b		_L11_5s			# no
 2550	bsr.l		src_qnan			# yes
 2551	bra.b		_L11_6s
 2552_L11_5s:
 2553	bsr.l		stwotoxd			# operand is a DENORM
 2554_L11_6s:
 2555
 2556#
 2557#	Result is now in FP0
 2558#
 2559	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2560	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2561	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2562	unlk		%a6
 2563	rts
 2564
 2565	global		_ftwotoxd_
 2566_ftwotoxd_:
 2567	link		%a6,&-LOCAL_SIZE
 2568
 2569	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2570	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2571	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2572
 2573	fmov.l		&0x0,%fpcr		# zero FPCR
 2574
 2575#
 2576#	copy, convert, and tag input argument
 2577#
 2578	fmov.d		0x8(%a6),%fp0		# load dbl input
 2579	fmov.x		%fp0,FP_SRC(%a6)
 2580	lea		FP_SRC(%a6),%a0
 2581	bsr.l		tag			# fetch operand type
 2582	mov.b		%d0,STAG(%a6)
 2583	mov.b		%d0,%d1
 2584
 2585	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2586
 2587	clr.l		%d0
 2588	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2589
 2590	mov.b		%d1,STAG(%a6)
 2591	tst.b		%d1
 2592	bne.b		_L11_2d
 2593	bsr.l		stwotox			# operand is a NORM
 2594	bra.b		_L11_6d
 2595_L11_2d:
 2596	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2597	bne.b		_L11_3d			# no
 2598	bsr.l		ld_pone			# yes
 2599	bra.b		_L11_6d
 2600_L11_3d:
 2601	cmpi.b		%d1,&INF		# is operand an INF?
 2602	bne.b		_L11_4d			# no
 2603	bsr.l		szr_inf			# yes
 2604	bra.b		_L11_6d
 2605_L11_4d:
 2606	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2607	bne.b		_L11_5d			# no
 2608	bsr.l		src_qnan			# yes
 2609	bra.b		_L11_6d
 2610_L11_5d:
 2611	bsr.l		stwotoxd			# operand is a DENORM
 2612_L11_6d:
 2613
 2614#
 2615#	Result is now in FP0
 2616#
 2617	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2618	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2619	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2620	unlk		%a6
 2621	rts
 2622
 2623	global		_ftwotoxx_
 2624_ftwotoxx_:
 2625	link		%a6,&-LOCAL_SIZE
 2626
 2627	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2628	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2629	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2630
 2631	fmov.l		&0x0,%fpcr		# zero FPCR
 2632
 2633#
 2634#	copy, convert, and tag input argument
 2635#
 2636	lea		FP_SRC(%a6),%a0
 2637	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 2638	mov.l		0x8+0x4(%a6),0x4(%a0)
 2639	mov.l		0x8+0x8(%a6),0x8(%a0)
 2640	bsr.l		tag			# fetch operand type
 2641	mov.b		%d0,STAG(%a6)
 2642	mov.b		%d0,%d1
 2643
 2644	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2645
 2646	clr.l		%d0
 2647	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2648
 2649	tst.b		%d1
 2650	bne.b		_L11_2x
 2651	bsr.l		stwotox			# operand is a NORM
 2652	bra.b		_L11_6x
 2653_L11_2x:
 2654	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2655	bne.b		_L11_3x			# no
 2656	bsr.l		ld_pone			# yes
 2657	bra.b		_L11_6x
 2658_L11_3x:
 2659	cmpi.b		%d1,&INF		# is operand an INF?
 2660	bne.b		_L11_4x			# no
 2661	bsr.l		szr_inf			# yes
 2662	bra.b		_L11_6x
 2663_L11_4x:
 2664	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2665	bne.b		_L11_5x			# no
 2666	bsr.l		src_qnan			# yes
 2667	bra.b		_L11_6x
 2668_L11_5x:
 2669	bsr.l		stwotoxd			# operand is a DENORM
 2670_L11_6x:
 2671
 2672#
 2673#	Result is now in FP0
 2674#
 2675	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2676	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2677	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2678	unlk		%a6
 2679	rts
 2680
 2681
 2682#########################################################################
 2683# MONADIC TEMPLATE							#
 2684#########################################################################
 2685	global		_ftentoxs_
 2686_ftentoxs_:
 2687	link		%a6,&-LOCAL_SIZE
 2688
 2689	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2690	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2691	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2692
 2693	fmov.l		&0x0,%fpcr		# zero FPCR
 2694
 2695#
 2696#	copy, convert, and tag input argument
 2697#
 2698	fmov.s		0x8(%a6),%fp0		# load sgl input
 2699	fmov.x		%fp0,FP_SRC(%a6)
 2700	lea		FP_SRC(%a6),%a0
 2701	bsr.l		tag			# fetch operand type
 2702	mov.b		%d0,STAG(%a6)
 2703	mov.b		%d0,%d1
 2704
 2705	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2706
 2707	clr.l		%d0
 2708	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2709
 2710	tst.b		%d1
 2711	bne.b		_L12_2s
 2712	bsr.l		stentox			# operand is a NORM
 2713	bra.b		_L12_6s
 2714_L12_2s:
 2715	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2716	bne.b		_L12_3s			# no
 2717	bsr.l		ld_pone			# yes
 2718	bra.b		_L12_6s
 2719_L12_3s:
 2720	cmpi.b		%d1,&INF		# is operand an INF?
 2721	bne.b		_L12_4s			# no
 2722	bsr.l		szr_inf			# yes
 2723	bra.b		_L12_6s
 2724_L12_4s:
 2725	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2726	bne.b		_L12_5s			# no
 2727	bsr.l		src_qnan			# yes
 2728	bra.b		_L12_6s
 2729_L12_5s:
 2730	bsr.l		stentoxd			# operand is a DENORM
 2731_L12_6s:
 2732
 2733#
 2734#	Result is now in FP0
 2735#
 2736	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2737	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2738	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2739	unlk		%a6
 2740	rts
 2741
 2742	global		_ftentoxd_
 2743_ftentoxd_:
 2744	link		%a6,&-LOCAL_SIZE
 2745
 2746	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2747	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2748	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2749
 2750	fmov.l		&0x0,%fpcr		# zero FPCR
 2751
 2752#
 2753#	copy, convert, and tag input argument
 2754#
 2755	fmov.d		0x8(%a6),%fp0		# load dbl input
 2756	fmov.x		%fp0,FP_SRC(%a6)
 2757	lea		FP_SRC(%a6),%a0
 2758	bsr.l		tag			# fetch operand type
 2759	mov.b		%d0,STAG(%a6)
 2760	mov.b		%d0,%d1
 2761
 2762	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2763
 2764	clr.l		%d0
 2765	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2766
 2767	mov.b		%d1,STAG(%a6)
 2768	tst.b		%d1
 2769	bne.b		_L12_2d
 2770	bsr.l		stentox			# operand is a NORM
 2771	bra.b		_L12_6d
 2772_L12_2d:
 2773	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2774	bne.b		_L12_3d			# no
 2775	bsr.l		ld_pone			# yes
 2776	bra.b		_L12_6d
 2777_L12_3d:
 2778	cmpi.b		%d1,&INF		# is operand an INF?
 2779	bne.b		_L12_4d			# no
 2780	bsr.l		szr_inf			# yes
 2781	bra.b		_L12_6d
 2782_L12_4d:
 2783	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2784	bne.b		_L12_5d			# no
 2785	bsr.l		src_qnan			# yes
 2786	bra.b		_L12_6d
 2787_L12_5d:
 2788	bsr.l		stentoxd			# operand is a DENORM
 2789_L12_6d:
 2790
 2791#
 2792#	Result is now in FP0
 2793#
 2794	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2795	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2796	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2797	unlk		%a6
 2798	rts
 2799
 2800	global		_ftentoxx_
 2801_ftentoxx_:
 2802	link		%a6,&-LOCAL_SIZE
 2803
 2804	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2805	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2806	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2807
 2808	fmov.l		&0x0,%fpcr		# zero FPCR
 2809
 2810#
 2811#	copy, convert, and tag input argument
 2812#
 2813	lea		FP_SRC(%a6),%a0
 2814	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 2815	mov.l		0x8+0x4(%a6),0x4(%a0)
 2816	mov.l		0x8+0x8(%a6),0x8(%a0)
 2817	bsr.l		tag			# fetch operand type
 2818	mov.b		%d0,STAG(%a6)
 2819	mov.b		%d0,%d1
 2820
 2821	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2822
 2823	clr.l		%d0
 2824	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2825
 2826	tst.b		%d1
 2827	bne.b		_L12_2x
 2828	bsr.l		stentox			# operand is a NORM
 2829	bra.b		_L12_6x
 2830_L12_2x:
 2831	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2832	bne.b		_L12_3x			# no
 2833	bsr.l		ld_pone			# yes
 2834	bra.b		_L12_6x
 2835_L12_3x:
 2836	cmpi.b		%d1,&INF		# is operand an INF?
 2837	bne.b		_L12_4x			# no
 2838	bsr.l		szr_inf			# yes
 2839	bra.b		_L12_6x
 2840_L12_4x:
 2841	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2842	bne.b		_L12_5x			# no
 2843	bsr.l		src_qnan			# yes
 2844	bra.b		_L12_6x
 2845_L12_5x:
 2846	bsr.l		stentoxd			# operand is a DENORM
 2847_L12_6x:
 2848
 2849#
 2850#	Result is now in FP0
 2851#
 2852	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2853	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2854	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2855	unlk		%a6
 2856	rts
 2857
 2858
 2859#########################################################################
 2860# MONADIC TEMPLATE							#
 2861#########################################################################
 2862	global		_flogns_
 2863_flogns_:
 2864	link		%a6,&-LOCAL_SIZE
 2865
 2866	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2867	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2868	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2869
 2870	fmov.l		&0x0,%fpcr		# zero FPCR
 2871
 2872#
 2873#	copy, convert, and tag input argument
 2874#
 2875	fmov.s		0x8(%a6),%fp0		# load sgl input
 2876	fmov.x		%fp0,FP_SRC(%a6)
 2877	lea		FP_SRC(%a6),%a0
 2878	bsr.l		tag			# fetch operand type
 2879	mov.b		%d0,STAG(%a6)
 2880	mov.b		%d0,%d1
 2881
 2882	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2883
 2884	clr.l		%d0
 2885	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2886
 2887	tst.b		%d1
 2888	bne.b		_L13_2s
 2889	bsr.l		slogn			# operand is a NORM
 2890	bra.b		_L13_6s
 2891_L13_2s:
 2892	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2893	bne.b		_L13_3s			# no
 2894	bsr.l		t_dz2			# yes
 2895	bra.b		_L13_6s
 2896_L13_3s:
 2897	cmpi.b		%d1,&INF		# is operand an INF?
 2898	bne.b		_L13_4s			# no
 2899	bsr.l		sopr_inf			# yes
 2900	bra.b		_L13_6s
 2901_L13_4s:
 2902	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2903	bne.b		_L13_5s			# no
 2904	bsr.l		src_qnan			# yes
 2905	bra.b		_L13_6s
 2906_L13_5s:
 2907	bsr.l		slognd			# operand is a DENORM
 2908_L13_6s:
 2909
 2910#
 2911#	Result is now in FP0
 2912#
 2913	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2914	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2915	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2916	unlk		%a6
 2917	rts
 2918
 2919	global		_flognd_
 2920_flognd_:
 2921	link		%a6,&-LOCAL_SIZE
 2922
 2923	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2924	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2925	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2926
 2927	fmov.l		&0x0,%fpcr		# zero FPCR
 2928
 2929#
 2930#	copy, convert, and tag input argument
 2931#
 2932	fmov.d		0x8(%a6),%fp0		# load dbl input
 2933	fmov.x		%fp0,FP_SRC(%a6)
 2934	lea		FP_SRC(%a6),%a0
 2935	bsr.l		tag			# fetch operand type
 2936	mov.b		%d0,STAG(%a6)
 2937	mov.b		%d0,%d1
 2938
 2939	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2940
 2941	clr.l		%d0
 2942	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 2943
 2944	mov.b		%d1,STAG(%a6)
 2945	tst.b		%d1
 2946	bne.b		_L13_2d
 2947	bsr.l		slogn			# operand is a NORM
 2948	bra.b		_L13_6d
 2949_L13_2d:
 2950	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 2951	bne.b		_L13_3d			# no
 2952	bsr.l		t_dz2			# yes
 2953	bra.b		_L13_6d
 2954_L13_3d:
 2955	cmpi.b		%d1,&INF		# is operand an INF?
 2956	bne.b		_L13_4d			# no
 2957	bsr.l		sopr_inf			# yes
 2958	bra.b		_L13_6d
 2959_L13_4d:
 2960	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 2961	bne.b		_L13_5d			# no
 2962	bsr.l		src_qnan			# yes
 2963	bra.b		_L13_6d
 2964_L13_5d:
 2965	bsr.l		slognd			# operand is a DENORM
 2966_L13_6d:
 2967
 2968#
 2969#	Result is now in FP0
 2970#
 2971	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 2972	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 2973	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 2974	unlk		%a6
 2975	rts
 2976
 2977	global		_flognx_
 2978_flognx_:
 2979	link		%a6,&-LOCAL_SIZE
 2980
 2981	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 2982	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 2983	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 2984
 2985	fmov.l		&0x0,%fpcr		# zero FPCR
 2986
 2987#
 2988#	copy, convert, and tag input argument
 2989#
 2990	lea		FP_SRC(%a6),%a0
 2991	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 2992	mov.l		0x8+0x4(%a6),0x4(%a0)
 2993	mov.l		0x8+0x8(%a6),0x8(%a0)
 2994	bsr.l		tag			# fetch operand type
 2995	mov.b		%d0,STAG(%a6)
 2996	mov.b		%d0,%d1
 2997
 2998	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 2999
 3000	clr.l		%d0
 3001	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3002
 3003	tst.b		%d1
 3004	bne.b		_L13_2x
 3005	bsr.l		slogn			# operand is a NORM
 3006	bra.b		_L13_6x
 3007_L13_2x:
 3008	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3009	bne.b		_L13_3x			# no
 3010	bsr.l		t_dz2			# yes
 3011	bra.b		_L13_6x
 3012_L13_3x:
 3013	cmpi.b		%d1,&INF		# is operand an INF?
 3014	bne.b		_L13_4x			# no
 3015	bsr.l		sopr_inf			# yes
 3016	bra.b		_L13_6x
 3017_L13_4x:
 3018	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3019	bne.b		_L13_5x			# no
 3020	bsr.l		src_qnan			# yes
 3021	bra.b		_L13_6x
 3022_L13_5x:
 3023	bsr.l		slognd			# operand is a DENORM
 3024_L13_6x:
 3025
 3026#
 3027#	Result is now in FP0
 3028#
 3029	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3030	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3031	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3032	unlk		%a6
 3033	rts
 3034
 3035
 3036#########################################################################
 3037# MONADIC TEMPLATE							#
 3038#########################################################################
 3039	global		_flog10s_
 3040_flog10s_:
 3041	link		%a6,&-LOCAL_SIZE
 3042
 3043	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3044	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3045	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3046
 3047	fmov.l		&0x0,%fpcr		# zero FPCR
 3048
 3049#
 3050#	copy, convert, and tag input argument
 3051#
 3052	fmov.s		0x8(%a6),%fp0		# load sgl input
 3053	fmov.x		%fp0,FP_SRC(%a6)
 3054	lea		FP_SRC(%a6),%a0
 3055	bsr.l		tag			# fetch operand type
 3056	mov.b		%d0,STAG(%a6)
 3057	mov.b		%d0,%d1
 3058
 3059	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3060
 3061	clr.l		%d0
 3062	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3063
 3064	tst.b		%d1
 3065	bne.b		_L14_2s
 3066	bsr.l		slog10			# operand is a NORM
 3067	bra.b		_L14_6s
 3068_L14_2s:
 3069	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3070	bne.b		_L14_3s			# no
 3071	bsr.l		t_dz2			# yes
 3072	bra.b		_L14_6s
 3073_L14_3s:
 3074	cmpi.b		%d1,&INF		# is operand an INF?
 3075	bne.b		_L14_4s			# no
 3076	bsr.l		sopr_inf			# yes
 3077	bra.b		_L14_6s
 3078_L14_4s:
 3079	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3080	bne.b		_L14_5s			# no
 3081	bsr.l		src_qnan			# yes
 3082	bra.b		_L14_6s
 3083_L14_5s:
 3084	bsr.l		slog10d			# operand is a DENORM
 3085_L14_6s:
 3086
 3087#
 3088#	Result is now in FP0
 3089#
 3090	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3091	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3092	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3093	unlk		%a6
 3094	rts
 3095
 3096	global		_flog10d_
 3097_flog10d_:
 3098	link		%a6,&-LOCAL_SIZE
 3099
 3100	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3101	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3102	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3103
 3104	fmov.l		&0x0,%fpcr		# zero FPCR
 3105
 3106#
 3107#	copy, convert, and tag input argument
 3108#
 3109	fmov.d		0x8(%a6),%fp0		# load dbl input
 3110	fmov.x		%fp0,FP_SRC(%a6)
 3111	lea		FP_SRC(%a6),%a0
 3112	bsr.l		tag			# fetch operand type
 3113	mov.b		%d0,STAG(%a6)
 3114	mov.b		%d0,%d1
 3115
 3116	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3117
 3118	clr.l		%d0
 3119	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3120
 3121	mov.b		%d1,STAG(%a6)
 3122	tst.b		%d1
 3123	bne.b		_L14_2d
 3124	bsr.l		slog10			# operand is a NORM
 3125	bra.b		_L14_6d
 3126_L14_2d:
 3127	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3128	bne.b		_L14_3d			# no
 3129	bsr.l		t_dz2			# yes
 3130	bra.b		_L14_6d
 3131_L14_3d:
 3132	cmpi.b		%d1,&INF		# is operand an INF?
 3133	bne.b		_L14_4d			# no
 3134	bsr.l		sopr_inf			# yes
 3135	bra.b		_L14_6d
 3136_L14_4d:
 3137	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3138	bne.b		_L14_5d			# no
 3139	bsr.l		src_qnan			# yes
 3140	bra.b		_L14_6d
 3141_L14_5d:
 3142	bsr.l		slog10d			# operand is a DENORM
 3143_L14_6d:
 3144
 3145#
 3146#	Result is now in FP0
 3147#
 3148	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3149	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3150	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3151	unlk		%a6
 3152	rts
 3153
 3154	global		_flog10x_
 3155_flog10x_:
 3156	link		%a6,&-LOCAL_SIZE
 3157
 3158	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3159	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3160	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3161
 3162	fmov.l		&0x0,%fpcr		# zero FPCR
 3163
 3164#
 3165#	copy, convert, and tag input argument
 3166#
 3167	lea		FP_SRC(%a6),%a0
 3168	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 3169	mov.l		0x8+0x4(%a6),0x4(%a0)
 3170	mov.l		0x8+0x8(%a6),0x8(%a0)
 3171	bsr.l		tag			# fetch operand type
 3172	mov.b		%d0,STAG(%a6)
 3173	mov.b		%d0,%d1
 3174
 3175	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3176
 3177	clr.l		%d0
 3178	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3179
 3180	tst.b		%d1
 3181	bne.b		_L14_2x
 3182	bsr.l		slog10			# operand is a NORM
 3183	bra.b		_L14_6x
 3184_L14_2x:
 3185	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3186	bne.b		_L14_3x			# no
 3187	bsr.l		t_dz2			# yes
 3188	bra.b		_L14_6x
 3189_L14_3x:
 3190	cmpi.b		%d1,&INF		# is operand an INF?
 3191	bne.b		_L14_4x			# no
 3192	bsr.l		sopr_inf			# yes
 3193	bra.b		_L14_6x
 3194_L14_4x:
 3195	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3196	bne.b		_L14_5x			# no
 3197	bsr.l		src_qnan			# yes
 3198	bra.b		_L14_6x
 3199_L14_5x:
 3200	bsr.l		slog10d			# operand is a DENORM
 3201_L14_6x:
 3202
 3203#
 3204#	Result is now in FP0
 3205#
 3206	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3207	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3208	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3209	unlk		%a6
 3210	rts
 3211
 3212
 3213#########################################################################
 3214# MONADIC TEMPLATE							#
 3215#########################################################################
 3216	global		_flog2s_
 3217_flog2s_:
 3218	link		%a6,&-LOCAL_SIZE
 3219
 3220	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3221	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3222	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3223
 3224	fmov.l		&0x0,%fpcr		# zero FPCR
 3225
 3226#
 3227#	copy, convert, and tag input argument
 3228#
 3229	fmov.s		0x8(%a6),%fp0		# load sgl input
 3230	fmov.x		%fp0,FP_SRC(%a6)
 3231	lea		FP_SRC(%a6),%a0
 3232	bsr.l		tag			# fetch operand type
 3233	mov.b		%d0,STAG(%a6)
 3234	mov.b		%d0,%d1
 3235
 3236	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3237
 3238	clr.l		%d0
 3239	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3240
 3241	tst.b		%d1
 3242	bne.b		_L15_2s
 3243	bsr.l		slog2			# operand is a NORM
 3244	bra.b		_L15_6s
 3245_L15_2s:
 3246	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3247	bne.b		_L15_3s			# no
 3248	bsr.l		t_dz2			# yes
 3249	bra.b		_L15_6s
 3250_L15_3s:
 3251	cmpi.b		%d1,&INF		# is operand an INF?
 3252	bne.b		_L15_4s			# no
 3253	bsr.l		sopr_inf			# yes
 3254	bra.b		_L15_6s
 3255_L15_4s:
 3256	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3257	bne.b		_L15_5s			# no
 3258	bsr.l		src_qnan			# yes
 3259	bra.b		_L15_6s
 3260_L15_5s:
 3261	bsr.l		slog2d			# operand is a DENORM
 3262_L15_6s:
 3263
 3264#
 3265#	Result is now in FP0
 3266#
 3267	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3268	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3269	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3270	unlk		%a6
 3271	rts
 3272
 3273	global		_flog2d_
 3274_flog2d_:
 3275	link		%a6,&-LOCAL_SIZE
 3276
 3277	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3278	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3279	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3280
 3281	fmov.l		&0x0,%fpcr		# zero FPCR
 3282
 3283#
 3284#	copy, convert, and tag input argument
 3285#
 3286	fmov.d		0x8(%a6),%fp0		# load dbl input
 3287	fmov.x		%fp0,FP_SRC(%a6)
 3288	lea		FP_SRC(%a6),%a0
 3289	bsr.l		tag			# fetch operand type
 3290	mov.b		%d0,STAG(%a6)
 3291	mov.b		%d0,%d1
 3292
 3293	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3294
 3295	clr.l		%d0
 3296	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3297
 3298	mov.b		%d1,STAG(%a6)
 3299	tst.b		%d1
 3300	bne.b		_L15_2d
 3301	bsr.l		slog2			# operand is a NORM
 3302	bra.b		_L15_6d
 3303_L15_2d:
 3304	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3305	bne.b		_L15_3d			# no
 3306	bsr.l		t_dz2			# yes
 3307	bra.b		_L15_6d
 3308_L15_3d:
 3309	cmpi.b		%d1,&INF		# is operand an INF?
 3310	bne.b		_L15_4d			# no
 3311	bsr.l		sopr_inf			# yes
 3312	bra.b		_L15_6d
 3313_L15_4d:
 3314	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3315	bne.b		_L15_5d			# no
 3316	bsr.l		src_qnan			# yes
 3317	bra.b		_L15_6d
 3318_L15_5d:
 3319	bsr.l		slog2d			# operand is a DENORM
 3320_L15_6d:
 3321
 3322#
 3323#	Result is now in FP0
 3324#
 3325	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3326	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3327	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3328	unlk		%a6
 3329	rts
 3330
 3331	global		_flog2x_
 3332_flog2x_:
 3333	link		%a6,&-LOCAL_SIZE
 3334
 3335	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3336	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3337	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3338
 3339	fmov.l		&0x0,%fpcr		# zero FPCR
 3340
 3341#
 3342#	copy, convert, and tag input argument
 3343#
 3344	lea		FP_SRC(%a6),%a0
 3345	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 3346	mov.l		0x8+0x4(%a6),0x4(%a0)
 3347	mov.l		0x8+0x8(%a6),0x8(%a0)
 3348	bsr.l		tag			# fetch operand type
 3349	mov.b		%d0,STAG(%a6)
 3350	mov.b		%d0,%d1
 3351
 3352	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3353
 3354	clr.l		%d0
 3355	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3356
 3357	tst.b		%d1
 3358	bne.b		_L15_2x
 3359	bsr.l		slog2			# operand is a NORM
 3360	bra.b		_L15_6x
 3361_L15_2x:
 3362	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3363	bne.b		_L15_3x			# no
 3364	bsr.l		t_dz2			# yes
 3365	bra.b		_L15_6x
 3366_L15_3x:
 3367	cmpi.b		%d1,&INF		# is operand an INF?
 3368	bne.b		_L15_4x			# no
 3369	bsr.l		sopr_inf			# yes
 3370	bra.b		_L15_6x
 3371_L15_4x:
 3372	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3373	bne.b		_L15_5x			# no
 3374	bsr.l		src_qnan			# yes
 3375	bra.b		_L15_6x
 3376_L15_5x:
 3377	bsr.l		slog2d			# operand is a DENORM
 3378_L15_6x:
 3379
 3380#
 3381#	Result is now in FP0
 3382#
 3383	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3384	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3385	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3386	unlk		%a6
 3387	rts
 3388
 3389
 3390#########################################################################
 3391# MONADIC TEMPLATE							#
 3392#########################################################################
 3393	global		_fcoshs_
 3394_fcoshs_:
 3395	link		%a6,&-LOCAL_SIZE
 3396
 3397	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3398	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3399	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3400
 3401	fmov.l		&0x0,%fpcr		# zero FPCR
 3402
 3403#
 3404#	copy, convert, and tag input argument
 3405#
 3406	fmov.s		0x8(%a6),%fp0		# load sgl input
 3407	fmov.x		%fp0,FP_SRC(%a6)
 3408	lea		FP_SRC(%a6),%a0
 3409	bsr.l		tag			# fetch operand type
 3410	mov.b		%d0,STAG(%a6)
 3411	mov.b		%d0,%d1
 3412
 3413	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3414
 3415	clr.l		%d0
 3416	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3417
 3418	tst.b		%d1
 3419	bne.b		_L16_2s
 3420	bsr.l		scosh			# operand is a NORM
 3421	bra.b		_L16_6s
 3422_L16_2s:
 3423	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3424	bne.b		_L16_3s			# no
 3425	bsr.l		ld_pone			# yes
 3426	bra.b		_L16_6s
 3427_L16_3s:
 3428	cmpi.b		%d1,&INF		# is operand an INF?
 3429	bne.b		_L16_4s			# no
 3430	bsr.l		ld_pinf			# yes
 3431	bra.b		_L16_6s
 3432_L16_4s:
 3433	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3434	bne.b		_L16_5s			# no
 3435	bsr.l		src_qnan			# yes
 3436	bra.b		_L16_6s
 3437_L16_5s:
 3438	bsr.l		scoshd			# operand is a DENORM
 3439_L16_6s:
 3440
 3441#
 3442#	Result is now in FP0
 3443#
 3444	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3445	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3446	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3447	unlk		%a6
 3448	rts
 3449
 3450	global		_fcoshd_
 3451_fcoshd_:
 3452	link		%a6,&-LOCAL_SIZE
 3453
 3454	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3455	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3456	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3457
 3458	fmov.l		&0x0,%fpcr		# zero FPCR
 3459
 3460#
 3461#	copy, convert, and tag input argument
 3462#
 3463	fmov.d		0x8(%a6),%fp0		# load dbl input
 3464	fmov.x		%fp0,FP_SRC(%a6)
 3465	lea		FP_SRC(%a6),%a0
 3466	bsr.l		tag			# fetch operand type
 3467	mov.b		%d0,STAG(%a6)
 3468	mov.b		%d0,%d1
 3469
 3470	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3471
 3472	clr.l		%d0
 3473	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3474
 3475	mov.b		%d1,STAG(%a6)
 3476	tst.b		%d1
 3477	bne.b		_L16_2d
 3478	bsr.l		scosh			# operand is a NORM
 3479	bra.b		_L16_6d
 3480_L16_2d:
 3481	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3482	bne.b		_L16_3d			# no
 3483	bsr.l		ld_pone			# yes
 3484	bra.b		_L16_6d
 3485_L16_3d:
 3486	cmpi.b		%d1,&INF		# is operand an INF?
 3487	bne.b		_L16_4d			# no
 3488	bsr.l		ld_pinf			# yes
 3489	bra.b		_L16_6d
 3490_L16_4d:
 3491	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3492	bne.b		_L16_5d			# no
 3493	bsr.l		src_qnan			# yes
 3494	bra.b		_L16_6d
 3495_L16_5d:
 3496	bsr.l		scoshd			# operand is a DENORM
 3497_L16_6d:
 3498
 3499#
 3500#	Result is now in FP0
 3501#
 3502	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3503	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3504	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3505	unlk		%a6
 3506	rts
 3507
 3508	global		_fcoshx_
 3509_fcoshx_:
 3510	link		%a6,&-LOCAL_SIZE
 3511
 3512	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3513	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3514	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3515
 3516	fmov.l		&0x0,%fpcr		# zero FPCR
 3517
 3518#
 3519#	copy, convert, and tag input argument
 3520#
 3521	lea		FP_SRC(%a6),%a0
 3522	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 3523	mov.l		0x8+0x4(%a6),0x4(%a0)
 3524	mov.l		0x8+0x8(%a6),0x8(%a0)
 3525	bsr.l		tag			# fetch operand type
 3526	mov.b		%d0,STAG(%a6)
 3527	mov.b		%d0,%d1
 3528
 3529	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3530
 3531	clr.l		%d0
 3532	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3533
 3534	tst.b		%d1
 3535	bne.b		_L16_2x
 3536	bsr.l		scosh			# operand is a NORM
 3537	bra.b		_L16_6x
 3538_L16_2x:
 3539	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3540	bne.b		_L16_3x			# no
 3541	bsr.l		ld_pone			# yes
 3542	bra.b		_L16_6x
 3543_L16_3x:
 3544	cmpi.b		%d1,&INF		# is operand an INF?
 3545	bne.b		_L16_4x			# no
 3546	bsr.l		ld_pinf			# yes
 3547	bra.b		_L16_6x
 3548_L16_4x:
 3549	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3550	bne.b		_L16_5x			# no
 3551	bsr.l		src_qnan			# yes
 3552	bra.b		_L16_6x
 3553_L16_5x:
 3554	bsr.l		scoshd			# operand is a DENORM
 3555_L16_6x:
 3556
 3557#
 3558#	Result is now in FP0
 3559#
 3560	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3561	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3562	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3563	unlk		%a6
 3564	rts
 3565
 3566
 3567#########################################################################
 3568# MONADIC TEMPLATE							#
 3569#########################################################################
 3570	global		_facoss_
 3571_facoss_:
 3572	link		%a6,&-LOCAL_SIZE
 3573
 3574	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3575	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3576	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3577
 3578	fmov.l		&0x0,%fpcr		# zero FPCR
 3579
 3580#
 3581#	copy, convert, and tag input argument
 3582#
 3583	fmov.s		0x8(%a6),%fp0		# load sgl input
 3584	fmov.x		%fp0,FP_SRC(%a6)
 3585	lea		FP_SRC(%a6),%a0
 3586	bsr.l		tag			# fetch operand type
 3587	mov.b		%d0,STAG(%a6)
 3588	mov.b		%d0,%d1
 3589
 3590	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3591
 3592	clr.l		%d0
 3593	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3594
 3595	tst.b		%d1
 3596	bne.b		_L17_2s
 3597	bsr.l		sacos			# operand is a NORM
 3598	bra.b		_L17_6s
 3599_L17_2s:
 3600	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3601	bne.b		_L17_3s			# no
 3602	bsr.l		ld_ppi2			# yes
 3603	bra.b		_L17_6s
 3604_L17_3s:
 3605	cmpi.b		%d1,&INF		# is operand an INF?
 3606	bne.b		_L17_4s			# no
 3607	bsr.l		t_operr			# yes
 3608	bra.b		_L17_6s
 3609_L17_4s:
 3610	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3611	bne.b		_L17_5s			# no
 3612	bsr.l		src_qnan			# yes
 3613	bra.b		_L17_6s
 3614_L17_5s:
 3615	bsr.l		sacosd			# operand is a DENORM
 3616_L17_6s:
 3617
 3618#
 3619#	Result is now in FP0
 3620#
 3621	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3622	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3623	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3624	unlk		%a6
 3625	rts
 3626
 3627	global		_facosd_
 3628_facosd_:
 3629	link		%a6,&-LOCAL_SIZE
 3630
 3631	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3632	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3633	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3634
 3635	fmov.l		&0x0,%fpcr		# zero FPCR
 3636
 3637#
 3638#	copy, convert, and tag input argument
 3639#
 3640	fmov.d		0x8(%a6),%fp0		# load dbl input
 3641	fmov.x		%fp0,FP_SRC(%a6)
 3642	lea		FP_SRC(%a6),%a0
 3643	bsr.l		tag			# fetch operand type
 3644	mov.b		%d0,STAG(%a6)
 3645	mov.b		%d0,%d1
 3646
 3647	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3648
 3649	clr.l		%d0
 3650	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3651
 3652	mov.b		%d1,STAG(%a6)
 3653	tst.b		%d1
 3654	bne.b		_L17_2d
 3655	bsr.l		sacos			# operand is a NORM
 3656	bra.b		_L17_6d
 3657_L17_2d:
 3658	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3659	bne.b		_L17_3d			# no
 3660	bsr.l		ld_ppi2			# yes
 3661	bra.b		_L17_6d
 3662_L17_3d:
 3663	cmpi.b		%d1,&INF		# is operand an INF?
 3664	bne.b		_L17_4d			# no
 3665	bsr.l		t_operr			# yes
 3666	bra.b		_L17_6d
 3667_L17_4d:
 3668	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3669	bne.b		_L17_5d			# no
 3670	bsr.l		src_qnan			# yes
 3671	bra.b		_L17_6d
 3672_L17_5d:
 3673	bsr.l		sacosd			# operand is a DENORM
 3674_L17_6d:
 3675
 3676#
 3677#	Result is now in FP0
 3678#
 3679	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3680	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3681	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3682	unlk		%a6
 3683	rts
 3684
 3685	global		_facosx_
 3686_facosx_:
 3687	link		%a6,&-LOCAL_SIZE
 3688
 3689	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3690	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3691	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3692
 3693	fmov.l		&0x0,%fpcr		# zero FPCR
 3694
 3695#
 3696#	copy, convert, and tag input argument
 3697#
 3698	lea		FP_SRC(%a6),%a0
 3699	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 3700	mov.l		0x8+0x4(%a6),0x4(%a0)
 3701	mov.l		0x8+0x8(%a6),0x8(%a0)
 3702	bsr.l		tag			# fetch operand type
 3703	mov.b		%d0,STAG(%a6)
 3704	mov.b		%d0,%d1
 3705
 3706	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3707
 3708	clr.l		%d0
 3709	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3710
 3711	tst.b		%d1
 3712	bne.b		_L17_2x
 3713	bsr.l		sacos			# operand is a NORM
 3714	bra.b		_L17_6x
 3715_L17_2x:
 3716	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3717	bne.b		_L17_3x			# no
 3718	bsr.l		ld_ppi2			# yes
 3719	bra.b		_L17_6x
 3720_L17_3x:
 3721	cmpi.b		%d1,&INF		# is operand an INF?
 3722	bne.b		_L17_4x			# no
 3723	bsr.l		t_operr			# yes
 3724	bra.b		_L17_6x
 3725_L17_4x:
 3726	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3727	bne.b		_L17_5x			# no
 3728	bsr.l		src_qnan			# yes
 3729	bra.b		_L17_6x
 3730_L17_5x:
 3731	bsr.l		sacosd			# operand is a DENORM
 3732_L17_6x:
 3733
 3734#
 3735#	Result is now in FP0
 3736#
 3737	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3738	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3739	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3740	unlk		%a6
 3741	rts
 3742
 3743
 3744#########################################################################
 3745# MONADIC TEMPLATE							#
 3746#########################################################################
 3747	global		_fgetexps_
 3748_fgetexps_:
 3749	link		%a6,&-LOCAL_SIZE
 3750
 3751	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3752	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3753	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3754
 3755	fmov.l		&0x0,%fpcr		# zero FPCR
 3756
 3757#
 3758#	copy, convert, and tag input argument
 3759#
 3760	fmov.s		0x8(%a6),%fp0		# load sgl input
 3761	fmov.x		%fp0,FP_SRC(%a6)
 3762	lea		FP_SRC(%a6),%a0
 3763	bsr.l		tag			# fetch operand type
 3764	mov.b		%d0,STAG(%a6)
 3765	mov.b		%d0,%d1
 3766
 3767	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3768
 3769	clr.l		%d0
 3770	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3771
 3772	tst.b		%d1
 3773	bne.b		_L18_2s
 3774	bsr.l		sgetexp			# operand is a NORM
 3775	bra.b		_L18_6s
 3776_L18_2s:
 3777	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3778	bne.b		_L18_3s			# no
 3779	bsr.l		src_zero			# yes
 3780	bra.b		_L18_6s
 3781_L18_3s:
 3782	cmpi.b		%d1,&INF		# is operand an INF?
 3783	bne.b		_L18_4s			# no
 3784	bsr.l		t_operr			# yes
 3785	bra.b		_L18_6s
 3786_L18_4s:
 3787	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3788	bne.b		_L18_5s			# no
 3789	bsr.l		src_qnan			# yes
 3790	bra.b		_L18_6s
 3791_L18_5s:
 3792	bsr.l		sgetexpd			# operand is a DENORM
 3793_L18_6s:
 3794
 3795#
 3796#	Result is now in FP0
 3797#
 3798	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3799	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3800	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3801	unlk		%a6
 3802	rts
 3803
 3804	global		_fgetexpd_
 3805_fgetexpd_:
 3806	link		%a6,&-LOCAL_SIZE
 3807
 3808	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3809	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3810	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3811
 3812	fmov.l		&0x0,%fpcr		# zero FPCR
 3813
 3814#
 3815#	copy, convert, and tag input argument
 3816#
 3817	fmov.d		0x8(%a6),%fp0		# load dbl input
 3818	fmov.x		%fp0,FP_SRC(%a6)
 3819	lea		FP_SRC(%a6),%a0
 3820	bsr.l		tag			# fetch operand type
 3821	mov.b		%d0,STAG(%a6)
 3822	mov.b		%d0,%d1
 3823
 3824	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3825
 3826	clr.l		%d0
 3827	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3828
 3829	mov.b		%d1,STAG(%a6)
 3830	tst.b		%d1
 3831	bne.b		_L18_2d
 3832	bsr.l		sgetexp			# operand is a NORM
 3833	bra.b		_L18_6d
 3834_L18_2d:
 3835	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3836	bne.b		_L18_3d			# no
 3837	bsr.l		src_zero			# yes
 3838	bra.b		_L18_6d
 3839_L18_3d:
 3840	cmpi.b		%d1,&INF		# is operand an INF?
 3841	bne.b		_L18_4d			# no
 3842	bsr.l		t_operr			# yes
 3843	bra.b		_L18_6d
 3844_L18_4d:
 3845	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3846	bne.b		_L18_5d			# no
 3847	bsr.l		src_qnan			# yes
 3848	bra.b		_L18_6d
 3849_L18_5d:
 3850	bsr.l		sgetexpd			# operand is a DENORM
 3851_L18_6d:
 3852
 3853#
 3854#	Result is now in FP0
 3855#
 3856	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3857	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3858	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3859	unlk		%a6
 3860	rts
 3861
 3862	global		_fgetexpx_
 3863_fgetexpx_:
 3864	link		%a6,&-LOCAL_SIZE
 3865
 3866	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3867	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3868	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3869
 3870	fmov.l		&0x0,%fpcr		# zero FPCR
 3871
 3872#
 3873#	copy, convert, and tag input argument
 3874#
 3875	lea		FP_SRC(%a6),%a0
 3876	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 3877	mov.l		0x8+0x4(%a6),0x4(%a0)
 3878	mov.l		0x8+0x8(%a6),0x8(%a0)
 3879	bsr.l		tag			# fetch operand type
 3880	mov.b		%d0,STAG(%a6)
 3881	mov.b		%d0,%d1
 3882
 3883	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3884
 3885	clr.l		%d0
 3886	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3887
 3888	tst.b		%d1
 3889	bne.b		_L18_2x
 3890	bsr.l		sgetexp			# operand is a NORM
 3891	bra.b		_L18_6x
 3892_L18_2x:
 3893	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3894	bne.b		_L18_3x			# no
 3895	bsr.l		src_zero			# yes
 3896	bra.b		_L18_6x
 3897_L18_3x:
 3898	cmpi.b		%d1,&INF		# is operand an INF?
 3899	bne.b		_L18_4x			# no
 3900	bsr.l		t_operr			# yes
 3901	bra.b		_L18_6x
 3902_L18_4x:
 3903	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3904	bne.b		_L18_5x			# no
 3905	bsr.l		src_qnan			# yes
 3906	bra.b		_L18_6x
 3907_L18_5x:
 3908	bsr.l		sgetexpd			# operand is a DENORM
 3909_L18_6x:
 3910
 3911#
 3912#	Result is now in FP0
 3913#
 3914	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3915	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3916	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3917	unlk		%a6
 3918	rts
 3919
 3920
 3921#########################################################################
 3922# MONADIC TEMPLATE							#
 3923#########################################################################
 3924	global		_fgetmans_
 3925_fgetmans_:
 3926	link		%a6,&-LOCAL_SIZE
 3927
 3928	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3929	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3930	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3931
 3932	fmov.l		&0x0,%fpcr		# zero FPCR
 3933
 3934#
 3935#	copy, convert, and tag input argument
 3936#
 3937	fmov.s		0x8(%a6),%fp0		# load sgl input
 3938	fmov.x		%fp0,FP_SRC(%a6)
 3939	lea		FP_SRC(%a6),%a0
 3940	bsr.l		tag			# fetch operand type
 3941	mov.b		%d0,STAG(%a6)
 3942	mov.b		%d0,%d1
 3943
 3944	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 3945
 3946	clr.l		%d0
 3947	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 3948
 3949	tst.b		%d1
 3950	bne.b		_L19_2s
 3951	bsr.l		sgetman			# operand is a NORM
 3952	bra.b		_L19_6s
 3953_L19_2s:
 3954	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 3955	bne.b		_L19_3s			# no
 3956	bsr.l		src_zero			# yes
 3957	bra.b		_L19_6s
 3958_L19_3s:
 3959	cmpi.b		%d1,&INF		# is operand an INF?
 3960	bne.b		_L19_4s			# no
 3961	bsr.l		t_operr			# yes
 3962	bra.b		_L19_6s
 3963_L19_4s:
 3964	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 3965	bne.b		_L19_5s			# no
 3966	bsr.l		src_qnan			# yes
 3967	bra.b		_L19_6s
 3968_L19_5s:
 3969	bsr.l		sgetmand			# operand is a DENORM
 3970_L19_6s:
 3971
 3972#
 3973#	Result is now in FP0
 3974#
 3975	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 3976	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 3977	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 3978	unlk		%a6
 3979	rts
 3980
 3981	global		_fgetmand_
 3982_fgetmand_:
 3983	link		%a6,&-LOCAL_SIZE
 3984
 3985	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 3986	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 3987	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 3988
 3989	fmov.l		&0x0,%fpcr		# zero FPCR
 3990
 3991#
 3992#	copy, convert, and tag input argument
 3993#
 3994	fmov.d		0x8(%a6),%fp0		# load dbl input
 3995	fmov.x		%fp0,FP_SRC(%a6)
 3996	lea		FP_SRC(%a6),%a0
 3997	bsr.l		tag			# fetch operand type
 3998	mov.b		%d0,STAG(%a6)
 3999	mov.b		%d0,%d1
 4000
 4001	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4002
 4003	clr.l		%d0
 4004	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4005
 4006	mov.b		%d1,STAG(%a6)
 4007	tst.b		%d1
 4008	bne.b		_L19_2d
 4009	bsr.l		sgetman			# operand is a NORM
 4010	bra.b		_L19_6d
 4011_L19_2d:
 4012	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4013	bne.b		_L19_3d			# no
 4014	bsr.l		src_zero			# yes
 4015	bra.b		_L19_6d
 4016_L19_3d:
 4017	cmpi.b		%d1,&INF		# is operand an INF?
 4018	bne.b		_L19_4d			# no
 4019	bsr.l		t_operr			# yes
 4020	bra.b		_L19_6d
 4021_L19_4d:
 4022	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4023	bne.b		_L19_5d			# no
 4024	bsr.l		src_qnan			# yes
 4025	bra.b		_L19_6d
 4026_L19_5d:
 4027	bsr.l		sgetmand			# operand is a DENORM
 4028_L19_6d:
 4029
 4030#
 4031#	Result is now in FP0
 4032#
 4033	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4034	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4035	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4036	unlk		%a6
 4037	rts
 4038
 4039	global		_fgetmanx_
 4040_fgetmanx_:
 4041	link		%a6,&-LOCAL_SIZE
 4042
 4043	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4044	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4045	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4046
 4047	fmov.l		&0x0,%fpcr		# zero FPCR
 4048
 4049#
 4050#	copy, convert, and tag input argument
 4051#
 4052	lea		FP_SRC(%a6),%a0
 4053	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 4054	mov.l		0x8+0x4(%a6),0x4(%a0)
 4055	mov.l		0x8+0x8(%a6),0x8(%a0)
 4056	bsr.l		tag			# fetch operand type
 4057	mov.b		%d0,STAG(%a6)
 4058	mov.b		%d0,%d1
 4059
 4060	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4061
 4062	clr.l		%d0
 4063	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4064
 4065	tst.b		%d1
 4066	bne.b		_L19_2x
 4067	bsr.l		sgetman			# operand is a NORM
 4068	bra.b		_L19_6x
 4069_L19_2x:
 4070	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4071	bne.b		_L19_3x			# no
 4072	bsr.l		src_zero			# yes
 4073	bra.b		_L19_6x
 4074_L19_3x:
 4075	cmpi.b		%d1,&INF		# is operand an INF?
 4076	bne.b		_L19_4x			# no
 4077	bsr.l		t_operr			# yes
 4078	bra.b		_L19_6x
 4079_L19_4x:
 4080	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4081	bne.b		_L19_5x			# no
 4082	bsr.l		src_qnan			# yes
 4083	bra.b		_L19_6x
 4084_L19_5x:
 4085	bsr.l		sgetmand			# operand is a DENORM
 4086_L19_6x:
 4087
 4088#
 4089#	Result is now in FP0
 4090#
 4091	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4092	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4093	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4094	unlk		%a6
 4095	rts
 4096
 4097
 4098#########################################################################
 4099# MONADIC TEMPLATE							#
 4100#########################################################################
 4101	global		_fsincoss_
 4102_fsincoss_:
 4103	link		%a6,&-LOCAL_SIZE
 4104
 4105	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4106	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4107	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4108
 4109	fmov.l		&0x0,%fpcr		# zero FPCR
 4110
 4111#
 4112#	copy, convert, and tag input argument
 4113#
 4114	fmov.s		0x8(%a6),%fp0		# load sgl input
 4115	fmov.x		%fp0,FP_SRC(%a6)
 4116	lea		FP_SRC(%a6),%a0
 4117	bsr.l		tag			# fetch operand type
 4118	mov.b		%d0,STAG(%a6)
 4119	mov.b		%d0,%d1
 4120
 4121	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4122
 4123	clr.l		%d0
 4124	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4125
 4126	tst.b		%d1
 4127	bne.b		_L20_2s
 4128	bsr.l		ssincos			# operand is a NORM
 4129	bra.b		_L20_6s
 4130_L20_2s:
 4131	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4132	bne.b		_L20_3s			# no
 4133	bsr.l		ssincosz			# yes
 4134	bra.b		_L20_6s
 4135_L20_3s:
 4136	cmpi.b		%d1,&INF		# is operand an INF?
 4137	bne.b		_L20_4s			# no
 4138	bsr.l		ssincosi			# yes
 4139	bra.b		_L20_6s
 4140_L20_4s:
 4141	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4142	bne.b		_L20_5s			# no
 4143	bsr.l		ssincosqnan			# yes
 4144	bra.b		_L20_6s
 4145_L20_5s:
 4146	bsr.l		ssincosd			# operand is a DENORM
 4147_L20_6s:
 4148
 4149#
 4150#	Result is now in FP0
 4151#
 4152	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4153	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4154	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
 4155	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
 4156	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
 4157	unlk		%a6
 4158	rts
 4159
 4160	global		_fsincosd_
 4161_fsincosd_:
 4162	link		%a6,&-LOCAL_SIZE
 4163
 4164	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4165	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4166	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4167
 4168	fmov.l		&0x0,%fpcr		# zero FPCR
 4169
 4170#
 4171#	copy, convert, and tag input argument
 4172#
 4173	fmov.d		0x8(%a6),%fp0		# load dbl input
 4174	fmov.x		%fp0,FP_SRC(%a6)
 4175	lea		FP_SRC(%a6),%a0
 4176	bsr.l		tag			# fetch operand type
 4177	mov.b		%d0,STAG(%a6)
 4178	mov.b		%d0,%d1
 4179
 4180	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4181
 4182	clr.l		%d0
 4183	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4184
 4185	mov.b		%d1,STAG(%a6)
 4186	tst.b		%d1
 4187	bne.b		_L20_2d
 4188	bsr.l		ssincos			# operand is a NORM
 4189	bra.b		_L20_6d
 4190_L20_2d:
 4191	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4192	bne.b		_L20_3d			# no
 4193	bsr.l		ssincosz			# yes
 4194	bra.b		_L20_6d
 4195_L20_3d:
 4196	cmpi.b		%d1,&INF		# is operand an INF?
 4197	bne.b		_L20_4d			# no
 4198	bsr.l		ssincosi			# yes
 4199	bra.b		_L20_6d
 4200_L20_4d:
 4201	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4202	bne.b		_L20_5d			# no
 4203	bsr.l		ssincosqnan			# yes
 4204	bra.b		_L20_6d
 4205_L20_5d:
 4206	bsr.l		ssincosd			# operand is a DENORM
 4207_L20_6d:
 4208
 4209#
 4210#	Result is now in FP0
 4211#
 4212	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4213	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4214	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
 4215	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
 4216	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
 4217	unlk		%a6
 4218	rts
 4219
 4220	global		_fsincosx_
 4221_fsincosx_:
 4222	link		%a6,&-LOCAL_SIZE
 4223
 4224	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4225	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4226	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4227
 4228	fmov.l		&0x0,%fpcr		# zero FPCR
 4229
 4230#
 4231#	copy, convert, and tag input argument
 4232#
 4233	lea		FP_SRC(%a6),%a0
 4234	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
 4235	mov.l		0x8+0x4(%a6),0x4(%a0)
 4236	mov.l		0x8+0x8(%a6),0x8(%a0)
 4237	bsr.l		tag			# fetch operand type
 4238	mov.b		%d0,STAG(%a6)
 4239	mov.b		%d0,%d1
 4240
 4241	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4242
 4243	clr.l		%d0
 4244	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4245
 4246	tst.b		%d1
 4247	bne.b		_L20_2x
 4248	bsr.l		ssincos			# operand is a NORM
 4249	bra.b		_L20_6x
 4250_L20_2x:
 4251	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4252	bne.b		_L20_3x			# no
 4253	bsr.l		ssincosz			# yes
 4254	bra.b		_L20_6x
 4255_L20_3x:
 4256	cmpi.b		%d1,&INF		# is operand an INF?
 4257	bne.b		_L20_4x			# no
 4258	bsr.l		ssincosi			# yes
 4259	bra.b		_L20_6x
 4260_L20_4x:
 4261	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4262	bne.b		_L20_5x			# no
 4263	bsr.l		ssincosqnan			# yes
 4264	bra.b		_L20_6x
 4265_L20_5x:
 4266	bsr.l		ssincosd			# operand is a DENORM
 4267_L20_6x:
 4268
 4269#
 4270#	Result is now in FP0
 4271#
 4272	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4273	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4274	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
 4275	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
 4276	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
 4277	unlk		%a6
 4278	rts
 4279
 4280
 4281#########################################################################
 4282# DYADIC TEMPLATE							#
 4283#########################################################################
 4284	global		_frems_
 4285_frems_:
 4286	link		%a6,&-LOCAL_SIZE
 4287
 4288	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4289	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4290	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4291
 4292	fmov.l		&0x0,%fpcr		# zero FPCR
 4293
 4294#
 4295#	copy, convert, and tag input argument
 4296#
 4297	fmov.s		0x8(%a6),%fp0		# load sgl dst
 4298	fmov.x		%fp0,FP_DST(%a6)
 4299	lea		FP_DST(%a6),%a0
 4300	bsr.l		tag			# fetch operand type
 4301	mov.b		%d0,DTAG(%a6)
 4302
 4303	fmov.s		0xc(%a6),%fp0		# load sgl src
 4304	fmov.x		%fp0,FP_SRC(%a6)
 4305	lea		FP_SRC(%a6),%a0
 4306	bsr.l		tag			# fetch operand type
 4307	mov.b		%d0,STAG(%a6)
 4308	mov.l		%d0,%d1
 4309
 4310	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4311
 4312	clr.l		%d0
 4313	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4314
 4315	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4316	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4317
 4318	tst.b		%d1
 4319	bne.b		_L21_2s
 4320	bsr.l		srem_snorm			# operand is a NORM
 4321	bra.b		_L21_6s
 4322_L21_2s:
 4323	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4324	bne.b		_L21_3s			# no
 4325	bsr.l		srem_szero			# yes
 4326	bra.b		_L21_6s
 4327_L21_3s:
 4328	cmpi.b		%d1,&INF		# is operand an INF?
 4329	bne.b		_L21_4s			# no
 4330	bsr.l		srem_sinf			# yes
 4331	bra.b		_L21_6s
 4332_L21_4s:
 4333	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4334	bne.b		_L21_5s			# no
 4335	bsr.l		sop_sqnan			# yes
 4336	bra.b		_L21_6s
 4337_L21_5s:
 4338	bsr.l		srem_sdnrm			# operand is a DENORM
 4339_L21_6s:
 4340
 4341#
 4342#	Result is now in FP0
 4343#
 4344	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4345	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4346	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4347	unlk		%a6
 4348	rts
 4349
 4350	global		_fremd_
 4351_fremd_:
 4352	link		%a6,&-LOCAL_SIZE
 4353
 4354	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4355	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4356	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4357
 4358	fmov.l		&0x0,%fpcr		# zero FPCR
 4359
 4360#
 4361#	copy, convert, and tag input argument
 4362#
 4363	fmov.d		0x8(%a6),%fp0		# load dbl dst
 4364	fmov.x		%fp0,FP_DST(%a6)
 4365	lea		FP_DST(%a6),%a0
 4366	bsr.l		tag			# fetch operand type
 4367	mov.b		%d0,DTAG(%a6)
 4368
 4369	fmov.d		0x10(%a6),%fp0		# load dbl src
 4370	fmov.x		%fp0,FP_SRC(%a6)
 4371	lea		FP_SRC(%a6),%a0
 4372	bsr.l		tag			# fetch operand type
 4373	mov.b		%d0,STAG(%a6)
 4374	mov.l		%d0,%d1
 4375
 4376	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4377
 4378	clr.l		%d0
 4379	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4380
 4381	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4382	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4383
 4384	tst.b		%d1
 4385	bne.b		_L21_2d
 4386	bsr.l		srem_snorm			# operand is a NORM
 4387	bra.b		_L21_6d
 4388_L21_2d:
 4389	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4390	bne.b		_L21_3d			# no
 4391	bsr.l		srem_szero			# yes
 4392	bra.b		_L21_6d
 4393_L21_3d:
 4394	cmpi.b		%d1,&INF		# is operand an INF?
 4395	bne.b		_L21_4d			# no
 4396	bsr.l		srem_sinf			# yes
 4397	bra.b		_L21_6d
 4398_L21_4d:
 4399	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4400	bne.b		_L21_5d			# no
 4401	bsr.l		sop_sqnan			# yes
 4402	bra.b		_L21_6d
 4403_L21_5d:
 4404	bsr.l		srem_sdnrm			# operand is a DENORM
 4405_L21_6d:
 4406
 4407#
 4408#	Result is now in FP0
 4409#
 4410	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4411	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4412	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4413	unlk		%a6
 4414	rts
 4415
 4416	global		_fremx_
 4417_fremx_:
 4418	link		%a6,&-LOCAL_SIZE
 4419
 4420	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4421	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4422	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4423
 4424	fmov.l		&0x0,%fpcr		# zero FPCR
 4425
 4426#
 4427#	copy, convert, and tag input argument
 4428#
 4429	lea		FP_DST(%a6),%a0
 4430	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
 4431	mov.l		0x8+0x4(%a6),0x4(%a0)
 4432	mov.l		0x8+0x8(%a6),0x8(%a0)
 4433	bsr.l		tag			# fetch operand type
 4434	mov.b		%d0,DTAG(%a6)
 4435
 4436	lea		FP_SRC(%a6),%a0
 4437	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
 4438	mov.l		0x14+0x4(%a6),0x4(%a0)
 4439	mov.l		0x14+0x8(%a6),0x8(%a0)
 4440	bsr.l		tag			# fetch operand type
 4441	mov.b		%d0,STAG(%a6)
 4442	mov.l		%d0,%d1
 4443
 4444	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4445
 4446	clr.l		%d0
 4447	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4448
 4449	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4450	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4451
 4452	tst.b		%d1
 4453	bne.b		_L21_2x
 4454	bsr.l		srem_snorm			# operand is a NORM
 4455	bra.b		_L21_6x
 4456_L21_2x:
 4457	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4458	bne.b		_L21_3x			# no
 4459	bsr.l		srem_szero			# yes
 4460	bra.b		_L21_6x
 4461_L21_3x:
 4462	cmpi.b		%d1,&INF		# is operand an INF?
 4463	bne.b		_L21_4x			# no
 4464	bsr.l		srem_sinf			# yes
 4465	bra.b		_L21_6x
 4466_L21_4x:
 4467	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4468	bne.b		_L21_5x			# no
 4469	bsr.l		sop_sqnan			# yes
 4470	bra.b		_L21_6x
 4471_L21_5x:
 4472	bsr.l		srem_sdnrm			# operand is a DENORM
 4473_L21_6x:
 4474
 4475#
 4476#	Result is now in FP0
 4477#
 4478	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4479	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4480	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4481	unlk		%a6
 4482	rts
 4483
 4484
 4485#########################################################################
 4486# DYADIC TEMPLATE							#
 4487#########################################################################
 4488	global		_fmods_
 4489_fmods_:
 4490	link		%a6,&-LOCAL_SIZE
 4491
 4492	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4493	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4494	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4495
 4496	fmov.l		&0x0,%fpcr		# zero FPCR
 4497
 4498#
 4499#	copy, convert, and tag input argument
 4500#
 4501	fmov.s		0x8(%a6),%fp0		# load sgl dst
 4502	fmov.x		%fp0,FP_DST(%a6)
 4503	lea		FP_DST(%a6),%a0
 4504	bsr.l		tag			# fetch operand type
 4505	mov.b		%d0,DTAG(%a6)
 4506
 4507	fmov.s		0xc(%a6),%fp0		# load sgl src
 4508	fmov.x		%fp0,FP_SRC(%a6)
 4509	lea		FP_SRC(%a6),%a0
 4510	bsr.l		tag			# fetch operand type
 4511	mov.b		%d0,STAG(%a6)
 4512	mov.l		%d0,%d1
 4513
 4514	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4515
 4516	clr.l		%d0
 4517	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4518
 4519	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4520	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4521
 4522	tst.b		%d1
 4523	bne.b		_L22_2s
 4524	bsr.l		smod_snorm			# operand is a NORM
 4525	bra.b		_L22_6s
 4526_L22_2s:
 4527	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4528	bne.b		_L22_3s			# no
 4529	bsr.l		smod_szero			# yes
 4530	bra.b		_L22_6s
 4531_L22_3s:
 4532	cmpi.b		%d1,&INF		# is operand an INF?
 4533	bne.b		_L22_4s			# no
 4534	bsr.l		smod_sinf			# yes
 4535	bra.b		_L22_6s
 4536_L22_4s:
 4537	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4538	bne.b		_L22_5s			# no
 4539	bsr.l		sop_sqnan			# yes
 4540	bra.b		_L22_6s
 4541_L22_5s:
 4542	bsr.l		smod_sdnrm			# operand is a DENORM
 4543_L22_6s:
 4544
 4545#
 4546#	Result is now in FP0
 4547#
 4548	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4549	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4550	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4551	unlk		%a6
 4552	rts
 4553
 4554	global		_fmodd_
 4555_fmodd_:
 4556	link		%a6,&-LOCAL_SIZE
 4557
 4558	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4559	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4560	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4561
 4562	fmov.l		&0x0,%fpcr		# zero FPCR
 4563
 4564#
 4565#	copy, convert, and tag input argument
 4566#
 4567	fmov.d		0x8(%a6),%fp0		# load dbl dst
 4568	fmov.x		%fp0,FP_DST(%a6)
 4569	lea		FP_DST(%a6),%a0
 4570	bsr.l		tag			# fetch operand type
 4571	mov.b		%d0,DTAG(%a6)
 4572
 4573	fmov.d		0x10(%a6),%fp0		# load dbl src
 4574	fmov.x		%fp0,FP_SRC(%a6)
 4575	lea		FP_SRC(%a6),%a0
 4576	bsr.l		tag			# fetch operand type
 4577	mov.b		%d0,STAG(%a6)
 4578	mov.l		%d0,%d1
 4579
 4580	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4581
 4582	clr.l		%d0
 4583	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4584
 4585	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4586	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4587
 4588	tst.b		%d1
 4589	bne.b		_L22_2d
 4590	bsr.l		smod_snorm			# operand is a NORM
 4591	bra.b		_L22_6d
 4592_L22_2d:
 4593	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4594	bne.b		_L22_3d			# no
 4595	bsr.l		smod_szero			# yes
 4596	bra.b		_L22_6d
 4597_L22_3d:
 4598	cmpi.b		%d1,&INF		# is operand an INF?
 4599	bne.b		_L22_4d			# no
 4600	bsr.l		smod_sinf			# yes
 4601	bra.b		_L22_6d
 4602_L22_4d:
 4603	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4604	bne.b		_L22_5d			# no
 4605	bsr.l		sop_sqnan			# yes
 4606	bra.b		_L22_6d
 4607_L22_5d:
 4608	bsr.l		smod_sdnrm			# operand is a DENORM
 4609_L22_6d:
 4610
 4611#
 4612#	Result is now in FP0
 4613#
 4614	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4615	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4616	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4617	unlk		%a6
 4618	rts
 4619
 4620	global		_fmodx_
 4621_fmodx_:
 4622	link		%a6,&-LOCAL_SIZE
 4623
 4624	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4625	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4626	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4627
 4628	fmov.l		&0x0,%fpcr		# zero FPCR
 4629
 4630#
 4631#	copy, convert, and tag input argument
 4632#
 4633	lea		FP_DST(%a6),%a0
 4634	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
 4635	mov.l		0x8+0x4(%a6),0x4(%a0)
 4636	mov.l		0x8+0x8(%a6),0x8(%a0)
 4637	bsr.l		tag			# fetch operand type
 4638	mov.b		%d0,DTAG(%a6)
 4639
 4640	lea		FP_SRC(%a6),%a0
 4641	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
 4642	mov.l		0x14+0x4(%a6),0x4(%a0)
 4643	mov.l		0x14+0x8(%a6),0x8(%a0)
 4644	bsr.l		tag			# fetch operand type
 4645	mov.b		%d0,STAG(%a6)
 4646	mov.l		%d0,%d1
 4647
 4648	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4649
 4650	clr.l		%d0
 4651	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4652
 4653	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4654	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4655
 4656	tst.b		%d1
 4657	bne.b		_L22_2x
 4658	bsr.l		smod_snorm			# operand is a NORM
 4659	bra.b		_L22_6x
 4660_L22_2x:
 4661	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4662	bne.b		_L22_3x			# no
 4663	bsr.l		smod_szero			# yes
 4664	bra.b		_L22_6x
 4665_L22_3x:
 4666	cmpi.b		%d1,&INF		# is operand an INF?
 4667	bne.b		_L22_4x			# no
 4668	bsr.l		smod_sinf			# yes
 4669	bra.b		_L22_6x
 4670_L22_4x:
 4671	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4672	bne.b		_L22_5x			# no
 4673	bsr.l		sop_sqnan			# yes
 4674	bra.b		_L22_6x
 4675_L22_5x:
 4676	bsr.l		smod_sdnrm			# operand is a DENORM
 4677_L22_6x:
 4678
 4679#
 4680#	Result is now in FP0
 4681#
 4682	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4683	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4684	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4685	unlk		%a6
 4686	rts
 4687
 4688
 4689#########################################################################
 4690# DYADIC TEMPLATE							#
 4691#########################################################################
 4692	global		_fscales_
 4693_fscales_:
 4694	link		%a6,&-LOCAL_SIZE
 4695
 4696	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4697	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4698	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4699
 4700	fmov.l		&0x0,%fpcr		# zero FPCR
 4701
 4702#
 4703#	copy, convert, and tag input argument
 4704#
 4705	fmov.s		0x8(%a6),%fp0		# load sgl dst
 4706	fmov.x		%fp0,FP_DST(%a6)
 4707	lea		FP_DST(%a6),%a0
 4708	bsr.l		tag			# fetch operand type
 4709	mov.b		%d0,DTAG(%a6)
 4710
 4711	fmov.s		0xc(%a6),%fp0		# load sgl src
 4712	fmov.x		%fp0,FP_SRC(%a6)
 4713	lea		FP_SRC(%a6),%a0
 4714	bsr.l		tag			# fetch operand type
 4715	mov.b		%d0,STAG(%a6)
 4716	mov.l		%d0,%d1
 4717
 4718	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4719
 4720	clr.l		%d0
 4721	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4722
 4723	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4724	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4725
 4726	tst.b		%d1
 4727	bne.b		_L23_2s
 4728	bsr.l		sscale_snorm			# operand is a NORM
 4729	bra.b		_L23_6s
 4730_L23_2s:
 4731	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4732	bne.b		_L23_3s			# no
 4733	bsr.l		sscale_szero			# yes
 4734	bra.b		_L23_6s
 4735_L23_3s:
 4736	cmpi.b		%d1,&INF		# is operand an INF?
 4737	bne.b		_L23_4s			# no
 4738	bsr.l		sscale_sinf			# yes
 4739	bra.b		_L23_6s
 4740_L23_4s:
 4741	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4742	bne.b		_L23_5s			# no
 4743	bsr.l		sop_sqnan			# yes
 4744	bra.b		_L23_6s
 4745_L23_5s:
 4746	bsr.l		sscale_sdnrm			# operand is a DENORM
 4747_L23_6s:
 4748
 4749#
 4750#	Result is now in FP0
 4751#
 4752	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4753	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4754	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4755	unlk		%a6
 4756	rts
 4757
 4758	global		_fscaled_
 4759_fscaled_:
 4760	link		%a6,&-LOCAL_SIZE
 4761
 4762	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4763	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4764	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4765
 4766	fmov.l		&0x0,%fpcr		# zero FPCR
 4767
 4768#
 4769#	copy, convert, and tag input argument
 4770#
 4771	fmov.d		0x8(%a6),%fp0		# load dbl dst
 4772	fmov.x		%fp0,FP_DST(%a6)
 4773	lea		FP_DST(%a6),%a0
 4774	bsr.l		tag			# fetch operand type
 4775	mov.b		%d0,DTAG(%a6)
 4776
 4777	fmov.d		0x10(%a6),%fp0		# load dbl src
 4778	fmov.x		%fp0,FP_SRC(%a6)
 4779	lea		FP_SRC(%a6),%a0
 4780	bsr.l		tag			# fetch operand type
 4781	mov.b		%d0,STAG(%a6)
 4782	mov.l		%d0,%d1
 4783
 4784	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4785
 4786	clr.l		%d0
 4787	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4788
 4789	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4790	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4791
 4792	tst.b		%d1
 4793	bne.b		_L23_2d
 4794	bsr.l		sscale_snorm			# operand is a NORM
 4795	bra.b		_L23_6d
 4796_L23_2d:
 4797	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4798	bne.b		_L23_3d			# no
 4799	bsr.l		sscale_szero			# yes
 4800	bra.b		_L23_6d
 4801_L23_3d:
 4802	cmpi.b		%d1,&INF		# is operand an INF?
 4803	bne.b		_L23_4d			# no
 4804	bsr.l		sscale_sinf			# yes
 4805	bra.b		_L23_6d
 4806_L23_4d:
 4807	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4808	bne.b		_L23_5d			# no
 4809	bsr.l		sop_sqnan			# yes
 4810	bra.b		_L23_6d
 4811_L23_5d:
 4812	bsr.l		sscale_sdnrm			# operand is a DENORM
 4813_L23_6d:
 4814
 4815#
 4816#	Result is now in FP0
 4817#
 4818	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4819	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4820	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4821	unlk		%a6
 4822	rts
 4823
 4824	global		_fscalex_
 4825_fscalex_:
 4826	link		%a6,&-LOCAL_SIZE
 4827
 4828	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
 4829	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
 4830	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
 4831
 4832	fmov.l		&0x0,%fpcr		# zero FPCR
 4833
 4834#
 4835#	copy, convert, and tag input argument
 4836#
 4837	lea		FP_DST(%a6),%a0
 4838	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
 4839	mov.l		0x8+0x4(%a6),0x4(%a0)
 4840	mov.l		0x8+0x8(%a6),0x8(%a0)
 4841	bsr.l		tag			# fetch operand type
 4842	mov.b		%d0,DTAG(%a6)
 4843
 4844	lea		FP_SRC(%a6),%a0
 4845	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
 4846	mov.l		0x14+0x4(%a6),0x4(%a0)
 4847	mov.l		0x14+0x8(%a6),0x8(%a0)
 4848	bsr.l		tag			# fetch operand type
 4849	mov.b		%d0,STAG(%a6)
 4850	mov.l		%d0,%d1
 4851
 4852	andi.l		&0x00ff00ff,USER_FPSR(%a6)
 4853
 4854	clr.l		%d0
 4855	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
 4856
 4857	lea		FP_SRC(%a6),%a0		# pass ptr to src
 4858	lea		FP_DST(%a6),%a1		# pass ptr to dst
 4859
 4860	tst.b		%d1
 4861	bne.b		_L23_2x
 4862	bsr.l		sscale_snorm			# operand is a NORM
 4863	bra.b		_L23_6x
 4864_L23_2x:
 4865	cmpi.b		%d1,&ZERO		# is operand a ZERO?
 4866	bne.b		_L23_3x			# no
 4867	bsr.l		sscale_szero			# yes
 4868	bra.b		_L23_6x
 4869_L23_3x:
 4870	cmpi.b		%d1,&INF		# is operand an INF?
 4871	bne.b		_L23_4x			# no
 4872	bsr.l		sscale_sinf			# yes
 4873	bra.b		_L23_6x
 4874_L23_4x:
 4875	cmpi.b		%d1,&QNAN		# is operand a QNAN?
 4876	bne.b		_L23_5x			# no
 4877	bsr.l		sop_sqnan			# yes
 4878	bra.b		_L23_6x
 4879_L23_5x:
 4880	bsr.l		sscale_sdnrm			# operand is a DENORM
 4881_L23_6x:
 4882
 4883#
 4884#	Result is now in FP0
 4885#
 4886	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
 4887	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
 4888	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
 4889	unlk		%a6
 4890	rts
 4891
 4892
 4893#########################################################################
 4894# ssin():     computes the sine of a normalized input			#
 4895# ssind():    computes the sine of a denormalized input			#
 4896# scos():     computes the cosine of a normalized input			#
 4897# scosd():    computes the cosine of a denormalized input		#
 4898# ssincos():  computes the sine and cosine of a normalized input	#
 4899# ssincosd(): computes the sine and cosine of a denormalized input	#
 4900#									#
 4901# INPUT *************************************************************** #
 4902#	a0 = pointer to extended precision input			#
 4903#	d0 = round precision,mode					#
 4904#									#
 4905# OUTPUT ************************************************************** #
 4906#	fp0 = sin(X) or cos(X)						#
 4907#									#
 4908#    For ssincos(X):							#
 4909#	fp0 = sin(X)							#
 4910#	fp1 = cos(X)							#
 4911#									#
 4912# ACCURACY and MONOTONICITY ******************************************* #
 4913#	The returned result is within 1 ulp in 64 significant bit, i.e.	#
 4914#	within 0.5001 ulp to 53 bits if the result is subsequently	#
 4915#	rounded to double precision. The result is provably monotonic	#
 4916#	in double precision.						#
 4917#									#
 4918# ALGORITHM ***********************************************************	#
 4919#									#
 4920#	SIN and COS:							#
 4921#	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
 4922#									#
 4923#	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
 4924#									#
 4925#	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
 4926#		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
 4927#		Overwrite k by k := k + AdjN.				#
 4928#									#
 4929#	4. If k is even, go to 6.					#
 4930#									#
 4931#	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j.			#
 4932#		Return sgn*cos(r) where cos(r) is approximated by an	#
 4933#		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
 4934#		s = r*r.						#
 4935#		Exit.							#
 4936#									#
 4937#	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
 4938#		where sin(r) is approximated by an odd polynomial in r	#
 4939#		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
 4940#		Exit.							#
 4941#									#
 4942#	7. If |X| > 1, go to 9.						#
 4943#									#
 4944#	8. (|X|<2**(-40)) If SIN is invoked, return X;			#
 4945#		otherwise return 1.					#
 4946#									#
 4947#	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
 4948#		go back to 3.						#
 4949#									#
 4950#	SINCOS:								#
 4951#	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
 4952#									#
 4953#	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
 4954#		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
 4955#									#
 4956#	3. If k is even, go to 5.					#
 4957#									#
 4958#	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
 4959#		j1 exclusive or with the l.s.b. of k.			#
 4960#		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
 4961#		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
 4962#		sin(r) and cos(r) are computed as odd and even		#
 4963#		polynomials in r, respectively. Exit			#
 4964#									#
 4965#	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
 4966#		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
 4967#		sin(r) and cos(r) are computed as odd and even		#
 4968#		polynomials in r, respectively. Exit			#
 4969#									#
 4970#	6. If |X| > 1, go to 8.						#
 4971#									#
 4972#	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
 4973#									#
 4974#	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi,		#
 4975#		go back to 2.						#
 4976#									#
 4977#########################################################################
 4978
 4979SINA7:	long		0xBD6AAA77,0xCCC994F5
 4980SINA6:	long		0x3DE61209,0x7AAE8DA1
 4981SINA5:	long		0xBE5AE645,0x2A118AE4
 4982SINA4:	long		0x3EC71DE3,0xA5341531
 4983SINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
 4984SINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
 4985SINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
 4986
 4987COSB8:	long		0x3D2AC4D0,0xD6011EE3
 4988COSB7:	long		0xBDA9396F,0x9F45AC19
 4989COSB6:	long		0x3E21EED9,0x0612C972
 4990COSB5:	long		0xBE927E4F,0xB79D9FCF
 4991COSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
 4992COSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
 4993COSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
 4994COSB1:	long		0xBF000000
 4995
 4996	set		INARG,FP_SCR0
 4997
 4998	set		X,FP_SCR0
 4999#	set		XDCARE,X+2
 5000	set		XFRAC,X+4
 5001
 5002	set		RPRIME,FP_SCR0
 5003	set		SPRIME,FP_SCR1
 5004
 5005	set		POSNEG1,L_SCR1
 5006	set		TWOTO63,L_SCR1
 5007
 5008	set		ENDFLAG,L_SCR2
 5009	set		INT,L_SCR2
 5010
 5011	set		ADJN,L_SCR3
 5012
 5013############################################
 5014	global		ssin
 5015ssin:
 5016	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
 5017	bra.b		SINBGN
 5018
 5019############################################
 5020	global		scos
 5021scos:
 5022	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
 5023
 5024############################################
 5025SINBGN:
 5026#--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
 5027
 5028	fmov.x		(%a0),%fp0		# LOAD INPUT
 5029	fmov.x		%fp0,X(%a6)		# save input at X
 5030
 5031# "COMPACTIFY" X
 5032	mov.l		(%a0),%d1		# put exp in hi word
 5033	mov.w		4(%a0),%d1		# fetch hi(man)
 5034	and.l		&0x7FFFFFFF,%d1		# strip sign
 5035
 5036	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
 5037	bge.b		SOK1			# no
 5038	bra.w		SINSM			# yes; input is very small
 5039
 5040SOK1:
 5041	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
 5042	blt.b		SINMAIN			# no
 5043	bra.w		SREDUCEX		# yes; input is very large
 5044
 5045#--THIS IS THE USUAL CASE, |X| <= 15 PI.
 5046#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
 5047SINMAIN:
 5048	fmov.x		%fp0,%fp1
 5049	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
 5050
 5051	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
 5052
 5053	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
 5054
 5055	mov.l		INT(%a6),%d1		# make a copy of N
 5056	asl.l		&4,%d1			# N *= 16
 5057	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
 5058
 5059# A1 IS THE ADDRESS OF N*PIBY2
 5060# ...WHICH IS IN TWO PIECES Y1 & Y2
 5061	fsub.x		(%a1)+,%fp0		# X-Y1
 5062	fsub.s		(%a1),%fp0		# fp0 = R = (X-Y1)-Y2
 5063
 5064SINCONT:
 5065#--continuation from REDUCEX
 5066
 5067#--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
 5068	mov.l		INT(%a6),%d1
 5069	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
 5070	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
 5071	cmp.l		%d1,&0
 5072	blt.w		COSPOLY
 5073
 5074#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
 5075#--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
 5076#--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
 5077#--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
 5078#--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
 5079#--WHERE T=S*S.
 5080#--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
 5081#--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
 5082SINPOLY:
 5083	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
 5084
 5085	fmov.x		%fp0,X(%a6)		# X IS R
 5086	fmul.x		%fp0,%fp0		# FP0 IS S
 5087
 5088	fmov.d		SINA7(%pc),%fp3
 5089	fmov.d		SINA6(%pc),%fp2
 5090
 5091	fmov.x		%fp0,%fp1
 5092	fmul.x		%fp1,%fp1		# FP1 IS T
 5093
 5094	ror.l		&1,%d1
 5095	and.l		&0x80000000,%d1
 5096# ...LEAST SIG. BIT OF D0 IN SIGN POSITION
 5097	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
 5098
 5099	fmul.x		%fp1,%fp3		# TA7
 5100	fmul.x		%fp1,%fp2		# TA6
 5101
 5102	fadd.d		SINA5(%pc),%fp3		# A5+TA7
 5103	fadd.d		SINA4(%pc),%fp2		# A4+TA6
 5104
 5105	fmul.x		%fp1,%fp3		# T(A5+TA7)
 5106	fmul.x		%fp1,%fp2		# T(A4+TA6)
 5107
 5108	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
 5109	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
 5110
 5111	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
 5112
 5113	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
 5114	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
 5115	fmul.x		X(%a6),%fp0		# R'*S
 5116
 5117	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
 5118
 5119	fmul.x		%fp1,%fp0		# SIN(R')-R'
 5120
 5121	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
 5122
 5123	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5124	fadd.x		X(%a6),%fp0		# last inst - possible exception set
 5125	bra		t_inx2
 5126
 5127#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
 5128#--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
 5129#--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
 5130#--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
 5131#--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
 5132#--WHERE T=S*S.
 5133#--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
 5134#--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
 5135#--AND IS THEREFORE STORED AS SINGLE PRECISION.
 5136COSPOLY:
 5137	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
 5138
 5139	fmul.x		%fp0,%fp0		# FP0 IS S
 5140
 5141	fmov.d		COSB8(%pc),%fp2
 5142	fmov.d		COSB7(%pc),%fp3
 5143
 5144	fmov.x		%fp0,%fp1
 5145	fmul.x		%fp1,%fp1		# FP1 IS T
 5146
 5147	fmov.x		%fp0,X(%a6)		# X IS S
 5148	ror.l		&1,%d1
 5149	and.l		&0x80000000,%d1
 5150# ...LEAST SIG. BIT OF D0 IN SIGN POSITION
 5151
 5152	fmul.x		%fp1,%fp2		# TB8
 5153
 5154	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
 5155	and.l		&0x80000000,%d1
 5156
 5157	fmul.x		%fp1,%fp3		# TB7
 5158
 5159	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
 5160	mov.l		%d1,POSNEG1(%a6)
 5161
 5162	fadd.d		COSB6(%pc),%fp2		# B6+TB8
 5163	fadd.d		COSB5(%pc),%fp3		# B5+TB7
 5164
 5165	fmul.x		%fp1,%fp2		# T(B6+TB8)
 5166	fmul.x		%fp1,%fp3		# T(B5+TB7)
 5167
 5168	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
 5169	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
 5170
 5171	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
 5172	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
 5173
 5174	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
 5175	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
 5176
 5177	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
 5178
 5179	fadd.x		%fp1,%fp0
 5180
 5181	fmul.x		X(%a6),%fp0
 5182
 5183	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
 5184
 5185	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5186	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
 5187	bra		t_inx2
 5188
 5189##############################################
 5190
 5191# SINe: Big OR Small?
 5192#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
 5193#--IF |X| < 2**(-40), RETURN X OR 1.
 5194SINBORS:
 5195	cmp.l		%d1,&0x3FFF8000
 5196	bgt.l		SREDUCEX
 5197
 5198SINSM:
 5199	mov.l		ADJN(%a6),%d1
 5200	cmp.l		%d1,&0
 5201	bgt.b		COSTINY
 5202
 5203# here, the operation may underflow iff the precision is sgl or dbl.
 5204# extended denorms are handled through another entry point.
 5205SINTINY:
 5206#	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
 5207
 5208	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5209	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 5210	fmov.x		X(%a6),%fp0		# last inst - possible exception set
 5211	bra		t_catch
 5212
 5213COSTINY:
 5214	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
 5215	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5216	fadd.s		&0x80800000,%fp0	# last inst - possible exception set
 5217	bra		t_pinx2
 5218
 5219################################################
 5220	global		ssind
 5221#--SIN(X) = X FOR DENORMALIZED X
 5222ssind:
 5223	bra		t_extdnrm
 5224
 5225############################################
 5226	global		scosd
 5227#--COS(X) = 1 FOR DENORMALIZED X
 5228scosd:
 5229	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
 5230	bra		t_pinx2
 5231
 5232##################################################
 5233
 5234	global		ssincos
 5235ssincos:
 5236#--SET ADJN TO 4
 5237	mov.l		&4,ADJN(%a6)
 5238
 5239	fmov.x		(%a0),%fp0		# LOAD INPUT
 5240	fmov.x		%fp0,X(%a6)
 5241
 5242	mov.l		(%a0),%d1
 5243	mov.w		4(%a0),%d1
 5244	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
 5245
 5246	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
 5247	bge.b		SCOK1
 5248	bra.w		SCSM
 5249
 5250SCOK1:
 5251	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
 5252	blt.b		SCMAIN
 5253	bra.w		SREDUCEX
 5254
 5255
 5256#--THIS IS THE USUAL CASE, |X| <= 15 PI.
 5257#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
 5258SCMAIN:
 5259	fmov.x		%fp0,%fp1
 5260
 5261	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
 5262
 5263	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
 5264
 5265	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
 5266
 5267	mov.l		INT(%a6),%d1
 5268	asl.l		&4,%d1
 5269	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
 5270
 5271	fsub.x		(%a1)+,%fp0		# X-Y1
 5272	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
 5273
 5274SCCONT:
 5275#--continuation point from REDUCEX
 5276
 5277	mov.l		INT(%a6),%d1
 5278	ror.l		&1,%d1
 5279	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
 5280	bge.w		NEVEN
 5281
 5282SNODD:
 5283#--REGISTERS SAVED SO FAR: D0, A0, FP2.
 5284	fmovm.x		&0x04,-(%sp)		# save fp2
 5285
 5286	fmov.x		%fp0,RPRIME(%a6)
 5287	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
 5288	fmov.d		SINA7(%pc),%fp1		# A7
 5289	fmov.d		COSB8(%pc),%fp2		# B8
 5290	fmul.x		%fp0,%fp1		# SA7
 5291	fmul.x		%fp0,%fp2		# SB8
 5292
 5293	mov.l		%d2,-(%sp)
 5294	mov.l		%d1,%d2
 5295	ror.l		&1,%d2
 5296	and.l		&0x80000000,%d2
 5297	eor.l		%d1,%d2
 5298	and.l		&0x80000000,%d2
 5299
 5300	fadd.d		SINA6(%pc),%fp1		# A6+SA7
 5301	fadd.d		COSB7(%pc),%fp2		# B7+SB8
 5302
 5303	fmul.x		%fp0,%fp1		# S(A6+SA7)
 5304	eor.l		%d2,RPRIME(%a6)
 5305	mov.l		(%sp)+,%d2
 5306	fmul.x		%fp0,%fp2		# S(B7+SB8)
 5307	ror.l		&1,%d1
 5308	and.l		&0x80000000,%d1
 5309	mov.l		&0x3F800000,POSNEG1(%a6)
 5310	eor.l		%d1,POSNEG1(%a6)
 5311
 5312	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
 5313	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
 5314
 5315	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
 5316	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
 5317	fmov.x		%fp0,SPRIME(%a6)
 5318
 5319	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
 5320	eor.l		%d1,SPRIME(%a6)
 5321	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
 5322
 5323	fmul.x		%fp0,%fp1		# S(A4+...)
 5324	fmul.x		%fp0,%fp2		# S(B5+...)
 5325
 5326	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
 5327	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
 5328
 5329	fmul.x		%fp0,%fp1		# S(A3+...)
 5330	fmul.x		%fp0,%fp2		# S(B4+...)
 5331
 5332	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
 5333	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
 5334
 5335	fmul.x		%fp0,%fp1		# S(A2+...)
 5336	fmul.x		%fp0,%fp2		# S(B3+...)
 5337
 5338	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
 5339	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
 5340
 5341	fmul.x		%fp0,%fp1		# S(A1+...)
 5342	fmul.x		%fp2,%fp0		# S(B2+...)
 5343
 5344	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
 5345	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
 5346	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
 5347
 5348	fmovm.x		(%sp)+,&0x20		# restore fp2
 5349
 5350	fmov.l		%d0,%fpcr
 5351	fadd.x		RPRIME(%a6),%fp1	# COS(X)
 5352	bsr		sto_cos			# store cosine result
 5353	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
 5354	bra		t_inx2
 5355
 5356NEVEN:
 5357#--REGISTERS SAVED SO FAR: FP2.
 5358	fmovm.x		&0x04,-(%sp)		# save fp2
 5359
 5360	fmov.x		%fp0,RPRIME(%a6)
 5361	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
 5362
 5363	fmov.d		COSB8(%pc),%fp1		# B8
 5364	fmov.d		SINA7(%pc),%fp2		# A7
 5365
 5366	fmul.x		%fp0,%fp1		# SB8
 5367	fmov.x		%fp0,SPRIME(%a6)
 5368	fmul.x		%fp0,%fp2		# SA7
 5369
 5370	ror.l		&1,%d1
 5371	and.l		&0x80000000,%d1
 5372
 5373	fadd.d		COSB7(%pc),%fp1		# B7+SB8
 5374	fadd.d		SINA6(%pc),%fp2		# A6+SA7
 5375
 5376	eor.l		%d1,RPRIME(%a6)
 5377	eor.l		%d1,SPRIME(%a6)
 5378
 5379	fmul.x		%fp0,%fp1		# S(B7+SB8)
 5380
 5381	or.l		&0x3F800000,%d1
 5382	mov.l		%d1,POSNEG1(%a6)
 5383
 5384	fmul.x		%fp0,%fp2		# S(A6+SA7)
 5385
 5386	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
 5387	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
 5388
 5389	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
 5390	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
 5391
 5392	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
 5393	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
 5394
 5395	fmul.x		%fp0,%fp1		# S(B5+...)
 5396	fmul.x		%fp0,%fp2		# S(A4+...)
 5397
 5398	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
 5399	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
 5400
 5401	fmul.x		%fp0,%fp1		# S(B4+...)
 5402	fmul.x		%fp0,%fp2		# S(A3+...)
 5403
 5404	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
 5405	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
 5406
 5407	fmul.x		%fp0,%fp1		# S(B3+...)
 5408	fmul.x		%fp0,%fp2		# S(A2+...)
 5409
 5410	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
 5411	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
 5412
 5413	fmul.x		%fp0,%fp1		# S(B2+...)
 5414	fmul.x		%fp2,%fp0		# s(a1+...)
 5415
 5416
 5417	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
 5418	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
 5419	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
 5420
 5421	fmovm.x		(%sp)+,&0x20		# restore fp2
 5422
 5423	fmov.l		%d0,%fpcr
 5424	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
 5425	bsr		sto_cos			# store cosine result
 5426	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
 5427	bra		t_inx2
 5428
 5429################################################
 5430
 5431SCBORS:
 5432	cmp.l		%d1,&0x3FFF8000
 5433	bgt.w		SREDUCEX
 5434
 5435################################################
 5436
 5437SCSM:
 5438#	mov.w		&0x0000,XDCARE(%a6)
 5439	fmov.s		&0x3F800000,%fp1
 5440
 5441	fmov.l		%d0,%fpcr
 5442	fsub.s		&0x00800000,%fp1
 5443	bsr		sto_cos			# store cosine result
 5444	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
 5445	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 5446	fmov.x		X(%a6),%fp0
 5447	bra		t_catch
 5448
 5449##############################################
 5450
 5451	global		ssincosd
 5452#--SIN AND COS OF X FOR DENORMALIZED X
 5453ssincosd:
 5454	mov.l		%d0,-(%sp)		# save d0
 5455	fmov.s		&0x3F800000,%fp1
 5456	bsr		sto_cos			# store cosine result
 5457	mov.l		(%sp)+,%d0		# restore d0
 5458	bra		t_extdnrm
 5459
 5460############################################
 5461
 5462#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
 5463#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
 5464#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
 5465SREDUCEX:
 5466	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
 5467	mov.l		%d2,-(%sp)		# save d2
 5468	fmov.s		&0x00000000,%fp1	# fp1 = 0
 5469
 5470#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
 5471#--there is a danger of unwanted overflow in first LOOP iteration.  In this
 5472#--case, reduce argument by one remainder step to make subsequent reduction
 5473#--safe.
 5474	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
 5475	bne.b		SLOOP			# no
 5476
 5477# yes; create 2**16383*PI/2
 5478	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
 5479	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
 5480	clr.l		FP_SCR0_LO(%a6)
 5481
 5482# create low half of 2**16383*PI/2 at FP_SCR1
 5483	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
 5484	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
 5485	clr.l		FP_SCR1_LO(%a6)
 5486
 5487	ftest.x		%fp0			# test sign of argument
 5488	fblt.w		sred_neg
 5489
 5490	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
 5491	or.b		&0x80,FP_SCR1_EX(%a6)
 5492sred_neg:
 5493	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
 5494	fmov.x		%fp0,%fp1		# save high result in fp1
 5495	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
 5496	fsub.x		%fp0,%fp1		# determine low component of result
 5497	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
 5498
 5499#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
 5500#--integer quotient will be stored in N
 5501#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
 5502SLOOP:
 5503	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
 5504	mov.w		INARG(%a6),%d1
 5505	mov.l		%d1,%a1			# save a copy of D0
 5506	and.l		&0x00007FFF,%d1
 5507	sub.l		&0x00003FFF,%d1		# d0 = K
 5508	cmp.l		%d1,&28
 5509	ble.b		SLASTLOOP
 5510SCONTLOOP:
 5511	sub.l		&27,%d1			# d0 = L := K-27
 5512	mov.b		&0,ENDFLAG(%a6)
 5513	bra.b		SWORK
 5514SLASTLOOP:
 5515	clr.l		%d1			# d0 = L := 0
 5516	mov.b		&1,ENDFLAG(%a6)
 5517
 5518SWORK:
 5519#--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
 5520#--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
 5521
 5522#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
 5523#--2**L * (PIby2_1), 2**L * (PIby2_2)
 5524
 5525	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
 5526	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
 5527
 5528	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
 5529	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
 5530	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
 5531
 5532	fmov.x		%fp0,%fp2
 5533	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
 5534
 5535#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
 5536#--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
 5537#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
 5538#--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
 5539#--US THE DESIRED VALUE IN FLOATING POINT.
 5540	mov.l		%a1,%d2
 5541	swap		%d2
 5542	and.l		&0x80000000,%d2
 5543	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
 5544	mov.l		%d2,TWOTO63(%a6)
 5545	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
 5546	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
 5547#	fint.x		%fp2
 5548
 5549#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
 5550	mov.l		%d1,%d2			# d2 = L
 5551
 5552	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
 5553	mov.w		%d2,FP_SCR0_EX(%a6)
 5554	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
 5555	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
 5556
 5557	add.l		&0x00003FDD,%d1
 5558	mov.w		%d1,FP_SCR1_EX(%a6)
 5559	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
 5560	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
 5561
 5562	mov.b		ENDFLAG(%a6),%d1
 5563
 5564#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
 5565#--P2 = 2**(L) * Piby2_2
 5566	fmov.x		%fp2,%fp4		# fp4 = N
 5567	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
 5568	fmov.x		%fp2,%fp5		# fp5 = N
 5569	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
 5570	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
 5571
 5572#--we want P+p = W+w  but  |p| <= half ulp of P
 5573#--Then, we need to compute  A := R-P   and  a := r-p
 5574	fadd.x		%fp5,%fp3		# fp3 = P
 5575	fsub.x		%fp3,%fp4		# fp4 = W-P
 5576
 5577	fsub.x		%fp3,%fp0		# fp0 = A := R - P
 5578	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
 5579
 5580	fmov.x		%fp0,%fp3		# fp3 = A
 5581	fsub.x		%fp4,%fp1		# fp1 = a := r - p
 5582
 5583#--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
 5584#--|r| <= half ulp of R.
 5585	fadd.x		%fp1,%fp0		# fp0 = R := A+a
 5586#--No need to calculate r if this is the last loop
 5587	cmp.b		%d1,&0
 5588	bgt.w		SRESTORE
 5589
 5590#--Need to calculate r
 5591	fsub.x		%fp0,%fp3		# fp3 = A-R
 5592	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
 5593	bra.w		SLOOP
 5594
 5595SRESTORE:
 5596	fmov.l		%fp2,INT(%a6)
 5597	mov.l		(%sp)+,%d2		# restore d2
 5598	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
 5599
 5600	mov.l		ADJN(%a6),%d1
 5601	cmp.l		%d1,&4
 5602
 5603	blt.w		SINCONT
 5604	bra.w		SCCONT
 5605
 5606#########################################################################
 5607# stan():  computes the tangent of a normalized input			#
 5608# stand(): computes the tangent of a denormalized input			#
 5609#									#
 5610# INPUT *************************************************************** #
 5611#	a0 = pointer to extended precision input			#
 5612#	d0 = round precision,mode					#
 5613#									#
 5614# OUTPUT ************************************************************** #
 5615#	fp0 = tan(X)							#
 5616#									#
 5617# ACCURACY and MONOTONICITY ******************************************* #
 5618#	The returned result is within 3 ulp in 64 significant bit, i.e. #
 5619#	within 0.5001 ulp to 53 bits if the result is subsequently	#
 5620#	rounded to double precision. The result is provably monotonic	#
 5621#	in double precision.						#
 5622#									#
 5623# ALGORITHM *********************************************************** #
 5624#									#
 5625#	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
 5626#									#
 5627#	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
 5628#		k = N mod 2, so in particular, k = 0 or 1.		#
 5629#									#
 5630#	3. If k is odd, go to 5.					#
 5631#									#
 5632#	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
 5633#		rational function U/V where				#
 5634#		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
 5635#		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
 5636#		Exit.							#
 5637#									#
 5638#	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
 5639#		a rational function U/V where				#
 5640#		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
 5641#		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
 5642#		-Cot(r) = -V/U. Exit.					#
 5643#									#
 5644#	6. If |X| > 1, go to 8.						#
 5645#									#
 5646#	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
 5647#									#
 5648#	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back	#
 5649#		to 2.							#
 5650#									#
 5651#########################################################################
 5652
 5653TANQ4:
 5654	long		0x3EA0B759,0xF50F8688
 5655TANP3:
 5656	long		0xBEF2BAA5,0xA8924F04
 5657
 5658TANQ3:
 5659	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
 5660
 5661TANP2:
 5662	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
 5663
 5664TANQ2:
 5665	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
 5666
 5667TANP1:
 5668	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
 5669
 5670TANQ1:
 5671	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
 5672
 5673INVTWOPI:
 5674	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
 5675
 5676TWOPI1:
 5677	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
 5678TWOPI2:
 5679	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
 5680
 5681#--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
 5682#--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
 5683#--MOST 69 BITS LONG.
 5684#	global		PITBL
 5685PITBL:
 5686	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
 5687	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
 5688	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
 5689	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
 5690	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
 5691	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
 5692	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
 5693	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
 5694	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
 5695	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
 5696	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
 5697	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
 5698	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
 5699	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
 5700	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
 5701	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
 5702	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
 5703	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
 5704	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
 5705	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
 5706	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
 5707	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
 5708	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
 5709	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
 5710	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
 5711	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
 5712	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
 5713	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
 5714	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
 5715	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
 5716	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
 5717	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
 5718	long		0x00000000,0x00000000,0x00000000,0x00000000
 5719	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
 5720	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
 5721	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
 5722	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
 5723	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
 5724	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
 5725	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
 5726	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
 5727	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
 5728	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
 5729	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
 5730	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
 5731	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
 5732	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
 5733	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
 5734	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
 5735	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
 5736	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
 5737	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
 5738	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
 5739	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
 5740	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
 5741	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
 5742	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
 5743	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
 5744	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
 5745	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
 5746	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
 5747	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
 5748	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
 5749	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
 5750	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
 5751
 5752	set		INARG,FP_SCR0
 5753
 5754	set		TWOTO63,L_SCR1
 5755	set		INT,L_SCR1
 5756	set		ENDFLAG,L_SCR2
 5757
 5758	global		stan
 5759stan:
 5760	fmov.x		(%a0),%fp0		# LOAD INPUT
 5761
 5762	mov.l		(%a0),%d1
 5763	mov.w		4(%a0),%d1
 5764	and.l		&0x7FFFFFFF,%d1
 5765
 5766	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
 5767	bge.b		TANOK1
 5768	bra.w		TANSM
 5769TANOK1:
 5770	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
 5771	blt.b		TANMAIN
 5772	bra.w		REDUCEX
 5773
 5774TANMAIN:
 5775#--THIS IS THE USUAL CASE, |X| <= 15 PI.
 5776#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
 5777	fmov.x		%fp0,%fp1
 5778	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
 5779
 5780	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
 5781
 5782	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
 5783
 5784	asl.l		&4,%d1
 5785	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
 5786
 5787	fsub.x		(%a1)+,%fp0		# X-Y1
 5788
 5789	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
 5790
 5791	ror.l		&5,%d1
 5792	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
 5793
 5794TANCONT:
 5795	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
 5796
 5797	cmp.l		%d1,&0
 5798	blt.w		NODD
 5799
 5800	fmov.x		%fp0,%fp1
 5801	fmul.x		%fp1,%fp1		# S = R*R
 5802
 5803	fmov.d		TANQ4(%pc),%fp3
 5804	fmov.d		TANP3(%pc),%fp2
 5805
 5806	fmul.x		%fp1,%fp3		# SQ4
 5807	fmul.x		%fp1,%fp2		# SP3
 5808
 5809	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
 5810	fadd.x		TANP2(%pc),%fp2		# P2+SP3
 5811
 5812	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
 5813	fmul.x		%fp1,%fp2		# S(P2+SP3)
 5814
 5815	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
 5816	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
 5817
 5818	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
 5819	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
 5820
 5821	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
 5822	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
 5823
 5824	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
 5825
 5826	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
 5827
 5828	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
 5829
 5830	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
 5831
 5832	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5833	fdiv.x		%fp1,%fp0		# last inst - possible exception set
 5834	bra		t_inx2
 5835
 5836NODD:
 5837	fmov.x		%fp0,%fp1
 5838	fmul.x		%fp0,%fp0		# S = R*R
 5839
 5840	fmov.d		TANQ4(%pc),%fp3
 5841	fmov.d		TANP3(%pc),%fp2
 5842
 5843	fmul.x		%fp0,%fp3		# SQ4
 5844	fmul.x		%fp0,%fp2		# SP3
 5845
 5846	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
 5847	fadd.x		TANP2(%pc),%fp2		# P2+SP3
 5848
 5849	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
 5850	fmul.x		%fp0,%fp2		# S(P2+SP3)
 5851
 5852	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
 5853	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
 5854
 5855	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
 5856	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
 5857
 5858	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
 5859	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
 5860
 5861	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
 5862
 5863	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
 5864	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
 5865
 5866	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
 5867
 5868	fmov.x		%fp1,-(%sp)
 5869	eor.l		&0x80000000,(%sp)
 5870
 5871	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5872	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
 5873	bra		t_inx2
 5874
 5875TANBORS:
 5876#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
 5877#--IF |X| < 2**(-40), RETURN X OR 1.
 5878	cmp.l		%d1,&0x3FFF8000
 5879	bgt.b		REDUCEX
 5880
 5881TANSM:
 5882	fmov.x		%fp0,-(%sp)
 5883	fmov.l		%d0,%fpcr		# restore users round mode,prec
 5884	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 5885	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
 5886	bra		t_catch
 5887
 5888	global		stand
 5889#--TAN(X) = X FOR DENORMALIZED X
 5890stand:
 5891	bra		t_extdnrm
 5892
 5893#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
 5894#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
 5895#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
 5896REDUCEX:
 5897	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
 5898	mov.l		%d2,-(%sp)		# save d2
 5899	fmov.s		&0x00000000,%fp1	# fp1 = 0
 5900
 5901#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
 5902#--there is a danger of unwanted overflow in first LOOP iteration.  In this
 5903#--case, reduce argument by one remainder step to make subsequent reduction
 5904#--safe.
 5905	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
 5906	bne.b		LOOP			# no
 5907
 5908# yes; create 2**16383*PI/2
 5909	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
 5910	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
 5911	clr.l		FP_SCR0_LO(%a6)
 5912
 5913# create low half of 2**16383*PI/2 at FP_SCR1
 5914	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
 5915	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
 5916	clr.l		FP_SCR1_LO(%a6)
 5917
 5918	ftest.x		%fp0			# test sign of argument
 5919	fblt.w		red_neg
 5920
 5921	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
 5922	or.b		&0x80,FP_SCR1_EX(%a6)
 5923red_neg:
 5924	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
 5925	fmov.x		%fp0,%fp1		# save high result in fp1
 5926	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
 5927	fsub.x		%fp0,%fp1		# determine low component of result
 5928	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
 5929
 5930#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
 5931#--integer quotient will be stored in N
 5932#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
 5933LOOP:
 5934	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
 5935	mov.w		INARG(%a6),%d1
 5936	mov.l		%d1,%a1			# save a copy of D0
 5937	and.l		&0x00007FFF,%d1
 5938	sub.l		&0x00003FFF,%d1		# d0 = K
 5939	cmp.l		%d1,&28
 5940	ble.b		LASTLOOP
 5941CONTLOOP:
 5942	sub.l		&27,%d1			# d0 = L := K-27
 5943	mov.b		&0,ENDFLAG(%a6)
 5944	bra.b		WORK
 5945LASTLOOP:
 5946	clr.l		%d1			# d0 = L := 0
 5947	mov.b		&1,ENDFLAG(%a6)
 5948
 5949WORK:
 5950#--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
 5951#--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
 5952
 5953#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
 5954#--2**L * (PIby2_1), 2**L * (PIby2_2)
 5955
 5956	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
 5957	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
 5958
 5959	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
 5960	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
 5961	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
 5962
 5963	fmov.x		%fp0,%fp2
 5964	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
 5965
 5966#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
 5967#--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
 5968#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
 5969#--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
 5970#--US THE DESIRED VALUE IN FLOATING POINT.
 5971	mov.l		%a1,%d2
 5972	swap		%d2
 5973	and.l		&0x80000000,%d2
 5974	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
 5975	mov.l		%d2,TWOTO63(%a6)
 5976	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
 5977	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
 5978#	fintrz.x	%fp2,%fp2
 5979
 5980#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
 5981	mov.l		%d1,%d2			# d2 = L
 5982
 5983	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
 5984	mov.w		%d2,FP_SCR0_EX(%a6)
 5985	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
 5986	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
 5987
 5988	add.l		&0x00003FDD,%d1
 5989	mov.w		%d1,FP_SCR1_EX(%a6)
 5990	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
 5991	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
 5992
 5993	mov.b		ENDFLAG(%a6),%d1
 5994
 5995#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
 5996#--P2 = 2**(L) * Piby2_2
 5997	fmov.x		%fp2,%fp4		# fp4 = N
 5998	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
 5999	fmov.x		%fp2,%fp5		# fp5 = N
 6000	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
 6001	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
 6002
 6003#--we want P+p = W+w  but  |p| <= half ulp of P
 6004#--Then, we need to compute  A := R-P   and  a := r-p
 6005	fadd.x		%fp5,%fp3		# fp3 = P
 6006	fsub.x		%fp3,%fp4		# fp4 = W-P
 6007
 6008	fsub.x		%fp3,%fp0		# fp0 = A := R - P
 6009	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
 6010
 6011	fmov.x		%fp0,%fp3		# fp3 = A
 6012	fsub.x		%fp4,%fp1		# fp1 = a := r - p
 6013
 6014#--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
 6015#--|r| <= half ulp of R.
 6016	fadd.x		%fp1,%fp0		# fp0 = R := A+a
 6017#--No need to calculate r if this is the last loop
 6018	cmp.b		%d1,&0
 6019	bgt.w		RESTORE
 6020
 6021#--Need to calculate r
 6022	fsub.x		%fp0,%fp3		# fp3 = A-R
 6023	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
 6024	bra.w		LOOP
 6025
 6026RESTORE:
 6027	fmov.l		%fp2,INT(%a6)
 6028	mov.l		(%sp)+,%d2		# restore d2
 6029	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
 6030
 6031	mov.l		INT(%a6),%d1
 6032	ror.l		&1,%d1
 6033
 6034	bra.w		TANCONT
 6035
 6036#########################################################################
 6037# satan():  computes the arctangent of a normalized number		#
 6038# satand(): computes the arctangent of a denormalized number		#
 6039#									#
 6040# INPUT	*************************************************************** #
 6041#	a0 = pointer to extended precision input			#
 6042#	d0 = round precision,mode					#
 6043#									#
 6044# OUTPUT ************************************************************** #
 6045#	fp0 = arctan(X)							#
 6046#									#
 6047# ACCURACY and MONOTONICITY ******************************************* #
 6048#	The returned result is within 2 ulps in	64 significant bit,	#
 6049#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 6050#	rounded to double precision. The result is provably monotonic	#
 6051#	in double precision.						#
 6052#									#
 6053# ALGORITHM *********************************************************** #
 6054#	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
 6055#									#
 6056#	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x.			#
 6057#		Note that k = -4, -3,..., or 3.				#
 6058#		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5	#
 6059#		significant bits of X with a bit-1 attached at the 6-th	#
 6060#		bit position. Define u to be u = (X-F) / (1 + X*F).	#
 6061#									#
 6062#	Step 3. Approximate arctan(u) by a polynomial poly.		#
 6063#									#
 6064#	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a	#
 6065#		table of values calculated beforehand. Exit.		#
 6066#									#
 6067#	Step 5. If |X| >= 16, go to Step 7.				#
 6068#									#
 6069#	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
 6070#									#
 6071#	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd	#
 6072#		polynomial in X'.					#
 6073#		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
 6074#									#
 6075#########################################################################
 6076
 6077ATANA3:	long		0xBFF6687E,0x314987D8
 6078ATANA2:	long		0x4002AC69,0x34A26DB3
 6079ATANA1:	long		0xBFC2476F,0x4E1DA28E
 6080
 6081ATANB6:	long		0x3FB34444,0x7F876989
 6082ATANB5:	long		0xBFB744EE,0x7FAF45DB
 6083ATANB4:	long		0x3FBC71C6,0x46940220
 6084ATANB3:	long		0xBFC24924,0x921872F9
 6085ATANB2:	long		0x3FC99999,0x99998FA9
 6086ATANB1:	long		0xBFD55555,0x55555555
 6087
 6088ATANC5:	long		0xBFB70BF3,0x98539E6A
 6089ATANC4:	long		0x3FBC7187,0x962D1D7D
 6090ATANC3:	long		0xBFC24924,0x827107B8
 6091ATANC2:	long		0x3FC99999,0x9996263E
 6092ATANC1:	long		0xBFD55555,0x55555536
 6093
 6094PPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
 6095NPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
 6096
 6097PTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
 6098NTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
 6099
 6100ATANTBL:
 6101	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
 6102	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
 6103	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
 6104	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
 6105	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
 6106	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
 6107	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
 6108	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
 6109	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
 6110	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
 6111	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
 6112	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
 6113	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
 6114	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
 6115	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
 6116	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
 6117	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
 6118	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
 6119	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
 6120	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
 6121	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
 6122	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
 6123	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
 6124	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
 6125	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
 6126	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
 6127	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
 6128	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
 6129	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
 6130	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
 6131	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
 6132	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
 6133	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
 6134	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
 6135	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
 6136	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
 6137	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
 6138	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
 6139	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
 6140	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
 6141	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
 6142	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
 6143	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
 6144	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
 6145	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
 6146	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
 6147	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
 6148	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
 6149	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
 6150	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
 6151	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
 6152	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
 6153	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
 6154	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
 6155	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
 6156	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
 6157	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
 6158	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
 6159	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
 6160	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
 6161	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
 6162	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
 6163	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
 6164	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
 6165	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
 6166	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
 6167	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
 6168	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
 6169	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
 6170	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
 6171	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
 6172	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
 6173	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
 6174	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
 6175	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
 6176	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
 6177	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
 6178	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
 6179	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
 6180	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
 6181	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
 6182	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
 6183	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
 6184	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
 6185	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
 6186	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
 6187	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
 6188	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
 6189	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
 6190	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
 6191	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
 6192	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
 6193	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
 6194	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
 6195	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
 6196	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
 6197	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
 6198	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
 6199	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
 6200	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
 6201	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
 6202	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
 6203	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
 6204	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
 6205	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
 6206	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
 6207	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
 6208	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
 6209	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
 6210	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
 6211	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
 6212	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
 6213	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
 6214	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
 6215	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
 6216	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
 6217	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
 6218	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
 6219	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
 6220	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
 6221	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
 6222	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
 6223	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
 6224	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
 6225	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
 6226	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
 6227	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
 6228	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
 6229
 6230	set		X,FP_SCR0
 6231	set		XDCARE,X+2
 6232	set		XFRAC,X+4
 6233	set		XFRACLO,X+8
 6234
 6235	set		ATANF,FP_SCR1
 6236	set		ATANFHI,ATANF+4
 6237	set		ATANFLO,ATANF+8
 6238
 6239	global		satan
 6240#--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
 6241satan:
 6242	fmov.x		(%a0),%fp0		# LOAD INPUT
 6243
 6244	mov.l		(%a0),%d1
 6245	mov.w		4(%a0),%d1
 6246	fmov.x		%fp0,X(%a6)
 6247	and.l		&0x7FFFFFFF,%d1
 6248
 6249	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
 6250	bge.b		ATANOK1
 6251	bra.w		ATANSM
 6252
 6253ATANOK1:
 6254	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
 6255	ble.b		ATANMAIN
 6256	bra.w		ATANBIG
 6257
 6258#--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
 6259#--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
 6260#--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
 6261#--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
 6262#--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
 6263#--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
 6264#--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
 6265#--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
 6266#--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
 6267#--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
 6268#--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
 6269#--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
 6270#--WILL INVOLVE A VERY LONG POLYNOMIAL.
 6271
 6272#--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
 6273#--WE CHOSE F TO BE +-2^K * 1.BBBB1
 6274#--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
 6275#--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
 6276#--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
 6277#-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
 6278
 6279ATANMAIN:
 6280
 6281	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
 6282	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
 6283	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
 6284
 6285	fmov.x		%fp0,%fp1		# FP1 IS X
 6286	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
 6287	fsub.x		X(%a6),%fp0		# FP0 IS X-F
 6288	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
 6289	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
 6290
 6291#--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
 6292#--CREATE ATAN(F) AND STORE IT IN ATANF, AND
 6293#--SAVE REGISTERS FP2.
 6294
 6295	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
 6296	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
 6297	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
 6298	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
 6299	sub.l		&0x3FFB0000,%d2		# K+4
 6300	asr.l		&1,%d2
 6301	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
 6302	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
 6303	lea		ATANTBL(%pc),%a1
 6304	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
 6305	mov.l		(%a1)+,ATANF(%a6)
 6306	mov.l		(%a1)+,ATANFHI(%a6)
 6307	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
 6308	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
 6309	and.l		&0x80000000,%d1		# SIGN(F)
 6310	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
 6311	mov.l		(%sp)+,%d2		# RESTORE d2
 6312
 6313#--THAT'S ALL I HAVE TO DO FOR NOW,
 6314#--BUT ALAS, THE DIVIDE IS STILL CRANKING!
 6315
 6316#--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
 6317#--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
 6318#--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
 6319#--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
 6320#--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
 6321#--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
 6322#--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
 6323
 6324	fmovm.x		&0x04,-(%sp)		# save fp2
 6325
 6326	fmov.x		%fp0,%fp1
 6327	fmul.x		%fp1,%fp1
 6328	fmov.d		ATANA3(%pc),%fp2
 6329	fadd.x		%fp1,%fp2		# A3+V
 6330	fmul.x		%fp1,%fp2		# V*(A3+V)
 6331	fmul.x		%fp0,%fp1		# U*V
 6332	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
 6333	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
 6334	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
 6335	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
 6336
 6337	fmovm.x		(%sp)+,&0x20		# restore fp2
 6338
 6339	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
 6340	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
 6341	bra		t_inx2
 6342
 6343ATANBORS:
 6344#--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
 6345#--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
 6346	cmp.l		%d1,&0x3FFF8000
 6347	bgt.w		ATANBIG			# I.E. |X| >= 16
 6348
 6349ATANSM:
 6350#--|X| <= 1/16
 6351#--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
 6352#--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
 6353#--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
 6354#--WHERE Y = X*X, AND Z = Y*Y.
 6355
 6356	cmp.l		%d1,&0x3FD78000
 6357	blt.w		ATANTINY
 6358
 6359#--COMPUTE POLYNOMIAL
 6360	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
 6361
 6362	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
 6363
 6364	fmov.x		%fp0,%fp1
 6365	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
 6366
 6367	fmov.d		ATANB6(%pc),%fp2
 6368	fmov.d		ATANB5(%pc),%fp3
 6369
 6370	fmul.x		%fp1,%fp2		# Z*B6
 6371	fmul.x		%fp1,%fp3		# Z*B5
 6372
 6373	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
 6374	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
 6375
 6376	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
 6377	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
 6378
 6379	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
 6380	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
 6381
 6382	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
 6383	fmul.x		X(%a6),%fp0		# X*Y
 6384
 6385	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
 6386
 6387	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
 6388
 6389	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
 6390
 6391	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
 6392	fadd.x		X(%a6),%fp0
 6393	bra		t_inx2
 6394
 6395ATANTINY:
 6396#--|X| < 2^(-40), ATAN(X) = X
 6397
 6398	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
 6399	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 6400	fmov.x		X(%a6),%fp0		# last inst - possible exception set
 6401
 6402	bra		t_catch
 6403
 6404ATANBIG:
 6405#--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
 6406#--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
 6407	cmp.l		%d1,&0x40638000
 6408	bgt.w		ATANHUGE
 6409
 6410#--APPROXIMATE ATAN(-1/X) BY
 6411#--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
 6412#--THIS CAN BE RE-WRITTEN AS
 6413#--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
 6414
 6415	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
 6416
 6417	fmov.s		&0xBF800000,%fp1	# LOAD -1
 6418	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
 6419
 6420#--DIVIDE IS STILL CRANKING
 6421
 6422	fmov.x		%fp1,%fp0		# FP0 IS X'
 6423	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
 6424	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
 6425
 6426	fmov.x		%fp0,%fp1
 6427	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
 6428
 6429	fmov.d		ATANC5(%pc),%fp3
 6430	fmov.d		ATANC4(%pc),%fp2
 6431
 6432	fmul.x		%fp1,%fp3		# Z*C5
 6433	fmul.x		%fp1,%fp2		# Z*B4
 6434
 6435	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
 6436	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
 6437
 6438	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
 6439	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
 6440
 6441	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
 6442	fmul.x		X(%a6),%fp0		# X'*Y
 6443
 6444	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
 6445
 6446	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
 6447#					...	+[Y*(B2+Z*(B4+Z*B6))])
 6448	fadd.x		X(%a6),%fp0
 6449
 6450	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
 6451
 6452	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
 6453	tst.b		(%a0)
 6454	bpl.b		pos_big
 6455
 6456neg_big:
 6457	fadd.x		NPIBY2(%pc),%fp0
 6458	bra		t_minx2
 6459
 6460pos_big:
 6461	fadd.x		PPIBY2(%pc),%fp0
 6462	bra		t_pinx2
 6463
 6464ATANHUGE:
 6465#--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
 6466	tst.b		(%a0)
 6467	bpl.b		pos_huge
 6468
 6469neg_huge:
 6470	fmov.x		NPIBY2(%pc),%fp0
 6471	fmov.l		%d0,%fpcr
 6472	fadd.x		PTINY(%pc),%fp0
 6473	bra		t_minx2
 6474
 6475pos_huge:
 6476	fmov.x		PPIBY2(%pc),%fp0
 6477	fmov.l		%d0,%fpcr
 6478	fadd.x		NTINY(%pc),%fp0
 6479	bra		t_pinx2
 6480
 6481	global		satand
 6482#--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
 6483satand:
 6484	bra		t_extdnrm
 6485
 6486#########################################################################
 6487# sasin():  computes the inverse sine of a normalized input		#
 6488# sasind(): computes the inverse sine of a denormalized input		#
 6489#									#
 6490# INPUT ***************************************************************	#
 6491#	a0 = pointer to extended precision input			#
 6492#	d0 = round precision,mode					#
 6493#									#
 6494# OUTPUT **************************************************************	#
 6495#	fp0 = arcsin(X)							#
 6496#									#
 6497# ACCURACY and MONOTONICITY *******************************************	#
 6498#	The returned result is within 3 ulps in	64 significant bit,	#
 6499#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 6500#	rounded to double precision. The result is provably monotonic	#
 6501#	in double precision.						#
 6502#									#
 6503# ALGORITHM ***********************************************************	#
 6504#									#
 6505#	ASIN								#
 6506#	1. If |X| >= 1, go to 3.					#
 6507#									#
 6508#	2. (|X| < 1) Calculate asin(X) by				#
 6509#		z := sqrt( [1-X][1+X] )					#
 6510#		asin(X) = atan( x / z ).				#
 6511#		Exit.							#
 6512#									#
 6513#	3. If |X| > 1, go to 5.						#
 6514#									#
 6515#	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
 6516#									#
 6517#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
 6518#		Exit.							#
 6519#									#
 6520#########################################################################
 6521
 6522	global		sasin
 6523sasin:
 6524	fmov.x		(%a0),%fp0		# LOAD INPUT
 6525
 6526	mov.l		(%a0),%d1
 6527	mov.w		4(%a0),%d1
 6528	and.l		&0x7FFFFFFF,%d1
 6529	cmp.l		%d1,&0x3FFF8000
 6530	bge.b		ASINBIG
 6531
 6532# This catch is added here for the '060 QSP. Originally, the call to
 6533# satan() would handle this case by causing the exception which would
 6534# not be caught until gen_except(). Now, with the exceptions being
 6535# detected inside of satan(), the exception would have been handled there
 6536# instead of inside sasin() as expected.
 6537	cmp.l		%d1,&0x3FD78000
 6538	blt.w		ASINTINY
 6539
 6540#--THIS IS THE USUAL CASE, |X| < 1
 6541#--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
 6542
 6543ASINMAIN:
 6544	fmov.s		&0x3F800000,%fp1
 6545	fsub.x		%fp0,%fp1		# 1-X
 6546	fmovm.x		&0x4,-(%sp)		#  {fp2}
 6547	fmov.s		&0x3F800000,%fp2
 6548	fadd.x		%fp0,%fp2		# 1+X
 6549	fmul.x		%fp2,%fp1		# (1+X)(1-X)
 6550	fmovm.x		(%sp)+,&0x20		#  {fp2}
 6551	fsqrt.x		%fp1			# SQRT([1-X][1+X])
 6552	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
 6553	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
 6554	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
 6555	bsr		satan
 6556	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
 6557	bra		t_inx2
 6558
 6559ASINBIG:
 6560	fabs.x		%fp0			# |X|
 6561	fcmp.s		%fp0,&0x3F800000
 6562	fbgt		t_operr			# cause an operr exception
 6563
 6564#--|X| = 1, ASIN(X) = +- PI/2.
 6565ASINONE:
 6566	fmov.x		PIBY2(%pc),%fp0
 6567	mov.l		(%a0),%d1
 6568	and.l		&0x80000000,%d1		# SIGN BIT OF X
 6569	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
 6570	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
 6571	fmov.l		%d0,%fpcr
 6572	fmul.s		(%sp)+,%fp0
 6573	bra		t_inx2
 6574
 6575#--|X| < 2^(-40), ATAN(X) = X
 6576ASINTINY:
 6577	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
 6578	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 6579	fmov.x		(%a0),%fp0		# last inst - possible exception
 6580	bra		t_catch
 6581
 6582	global		sasind
 6583#--ASIN(X) = X FOR DENORMALIZED X
 6584sasind:
 6585	bra		t_extdnrm
 6586
 6587#########################################################################
 6588# sacos():  computes the inverse cosine of a normalized input		#
 6589# sacosd(): computes the inverse cosine of a denormalized input		#
 6590#									#
 6591# INPUT ***************************************************************	#
 6592#	a0 = pointer to extended precision input			#
 6593#	d0 = round precision,mode					#
 6594#									#
 6595# OUTPUT ************************************************************** #
 6596#	fp0 = arccos(X)							#
 6597#									#
 6598# ACCURACY and MONOTONICITY *******************************************	#
 6599#	The returned result is within 3 ulps in	64 significant bit,	#
 6600#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 6601#	rounded to double precision. The result is provably monotonic	#
 6602#	in double precision.						#
 6603#									#
 6604# ALGORITHM *********************************************************** #
 6605#									#
 6606#	ACOS								#
 6607#	1. If |X| >= 1, go to 3.					#
 6608#									#
 6609#	2. (|X| < 1) Calculate acos(X) by				#
 6610#		z := (1-X) / (1+X)					#
 6611#		acos(X) = 2 * atan( sqrt(z) ).				#
 6612#		Exit.							#
 6613#									#
 6614#	3. If |X| > 1, go to 5.						#
 6615#									#
 6616#	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
 6617#									#
 6618#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
 6619#		Exit.							#
 6620#									#
 6621#########################################################################
 6622
 6623	global		sacos
 6624sacos:
 6625	fmov.x		(%a0),%fp0		# LOAD INPUT
 6626
 6627	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
 6628	mov.w		4(%a0),%d1
 6629	and.l		&0x7FFFFFFF,%d1
 6630	cmp.l		%d1,&0x3FFF8000
 6631	bge.b		ACOSBIG
 6632
 6633#--THIS IS THE USUAL CASE, |X| < 1
 6634#--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
 6635
 6636ACOSMAIN:
 6637	fmov.s		&0x3F800000,%fp1
 6638	fadd.x		%fp0,%fp1		# 1+X
 6639	fneg.x		%fp0			# -X
 6640	fadd.s		&0x3F800000,%fp0	# 1-X
 6641	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
 6642	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
 6643	mov.l		%d0,-(%sp)		# save original users fpcr
 6644	clr.l		%d0
 6645	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
 6646	lea		(%sp),%a0		# pass ptr to sqrt
 6647	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
 6648	add.l		&0xc,%sp		# clear SQRT(...) from stack
 6649
 6650	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
 6651	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
 6652	bra		t_pinx2
 6653
 6654ACOSBIG:
 6655	fabs.x		%fp0
 6656	fcmp.s		%fp0,&0x3F800000
 6657	fbgt		t_operr			# cause an operr exception
 6658
 6659#--|X| = 1, ACOS(X) = 0 OR PI
 6660	tst.b		(%a0)			# is X positive or negative?
 6661	bpl.b		ACOSP1
 6662
 6663#--X = -1
 6664#Returns PI and inexact exception
 6665ACOSM1:
 6666	fmov.x		PI(%pc),%fp0		# load PI
 6667	fmov.l		%d0,%fpcr		# load round mode,prec
 6668	fadd.s		&0x00800000,%fp0	# add a small value
 6669	bra		t_pinx2
 6670
 6671ACOSP1:
 6672	bra		ld_pzero		# answer is positive zero
 6673
 6674	global		sacosd
 6675#--ACOS(X) = PI/2 FOR DENORMALIZED X
 6676sacosd:
 6677	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
 6678	fmov.x		PIBY2(%pc),%fp0
 6679	bra		t_pinx2
 6680
 6681#########################################################################
 6682# setox():    computes the exponential for a normalized input		#
 6683# setoxd():   computes the exponential for a denormalized input		#
 6684# setoxm1():  computes the exponential minus 1 for a normalized input	#
 6685# setoxm1d(): computes the exponential minus 1 for a denormalized input	#
 6686#									#
 6687# INPUT	*************************************************************** #
 6688#	a0 = pointer to extended precision input			#
 6689#	d0 = round precision,mode					#
 6690#									#
 6691# OUTPUT ************************************************************** #
 6692#	fp0 = exp(X) or exp(X)-1					#
 6693#									#
 6694# ACCURACY and MONOTONICITY ******************************************* #
 6695#	The returned result is within 0.85 ulps in 64 significant bit,	#
 6696#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
 6697#	rounded to double precision. The result is provably monotonic	#
 6698#	in double precision.						#
 6699#									#
 6700# ALGORITHM and IMPLEMENTATION **************************************** #
 6701#									#
 6702#	setoxd								#
 6703#	------								#
 6704#	Step 1.	Set ans := 1.0						#
 6705#									#
 6706#	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
 6707#	Notes:	This will always generate one exception -- inexact.	#
 6708#									#
 6709#									#
 6710#	setox								#
 6711#	-----								#
 6712#									#
 6713#	Step 1.	Filter out extreme cases of input argument.		#
 6714#		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
 6715#		1.2	Go to Step 7.					#
 6716#		1.3	If |X| < 16380 log(2), go to Step 2.		#
 6717#		1.4	Go to Step 8.					#
 6718#	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
 6719#		To avoid the use of floating-point comparisons, a	#
 6720#		compact representation of |X| is used. This format is a	#
 6721#		32-bit integer, the upper (more significant) 16 bits	#
 6722#		are the sign and biased exponent field of |X|; the	#
 6723#		lower 16 bits are the 16 most significant fraction	#
 6724#		(including the explicit bit) bits of |X|. Consequently,	#
 6725#		the comparisons in Steps 1.1 and 1.3 can be performed	#
 6726#		by integer comparison. Note also that the constant	#
 6727#		16380 log(2) used in Step 1.3 is also in the compact	#
 6728#		form. Thus taking the branch to Step 2 guarantees	#
 6729#		|X| < 16380 log(2). There is no harm to have a small	#
 6730#		number of cases where |X| is less than,	but close to,	#
 6731#		16380 log(2) and the branch to Step 9 is taken.		#
 6732#									#
 6733#	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
 6734#		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
 6735#			was taken)					#
 6736#		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
 6737#		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
 6738#			or 63.						#
 6739#		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
 6740#		2.5	Calculate the address of the stored value of	#
 6741#			2^(J/64).					#
 6742#		2.6	Create the value Scale = 2^M.			#
 6743#	Notes:	The calculation in 2.2 is really performed by		#
 6744#			Z := X * constant				#
 6745#			N := round-to-nearest-integer(Z)		#
 6746#		where							#
 6747#			constant := single-precision( 64/log 2 ).	#
 6748#									#
 6749#		Using a single-precision constant avoids memory		#
 6750#		access. Another effect of using a single-precision	#
 6751#		"constant" is that the calculated value Z is		#
 6752#									#
 6753#			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
 6754#									#
 6755#		This error has to be considered later in Steps 3 and 4.	#
 6756#									#
 6757#	Step 3.	Calculate X - N*log2/64.				#
 6758#		3.1	R := X + N*L1,					#
 6759#				where L1 := single-precision(-log2/64).	#
 6760#		3.2	R := R + N*L2,					#
 6761#				L2 := extended-precision(-log2/64 - L1).#
 6762#	Notes:	a) The way L1 and L2 are chosen ensures L1+L2		#
 6763#		approximate the value -log2/64 to 88 bits of accuracy.	#
 6764#		b) N*L1 is exact because N is no longer than 22 bits	#
 6765#		and L1 is no longer than 24 bits.			#
 6766#		c) The calculation X+N*L1 is also exact due to		#
 6767#		cancellation. Thus, R is practically X+N(L1+L2) to full	#
 6768#		64 bits.						#
 6769#		d) It is important to estimate how large can |R| be	#
 6770#		after Step 3.2.						#
 6771#									#
 6772#		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
 6773#		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
 6774#		X*64/log2 - N	=	f - eps*X 64/log2		#
 6775#		X - N*log2/64	=	f*log2/64 - eps*X		#
 6776#									#
 6777#									#
 6778#		Now |X| <= 16446 log2, thus				#
 6779#									#
 6780#			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
 6781#					<= 0.57 log2/64.		#
 6782#		 This bound will be used in Step 4.			#
 6783#									#
 6784#	Step 4.	Approximate exp(R)-1 by a polynomial			#
 6785#		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
 6786#	Notes:	a) In order to reduce memory access, the coefficients	#
 6787#		are made as "short" as possible: A1 (which is 1/2), A4	#
 6788#		and A5 are single precision; A2 and A3 are double	#
 6789#		precision.						#
 6790#		b) Even with the restrictions above,			#
 6791#		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
 6792#		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
 6793#		c) To fully utilize the pipeline, p is separated into	#
 6794#		two independent pieces of roughly equal complexities	#
 6795#			p = [ R + R*S*(A2 + S*A4) ]	+		#
 6796#				[ S*(A1 + S*(A3 + S*A5)) ]		#
 6797#		where S = R*R.						#
 6798#									#
 6799#	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
 6800#				ans := T + ( T*p + t)			#
 6801#		where T and t are the stored values for 2^(J/64).	#
 6802#	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
 6803#		2^(J/64) to roughly 85 bits; T is in extended precision	#
 6804#		and t is in single precision. Note also that T is	#
 6805#		rounded to 62 bits so that the last two bits of T are	#
 6806#		zero. The reason for such a special form is that T-1,	#
 6807#		T-2, and T-8 will all be exact --- a property that will	#
 6808#		give much more accurate computation of the function	#
 6809#		EXPM1.							#
 6810#									#
 6811#	Step 6.	Reconstruction of exp(X)				#
 6812#			exp(X) = 2^M * 2^(J/64) * exp(R).		#
 6813#		6.1	If AdjFlag = 0, go to 6.3			#
 6814#		6.2	ans := ans * AdjScale				#
 6815#		6.3	Restore the user FPCR				#
 6816#		6.4	Return ans := ans * Scale. Exit.		#
 6817#	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
 6818#		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
 6819#		neither overflow nor underflow. If AdjFlag = 1, that	#
 6820#		means that						#
 6821#			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
 6822#		Hence, exp(X) may overflow or underflow or neither.	#
 6823#		When that is the case, AdjScale = 2^(M1) where M1 is	#
 6824#		approximately M. Thus 6.2 will never cause		#
 6825#		over/underflow. Possible exception in 6.4 is overflow	#
 6826#		or underflow. The inexact exception is not generated in	#
 6827#		6.4. Although one can argue that the inexact flag	#
 6828#		should always be raised, to simulate that exception	#
 6829#		cost to much than the flag is worth in practical uses.	#
 6830#									#
 6831#	Step 7.	Return 1 + X.						#
 6832#		7.1	ans := X					#
 6833#		7.2	Restore user FPCR.				#
 6834#		7.3	Return ans := 1 + ans. Exit			#
 6835#	Notes:	For non-zero X, the inexact exception will always be	#
 6836#		raised by 7.3. That is the only exception raised by 7.3.#
 6837#		Note also that we use the FMOVEM instruction to move X	#
 6838#		in Step 7.1 to avoid unnecessary trapping. (Although	#
 6839#		the FMOVEM may not seem relevant since X is normalized,	#
 6840#		the precaution will be useful in the library version of	#
 6841#		this code where the separate entry for denormalized	#
 6842#		inputs will be done away with.)				#
 6843#									#
 6844#	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
 6845#		8.1	If |X| > 16480 log2, go to Step 9.		#
 6846#		(mimic 2.2 - 2.6)					#
 6847#		8.2	N := round-to-integer( X * 64/log2 )		#
 6848#		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
 6849#		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1,	#
 6850#			AdjFlag := 1.					#
 6851#		8.5	Calculate the address of the stored value	#
 6852#			2^(J/64).					#
 6853#		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
 6854#		8.7	Go to Step 3.					#
 6855#	Notes:	Refer to notes for 2.2 - 2.6.				#
 6856#									#
 6857#	Step 9.	Handle exp(X), |X| > 16480 log2.			#
 6858#		9.1	If X < 0, go to 9.3				#
 6859#		9.2	ans := Huge, go to 9.4				#
 6860#		9.3	ans := Tiny.					#
 6861#		9.4	Restore user FPCR.				#
 6862#		9.5	Return ans := ans * ans. Exit.			#
 6863#	Notes:	Exp(X) will surely overflow or underflow, depending on	#
 6864#		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
 6865#		extended-precision numbers whose square over/underflow	#
 6866#		with an inexact result. Thus, 9.5 always raises the	#
 6867#		inexact together with either overflow or underflow.	#
 6868#									#
 6869#	setoxm1d							#
 6870#	--------							#
 6871#									#
 6872#	Step 1.	Set ans := 0						#
 6873#									#
 6874#	Step 2.	Return	ans := X + ans. Exit.				#
 6875#	Notes:	This will return X with the appropriate rounding	#
 6876#		 precision prescribed by the user FPCR.			#
 6877#									#
 6878#	setoxm1								#
 6879#	-------								#
 6880#									#
 6881#	Step 1.	Check |X|						#
 6882#		1.1	If |X| >= 1/4, go to Step 1.3.			#
 6883#		1.2	Go to Step 7.					#
 6884#		1.3	If |X| < 70 log(2), go to Step 2.		#
 6885#		1.4	Go to Step 10.					#
 6886#	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
 6887#		However, it is conceivable |X| can be small very often	#
 6888#		because EXPM1 is intended to evaluate exp(X)-1		#
 6889#		accurately when |X| is small. For further details on	#
 6890#		the comparisons, see the notes on Step 1 of setox.	#
 6891#									#
 6892#	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
 6893#		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
 6894#		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
 6895#			or 63.						#
 6896#		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
 6897#		2.4	Calculate the address of the stored value of	#
 6898#			2^(J/64).					#
 6899#		2.5	Create the values Sc = 2^M and			#
 6900#			OnebySc := -2^(-M).				#
 6901#	Notes:	See the notes on Step 2 of setox.			#
 6902#									#
 6903#	Step 3.	Calculate X - N*log2/64.				#
 6904#		3.1	R := X + N*L1,					#
 6905#				where L1 := single-precision(-log2/64).	#
 6906#		3.2	R := R + N*L2,					#
 6907#				L2 := extended-precision(-log2/64 - L1).#
 6908#	Notes:	Applying the analysis of Step 3 of setox in this case	#
 6909#		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
 6910#		this case).						#
 6911#									#
 6912#	Step 4.	Approximate exp(R)-1 by a polynomial			#
 6913#			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
 6914#	Notes:	a) In order to reduce memory access, the coefficients	#
 6915#		are made as "short" as possible: A1 (which is 1/2), A5	#
 6916#		and A6 are single precision; A2, A3 and A4 are double	#
 6917#		precision.						#
 6918#		b) Even with the restriction above,			#
 6919#			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
 6920#		for all |R| <= 0.0055.					#
 6921#		c) To fully utilize the pipeline, p is separated into	#
 6922#		two independent pieces of roughly equal complexity	#
 6923#			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
 6924#				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
 6925#		where S = R*R.						#
 6926#									#
 6927#	Step 5.	Compute 2^(J/64)*p by					#
 6928#				p := T*p				#
 6929#		where T and t are the stored values for 2^(J/64).	#
 6930#	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
 6931#		2^(J/64) to roughly 85 bits; T is in extended precision	#
 6932#		and t is in single precision. Note also that T is	#
 6933#		rounded to 62 bits so that the last two bits of T are	#
 6934#		zero. The reason for such a special form is that T-1,	#
 6935#		T-2, and T-8 will all be exact --- a property that will	#
 6936#		be exploited in Step 6 below. The total relative error	#
 6937#		in p is no bigger than 2^(-67.7) compared to the final	#
 6938#		result.							#
 6939#									#
 6940#	Step 6.	Reconstruction of exp(X)-1				#
 6941#			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
 6942#		6.1	If M <= 63, go to Step 6.3.			#
 6943#		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
 6944#		6.3	If M >= -3, go to 6.5.				#
 6945#		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
 6946#		6.5	ans := (T + OnebySc) + (p + t).			#
 6947#		6.6	Restore user FPCR.				#
 6948#		6.7	Return ans := Sc * ans. Exit.			#
 6949#	Notes:	The various arrangements of the expressions give	#
 6950#		accurate evaluations.					#
 6951#									#
 6952#	Step 7.	exp(X)-1 for |X| < 1/4.					#
 6953#		7.1	If |X| >= 2^(-65), go to Step 9.		#
 6954#		7.2	Go to Step 8.					#
 6955#									#
 6956#	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
 6957#		8.1	If |X| < 2^(-16312), goto 8.3			#
 6958#		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
 6959#			Exit.						#
 6960#		8.3	X := X * 2^(140).				#
 6961#		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
 6962#		 Return ans := ans*2^(140). Exit			#
 6963#	Notes:	The idea is to return "X - tiny" under the user		#
 6964#		precision and rounding modes. To avoid unnecessary	#
 6965#		inefficiency, we stay away from denormalized numbers	#
 6966#		the best we can. For |X| >= 2^(-16312), the		#
 6967#		straightforward 8.2 generates the inexact exception as	#
 6968#		the case warrants.					#
 6969#									#
 6970#	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
 6971#			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
 6972#	Notes:	a) In order to reduce memory access, the coefficients	#
 6973#		are made as "short" as possible: B1 (which is 1/2), B9	#
 6974#		to B12 are single precision; B3 to B8 are double	#
 6975#		precision; and B2 is double extended.			#
 6976#		b) Even with the restriction above,			#
 6977#			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
 6978#		for all |X| <= 0.251.					#
 6979#		Note that 0.251 is slightly bigger than 1/4.		#
 6980#		c) To fully preserve accuracy, the polynomial is	#
 6981#		computed as						#
 6982#			X + ( S*B1 +	Q ) where S = X*X and		#
 6983#			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
 6984#		d) To fully utilize the pipeline, Q is separated into	#
 6985#		two independent pieces of roughly equal complexity	#
 6986#			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
 6987#				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
 6988#									#
 6989#	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
 6990#		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all	#
 6991#		practical purposes. Therefore, go to Step 1 of setox.	#
 6992#		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
 6993#		purposes.						#
 6994#		ans := -1						#
 6995#		Restore user FPCR					#
 6996#		Return ans := ans + 2^(-126). Exit.			#
 6997#	Notes:	10.2 will always create an inexact and return -1 + tiny	#
 6998#		in the user rounding precision and mode.		#
 6999#									#
 7000#########################################################################
 7001
 7002L2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
 7003
 7004EEXPA3:	long		0x3FA55555,0x55554CC1
 7005EEXPA2:	long		0x3FC55555,0x55554A54
 7006
 7007EM1A4:	long		0x3F811111,0x11174385
 7008EM1A3:	long		0x3FA55555,0x55554F5A
 7009
 7010EM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
 7011
 7012EM1B8:	long		0x3EC71DE3,0xA5774682
 7013EM1B7:	long		0x3EFA01A0,0x19D7CB68
 7014
 7015EM1B6:	long		0x3F2A01A0,0x1A019DF3
 7016EM1B5:	long		0x3F56C16C,0x16C170E2
 7017
 7018EM1B4:	long		0x3F811111,0x11111111
 7019EM1B3:	long		0x3FA55555,0x55555555
 7020
 7021EM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
 7022	long		0x00000000
 7023
 7024TWO140:	long		0x48B00000,0x00000000
 7025TWON140:
 7026	long		0x37300000,0x00000000
 7027
 7028EEXPTBL:
 7029	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
 7030	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
 7031	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
 7032	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
 7033	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
 7034	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
 7035	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
 7036	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
 7037	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
 7038	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
 7039	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
 7040	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
 7041	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
 7042	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
 7043	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
 7044	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
 7045	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
 7046	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
 7047	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
 7048	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
 7049	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
 7050	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
 7051	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
 7052	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
 7053	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
 7054	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
 7055	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
 7056	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
 7057	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
 7058	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
 7059	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
 7060	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
 7061	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
 7062	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
 7063	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
 7064	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
 7065	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
 7066	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
 7067	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
 7068	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
 7069	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
 7070	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
 7071	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
 7072	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
 7073	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
 7074	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
 7075	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
 7076	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
 7077	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
 7078	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
 7079	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
 7080	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
 7081	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
 7082	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
 7083	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
 7084	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
 7085	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
 7086	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
 7087	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
 7088	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
 7089	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
 7090	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
 7091	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
 7092	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
 7093
 7094	set		ADJFLAG,L_SCR2
 7095	set		SCALE,FP_SCR0
 7096	set		ADJSCALE,FP_SCR1
 7097	set		SC,FP_SCR0
 7098	set		ONEBYSC,FP_SCR1
 7099
 7100	global		setox
 7101setox:
 7102#--entry point for EXP(X), here X is finite, non-zero, and not NaN's
 7103
 7104#--Step 1.
 7105	mov.l		(%a0),%d1		# load part of input X
 7106	and.l		&0x7FFF0000,%d1		# biased expo. of X
 7107	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
 7108	bge.b		EXPC1			# normal case
 7109	bra		EXPSM
 7110
 7111EXPC1:
 7112#--The case |X| >= 2^(-65)
 7113	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
 7114	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
 7115	blt.b		EXPMAIN			# normal case
 7116	bra		EEXPBIG
 7117
 7118EXPMAIN:
 7119#--Step 2.
 7120#--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
 7121	fmov.x		(%a0),%fp0		# load input from (a0)
 7122
 7123	fmov.x		%fp0,%fp1
 7124	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
 7125	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
 7126	mov.l		&0,ADJFLAG(%a6)
 7127	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
 7128	lea		EEXPTBL(%pc),%a1
 7129	fmov.l		%d1,%fp0		# convert to floating-format
 7130
 7131	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
 7132	and.l		&0x3F,%d1		# D0 is J = N mod 64
 7133	lsl.l		&4,%d1
 7134	add.l		%d1,%a1			# address of 2^(J/64)
 7135	mov.l		L_SCR1(%a6),%d1
 7136	asr.l		&6,%d1			# D0 is M
 7137	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
 7138	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
 7139
 7140EXPCONT1:
 7141#--Step 3.
 7142#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
 7143#--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
 7144	fmov.x		%fp0,%fp2
 7145	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
 7146	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
 7147	fadd.x		%fp1,%fp0		# X + N*L1
 7148	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
 7149
 7150#--Step 4.
 7151#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
 7152#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
 7153#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
 7154#--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
 7155
 7156	fmov.x		%fp0,%fp1
 7157	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
 7158
 7159	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
 7160
 7161	fmul.x		%fp1,%fp2		# fp2 IS S*A5
 7162	fmov.x		%fp1,%fp3
 7163	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
 7164
 7165	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
 7166	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
 7167
 7168	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
 7169	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
 7170	mov.l		&0x80000000,SCALE+4(%a6)
 7171	clr.l		SCALE+8(%a6)
 7172
 7173	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
 7174
 7175	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
 7176	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
 7177
 7178	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
 7179	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
 7180
 7181	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
 7182	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
 7183
 7184#--Step 5
 7185#--final reconstruction process
 7186#--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
 7187
 7188	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
 7189	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
 7190	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
 7191
 7192	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
 7193	mov.l		ADJFLAG(%a6),%d1
 7194
 7195#--Step 6
 7196	tst.l		%d1
 7197	beq.b		NORMAL
 7198ADJUST:
 7199	fmul.x		ADJSCALE(%a6),%fp0
 7200NORMAL:
 7201	fmov.l		%d0,%fpcr		# restore user FPCR
 7202	mov.b		&FMUL_OP,%d1		# last inst is MUL
 7203	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
 7204	bra		t_catch
 7205
 7206EXPSM:
 7207#--Step 7
 7208	fmovm.x		(%a0),&0x80		# load X
 7209	fmov.l		%d0,%fpcr
 7210	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
 7211	bra		t_pinx2
 7212
 7213EEXPBIG:
 7214#--Step 8
 7215	cmp.l		%d1,&0x400CB27C		# 16480 log2
 7216	bgt.b		EXP2BIG
 7217#--Steps 8.2 -- 8.6
 7218	fmov.x		(%a0),%fp0		# load input from (a0)
 7219
 7220	fmov.x		%fp0,%fp1
 7221	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
 7222	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
 7223	mov.l		&1,ADJFLAG(%a6)
 7224	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
 7225	lea		EEXPTBL(%pc),%a1
 7226	fmov.l		%d1,%fp0		# convert to floating-format
 7227	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
 7228	and.l		&0x3F,%d1		# D0 is J = N mod 64
 7229	lsl.l		&4,%d1
 7230	add.l		%d1,%a1			# address of 2^(J/64)
 7231	mov.l		L_SCR1(%a6),%d1
 7232	asr.l		&6,%d1			# D0 is K
 7233	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
 7234	asr.l		&1,%d1			# D0 is M1
 7235	sub.l		%d1,L_SCR1(%a6)		# a1 is M
 7236	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
 7237	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
 7238	mov.l		&0x80000000,ADJSCALE+4(%a6)
 7239	clr.l		ADJSCALE+8(%a6)
 7240	mov.l		L_SCR1(%a6),%d1		# D0 is M
 7241	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
 7242	bra.w		EXPCONT1		# go back to Step 3
 7243
 7244EXP2BIG:
 7245#--Step 9
 7246	tst.b		(%a0)			# is X positive or negative?
 7247	bmi		t_unfl2
 7248	bra		t_ovfl2
 7249
 7250	global		setoxd
 7251setoxd:
 7252#--entry point for EXP(X), X is denormalized
 7253	mov.l		(%a0),-(%sp)
 7254	andi.l		&0x80000000,(%sp)
 7255	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
 7256
 7257	fmov.s		&0x3F800000,%fp0
 7258
 7259	fmov.l		%d0,%fpcr
 7260	fadd.s		(%sp)+,%fp0
 7261	bra		t_pinx2
 7262
 7263	global		setoxm1
 7264setoxm1:
 7265#--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
 7266
 7267#--Step 1.
 7268#--Step 1.1
 7269	mov.l		(%a0),%d1		# load part of input X
 7270	and.l		&0x7FFF0000,%d1		# biased expo. of X
 7271	cmp.l		%d1,&0x3FFD0000		# 1/4
 7272	bge.b		EM1CON1			# |X| >= 1/4
 7273	bra		EM1SM
 7274
 7275EM1CON1:
 7276#--Step 1.3
 7277#--The case |X| >= 1/4
 7278	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
 7279	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
 7280	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
 7281	bra		EM1BIG
 7282
 7283EM1MAIN:
 7284#--Step 2.
 7285#--This is the case:	1/4 <= |X| <= 70 log2.
 7286	fmov.x		(%a0),%fp0		# load input from (a0)
 7287
 7288	fmov.x		%fp0,%fp1
 7289	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
 7290	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
 7291	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
 7292	lea		EEXPTBL(%pc),%a1
 7293	fmov.l		%d1,%fp0		# convert to floating-format
 7294
 7295	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
 7296	and.l		&0x3F,%d1		# D0 is J = N mod 64
 7297	lsl.l		&4,%d1
 7298	add.l		%d1,%a1			# address of 2^(J/64)
 7299	mov.l		L_SCR1(%a6),%d1
 7300	asr.l		&6,%d1			# D0 is M
 7301	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
 7302
 7303#--Step 3.
 7304#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
 7305#--a0 points to 2^(J/64), D0 and a1 both contain M
 7306	fmov.x		%fp0,%fp2
 7307	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
 7308	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
 7309	fadd.x		%fp1,%fp0		# X + N*L1
 7310	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
 7311	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
 7312
 7313#--Step 4.
 7314#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
 7315#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
 7316#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
 7317#--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
 7318
 7319	fmov.x		%fp0,%fp1
 7320	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
 7321
 7322	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
 7323
 7324	fmul.x		%fp1,%fp2		# fp2 IS S*A6
 7325	fmov.x		%fp1,%fp3
 7326	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
 7327
 7328	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
 7329	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
 7330	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
 7331	mov.l		&0x80000000,SC+4(%a6)
 7332	clr.l		SC+8(%a6)
 7333
 7334	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
 7335	mov.l		L_SCR1(%a6),%d1		# D0 is	M
 7336	neg.w		%d1			# D0 is -M
 7337	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
 7338	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
 7339	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
 7340	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
 7341
 7342	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
 7343	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
 7344	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
 7345	mov.l		&0x80000000,ONEBYSC+4(%a6)
 7346	clr.l		ONEBYSC+8(%a6)
 7347	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
 7348
 7349	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
 7350	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
 7351
 7352	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
 7353
 7354	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
 7355
 7356#--Step 5
 7357#--Compute 2^(J/64)*p
 7358
 7359	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
 7360
 7361#--Step 6
 7362#--Step 6.1
 7363	mov.l		L_SCR1(%a6),%d1		# retrieve M
 7364	cmp.l		%d1,&63
 7365	ble.b		MLE63
 7366#--Step 6.2	M >= 64
 7367	fmov.s		12(%a1),%fp1		# fp1 is t
 7368	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
 7369	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
 7370	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
 7371	bra		EM1SCALE
 7372MLE63:
 7373#--Step 6.3	M <= 63
 7374	cmp.l		%d1,&-3
 7375	bge.b		MGEN3
 7376MLTN3:
 7377#--Step 6.4	M <= -4
 7378	fadd.s		12(%a1),%fp0		# p+t
 7379	fadd.x		(%a1),%fp0		# T+(p+t)
 7380	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
 7381	bra		EM1SCALE
 7382MGEN3:
 7383#--Step 6.5	-3 <= M <= 63
 7384	fmov.x		(%a1)+,%fp1		# fp1 is T
 7385	fadd.s		(%a1),%fp0		# fp0 is p+t
 7386	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
 7387	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
 7388
 7389EM1SCALE:
 7390#--Step 6.6
 7391	fmov.l		%d0,%fpcr
 7392	fmul.x		SC(%a6),%fp0
 7393	bra		t_inx2
 7394
 7395EM1SM:
 7396#--Step 7	|X| < 1/4.
 7397	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
 7398	bge.b		EM1POLY
 7399
 7400EM1TINY:
 7401#--Step 8	|X| < 2^(-65)
 7402	cmp.l		%d1,&0x00330000		# 2^(-16312)
 7403	blt.b		EM12TINY
 7404#--Step 8.2
 7405	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
 7406	mov.l		&0x80000000,SC+4(%a6)
 7407	clr.l		SC+8(%a6)
 7408	fmov.x		(%a0),%fp0
 7409	fmov.l		%d0,%fpcr
 7410	mov.b		&FADD_OP,%d1		# last inst is ADD
 7411	fadd.x		SC(%a6),%fp0
 7412	bra		t_catch
 7413
 7414EM12TINY:
 7415#--Step 8.3
 7416	fmov.x		(%a0),%fp0
 7417	fmul.d		TWO140(%pc),%fp0
 7418	mov.l		&0x80010000,SC(%a6)
 7419	mov.l		&0x80000000,SC+4(%a6)
 7420	clr.l		SC+8(%a6)
 7421	fadd.x		SC(%a6),%fp0
 7422	fmov.l		%d0,%fpcr
 7423	mov.b		&FMUL_OP,%d1		# last inst is MUL
 7424	fmul.d		TWON140(%pc),%fp0
 7425	bra		t_catch
 7426
 7427EM1POLY:
 7428#--Step 9	exp(X)-1 by a simple polynomial
 7429	fmov.x		(%a0),%fp0		# fp0 is X
 7430	fmul.x		%fp0,%fp0		# fp0 is S := X*X
 7431	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
 7432	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
 7433	fmul.x		%fp0,%fp1		# fp1 is S*B12
 7434	fmov.s		&0x310F8290,%fp2	# fp2 is B11
 7435	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
 7436
 7437	fmul.x		%fp0,%fp2		# fp2 is S*B11
 7438	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
 7439
 7440	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
 7441	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
 7442
 7443	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
 7444	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
 7445
 7446	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
 7447	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
 7448
 7449	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
 7450	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
 7451
 7452	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
 7453	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
 7454
 7455	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
 7456	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
 7457
 7458	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
 7459	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
 7460
 7461	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
 7462	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
 7463
 7464	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
 7465	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
 7466
 7467	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
 7468	fadd.x		%fp2,%fp1		# fp1 is Q
 7469
 7470	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
 7471
 7472	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
 7473
 7474	fmov.l		%d0,%fpcr
 7475	fadd.x		(%a0),%fp0
 7476	bra		t_inx2
 7477
 7478EM1BIG:
 7479#--Step 10	|X| > 70 log2
 7480	mov.l		(%a0),%d1
 7481	cmp.l		%d1,&0
 7482	bgt.w		EXPC1
 7483#--Step 10.2
 7484	fmov.s		&0xBF800000,%fp0	# fp0 is -1
 7485	fmov.l		%d0,%fpcr
 7486	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
 7487	bra		t_minx2
 7488
 7489	global		setoxm1d
 7490setoxm1d:
 7491#--entry point for EXPM1(X), here X is denormalized
 7492#--Step 0.
 7493	bra		t_extdnrm
 7494
 7495#########################################################################
 7496# sgetexp():  returns the exponent portion of the input argument.	#
 7497#	      The exponent bias is removed and the exponent value is	#
 7498#	      returned as an extended precision number in fp0.		#
 7499# sgetexpd(): handles denormalized numbers.				#
 7500#									#
 7501# sgetman():  extracts the mantissa of the input argument. The		#
 7502#	      mantissa is converted to an extended precision number w/	#
 7503#	      an exponent of $3fff and is returned in fp0. The range of #
 7504#	      the result is [1.0 - 2.0).				#
 7505# sgetmand(): handles denormalized numbers.				#
 7506#									#
 7507# INPUT *************************************************************** #
 7508#	a0  = pointer to extended precision input			#
 7509#									#
 7510# OUTPUT ************************************************************** #
 7511#	fp0 = exponent(X) or mantissa(X)				#
 7512#									#
 7513#########################################################################
 7514
 7515	global		sgetexp
 7516sgetexp:
 7517	mov.w		SRC_EX(%a0),%d0		# get the exponent
 7518	bclr		&0xf,%d0		# clear the sign bit
 7519	subi.w		&0x3fff,%d0		# subtract off the bias
 7520	fmov.w		%d0,%fp0		# return exp in fp0
 7521	blt.b		sgetexpn		# it's negative
 7522	rts
 7523
 7524sgetexpn:
 7525	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
 7526	rts
 7527
 7528	global		sgetexpd
 7529sgetexpd:
 7530	bsr.l		norm			# normalize
 7531	neg.w		%d0			# new exp = -(shft amt)
 7532	subi.w		&0x3fff,%d0		# subtract off the bias
 7533	fmov.w		%d0,%fp0		# return exp in fp0
 7534	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
 7535	rts
 7536
 7537	global		sgetman
 7538sgetman:
 7539	mov.w		SRC_EX(%a0),%d0		# get the exp
 7540	ori.w		&0x7fff,%d0		# clear old exp
 7541	bclr		&0xe,%d0		# make it the new exp +-3fff
 7542
 7543# here, we build the result in a tmp location so as not to disturb the input
 7544	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
 7545	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
 7546	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
 7547	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
 7548	bmi.b		sgetmann		# it's negative
 7549	rts
 7550
 7551sgetmann:
 7552	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
 7553	rts
 7554
 7555#
 7556# For denormalized numbers, shift the mantissa until the j-bit = 1,
 7557# then load the exponent with +/1 $3fff.
 7558#
 7559	global		sgetmand
 7560sgetmand:
 7561	bsr.l		norm			# normalize exponent
 7562	bra.b		sgetman
 7563
 7564#########################################################################
 7565# scosh():  computes the hyperbolic cosine of a normalized input	#
 7566# scoshd(): computes the hyperbolic cosine of a denormalized input	#
 7567#									#
 7568# INPUT ***************************************************************	#
 7569#	a0 = pointer to extended precision input			#
 7570#	d0 = round precision,mode					#
 7571#									#
 7572# OUTPUT **************************************************************	#
 7573#	fp0 = cosh(X)							#
 7574#									#
 7575# ACCURACY and MONOTONICITY *******************************************	#
 7576#	The returned result is within 3 ulps in 64 significant bit,	#
 7577#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 7578#	rounded to double precision. The result is provably monotonic	#
 7579#	in double precision.						#
 7580#									#
 7581# ALGORITHM ***********************************************************	#
 7582#									#
 7583#	COSH								#
 7584#	1. If |X| > 16380 log2, go to 3.				#
 7585#									#
 7586#	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
 7587#		y = |X|, z = exp(Y), and				#
 7588#		cosh(X) = (1/2)*( z + 1/z ).				#
 7589#		Exit.							#
 7590#									#
 7591#	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
 7592#									#
 7593#	4. (16380 log2 < |X| <= 16480 log2)				#
 7594#		cosh(X) = sign(X) * exp(|X|)/2.				#
 7595#		However, invoking exp(|X|) may cause premature		#
 7596#		overflow. Thus, we calculate sinh(X) as follows:	#
 7597#		Y	:= |X|						#
 7598#		Fact	:=	2**(16380)				#
 7599#		Y'	:= Y - 16381 log2				#
 7600#		cosh(X) := Fact * exp(Y').				#
 7601#		Exit.							#
 7602#									#
 7603#	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
 7604#		Huge*Huge to generate overflow and an infinity with	#
 7605#		the appropriate sign. Huge is the largest finite number	#
 7606#		in extended format. Exit.				#
 7607#									#
 7608#########################################################################
 7609
 7610TWO16380:
 7611	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
 7612
 7613	global		scosh
 7614scosh:
 7615	fmov.x		(%a0),%fp0		# LOAD INPUT
 7616
 7617	mov.l		(%a0),%d1
 7618	mov.w		4(%a0),%d1
 7619	and.l		&0x7FFFFFFF,%d1
 7620	cmp.l		%d1,&0x400CB167
 7621	bgt.b		COSHBIG
 7622
 7623#--THIS IS THE USUAL CASE, |X| < 16380 LOG2
 7624#--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
 7625
 7626	fabs.x		%fp0			# |X|
 7627
 7628	mov.l		%d0,-(%sp)
 7629	clr.l		%d0
 7630	fmovm.x		&0x01,-(%sp)		# save |X| to stack
 7631	lea		(%sp),%a0		# pass ptr to |X|
 7632	bsr		setox			# FP0 IS EXP(|X|)
 7633	add.l		&0xc,%sp		# erase |X| from stack
 7634	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
 7635	mov.l		(%sp)+,%d0
 7636
 7637	fmov.s		&0x3E800000,%fp1	# (1/4)
 7638	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
 7639
 7640	fmov.l		%d0,%fpcr
 7641	mov.b		&FADD_OP,%d1		# last inst is ADD
 7642	fadd.x		%fp1,%fp0
 7643	bra		t_catch
 7644
 7645COSHBIG:
 7646	cmp.l		%d1,&0x400CB2B3
 7647	bgt.b		COSHHUGE
 7648
 7649	fabs.x		%fp0
 7650	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
 7651	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
 7652
 7653	mov.l		%d0,-(%sp)
 7654	clr.l		%d0
 7655	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
 7656	lea		(%sp),%a0		# pass ptr to fp0
 7657	bsr		setox
 7658	add.l		&0xc,%sp		# clear fp0 from stack
 7659	mov.l		(%sp)+,%d0
 7660
 7661	fmov.l		%d0,%fpcr
 7662	mov.b		&FMUL_OP,%d1		# last inst is MUL
 7663	fmul.x		TWO16380(%pc),%fp0
 7664	bra		t_catch
 7665
 7666COSHHUGE:
 7667	bra		t_ovfl2
 7668
 7669	global		scoshd
 7670#--COSH(X) = 1 FOR DENORMALIZED X
 7671scoshd:
 7672	fmov.s		&0x3F800000,%fp0
 7673
 7674	fmov.l		%d0,%fpcr
 7675	fadd.s		&0x00800000,%fp0
 7676	bra		t_pinx2
 7677
 7678#########################################################################
 7679# ssinh():  computes the hyperbolic sine of a normalized input		#
 7680# ssinhd(): computes the hyperbolic sine of a denormalized input	#
 7681#									#
 7682# INPUT *************************************************************** #
 7683#	a0 = pointer to extended precision input			#
 7684#	d0 = round precision,mode					#
 7685#									#
 7686# OUTPUT ************************************************************** #
 7687#	fp0 = sinh(X)							#
 7688#									#
 7689# ACCURACY and MONOTONICITY *******************************************	#
 7690#	The returned result is within 3 ulps in 64 significant bit,	#
 7691#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
 7692#	rounded to double precision. The result is provably monotonic	#
 7693#	in double precision.						#
 7694#									#
 7695# ALGORITHM *********************************************************** #
 7696#									#
 7697#       SINH								#
 7698#       1. If |X| > 16380 log2, go to 3.				#
 7699#									#
 7700#       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
 7701#               y = |X|, sgn = sign(X), and z = expm1(Y),		#
 7702#               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
 7703#          Exit.							#
 7704#									#
 7705#       3. If |X| > 16480 log2, go to 5.				#
 7706#									#
 7707#       4. (16380 log2 < |X| <= 16480 log2)				#
 7708#               sinh(X) = sign(X) * exp(|X|)/2.				#
 7709#          However, invoking exp(|X|) may cause premature overflow.	#
 7710#          Thus, we calculate sinh(X) as follows:			#
 7711#             Y       := |X|						#
 7712#             sgn     := sign(X)					#
 7713#             sgnFact := sgn * 2**(16380)				#
 7714#             Y'      := Y - 16381 log2					#
 7715#             sinh(X) := sgnFact * exp(Y').				#
 7716#          Exit.							#
 7717#									#
 7718#       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
 7719#          sign(X)*Huge*Huge to generate overflow and an infinity with	#
 7720#          the appropriate sign. Huge is the largest finite number in	#
 7721#          extended format. Exit.					#
 7722#									#
 7723#########################################################################
 7724
 7725	global		ssinh
 7726ssinh:
 7727	fmov.x		(%a0),%fp0		# LOAD INPUT
 7728
 7729	mov.l		(%a0),%d1
 7730	mov.w		4(%a0),%d1
 7731	mov.l		%d1,%a1			# save (compacted) operand
 7732	and.l		&0x7FFFFFFF,%d1
 7733	cmp.l		%d1,&0x400CB167
 7734	bgt.b		SINHBIG
 7735
 7736#--THIS IS THE USUAL CASE, |X| < 16380 LOG2
 7737#--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
 7738
 7739	fabs.x		%fp0			# Y = |X|
 7740
 7741	movm.l		&0x8040,-(%sp)		# {a1/d0}
 7742	fmovm.x		&0x01,-(%sp)		# save Y on stack
 7743	lea		(%sp),%a0		# pass ptr to Y
 7744	clr.l		%d0
 7745	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
 7746	add.l		&0xc,%sp		# clear Y from stack
 7747	fmov.l		&0,%fpcr
 7748	movm.l		(%sp)+,&0x0201		# {a1/d0}
 7749
 7750	fmov.x		%fp0,%fp1
 7751	fadd.s		&0x3F800000,%fp1	# 1+Z
 7752	fmov.x		%fp0,-(%sp)
 7753	fdiv.x		%fp1,%fp0		# Z/(1+Z)
 7754	mov.l		%a1,%d1
 7755	and.l		&0x80000000,%d1
 7756	or.l		&0x3F000000,%d1
 7757	fadd.x		(%sp)+,%fp0
 7758	mov.l		%d1,-(%sp)
 7759
 7760	fmov.l		%d0,%fpcr
 7761	mov.b		&FMUL_OP,%d1		# last inst is MUL
 7762	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
 7763	bra		t_catch
 7764
 7765SINHBIG:
 7766	cmp.l		%d1,&0x400CB2B3
 7767	bgt		t_ovfl
 7768	fabs.x		%fp0
 7769	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
 7770	mov.l		&0,-(%sp)
 7771	mov.l		&0x80000000,-(%sp)
 7772	mov.l		%a1,%d1
 7773	and.l		&0x80000000,%d1
 7774	or.l		&0x7FFB0000,%d1
 7775	mov.l		%d1,-(%sp)		# EXTENDED FMT
 7776	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
 7777
 7778	mov.l		%d0,-(%sp)
 7779	clr.l		%d0
 7780	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
 7781	lea		(%sp),%a0		# pass ptr to fp0
 7782	bsr		setox
 7783	add.l		&0xc,%sp		# clear fp0 from stack
 7784
 7785	mov.l		(%sp)+,%d0
 7786	fmov.l		%d0,%fpcr
 7787	mov.b		&FMUL_OP,%d1		# last inst is MUL
 7788	fmul.x		(%sp)+,%fp0		# possible exception
 7789	bra		t_catch
 7790
 7791	global		ssinhd
 7792#--SINH(X) = X FOR DENORMALIZED X
 7793ssinhd:
 7794	bra		t_extdnrm
 7795
 7796#########################################################################
 7797# stanh():  computes the hyperbolic tangent of a normalized input	#
 7798# stanhd(): computes the hyperbolic tangent of a denormalized input	#
 7799#									#
 7800# INPUT ***************************************************************	#
 7801#	a0 = pointer to extended precision input			#
 7802#	d0 = round precision,mode					#
 7803#									#
 7804# OUTPUT **************************************************************	#
 7805#	fp0 = tanh(X)							#
 7806#									#
 7807# ACCURACY and MONOTONICITY *******************************************	#
 7808#	The returned result is within 3 ulps in 64 significant bit,	#
 7809#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
 7810#	rounded to double precision. The result is provably monotonic	#
 7811#	in double precision.						#
 7812#									#
 7813# ALGORITHM ***********************************************************	#
 7814#									#
 7815#	TANH								#
 7816#	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
 7817#									#
 7818#	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
 7819#		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
 7820#		tanh(X) = sgn*( z/(2+z) ).				#
 7821#		Exit.							#
 7822#									#
 7823#	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
 7824#		go to 7.						#
 7825#									#
 7826#	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
 7827#									#
 7828#	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
 7829#		sgn := sign(X), y := 2|X|, z := exp(Y),			#
 7830#		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
 7831#		Exit.							#
 7832#									#
 7833#	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
 7834#		calculate Tanh(X) by					#
 7835#		sgn := sign(X), Tiny := 2**(-126),			#
 7836#		tanh(X) := sgn - sgn*Tiny.				#
 7837#		Exit.							#
 7838#									#
 7839#	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
 7840#									#
 7841#########################################################################
 7842
 7843	set		X,FP_SCR0
 7844	set		XFRAC,X+4
 7845
 7846	set		SGN,L_SCR3
 7847
 7848	set		V,FP_SCR0
 7849
 7850	global		stanh
 7851stanh:
 7852	fmov.x		(%a0),%fp0		# LOAD INPUT
 7853
 7854	fmov.x		%fp0,X(%a6)
 7855	mov.l		(%a0),%d1
 7856	mov.w		4(%a0),%d1
 7857	mov.l		%d1,X(%a6)
 7858	and.l		&0x7FFFFFFF,%d1
 7859	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
 7860	blt.w		TANHBORS		# yes
 7861	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
 7862	bgt.w		TANHBORS		# yes
 7863
 7864#--THIS IS THE USUAL CASE
 7865#--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
 7866
 7867	mov.l		X(%a6),%d1
 7868	mov.l		%d1,SGN(%a6)
 7869	and.l		&0x7FFF0000,%d1
 7870	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
 7871	mov.l		%d1,X(%a6)
 7872	and.l		&0x80000000,SGN(%a6)
 7873	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
 7874
 7875	mov.l		%d0,-(%sp)
 7876	clr.l		%d0
 7877	fmovm.x		&0x1,-(%sp)		# save Y on stack
 7878	lea		(%sp),%a0		# pass ptr to Y
 7879	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
 7880	add.l		&0xc,%sp		# clear Y from stack
 7881	mov.l		(%sp)+,%d0
 7882
 7883	fmov.x		%fp0,%fp1
 7884	fadd.s		&0x40000000,%fp1	# Z+2
 7885	mov.l		SGN(%a6),%d1
 7886	fmov.x		%fp1,V(%a6)
 7887	eor.l		%d1,V(%a6)
 7888
 7889	fmov.l		%d0,%fpcr		# restore users round prec,mode
 7890	fdiv.x		V(%a6),%fp0
 7891	bra		t_inx2
 7892
 7893TANHBORS:
 7894	cmp.l		%d1,&0x3FFF8000
 7895	blt.w		TANHSM
 7896
 7897	cmp.l		%d1,&0x40048AA1
 7898	bgt.w		TANHHUGE
 7899
 7900#-- (5/2) LOG2 < |X| < 50 LOG2,
 7901#--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
 7902#--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
 7903
 7904	mov.l		X(%a6),%d1
 7905	mov.l		%d1,SGN(%a6)
 7906	and.l		&0x7FFF0000,%d1
 7907	add.l		&0x00010000,%d1		# EXPO OF 2|X|
 7908	mov.l		%d1,X(%a6)		# Y = 2|X|
 7909	and.l		&0x80000000,SGN(%a6)
 7910	mov.l		SGN(%a6),%d1
 7911	fmov.x		X(%a6),%fp0		# Y = 2|X|
 7912
 7913	mov.l		%d0,-(%sp)
 7914	clr.l		%d0
 7915	fmovm.x		&0x01,-(%sp)		# save Y on stack
 7916	lea		(%sp),%a0		# pass ptr to Y
 7917	bsr		setox			# FP0 IS EXP(Y)
 7918	add.l		&0xc,%sp		# clear Y from stack
 7919	mov.l		(%sp)+,%d0
 7920	mov.l		SGN(%a6),%d1
 7921	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
 7922
 7923	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
 7924	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
 7925	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
 7926
 7927	mov.l		SGN(%a6),%d1
 7928	or.l		&0x3F800000,%d1		# SGN
 7929	fmov.s		%d1,%fp0		# SGN IN SGL FMT
 7930
 7931	fmov.l		%d0,%fpcr		# restore users round prec,mode
 7932	mov.b		&FADD_OP,%d1		# last inst is ADD
 7933	fadd.x		%fp1,%fp0
 7934	bra		t_inx2
 7935
 7936TANHSM:
 7937	fmov.l		%d0,%fpcr		# restore users round prec,mode
 7938	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 7939	fmov.x		X(%a6),%fp0		# last inst - possible exception set
 7940	bra		t_catch
 7941
 7942#---RETURN SGN(X) - SGN(X)EPS
 7943TANHHUGE:
 7944	mov.l		X(%a6),%d1
 7945	and.l		&0x80000000,%d1
 7946	or.l		&0x3F800000,%d1
 7947	fmov.s		%d1,%fp0
 7948	and.l		&0x80000000,%d1
 7949	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
 7950
 7951	fmov.l		%d0,%fpcr		# restore users round prec,mode
 7952	fadd.s		%d1,%fp0
 7953	bra		t_inx2
 7954
 7955	global		stanhd
 7956#--TANH(X) = X FOR DENORMALIZED X
 7957stanhd:
 7958	bra		t_extdnrm
 7959
 7960#########################################################################
 7961# slogn():    computes the natural logarithm of a normalized input	#
 7962# slognd():   computes the natural logarithm of a denormalized input	#
 7963# slognp1():  computes the log(1+X) of a normalized input		#
 7964# slognp1d(): computes the log(1+X) of a denormalized input		#
 7965#									#
 7966# INPUT ***************************************************************	#
 7967#	a0 = pointer to extended precision input			#
 7968#	d0 = round precision,mode					#
 7969#									#
 7970# OUTPUT **************************************************************	#
 7971#	fp0 = log(X) or log(1+X)					#
 7972#									#
 7973# ACCURACY and MONOTONICITY *******************************************	#
 7974#	The returned result is within 2 ulps in 64 significant bit,	#
 7975#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 7976#	rounded to double precision. The result is provably monotonic	#
 7977#	in double precision.						#
 7978#									#
 7979# ALGORITHM ***********************************************************	#
 7980#	LOGN:								#
 7981#	Step 1. If |X-1| < 1/16, approximate log(X) by an odd		#
 7982#		polynomial in u, where u = 2(X-1)/(X+1). Otherwise,	#
 7983#		move on to Step 2.					#
 7984#									#
 7985#	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
 7986#		seven significant bits of Y plus 2**(-7), i.e.		#
 7987#		F = 1.xxxxxx1 in base 2 where the six "x" match those	#
 7988#		of Y. Note that |Y-F| <= 2**(-7).			#
 7989#									#
 7990#	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a		#
 7991#		polynomial in u, log(1+u) = poly.			#
 7992#									#
 7993#	Step 4. Reconstruct						#
 7994#		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
 7995#		by k*log(2) + (log(F) + poly). The values of log(F) are	#
 7996#		calculated beforehand and stored in the program.	#
 7997#									#
 7998#	lognp1:								#
 7999#	Step 1: If |X| < 1/16, approximate log(1+X) by an odd		#
 8000#		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
 8001#		to Step 2.						#
 8002#									#
 8003#	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
 8004#		in Step 2 of the algorithm for LOGN and compute		#
 8005#		log(1+X) as k*log(2) + log(F) + poly where poly		#
 8006#		approximates log(1+u), u = (Y-F)/F.			#
 8007#									#
 8008#	Implementation Notes:						#
 8009#	Note 1. There are 64 different possible values for F, thus 64	#
 8010#		log(F)'s need to be tabulated. Moreover, the values of	#
 8011#		1/F are also tabulated so that the division in (Y-F)/F	#
 8012#		can be performed by a multiplication.			#
 8013#									#
 8014#	Note 2. In Step 2 of lognp1, in order to preserved accuracy,	#
 8015#		the value Y-F has to be calculated carefully when	#
 8016#		1/2 <= X < 3/2.						#
 8017#									#
 8018#	Note 3. To fully exploit the pipeline, polynomials are usually	#
 8019#		separated into two parts evaluated independently before	#
 8020#		being added up.						#
 8021#									#
 8022#########################################################################
 8023LOGOF2:
 8024	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
 8025
 8026one:
 8027	long		0x3F800000
 8028zero:
 8029	long		0x00000000
 8030infty:
 8031	long		0x7F800000
 8032negone:
 8033	long		0xBF800000
 8034
 8035LOGA6:
 8036	long		0x3FC2499A,0xB5E4040B
 8037LOGA5:
 8038	long		0xBFC555B5,0x848CB7DB
 8039
 8040LOGA4:
 8041	long		0x3FC99999,0x987D8730
 8042LOGA3:
 8043	long		0xBFCFFFFF,0xFF6F7E97
 8044
 8045LOGA2:
 8046	long		0x3FD55555,0x555555A4
 8047LOGA1:
 8048	long		0xBFE00000,0x00000008
 8049
 8050LOGB5:
 8051	long		0x3F175496,0xADD7DAD6
 8052LOGB4:
 8053	long		0x3F3C71C2,0xFE80C7E0
 8054
 8055LOGB3:
 8056	long		0x3F624924,0x928BCCFF
 8057LOGB2:
 8058	long		0x3F899999,0x999995EC
 8059
 8060LOGB1:
 8061	long		0x3FB55555,0x55555555
 8062TWO:
 8063	long		0x40000000,0x00000000
 8064
 8065LTHOLD:
 8066	long		0x3f990000,0x80000000,0x00000000,0x00000000
 8067
 8068LOGTBL:
 8069	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
 8070	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
 8071	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
 8072	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
 8073	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
 8074	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
 8075	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
 8076	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
 8077	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
 8078	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
 8079	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
 8080	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
 8081	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
 8082	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
 8083	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
 8084	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
 8085	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
 8086	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
 8087	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
 8088	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
 8089	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
 8090	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
 8091	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
 8092	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
 8093	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
 8094	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
 8095	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
 8096	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
 8097	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
 8098	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
 8099	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
 8100	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
 8101	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
 8102	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
 8103	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
 8104	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
 8105	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
 8106	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
 8107	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
 8108	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
 8109	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
 8110	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
 8111	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
 8112	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
 8113	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
 8114	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
 8115	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
 8116	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
 8117	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
 8118	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
 8119	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
 8120	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
 8121	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
 8122	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
 8123	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
 8124	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
 8125	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
 8126	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
 8127	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
 8128	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
 8129	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
 8130	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
 8131	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
 8132	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
 8133	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
 8134	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
 8135	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
 8136	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
 8137	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
 8138	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
 8139	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
 8140	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
 8141	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
 8142	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
 8143	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
 8144	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
 8145	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
 8146	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
 8147	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
 8148	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
 8149	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
 8150	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
 8151	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
 8152	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
 8153	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
 8154	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
 8155	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
 8156	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
 8157	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
 8158	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
 8159	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
 8160	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
 8161	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
 8162	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
 8163	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
 8164	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
 8165	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
 8166	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
 8167	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
 8168	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
 8169	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
 8170	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
 8171	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
 8172	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
 8173	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
 8174	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
 8175	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
 8176	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
 8177	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
 8178	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
 8179	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
 8180	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
 8181	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
 8182	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
 8183	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
 8184	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
 8185	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
 8186	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
 8187	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
 8188	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
 8189	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
 8190	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
 8191	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
 8192	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
 8193	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
 8194	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
 8195	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
 8196	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
 8197
 8198	set		ADJK,L_SCR1
 8199
 8200	set		X,FP_SCR0
 8201	set		XDCARE,X+2
 8202	set		XFRAC,X+4
 8203
 8204	set		F,FP_SCR1
 8205	set		FFRAC,F+4
 8206
 8207	set		KLOG2,FP_SCR0
 8208
 8209	set		SAVEU,FP_SCR0
 8210
 8211	global		slogn
 8212#--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
 8213slogn:
 8214	fmov.x		(%a0),%fp0		# LOAD INPUT
 8215	mov.l		&0x00000000,ADJK(%a6)
 8216
 8217LOGBGN:
 8218#--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
 8219#--A FINITE, NON-ZERO, NORMALIZED NUMBER.
 8220
 8221	mov.l		(%a0),%d1
 8222	mov.w		4(%a0),%d1
 8223
 8224	mov.l		(%a0),X(%a6)
 8225	mov.l		4(%a0),X+4(%a6)
 8226	mov.l		8(%a0),X+8(%a6)
 8227
 8228	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
 8229	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
 8230# X IS POSITIVE, CHECK IF X IS NEAR 1
 8231	cmp.l		%d1,&0x3ffef07d		# IS X < 15/16?
 8232	blt.b		LOGMAIN			# YES
 8233	cmp.l		%d1,&0x3fff8841		# IS X > 17/16?
 8234	ble.w		LOGNEAR1		# NO
 8235
 8236LOGMAIN:
 8237#--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
 8238
 8239#--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
 8240#--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
 8241#--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
 8242#--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
 8243#--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
 8244#--LOG(1+U) CAN BE VERY EFFICIENT.
 8245#--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
 8246#--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
 8247
 8248#--GET K, Y, F, AND ADDRESS OF 1/F.
 8249	asr.l		&8,%d1
 8250	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
 8251	sub.l		&0x3FFF,%d1		# THIS IS K
 8252	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
 8253	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
 8254	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
 8255
 8256#--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
 8257	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
 8258	mov.l		XFRAC(%a6),FFRAC(%a6)
 8259	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
 8260	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
 8261	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
 8262	and.l		&0x7E000000,%d1
 8263	asr.l		&8,%d1
 8264	asr.l		&8,%d1
 8265	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
 8266	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
 8267
 8268	fmov.x		X(%a6),%fp0
 8269	mov.l		&0x3fff0000,F(%a6)
 8270	clr.l		F+8(%a6)
 8271	fsub.x		F(%a6),%fp0		# Y-F
 8272	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
 8273#--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
 8274#--REGISTERS SAVED: FPCR, FP1, FP2
 8275
 8276LP1CONT1:
 8277#--AN RE-ENTRY POINT FOR LOGNP1
 8278	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
 8279	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
 8280	fmov.x		%fp0,%fp2
 8281	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
 8282	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
 8283
 8284#--LOG(1+U) IS APPROXIMATED BY
 8285#--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
 8286#--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
 8287
 8288	fmov.x		%fp2,%fp3
 8289	fmov.x		%fp2,%fp1
 8290
 8291	fmul.d		LOGA6(%pc),%fp1		# V*A6
 8292	fmul.d		LOGA5(%pc),%fp2		# V*A5
 8293
 8294	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
 8295	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
 8296
 8297	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
 8298	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
 8299
 8300	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
 8301	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
 8302
 8303	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
 8304	add.l		&16,%a0			# ADDRESS OF LOG(F)
 8305	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
 8306
 8307	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
 8308	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
 8309
 8310	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
 8311	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
 8312	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
 8313
 8314	fmov.l		%d0,%fpcr
 8315	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
 8316	bra		t_inx2
 8317
 8318
 8319LOGNEAR1:
 8320
 8321# if the input is exactly equal to one, then exit through ld_pzero.
 8322# if these 2 lines weren't here, the correct answer would be returned
 8323# but the INEX2 bit would be set.
 8324	fcmp.b		%fp0,&0x1		# is it equal to one?
 8325	fbeq.l		ld_pzero		# yes
 8326
 8327#--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
 8328	fmov.x		%fp0,%fp1
 8329	fsub.s		one(%pc),%fp1		# FP1 IS X-1
 8330	fadd.s		one(%pc),%fp0		# FP0 IS X+1
 8331	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
 8332#--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
 8333#--IN U, U = 2(X-1)/(X+1) = FP1/FP0
 8334
 8335LP1CONT2:
 8336#--THIS IS AN RE-ENTRY POINT FOR LOGNP1
 8337	fdiv.x		%fp0,%fp1		# FP1 IS U
 8338	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
 8339#--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
 8340#--LET V=U*U, W=V*V, CALCULATE
 8341#--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
 8342#--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
 8343	fmov.x		%fp1,%fp0
 8344	fmul.x		%fp0,%fp0		# FP0 IS V
 8345	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
 8346	fmov.x		%fp0,%fp1
 8347	fmul.x		%fp1,%fp1		# FP1 IS W
 8348
 8349	fmov.d		LOGB5(%pc),%fp3
 8350	fmov.d		LOGB4(%pc),%fp2
 8351
 8352	fmul.x		%fp1,%fp3		# W*B5
 8353	fmul.x		%fp1,%fp2		# W*B4
 8354
 8355	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
 8356	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
 8357
 8358	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
 8359
 8360	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
 8361
 8362	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
 8363	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
 8364
 8365	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
 8366	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
 8367
 8368	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
 8369
 8370	fmov.l		%d0,%fpcr
 8371	fadd.x		SAVEU(%a6),%fp0
 8372	bra		t_inx2
 8373
 8374#--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
 8375LOGNEG:
 8376	bra		t_operr
 8377
 8378	global		slognd
 8379slognd:
 8380#--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
 8381
 8382	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
 8383
 8384#----normalize the input value by left shifting k bits (k to be determined
 8385#----below), adjusting exponent and storing -k to  ADJK
 8386#----the value TWOTO100 is no longer needed.
 8387#----Note that this code assumes the denormalized input is NON-ZERO.
 8388
 8389	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
 8390	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
 8391	mov.l		4(%a0),%d4
 8392	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
 8393	clr.l		%d2			# D2 used for holding K
 8394
 8395	tst.l		%d4
 8396	bne.b		Hi_not0
 8397
 8398Hi_0:
 8399	mov.l		%d5,%d4
 8400	clr.l		%d5
 8401	mov.l		&32,%d2
 8402	clr.l		%d6
 8403	bfffo		%d4{&0:&32},%d6
 8404	lsl.l		%d6,%d4
 8405	add.l		%d6,%d2			# (D3,D4,D5) is normalized
 8406
 8407	mov.l		%d3,X(%a6)
 8408	mov.l		%d4,XFRAC(%a6)
 8409	mov.l		%d5,XFRAC+4(%a6)
 8410	neg.l		%d2
 8411	mov.l		%d2,ADJK(%a6)
 8412	fmov.x		X(%a6),%fp0
 8413	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
 8414	lea		X(%a6),%a0
 8415	bra.w		LOGBGN			# begin regular log(X)
 8416
 8417Hi_not0:
 8418	clr.l		%d6
 8419	bfffo		%d4{&0:&32},%d6		# find first 1
 8420	mov.l		%d6,%d2			# get k
 8421	lsl.l		%d6,%d4
 8422	mov.l		%d5,%d7			# a copy of D5
 8423	lsl.l		%d6,%d5
 8424	neg.l		%d6
 8425	add.l		&32,%d6
 8426	lsr.l		%d6,%d7
 8427	or.l		%d7,%d4			# (D3,D4,D5) normalized
 8428
 8429	mov.l		%d3,X(%a6)
 8430	mov.l		%d4,XFRAC(%a6)
 8431	mov.l		%d5,XFRAC+4(%a6)
 8432	neg.l		%d2
 8433	mov.l		%d2,ADJK(%a6)
 8434	fmov.x		X(%a6),%fp0
 8435	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
 8436	lea		X(%a6),%a0
 8437	bra.w		LOGBGN			# begin regular log(X)
 8438
 8439	global		slognp1
 8440#--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
 8441slognp1:
 8442	fmov.x		(%a0),%fp0		# LOAD INPUT
 8443	fabs.x		%fp0			# test magnitude
 8444	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
 8445	fbgt.w		LP1REAL			# if greater, continue
 8446	fmov.l		%d0,%fpcr
 8447	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 8448	fmov.x		(%a0),%fp0		# return signed argument
 8449	bra		t_catch
 8450
 8451LP1REAL:
 8452	fmov.x		(%a0),%fp0		# LOAD INPUT
 8453	mov.l		&0x00000000,ADJK(%a6)
 8454	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
 8455	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
 8456	fmov.x		%fp0,X(%a6)
 8457	mov.w		XFRAC(%a6),XDCARE(%a6)
 8458	mov.l		X(%a6),%d1
 8459	cmp.l		%d1,&0
 8460	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
 8461	cmp.l		%d1,&0x3ffe8000		# IS BOUNDS [1/2,3/2]?
 8462	blt.w		LOGMAIN
 8463	cmp.l		%d1,&0x3fffc000
 8464	bgt.w		LOGMAIN
 8465#--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
 8466#--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
 8467#--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
 8468
 8469LP1NEAR1:
 8470#--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
 8471	cmp.l		%d1,&0x3ffef07d
 8472	blt.w		LP1CARE
 8473	cmp.l		%d1,&0x3fff8841
 8474	bgt.w		LP1CARE
 8475
 8476LP1ONE16:
 8477#--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
 8478#--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
 8479	fadd.x		%fp1,%fp1		# FP1 IS 2Z
 8480	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
 8481#--U = FP1/FP0
 8482	bra.w		LP1CONT2
 8483
 8484LP1CARE:
 8485#--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
 8486#--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
 8487#--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
 8488#--THERE ARE ONLY TWO CASES.
 8489#--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
 8490#--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
 8491#--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
 8492#--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
 8493
 8494	mov.l		XFRAC(%a6),FFRAC(%a6)
 8495	and.l		&0xFE000000,FFRAC(%a6)
 8496	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
 8497	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
 8498	bge.b		KISZERO
 8499
 8500KISNEG1:
 8501	fmov.s		TWO(%pc),%fp0
 8502	mov.l		&0x3fff0000,F(%a6)
 8503	clr.l		F+8(%a6)
 8504	fsub.x		F(%a6),%fp0		# 2-F
 8505	mov.l		FFRAC(%a6),%d1
 8506	and.l		&0x7E000000,%d1
 8507	asr.l		&8,%d1
 8508	asr.l		&8,%d1
 8509	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
 8510	fadd.x		%fp1,%fp1		# GET 2Z
 8511	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
 8512	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
 8513	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
 8514	add.l		%d1,%a0
 8515	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
 8516	bra.w		LP1CONT1
 8517
 8518KISZERO:
 8519	fmov.s		one(%pc),%fp0
 8520	mov.l		&0x3fff0000,F(%a6)
 8521	clr.l		F+8(%a6)
 8522	fsub.x		F(%a6),%fp0		# 1-F
 8523	mov.l		FFRAC(%a6),%d1
 8524	and.l		&0x7E000000,%d1
 8525	asr.l		&8,%d1
 8526	asr.l		&8,%d1
 8527	asr.l		&4,%d1
 8528	fadd.x		%fp1,%fp0		# FP0 IS Y-F
 8529	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
 8530	lea		LOGTBL(%pc),%a0
 8531	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
 8532	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
 8533	bra.w		LP1CONT1
 8534
 8535LP1NEG0:
 8536#--FPCR SAVED. D0 IS X IN COMPACT FORM.
 8537	cmp.l		%d1,&0
 8538	blt.b		LP1NEG
 8539LP1ZERO:
 8540	fmov.s		negone(%pc),%fp0
 8541
 8542	fmov.l		%d0,%fpcr
 8543	bra		t_dz
 8544
 8545LP1NEG:
 8546	fmov.s		zero(%pc),%fp0
 8547
 8548	fmov.l		%d0,%fpcr
 8549	bra		t_operr
 8550
 8551	global		slognp1d
 8552#--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
 8553# Simply return the denorm
 8554slognp1d:
 8555	bra		t_extdnrm
 8556
 8557#########################################################################
 8558# satanh():  computes the inverse hyperbolic tangent of a norm input	#
 8559# satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
 8560#									#
 8561# INPUT ***************************************************************	#
 8562#	a0 = pointer to extended precision input			#
 8563#	d0 = round precision,mode					#
 8564#									#
 8565# OUTPUT **************************************************************	#
 8566#	fp0 = arctanh(X)						#
 8567#									#
 8568# ACCURACY and MONOTONICITY *******************************************	#
 8569#	The returned result is within 3 ulps in	64 significant bit,	#
 8570#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 8571#	rounded to double precision. The result is provably monotonic	#
 8572#	in double precision.						#
 8573#									#
 8574# ALGORITHM ***********************************************************	#
 8575#									#
 8576#	ATANH								#
 8577#	1. If |X| >= 1, go to 3.					#
 8578#									#
 8579#	2. (|X| < 1) Calculate atanh(X) by				#
 8580#		sgn := sign(X)						#
 8581#		y := |X|						#
 8582#		z := 2y/(1-y)						#
 8583#		atanh(X) := sgn * (1/2) * logp1(z)			#
 8584#		Exit.							#
 8585#									#
 8586#	3. If |X| > 1, go to 5.						#
 8587#									#
 8588#	4. (|X| = 1) Generate infinity with an appropriate sign and	#
 8589#		divide-by-zero by					#
 8590#		sgn := sign(X)						#
 8591#		atan(X) := sgn / (+0).					#
 8592#		Exit.							#
 8593#									#
 8594#	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
 8595#		Exit.							#
 8596#									#
 8597#########################################################################
 8598
 8599	global		satanh
 8600satanh:
 8601	mov.l		(%a0),%d1
 8602	mov.w		4(%a0),%d1
 8603	and.l		&0x7FFFFFFF,%d1
 8604	cmp.l		%d1,&0x3FFF8000
 8605	bge.b		ATANHBIG
 8606
 8607#--THIS IS THE USUAL CASE, |X| < 1
 8608#--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
 8609
 8610	fabs.x		(%a0),%fp0		# Y = |X|
 8611	fmov.x		%fp0,%fp1
 8612	fneg.x		%fp1			# -Y
 8613	fadd.x		%fp0,%fp0		# 2Y
 8614	fadd.s		&0x3F800000,%fp1	# 1-Y
 8615	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
 8616	mov.l		(%a0),%d1
 8617	and.l		&0x80000000,%d1
 8618	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
 8619	mov.l		%d1,-(%sp)
 8620
 8621	mov.l		%d0,-(%sp)		# save rnd prec,mode
 8622	clr.l		%d0			# pass ext prec,RN
 8623	fmovm.x		&0x01,-(%sp)		# save Z on stack
 8624	lea		(%sp),%a0		# pass ptr to Z
 8625	bsr		slognp1			# LOG1P(Z)
 8626	add.l		&0xc,%sp		# clear Z from stack
 8627
 8628	mov.l		(%sp)+,%d0		# fetch old prec,mode
 8629	fmov.l		%d0,%fpcr		# load it
 8630	mov.b		&FMUL_OP,%d1		# last inst is MUL
 8631	fmul.s		(%sp)+,%fp0
 8632	bra		t_catch
 8633
 8634ATANHBIG:
 8635	fabs.x		(%a0),%fp0		# |X|
 8636	fcmp.s		%fp0,&0x3F800000
 8637	fbgt		t_operr
 8638	bra		t_dz
 8639
 8640	global		satanhd
 8641#--ATANH(X) = X FOR DENORMALIZED X
 8642satanhd:
 8643	bra		t_extdnrm
 8644
 8645#########################################################################
 8646# slog10():  computes the base-10 logarithm of a normalized input	#
 8647# slog10d(): computes the base-10 logarithm of a denormalized input	#
 8648# slog2():   computes the base-2 logarithm of a normalized input	#
 8649# slog2d():  computes the base-2 logarithm of a denormalized input	#
 8650#									#
 8651# INPUT *************************************************************** #
 8652#	a0 = pointer to extended precision input			#
 8653#	d0 = round precision,mode					#
 8654#									#
 8655# OUTPUT **************************************************************	#
 8656#	fp0 = log_10(X) or log_2(X)					#
 8657#									#
 8658# ACCURACY and MONOTONICITY *******************************************	#
 8659#	The returned result is within 1.7 ulps in 64 significant bit,	#
 8660#	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
 8661#	rounded to double precision. The result is provably monotonic	#
 8662#	in double precision.						#
 8663#									#
 8664# ALGORITHM ***********************************************************	#
 8665#									#
 8666#       slog10d:							#
 8667#									#
 8668#       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
 8669#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
 8670#       Notes:  Default means round-to-nearest mode, no floating-point	#
 8671#               traps, and precision control = double extended.		#
 8672#									#
 8673#       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
 8674#       Notes:  Even if X is denormalized, log(X) is always normalized.	#
 8675#									#
 8676#       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
 8677#            2.1 Restore the user FPCR					#
 8678#            2.2 Return ans := Y * INV_L10.				#
 8679#									#
 8680#       slog10:								#
 8681#									#
 8682#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
 8683#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
 8684#       Notes:  Default means round-to-nearest mode, no floating-point	#
 8685#               traps, and precision control = double extended.		#
 8686#									#
 8687#       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
 8688#									#
 8689#       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
 8690#            2.1  Restore the user FPCR					#
 8691#            2.2  Return ans := Y * INV_L10.				#
 8692#									#
 8693#       sLog2d:								#
 8694#									#
 8695#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
 8696#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
 8697#       Notes:  Default means round-to-nearest mode, no floating-point	#
 8698#               traps, and precision control = double extended.		#
 8699#									#
 8700#       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
 8701#       Notes:  Even if X is denormalized, log(X) is always normalized.	#
 8702#									#
 8703#       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
 8704#            2.1  Restore the user FPCR					#
 8705#            2.2  Return ans := Y * INV_L2.				#
 8706#									#
 8707#       sLog2:								#
 8708#									#
 8709#       Step 0. If X < 0, create a NaN and raise the invalid operation	#
 8710#               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
 8711#       Notes:  Default means round-to-nearest mode, no floating-point	#
 8712#               traps, and precision control = double extended.		#
 8713#									#
 8714#       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
 8715#               go to Step 3.						#
 8716#									#
 8717#       Step 2.   Return k.						#
 8718#            2.1  Get integer k, X = 2^k.				#
 8719#            2.2  Restore the user FPCR.				#
 8720#            2.3  Return ans := convert-to-double-extended(k).		#
 8721#									#
 8722#       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
 8723#									#
 8724#       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
 8725#            4.1  Restore the user FPCR					#
 8726#            4.2  Return ans := Y * INV_L2.				#
 8727#									#
 8728#########################################################################
 8729
 8730INV_L10:
 8731	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
 8732
 8733INV_L2:
 8734	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
 8735
 8736	global		slog10
 8737#--entry point for Log10(X), X is normalized
 8738slog10:
 8739	fmov.b		&0x1,%fp0
 8740	fcmp.x		%fp0,(%a0)		# if operand == 1,
 8741	fbeq.l		ld_pzero		# return an EXACT zero
 8742
 8743	mov.l		(%a0),%d1
 8744	blt.w		invalid
 8745	mov.l		%d0,-(%sp)
 8746	clr.l		%d0
 8747	bsr		slogn			# log(X), X normal.
 8748	fmov.l		(%sp)+,%fpcr
 8749	fmul.x		INV_L10(%pc),%fp0
 8750	bra		t_inx2
 8751
 8752	global		slog10d
 8753#--entry point for Log10(X), X is denormalized
 8754slog10d:
 8755	mov.l		(%a0),%d1
 8756	blt.w		invalid
 8757	mov.l		%d0,-(%sp)
 8758	clr.l		%d0
 8759	bsr		slognd			# log(X), X denorm.
 8760	fmov.l		(%sp)+,%fpcr
 8761	fmul.x		INV_L10(%pc),%fp0
 8762	bra		t_minx2
 8763
 8764	global		slog2
 8765#--entry point for Log2(X), X is normalized
 8766slog2:
 8767	mov.l		(%a0),%d1
 8768	blt.w		invalid
 8769
 8770	mov.l		8(%a0),%d1
 8771	bne.b		continue		# X is not 2^k
 8772
 8773	mov.l		4(%a0),%d1
 8774	and.l		&0x7FFFFFFF,%d1
 8775	bne.b		continue
 8776
 8777#--X = 2^k.
 8778	mov.w		(%a0),%d1
 8779	and.l		&0x00007FFF,%d1
 8780	sub.l		&0x3FFF,%d1
 8781	beq.l		ld_pzero
 8782	fmov.l		%d0,%fpcr
 8783	fmov.l		%d1,%fp0
 8784	bra		t_inx2
 8785
 8786continue:
 8787	mov.l		%d0,-(%sp)
 8788	clr.l		%d0
 8789	bsr		slogn			# log(X), X normal.
 8790	fmov.l		(%sp)+,%fpcr
 8791	fmul.x		INV_L2(%pc),%fp0
 8792	bra		t_inx2
 8793
 8794invalid:
 8795	bra		t_operr
 8796
 8797	global		slog2d
 8798#--entry point for Log2(X), X is denormalized
 8799slog2d:
 8800	mov.l		(%a0),%d1
 8801	blt.w		invalid
 8802	mov.l		%d0,-(%sp)
 8803	clr.l		%d0
 8804	bsr		slognd			# log(X), X denorm.
 8805	fmov.l		(%sp)+,%fpcr
 8806	fmul.x		INV_L2(%pc),%fp0
 8807	bra		t_minx2
 8808
 8809#########################################################################
 8810# stwotox():  computes 2**X for a normalized input			#
 8811# stwotoxd(): computes 2**X for a denormalized input			#
 8812# stentox():  computes 10**X for a normalized input			#
 8813# stentoxd(): computes 10**X for a denormalized input			#
 8814#									#
 8815# INPUT ***************************************************************	#
 8816#	a0 = pointer to extended precision input			#
 8817#	d0 = round precision,mode					#
 8818#									#
 8819# OUTPUT **************************************************************	#
 8820#	fp0 = 2**X or 10**X						#
 8821#									#
 8822# ACCURACY and MONOTONICITY *******************************************	#
 8823#	The returned result is within 2 ulps in 64 significant bit,	#
 8824#	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
 8825#	rounded to double precision. The result is provably monotonic	#
 8826#	in double precision.						#
 8827#									#
 8828# ALGORITHM ***********************************************************	#
 8829#									#
 8830#	twotox								#
 8831#	1. If |X| > 16480, go to ExpBig.				#
 8832#									#
 8833#	2. If |X| < 2**(-70), go to ExpSm.				#
 8834#									#
 8835#	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
 8836#		decompose N as						#
 8837#		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
 8838#									#
 8839#	4. Overwrite r := r * log2. Then				#
 8840#		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
 8841#		Go to expr to compute that expression.			#
 8842#									#
 8843#	tentox								#
 8844#	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
 8845#									#
 8846#	2. If |X| < 2**(-70), go to ExpSm.				#
 8847#									#
 8848#	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
 8849#		N := round-to-int(y). Decompose N as			#
 8850#		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
 8851#									#
 8852#	4. Define r as							#
 8853#		r := ((X - N*L1)-N*L2) * L10				#
 8854#		where L1, L2 are the leading and trailing parts of	#
 8855#		log_10(2)/64 and L10 is the natural log of 10. Then	#
 8856#		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
 8857#		Go to expr to compute that expression.			#
 8858#									#
 8859#	expr								#
 8860#	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
 8861#									#
 8862#	2. Overwrite Fact1 and Fact2 by					#
 8863#		Fact1 := 2**(M) * Fact1					#
 8864#		Fact2 := 2**(M) * Fact2					#
 8865#		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
 8866#									#
 8867#	3. Calculate P where 1 + P approximates exp(r):			#
 8868#		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
 8869#									#
 8870#	4. Let AdjFact := 2**(M'). Return				#
 8871#		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
 8872#		Exit.							#
 8873#									#
 8874#	ExpBig								#
 8875#	1. Generate overflow by Huge * Huge if X > 0; otherwise,	#
 8876#	        generate underflow by Tiny * Tiny.			#
 8877#									#
 8878#	ExpSm								#
 8879#	1. Return 1 + X.						#
 8880#									#
 8881#########################################################################
 8882
 8883L2TEN64:
 8884	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
 8885L10TWO1:
 8886	long		0x3F734413,0x509F8000	# LOG2/64LOG10
 8887
 8888L10TWO2:
 8889	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
 8890
 8891LOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
 8892
 8893LOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
 8894
 8895EXPA5:	long		0x3F56C16D,0x6F7BD0B2
 8896EXPA4:	long		0x3F811112,0x302C712C
 8897EXPA3:	long		0x3FA55555,0x55554CC1
 8898EXPA2:	long		0x3FC55555,0x55554A54
 8899EXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
 8900
 8901TEXPTBL:
 8902	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
 8903	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
 8904	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
 8905	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
 8906	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
 8907	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
 8908	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
 8909	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
 8910	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
 8911	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
 8912	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
 8913	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
 8914	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
 8915	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
 8916	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
 8917	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
 8918	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
 8919	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
 8920	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
 8921	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
 8922	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
 8923	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
 8924	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
 8925	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
 8926	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
 8927	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
 8928	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
 8929	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
 8930	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
 8931	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
 8932	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
 8933	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
 8934	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
 8935	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
 8936	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
 8937	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
 8938	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
 8939	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
 8940	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
 8941	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
 8942	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
 8943	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
 8944	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
 8945	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
 8946	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
 8947	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
 8948	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
 8949	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
 8950	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
 8951	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
 8952	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
 8953	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
 8954	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
 8955	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
 8956	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
 8957	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
 8958	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
 8959	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
 8960	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
 8961	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
 8962	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
 8963	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
 8964	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
 8965	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
 8966
 8967	set		INT,L_SCR1
 8968
 8969	set		X,FP_SCR0
 8970	set		XDCARE,X+2
 8971	set		XFRAC,X+4
 8972
 8973	set		ADJFACT,FP_SCR0
 8974
 8975	set		FACT1,FP_SCR0
 8976	set		FACT1HI,FACT1+4
 8977	set		FACT1LOW,FACT1+8
 8978
 8979	set		FACT2,FP_SCR1
 8980	set		FACT2HI,FACT2+4
 8981	set		FACT2LOW,FACT2+8
 8982
 8983	global		stwotox
 8984#--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
 8985stwotox:
 8986	fmovm.x		(%a0),&0x80		# LOAD INPUT
 8987
 8988	mov.l		(%a0),%d1
 8989	mov.w		4(%a0),%d1
 8990	fmov.x		%fp0,X(%a6)
 8991	and.l		&0x7FFFFFFF,%d1
 8992
 8993	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
 8994	bge.b		TWOOK1
 8995	bra.w		EXPBORS
 8996
 8997TWOOK1:
 8998	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
 8999	ble.b		TWOMAIN
 9000	bra.w		EXPBORS
 9001
 9002TWOMAIN:
 9003#--USUAL CASE, 2^(-70) <= |X| <= 16480
 9004
 9005	fmov.x		%fp0,%fp1
 9006	fmul.s		&0x42800000,%fp1	# 64 * X
 9007	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
 9008	mov.l		%d2,-(%sp)
 9009	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
 9010	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
 9011	mov.l		INT(%a6),%d1
 9012	mov.l		%d1,%d2
 9013	and.l		&0x3F,%d1		# D0 IS J
 9014	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
 9015	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
 9016	asr.l		&6,%d2			# d2 IS L, N = 64L + J
 9017	mov.l		%d2,%d1
 9018	asr.l		&1,%d1			# D0 IS M
 9019	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
 9020	add.l		&0x3FFF,%d2
 9021
 9022#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
 9023#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
 9024#--ADJFACT = 2^(M').
 9025#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
 9026
 9027	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
 9028
 9029	fmul.s		&0x3C800000,%fp1	# (1/64)*N
 9030	mov.l		(%a1)+,FACT1(%a6)
 9031	mov.l		(%a1)+,FACT1HI(%a6)
 9032	mov.l		(%a1)+,FACT1LOW(%a6)
 9033	mov.w		(%a1)+,FACT2(%a6)
 9034
 9035	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
 9036
 9037	mov.w		(%a1)+,FACT2HI(%a6)
 9038	clr.w		FACT2HI+2(%a6)
 9039	clr.l		FACT2LOW(%a6)
 9040	add.w		%d1,FACT1(%a6)
 9041	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
 9042	add.w		%d1,FACT2(%a6)
 9043
 9044	bra.w		expr
 9045
 9046EXPBORS:
 9047#--FPCR, D0 SAVED
 9048	cmp.l		%d1,&0x3FFF8000
 9049	bgt.b		TEXPBIG
 9050
 9051#--|X| IS SMALL, RETURN 1 + X
 9052
 9053	fmov.l		%d0,%fpcr		# restore users round prec,mode
 9054	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
 9055	bra		t_pinx2
 9056
 9057TEXPBIG:
 9058#--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
 9059#--REGISTERS SAVE SO FAR ARE FPCR AND  D0
 9060	mov.l		X(%a6),%d1
 9061	cmp.l		%d1,&0
 9062	blt.b		EXPNEG
 9063
 9064	bra		t_ovfl2			# t_ovfl expects positive value
 9065
 9066EXPNEG:
 9067	bra		t_unfl2			# t_unfl expects positive value
 9068
 9069	global		stwotoxd
 9070stwotoxd:
 9071#--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
 9072
 9073	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
 9074	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
 9075	mov.l		(%a0),%d1
 9076	or.l		&0x00800001,%d1
 9077	fadd.s		%d1,%fp0
 9078	bra		t_pinx2
 9079
 9080	global		stentox
 9081#--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
 9082stentox:
 9083	fmovm.x		(%a0),&0x80		# LOAD INPUT
 9084
 9085	mov.l		(%a0),%d1
 9086	mov.w		4(%a0),%d1
 9087	fmov.x		%fp0,X(%a6)
 9088	and.l		&0x7FFFFFFF,%d1
 9089
 9090	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
 9091	bge.b		TENOK1
 9092	bra.w		EXPBORS
 9093
 9094TENOK1:
 9095	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
 9096	ble.b		TENMAIN
 9097	bra.w		EXPBORS
 9098
 9099TENMAIN:
 9100#--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
 9101
 9102	fmov.x		%fp0,%fp1
 9103	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
 9104	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
 9105	mov.l		%d2,-(%sp)
 9106	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
 9107	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
 9108	mov.l		INT(%a6),%d1
 9109	mov.l		%d1,%d2
 9110	and.l		&0x3F,%d1		# D0 IS J
 9111	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
 9112	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
 9113	asr.l		&6,%d2			# d2 IS L, N = 64L + J
 9114	mov.l		%d2,%d1
 9115	asr.l		&1,%d1			# D0 IS M
 9116	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
 9117	add.l		&0x3FFF,%d2
 9118
 9119#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
 9120#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
 9121#--ADJFACT = 2^(M').
 9122#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
 9123	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
 9124
 9125	fmov.x		%fp1,%fp2
 9126
 9127	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
 9128	mov.l		(%a1)+,FACT1(%a6)
 9129
 9130	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
 9131
 9132	mov.l		(%a1)+,FACT1HI(%a6)
 9133	mov.l		(%a1)+,FACT1LOW(%a6)
 9134	fsub.x		%fp1,%fp0		# X - N L_LEAD
 9135	mov.w		(%a1)+,FACT2(%a6)
 9136
 9137	fsub.x		%fp2,%fp0		# X - N L_TRAIL
 9138
 9139	mov.w		(%a1)+,FACT2HI(%a6)
 9140	clr.w		FACT2HI+2(%a6)
 9141	clr.l		FACT2LOW(%a6)
 9142
 9143	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
 9144	add.w		%d1,FACT1(%a6)
 9145	add.w		%d1,FACT2(%a6)
 9146
 9147expr:
 9148#--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
 9149#--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
 9150#--FP0 IS R. THE FOLLOWING CODE COMPUTES
 9151#--	2**(M'+M) * 2**(J/64) * EXP(R)
 9152
 9153	fmov.x		%fp0,%fp1
 9154	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
 9155
 9156	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
 9157	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
 9158
 9159	fmul.x		%fp1,%fp2		# FP2 IS S*A5
 9160	fmul.x		%fp1,%fp3		# FP3 IS S*A4
 9161
 9162	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
 9163	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
 9164
 9165	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
 9166	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
 9167
 9168	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
 9169	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
 9170
 9171	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
 9172	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
 9173	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
 9174
 9175	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
 9176
 9177#--FINAL RECONSTRUCTION PROCESS
 9178#--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
 9179
 9180	fmul.x		FACT1(%a6),%fp0
 9181	fadd.x		FACT2(%a6),%fp0
 9182	fadd.x		FACT1(%a6),%fp0
 9183
 9184	fmov.l		%d0,%fpcr		# restore users round prec,mode
 9185	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
 9186	mov.l		(%sp)+,%d2
 9187	mov.l		&0x80000000,ADJFACT+4(%a6)
 9188	clr.l		ADJFACT+8(%a6)
 9189	mov.b		&FMUL_OP,%d1		# last inst is MUL
 9190	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
 9191	bra		t_catch
 9192
 9193	global		stentoxd
 9194stentoxd:
 9195#--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
 9196
 9197	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
 9198	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
 9199	mov.l		(%a0),%d1
 9200	or.l		&0x00800001,%d1
 9201	fadd.s		%d1,%fp0
 9202	bra		t_pinx2
 9203
 9204#########################################################################
 9205# sscale(): computes the destination operand scaled by the source	#
 9206#	    operand. If the absoulute value of the source operand is	#
 9207#	    >= 2^14, an overflow or underflow is returned.		#
 9208#									#
 9209# INPUT *************************************************************** #
 9210#	a0  = pointer to double-extended source operand X		#
 9211#	a1  = pointer to double-extended destination operand Y		#
 9212#									#
 9213# OUTPUT ************************************************************** #
 9214#	fp0 =  scale(X,Y)						#
 9215#									#
 9216#########################################################################
 9217
 9218set	SIGN,		L_SCR1
 9219
 9220	global		sscale
 9221sscale:
 9222	mov.l		%d0,-(%sp)		# store off ctrl bits for now
 9223
 9224	mov.w		DST_EX(%a1),%d1		# get dst exponent
 9225	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
 9226	andi.l		&0x00007fff,%d1		# strip sign from dst exp
 9227
 9228	mov.w		SRC_EX(%a0),%d0		# check src bounds
 9229	andi.w		&0x7fff,%d0		# clr src sign bit
 9230	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
 9231	blt.w		src_small		# yes
 9232	cmpi.w		%d0,&0x400c		# no; is src too big?
 9233	bgt.w		src_out			# yes
 9234
 9235#
 9236# Source is within 2^14 range.
 9237#
 9238src_ok:
 9239	fintrz.x	SRC(%a0),%fp0		# calc int of src
 9240	fmov.l		%fp0,%d0		# int src to d0
 9241# don't want any accrued bits from the fintrz showing up later since
 9242# we may need to read the fpsr for the last fp op in t_catch2().
 9243	fmov.l		&0x0,%fpsr
 9244
 9245	tst.b		DST_HI(%a1)		# is dst denormalized?
 9246	bmi.b		sok_norm
 9247
 9248# the dst is a DENORM. normalize the DENORM and add the adjustment to
 9249# the src value. then, jump to the norm part of the routine.
 9250sok_dnrm:
 9251	mov.l		%d0,-(%sp)		# save src for now
 9252
 9253	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
 9254	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
 9255	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
 9256
 9257	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
 9258	bsr.l		norm			# normalize the DENORM
 9259	neg.l		%d0
 9260	add.l		(%sp)+,%d0		# add adjustment to src
 9261
 9262	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
 9263
 9264	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
 9265	bge.b		sok_norm2		# thank goodness no
 9266
 9267# the multiply factor that we're trying to create should be a denorm
 9268# for the multiply to work. therefore, we're going to actually do a
 9269# multiply with a denorm which will cause an unimplemented data type
 9270# exception to be put into the machine which will be caught and corrected
 9271# later. we don't do this with the DENORMs above because this method
 9272# is slower. but, don't fret, I don't see it being used much either.
 9273	fmov.l		(%sp)+,%fpcr		# restore user fpcr
 9274	mov.l		&0x80000000,%d1		# load normalized mantissa
 9275	subi.l		&-0x3fff,%d0		# how many should we shift?
 9276	neg.l		%d0			# make it positive
 9277	cmpi.b		%d0,&0x20		# is it > 32?
 9278	bge.b		sok_dnrm_32		# yes
 9279	lsr.l		%d0,%d1			# no; bit stays in upper lw
 9280	clr.l		-(%sp)			# insert zero low mantissa
 9281	mov.l		%d1,-(%sp)		# insert new high mantissa
 9282	clr.l		-(%sp)			# make zero exponent
 9283	bra.b		sok_norm_cont
 9284sok_dnrm_32:
 9285	subi.b		&0x20,%d0		# get shift count
 9286	lsr.l		%d0,%d1			# make low mantissa longword
 9287	mov.l		%d1,-(%sp)		# insert new low mantissa
 9288	clr.l		-(%sp)			# insert zero high mantissa
 9289	clr.l		-(%sp)			# make zero exponent
 9290	bra.b		sok_norm_cont
 9291
 9292# the src will force the dst to a DENORM value or worse. so, let's
 9293# create an fp multiply that will create the result.
 9294sok_norm:
 9295	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
 9296sok_norm2:
 9297	fmov.l		(%sp)+,%fpcr		# restore user fpcr
 9298
 9299	addi.w		&0x3fff,%d0		# turn src amt into exp value
 9300	swap		%d0			# put exponent in high word
 9301	clr.l		-(%sp)			# insert new exponent
 9302	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
 9303	mov.l		%d0,-(%sp)		# insert new lo mantissa
 9304
 9305sok_norm_cont:
 9306	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
 9307	mov.b		&FMUL_OP,%d1		# last inst is MUL
 9308	fmul.x		(%sp)+,%fp0		# do the multiply
 9309	bra		t_catch2		# catch any exceptions
 9310
 9311#
 9312# Source is outside of 2^14 range.  Test the sign and branch
 9313# to the appropriate exception handler.
 9314#
 9315src_out:
 9316	mov.l		(%sp)+,%d0		# restore ctrl bits
 9317	exg		%a0,%a1			# swap src,dst ptrs
 9318	tst.b		SRC_EX(%a1)		# is src negative?
 9319	bmi		t_unfl			# yes; underflow
 9320	bra		t_ovfl_sc		# no; overflow
 9321
 9322#
 9323# The source input is below 1, so we check for denormalized numbers
 9324# and set unfl.
 9325#
 9326src_small:
 9327	tst.b		DST_HI(%a1)		# is dst denormalized?
 9328	bpl.b		ssmall_done		# yes
 9329
 9330	mov.l		(%sp)+,%d0
 9331	fmov.l		%d0,%fpcr		# no; load control bits
 9332	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 9333	fmov.x		DST(%a1),%fp0		# simply return dest
 9334	bra		t_catch2
 9335ssmall_done:
 9336	mov.l		(%sp)+,%d0		# load control bits into d1
 9337	mov.l		%a1,%a0			# pass ptr to dst
 9338	bra		t_resdnrm
 9339
 9340#########################################################################
 9341# smod(): computes the fp MOD of the input values X,Y.			#
 9342# srem(): computes the fp (IEEE) REM of the input values X,Y.		#
 9343#									#
 9344# INPUT *************************************************************** #
 9345#	a0 = pointer to extended precision input X			#
 9346#	a1 = pointer to extended precision input Y			#
 9347#	d0 = round precision,mode					#
 9348#									#
 9349#	The input operands X and Y can be either normalized or		#
 9350#	denormalized.							#
 9351#									#
 9352# OUTPUT ************************************************************** #
 9353#      fp0 = FREM(X,Y) or FMOD(X,Y)					#
 9354#									#
 9355# ALGORITHM *********************************************************** #
 9356#									#
 9357#       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
 9358#                signY := sign(Y), X := |X|, Y := |Y|,			#
 9359#                signQ := signX EOR signY. Record whether MOD or REM	#
 9360#                is requested.						#
 9361#									#
 9362#       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
 9363#                If (L < 0) then					#
 9364#                   R := X, go to Step 4.				#
 9365#                else							#
 9366#                   R := 2^(-L)X, j := L.				#
 9367#                endif							#
 9368#									#
 9369#       Step 3.  Perform MOD(X,Y)					#
 9370#            3.1 If R = Y, go to Step 9.				#
 9371#            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
 9372#            3.3 If j = 0, go to Step 4.				#
 9373#            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
 9374#                Step 3.1.						#
 9375#									#
 9376#       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
 9377#                Last_Subtract := false (used in Step 7 below). If	#
 9378#                MOD is requested, go to Step 6.			#
 9379#									#
 9380#       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
 9381#            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
 9382#                Step 6.						#
 9383#            5.2 If R > Y/2, then { set Last_Subtract := true,		#
 9384#                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
 9385#            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
 9386#                then { Q := Q + 1, signX := -signX }.			#
 9387#									#
 9388#       Step 6.  R := signX*R.						#
 9389#									#
 9390#       Step 7.  If Last_Subtract = true, R := R - Y.			#
 9391#									#
 9392#       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
 9393#									#
 9394#       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
 9395#                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
 9396#                R := 0. Return signQ, last 7 bits of Q, and R.		#
 9397#									#
 9398#########################################################################
 9399
 9400	set		Mod_Flag,L_SCR3
 9401	set		Sc_Flag,L_SCR3+1
 9402
 9403	set		SignY,L_SCR2
 9404	set		SignX,L_SCR2+2
 9405	set		SignQ,L_SCR3+2
 9406
 9407	set		Y,FP_SCR0
 9408	set		Y_Hi,Y+4
 9409	set		Y_Lo,Y+8
 9410
 9411	set		R,FP_SCR1
 9412	set		R_Hi,R+4
 9413	set		R_Lo,R+8
 9414
 9415Scale:
 9416	long		0x00010000,0x80000000,0x00000000,0x00000000
 9417
 9418	global		smod
 9419smod:
 9420	clr.b		FPSR_QBYTE(%a6)
 9421	mov.l		%d0,-(%sp)		# save ctrl bits
 9422	clr.b		Mod_Flag(%a6)
 9423	bra.b		Mod_Rem
 9424
 9425	global		srem
 9426srem:
 9427	clr.b		FPSR_QBYTE(%a6)
 9428	mov.l		%d0,-(%sp)		# save ctrl bits
 9429	mov.b		&0x1,Mod_Flag(%a6)
 9430
 9431Mod_Rem:
 9432#..Save sign of X and Y
 9433	movm.l		&0x3f00,-(%sp)		# save data registers
 9434	mov.w		SRC_EX(%a0),%d3
 9435	mov.w		%d3,SignY(%a6)
 9436	and.l		&0x00007FFF,%d3		# Y := |Y|
 9437
 9438#
 9439	mov.l		SRC_HI(%a0),%d4
 9440	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
 9441
 9442	tst.l		%d3
 9443	bne.b		Y_Normal
 9444
 9445	mov.l		&0x00003FFE,%d3		# $3FFD + 1
 9446	tst.l		%d4
 9447	bne.b		HiY_not0
 9448
 9449HiY_0:
 9450	mov.l		%d5,%d4
 9451	clr.l		%d5
 9452	sub.l		&32,%d3
 9453	clr.l		%d6
 9454	bfffo		%d4{&0:&32},%d6
 9455	lsl.l		%d6,%d4
 9456	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
 9457#	                                        ...with bias $7FFD
 9458	bra.b		Chk_X
 9459
 9460HiY_not0:
 9461	clr.l		%d6
 9462	bfffo		%d4{&0:&32},%d6
 9463	sub.l		%d6,%d3
 9464	lsl.l		%d6,%d4
 9465	mov.l		%d5,%d7			# a copy of D5
 9466	lsl.l		%d6,%d5
 9467	neg.l		%d6
 9468	add.l		&32,%d6
 9469	lsr.l		%d6,%d7
 9470	or.l		%d7,%d4			# (D3,D4,D5) normalized
 9471#                                       ...with bias $7FFD
 9472	bra.b		Chk_X
 9473
 9474Y_Normal:
 9475	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
 9476#                                       ...with bias $7FFD
 9477
 9478Chk_X:
 9479	mov.w		DST_EX(%a1),%d0
 9480	mov.w		%d0,SignX(%a6)
 9481	mov.w		SignY(%a6),%d1
 9482	eor.l		%d0,%d1
 9483	and.l		&0x00008000,%d1
 9484	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
 9485	and.l		&0x00007FFF,%d0
 9486	mov.l		DST_HI(%a1),%d1
 9487	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
 9488	tst.l		%d0
 9489	bne.b		X_Normal
 9490	mov.l		&0x00003FFE,%d0
 9491	tst.l		%d1
 9492	bne.b		HiX_not0
 9493
 9494HiX_0:
 9495	mov.l		%d2,%d1
 9496	clr.l		%d2
 9497	sub.l		&32,%d0
 9498	clr.l		%d6
 9499	bfffo		%d1{&0:&32},%d6
 9500	lsl.l		%d6,%d1
 9501	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
 9502#                                       ...with bias $7FFD
 9503	bra.b		Init
 9504
 9505HiX_not0:
 9506	clr.l		%d6
 9507	bfffo		%d1{&0:&32},%d6
 9508	sub.l		%d6,%d0
 9509	lsl.l		%d6,%d1
 9510	mov.l		%d2,%d7			# a copy of D2
 9511	lsl.l		%d6,%d2
 9512	neg.l		%d6
 9513	add.l		&32,%d6
 9514	lsr.l		%d6,%d7
 9515	or.l		%d7,%d1			# (D0,D1,D2) normalized
 9516#                                       ...with bias $7FFD
 9517	bra.b		Init
 9518
 9519X_Normal:
 9520	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
 9521#                                       ...with bias $7FFD
 9522
 9523Init:
 9524#
 9525	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
 9526	mov.l		%d0,-(%sp)		# save biased exp(X)
 9527	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
 9528
 9529	clr.l		%d6			# D6 := carry <- 0
 9530	clr.l		%d3			# D3 is Q
 9531	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
 9532
 9533#..(Carry,D1,D2) is R
 9534	tst.l		%d0
 9535	bge.b		Mod_Loop_pre
 9536
 9537#..expo(X) < expo(Y). Thus X = mod(X,Y)
 9538#
 9539	mov.l		(%sp)+,%d0		# restore d0
 9540	bra.w		Get_Mod
 9541
 9542Mod_Loop_pre:
 9543	addq.l		&0x4,%sp		# erase exp(X)
 9544#..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
 9545Mod_Loop:
 9546	tst.l		%d6			# test carry bit
 9547	bgt.b		R_GT_Y
 9548
 9549#..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
 9550	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
 9551	bne.b		R_NE_Y
 9552	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
 9553	bne.b		R_NE_Y
 9554
 9555#..At this point, R = Y
 9556	bra.w		Rem_is_0
 9557
 9558R_NE_Y:
 9559#..use the borrow of the previous compare
 9560	bcs.b		R_LT_Y			# borrow is set iff R < Y
 9561
 9562R_GT_Y:
 9563#..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
 9564#..and Y < (D1,D2) < 2Y. Either way, perform R - Y
 9565	sub.l		%d5,%d2			# lo(R) - lo(Y)
 9566	subx.l		%d4,%d1			# hi(R) - hi(Y)
 9567	clr.l		%d6			# clear carry
 9568	addq.l		&1,%d3			# Q := Q + 1
 9569
 9570R_LT_Y:
 9571#..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
 9572	tst.l		%d0			# see if j = 0.
 9573	beq.b		PostLoop
 9574
 9575	add.l		%d3,%d3			# Q := 2Q
 9576	add.l		%d2,%d2			# lo(R) = 2lo(R)
 9577	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
 9578	scs		%d6			# set Carry if 2(R) overflows
 9579	addq.l		&1,%a1			# k := k+1
 9580	subq.l		&1,%d0			# j := j - 1
 9581#..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
 9582
 9583	bra.b		Mod_Loop
 9584
 9585PostLoop:
 9586#..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
 9587
 9588#..normalize R.
 9589	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
 9590	tst.l		%d1
 9591	bne.b		HiR_not0
 9592
 9593HiR_0:
 9594	mov.l		%d2,%d1
 9595	clr.l		%d2
 9596	sub.l		&32,%d0
 9597	clr.l		%d6
 9598	bfffo		%d1{&0:&32},%d6
 9599	lsl.l		%d6,%d1
 9600	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
 9601#                                       ...with bias $7FFD
 9602	bra.b		Get_Mod
 9603
 9604HiR_not0:
 9605	clr.l		%d6
 9606	bfffo		%d1{&0:&32},%d6
 9607	bmi.b		Get_Mod			# already normalized
 9608	sub.l		%d6,%d0
 9609	lsl.l		%d6,%d1
 9610	mov.l		%d2,%d7			# a copy of D2
 9611	lsl.l		%d6,%d2
 9612	neg.l		%d6
 9613	add.l		&32,%d6
 9614	lsr.l		%d6,%d7
 9615	or.l		%d7,%d1			# (D0,D1,D2) normalized
 9616
 9617#
 9618Get_Mod:
 9619	cmp.l		%d0,&0x000041FE
 9620	bge.b		No_Scale
 9621Do_Scale:
 9622	mov.w		%d0,R(%a6)
 9623	mov.l		%d1,R_Hi(%a6)
 9624	mov.l		%d2,R_Lo(%a6)
 9625	mov.l		L_SCR1(%a6),%d6
 9626	mov.w		%d6,Y(%a6)
 9627	mov.l		%d4,Y_Hi(%a6)
 9628	mov.l		%d5,Y_Lo(%a6)
 9629	fmov.x		R(%a6),%fp0		# no exception
 9630	mov.b		&1,Sc_Flag(%a6)
 9631	bra.b		ModOrRem
 9632No_Scale:
 9633	mov.l		%d1,R_Hi(%a6)
 9634	mov.l		%d2,R_Lo(%a6)
 9635	sub.l		&0x3FFE,%d0
 9636	mov.w		%d0,R(%a6)
 9637	mov.l		L_SCR1(%a6),%d6
 9638	sub.l		&0x3FFE,%d6
 9639	mov.l		%d6,L_SCR1(%a6)
 9640	fmov.x		R(%a6),%fp0
 9641	mov.w		%d6,Y(%a6)
 9642	mov.l		%d4,Y_Hi(%a6)
 9643	mov.l		%d5,Y_Lo(%a6)
 9644	clr.b		Sc_Flag(%a6)
 9645
 9646#
 9647ModOrRem:
 9648	tst.b		Mod_Flag(%a6)
 9649	beq.b		Fix_Sign
 9650
 9651	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
 9652	subq.l		&1,%d6			# biased expo(Y/2)
 9653	cmp.l		%d0,%d6
 9654	blt.b		Fix_Sign
 9655	bgt.b		Last_Sub
 9656
 9657	cmp.l		%d1,%d4
 9658	bne.b		Not_EQ
 9659	cmp.l		%d2,%d5
 9660	bne.b		Not_EQ
 9661	bra.w		Tie_Case
 9662
 9663Not_EQ:
 9664	bcs.b		Fix_Sign
 9665
 9666Last_Sub:
 9667#
 9668	fsub.x		Y(%a6),%fp0		# no exceptions
 9669	addq.l		&1,%d3			# Q := Q + 1
 9670
 9671#
 9672Fix_Sign:
 9673#..Get sign of X
 9674	mov.w		SignX(%a6),%d6
 9675	bge.b		Get_Q
 9676	fneg.x		%fp0
 9677
 9678#..Get Q
 9679#
 9680Get_Q:
 9681	clr.l		%d6
 9682	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
 9683	mov.l		&8,%d7
 9684	lsr.l		%d7,%d6
 9685	and.l		&0x0000007F,%d3		# 7 bits of Q
 9686	or.l		%d6,%d3			# sign and bits of Q
 9687#	swap		%d3
 9688#	fmov.l		%fpsr,%d6
 9689#	and.l		&0xFF00FFFF,%d6
 9690#	or.l		%d3,%d6
 9691#	fmov.l		%d6,%fpsr		# put Q in fpsr
 9692	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
 9693
 9694#
 9695Restore:
 9696	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
 9697	mov.l		(%sp)+,%d0
 9698	fmov.l		%d0,%fpcr
 9699	tst.b		Sc_Flag(%a6)
 9700	beq.b		Finish
 9701	mov.b		&FMUL_OP,%d1		# last inst is MUL
 9702	fmul.x		Scale(%pc),%fp0		# may cause underflow
 9703	bra		t_catch2
 9704# the '040 package did this apparently to see if the dst operand for the
 9705# preceding fmul was a denorm. but, it better not have been since the
 9706# algorithm just got done playing with fp0 and expected no exceptions
 9707# as a result. trust me...
 9708#	bra		t_avoid_unsupp		# check for denorm as a
 9709#						;result of the scaling
 9710
 9711Finish:
 9712	mov.b		&FMOV_OP,%d1		# last inst is MOVE
 9713	fmov.x		%fp0,%fp0		# capture exceptions & round
 9714	bra		t_catch2
 9715
 9716Rem_is_0:
 9717#..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
 9718	addq.l		&1,%d3
 9719	cmp.l		%d0,&8			# D0 is j
 9720	bge.b		Q_Big
 9721
 9722	lsl.l		%d0,%d3
 9723	bra.b		Set_R_0
 9724
 9725Q_Big:
 9726	clr.l		%d3
 9727
 9728Set_R_0:
 9729	fmov.s		&0x00000000,%fp0
 9730	clr.b		Sc_Flag(%a6)
 9731	bra.w		Fix_Sign
 9732
 9733Tie_Case:
 9734#..Check parity of Q
 9735	mov.l		%d3,%d6
 9736	and.l		&0x00000001,%d6
 9737	tst.l		%d6
 9738	beq.w		Fix_Sign		# Q is even
 9739
 9740#..Q is odd, Q := Q + 1, signX := -signX
 9741	addq.l		&1,%d3
 9742	mov.w		SignX(%a6),%d6
 9743	eor.l		&0x00008000,%d6
 9744	mov.w		%d6,SignX(%a6)
 9745	bra.w		Fix_Sign
 9746
 9747#########################################################################
 9748# XDEF ****************************************************************	#
 9749#	tag(): return the optype of the input ext fp number		#
 9750#									#
 9751#	This routine is used by the 060FPLSP.				#
 9752#									#
 9753# XREF ****************************************************************	#
 9754#	None								#
 9755#									#
 9756# INPUT ***************************************************************	#
 9757#	a0 = pointer to extended precision operand			#
 9758#									#
 9759# OUTPUT **************************************************************	#
 9760#	d0 = value of type tag						#
 9761#		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
 9762#									#
 9763# ALGORITHM ***********************************************************	#
 9764#	Simply test the exponent, j-bit, and mantissa values to		#
 9765# determine the type of operand.					#
 9766#	If it's an unnormalized zero, alter the operand and force it	#
 9767# to be a normal zero.							#
 9768#									#
 9769#########################################################################
 9770
 9771	global		tag
 9772tag:
 9773	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
 9774	andi.w		&0x7fff, %d0		# strip off sign
 9775	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
 9776	beq.b		inf_or_nan_x
 9777not_inf_or_nan_x:
 9778	btst		&0x7,FTEMP_HI(%a0)
 9779	beq.b		not_norm_x
 9780is_norm_x:
 9781	mov.b		&NORM, %d0
 9782	rts
 9783not_norm_x:
 9784	tst.w		%d0			# is exponent = 0?
 9785	bne.b		is_unnorm_x
 9786not_unnorm_x:
 9787	tst.l		FTEMP_HI(%a0)
 9788	bne.b		is_denorm_x
 9789	tst.l		FTEMP_LO(%a0)
 9790	bne.b		is_denorm_x
 9791is_zero_x:
 9792	mov.b		&ZERO, %d0
 9793	rts
 9794is_denorm_x:
 9795	mov.b		&DENORM, %d0
 9796	rts
 9797is_unnorm_x:
 9798	bsr.l		unnorm_fix		# convert to norm,denorm,or zero
 9799	rts
 9800is_unnorm_reg_x:
 9801	mov.b		&UNNORM, %d0
 9802	rts
 9803inf_or_nan_x:
 9804	tst.l		FTEMP_LO(%a0)
 9805	bne.b		is_nan_x
 9806	mov.l		FTEMP_HI(%a0), %d0
 9807	and.l		&0x7fffffff, %d0	# msb is a don't care!
 9808	bne.b		is_nan_x
 9809is_inf_x:
 9810	mov.b		&INF, %d0
 9811	rts
 9812is_nan_x:
 9813	mov.b		&QNAN, %d0
 9814	rts
 9815
 9816#############################################################
 9817
 9818qnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
 9819
 9820#########################################################################
 9821# XDEF ****************************************************************	#
 9822#	t_dz(): Handle 060FPLSP dz exception for "flogn" emulation.	#
 9823#	t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation.	#
 9824#									#
 9825#	These rouitnes are used by the 060FPLSP package.		#
 9826#									#
 9827# XREF ****************************************************************	#
 9828#	None								#
 9829#									#
 9830# INPUT ***************************************************************	#
 9831#	a0 = pointer to extended precision source operand.		#
 9832#									#
 9833# OUTPUT **************************************************************	#
 9834#	fp0 = default DZ result.					#
 9835#									#
 9836# ALGORITHM ***********************************************************	#
 9837#	Transcendental emulation for the 060FPLSP has detected that	#
 9838# a DZ exception should occur for the instruction. If DZ is disabled,	#
 9839# return the default result.						#
 9840#	If DZ is enabled, the dst operand should be returned unscathed	#
 9841# in fp0 while fp1 is used to create a DZ exception so that the		#
 9842# operating system can log that such an event occurred.			#
 9843#									#
 9844#########################################################################
 9845
 9846	global		t_dz
 9847t_dz:
 9848	tst.b		SRC_EX(%a0)		# check sign for neg or pos
 9849	bpl.b		dz_pinf			# branch if pos sign
 9850
 9851	global		t_dz2
 9852t_dz2:
 9853	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
 9854
 9855	btst		&dz_bit,FPCR_ENABLE(%a6)
 9856	bne.b		dz_minf_ena
 9857
 9858# dz is disabled. return a -INF.
 9859	fmov.s		&0xff800000,%fp0	# return -INF
 9860	rts
 9861
 9862# dz is enabled. create a dz exception so the user can record it
 9863# but use fp1 instead. return the dst operand unscathed in fp0.
 9864dz_minf_ena:
 9865	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
 9866	fmov.l		USER_FPCR(%a6),%fpcr
 9867	fmov.s		&0xbf800000,%fp1	# load -1
 9868	fdiv.s		&0x00000000,%fp1	# -1 / 0
 9869	rts
 9870
 9871dz_pinf:
 9872	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
 9873
 9874	btst		&dz_bit,FPCR_ENABLE(%a6)
 9875	bne.b		dz_pinf_ena
 9876
 9877# dz is disabled. return a +INF.
 9878	fmov.s		&0x7f800000,%fp0	# return +INF
 9879	rts
 9880
 9881# dz is enabled. create a dz exception so the user can record it
 9882# but use fp1 instead. return the dst operand unscathed in fp0.
 9883dz_pinf_ena:
 9884	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
 9885	fmov.l		USER_FPCR(%a6),%fpcr
 9886	fmov.s		&0x3f800000,%fp1	# load +1
 9887	fdiv.s		&0x00000000,%fp1	# +1 / 0
 9888	rts
 9889
 9890#########################################################################
 9891# XDEF ****************************************************************	#
 9892#	t_operr(): Handle 060FPLSP OPERR exception during emulation.	#
 9893#									#
 9894#	This routine is used by the 060FPLSP package.			#
 9895#									#
 9896# XREF ****************************************************************	#
 9897#	None.								#
 9898#									#
 9899# INPUT ***************************************************************	#
 9900#	fp1 = source operand						#
 9901#									#
 9902# OUTPUT **************************************************************	#
 9903#	fp0 = default result						#
 9904#	fp1 = unchanged							#
 9905#									#
 9906# ALGORITHM ***********************************************************	#
 9907#	An operand error should occur as the result of transcendental	#
 9908# emulation in the 060FPLSP. If OPERR is disabled, just return a NAN	#
 9909# in fp0. If OPERR is enabled, return the dst operand unscathed in fp0	#
 9910# and the source operand in fp1. Use fp2 to create an OPERR exception	#
 9911# so that the operating system can log the event.			#
 9912#									#
 9913#########################################################################
 9914
 9915	global		t_operr
 9916t_operr:
 9917	ori.l		&opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
 9918
 9919	btst		&operr_bit,FPCR_ENABLE(%a6)
 9920	bne.b		operr_ena
 9921
 9922# operr is disabled. return a QNAN in fp0
 9923	fmovm.x		qnan(%pc),&0x80		# return QNAN
 9924	rts
 9925
 9926# operr is enabled. create an operr exception so the user can record it
 9927# but use fp2 instead. return the dst operand unscathed in fp0.
 9928operr_ena:
 9929	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
 9930	fmov.l		USER_FPCR(%a6),%fpcr
 9931	fmovm.x		&0x04,-(%sp)		# save fp2
 9932	fmov.s		&0x7f800000,%fp2	# load +INF
 9933	fmul.s		&0x00000000,%fp2	# +INF x 0
 9934	fmovm.x		(%sp)+,&0x20		# restore fp2
 9935	rts
 9936
 9937pls_huge:
 9938	long		0x7ffe0000,0xffffffff,0xffffffff
 9939mns_huge:
 9940	long		0xfffe0000,0xffffffff,0xffffffff
 9941pls_tiny:
 9942	long		0x00000000,0x80000000,0x00000000
 9943mns_tiny:
 9944	long		0x80000000,0x80000000,0x00000000
 9945
 9946#########################################################################
 9947# XDEF ****************************************************************	#
 9948#	t_unfl(): Handle 060FPLSP underflow exception during emulation.	#
 9949#	t_unfl2(): Handle 060FPLSP underflow exception during		#
 9950#	           emulation. result always positive.			#
 9951#									#
 9952#	This routine is used by the 060FPLSP package.			#
 9953#									#
 9954# XREF ****************************************************************	#
 9955#	None.								#
 9956#									#
 9957# INPUT ***************************************************************	#
 9958#	a0 = pointer to extended precision source operand		#
 9959#									#
 9960# OUTPUT **************************************************************	#
 9961#	fp0 = default underflow result					#
 9962#									#
 9963# ALGORITHM ***********************************************************	#
 9964#	An underflow should occur as the result of transcendental	#
 9965# emulation in the 060FPLSP. Create an underflow by using "fmul"	#
 9966# and two very small numbers of appropriate sign so the operating	#
 9967# system can log the event.						#
 9968#									#
 9969#########################################################################
 9970
 9971	global		t_unfl
 9972t_unfl:
 9973	tst.b		SRC_EX(%a0)
 9974	bpl.b		unf_pos
 9975
 9976	global		t_unfl2
 9977t_unfl2:
 9978	ori.l		&unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
 9979
 9980	fmov.l		USER_FPCR(%a6),%fpcr
 9981	fmovm.x		mns_tiny(%pc),&0x80
 9982	fmul.x		pls_tiny(%pc),%fp0
 9983
 9984	fmov.l		%fpsr,%d0
 9985	rol.l		&0x8,%d0
 9986	mov.b		%d0,FPSR_CC(%a6)
 9987	rts
 9988unf_pos:
 9989	ori.w		&unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
 9990
 9991	fmov.l		USER_FPCR(%a6),%fpcr
 9992	fmovm.x		pls_tiny(%pc),&0x80
 9993	fmul.x		%fp0,%fp0
 9994
 9995	fmov.l		%fpsr,%d0
 9996	rol.l		&0x8,%d0
 9997	mov.b		%d0,FPSR_CC(%a6)
 9998	rts
 9999
10000#########################################################################
10001# XDEF ****************************************************************	#
10002#	t_ovfl(): Handle 060FPLSP overflow exception during emulation.	#
10003#		  (monadic)						#
10004#	t_ovfl2(): Handle 060FPLSP overflow exception during		#
10005#	           emulation. result always positive. (dyadic)		#
10006#	t_ovfl_sc(): Handle 060FPLSP overflow exception during		#
10007#	             emulation for "fscale".				#
10008#									#
10009#	This routine is used by the 060FPLSP package.			#
10010#									#
10011# XREF ****************************************************************	#
10012#	None.								#
10013#									#
10014# INPUT ***************************************************************	#
10015#	a0 = pointer to extended precision source operand		#
10016#									#
10017# OUTPUT **************************************************************	#
10018#	fp0 = default underflow result					#
10019#									#
10020# ALGORITHM ***********************************************************	#
10021#	An overflow should occur as the result of transcendental	#
10022# emulation in the 060FPLSP. Create an overflow by using "fmul"		#
10023# and two very lareg numbers of appropriate sign so the operating	#
10024# system can log the event.						#
10025#	For t_ovfl_sc() we take special care not to lose the INEX2 bit.	#
10026#									#
10027#########################################################################
10028
10029	global		t_ovfl_sc
10030t_ovfl_sc:
10031	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
10032
10033	mov.b		%d0,%d1			# fetch rnd prec,mode
10034	andi.b		&0xc0,%d1		# extract prec
10035	beq.w		ovfl_work
10036
10037# dst op is a DENORM. we have to normalize the mantissa to see if the
10038# result would be inexact for the given precision. make a copy of the
10039# dst so we don't screw up the version passed to us.
10040	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
10041	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
10042	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
10043	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
10044	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
10045	bsr.l		norm			# normalize mantissa
10046	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
10047
10048	cmpi.b		%d1,&0x40		# is precision sgl?
10049	bne.b		ovfl_sc_dbl		# no; dbl
10050ovfl_sc_sgl:
10051	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
10052	bne.b		ovfl_sc_inx		# yes
10053	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
10054	bne.b		ovfl_sc_inx		# yes
10055	bra.w		ovfl_work		# don't set INEX2
10056ovfl_sc_dbl:
10057	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
10058	andi.l		&0x7ff,%d1		# dbl mantissa set?
10059	beq.w		ovfl_work		# no; don't set INEX2
10060ovfl_sc_inx:
10061	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
10062	bra.b		ovfl_work		# continue
10063
10064	global		t_ovfl
10065t_ovfl:
10066	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
10067ovfl_work:
10068	tst.b		SRC_EX(%a0)
10069	bpl.b		ovfl_p
10070ovfl_m:
10071	fmov.l		USER_FPCR(%a6),%fpcr
10072	fmovm.x		mns_huge(%pc),&0x80
10073	fmul.x		pls_huge(%pc),%fp0
10074
10075	fmov.l		%fpsr,%d0
10076	rol.l		&0x8,%d0
10077	ori.b		&neg_mask,%d0
10078	mov.b		%d0,FPSR_CC(%a6)
10079	rts
10080ovfl_p:
10081	fmov.l		USER_FPCR(%a6),%fpcr
10082	fmovm.x		pls_huge(%pc),&0x80
10083	fmul.x		pls_huge(%pc),%fp0
10084
10085	fmov.l		%fpsr,%d0
10086	rol.l		&0x8,%d0
10087	mov.b		%d0,FPSR_CC(%a6)
10088	rts
10089
10090	global		t_ovfl2
10091t_ovfl2:
10092	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
10093	fmov.l		USER_FPCR(%a6),%fpcr
10094	fmovm.x		pls_huge(%pc),&0x80
10095	fmul.x		pls_huge(%pc),%fp0
10096
10097	fmov.l		%fpsr,%d0
10098	rol.l		&0x8,%d0
10099	mov.b		%d0,FPSR_CC(%a6)
10100	rts
10101
10102#########################################################################
10103# XDEF ****************************************************************	#
10104#	t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
10105#		   emulation.						#
10106#	t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
10107#		    emulation.						#
10108#									#
10109#	These routines are used by the 060FPLSP package.		#
10110#									#
10111# XREF ****************************************************************	#
10112#	None.								#
10113#									#
10114# INPUT ***************************************************************	#
10115#	fp0 = default underflow or overflow result			#
10116#									#
10117# OUTPUT **************************************************************	#
10118#	fp0 = default result						#
10119#									#
10120# ALGORITHM ***********************************************************	#
10121#	If an overflow or underflow occurred during the last		#
10122# instruction of transcendental 060FPLSP emulation, then it has already	#
10123# occurred and has been logged. Now we need to see if an inexact	#
10124# exception should occur.						#
10125#									#
10126#########################################################################
10127
10128	global		t_catch2
10129t_catch2:
10130	fmov.l		%fpsr,%d0
10131	or.l		%d0,USER_FPSR(%a6)
10132	bra.b		inx2_work
10133
10134	global		t_catch
10135t_catch:
10136	fmov.l		%fpsr,%d0
10137	or.l		%d0,USER_FPSR(%a6)
10138
10139#########################################################################
10140# XDEF ****************************************************************	#
10141#	t_inx2(): Handle inexact 060FPLSP exception during emulation.	#
10142#	t_pinx2(): Handle inexact 060FPLSP exception for "+" results.	#
10143#	t_minx2(): Handle inexact 060FPLSP exception for "-" results.	#
10144#									#
10145# XREF ****************************************************************	#
10146#	None.								#
10147#									#
10148# INPUT ***************************************************************	#
10149#	fp0 = default result						#
10150#									#
10151# OUTPUT **************************************************************	#
10152#	fp0 = default result						#
10153#									#
10154# ALGORITHM ***********************************************************	#
10155#	The last instruction of transcendental emulation for the	#
10156# 060FPLSP should be inexact. So, if inexact is enabled, then we create	#
10157# the event here by adding a large and very small number together	#
10158# so that the operating system can log the event.			#
10159#	Must check, too, if the result was zero, in which case we just	#
10160# set the FPSR bits and return.						#
10161#									#
10162#########################################################################
10163
10164	global		t_inx2
10165t_inx2:
10166	fblt.w		t_minx2
10167	fbeq.w		inx2_zero
10168
10169	global		t_pinx2
10170t_pinx2:
10171	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
10172	bra.b		inx2_work
10173
10174	global		t_minx2
10175t_minx2:
10176	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6)
10177
10178inx2_work:
10179	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
10180	bne.b		inx2_work_ena		# yes
10181	rts
10182inx2_work_ena:
10183	fmov.l		USER_FPCR(%a6),%fpcr	# insert user's exceptions
10184	fmov.s		&0x3f800000,%fp1	# load +1
10185	fadd.x		pls_tiny(%pc),%fp1	# cause exception
10186	rts
10187
10188inx2_zero:
10189	mov.b		&z_bmask,FPSR_CC(%a6)
10190	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
10191	rts
10192
10193#########################################################################
10194# XDEF ****************************************************************	#
10195#	t_extdnrm(): Handle DENORM inputs in 060FPLSP.			#
10196#	t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale".	#
10197#									#
10198#	This routine is used by the 060FPLSP package.			#
10199#									#
10200# XREF ****************************************************************	#
10201#	None.								#
10202#									#
10203# INPUT ***************************************************************	#
10204#	a0 = pointer to extended precision input operand		#
10205#									#
10206# OUTPUT **************************************************************	#
10207#	fp0 = default result						#
10208#									#
10209# ALGORITHM ***********************************************************	#
10210#	For all functions that have a denormalized input and that	#
10211# f(x)=x, this is the entry point.					#
10212#	DENORM value is moved using "fmove" which triggers an exception	#
10213# if enabled so the operating system can log the event.			#
10214#									#
10215#########################################################################
10216
10217	global		t_extdnrm
10218t_extdnrm:
10219	fmov.l		USER_FPCR(%a6),%fpcr
10220	fmov.x		SRC_EX(%a0),%fp0
10221	fmov.l		%fpsr,%d0
10222	ori.l		&unfinx_mask,%d0
10223	or.l		%d0,USER_FPSR(%a6)
10224	rts
10225
10226	global		t_resdnrm
10227t_resdnrm:
10228	fmov.l		USER_FPCR(%a6),%fpcr
10229	fmov.x		SRC_EX(%a0),%fp0
10230	fmov.l		%fpsr,%d0
10231	or.l		%d0,USER_FPSR(%a6)
10232	rts
10233
10234##########################################
10235
10236#
10237# sto_cos:
10238#	This is used by fsincos library emulation. The correct
10239# values are already in fp0 and fp1 so we do nothing here.
10240#
10241	global		sto_cos
10242sto_cos:
10243	rts
10244
10245##########################################
10246
10247#
10248#	dst_qnan --- force result when destination is a NaN
10249#
10250	global		dst_qnan
10251dst_qnan:
10252	fmov.x		DST(%a1),%fp0
10253	tst.b		DST_EX(%a1)
10254	bmi.b		dst_qnan_m
10255dst_qnan_p:
10256	mov.b		&nan_bmask,FPSR_CC(%a6)
10257	rts
10258dst_qnan_m:
10259	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
10260	rts
10261
10262#
10263#	src_qnan --- force result when source is a NaN
10264#
10265	global		src_qnan
10266src_qnan:
10267	fmov.x		SRC(%a0),%fp0
10268	tst.b		SRC_EX(%a0)
10269	bmi.b		src_qnan_m
10270src_qnan_p:
10271	mov.b		&nan_bmask,FPSR_CC(%a6)
10272	rts
10273src_qnan_m:
10274	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
10275	rts
10276
10277##########################################
10278
10279#
10280#	Native instruction support
10281#
10282#	Some systems may need entry points even for 68060 native
10283#	instructions.  These routines are provided for
10284#	convenience.
10285#
10286	global		_fadds_
10287_fadds_:
10288	fmov.l		%fpcr,-(%sp)		# save fpcr
10289	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10290	fmov.s		0x8(%sp),%fp0		# load sgl dst
10291	fmov.l		(%sp)+,%fpcr		# restore fpcr
10292	fadd.s		0x8(%sp),%fp0		# fadd w/ sgl src
10293	rts
10294
10295	global		_faddd_
10296_faddd_:
10297	fmov.l		%fpcr,-(%sp)		# save fpcr
10298	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10299	fmov.d		0x8(%sp),%fp0		# load dbl dst
10300	fmov.l		(%sp)+,%fpcr		# restore fpcr
10301	fadd.d		0xc(%sp),%fp0		# fadd w/ dbl src
10302	rts
10303
10304	global		_faddx_
10305_faddx_:
10306	fmovm.x		0x4(%sp),&0x80		# load ext dst
10307	fadd.x		0x10(%sp),%fp0		# fadd w/ ext src
10308	rts
10309
10310	global		_fsubs_
10311_fsubs_:
10312	fmov.l		%fpcr,-(%sp)		# save fpcr
10313	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10314	fmov.s		0x8(%sp),%fp0		# load sgl dst
10315	fmov.l		(%sp)+,%fpcr		# restore fpcr
10316	fsub.s		0x8(%sp),%fp0		# fsub w/ sgl src
10317	rts
10318
10319	global		_fsubd_
10320_fsubd_:
10321	fmov.l		%fpcr,-(%sp)		# save fpcr
10322	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10323	fmov.d		0x8(%sp),%fp0		# load dbl dst
10324	fmov.l		(%sp)+,%fpcr		# restore fpcr
10325	fsub.d		0xc(%sp),%fp0		# fsub w/ dbl src
10326	rts
10327
10328	global		_fsubx_
10329_fsubx_:
10330	fmovm.x		0x4(%sp),&0x80		# load ext dst
10331	fsub.x		0x10(%sp),%fp0		# fsub w/ ext src
10332	rts
10333
10334	global		_fmuls_
10335_fmuls_:
10336	fmov.l		%fpcr,-(%sp)		# save fpcr
10337	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10338	fmov.s		0x8(%sp),%fp0		# load sgl dst
10339	fmov.l		(%sp)+,%fpcr		# restore fpcr
10340	fmul.s		0x8(%sp),%fp0		# fmul w/ sgl src
10341	rts
10342
10343	global		_fmuld_
10344_fmuld_:
10345	fmov.l		%fpcr,-(%sp)		# save fpcr
10346	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10347	fmov.d		0x8(%sp),%fp0		# load dbl dst
10348	fmov.l		(%sp)+,%fpcr		# restore fpcr
10349	fmul.d		0xc(%sp),%fp0		# fmul w/ dbl src
10350	rts
10351
10352	global		_fmulx_
10353_fmulx_:
10354	fmovm.x		0x4(%sp),&0x80		# load ext dst
10355	fmul.x		0x10(%sp),%fp0		# fmul w/ ext src
10356	rts
10357
10358	global		_fdivs_
10359_fdivs_:
10360	fmov.l		%fpcr,-(%sp)		# save fpcr
10361	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10362	fmov.s		0x8(%sp),%fp0		# load sgl dst
10363	fmov.l		(%sp)+,%fpcr		# restore fpcr
10364	fdiv.s		0x8(%sp),%fp0		# fdiv w/ sgl src
10365	rts
10366
10367	global		_fdivd_
10368_fdivd_:
10369	fmov.l		%fpcr,-(%sp)		# save fpcr
10370	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
10371	fmov.d		0x8(%sp),%fp0		# load dbl dst
10372	fmov.l		(%sp)+,%fpcr		# restore fpcr
10373	fdiv.d		0xc(%sp),%fp0		# fdiv w/ dbl src
10374	rts
10375
10376	global		_fdivx_
10377_fdivx_:
10378	fmovm.x		0x4(%sp),&0x80		# load ext dst
10379	fdiv.x		0x10(%sp),%fp0		# fdiv w/ ext src
10380	rts
10381
10382	global		_fabss_
10383_fabss_:
10384	fabs.s		0x4(%sp),%fp0		# fabs w/ sgl src
10385	rts
10386
10387	global		_fabsd_
10388_fabsd_:
10389	fabs.d		0x4(%sp),%fp0		# fabs w/ dbl src
10390	rts
10391
10392	global		_fabsx_
10393_fabsx_:
10394	fabs.x		0x4(%sp),%fp0		# fabs w/ ext src
10395	rts
10396
10397	global		_fnegs_
10398_fnegs_:
10399	fneg.s		0x4(%sp),%fp0		# fneg w/ sgl src
10400	rts
10401
10402	global		_fnegd_
10403_fnegd_:
10404	fneg.d		0x4(%sp),%fp0		# fneg w/ dbl src
10405	rts
10406
10407	global		_fnegx_
10408_fnegx_:
10409	fneg.x		0x4(%sp),%fp0		# fneg w/ ext src
10410	rts
10411
10412	global		_fsqrts_
10413_fsqrts_:
10414	fsqrt.s		0x4(%sp),%fp0		# fsqrt w/ sgl src
10415	rts
10416
10417	global		_fsqrtd_
10418_fsqrtd_:
10419	fsqrt.d		0x4(%sp),%fp0		# fsqrt w/ dbl src
10420	rts
10421
10422	global		_fsqrtx_
10423_fsqrtx_:
10424	fsqrt.x		0x4(%sp),%fp0		# fsqrt w/ ext src
10425	rts
10426
10427	global		_fints_
10428_fints_:
10429	fint.s		0x4(%sp),%fp0		# fint w/ sgl src
10430	rts
10431
10432	global		_fintd_
10433_fintd_:
10434	fint.d		0x4(%sp),%fp0		# fint w/ dbl src
10435	rts
10436
10437	global		_fintx_
10438_fintx_:
10439	fint.x		0x4(%sp),%fp0		# fint w/ ext src
10440	rts
10441
10442	global		_fintrzs_
10443_fintrzs_:
10444	fintrz.s	0x4(%sp),%fp0		# fintrz w/ sgl src
10445	rts
10446
10447	global		_fintrzd_
10448_fintrzd_:
10449	fintrz.d	0x4(%sp),%fp0		# fintrx w/ dbl src
10450	rts
10451
10452	global		_fintrzx_
10453_fintrzx_:
10454	fintrz.x	0x4(%sp),%fp0		# fintrz w/ ext src
10455	rts
10456
10457########################################################################
10458
10459#########################################################################
10460# src_zero(): Return signed zero according to sign of src operand.	#
10461#########################################################################
10462	global		src_zero
10463src_zero:
10464	tst.b		SRC_EX(%a0)		# get sign of src operand
10465	bmi.b		ld_mzero		# if neg, load neg zero
10466
10467#
10468# ld_pzero(): return a positive zero.
10469#
10470	global		ld_pzero
10471ld_pzero:
10472	fmov.s		&0x00000000,%fp0	# load +0
10473	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
10474	rts
10475
10476# ld_mzero(): return a negative zero.
10477	global		ld_mzero
10478ld_mzero:
10479	fmov.s		&0x80000000,%fp0	# load -0
10480	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
10481	rts
10482
10483#########################################################################
10484# dst_zero(): Return signed zero according to sign of dst operand.	#
10485#########################################################################
10486	global		dst_zero
10487dst_zero:
10488	tst.b		DST_EX(%a1)		# get sign of dst operand
10489	bmi.b		ld_mzero		# if neg, load neg zero
10490	bra.b		ld_pzero		# load positive zero
10491
10492#########################################################################
10493# src_inf(): Return signed inf according to sign of src operand.	#
10494#########################################################################
10495	global		src_inf
10496src_inf:
10497	tst.b		SRC_EX(%a0)		# get sign of src operand
10498	bmi.b		ld_minf			# if negative branch
10499
10500#
10501# ld_pinf(): return a positive infinity.
10502#
10503	global		ld_pinf
10504ld_pinf:
10505	fmov.s		&0x7f800000,%fp0	# load +INF
10506	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
10507	rts
10508
10509#
10510# ld_minf():return a negative infinity.
10511#
10512	global		ld_minf
10513ld_minf:
10514	fmov.s		&0xff800000,%fp0	# load -INF
10515	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
10516	rts
10517
10518#########################################################################
10519# dst_inf(): Return signed inf according to sign of dst operand.	#
10520#########################################################################
10521	global		dst_inf
10522dst_inf:
10523	tst.b		DST_EX(%a1)		# get sign of dst operand
10524	bmi.b		ld_minf			# if negative branch
10525	bra.b		ld_pinf
10526
10527	global		szr_inf
10528#################################################################
10529# szr_inf(): Return +ZERO for a negative src operand or		#
10530#	            +INF for a positive src operand.		#
10531#	     Routine used for fetox, ftwotox, and ftentox.	#
10532#################################################################
10533szr_inf:
10534	tst.b		SRC_EX(%a0)		# check sign of source
10535	bmi.b		ld_pzero
10536	bra.b		ld_pinf
10537
10538#########################################################################
10539# sopr_inf(): Return +INF for a positive src operand or			#
10540#	      jump to operand error routine for a negative src operand.	#
10541#	      Routine used for flogn, flognp1, flog10, and flog2.	#
10542#########################################################################
10543	global		sopr_inf
10544sopr_inf:
10545	tst.b		SRC_EX(%a0)		# check sign of source
10546	bmi.w		t_operr
10547	bra.b		ld_pinf
10548
10549#################################################################
10550# setoxm1i(): Return minus one for a negative src operand or	#
10551#	      positive infinity for a positive src operand.	#
10552#	      Routine used for fetoxm1.				#
10553#################################################################
10554	global		setoxm1i
10555setoxm1i:
10556	tst.b		SRC_EX(%a0)		# check sign of source
10557	bmi.b		ld_mone
10558	bra.b		ld_pinf
10559
10560#########################################################################
10561# src_one(): Return signed one according to sign of src operand.	#
10562#########################################################################
10563	global		src_one
10564src_one:
10565	tst.b		SRC_EX(%a0)		# check sign of source
10566	bmi.b		ld_mone
10567
10568#
10569# ld_pone(): return positive one.
10570#
10571	global		ld_pone
10572ld_pone:
10573	fmov.s		&0x3f800000,%fp0	# load +1
10574	clr.b		FPSR_CC(%a6)
10575	rts
10576
10577#
10578# ld_mone(): return negative one.
10579#
10580	global		ld_mone
10581ld_mone:
10582	fmov.s		&0xbf800000,%fp0	# load -1
10583	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
10584	rts
10585
10586ppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
10587mpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
10588
10589#################################################################
10590# spi_2(): Return signed PI/2 according to sign of src operand.	#
10591#################################################################
10592	global		spi_2
10593spi_2:
10594	tst.b		SRC_EX(%a0)		# check sign of source
10595	bmi.b		ld_mpi2
10596
10597#
10598# ld_ppi2(): return positive PI/2.
10599#
10600	global		ld_ppi2
10601ld_ppi2:
10602	fmov.l		%d0,%fpcr
10603	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
10604	bra.w		t_pinx2			# set INEX2
10605
10606#
10607# ld_mpi2(): return negative PI/2.
10608#
10609	global		ld_mpi2
10610ld_mpi2:
10611	fmov.l		%d0,%fpcr
10612	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
10613	bra.w		t_minx2			# set INEX2
10614
10615####################################################
10616# The following routines give support for fsincos. #
10617####################################################
10618
10619#
10620# ssincosz(): When the src operand is ZERO, store a one in the
10621#	      cosine register and return a ZERO in fp0 w/ the same sign
10622#	      as the src operand.
10623#
10624	global		ssincosz
10625ssincosz:
10626	fmov.s		&0x3f800000,%fp1
10627	tst.b		SRC_EX(%a0)		# test sign
10628	bpl.b		sincoszp
10629	fmov.s		&0x80000000,%fp0	# return sin result in fp0
10630	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
10631	rts
10632sincoszp:
10633	fmov.s		&0x00000000,%fp0	# return sin result in fp0
10634	mov.b		&z_bmask,FPSR_CC(%a6)
10635	rts
10636
10637#
10638# ssincosi(): When the src operand is INF, store a QNAN in the cosine
10639#	      register and jump to the operand error routine for negative
10640#	      src operands.
10641#
10642	global		ssincosi
10643ssincosi:
10644	fmov.x		qnan(%pc),%fp1		# load NAN
10645	bra.w		t_operr
10646
10647#
10648# ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
10649#		 register and branch to the src QNAN routine.
10650#
10651	global		ssincosqnan
10652ssincosqnan:
10653	fmov.x		LOCAL_EX(%a0),%fp1
10654	bra.w		src_qnan
10655
10656########################################################################
10657
10658	global		smod_sdnrm
10659	global		smod_snorm
10660smod_sdnrm:
10661smod_snorm:
10662	mov.b		DTAG(%a6),%d1
10663	beq.l		smod
10664	cmpi.b		%d1,&ZERO
10665	beq.w		smod_zro
10666	cmpi.b		%d1,&INF
10667	beq.l		t_operr
10668	cmpi.b		%d1,&DENORM
10669	beq.l		smod
10670	bra.l		dst_qnan
10671
10672	global		smod_szero
10673smod_szero:
10674	mov.b		DTAG(%a6),%d1
10675	beq.l		t_operr
10676	cmpi.b		%d1,&ZERO
10677	beq.l		t_operr
10678	cmpi.b		%d1,&INF
10679	beq.l		t_operr
10680	cmpi.b		%d1,&DENORM
10681	beq.l		t_operr
10682	bra.l		dst_qnan
10683
10684	global		smod_sinf
10685smod_sinf:
10686	mov.b		DTAG(%a6),%d1
10687	beq.l		smod_fpn
10688	cmpi.b		%d1,&ZERO
10689	beq.l		smod_zro
10690	cmpi.b		%d1,&INF
10691	beq.l		t_operr
10692	cmpi.b		%d1,&DENORM
10693	beq.l		smod_fpn
10694	bra.l		dst_qnan
10695
10696smod_zro:
10697srem_zro:
10698	mov.b		SRC_EX(%a0),%d1		# get src sign
10699	mov.b		DST_EX(%a1),%d0		# get dst sign
10700	eor.b		%d0,%d1			# get qbyte sign
10701	andi.b		&0x80,%d1
10702	mov.b		%d1,FPSR_QBYTE(%a6)
10703	tst.b		%d0
10704	bpl.w		ld_pzero
10705	bra.w		ld_mzero
10706
10707smod_fpn:
10708srem_fpn:
10709	clr.b		FPSR_QBYTE(%a6)
10710	mov.l		%d0,-(%sp)
10711	mov.b		SRC_EX(%a0),%d1		# get src sign
10712	mov.b		DST_EX(%a1),%d0		# get dst sign
10713	eor.b		%d0,%d1			# get qbyte sign
10714	andi.b		&0x80,%d1
10715	mov.b		%d1,FPSR_QBYTE(%a6)
10716	cmpi.b		DTAG(%a6),&DENORM
10717	bne.b		smod_nrm
10718	lea		DST(%a1),%a0
10719	mov.l		(%sp)+,%d0
10720	bra		t_resdnrm
10721smod_nrm:
10722	fmov.l		(%sp)+,%fpcr
10723	fmov.x		DST(%a1),%fp0
10724	tst.b		DST_EX(%a1)
10725	bmi.b		smod_nrm_neg
10726	rts
10727
10728smod_nrm_neg:
10729	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' code
10730	rts
10731
10732#########################################################################
10733	global		srem_snorm
10734	global		srem_sdnrm
10735srem_sdnrm:
10736srem_snorm:
10737	mov.b		DTAG(%a6),%d1
10738	beq.l		srem
10739	cmpi.b		%d1,&ZERO
10740	beq.w		srem_zro
10741	cmpi.b		%d1,&INF
10742	beq.l		t_operr
10743	cmpi.b		%d1,&DENORM
10744	beq.l		srem
10745	bra.l		dst_qnan
10746
10747	global		srem_szero
10748srem_szero:
10749	mov.b		DTAG(%a6),%d1
10750	beq.l		t_operr
10751	cmpi.b		%d1,&ZERO
10752	beq.l		t_operr
10753	cmpi.b		%d1,&INF
10754	beq.l		t_operr
10755	cmpi.b		%d1,&DENORM
10756	beq.l		t_operr
10757	bra.l		dst_qnan
10758
10759	global		srem_sinf
10760srem_sinf:
10761	mov.b		DTAG(%a6),%d1
10762	beq.w		srem_fpn
10763	cmpi.b		%d1,&ZERO
10764	beq.w		srem_zro
10765	cmpi.b		%d1,&INF
10766	beq.l		t_operr
10767	cmpi.b		%d1,&DENORM
10768	beq.l		srem_fpn
10769	bra.l		dst_qnan
10770
10771#########################################################################
10772
10773	global		sscale_snorm
10774	global		sscale_sdnrm
10775sscale_snorm:
10776sscale_sdnrm:
10777	mov.b		DTAG(%a6),%d1
10778	beq.l		sscale
10779	cmpi.b		%d1,&ZERO
10780	beq.l		dst_zero
10781	cmpi.b		%d1,&INF
10782	beq.l		dst_inf
10783	cmpi.b		%d1,&DENORM
10784	beq.l		sscale
10785	bra.l		dst_qnan
10786
10787	global		sscale_szero
10788sscale_szero:
10789	mov.b		DTAG(%a6),%d1
10790	beq.l		sscale
10791	cmpi.b		%d1,&ZERO
10792	beq.l		dst_zero
10793	cmpi.b		%d1,&INF
10794	beq.l		dst_inf
10795	cmpi.b		%d1,&DENORM
10796	beq.l		sscale
10797	bra.l		dst_qnan
10798
10799	global		sscale_sinf
10800sscale_sinf:
10801	mov.b		DTAG(%a6),%d1
10802	beq.l		t_operr
10803	cmpi.b		%d1,&QNAN
10804	beq.l		dst_qnan
10805	bra.l		t_operr
10806
10807########################################################################
10808
10809	global		sop_sqnan
10810sop_sqnan:
10811	mov.b		DTAG(%a6),%d1
10812	cmpi.b		%d1,&QNAN
10813	beq.l		dst_qnan
10814	bra.l		src_qnan
10815
10816#########################################################################
10817# norm(): normalize the mantissa of an extended precision input. the	#
10818#	  input operand should not be normalized already.		#
10819#									#
10820# XDEF ****************************************************************	#
10821#	norm()								#
10822#									#
10823# XREF **************************************************************** #
10824#	none								#
10825#									#
10826# INPUT *************************************************************** #
10827#	a0 = pointer fp extended precision operand to normalize		#
10828#									#
10829# OUTPUT ************************************************************** #
10830#	d0 = number of bit positions the mantissa was shifted		#
10831#	a0 = the input operand's mantissa is normalized; the exponent	#
10832#	     is unchanged.						#
10833#									#
10834#########################################################################
10835	global		norm
10836norm:
10837	mov.l		%d2, -(%sp)		# create some temp regs
10838	mov.l		%d3, -(%sp)
10839
10840	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
10841	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
10842
10843	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
10844	beq.b		norm_lo			# hi(man) is all zeroes!
10845
10846norm_hi:
10847	lsl.l		%d2, %d0		# left shift hi(man)
10848	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
10849
10850	or.l		%d3, %d0		# create hi(man)
10851	lsl.l		%d2, %d1		# create lo(man)
10852
10853	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
10854	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
10855
10856	mov.l		%d2, %d0		# return shift amount
10857
10858	mov.l		(%sp)+, %d3		# restore temp regs
10859	mov.l		(%sp)+, %d2
10860
10861	rts
10862
10863norm_lo:
10864	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
10865	lsl.l		%d2, %d1		# shift lo(man)
10866	add.l		&32, %d2		# add 32 to shft amount
10867
10868	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
10869	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
10870
10871	mov.l		%d2, %d0		# return shift amount
10872
10873	mov.l		(%sp)+, %d3		# restore temp regs
10874	mov.l		(%sp)+, %d2
10875
10876	rts
10877
10878#########################################################################
10879# unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
10880#		- returns corresponding optype tag			#
10881#									#
10882# XDEF ****************************************************************	#
10883#	unnorm_fix()							#
10884#									#
10885# XREF **************************************************************** #
10886#	norm() - normalize the mantissa					#
10887#									#
10888# INPUT *************************************************************** #
10889#	a0 = pointer to unnormalized extended precision number		#
10890#									#
10891# OUTPUT ************************************************************** #
10892#	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
10893#	a0 = input operand has been converted to a norm, denorm, or	#
10894#	     zero; both the exponent and mantissa are changed.		#
10895#									#
10896#########################################################################
10897
10898	global		unnorm_fix
10899unnorm_fix:
10900	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
10901	bne.b		unnorm_shift		# hi(man) is not all zeroes
10902
10903#
10904# hi(man) is all zeroes so see if any bits in lo(man) are set
10905#
10906unnorm_chk_lo:
10907	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
10908	beq.w		unnorm_zero		# yes
10909
10910	add.w		&32, %d0		# no; fix shift distance
10911
10912#
10913# d0 = # shifts needed for complete normalization
10914#
10915unnorm_shift:
10916	clr.l		%d1			# clear top word
10917	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
10918	and.w		&0x7fff, %d1		# strip off sgn
10919
10920	cmp.w		%d0, %d1		# will denorm push exp < 0?
10921	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
10922
10923#
10924# exponent would not go < 0. therefore, number stays normalized
10925#
10926	sub.w		%d0, %d1		# shift exponent value
10927	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
10928	and.w		&0x8000, %d0		# save old sign
10929	or.w		%d0, %d1		# {sgn,new exp}
10930	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
10931
10932	bsr.l		norm			# normalize UNNORM
10933
10934	mov.b		&NORM, %d0		# return new optype tag
10935	rts
10936
10937#
10938# exponent would go < 0, so only denormalize until exp = 0
10939#
10940unnorm_nrm_zero:
10941	cmp.b		%d1, &32		# is exp <= 32?
10942	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
10943
10944	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
10945	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
10946
10947	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
10948	lsl.l		%d1, %d0		# extract new lo(man)
10949	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
10950
10951	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
10952
10953	mov.b		&DENORM, %d0		# return new optype tag
10954	rts
10955
10956#
10957# only mantissa bits set are in lo(man)
10958#
10959unnorm_nrm_zero_lrg:
10960	sub.w		&32, %d1		# adjust shft amt by 32
10961
10962	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
10963	lsl.l		%d1, %d0		# left shift lo(man)
10964
10965	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
10966	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
10967
10968	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
10969
10970	mov.b		&DENORM, %d0		# return new optype tag
10971	rts
10972
10973#
10974# whole mantissa is zero so this UNNORM is actually a zero
10975#
10976unnorm_zero:
10977	and.w		&0x8000, FTEMP_EX(%a0)	# force exponent to zero
10978
10979	mov.b		&ZERO, %d0		# fix optype tag
10980	rts
~/ Read-only file preview.