Home | History | Annotate | Line # | Download | only in dist
fplsp.s revision 1.1
      1 #
      2 # $NetBSD: fplsp.s,v 1.1 2000/04/14 20:24:37 is Exp $
      3 #
      4 
      5 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      6 # MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      7 # M68000 Hi-Performance Microprocessor Division
      8 # M68060 Software Package Production Release
      9 #
     10 # M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc.
     11 # All rights reserved.
     12 #
     13 # THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     14 # To the maximum extent permitted by applicable law,
     15 # MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     16 # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
     17 # FOR A PARTICULAR PURPOSE and any warranty against infringement with
     18 # regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     19 # and any accompanying written materials.
     20 #
     21 # To the maximum extent permitted by applicable law,
     22 # IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     23 # (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
     24 # BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
     25 # ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
     26 #
     27 # Motorola assumes no responsibility for the maintenance and support
     28 # of the SOFTWARE.
     29 #
     30 # You are hereby granted a copyright license to use, modify, and distribute the
     31 # SOFTWARE so long as this entire notice is retained without alteration
     32 # in any modified and/or redistributed versions, and that such modified
     33 # versions are clearly identified as such.
     34 # No licenses are granted by implication, estoppel or otherwise under any
     35 # patents or trademarks of Motorola, Inc.
     36 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     37 
     38 #
     39 # lfptop.s:
     40 #	This file is appended to the top of the 060ILSP package
     41 # and contains the entry points into the package. The user, in
     42 # effect, branches to one of the branch table entries located here.
     43 #
     44 
     45 	bra.l	_facoss_
     46 	short	0x0000
     47 	bra.l	_facosd_
     48 	short	0x0000
     49 	bra.l	_facosx_
     50 	short	0x0000
     51 
     52 	bra.l	_fasins_
     53 	short	0x0000
     54 	bra.l	_fasind_
     55 	short	0x0000
     56 	bra.l	_fasinx_
     57 	short	0x0000
     58 
     59 	bra.l	_fatans_
     60 	short	0x0000
     61 	bra.l	_fatand_
     62 	short	0x0000
     63 	bra.l	_fatanx_
     64 	short	0x0000
     65 
     66 	bra.l	_fatanhs_
     67 	short	0x0000
     68 	bra.l	_fatanhd_
     69 	short	0x0000
     70 	bra.l	_fatanhx_
     71 	short	0x0000
     72 
     73 	bra.l	_fcoss_
     74 	short	0x0000
     75 	bra.l	_fcosd_
     76 	short	0x0000
     77 	bra.l	_fcosx_
     78 	short	0x0000
     79 
     80 	bra.l	_fcoshs_
     81 	short	0x0000
     82 	bra.l	_fcoshd_
     83 	short	0x0000
     84 	bra.l	_fcoshx_
     85 	short	0x0000
     86 
     87 	bra.l	_fetoxs_
     88 	short	0x0000
     89 	bra.l	_fetoxd_
     90 	short	0x0000
     91 	bra.l	_fetoxx_
     92 	short	0x0000
     93 
     94 	bra.l	_fetoxm1s_
     95 	short	0x0000
     96 	bra.l	_fetoxm1d_
     97 	short	0x0000
     98 	bra.l	_fetoxm1x_
     99 	short	0x0000
    100 
    101 	bra.l	_fgetexps_
    102 	short	0x0000
    103 	bra.l	_fgetexpd_
    104 	short	0x0000
    105 	bra.l	_fgetexpx_
    106 	short	0x0000
    107 
    108 	bra.l	_fgetmans_
    109 	short	0x0000
    110 	bra.l	_fgetmand_
    111 	short	0x0000
    112 	bra.l	_fgetmanx_
    113 	short	0x0000
    114 
    115 	bra.l	_flog10s_
    116 	short	0x0000
    117 	bra.l	_flog10d_
    118 	short	0x0000
    119 	bra.l	_flog10x_
    120 	short	0x0000
    121 
    122 	bra.l	_flog2s_
    123 	short	0x0000
    124 	bra.l	_flog2d_
    125 	short	0x0000
    126 	bra.l	_flog2x_
    127 	short	0x0000
    128 
    129 	bra.l	_flogns_
    130 	short	0x0000
    131 	bra.l	_flognd_
    132 	short	0x0000
    133 	bra.l	_flognx_
    134 	short	0x0000
    135 
    136 	bra.l	_flognp1s_
    137 	short	0x0000
    138 	bra.l	_flognp1d_
    139 	short	0x0000
    140 	bra.l	_flognp1x_
    141 	short	0x0000
    142 
    143 	bra.l	_fmods_
    144 	short	0x0000
    145 	bra.l	_fmodd_
    146 	short	0x0000
    147 	bra.l	_fmodx_
    148 	short	0x0000
    149 
    150 	bra.l	_frems_
    151 	short	0x0000
    152 	bra.l	_fremd_
    153 	short	0x0000
    154 	bra.l	_fremx_
    155 	short	0x0000
    156 
    157 	bra.l	_fscales_
    158 	short	0x0000
    159 	bra.l	_fscaled_
    160 	short	0x0000
    161 	bra.l	_fscalex_
    162 	short	0x0000
    163 
    164 	bra.l	_fsins_
    165 	short	0x0000
    166 	bra.l	_fsind_
    167 	short	0x0000
    168 	bra.l	_fsinx_
    169 	short	0x0000
    170 
    171 	bra.l	_fsincoss_
    172 	short	0x0000
    173 	bra.l	_fsincosd_
    174 	short	0x0000
    175 	bra.l	_fsincosx_
    176 	short	0x0000
    177 
    178 	bra.l	_fsinhs_
    179 	short	0x0000
    180 	bra.l	_fsinhd_
    181 	short	0x0000
    182 	bra.l	_fsinhx_
    183 	short	0x0000
    184 
    185 	bra.l	_ftans_
    186 	short	0x0000
    187 	bra.l	_ftand_
    188 	short	0x0000
    189 	bra.l	_ftanx_
    190 	short	0x0000
    191 
    192 	bra.l	_ftanhs_
    193 	short	0x0000
    194 	bra.l	_ftanhd_
    195 	short	0x0000
    196 	bra.l	_ftanhx_
    197 	short	0x0000
    198 
    199 	bra.l	_ftentoxs_
    200 	short	0x0000
    201 	bra.l	_ftentoxd_
    202 	short	0x0000
    203 	bra.l	_ftentoxx_
    204 	short	0x0000
    205 
    206 	bra.l	_ftwotoxs_
    207 	short	0x0000
    208 	bra.l	_ftwotoxd_
    209 	short	0x0000
    210 	bra.l	_ftwotoxx_
    211 	short	0x0000
    212 
    213 	bra.l	_fabss_
    214 	short	0x0000
    215 	bra.l	_fabsd_
    216 	short	0x0000
    217 	bra.l	_fabsx_
    218 	short	0x0000
    219 
    220 	bra.l	_fadds_
    221 	short	0x0000
    222 	bra.l	_faddd_
    223 	short	0x0000
    224 	bra.l	_faddx_
    225 	short	0x0000
    226 
    227 	bra.l	_fdivs_
    228 	short	0x0000
    229 	bra.l	_fdivd_
    230 	short	0x0000
    231 	bra.l	_fdivx_
    232 	short	0x0000
    233 
    234 	bra.l	_fints_
    235 	short	0x0000
    236 	bra.l	_fintd_
    237 	short	0x0000
    238 	bra.l	_fintx_
    239 	short	0x0000
    240 
    241 	bra.l	_fintrzs_
    242 	short	0x0000
    243 	bra.l	_fintrzd_
    244 	short	0x0000
    245 	bra.l	_fintrzx_
    246 	short	0x0000
    247 
    248 	bra.l	_fmuls_
    249 	short	0x0000
    250 	bra.l	_fmuld_
    251 	short	0x0000
    252 	bra.l	_fmulx_
    253 	short	0x0000
    254 
    255 	bra.l	_fnegs_
    256 	short	0x0000
    257 	bra.l	_fnegd_
    258 	short	0x0000
    259 	bra.l	_fnegx_
    260 	short	0x0000
    261 
    262 	bra.l	_fsqrts_
    263 	short	0x0000
    264 	bra.l	_fsqrtd_
    265 	short	0x0000
    266 	bra.l	_fsqrtx_
    267 	short	0x0000
    268 
    269 	bra.l	_fsubs_
    270 	short	0x0000
    271 	bra.l	_fsubd_
    272 	short	0x0000
    273 	bra.l	_fsubx_
    274 	short	0x0000
    275 
    276 # leave room for future possible additions
    277 	align	0x400
    278 
    279 #
    280 # This file contains a set of define statements for constants
    281 # in order to promote readability within the corecode itself.
    282 #
    283 
    284 set LOCAL_SIZE,		192			# stack frame size(bytes)
    285 set LV,			-LOCAL_SIZE		# stack offset
    286 
    287 set EXC_SR,		0x4			# stack status register
    288 set EXC_PC,		0x6			# stack pc
    289 set EXC_VOFF,		0xa			# stacked vector offset
    290 set EXC_EA,		0xc			# stacked <ea>
    291 
    292 set EXC_FP,		0x0			# frame pointer
    293 
    294 set EXC_AREGS,		-68			# offset of all address regs
    295 set EXC_DREGS,		-100			# offset of all data regs
    296 set EXC_FPREGS,		-36			# offset of all fp regs
    297 
    298 set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
    299 set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
    300 set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
    301 set EXC_A5,		EXC_AREGS+(5*4)
    302 set EXC_A4,		EXC_AREGS+(4*4)
    303 set EXC_A3,		EXC_AREGS+(3*4)
    304 set EXC_A2,		EXC_AREGS+(2*4)
    305 set EXC_A1,		EXC_AREGS+(1*4)
    306 set EXC_A0,		EXC_AREGS+(0*4)
    307 set EXC_D7,		EXC_DREGS+(7*4)
    308 set EXC_D6,		EXC_DREGS+(6*4)
    309 set EXC_D5,		EXC_DREGS+(5*4)
    310 set EXC_D4,		EXC_DREGS+(4*4)
    311 set EXC_D3,		EXC_DREGS+(3*4)
    312 set EXC_D2,		EXC_DREGS+(2*4)
    313 set EXC_D1,		EXC_DREGS+(1*4)
    314 set EXC_D0,		EXC_DREGS+(0*4)
    315 
    316 set EXC_FP0, 		EXC_FPREGS+(0*12)	# offset of saved fp0
    317 set EXC_FP1, 		EXC_FPREGS+(1*12)	# offset of saved fp1
    318 set EXC_FP2, 		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
    319 
    320 set FP_SCR1, 		LV+80			# fp scratch 1
    321 set FP_SCR1_EX, 	FP_SCR1+0
    322 set FP_SCR1_SGN,	FP_SCR1+2
    323 set FP_SCR1_HI, 	FP_SCR1+4
    324 set FP_SCR1_LO, 	FP_SCR1+8
    325 
    326 set FP_SCR0, 		LV+68			# fp scratch 0
    327 set FP_SCR0_EX, 	FP_SCR0+0
    328 set FP_SCR0_SGN,	FP_SCR0+2
    329 set FP_SCR0_HI, 	FP_SCR0+4
    330 set FP_SCR0_LO, 	FP_SCR0+8
    331 
    332 set FP_DST, 		LV+56			# fp destination operand
    333 set FP_DST_EX, 		FP_DST+0
    334 set FP_DST_SGN,		FP_DST+2
    335 set FP_DST_HI, 		FP_DST+4
    336 set FP_DST_LO, 		FP_DST+8
    337 
    338 set FP_SRC, 		LV+44			# fp source operand
    339 set FP_SRC_EX, 		FP_SRC+0
    340 set FP_SRC_SGN,		FP_SRC+2
    341 set FP_SRC_HI, 		FP_SRC+4
    342 set FP_SRC_LO, 		FP_SRC+8
    343 
    344 set USER_FPIAR,		LV+40			# FP instr address register
    345 
    346 set USER_FPSR,		LV+36			# FP status register
    347 set FPSR_CC,		USER_FPSR+0		# FPSR condition codes
    348 set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
    349 set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
    350 set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
    351 
    352 set USER_FPCR,		LV+32			# FP control register
    353 set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
    354 set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
    355 
    356 set L_SCR3,		LV+28			# integer scratch 3
    357 set L_SCR2,		LV+24			# integer scratch 2
    358 set L_SCR1,		LV+20			# integer scratch 1
    359 
    360 set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
    361 
    362 set EXC_TEMP2,		LV+24			# temporary space
    363 set EXC_TEMP,		LV+16			# temporary space
    364 
    365 set DTAG,		LV+15			# destination operand type
    366 set STAG, 		LV+14			# source operand type
    367 
    368 set SPCOND_FLG,		LV+10			# flag: special case (see below)
    369 
    370 set EXC_CC,		LV+8			# saved condition codes
    371 set EXC_EXTWPTR,	LV+4			# saved current PC (active)
    372 set EXC_EXTWORD,	LV+2			# saved extension word
    373 set EXC_CMDREG,		LV+2			# saved extension word
    374 set EXC_OPWORD,		LV+0			# saved operation word
    375 
    376 ################################
    377 
    378 # Helpful macros
    379 
    380 set FTEMP,		0			# offsets within an
    381 set FTEMP_EX, 		0			# extended precision
    382 set FTEMP_SGN,		2			# value saved in memory.
    383 set FTEMP_HI, 		4
    384 set FTEMP_LO, 		8
    385 set FTEMP_GRS,		12
    386 
    387 set LOCAL,		0			# offsets within an
    388 set LOCAL_EX, 		0			# extended precision
    389 set LOCAL_SGN,		2			# value saved in memory.
    390 set LOCAL_HI, 		4
    391 set LOCAL_LO, 		8
    392 set LOCAL_GRS,		12
    393 
    394 set DST,		0			# offsets within an
    395 set DST_EX,		0			# extended precision
    396 set DST_HI,		4			# value saved in memory.
    397 set DST_LO,		8
    398 
    399 set SRC,		0			# offsets within an
    400 set SRC_EX,		0			# extended precision
    401 set SRC_HI,		4			# value saved in memory.
    402 set SRC_LO,		8
    403 
    404 set SGL_LO,		0x3f81			# min sgl prec exponent
    405 set SGL_HI,		0x407e			# max sgl prec exponent
    406 set DBL_LO,		0x3c01			# min dbl prec exponent
    407 set DBL_HI,		0x43fe			# max dbl prec exponent
    408 set EXT_LO,		0x0			# min ext prec exponent
    409 set EXT_HI,		0x7ffe			# max ext prec exponent
    410 
    411 set EXT_BIAS,		0x3fff			# extended precision bias
    412 set SGL_BIAS,		0x007f			# single precision bias
    413 set DBL_BIAS,		0x03ff			# double precision bias
    414 
    415 set NORM,		0x00			# operand type for STAG/DTAG
    416 set ZERO,		0x01			# operand type for STAG/DTAG
    417 set INF,		0x02			# operand type for STAG/DTAG
    418 set QNAN,		0x03			# operand type for STAG/DTAG
    419 set DENORM,		0x04			# operand type for STAG/DTAG
    420 set SNAN,		0x05			# operand type for STAG/DTAG
    421 set UNNORM,		0x06			# operand type for STAG/DTAG
    422 
    423 ##################
    424 # FPSR/FPCR bits #
    425 ##################
    426 set neg_bit,		0x3			# negative result
    427 set z_bit,		0x2			# zero result
    428 set inf_bit,		0x1			# infinite result
    429 set nan_bit,		0x0			# NAN result
    430 
    431 set q_sn_bit,		0x7			# sign bit of quotient byte
    432 
    433 set bsun_bit,		7			# branch on unordered
    434 set snan_bit,		6			# signalling NAN
    435 set operr_bit,		5			# operand error
    436 set ovfl_bit,		4			# overflow
    437 set unfl_bit,		3			# underflow
    438 set dz_bit,		2			# divide by zero
    439 set inex2_bit,		1			# inexact result 2
    440 set inex1_bit,		0			# inexact result 1
    441 
    442 set aiop_bit,		7			# accrued inexact operation bit
    443 set aovfl_bit,		6			# accrued overflow bit
    444 set aunfl_bit,		5			# accrued underflow bit
    445 set adz_bit,		4			# accrued dz bit
    446 set ainex_bit,		3			# accrued inexact bit
    447 
    448 #############################
    449 # FPSR individual bit masks #
    450 #############################
    451 set neg_mask,		0x08000000		# negative bit mask (lw)
    452 set inf_mask,		0x02000000		# infinity bit mask (lw)
    453 set z_mask,		0x04000000		# zero bit mask (lw)
    454 set nan_mask,		0x01000000		# nan bit mask (lw)
    455 
    456 set neg_bmask,		0x08			# negative bit mask (byte)
    457 set inf_bmask,		0x02			# infinity bit mask (byte)
    458 set z_bmask,		0x04			# zero bit mask (byte)
    459 set nan_bmask,		0x01			# nan bit mask (byte)
    460 
    461 set bsun_mask,		0x00008000		# bsun exception mask
    462 set snan_mask,		0x00004000		# snan exception mask
    463 set operr_mask,		0x00002000		# operr exception mask
    464 set ovfl_mask,		0x00001000		# overflow exception mask
    465 set unfl_mask,		0x00000800		# underflow exception mask
    466 set dz_mask,		0x00000400		# dz exception mask
    467 set inex2_mask,		0x00000200		# inex2 exception mask
    468 set inex1_mask,		0x00000100		# inex1 exception mask
    469 
    470 set aiop_mask,		0x00000080		# accrued illegal operation
    471 set aovfl_mask,		0x00000040		# accrued overflow
    472 set aunfl_mask,		0x00000020		# accrued underflow
    473 set adz_mask,		0x00000010		# accrued divide by zero
    474 set ainex_mask,		0x00000008		# accrued inexact
    475 
    476 ######################################
    477 # FPSR combinations used in the FPSP #
    478 ######################################
    479 set dzinf_mask,		inf_mask+dz_mask+adz_mask
    480 set opnan_mask,		nan_mask+operr_mask+aiop_mask
    481 set nzi_mask,		0x01ffffff 		#clears N, Z, and I
    482 set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
    483 set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
    484 set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
    485 set inx1a_mask,		inex1_mask+ainex_mask
    486 set inx2a_mask,		inex2_mask+ainex_mask
    487 set snaniop_mask, 	nan_mask+snan_mask+aiop_mask
    488 set snaniop2_mask,	snan_mask+aiop_mask
    489 set naniop_mask,	nan_mask+aiop_mask
    490 set neginf_mask,	neg_mask+inf_mask
    491 set infaiop_mask, 	inf_mask+aiop_mask
    492 set negz_mask,		neg_mask+z_mask
    493 set opaop_mask,		operr_mask+aiop_mask
    494 set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
    495 set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
    496 
    497 #########
    498 # misc. #
    499 #########
    500 set rnd_stky_bit,	29			# stky bit pos in longword
    501 
    502 set sign_bit,		0x7			# sign bit
    503 set signan_bit,		0x6			# signalling nan bit
    504 
    505 set sgl_thresh,		0x3f81			# minimum sgl exponent
    506 set dbl_thresh,		0x3c01			# minimum dbl exponent
    507 
    508 set x_mode,		0x0			# extended precision
    509 set s_mode,		0x4			# single precision
    510 set d_mode,		0x8			# double precision
    511 
    512 set rn_mode,		0x0			# round-to-nearest
    513 set rz_mode,		0x1			# round-to-zero
    514 set rm_mode,		0x2			# round-tp-minus-infinity
    515 set rp_mode,		0x3			# round-to-plus-infinity
    516 
    517 set mantissalen,	64			# length of mantissa in bits
    518 
    519 set BYTE,		1			# len(byte) == 1 byte
    520 set WORD, 		2			# len(word) == 2 bytes
    521 set LONG, 		4			# len(longword) == 2 bytes
    522 
    523 set BSUN_VEC,		0xc0			# bsun    vector offset
    524 set INEX_VEC,		0xc4			# inexact vector offset
    525 set DZ_VEC,		0xc8			# dz      vector offset
    526 set UNFL_VEC,		0xcc			# unfl    vector offset
    527 set OPERR_VEC,		0xd0			# operr   vector offset
    528 set OVFL_VEC,		0xd4			# ovfl    vector offset
    529 set SNAN_VEC,		0xd8			# snan    vector offset
    530 
    531 ###########################
    532 # SPecial CONDition FLaGs #
    533 ###########################
    534 set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
    535 set fbsun_flg,		0x02			# flag bit: bsun exception
    536 set mia7_flg,		0x04			# flag bit: (a7)+ <ea>
    537 set mda7_flg,		0x08			# flag bit: -(a7) <ea>
    538 set fmovm_flg,		0x40			# flag bit: fmovm instruction
    539 set immed_flg,		0x80			# flag bit: &<data> <ea>
    540 
    541 set ftrapcc_bit,	0x0
    542 set fbsun_bit,		0x1
    543 set mia7_bit,		0x2
    544 set mda7_bit,		0x3
    545 set immed_bit,		0x7
    546 
    547 ##################################
    548 # TRANSCENDENTAL "LAST-OP" FLAGS #
    549 ##################################
    550 set FMUL_OP,		0x0			# fmul instr performed last
    551 set FDIV_OP,		0x1			# fdiv performed last
    552 set FADD_OP,		0x2			# fadd performed last
    553 set FMOV_OP,		0x3			# fmov performed last
    554 
    555 #############
    556 # CONSTANTS #
    557 #############
    558 T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
    559 T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
    560 
    561 PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
    562 PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
    563 
    564 TWOBYPI:
    565 	long		0x3FE45F30,0x6DC9C883
    566 
    567 #########################################################################
    568 # MONADIC TEMPLATE							#
    569 #########################################################################
    570 	global		_fsins_
    571 _fsins_:
    572 	link		%a6,&-LOCAL_SIZE
    573 
    574 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    575 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    576 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    577 
    578 	fmov.l		&0x0,%fpcr		# zero FPCR
    579 
    580 #
    581 #	copy, convert, and tag input argument
    582 #
    583 	fmov.s		0x8(%a6),%fp0		# load sgl input
    584 	fmov.x		%fp0,FP_SRC(%a6)
    585 	lea		FP_SRC(%a6),%a0
    586 	bsr.l		tag			# fetch operand type
    587 	mov.b		%d0,STAG(%a6)
    588 	mov.b		%d0,%d1
    589 
    590 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    591 
    592 	clr.l		%d0
    593 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    594 
    595 	tst.b		%d1
    596 	bne.b		_L0_2s
    597 	bsr.l		ssin			# operand is a NORM
    598 	bra.b		_L0_6s
    599 _L0_2s:
    600 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    601 	bne.b		_L0_3s			# no
    602 	bsr.l		src_zero			# yes
    603 	bra.b		_L0_6s
    604 _L0_3s:
    605 	cmpi.b		%d1,&INF		# is operand an INF?
    606 	bne.b		_L0_4s			# no
    607 	bsr.l		t_operr			# yes
    608 	bra.b		_L0_6s
    609 _L0_4s:
    610 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    611 	bne.b		_L0_5s			# no
    612 	bsr.l		src_qnan			# yes
    613 	bra.b		_L0_6s
    614 _L0_5s:
    615 	bsr.l		ssind			# operand is a DENORM
    616 _L0_6s:
    617 
    618 #
    619 #	Result is now in FP0
    620 #
    621 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    622 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    623 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    624 	unlk		%a6
    625 	rts
    626 
    627 	global		_fsind_
    628 _fsind_:
    629 	link		%a6,&-LOCAL_SIZE
    630 
    631 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    632 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    633 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    634 
    635 	fmov.l		&0x0,%fpcr		# zero FPCR
    636 
    637 #
    638 #	copy, convert, and tag input argument
    639 #
    640 	fmov.d		0x8(%a6),%fp0		# load dbl input
    641 	fmov.x		%fp0,FP_SRC(%a6)
    642 	lea		FP_SRC(%a6),%a0
    643 	bsr.l		tag			# fetch operand type
    644 	mov.b		%d0,STAG(%a6)
    645 	mov.b		%d0,%d1
    646 
    647 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    648 
    649 	clr.l		%d0
    650 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    651 
    652 	mov.b		%d1,STAG(%a6)
    653 	tst.b		%d1
    654 	bne.b		_L0_2d
    655 	bsr.l		ssin			# operand is a NORM
    656 	bra.b		_L0_6d
    657 _L0_2d:
    658 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    659 	bne.b		_L0_3d			# no
    660 	bsr.l		src_zero			# yes
    661 	bra.b		_L0_6d
    662 _L0_3d:
    663 	cmpi.b		%d1,&INF		# is operand an INF?
    664 	bne.b		_L0_4d			# no
    665 	bsr.l		t_operr			# yes
    666 	bra.b		_L0_6d
    667 _L0_4d:
    668 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    669 	bne.b		_L0_5d			# no
    670 	bsr.l		src_qnan			# yes
    671 	bra.b		_L0_6d
    672 _L0_5d:
    673 	bsr.l		ssind			# operand is a DENORM
    674 _L0_6d:
    675 
    676 #
    677 #	Result is now in FP0
    678 #
    679 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    680 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    681 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    682 	unlk		%a6
    683 	rts
    684 
    685 	global		_fsinx_
    686 _fsinx_:
    687 	link		%a6,&-LOCAL_SIZE
    688 
    689 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    690 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    691 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    692 
    693 	fmov.l		&0x0,%fpcr		# zero FPCR
    694 
    695 #
    696 #	copy, convert, and tag input argument
    697 #
    698 	lea		FP_SRC(%a6),%a0
    699 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
    700 	mov.l		0x8+0x4(%a6),0x4(%a0)
    701 	mov.l		0x8+0x8(%a6),0x8(%a0)
    702 	bsr.l		tag			# fetch operand type
    703 	mov.b		%d0,STAG(%a6)
    704 	mov.b		%d0,%d1
    705 
    706 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    707 
    708 	clr.l		%d0
    709 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    710 
    711 	tst.b		%d1
    712 	bne.b		_L0_2x
    713 	bsr.l		ssin			# operand is a NORM
    714 	bra.b		_L0_6x
    715 _L0_2x:
    716 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    717 	bne.b		_L0_3x			# no
    718 	bsr.l		src_zero			# yes
    719 	bra.b		_L0_6x
    720 _L0_3x:
    721 	cmpi.b		%d1,&INF		# is operand an INF?
    722 	bne.b		_L0_4x			# no
    723 	bsr.l		t_operr			# yes
    724 	bra.b		_L0_6x
    725 _L0_4x:
    726 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    727 	bne.b		_L0_5x			# no
    728 	bsr.l		src_qnan			# yes
    729 	bra.b		_L0_6x
    730 _L0_5x:
    731 	bsr.l		ssind			# operand is a DENORM
    732 _L0_6x:
    733 
    734 #
    735 #	Result is now in FP0
    736 #
    737 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    738 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    739 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    740 	unlk		%a6
    741 	rts
    742 
    743 
    744 #########################################################################
    745 # MONADIC TEMPLATE							#
    746 #########################################################################
    747 	global		_fcoss_
    748 _fcoss_:
    749 	link		%a6,&-LOCAL_SIZE
    750 
    751 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    752 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    753 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    754 
    755 	fmov.l		&0x0,%fpcr		# zero FPCR
    756 
    757 #
    758 #	copy, convert, and tag input argument
    759 #
    760 	fmov.s		0x8(%a6),%fp0		# load sgl input
    761 	fmov.x		%fp0,FP_SRC(%a6)
    762 	lea		FP_SRC(%a6),%a0
    763 	bsr.l		tag			# fetch operand type
    764 	mov.b		%d0,STAG(%a6)
    765 	mov.b		%d0,%d1
    766 
    767 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    768 
    769 	clr.l		%d0
    770 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    771 
    772 	tst.b		%d1
    773 	bne.b		_L1_2s
    774 	bsr.l		scos			# operand is a NORM
    775 	bra.b		_L1_6s
    776 _L1_2s:
    777 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    778 	bne.b		_L1_3s			# no
    779 	bsr.l		ld_pone			# yes
    780 	bra.b		_L1_6s
    781 _L1_3s:
    782 	cmpi.b		%d1,&INF		# is operand an INF?
    783 	bne.b		_L1_4s			# no
    784 	bsr.l		t_operr			# yes
    785 	bra.b		_L1_6s
    786 _L1_4s:
    787 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    788 	bne.b		_L1_5s			# no
    789 	bsr.l		src_qnan			# yes
    790 	bra.b		_L1_6s
    791 _L1_5s:
    792 	bsr.l		scosd			# operand is a DENORM
    793 _L1_6s:
    794 
    795 #
    796 #	Result is now in FP0
    797 #
    798 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    799 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    800 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    801 	unlk		%a6
    802 	rts
    803 
    804 	global		_fcosd_
    805 _fcosd_:
    806 	link		%a6,&-LOCAL_SIZE
    807 
    808 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    809 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    810 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    811 
    812 	fmov.l		&0x0,%fpcr		# zero FPCR
    813 
    814 #
    815 #	copy, convert, and tag input argument
    816 #
    817 	fmov.d		0x8(%a6),%fp0		# load dbl input
    818 	fmov.x		%fp0,FP_SRC(%a6)
    819 	lea		FP_SRC(%a6),%a0
    820 	bsr.l		tag			# fetch operand type
    821 	mov.b		%d0,STAG(%a6)
    822 	mov.b		%d0,%d1
    823 
    824 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    825 
    826 	clr.l		%d0
    827 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    828 
    829 	mov.b		%d1,STAG(%a6)
    830 	tst.b		%d1
    831 	bne.b		_L1_2d
    832 	bsr.l		scos			# operand is a NORM
    833 	bra.b		_L1_6d
    834 _L1_2d:
    835 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    836 	bne.b		_L1_3d			# no
    837 	bsr.l		ld_pone			# yes
    838 	bra.b		_L1_6d
    839 _L1_3d:
    840 	cmpi.b		%d1,&INF		# is operand an INF?
    841 	bne.b		_L1_4d			# no
    842 	bsr.l		t_operr			# yes
    843 	bra.b		_L1_6d
    844 _L1_4d:
    845 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    846 	bne.b		_L1_5d			# no
    847 	bsr.l		src_qnan			# yes
    848 	bra.b		_L1_6d
    849 _L1_5d:
    850 	bsr.l		scosd			# operand is a DENORM
    851 _L1_6d:
    852 
    853 #
    854 #	Result is now in FP0
    855 #
    856 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    857 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    858 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    859 	unlk		%a6
    860 	rts
    861 
    862 	global		_fcosx_
    863 _fcosx_:
    864 	link		%a6,&-LOCAL_SIZE
    865 
    866 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    867 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    868 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    869 
    870 	fmov.l		&0x0,%fpcr		# zero FPCR
    871 
    872 #
    873 #	copy, convert, and tag input argument
    874 #
    875 	lea		FP_SRC(%a6),%a0
    876 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
    877 	mov.l		0x8+0x4(%a6),0x4(%a0)
    878 	mov.l		0x8+0x8(%a6),0x8(%a0)
    879 	bsr.l		tag			# fetch operand type
    880 	mov.b		%d0,STAG(%a6)
    881 	mov.b		%d0,%d1
    882 
    883 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    884 
    885 	clr.l		%d0
    886 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    887 
    888 	tst.b		%d1
    889 	bne.b		_L1_2x
    890 	bsr.l		scos			# operand is a NORM
    891 	bra.b		_L1_6x
    892 _L1_2x:
    893 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    894 	bne.b		_L1_3x			# no
    895 	bsr.l		ld_pone			# yes
    896 	bra.b		_L1_6x
    897 _L1_3x:
    898 	cmpi.b		%d1,&INF		# is operand an INF?
    899 	bne.b		_L1_4x			# no
    900 	bsr.l		t_operr			# yes
    901 	bra.b		_L1_6x
    902 _L1_4x:
    903 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    904 	bne.b		_L1_5x			# no
    905 	bsr.l		src_qnan			# yes
    906 	bra.b		_L1_6x
    907 _L1_5x:
    908 	bsr.l		scosd			# operand is a DENORM
    909 _L1_6x:
    910 
    911 #
    912 #	Result is now in FP0
    913 #
    914 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    915 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    916 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    917 	unlk		%a6
    918 	rts
    919 
    920 
    921 #########################################################################
    922 # MONADIC TEMPLATE							#
    923 #########################################################################
    924 	global		_fsinhs_
    925 _fsinhs_:
    926 	link		%a6,&-LOCAL_SIZE
    927 
    928 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    929 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    930 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    931 
    932 	fmov.l		&0x0,%fpcr		# zero FPCR
    933 
    934 #
    935 #	copy, convert, and tag input argument
    936 #
    937 	fmov.s		0x8(%a6),%fp0		# load sgl input
    938 	fmov.x		%fp0,FP_SRC(%a6)
    939 	lea		FP_SRC(%a6),%a0
    940 	bsr.l		tag			# fetch operand type
    941 	mov.b		%d0,STAG(%a6)
    942 	mov.b		%d0,%d1
    943 
    944 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
    945 
    946 	clr.l		%d0
    947 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
    948 
    949 	tst.b		%d1
    950 	bne.b		_L2_2s
    951 	bsr.l		ssinh			# operand is a NORM
    952 	bra.b		_L2_6s
    953 _L2_2s:
    954 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
    955 	bne.b		_L2_3s			# no
    956 	bsr.l		src_zero			# yes
    957 	bra.b		_L2_6s
    958 _L2_3s:
    959 	cmpi.b		%d1,&INF		# is operand an INF?
    960 	bne.b		_L2_4s			# no
    961 	bsr.l		src_inf			# yes
    962 	bra.b		_L2_6s
    963 _L2_4s:
    964 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
    965 	bne.b		_L2_5s			# no
    966 	bsr.l		src_qnan			# yes
    967 	bra.b		_L2_6s
    968 _L2_5s:
    969 	bsr.l		ssinhd			# operand is a DENORM
    970 _L2_6s:
    971 
    972 #
    973 #	Result is now in FP0
    974 #
    975 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    976 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
    977 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
    978 	unlk		%a6
    979 	rts
    980 
    981 	global		_fsinhd_
    982 _fsinhd_:
    983 	link		%a6,&-LOCAL_SIZE
    984 
    985 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    986 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
    987 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
    988 
    989 	fmov.l		&0x0,%fpcr		# zero FPCR
    990 
    991 #
    992 #	copy, convert, and tag input argument
    993 #
    994 	fmov.d		0x8(%a6),%fp0		# load dbl input
    995 	fmov.x		%fp0,FP_SRC(%a6)
    996 	lea		FP_SRC(%a6),%a0
    997 	bsr.l		tag			# fetch operand type
    998 	mov.b		%d0,STAG(%a6)
    999 	mov.b		%d0,%d1
   1000 
   1001 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1002 
   1003 	clr.l		%d0
   1004 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1005 
   1006 	mov.b		%d1,STAG(%a6)
   1007 	tst.b		%d1
   1008 	bne.b		_L2_2d
   1009 	bsr.l		ssinh			# operand is a NORM
   1010 	bra.b		_L2_6d
   1011 _L2_2d:
   1012 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1013 	bne.b		_L2_3d			# no
   1014 	bsr.l		src_zero			# yes
   1015 	bra.b		_L2_6d
   1016 _L2_3d:
   1017 	cmpi.b		%d1,&INF		# is operand an INF?
   1018 	bne.b		_L2_4d			# no
   1019 	bsr.l		src_inf			# yes
   1020 	bra.b		_L2_6d
   1021 _L2_4d:
   1022 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1023 	bne.b		_L2_5d			# no
   1024 	bsr.l		src_qnan			# yes
   1025 	bra.b		_L2_6d
   1026 _L2_5d:
   1027 	bsr.l		ssinhd			# operand is a DENORM
   1028 _L2_6d:
   1029 
   1030 #
   1031 #	Result is now in FP0
   1032 #
   1033 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1034 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1035 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1036 	unlk		%a6
   1037 	rts
   1038 
   1039 	global		_fsinhx_
   1040 _fsinhx_:
   1041 	link		%a6,&-LOCAL_SIZE
   1042 
   1043 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1044 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1045 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1046 
   1047 	fmov.l		&0x0,%fpcr		# zero FPCR
   1048 
   1049 #
   1050 #	copy, convert, and tag input argument
   1051 #
   1052 	lea		FP_SRC(%a6),%a0
   1053 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   1054 	mov.l		0x8+0x4(%a6),0x4(%a0)
   1055 	mov.l		0x8+0x8(%a6),0x8(%a0)
   1056 	bsr.l		tag			# fetch operand type
   1057 	mov.b		%d0,STAG(%a6)
   1058 	mov.b		%d0,%d1
   1059 
   1060 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1061 
   1062 	clr.l		%d0
   1063 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1064 
   1065 	tst.b		%d1
   1066 	bne.b		_L2_2x
   1067 	bsr.l		ssinh			# operand is a NORM
   1068 	bra.b		_L2_6x
   1069 _L2_2x:
   1070 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1071 	bne.b		_L2_3x			# no
   1072 	bsr.l		src_zero			# yes
   1073 	bra.b		_L2_6x
   1074 _L2_3x:
   1075 	cmpi.b		%d1,&INF		# is operand an INF?
   1076 	bne.b		_L2_4x			# no
   1077 	bsr.l		src_inf			# yes
   1078 	bra.b		_L2_6x
   1079 _L2_4x:
   1080 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1081 	bne.b		_L2_5x			# no
   1082 	bsr.l		src_qnan			# yes
   1083 	bra.b		_L2_6x
   1084 _L2_5x:
   1085 	bsr.l		ssinhd			# operand is a DENORM
   1086 _L2_6x:
   1087 
   1088 #
   1089 #	Result is now in FP0
   1090 #
   1091 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1092 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1093 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1094 	unlk		%a6
   1095 	rts
   1096 
   1097 
   1098 #########################################################################
   1099 # MONADIC TEMPLATE							#
   1100 #########################################################################
   1101 	global		_flognp1s_
   1102 _flognp1s_:
   1103 	link		%a6,&-LOCAL_SIZE
   1104 
   1105 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1106 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1107 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1108 
   1109 	fmov.l		&0x0,%fpcr		# zero FPCR
   1110 
   1111 #
   1112 #	copy, convert, and tag input argument
   1113 #
   1114 	fmov.s		0x8(%a6),%fp0		# load sgl input
   1115 	fmov.x		%fp0,FP_SRC(%a6)
   1116 	lea		FP_SRC(%a6),%a0
   1117 	bsr.l		tag			# fetch operand type
   1118 	mov.b		%d0,STAG(%a6)
   1119 	mov.b		%d0,%d1
   1120 
   1121 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1122 
   1123 	clr.l		%d0
   1124 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1125 
   1126 	tst.b		%d1
   1127 	bne.b		_L3_2s
   1128 	bsr.l		slognp1			# operand is a NORM
   1129 	bra.b		_L3_6s
   1130 _L3_2s:
   1131 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1132 	bne.b		_L3_3s			# no
   1133 	bsr.l		src_zero			# yes
   1134 	bra.b		_L3_6s
   1135 _L3_3s:
   1136 	cmpi.b		%d1,&INF		# is operand an INF?
   1137 	bne.b		_L3_4s			# no
   1138 	bsr.l		sopr_inf			# yes
   1139 	bra.b		_L3_6s
   1140 _L3_4s:
   1141 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1142 	bne.b		_L3_5s			# no
   1143 	bsr.l		src_qnan			# yes
   1144 	bra.b		_L3_6s
   1145 _L3_5s:
   1146 	bsr.l		slognp1d			# operand is a DENORM
   1147 _L3_6s:
   1148 
   1149 #
   1150 #	Result is now in FP0
   1151 #
   1152 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1153 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1154 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1155 	unlk		%a6
   1156 	rts
   1157 
   1158 	global		_flognp1d_
   1159 _flognp1d_:
   1160 	link		%a6,&-LOCAL_SIZE
   1161 
   1162 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1163 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1164 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1165 
   1166 	fmov.l		&0x0,%fpcr		# zero FPCR
   1167 
   1168 #
   1169 #	copy, convert, and tag input argument
   1170 #
   1171 	fmov.d		0x8(%a6),%fp0		# load dbl input
   1172 	fmov.x		%fp0,FP_SRC(%a6)
   1173 	lea		FP_SRC(%a6),%a0
   1174 	bsr.l		tag			# fetch operand type
   1175 	mov.b		%d0,STAG(%a6)
   1176 	mov.b		%d0,%d1
   1177 
   1178 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1179 
   1180 	clr.l		%d0
   1181 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1182 
   1183 	mov.b		%d1,STAG(%a6)
   1184 	tst.b		%d1
   1185 	bne.b		_L3_2d
   1186 	bsr.l		slognp1			# operand is a NORM
   1187 	bra.b		_L3_6d
   1188 _L3_2d:
   1189 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1190 	bne.b		_L3_3d			# no
   1191 	bsr.l		src_zero			# yes
   1192 	bra.b		_L3_6d
   1193 _L3_3d:
   1194 	cmpi.b		%d1,&INF		# is operand an INF?
   1195 	bne.b		_L3_4d			# no
   1196 	bsr.l		sopr_inf			# yes
   1197 	bra.b		_L3_6d
   1198 _L3_4d:
   1199 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1200 	bne.b		_L3_5d			# no
   1201 	bsr.l		src_qnan			# yes
   1202 	bra.b		_L3_6d
   1203 _L3_5d:
   1204 	bsr.l		slognp1d			# operand is a DENORM
   1205 _L3_6d:
   1206 
   1207 #
   1208 #	Result is now in FP0
   1209 #
   1210 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1211 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1212 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1213 	unlk		%a6
   1214 	rts
   1215 
   1216 	global		_flognp1x_
   1217 _flognp1x_:
   1218 	link		%a6,&-LOCAL_SIZE
   1219 
   1220 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1221 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1222 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1223 
   1224 	fmov.l		&0x0,%fpcr		# zero FPCR
   1225 
   1226 #
   1227 #	copy, convert, and tag input argument
   1228 #
   1229 	lea		FP_SRC(%a6),%a0
   1230 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   1231 	mov.l		0x8+0x4(%a6),0x4(%a0)
   1232 	mov.l		0x8+0x8(%a6),0x8(%a0)
   1233 	bsr.l		tag			# fetch operand type
   1234 	mov.b		%d0,STAG(%a6)
   1235 	mov.b		%d0,%d1
   1236 
   1237 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1238 
   1239 	clr.l		%d0
   1240 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1241 
   1242 	tst.b		%d1
   1243 	bne.b		_L3_2x
   1244 	bsr.l		slognp1			# operand is a NORM
   1245 	bra.b		_L3_6x
   1246 _L3_2x:
   1247 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1248 	bne.b		_L3_3x			# no
   1249 	bsr.l		src_zero			# yes
   1250 	bra.b		_L3_6x
   1251 _L3_3x:
   1252 	cmpi.b		%d1,&INF		# is operand an INF?
   1253 	bne.b		_L3_4x			# no
   1254 	bsr.l		sopr_inf			# yes
   1255 	bra.b		_L3_6x
   1256 _L3_4x:
   1257 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1258 	bne.b		_L3_5x			# no
   1259 	bsr.l		src_qnan			# yes
   1260 	bra.b		_L3_6x
   1261 _L3_5x:
   1262 	bsr.l		slognp1d			# operand is a DENORM
   1263 _L3_6x:
   1264 
   1265 #
   1266 #	Result is now in FP0
   1267 #
   1268 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1269 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1270 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1271 	unlk		%a6
   1272 	rts
   1273 
   1274 
   1275 #########################################################################
   1276 # MONADIC TEMPLATE							#
   1277 #########################################################################
   1278 	global		_fetoxm1s_
   1279 _fetoxm1s_:
   1280 	link		%a6,&-LOCAL_SIZE
   1281 
   1282 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1283 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1284 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1285 
   1286 	fmov.l		&0x0,%fpcr		# zero FPCR
   1287 
   1288 #
   1289 #	copy, convert, and tag input argument
   1290 #
   1291 	fmov.s		0x8(%a6),%fp0		# load sgl input
   1292 	fmov.x		%fp0,FP_SRC(%a6)
   1293 	lea		FP_SRC(%a6),%a0
   1294 	bsr.l		tag			# fetch operand type
   1295 	mov.b		%d0,STAG(%a6)
   1296 	mov.b		%d0,%d1
   1297 
   1298 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1299 
   1300 	clr.l		%d0
   1301 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1302 
   1303 	tst.b		%d1
   1304 	bne.b		_L4_2s
   1305 	bsr.l		setoxm1			# operand is a NORM
   1306 	bra.b		_L4_6s
   1307 _L4_2s:
   1308 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1309 	bne.b		_L4_3s			# no
   1310 	bsr.l		src_zero			# yes
   1311 	bra.b		_L4_6s
   1312 _L4_3s:
   1313 	cmpi.b		%d1,&INF		# is operand an INF?
   1314 	bne.b		_L4_4s			# no
   1315 	bsr.l		setoxm1i			# yes
   1316 	bra.b		_L4_6s
   1317 _L4_4s:
   1318 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1319 	bne.b		_L4_5s			# no
   1320 	bsr.l		src_qnan			# yes
   1321 	bra.b		_L4_6s
   1322 _L4_5s:
   1323 	bsr.l		setoxm1d			# operand is a DENORM
   1324 _L4_6s:
   1325 
   1326 #
   1327 #	Result is now in FP0
   1328 #
   1329 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1330 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1331 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1332 	unlk		%a6
   1333 	rts
   1334 
   1335 	global		_fetoxm1d_
   1336 _fetoxm1d_:
   1337 	link		%a6,&-LOCAL_SIZE
   1338 
   1339 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1340 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1341 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1342 
   1343 	fmov.l		&0x0,%fpcr		# zero FPCR
   1344 
   1345 #
   1346 #	copy, convert, and tag input argument
   1347 #
   1348 	fmov.d		0x8(%a6),%fp0		# load dbl input
   1349 	fmov.x		%fp0,FP_SRC(%a6)
   1350 	lea		FP_SRC(%a6),%a0
   1351 	bsr.l		tag			# fetch operand type
   1352 	mov.b		%d0,STAG(%a6)
   1353 	mov.b		%d0,%d1
   1354 
   1355 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1356 
   1357 	clr.l		%d0
   1358 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1359 
   1360 	mov.b		%d1,STAG(%a6)
   1361 	tst.b		%d1
   1362 	bne.b		_L4_2d
   1363 	bsr.l		setoxm1			# operand is a NORM
   1364 	bra.b		_L4_6d
   1365 _L4_2d:
   1366 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1367 	bne.b		_L4_3d			# no
   1368 	bsr.l		src_zero			# yes
   1369 	bra.b		_L4_6d
   1370 _L4_3d:
   1371 	cmpi.b		%d1,&INF		# is operand an INF?
   1372 	bne.b		_L4_4d			# no
   1373 	bsr.l		setoxm1i			# yes
   1374 	bra.b		_L4_6d
   1375 _L4_4d:
   1376 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1377 	bne.b		_L4_5d			# no
   1378 	bsr.l		src_qnan			# yes
   1379 	bra.b		_L4_6d
   1380 _L4_5d:
   1381 	bsr.l		setoxm1d			# operand is a DENORM
   1382 _L4_6d:
   1383 
   1384 #
   1385 #	Result is now in FP0
   1386 #
   1387 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1388 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1389 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1390 	unlk		%a6
   1391 	rts
   1392 
   1393 	global		_fetoxm1x_
   1394 _fetoxm1x_:
   1395 	link		%a6,&-LOCAL_SIZE
   1396 
   1397 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1398 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1399 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1400 
   1401 	fmov.l		&0x0,%fpcr		# zero FPCR
   1402 
   1403 #
   1404 #	copy, convert, and tag input argument
   1405 #
   1406 	lea		FP_SRC(%a6),%a0
   1407 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   1408 	mov.l		0x8+0x4(%a6),0x4(%a0)
   1409 	mov.l		0x8+0x8(%a6),0x8(%a0)
   1410 	bsr.l		tag			# fetch operand type
   1411 	mov.b		%d0,STAG(%a6)
   1412 	mov.b		%d0,%d1
   1413 
   1414 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1415 
   1416 	clr.l		%d0
   1417 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1418 
   1419 	tst.b		%d1
   1420 	bne.b		_L4_2x
   1421 	bsr.l		setoxm1			# operand is a NORM
   1422 	bra.b		_L4_6x
   1423 _L4_2x:
   1424 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1425 	bne.b		_L4_3x			# no
   1426 	bsr.l		src_zero			# yes
   1427 	bra.b		_L4_6x
   1428 _L4_3x:
   1429 	cmpi.b		%d1,&INF		# is operand an INF?
   1430 	bne.b		_L4_4x			# no
   1431 	bsr.l		setoxm1i			# yes
   1432 	bra.b		_L4_6x
   1433 _L4_4x:
   1434 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1435 	bne.b		_L4_5x			# no
   1436 	bsr.l		src_qnan			# yes
   1437 	bra.b		_L4_6x
   1438 _L4_5x:
   1439 	bsr.l		setoxm1d			# operand is a DENORM
   1440 _L4_6x:
   1441 
   1442 #
   1443 #	Result is now in FP0
   1444 #
   1445 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1446 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1447 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1448 	unlk		%a6
   1449 	rts
   1450 
   1451 
   1452 #########################################################################
   1453 # MONADIC TEMPLATE							#
   1454 #########################################################################
   1455 	global		_ftanhs_
   1456 _ftanhs_:
   1457 	link		%a6,&-LOCAL_SIZE
   1458 
   1459 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1460 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1461 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1462 
   1463 	fmov.l		&0x0,%fpcr		# zero FPCR
   1464 
   1465 #
   1466 #	copy, convert, and tag input argument
   1467 #
   1468 	fmov.s		0x8(%a6),%fp0		# load sgl input
   1469 	fmov.x		%fp0,FP_SRC(%a6)
   1470 	lea		FP_SRC(%a6),%a0
   1471 	bsr.l		tag			# fetch operand type
   1472 	mov.b		%d0,STAG(%a6)
   1473 	mov.b		%d0,%d1
   1474 
   1475 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1476 
   1477 	clr.l		%d0
   1478 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1479 
   1480 	tst.b		%d1
   1481 	bne.b		_L5_2s
   1482 	bsr.l		stanh			# operand is a NORM
   1483 	bra.b		_L5_6s
   1484 _L5_2s:
   1485 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1486 	bne.b		_L5_3s			# no
   1487 	bsr.l		src_zero			# yes
   1488 	bra.b		_L5_6s
   1489 _L5_3s:
   1490 	cmpi.b		%d1,&INF		# is operand an INF?
   1491 	bne.b		_L5_4s			# no
   1492 	bsr.l		src_one			# yes
   1493 	bra.b		_L5_6s
   1494 _L5_4s:
   1495 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1496 	bne.b		_L5_5s			# no
   1497 	bsr.l		src_qnan			# yes
   1498 	bra.b		_L5_6s
   1499 _L5_5s:
   1500 	bsr.l		stanhd			# operand is a DENORM
   1501 _L5_6s:
   1502 
   1503 #
   1504 #	Result is now in FP0
   1505 #
   1506 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1507 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1508 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1509 	unlk		%a6
   1510 	rts
   1511 
   1512 	global		_ftanhd_
   1513 _ftanhd_:
   1514 	link		%a6,&-LOCAL_SIZE
   1515 
   1516 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1517 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1518 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1519 
   1520 	fmov.l		&0x0,%fpcr		# zero FPCR
   1521 
   1522 #
   1523 #	copy, convert, and tag input argument
   1524 #
   1525 	fmov.d		0x8(%a6),%fp0		# load dbl input
   1526 	fmov.x		%fp0,FP_SRC(%a6)
   1527 	lea		FP_SRC(%a6),%a0
   1528 	bsr.l		tag			# fetch operand type
   1529 	mov.b		%d0,STAG(%a6)
   1530 	mov.b		%d0,%d1
   1531 
   1532 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1533 
   1534 	clr.l		%d0
   1535 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1536 
   1537 	mov.b		%d1,STAG(%a6)
   1538 	tst.b		%d1
   1539 	bne.b		_L5_2d
   1540 	bsr.l		stanh			# operand is a NORM
   1541 	bra.b		_L5_6d
   1542 _L5_2d:
   1543 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1544 	bne.b		_L5_3d			# no
   1545 	bsr.l		src_zero			# yes
   1546 	bra.b		_L5_6d
   1547 _L5_3d:
   1548 	cmpi.b		%d1,&INF		# is operand an INF?
   1549 	bne.b		_L5_4d			# no
   1550 	bsr.l		src_one			# yes
   1551 	bra.b		_L5_6d
   1552 _L5_4d:
   1553 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1554 	bne.b		_L5_5d			# no
   1555 	bsr.l		src_qnan			# yes
   1556 	bra.b		_L5_6d
   1557 _L5_5d:
   1558 	bsr.l		stanhd			# operand is a DENORM
   1559 _L5_6d:
   1560 
   1561 #
   1562 #	Result is now in FP0
   1563 #
   1564 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1565 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1566 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1567 	unlk		%a6
   1568 	rts
   1569 
   1570 	global		_ftanhx_
   1571 _ftanhx_:
   1572 	link		%a6,&-LOCAL_SIZE
   1573 
   1574 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1575 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1576 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1577 
   1578 	fmov.l		&0x0,%fpcr		# zero FPCR
   1579 
   1580 #
   1581 #	copy, convert, and tag input argument
   1582 #
   1583 	lea		FP_SRC(%a6),%a0
   1584 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   1585 	mov.l		0x8+0x4(%a6),0x4(%a0)
   1586 	mov.l		0x8+0x8(%a6),0x8(%a0)
   1587 	bsr.l		tag			# fetch operand type
   1588 	mov.b		%d0,STAG(%a6)
   1589 	mov.b		%d0,%d1
   1590 
   1591 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1592 
   1593 	clr.l		%d0
   1594 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1595 
   1596 	tst.b		%d1
   1597 	bne.b		_L5_2x
   1598 	bsr.l		stanh			# operand is a NORM
   1599 	bra.b		_L5_6x
   1600 _L5_2x:
   1601 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1602 	bne.b		_L5_3x			# no
   1603 	bsr.l		src_zero			# yes
   1604 	bra.b		_L5_6x
   1605 _L5_3x:
   1606 	cmpi.b		%d1,&INF		# is operand an INF?
   1607 	bne.b		_L5_4x			# no
   1608 	bsr.l		src_one			# yes
   1609 	bra.b		_L5_6x
   1610 _L5_4x:
   1611 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1612 	bne.b		_L5_5x			# no
   1613 	bsr.l		src_qnan			# yes
   1614 	bra.b		_L5_6x
   1615 _L5_5x:
   1616 	bsr.l		stanhd			# operand is a DENORM
   1617 _L5_6x:
   1618 
   1619 #
   1620 #	Result is now in FP0
   1621 #
   1622 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1623 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1624 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1625 	unlk		%a6
   1626 	rts
   1627 
   1628 
   1629 #########################################################################
   1630 # MONADIC TEMPLATE							#
   1631 #########################################################################
   1632 	global		_fatans_
   1633 _fatans_:
   1634 	link		%a6,&-LOCAL_SIZE
   1635 
   1636 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1637 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1638 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1639 
   1640 	fmov.l		&0x0,%fpcr		# zero FPCR
   1641 
   1642 #
   1643 #	copy, convert, and tag input argument
   1644 #
   1645 	fmov.s		0x8(%a6),%fp0		# load sgl input
   1646 	fmov.x		%fp0,FP_SRC(%a6)
   1647 	lea		FP_SRC(%a6),%a0
   1648 	bsr.l		tag			# fetch operand type
   1649 	mov.b		%d0,STAG(%a6)
   1650 	mov.b		%d0,%d1
   1651 
   1652 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1653 
   1654 	clr.l		%d0
   1655 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1656 
   1657 	tst.b		%d1
   1658 	bne.b		_L6_2s
   1659 	bsr.l		satan			# operand is a NORM
   1660 	bra.b		_L6_6s
   1661 _L6_2s:
   1662 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1663 	bne.b		_L6_3s			# no
   1664 	bsr.l		src_zero			# yes
   1665 	bra.b		_L6_6s
   1666 _L6_3s:
   1667 	cmpi.b		%d1,&INF		# is operand an INF?
   1668 	bne.b		_L6_4s			# no
   1669 	bsr.l		spi_2			# yes
   1670 	bra.b		_L6_6s
   1671 _L6_4s:
   1672 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1673 	bne.b		_L6_5s			# no
   1674 	bsr.l		src_qnan			# yes
   1675 	bra.b		_L6_6s
   1676 _L6_5s:
   1677 	bsr.l		satand			# operand is a DENORM
   1678 _L6_6s:
   1679 
   1680 #
   1681 #	Result is now in FP0
   1682 #
   1683 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1684 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1685 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1686 	unlk		%a6
   1687 	rts
   1688 
   1689 	global		_fatand_
   1690 _fatand_:
   1691 	link		%a6,&-LOCAL_SIZE
   1692 
   1693 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1694 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1695 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1696 
   1697 	fmov.l		&0x0,%fpcr		# zero FPCR
   1698 
   1699 #
   1700 #	copy, convert, and tag input argument
   1701 #
   1702 	fmov.d		0x8(%a6),%fp0		# load dbl input
   1703 	fmov.x		%fp0,FP_SRC(%a6)
   1704 	lea		FP_SRC(%a6),%a0
   1705 	bsr.l		tag			# fetch operand type
   1706 	mov.b		%d0,STAG(%a6)
   1707 	mov.b		%d0,%d1
   1708 
   1709 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1710 
   1711 	clr.l		%d0
   1712 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1713 
   1714 	mov.b		%d1,STAG(%a6)
   1715 	tst.b		%d1
   1716 	bne.b		_L6_2d
   1717 	bsr.l		satan			# operand is a NORM
   1718 	bra.b		_L6_6d
   1719 _L6_2d:
   1720 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1721 	bne.b		_L6_3d			# no
   1722 	bsr.l		src_zero			# yes
   1723 	bra.b		_L6_6d
   1724 _L6_3d:
   1725 	cmpi.b		%d1,&INF		# is operand an INF?
   1726 	bne.b		_L6_4d			# no
   1727 	bsr.l		spi_2			# yes
   1728 	bra.b		_L6_6d
   1729 _L6_4d:
   1730 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1731 	bne.b		_L6_5d			# no
   1732 	bsr.l		src_qnan			# yes
   1733 	bra.b		_L6_6d
   1734 _L6_5d:
   1735 	bsr.l		satand			# operand is a DENORM
   1736 _L6_6d:
   1737 
   1738 #
   1739 #	Result is now in FP0
   1740 #
   1741 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1742 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1743 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1744 	unlk		%a6
   1745 	rts
   1746 
   1747 	global		_fatanx_
   1748 _fatanx_:
   1749 	link		%a6,&-LOCAL_SIZE
   1750 
   1751 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1752 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1753 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1754 
   1755 	fmov.l		&0x0,%fpcr		# zero FPCR
   1756 
   1757 #
   1758 #	copy, convert, and tag input argument
   1759 #
   1760 	lea		FP_SRC(%a6),%a0
   1761 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   1762 	mov.l		0x8+0x4(%a6),0x4(%a0)
   1763 	mov.l		0x8+0x8(%a6),0x8(%a0)
   1764 	bsr.l		tag			# fetch operand type
   1765 	mov.b		%d0,STAG(%a6)
   1766 	mov.b		%d0,%d1
   1767 
   1768 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1769 
   1770 	clr.l		%d0
   1771 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1772 
   1773 	tst.b		%d1
   1774 	bne.b		_L6_2x
   1775 	bsr.l		satan			# operand is a NORM
   1776 	bra.b		_L6_6x
   1777 _L6_2x:
   1778 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1779 	bne.b		_L6_3x			# no
   1780 	bsr.l		src_zero			# yes
   1781 	bra.b		_L6_6x
   1782 _L6_3x:
   1783 	cmpi.b		%d1,&INF		# is operand an INF?
   1784 	bne.b		_L6_4x			# no
   1785 	bsr.l		spi_2			# yes
   1786 	bra.b		_L6_6x
   1787 _L6_4x:
   1788 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1789 	bne.b		_L6_5x			# no
   1790 	bsr.l		src_qnan			# yes
   1791 	bra.b		_L6_6x
   1792 _L6_5x:
   1793 	bsr.l		satand			# operand is a DENORM
   1794 _L6_6x:
   1795 
   1796 #
   1797 #	Result is now in FP0
   1798 #
   1799 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1800 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1801 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1802 	unlk		%a6
   1803 	rts
   1804 
   1805 
   1806 #########################################################################
   1807 # MONADIC TEMPLATE							#
   1808 #########################################################################
   1809 	global		_fasins_
   1810 _fasins_:
   1811 	link		%a6,&-LOCAL_SIZE
   1812 
   1813 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1814 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1815 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1816 
   1817 	fmov.l		&0x0,%fpcr		# zero FPCR
   1818 
   1819 #
   1820 #	copy, convert, and tag input argument
   1821 #
   1822 	fmov.s		0x8(%a6),%fp0		# load sgl input
   1823 	fmov.x		%fp0,FP_SRC(%a6)
   1824 	lea		FP_SRC(%a6),%a0
   1825 	bsr.l		tag			# fetch operand type
   1826 	mov.b		%d0,STAG(%a6)
   1827 	mov.b		%d0,%d1
   1828 
   1829 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1830 
   1831 	clr.l		%d0
   1832 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1833 
   1834 	tst.b		%d1
   1835 	bne.b		_L7_2s
   1836 	bsr.l		sasin			# operand is a NORM
   1837 	bra.b		_L7_6s
   1838 _L7_2s:
   1839 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1840 	bne.b		_L7_3s			# no
   1841 	bsr.l		src_zero			# yes
   1842 	bra.b		_L7_6s
   1843 _L7_3s:
   1844 	cmpi.b		%d1,&INF		# is operand an INF?
   1845 	bne.b		_L7_4s			# no
   1846 	bsr.l		t_operr			# yes
   1847 	bra.b		_L7_6s
   1848 _L7_4s:
   1849 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1850 	bne.b		_L7_5s			# no
   1851 	bsr.l		src_qnan			# yes
   1852 	bra.b		_L7_6s
   1853 _L7_5s:
   1854 	bsr.l		sasind			# operand is a DENORM
   1855 _L7_6s:
   1856 
   1857 #
   1858 #	Result is now in FP0
   1859 #
   1860 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1861 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1862 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1863 	unlk		%a6
   1864 	rts
   1865 
   1866 	global		_fasind_
   1867 _fasind_:
   1868 	link		%a6,&-LOCAL_SIZE
   1869 
   1870 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1871 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1872 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1873 
   1874 	fmov.l		&0x0,%fpcr		# zero FPCR
   1875 
   1876 #
   1877 #	copy, convert, and tag input argument
   1878 #
   1879 	fmov.d		0x8(%a6),%fp0		# load dbl input
   1880 	fmov.x		%fp0,FP_SRC(%a6)
   1881 	lea		FP_SRC(%a6),%a0
   1882 	bsr.l		tag			# fetch operand type
   1883 	mov.b		%d0,STAG(%a6)
   1884 	mov.b		%d0,%d1
   1885 
   1886 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1887 
   1888 	clr.l		%d0
   1889 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1890 
   1891 	mov.b		%d1,STAG(%a6)
   1892 	tst.b		%d1
   1893 	bne.b		_L7_2d
   1894 	bsr.l		sasin			# operand is a NORM
   1895 	bra.b		_L7_6d
   1896 _L7_2d:
   1897 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1898 	bne.b		_L7_3d			# no
   1899 	bsr.l		src_zero			# yes
   1900 	bra.b		_L7_6d
   1901 _L7_3d:
   1902 	cmpi.b		%d1,&INF		# is operand an INF?
   1903 	bne.b		_L7_4d			# no
   1904 	bsr.l		t_operr			# yes
   1905 	bra.b		_L7_6d
   1906 _L7_4d:
   1907 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1908 	bne.b		_L7_5d			# no
   1909 	bsr.l		src_qnan			# yes
   1910 	bra.b		_L7_6d
   1911 _L7_5d:
   1912 	bsr.l		sasind			# operand is a DENORM
   1913 _L7_6d:
   1914 
   1915 #
   1916 #	Result is now in FP0
   1917 #
   1918 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1919 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1920 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1921 	unlk		%a6
   1922 	rts
   1923 
   1924 	global		_fasinx_
   1925 _fasinx_:
   1926 	link		%a6,&-LOCAL_SIZE
   1927 
   1928 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1929 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1930 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1931 
   1932 	fmov.l		&0x0,%fpcr		# zero FPCR
   1933 
   1934 #
   1935 #	copy, convert, and tag input argument
   1936 #
   1937 	lea		FP_SRC(%a6),%a0
   1938 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   1939 	mov.l		0x8+0x4(%a6),0x4(%a0)
   1940 	mov.l		0x8+0x8(%a6),0x8(%a0)
   1941 	bsr.l		tag			# fetch operand type
   1942 	mov.b		%d0,STAG(%a6)
   1943 	mov.b		%d0,%d1
   1944 
   1945 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   1946 
   1947 	clr.l		%d0
   1948 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   1949 
   1950 	tst.b		%d1
   1951 	bne.b		_L7_2x
   1952 	bsr.l		sasin			# operand is a NORM
   1953 	bra.b		_L7_6x
   1954 _L7_2x:
   1955 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   1956 	bne.b		_L7_3x			# no
   1957 	bsr.l		src_zero			# yes
   1958 	bra.b		_L7_6x
   1959 _L7_3x:
   1960 	cmpi.b		%d1,&INF		# is operand an INF?
   1961 	bne.b		_L7_4x			# no
   1962 	bsr.l		t_operr			# yes
   1963 	bra.b		_L7_6x
   1964 _L7_4x:
   1965 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   1966 	bne.b		_L7_5x			# no
   1967 	bsr.l		src_qnan			# yes
   1968 	bra.b		_L7_6x
   1969 _L7_5x:
   1970 	bsr.l		sasind			# operand is a DENORM
   1971 _L7_6x:
   1972 
   1973 #
   1974 #	Result is now in FP0
   1975 #
   1976 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1977 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   1978 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   1979 	unlk		%a6
   1980 	rts
   1981 
   1982 
   1983 #########################################################################
   1984 # MONADIC TEMPLATE							#
   1985 #########################################################################
   1986 	global		_fatanhs_
   1987 _fatanhs_:
   1988 	link		%a6,&-LOCAL_SIZE
   1989 
   1990 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1991 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   1992 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   1993 
   1994 	fmov.l		&0x0,%fpcr		# zero FPCR
   1995 
   1996 #
   1997 #	copy, convert, and tag input argument
   1998 #
   1999 	fmov.s		0x8(%a6),%fp0		# load sgl input
   2000 	fmov.x		%fp0,FP_SRC(%a6)
   2001 	lea		FP_SRC(%a6),%a0
   2002 	bsr.l		tag			# fetch operand type
   2003 	mov.b		%d0,STAG(%a6)
   2004 	mov.b		%d0,%d1
   2005 
   2006 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2007 
   2008 	clr.l		%d0
   2009 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2010 
   2011 	tst.b		%d1
   2012 	bne.b		_L8_2s
   2013 	bsr.l		satanh			# operand is a NORM
   2014 	bra.b		_L8_6s
   2015 _L8_2s:
   2016 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2017 	bne.b		_L8_3s			# no
   2018 	bsr.l		src_zero			# yes
   2019 	bra.b		_L8_6s
   2020 _L8_3s:
   2021 	cmpi.b		%d1,&INF		# is operand an INF?
   2022 	bne.b		_L8_4s			# no
   2023 	bsr.l		t_operr			# yes
   2024 	bra.b		_L8_6s
   2025 _L8_4s:
   2026 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2027 	bne.b		_L8_5s			# no
   2028 	bsr.l		src_qnan			# yes
   2029 	bra.b		_L8_6s
   2030 _L8_5s:
   2031 	bsr.l		satanhd			# operand is a DENORM
   2032 _L8_6s:
   2033 
   2034 #
   2035 #	Result is now in FP0
   2036 #
   2037 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2038 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2039 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2040 	unlk		%a6
   2041 	rts
   2042 
   2043 	global		_fatanhd_
   2044 _fatanhd_:
   2045 	link		%a6,&-LOCAL_SIZE
   2046 
   2047 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2048 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2049 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2050 
   2051 	fmov.l		&0x0,%fpcr		# zero FPCR
   2052 
   2053 #
   2054 #	copy, convert, and tag input argument
   2055 #
   2056 	fmov.d		0x8(%a6),%fp0		# load dbl input
   2057 	fmov.x		%fp0,FP_SRC(%a6)
   2058 	lea		FP_SRC(%a6),%a0
   2059 	bsr.l		tag			# fetch operand type
   2060 	mov.b		%d0,STAG(%a6)
   2061 	mov.b		%d0,%d1
   2062 
   2063 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2064 
   2065 	clr.l		%d0
   2066 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2067 
   2068 	mov.b		%d1,STAG(%a6)
   2069 	tst.b		%d1
   2070 	bne.b		_L8_2d
   2071 	bsr.l		satanh			# operand is a NORM
   2072 	bra.b		_L8_6d
   2073 _L8_2d:
   2074 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2075 	bne.b		_L8_3d			# no
   2076 	bsr.l		src_zero			# yes
   2077 	bra.b		_L8_6d
   2078 _L8_3d:
   2079 	cmpi.b		%d1,&INF		# is operand an INF?
   2080 	bne.b		_L8_4d			# no
   2081 	bsr.l		t_operr			# yes
   2082 	bra.b		_L8_6d
   2083 _L8_4d:
   2084 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2085 	bne.b		_L8_5d			# no
   2086 	bsr.l		src_qnan			# yes
   2087 	bra.b		_L8_6d
   2088 _L8_5d:
   2089 	bsr.l		satanhd			# operand is a DENORM
   2090 _L8_6d:
   2091 
   2092 #
   2093 #	Result is now in FP0
   2094 #
   2095 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2096 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2097 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2098 	unlk		%a6
   2099 	rts
   2100 
   2101 	global		_fatanhx_
   2102 _fatanhx_:
   2103 	link		%a6,&-LOCAL_SIZE
   2104 
   2105 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2106 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2107 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2108 
   2109 	fmov.l		&0x0,%fpcr		# zero FPCR
   2110 
   2111 #
   2112 #	copy, convert, and tag input argument
   2113 #
   2114 	lea		FP_SRC(%a6),%a0
   2115 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   2116 	mov.l		0x8+0x4(%a6),0x4(%a0)
   2117 	mov.l		0x8+0x8(%a6),0x8(%a0)
   2118 	bsr.l		tag			# fetch operand type
   2119 	mov.b		%d0,STAG(%a6)
   2120 	mov.b		%d0,%d1
   2121 
   2122 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2123 
   2124 	clr.l		%d0
   2125 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2126 
   2127 	tst.b		%d1
   2128 	bne.b		_L8_2x
   2129 	bsr.l		satanh			# operand is a NORM
   2130 	bra.b		_L8_6x
   2131 _L8_2x:
   2132 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2133 	bne.b		_L8_3x			# no
   2134 	bsr.l		src_zero			# yes
   2135 	bra.b		_L8_6x
   2136 _L8_3x:
   2137 	cmpi.b		%d1,&INF		# is operand an INF?
   2138 	bne.b		_L8_4x			# no
   2139 	bsr.l		t_operr			# yes
   2140 	bra.b		_L8_6x
   2141 _L8_4x:
   2142 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2143 	bne.b		_L8_5x			# no
   2144 	bsr.l		src_qnan			# yes
   2145 	bra.b		_L8_6x
   2146 _L8_5x:
   2147 	bsr.l		satanhd			# operand is a DENORM
   2148 _L8_6x:
   2149 
   2150 #
   2151 #	Result is now in FP0
   2152 #
   2153 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2154 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2155 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2156 	unlk		%a6
   2157 	rts
   2158 
   2159 
   2160 #########################################################################
   2161 # MONADIC TEMPLATE							#
   2162 #########################################################################
   2163 	global		_ftans_
   2164 _ftans_:
   2165 	link		%a6,&-LOCAL_SIZE
   2166 
   2167 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2168 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2169 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2170 
   2171 	fmov.l		&0x0,%fpcr		# zero FPCR
   2172 
   2173 #
   2174 #	copy, convert, and tag input argument
   2175 #
   2176 	fmov.s		0x8(%a6),%fp0		# load sgl input
   2177 	fmov.x		%fp0,FP_SRC(%a6)
   2178 	lea		FP_SRC(%a6),%a0
   2179 	bsr.l		tag			# fetch operand type
   2180 	mov.b		%d0,STAG(%a6)
   2181 	mov.b		%d0,%d1
   2182 
   2183 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2184 
   2185 	clr.l		%d0
   2186 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2187 
   2188 	tst.b		%d1
   2189 	bne.b		_L9_2s
   2190 	bsr.l		stan			# operand is a NORM
   2191 	bra.b		_L9_6s
   2192 _L9_2s:
   2193 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2194 	bne.b		_L9_3s			# no
   2195 	bsr.l		src_zero			# yes
   2196 	bra.b		_L9_6s
   2197 _L9_3s:
   2198 	cmpi.b		%d1,&INF		# is operand an INF?
   2199 	bne.b		_L9_4s			# no
   2200 	bsr.l		t_operr			# yes
   2201 	bra.b		_L9_6s
   2202 _L9_4s:
   2203 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2204 	bne.b		_L9_5s			# no
   2205 	bsr.l		src_qnan			# yes
   2206 	bra.b		_L9_6s
   2207 _L9_5s:
   2208 	bsr.l		stand			# operand is a DENORM
   2209 _L9_6s:
   2210 
   2211 #
   2212 #	Result is now in FP0
   2213 #
   2214 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2215 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2216 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2217 	unlk		%a6
   2218 	rts
   2219 
   2220 	global		_ftand_
   2221 _ftand_:
   2222 	link		%a6,&-LOCAL_SIZE
   2223 
   2224 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2225 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2226 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2227 
   2228 	fmov.l		&0x0,%fpcr		# zero FPCR
   2229 
   2230 #
   2231 #	copy, convert, and tag input argument
   2232 #
   2233 	fmov.d		0x8(%a6),%fp0		# load dbl input
   2234 	fmov.x		%fp0,FP_SRC(%a6)
   2235 	lea		FP_SRC(%a6),%a0
   2236 	bsr.l		tag			# fetch operand type
   2237 	mov.b		%d0,STAG(%a6)
   2238 	mov.b		%d0,%d1
   2239 
   2240 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2241 
   2242 	clr.l		%d0
   2243 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2244 
   2245 	mov.b		%d1,STAG(%a6)
   2246 	tst.b		%d1
   2247 	bne.b		_L9_2d
   2248 	bsr.l		stan			# operand is a NORM
   2249 	bra.b		_L9_6d
   2250 _L9_2d:
   2251 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2252 	bne.b		_L9_3d			# no
   2253 	bsr.l		src_zero			# yes
   2254 	bra.b		_L9_6d
   2255 _L9_3d:
   2256 	cmpi.b		%d1,&INF		# is operand an INF?
   2257 	bne.b		_L9_4d			# no
   2258 	bsr.l		t_operr			# yes
   2259 	bra.b		_L9_6d
   2260 _L9_4d:
   2261 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2262 	bne.b		_L9_5d			# no
   2263 	bsr.l		src_qnan			# yes
   2264 	bra.b		_L9_6d
   2265 _L9_5d:
   2266 	bsr.l		stand			# operand is a DENORM
   2267 _L9_6d:
   2268 
   2269 #
   2270 #	Result is now in FP0
   2271 #
   2272 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2273 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2274 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2275 	unlk		%a6
   2276 	rts
   2277 
   2278 	global		_ftanx_
   2279 _ftanx_:
   2280 	link		%a6,&-LOCAL_SIZE
   2281 
   2282 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2283 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2284 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2285 
   2286 	fmov.l		&0x0,%fpcr		# zero FPCR
   2287 
   2288 #
   2289 #	copy, convert, and tag input argument
   2290 #
   2291 	lea		FP_SRC(%a6),%a0
   2292 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   2293 	mov.l		0x8+0x4(%a6),0x4(%a0)
   2294 	mov.l		0x8+0x8(%a6),0x8(%a0)
   2295 	bsr.l		tag			# fetch operand type
   2296 	mov.b		%d0,STAG(%a6)
   2297 	mov.b		%d0,%d1
   2298 
   2299 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2300 
   2301 	clr.l		%d0
   2302 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2303 
   2304 	tst.b		%d1
   2305 	bne.b		_L9_2x
   2306 	bsr.l		stan			# operand is a NORM
   2307 	bra.b		_L9_6x
   2308 _L9_2x:
   2309 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2310 	bne.b		_L9_3x			# no
   2311 	bsr.l		src_zero			# yes
   2312 	bra.b		_L9_6x
   2313 _L9_3x:
   2314 	cmpi.b		%d1,&INF		# is operand an INF?
   2315 	bne.b		_L9_4x			# no
   2316 	bsr.l		t_operr			# yes
   2317 	bra.b		_L9_6x
   2318 _L9_4x:
   2319 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2320 	bne.b		_L9_5x			# no
   2321 	bsr.l		src_qnan			# yes
   2322 	bra.b		_L9_6x
   2323 _L9_5x:
   2324 	bsr.l		stand			# operand is a DENORM
   2325 _L9_6x:
   2326 
   2327 #
   2328 #	Result is now in FP0
   2329 #
   2330 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2331 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2332 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2333 	unlk		%a6
   2334 	rts
   2335 
   2336 
   2337 #########################################################################
   2338 # MONADIC TEMPLATE							#
   2339 #########################################################################
   2340 	global		_fetoxs_
   2341 _fetoxs_:
   2342 	link		%a6,&-LOCAL_SIZE
   2343 
   2344 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2345 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2346 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2347 
   2348 	fmov.l		&0x0,%fpcr		# zero FPCR
   2349 
   2350 #
   2351 #	copy, convert, and tag input argument
   2352 #
   2353 	fmov.s		0x8(%a6),%fp0		# load sgl input
   2354 	fmov.x		%fp0,FP_SRC(%a6)
   2355 	lea		FP_SRC(%a6),%a0
   2356 	bsr.l		tag			# fetch operand type
   2357 	mov.b		%d0,STAG(%a6)
   2358 	mov.b		%d0,%d1
   2359 
   2360 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2361 
   2362 	clr.l		%d0
   2363 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2364 
   2365 	tst.b		%d1
   2366 	bne.b		_L10_2s
   2367 	bsr.l		setox			# operand is a NORM
   2368 	bra.b		_L10_6s
   2369 _L10_2s:
   2370 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2371 	bne.b		_L10_3s			# no
   2372 	bsr.l		ld_pone			# yes
   2373 	bra.b		_L10_6s
   2374 _L10_3s:
   2375 	cmpi.b		%d1,&INF		# is operand an INF?
   2376 	bne.b		_L10_4s			# no
   2377 	bsr.l		szr_inf			# yes
   2378 	bra.b		_L10_6s
   2379 _L10_4s:
   2380 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2381 	bne.b		_L10_5s			# no
   2382 	bsr.l		src_qnan			# yes
   2383 	bra.b		_L10_6s
   2384 _L10_5s:
   2385 	bsr.l		setoxd			# operand is a DENORM
   2386 _L10_6s:
   2387 
   2388 #
   2389 #	Result is now in FP0
   2390 #
   2391 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2392 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2393 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2394 	unlk		%a6
   2395 	rts
   2396 
   2397 	global		_fetoxd_
   2398 _fetoxd_:
   2399 	link		%a6,&-LOCAL_SIZE
   2400 
   2401 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2402 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2403 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2404 
   2405 	fmov.l		&0x0,%fpcr		# zero FPCR
   2406 
   2407 #
   2408 #	copy, convert, and tag input argument
   2409 #
   2410 	fmov.d		0x8(%a6),%fp0		# load dbl input
   2411 	fmov.x		%fp0,FP_SRC(%a6)
   2412 	lea		FP_SRC(%a6),%a0
   2413 	bsr.l		tag			# fetch operand type
   2414 	mov.b		%d0,STAG(%a6)
   2415 	mov.b		%d0,%d1
   2416 
   2417 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2418 
   2419 	clr.l		%d0
   2420 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2421 
   2422 	mov.b		%d1,STAG(%a6)
   2423 	tst.b		%d1
   2424 	bne.b		_L10_2d
   2425 	bsr.l		setox			# operand is a NORM
   2426 	bra.b		_L10_6d
   2427 _L10_2d:
   2428 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2429 	bne.b		_L10_3d			# no
   2430 	bsr.l		ld_pone			# yes
   2431 	bra.b		_L10_6d
   2432 _L10_3d:
   2433 	cmpi.b		%d1,&INF		# is operand an INF?
   2434 	bne.b		_L10_4d			# no
   2435 	bsr.l		szr_inf			# yes
   2436 	bra.b		_L10_6d
   2437 _L10_4d:
   2438 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2439 	bne.b		_L10_5d			# no
   2440 	bsr.l		src_qnan			# yes
   2441 	bra.b		_L10_6d
   2442 _L10_5d:
   2443 	bsr.l		setoxd			# operand is a DENORM
   2444 _L10_6d:
   2445 
   2446 #
   2447 #	Result is now in FP0
   2448 #
   2449 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2450 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2451 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2452 	unlk		%a6
   2453 	rts
   2454 
   2455 	global		_fetoxx_
   2456 _fetoxx_:
   2457 	link		%a6,&-LOCAL_SIZE
   2458 
   2459 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2460 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2461 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2462 
   2463 	fmov.l		&0x0,%fpcr		# zero FPCR
   2464 
   2465 #
   2466 #	copy, convert, and tag input argument
   2467 #
   2468 	lea		FP_SRC(%a6),%a0
   2469 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   2470 	mov.l		0x8+0x4(%a6),0x4(%a0)
   2471 	mov.l		0x8+0x8(%a6),0x8(%a0)
   2472 	bsr.l		tag			# fetch operand type
   2473 	mov.b		%d0,STAG(%a6)
   2474 	mov.b		%d0,%d1
   2475 
   2476 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2477 
   2478 	clr.l		%d0
   2479 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2480 
   2481 	tst.b		%d1
   2482 	bne.b		_L10_2x
   2483 	bsr.l		setox			# operand is a NORM
   2484 	bra.b		_L10_6x
   2485 _L10_2x:
   2486 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2487 	bne.b		_L10_3x			# no
   2488 	bsr.l		ld_pone			# yes
   2489 	bra.b		_L10_6x
   2490 _L10_3x:
   2491 	cmpi.b		%d1,&INF		# is operand an INF?
   2492 	bne.b		_L10_4x			# no
   2493 	bsr.l		szr_inf			# yes
   2494 	bra.b		_L10_6x
   2495 _L10_4x:
   2496 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2497 	bne.b		_L10_5x			# no
   2498 	bsr.l		src_qnan			# yes
   2499 	bra.b		_L10_6x
   2500 _L10_5x:
   2501 	bsr.l		setoxd			# operand is a DENORM
   2502 _L10_6x:
   2503 
   2504 #
   2505 #	Result is now in FP0
   2506 #
   2507 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2508 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2509 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2510 	unlk		%a6
   2511 	rts
   2512 
   2513 
   2514 #########################################################################
   2515 # MONADIC TEMPLATE							#
   2516 #########################################################################
   2517 	global		_ftwotoxs_
   2518 _ftwotoxs_:
   2519 	link		%a6,&-LOCAL_SIZE
   2520 
   2521 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2522 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2523 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2524 
   2525 	fmov.l		&0x0,%fpcr		# zero FPCR
   2526 
   2527 #
   2528 #	copy, convert, and tag input argument
   2529 #
   2530 	fmov.s		0x8(%a6),%fp0		# load sgl input
   2531 	fmov.x		%fp0,FP_SRC(%a6)
   2532 	lea		FP_SRC(%a6),%a0
   2533 	bsr.l		tag			# fetch operand type
   2534 	mov.b		%d0,STAG(%a6)
   2535 	mov.b		%d0,%d1
   2536 
   2537 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2538 
   2539 	clr.l		%d0
   2540 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2541 
   2542 	tst.b		%d1
   2543 	bne.b		_L11_2s
   2544 	bsr.l		stwotox			# operand is a NORM
   2545 	bra.b		_L11_6s
   2546 _L11_2s:
   2547 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2548 	bne.b		_L11_3s			# no
   2549 	bsr.l		ld_pone			# yes
   2550 	bra.b		_L11_6s
   2551 _L11_3s:
   2552 	cmpi.b		%d1,&INF		# is operand an INF?
   2553 	bne.b		_L11_4s			# no
   2554 	bsr.l		szr_inf			# yes
   2555 	bra.b		_L11_6s
   2556 _L11_4s:
   2557 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2558 	bne.b		_L11_5s			# no
   2559 	bsr.l		src_qnan			# yes
   2560 	bra.b		_L11_6s
   2561 _L11_5s:
   2562 	bsr.l		stwotoxd			# operand is a DENORM
   2563 _L11_6s:
   2564 
   2565 #
   2566 #	Result is now in FP0
   2567 #
   2568 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2569 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2570 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2571 	unlk		%a6
   2572 	rts
   2573 
   2574 	global		_ftwotoxd_
   2575 _ftwotoxd_:
   2576 	link		%a6,&-LOCAL_SIZE
   2577 
   2578 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2579 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2580 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2581 
   2582 	fmov.l		&0x0,%fpcr		# zero FPCR
   2583 
   2584 #
   2585 #	copy, convert, and tag input argument
   2586 #
   2587 	fmov.d		0x8(%a6),%fp0		# load dbl input
   2588 	fmov.x		%fp0,FP_SRC(%a6)
   2589 	lea		FP_SRC(%a6),%a0
   2590 	bsr.l		tag			# fetch operand type
   2591 	mov.b		%d0,STAG(%a6)
   2592 	mov.b		%d0,%d1
   2593 
   2594 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2595 
   2596 	clr.l		%d0
   2597 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2598 
   2599 	mov.b		%d1,STAG(%a6)
   2600 	tst.b		%d1
   2601 	bne.b		_L11_2d
   2602 	bsr.l		stwotox			# operand is a NORM
   2603 	bra.b		_L11_6d
   2604 _L11_2d:
   2605 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2606 	bne.b		_L11_3d			# no
   2607 	bsr.l		ld_pone			# yes
   2608 	bra.b		_L11_6d
   2609 _L11_3d:
   2610 	cmpi.b		%d1,&INF		# is operand an INF?
   2611 	bne.b		_L11_4d			# no
   2612 	bsr.l		szr_inf			# yes
   2613 	bra.b		_L11_6d
   2614 _L11_4d:
   2615 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2616 	bne.b		_L11_5d			# no
   2617 	bsr.l		src_qnan			# yes
   2618 	bra.b		_L11_6d
   2619 _L11_5d:
   2620 	bsr.l		stwotoxd			# operand is a DENORM
   2621 _L11_6d:
   2622 
   2623 #
   2624 #	Result is now in FP0
   2625 #
   2626 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2627 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2628 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2629 	unlk		%a6
   2630 	rts
   2631 
   2632 	global		_ftwotoxx_
   2633 _ftwotoxx_:
   2634 	link		%a6,&-LOCAL_SIZE
   2635 
   2636 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2637 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2638 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2639 
   2640 	fmov.l		&0x0,%fpcr		# zero FPCR
   2641 
   2642 #
   2643 #	copy, convert, and tag input argument
   2644 #
   2645 	lea		FP_SRC(%a6),%a0
   2646 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   2647 	mov.l		0x8+0x4(%a6),0x4(%a0)
   2648 	mov.l		0x8+0x8(%a6),0x8(%a0)
   2649 	bsr.l		tag			# fetch operand type
   2650 	mov.b		%d0,STAG(%a6)
   2651 	mov.b		%d0,%d1
   2652 
   2653 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2654 
   2655 	clr.l		%d0
   2656 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2657 
   2658 	tst.b		%d1
   2659 	bne.b		_L11_2x
   2660 	bsr.l		stwotox			# operand is a NORM
   2661 	bra.b		_L11_6x
   2662 _L11_2x:
   2663 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2664 	bne.b		_L11_3x			# no
   2665 	bsr.l		ld_pone			# yes
   2666 	bra.b		_L11_6x
   2667 _L11_3x:
   2668 	cmpi.b		%d1,&INF		# is operand an INF?
   2669 	bne.b		_L11_4x			# no
   2670 	bsr.l		szr_inf			# yes
   2671 	bra.b		_L11_6x
   2672 _L11_4x:
   2673 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2674 	bne.b		_L11_5x			# no
   2675 	bsr.l		src_qnan			# yes
   2676 	bra.b		_L11_6x
   2677 _L11_5x:
   2678 	bsr.l		stwotoxd			# operand is a DENORM
   2679 _L11_6x:
   2680 
   2681 #
   2682 #	Result is now in FP0
   2683 #
   2684 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2685 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2686 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2687 	unlk		%a6
   2688 	rts
   2689 
   2690 
   2691 #########################################################################
   2692 # MONADIC TEMPLATE							#
   2693 #########################################################################
   2694 	global		_ftentoxs_
   2695 _ftentoxs_:
   2696 	link		%a6,&-LOCAL_SIZE
   2697 
   2698 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2699 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2700 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2701 
   2702 	fmov.l		&0x0,%fpcr		# zero FPCR
   2703 
   2704 #
   2705 #	copy, convert, and tag input argument
   2706 #
   2707 	fmov.s		0x8(%a6),%fp0		# load sgl input
   2708 	fmov.x		%fp0,FP_SRC(%a6)
   2709 	lea		FP_SRC(%a6),%a0
   2710 	bsr.l		tag			# fetch operand type
   2711 	mov.b		%d0,STAG(%a6)
   2712 	mov.b		%d0,%d1
   2713 
   2714 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2715 
   2716 	clr.l		%d0
   2717 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2718 
   2719 	tst.b		%d1
   2720 	bne.b		_L12_2s
   2721 	bsr.l		stentox			# operand is a NORM
   2722 	bra.b		_L12_6s
   2723 _L12_2s:
   2724 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2725 	bne.b		_L12_3s			# no
   2726 	bsr.l		ld_pone			# yes
   2727 	bra.b		_L12_6s
   2728 _L12_3s:
   2729 	cmpi.b		%d1,&INF		# is operand an INF?
   2730 	bne.b		_L12_4s			# no
   2731 	bsr.l		szr_inf			# yes
   2732 	bra.b		_L12_6s
   2733 _L12_4s:
   2734 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2735 	bne.b		_L12_5s			# no
   2736 	bsr.l		src_qnan			# yes
   2737 	bra.b		_L12_6s
   2738 _L12_5s:
   2739 	bsr.l		stentoxd			# operand is a DENORM
   2740 _L12_6s:
   2741 
   2742 #
   2743 #	Result is now in FP0
   2744 #
   2745 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2746 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2747 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2748 	unlk		%a6
   2749 	rts
   2750 
   2751 	global		_ftentoxd_
   2752 _ftentoxd_:
   2753 	link		%a6,&-LOCAL_SIZE
   2754 
   2755 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2756 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2757 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2758 
   2759 	fmov.l		&0x0,%fpcr		# zero FPCR
   2760 
   2761 #
   2762 #	copy, convert, and tag input argument
   2763 #
   2764 	fmov.d		0x8(%a6),%fp0		# load dbl input
   2765 	fmov.x		%fp0,FP_SRC(%a6)
   2766 	lea		FP_SRC(%a6),%a0
   2767 	bsr.l		tag			# fetch operand type
   2768 	mov.b		%d0,STAG(%a6)
   2769 	mov.b		%d0,%d1
   2770 
   2771 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2772 
   2773 	clr.l		%d0
   2774 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2775 
   2776 	mov.b		%d1,STAG(%a6)
   2777 	tst.b		%d1
   2778 	bne.b		_L12_2d
   2779 	bsr.l		stentox			# operand is a NORM
   2780 	bra.b		_L12_6d
   2781 _L12_2d:
   2782 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2783 	bne.b		_L12_3d			# no
   2784 	bsr.l		ld_pone			# yes
   2785 	bra.b		_L12_6d
   2786 _L12_3d:
   2787 	cmpi.b		%d1,&INF		# is operand an INF?
   2788 	bne.b		_L12_4d			# no
   2789 	bsr.l		szr_inf			# yes
   2790 	bra.b		_L12_6d
   2791 _L12_4d:
   2792 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2793 	bne.b		_L12_5d			# no
   2794 	bsr.l		src_qnan			# yes
   2795 	bra.b		_L12_6d
   2796 _L12_5d:
   2797 	bsr.l		stentoxd			# operand is a DENORM
   2798 _L12_6d:
   2799 
   2800 #
   2801 #	Result is now in FP0
   2802 #
   2803 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2804 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2805 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2806 	unlk		%a6
   2807 	rts
   2808 
   2809 	global		_ftentoxx_
   2810 _ftentoxx_:
   2811 	link		%a6,&-LOCAL_SIZE
   2812 
   2813 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2814 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2815 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2816 
   2817 	fmov.l		&0x0,%fpcr		# zero FPCR
   2818 
   2819 #
   2820 #	copy, convert, and tag input argument
   2821 #
   2822 	lea		FP_SRC(%a6),%a0
   2823 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   2824 	mov.l		0x8+0x4(%a6),0x4(%a0)
   2825 	mov.l		0x8+0x8(%a6),0x8(%a0)
   2826 	bsr.l		tag			# fetch operand type
   2827 	mov.b		%d0,STAG(%a6)
   2828 	mov.b		%d0,%d1
   2829 
   2830 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2831 
   2832 	clr.l		%d0
   2833 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2834 
   2835 	tst.b		%d1
   2836 	bne.b		_L12_2x
   2837 	bsr.l		stentox			# operand is a NORM
   2838 	bra.b		_L12_6x
   2839 _L12_2x:
   2840 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2841 	bne.b		_L12_3x			# no
   2842 	bsr.l		ld_pone			# yes
   2843 	bra.b		_L12_6x
   2844 _L12_3x:
   2845 	cmpi.b		%d1,&INF		# is operand an INF?
   2846 	bne.b		_L12_4x			# no
   2847 	bsr.l		szr_inf			# yes
   2848 	bra.b		_L12_6x
   2849 _L12_4x:
   2850 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2851 	bne.b		_L12_5x			# no
   2852 	bsr.l		src_qnan			# yes
   2853 	bra.b		_L12_6x
   2854 _L12_5x:
   2855 	bsr.l		stentoxd			# operand is a DENORM
   2856 _L12_6x:
   2857 
   2858 #
   2859 #	Result is now in FP0
   2860 #
   2861 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2862 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2863 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2864 	unlk		%a6
   2865 	rts
   2866 
   2867 
   2868 #########################################################################
   2869 # MONADIC TEMPLATE							#
   2870 #########################################################################
   2871 	global		_flogns_
   2872 _flogns_:
   2873 	link		%a6,&-LOCAL_SIZE
   2874 
   2875 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2876 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2877 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2878 
   2879 	fmov.l		&0x0,%fpcr		# zero FPCR
   2880 
   2881 #
   2882 #	copy, convert, and tag input argument
   2883 #
   2884 	fmov.s		0x8(%a6),%fp0		# load sgl input
   2885 	fmov.x		%fp0,FP_SRC(%a6)
   2886 	lea		FP_SRC(%a6),%a0
   2887 	bsr.l		tag			# fetch operand type
   2888 	mov.b		%d0,STAG(%a6)
   2889 	mov.b		%d0,%d1
   2890 
   2891 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2892 
   2893 	clr.l		%d0
   2894 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2895 
   2896 	tst.b		%d1
   2897 	bne.b		_L13_2s
   2898 	bsr.l		slogn			# operand is a NORM
   2899 	bra.b		_L13_6s
   2900 _L13_2s:
   2901 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2902 	bne.b		_L13_3s			# no
   2903 	bsr.l		t_dz2			# yes
   2904 	bra.b		_L13_6s
   2905 _L13_3s:
   2906 	cmpi.b		%d1,&INF		# is operand an INF?
   2907 	bne.b		_L13_4s			# no
   2908 	bsr.l		sopr_inf			# yes
   2909 	bra.b		_L13_6s
   2910 _L13_4s:
   2911 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2912 	bne.b		_L13_5s			# no
   2913 	bsr.l		src_qnan			# yes
   2914 	bra.b		_L13_6s
   2915 _L13_5s:
   2916 	bsr.l		slognd			# operand is a DENORM
   2917 _L13_6s:
   2918 
   2919 #
   2920 #	Result is now in FP0
   2921 #
   2922 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2923 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2924 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2925 	unlk		%a6
   2926 	rts
   2927 
   2928 	global		_flognd_
   2929 _flognd_:
   2930 	link		%a6,&-LOCAL_SIZE
   2931 
   2932 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2933 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2934 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2935 
   2936 	fmov.l		&0x0,%fpcr		# zero FPCR
   2937 
   2938 #
   2939 #	copy, convert, and tag input argument
   2940 #
   2941 	fmov.d		0x8(%a6),%fp0		# load dbl input
   2942 	fmov.x		%fp0,FP_SRC(%a6)
   2943 	lea		FP_SRC(%a6),%a0
   2944 	bsr.l		tag			# fetch operand type
   2945 	mov.b		%d0,STAG(%a6)
   2946 	mov.b		%d0,%d1
   2947 
   2948 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2949 
   2950 	clr.l		%d0
   2951 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   2952 
   2953 	mov.b		%d1,STAG(%a6)
   2954 	tst.b		%d1
   2955 	bne.b		_L13_2d
   2956 	bsr.l		slogn			# operand is a NORM
   2957 	bra.b		_L13_6d
   2958 _L13_2d:
   2959 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   2960 	bne.b		_L13_3d			# no
   2961 	bsr.l		t_dz2			# yes
   2962 	bra.b		_L13_6d
   2963 _L13_3d:
   2964 	cmpi.b		%d1,&INF		# is operand an INF?
   2965 	bne.b		_L13_4d			# no
   2966 	bsr.l		sopr_inf			# yes
   2967 	bra.b		_L13_6d
   2968 _L13_4d:
   2969 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   2970 	bne.b		_L13_5d			# no
   2971 	bsr.l		src_qnan			# yes
   2972 	bra.b		_L13_6d
   2973 _L13_5d:
   2974 	bsr.l		slognd			# operand is a DENORM
   2975 _L13_6d:
   2976 
   2977 #
   2978 #	Result is now in FP0
   2979 #
   2980 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2981 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   2982 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   2983 	unlk		%a6
   2984 	rts
   2985 
   2986 	global		_flognx_
   2987 _flognx_:
   2988 	link		%a6,&-LOCAL_SIZE
   2989 
   2990 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2991 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   2992 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   2993 
   2994 	fmov.l		&0x0,%fpcr		# zero FPCR
   2995 
   2996 #
   2997 #	copy, convert, and tag input argument
   2998 #
   2999 	lea		FP_SRC(%a6),%a0
   3000 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   3001 	mov.l		0x8+0x4(%a6),0x4(%a0)
   3002 	mov.l		0x8+0x8(%a6),0x8(%a0)
   3003 	bsr.l		tag			# fetch operand type
   3004 	mov.b		%d0,STAG(%a6)
   3005 	mov.b		%d0,%d1
   3006 
   3007 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3008 
   3009 	clr.l		%d0
   3010 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3011 
   3012 	tst.b		%d1
   3013 	bne.b		_L13_2x
   3014 	bsr.l		slogn			# operand is a NORM
   3015 	bra.b		_L13_6x
   3016 _L13_2x:
   3017 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3018 	bne.b		_L13_3x			# no
   3019 	bsr.l		t_dz2			# yes
   3020 	bra.b		_L13_6x
   3021 _L13_3x:
   3022 	cmpi.b		%d1,&INF		# is operand an INF?
   3023 	bne.b		_L13_4x			# no
   3024 	bsr.l		sopr_inf			# yes
   3025 	bra.b		_L13_6x
   3026 _L13_4x:
   3027 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3028 	bne.b		_L13_5x			# no
   3029 	bsr.l		src_qnan			# yes
   3030 	bra.b		_L13_6x
   3031 _L13_5x:
   3032 	bsr.l		slognd			# operand is a DENORM
   3033 _L13_6x:
   3034 
   3035 #
   3036 #	Result is now in FP0
   3037 #
   3038 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3039 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3040 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3041 	unlk		%a6
   3042 	rts
   3043 
   3044 
   3045 #########################################################################
   3046 # MONADIC TEMPLATE							#
   3047 #########################################################################
   3048 	global		_flog10s_
   3049 _flog10s_:
   3050 	link		%a6,&-LOCAL_SIZE
   3051 
   3052 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3053 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3054 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3055 
   3056 	fmov.l		&0x0,%fpcr		# zero FPCR
   3057 
   3058 #
   3059 #	copy, convert, and tag input argument
   3060 #
   3061 	fmov.s		0x8(%a6),%fp0		# load sgl input
   3062 	fmov.x		%fp0,FP_SRC(%a6)
   3063 	lea		FP_SRC(%a6),%a0
   3064 	bsr.l		tag			# fetch operand type
   3065 	mov.b		%d0,STAG(%a6)
   3066 	mov.b		%d0,%d1
   3067 
   3068 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3069 
   3070 	clr.l		%d0
   3071 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3072 
   3073 	tst.b		%d1
   3074 	bne.b		_L14_2s
   3075 	bsr.l		slog10			# operand is a NORM
   3076 	bra.b		_L14_6s
   3077 _L14_2s:
   3078 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3079 	bne.b		_L14_3s			# no
   3080 	bsr.l		t_dz2			# yes
   3081 	bra.b		_L14_6s
   3082 _L14_3s:
   3083 	cmpi.b		%d1,&INF		# is operand an INF?
   3084 	bne.b		_L14_4s			# no
   3085 	bsr.l		sopr_inf			# yes
   3086 	bra.b		_L14_6s
   3087 _L14_4s:
   3088 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3089 	bne.b		_L14_5s			# no
   3090 	bsr.l		src_qnan			# yes
   3091 	bra.b		_L14_6s
   3092 _L14_5s:
   3093 	bsr.l		slog10d			# operand is a DENORM
   3094 _L14_6s:
   3095 
   3096 #
   3097 #	Result is now in FP0
   3098 #
   3099 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3100 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3101 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3102 	unlk		%a6
   3103 	rts
   3104 
   3105 	global		_flog10d_
   3106 _flog10d_:
   3107 	link		%a6,&-LOCAL_SIZE
   3108 
   3109 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3110 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3111 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3112 
   3113 	fmov.l		&0x0,%fpcr		# zero FPCR
   3114 
   3115 #
   3116 #	copy, convert, and tag input argument
   3117 #
   3118 	fmov.d		0x8(%a6),%fp0		# load dbl input
   3119 	fmov.x		%fp0,FP_SRC(%a6)
   3120 	lea		FP_SRC(%a6),%a0
   3121 	bsr.l		tag			# fetch operand type
   3122 	mov.b		%d0,STAG(%a6)
   3123 	mov.b		%d0,%d1
   3124 
   3125 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3126 
   3127 	clr.l		%d0
   3128 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3129 
   3130 	mov.b		%d1,STAG(%a6)
   3131 	tst.b		%d1
   3132 	bne.b		_L14_2d
   3133 	bsr.l		slog10			# operand is a NORM
   3134 	bra.b		_L14_6d
   3135 _L14_2d:
   3136 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3137 	bne.b		_L14_3d			# no
   3138 	bsr.l		t_dz2			# yes
   3139 	bra.b		_L14_6d
   3140 _L14_3d:
   3141 	cmpi.b		%d1,&INF		# is operand an INF?
   3142 	bne.b		_L14_4d			# no
   3143 	bsr.l		sopr_inf			# yes
   3144 	bra.b		_L14_6d
   3145 _L14_4d:
   3146 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3147 	bne.b		_L14_5d			# no
   3148 	bsr.l		src_qnan			# yes
   3149 	bra.b		_L14_6d
   3150 _L14_5d:
   3151 	bsr.l		slog10d			# operand is a DENORM
   3152 _L14_6d:
   3153 
   3154 #
   3155 #	Result is now in FP0
   3156 #
   3157 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3158 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3159 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3160 	unlk		%a6
   3161 	rts
   3162 
   3163 	global		_flog10x_
   3164 _flog10x_:
   3165 	link		%a6,&-LOCAL_SIZE
   3166 
   3167 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3168 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3169 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3170 
   3171 	fmov.l		&0x0,%fpcr		# zero FPCR
   3172 
   3173 #
   3174 #	copy, convert, and tag input argument
   3175 #
   3176 	lea		FP_SRC(%a6),%a0
   3177 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   3178 	mov.l		0x8+0x4(%a6),0x4(%a0)
   3179 	mov.l		0x8+0x8(%a6),0x8(%a0)
   3180 	bsr.l		tag			# fetch operand type
   3181 	mov.b		%d0,STAG(%a6)
   3182 	mov.b		%d0,%d1
   3183 
   3184 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3185 
   3186 	clr.l		%d0
   3187 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3188 
   3189 	tst.b		%d1
   3190 	bne.b		_L14_2x
   3191 	bsr.l		slog10			# operand is a NORM
   3192 	bra.b		_L14_6x
   3193 _L14_2x:
   3194 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3195 	bne.b		_L14_3x			# no
   3196 	bsr.l		t_dz2			# yes
   3197 	bra.b		_L14_6x
   3198 _L14_3x:
   3199 	cmpi.b		%d1,&INF		# is operand an INF?
   3200 	bne.b		_L14_4x			# no
   3201 	bsr.l		sopr_inf			# yes
   3202 	bra.b		_L14_6x
   3203 _L14_4x:
   3204 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3205 	bne.b		_L14_5x			# no
   3206 	bsr.l		src_qnan			# yes
   3207 	bra.b		_L14_6x
   3208 _L14_5x:
   3209 	bsr.l		slog10d			# operand is a DENORM
   3210 _L14_6x:
   3211 
   3212 #
   3213 #	Result is now in FP0
   3214 #
   3215 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3216 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3217 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3218 	unlk		%a6
   3219 	rts
   3220 
   3221 
   3222 #########################################################################
   3223 # MONADIC TEMPLATE							#
   3224 #########################################################################
   3225 	global		_flog2s_
   3226 _flog2s_:
   3227 	link		%a6,&-LOCAL_SIZE
   3228 
   3229 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3230 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3231 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3232 
   3233 	fmov.l		&0x0,%fpcr		# zero FPCR
   3234 
   3235 #
   3236 #	copy, convert, and tag input argument
   3237 #
   3238 	fmov.s		0x8(%a6),%fp0		# load sgl input
   3239 	fmov.x		%fp0,FP_SRC(%a6)
   3240 	lea		FP_SRC(%a6),%a0
   3241 	bsr.l		tag			# fetch operand type
   3242 	mov.b		%d0,STAG(%a6)
   3243 	mov.b		%d0,%d1
   3244 
   3245 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3246 
   3247 	clr.l		%d0
   3248 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3249 
   3250 	tst.b		%d1
   3251 	bne.b		_L15_2s
   3252 	bsr.l		slog2			# operand is a NORM
   3253 	bra.b		_L15_6s
   3254 _L15_2s:
   3255 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3256 	bne.b		_L15_3s			# no
   3257 	bsr.l		t_dz2			# yes
   3258 	bra.b		_L15_6s
   3259 _L15_3s:
   3260 	cmpi.b		%d1,&INF		# is operand an INF?
   3261 	bne.b		_L15_4s			# no
   3262 	bsr.l		sopr_inf			# yes
   3263 	bra.b		_L15_6s
   3264 _L15_4s:
   3265 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3266 	bne.b		_L15_5s			# no
   3267 	bsr.l		src_qnan			# yes
   3268 	bra.b		_L15_6s
   3269 _L15_5s:
   3270 	bsr.l		slog2d			# operand is a DENORM
   3271 _L15_6s:
   3272 
   3273 #
   3274 #	Result is now in FP0
   3275 #
   3276 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3277 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3278 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3279 	unlk		%a6
   3280 	rts
   3281 
   3282 	global		_flog2d_
   3283 _flog2d_:
   3284 	link		%a6,&-LOCAL_SIZE
   3285 
   3286 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3287 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3288 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3289 
   3290 	fmov.l		&0x0,%fpcr		# zero FPCR
   3291 
   3292 #
   3293 #	copy, convert, and tag input argument
   3294 #
   3295 	fmov.d		0x8(%a6),%fp0		# load dbl input
   3296 	fmov.x		%fp0,FP_SRC(%a6)
   3297 	lea		FP_SRC(%a6),%a0
   3298 	bsr.l		tag			# fetch operand type
   3299 	mov.b		%d0,STAG(%a6)
   3300 	mov.b		%d0,%d1
   3301 
   3302 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3303 
   3304 	clr.l		%d0
   3305 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3306 
   3307 	mov.b		%d1,STAG(%a6)
   3308 	tst.b		%d1
   3309 	bne.b		_L15_2d
   3310 	bsr.l		slog2			# operand is a NORM
   3311 	bra.b		_L15_6d
   3312 _L15_2d:
   3313 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3314 	bne.b		_L15_3d			# no
   3315 	bsr.l		t_dz2			# yes
   3316 	bra.b		_L15_6d
   3317 _L15_3d:
   3318 	cmpi.b		%d1,&INF		# is operand an INF?
   3319 	bne.b		_L15_4d			# no
   3320 	bsr.l		sopr_inf			# yes
   3321 	bra.b		_L15_6d
   3322 _L15_4d:
   3323 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3324 	bne.b		_L15_5d			# no
   3325 	bsr.l		src_qnan			# yes
   3326 	bra.b		_L15_6d
   3327 _L15_5d:
   3328 	bsr.l		slog2d			# operand is a DENORM
   3329 _L15_6d:
   3330 
   3331 #
   3332 #	Result is now in FP0
   3333 #
   3334 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3335 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3336 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3337 	unlk		%a6
   3338 	rts
   3339 
   3340 	global		_flog2x_
   3341 _flog2x_:
   3342 	link		%a6,&-LOCAL_SIZE
   3343 
   3344 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3345 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3346 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3347 
   3348 	fmov.l		&0x0,%fpcr		# zero FPCR
   3349 
   3350 #
   3351 #	copy, convert, and tag input argument
   3352 #
   3353 	lea		FP_SRC(%a6),%a0
   3354 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   3355 	mov.l		0x8+0x4(%a6),0x4(%a0)
   3356 	mov.l		0x8+0x8(%a6),0x8(%a0)
   3357 	bsr.l		tag			# fetch operand type
   3358 	mov.b		%d0,STAG(%a6)
   3359 	mov.b		%d0,%d1
   3360 
   3361 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3362 
   3363 	clr.l		%d0
   3364 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3365 
   3366 	tst.b		%d1
   3367 	bne.b		_L15_2x
   3368 	bsr.l		slog2			# operand is a NORM
   3369 	bra.b		_L15_6x
   3370 _L15_2x:
   3371 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3372 	bne.b		_L15_3x			# no
   3373 	bsr.l		t_dz2			# yes
   3374 	bra.b		_L15_6x
   3375 _L15_3x:
   3376 	cmpi.b		%d1,&INF		# is operand an INF?
   3377 	bne.b		_L15_4x			# no
   3378 	bsr.l		sopr_inf			# yes
   3379 	bra.b		_L15_6x
   3380 _L15_4x:
   3381 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3382 	bne.b		_L15_5x			# no
   3383 	bsr.l		src_qnan			# yes
   3384 	bra.b		_L15_6x
   3385 _L15_5x:
   3386 	bsr.l		slog2d			# operand is a DENORM
   3387 _L15_6x:
   3388 
   3389 #
   3390 #	Result is now in FP0
   3391 #
   3392 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3393 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3394 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3395 	unlk		%a6
   3396 	rts
   3397 
   3398 
   3399 #########################################################################
   3400 # MONADIC TEMPLATE							#
   3401 #########################################################################
   3402 	global		_fcoshs_
   3403 _fcoshs_:
   3404 	link		%a6,&-LOCAL_SIZE
   3405 
   3406 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3407 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3408 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3409 
   3410 	fmov.l		&0x0,%fpcr		# zero FPCR
   3411 
   3412 #
   3413 #	copy, convert, and tag input argument
   3414 #
   3415 	fmov.s		0x8(%a6),%fp0		# load sgl input
   3416 	fmov.x		%fp0,FP_SRC(%a6)
   3417 	lea		FP_SRC(%a6),%a0
   3418 	bsr.l		tag			# fetch operand type
   3419 	mov.b		%d0,STAG(%a6)
   3420 	mov.b		%d0,%d1
   3421 
   3422 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3423 
   3424 	clr.l		%d0
   3425 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3426 
   3427 	tst.b		%d1
   3428 	bne.b		_L16_2s
   3429 	bsr.l		scosh			# operand is a NORM
   3430 	bra.b		_L16_6s
   3431 _L16_2s:
   3432 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3433 	bne.b		_L16_3s			# no
   3434 	bsr.l		ld_pone			# yes
   3435 	bra.b		_L16_6s
   3436 _L16_3s:
   3437 	cmpi.b		%d1,&INF		# is operand an INF?
   3438 	bne.b		_L16_4s			# no
   3439 	bsr.l		ld_pinf			# yes
   3440 	bra.b		_L16_6s
   3441 _L16_4s:
   3442 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3443 	bne.b		_L16_5s			# no
   3444 	bsr.l		src_qnan			# yes
   3445 	bra.b		_L16_6s
   3446 _L16_5s:
   3447 	bsr.l		scoshd			# operand is a DENORM
   3448 _L16_6s:
   3449 
   3450 #
   3451 #	Result is now in FP0
   3452 #
   3453 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3454 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3455 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3456 	unlk		%a6
   3457 	rts
   3458 
   3459 	global		_fcoshd_
   3460 _fcoshd_:
   3461 	link		%a6,&-LOCAL_SIZE
   3462 
   3463 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3464 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3465 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3466 
   3467 	fmov.l		&0x0,%fpcr		# zero FPCR
   3468 
   3469 #
   3470 #	copy, convert, and tag input argument
   3471 #
   3472 	fmov.d		0x8(%a6),%fp0		# load dbl input
   3473 	fmov.x		%fp0,FP_SRC(%a6)
   3474 	lea		FP_SRC(%a6),%a0
   3475 	bsr.l		tag			# fetch operand type
   3476 	mov.b		%d0,STAG(%a6)
   3477 	mov.b		%d0,%d1
   3478 
   3479 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3480 
   3481 	clr.l		%d0
   3482 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3483 
   3484 	mov.b		%d1,STAG(%a6)
   3485 	tst.b		%d1
   3486 	bne.b		_L16_2d
   3487 	bsr.l		scosh			# operand is a NORM
   3488 	bra.b		_L16_6d
   3489 _L16_2d:
   3490 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3491 	bne.b		_L16_3d			# no
   3492 	bsr.l		ld_pone			# yes
   3493 	bra.b		_L16_6d
   3494 _L16_3d:
   3495 	cmpi.b		%d1,&INF		# is operand an INF?
   3496 	bne.b		_L16_4d			# no
   3497 	bsr.l		ld_pinf			# yes
   3498 	bra.b		_L16_6d
   3499 _L16_4d:
   3500 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3501 	bne.b		_L16_5d			# no
   3502 	bsr.l		src_qnan			# yes
   3503 	bra.b		_L16_6d
   3504 _L16_5d:
   3505 	bsr.l		scoshd			# operand is a DENORM
   3506 _L16_6d:
   3507 
   3508 #
   3509 #	Result is now in FP0
   3510 #
   3511 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3512 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3513 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3514 	unlk		%a6
   3515 	rts
   3516 
   3517 	global		_fcoshx_
   3518 _fcoshx_:
   3519 	link		%a6,&-LOCAL_SIZE
   3520 
   3521 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3522 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3523 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3524 
   3525 	fmov.l		&0x0,%fpcr		# zero FPCR
   3526 
   3527 #
   3528 #	copy, convert, and tag input argument
   3529 #
   3530 	lea		FP_SRC(%a6),%a0
   3531 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   3532 	mov.l		0x8+0x4(%a6),0x4(%a0)
   3533 	mov.l		0x8+0x8(%a6),0x8(%a0)
   3534 	bsr.l		tag			# fetch operand type
   3535 	mov.b		%d0,STAG(%a6)
   3536 	mov.b		%d0,%d1
   3537 
   3538 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3539 
   3540 	clr.l		%d0
   3541 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3542 
   3543 	tst.b		%d1
   3544 	bne.b		_L16_2x
   3545 	bsr.l		scosh			# operand is a NORM
   3546 	bra.b		_L16_6x
   3547 _L16_2x:
   3548 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3549 	bne.b		_L16_3x			# no
   3550 	bsr.l		ld_pone			# yes
   3551 	bra.b		_L16_6x
   3552 _L16_3x:
   3553 	cmpi.b		%d1,&INF		# is operand an INF?
   3554 	bne.b		_L16_4x			# no
   3555 	bsr.l		ld_pinf			# yes
   3556 	bra.b		_L16_6x
   3557 _L16_4x:
   3558 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3559 	bne.b		_L16_5x			# no
   3560 	bsr.l		src_qnan			# yes
   3561 	bra.b		_L16_6x
   3562 _L16_5x:
   3563 	bsr.l		scoshd			# operand is a DENORM
   3564 _L16_6x:
   3565 
   3566 #
   3567 #	Result is now in FP0
   3568 #
   3569 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3570 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3571 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3572 	unlk		%a6
   3573 	rts
   3574 
   3575 
   3576 #########################################################################
   3577 # MONADIC TEMPLATE							#
   3578 #########################################################################
   3579 	global		_facoss_
   3580 _facoss_:
   3581 	link		%a6,&-LOCAL_SIZE
   3582 
   3583 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3584 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3585 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3586 
   3587 	fmov.l		&0x0,%fpcr		# zero FPCR
   3588 
   3589 #
   3590 #	copy, convert, and tag input argument
   3591 #
   3592 	fmov.s		0x8(%a6),%fp0		# load sgl input
   3593 	fmov.x		%fp0,FP_SRC(%a6)
   3594 	lea		FP_SRC(%a6),%a0
   3595 	bsr.l		tag			# fetch operand type
   3596 	mov.b		%d0,STAG(%a6)
   3597 	mov.b		%d0,%d1
   3598 
   3599 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3600 
   3601 	clr.l		%d0
   3602 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3603 
   3604 	tst.b		%d1
   3605 	bne.b		_L17_2s
   3606 	bsr.l		sacos			# operand is a NORM
   3607 	bra.b		_L17_6s
   3608 _L17_2s:
   3609 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3610 	bne.b		_L17_3s			# no
   3611 	bsr.l		ld_ppi2			# yes
   3612 	bra.b		_L17_6s
   3613 _L17_3s:
   3614 	cmpi.b		%d1,&INF		# is operand an INF?
   3615 	bne.b		_L17_4s			# no
   3616 	bsr.l		t_operr			# yes
   3617 	bra.b		_L17_6s
   3618 _L17_4s:
   3619 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3620 	bne.b		_L17_5s			# no
   3621 	bsr.l		src_qnan			# yes
   3622 	bra.b		_L17_6s
   3623 _L17_5s:
   3624 	bsr.l		sacosd			# operand is a DENORM
   3625 _L17_6s:
   3626 
   3627 #
   3628 #	Result is now in FP0
   3629 #
   3630 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3631 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3632 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3633 	unlk		%a6
   3634 	rts
   3635 
   3636 	global		_facosd_
   3637 _facosd_:
   3638 	link		%a6,&-LOCAL_SIZE
   3639 
   3640 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3641 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3642 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3643 
   3644 	fmov.l		&0x0,%fpcr		# zero FPCR
   3645 
   3646 #
   3647 #	copy, convert, and tag input argument
   3648 #
   3649 	fmov.d		0x8(%a6),%fp0		# load dbl input
   3650 	fmov.x		%fp0,FP_SRC(%a6)
   3651 	lea		FP_SRC(%a6),%a0
   3652 	bsr.l		tag			# fetch operand type
   3653 	mov.b		%d0,STAG(%a6)
   3654 	mov.b		%d0,%d1
   3655 
   3656 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3657 
   3658 	clr.l		%d0
   3659 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3660 
   3661 	mov.b		%d1,STAG(%a6)
   3662 	tst.b		%d1
   3663 	bne.b		_L17_2d
   3664 	bsr.l		sacos			# operand is a NORM
   3665 	bra.b		_L17_6d
   3666 _L17_2d:
   3667 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3668 	bne.b		_L17_3d			# no
   3669 	bsr.l		ld_ppi2			# yes
   3670 	bra.b		_L17_6d
   3671 _L17_3d:
   3672 	cmpi.b		%d1,&INF		# is operand an INF?
   3673 	bne.b		_L17_4d			# no
   3674 	bsr.l		t_operr			# yes
   3675 	bra.b		_L17_6d
   3676 _L17_4d:
   3677 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3678 	bne.b		_L17_5d			# no
   3679 	bsr.l		src_qnan			# yes
   3680 	bra.b		_L17_6d
   3681 _L17_5d:
   3682 	bsr.l		sacosd			# operand is a DENORM
   3683 _L17_6d:
   3684 
   3685 #
   3686 #	Result is now in FP0
   3687 #
   3688 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3689 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3690 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3691 	unlk		%a6
   3692 	rts
   3693 
   3694 	global		_facosx_
   3695 _facosx_:
   3696 	link		%a6,&-LOCAL_SIZE
   3697 
   3698 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3699 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3700 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3701 
   3702 	fmov.l		&0x0,%fpcr		# zero FPCR
   3703 
   3704 #
   3705 #	copy, convert, and tag input argument
   3706 #
   3707 	lea		FP_SRC(%a6),%a0
   3708 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   3709 	mov.l		0x8+0x4(%a6),0x4(%a0)
   3710 	mov.l		0x8+0x8(%a6),0x8(%a0)
   3711 	bsr.l		tag			# fetch operand type
   3712 	mov.b		%d0,STAG(%a6)
   3713 	mov.b		%d0,%d1
   3714 
   3715 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3716 
   3717 	clr.l		%d0
   3718 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3719 
   3720 	tst.b		%d1
   3721 	bne.b		_L17_2x
   3722 	bsr.l		sacos			# operand is a NORM
   3723 	bra.b		_L17_6x
   3724 _L17_2x:
   3725 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3726 	bne.b		_L17_3x			# no
   3727 	bsr.l		ld_ppi2			# yes
   3728 	bra.b		_L17_6x
   3729 _L17_3x:
   3730 	cmpi.b		%d1,&INF		# is operand an INF?
   3731 	bne.b		_L17_4x			# no
   3732 	bsr.l		t_operr			# yes
   3733 	bra.b		_L17_6x
   3734 _L17_4x:
   3735 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3736 	bne.b		_L17_5x			# no
   3737 	bsr.l		src_qnan			# yes
   3738 	bra.b		_L17_6x
   3739 _L17_5x:
   3740 	bsr.l		sacosd			# operand is a DENORM
   3741 _L17_6x:
   3742 
   3743 #
   3744 #	Result is now in FP0
   3745 #
   3746 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3747 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3748 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3749 	unlk		%a6
   3750 	rts
   3751 
   3752 
   3753 #########################################################################
   3754 # MONADIC TEMPLATE							#
   3755 #########################################################################
   3756 	global		_fgetexps_
   3757 _fgetexps_:
   3758 	link		%a6,&-LOCAL_SIZE
   3759 
   3760 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3761 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3762 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3763 
   3764 	fmov.l		&0x0,%fpcr		# zero FPCR
   3765 
   3766 #
   3767 #	copy, convert, and tag input argument
   3768 #
   3769 	fmov.s		0x8(%a6),%fp0		# load sgl input
   3770 	fmov.x		%fp0,FP_SRC(%a6)
   3771 	lea		FP_SRC(%a6),%a0
   3772 	bsr.l		tag			# fetch operand type
   3773 	mov.b		%d0,STAG(%a6)
   3774 	mov.b		%d0,%d1
   3775 
   3776 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3777 
   3778 	clr.l		%d0
   3779 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3780 
   3781 	tst.b		%d1
   3782 	bne.b		_L18_2s
   3783 	bsr.l		sgetexp			# operand is a NORM
   3784 	bra.b		_L18_6s
   3785 _L18_2s:
   3786 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3787 	bne.b		_L18_3s			# no
   3788 	bsr.l		src_zero			# yes
   3789 	bra.b		_L18_6s
   3790 _L18_3s:
   3791 	cmpi.b		%d1,&INF		# is operand an INF?
   3792 	bne.b		_L18_4s			# no
   3793 	bsr.l		t_operr			# yes
   3794 	bra.b		_L18_6s
   3795 _L18_4s:
   3796 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3797 	bne.b		_L18_5s			# no
   3798 	bsr.l		src_qnan			# yes
   3799 	bra.b		_L18_6s
   3800 _L18_5s:
   3801 	bsr.l		sgetexpd			# operand is a DENORM
   3802 _L18_6s:
   3803 
   3804 #
   3805 #	Result is now in FP0
   3806 #
   3807 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3808 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3809 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3810 	unlk		%a6
   3811 	rts
   3812 
   3813 	global		_fgetexpd_
   3814 _fgetexpd_:
   3815 	link		%a6,&-LOCAL_SIZE
   3816 
   3817 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3818 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3819 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3820 
   3821 	fmov.l		&0x0,%fpcr		# zero FPCR
   3822 
   3823 #
   3824 #	copy, convert, and tag input argument
   3825 #
   3826 	fmov.d		0x8(%a6),%fp0		# load dbl input
   3827 	fmov.x		%fp0,FP_SRC(%a6)
   3828 	lea		FP_SRC(%a6),%a0
   3829 	bsr.l		tag			# fetch operand type
   3830 	mov.b		%d0,STAG(%a6)
   3831 	mov.b		%d0,%d1
   3832 
   3833 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3834 
   3835 	clr.l		%d0
   3836 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3837 
   3838 	mov.b		%d1,STAG(%a6)
   3839 	tst.b		%d1
   3840 	bne.b		_L18_2d
   3841 	bsr.l		sgetexp			# operand is a NORM
   3842 	bra.b		_L18_6d
   3843 _L18_2d:
   3844 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3845 	bne.b		_L18_3d			# no
   3846 	bsr.l		src_zero			# yes
   3847 	bra.b		_L18_6d
   3848 _L18_3d:
   3849 	cmpi.b		%d1,&INF		# is operand an INF?
   3850 	bne.b		_L18_4d			# no
   3851 	bsr.l		t_operr			# yes
   3852 	bra.b		_L18_6d
   3853 _L18_4d:
   3854 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3855 	bne.b		_L18_5d			# no
   3856 	bsr.l		src_qnan			# yes
   3857 	bra.b		_L18_6d
   3858 _L18_5d:
   3859 	bsr.l		sgetexpd			# operand is a DENORM
   3860 _L18_6d:
   3861 
   3862 #
   3863 #	Result is now in FP0
   3864 #
   3865 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3866 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3867 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3868 	unlk		%a6
   3869 	rts
   3870 
   3871 	global		_fgetexpx_
   3872 _fgetexpx_:
   3873 	link		%a6,&-LOCAL_SIZE
   3874 
   3875 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3876 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3877 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3878 
   3879 	fmov.l		&0x0,%fpcr		# zero FPCR
   3880 
   3881 #
   3882 #	copy, convert, and tag input argument
   3883 #
   3884 	lea		FP_SRC(%a6),%a0
   3885 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   3886 	mov.l		0x8+0x4(%a6),0x4(%a0)
   3887 	mov.l		0x8+0x8(%a6),0x8(%a0)
   3888 	bsr.l		tag			# fetch operand type
   3889 	mov.b		%d0,STAG(%a6)
   3890 	mov.b		%d0,%d1
   3891 
   3892 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3893 
   3894 	clr.l		%d0
   3895 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3896 
   3897 	tst.b		%d1
   3898 	bne.b		_L18_2x
   3899 	bsr.l		sgetexp			# operand is a NORM
   3900 	bra.b		_L18_6x
   3901 _L18_2x:
   3902 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3903 	bne.b		_L18_3x			# no
   3904 	bsr.l		src_zero			# yes
   3905 	bra.b		_L18_6x
   3906 _L18_3x:
   3907 	cmpi.b		%d1,&INF		# is operand an INF?
   3908 	bne.b		_L18_4x			# no
   3909 	bsr.l		t_operr			# yes
   3910 	bra.b		_L18_6x
   3911 _L18_4x:
   3912 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3913 	bne.b		_L18_5x			# no
   3914 	bsr.l		src_qnan			# yes
   3915 	bra.b		_L18_6x
   3916 _L18_5x:
   3917 	bsr.l		sgetexpd			# operand is a DENORM
   3918 _L18_6x:
   3919 
   3920 #
   3921 #	Result is now in FP0
   3922 #
   3923 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3924 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3925 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3926 	unlk		%a6
   3927 	rts
   3928 
   3929 
   3930 #########################################################################
   3931 # MONADIC TEMPLATE							#
   3932 #########################################################################
   3933 	global		_fgetmans_
   3934 _fgetmans_:
   3935 	link		%a6,&-LOCAL_SIZE
   3936 
   3937 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3938 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3939 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3940 
   3941 	fmov.l		&0x0,%fpcr		# zero FPCR
   3942 
   3943 #
   3944 #	copy, convert, and tag input argument
   3945 #
   3946 	fmov.s		0x8(%a6),%fp0		# load sgl input
   3947 	fmov.x		%fp0,FP_SRC(%a6)
   3948 	lea		FP_SRC(%a6),%a0
   3949 	bsr.l		tag			# fetch operand type
   3950 	mov.b		%d0,STAG(%a6)
   3951 	mov.b		%d0,%d1
   3952 
   3953 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   3954 
   3955 	clr.l		%d0
   3956 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   3957 
   3958 	tst.b		%d1
   3959 	bne.b		_L19_2s
   3960 	bsr.l		sgetman			# operand is a NORM
   3961 	bra.b		_L19_6s
   3962 _L19_2s:
   3963 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   3964 	bne.b		_L19_3s			# no
   3965 	bsr.l		src_zero			# yes
   3966 	bra.b		_L19_6s
   3967 _L19_3s:
   3968 	cmpi.b		%d1,&INF		# is operand an INF?
   3969 	bne.b		_L19_4s			# no
   3970 	bsr.l		t_operr			# yes
   3971 	bra.b		_L19_6s
   3972 _L19_4s:
   3973 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   3974 	bne.b		_L19_5s			# no
   3975 	bsr.l		src_qnan			# yes
   3976 	bra.b		_L19_6s
   3977 _L19_5s:
   3978 	bsr.l		sgetmand			# operand is a DENORM
   3979 _L19_6s:
   3980 
   3981 #
   3982 #	Result is now in FP0
   3983 #
   3984 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3985 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   3986 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   3987 	unlk		%a6
   3988 	rts
   3989 
   3990 	global		_fgetmand_
   3991 _fgetmand_:
   3992 	link		%a6,&-LOCAL_SIZE
   3993 
   3994 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3995 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   3996 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   3997 
   3998 	fmov.l		&0x0,%fpcr		# zero FPCR
   3999 
   4000 #
   4001 #	copy, convert, and tag input argument
   4002 #
   4003 	fmov.d		0x8(%a6),%fp0		# load dbl input
   4004 	fmov.x		%fp0,FP_SRC(%a6)
   4005 	lea		FP_SRC(%a6),%a0
   4006 	bsr.l		tag			# fetch operand type
   4007 	mov.b		%d0,STAG(%a6)
   4008 	mov.b		%d0,%d1
   4009 
   4010 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4011 
   4012 	clr.l		%d0
   4013 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4014 
   4015 	mov.b		%d1,STAG(%a6)
   4016 	tst.b		%d1
   4017 	bne.b		_L19_2d
   4018 	bsr.l		sgetman			# operand is a NORM
   4019 	bra.b		_L19_6d
   4020 _L19_2d:
   4021 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4022 	bne.b		_L19_3d			# no
   4023 	bsr.l		src_zero			# yes
   4024 	bra.b		_L19_6d
   4025 _L19_3d:
   4026 	cmpi.b		%d1,&INF		# is operand an INF?
   4027 	bne.b		_L19_4d			# no
   4028 	bsr.l		t_operr			# yes
   4029 	bra.b		_L19_6d
   4030 _L19_4d:
   4031 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4032 	bne.b		_L19_5d			# no
   4033 	bsr.l		src_qnan			# yes
   4034 	bra.b		_L19_6d
   4035 _L19_5d:
   4036 	bsr.l		sgetmand			# operand is a DENORM
   4037 _L19_6d:
   4038 
   4039 #
   4040 #	Result is now in FP0
   4041 #
   4042 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4043 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4044 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4045 	unlk		%a6
   4046 	rts
   4047 
   4048 	global		_fgetmanx_
   4049 _fgetmanx_:
   4050 	link		%a6,&-LOCAL_SIZE
   4051 
   4052 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4053 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4054 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4055 
   4056 	fmov.l		&0x0,%fpcr		# zero FPCR
   4057 
   4058 #
   4059 #	copy, convert, and tag input argument
   4060 #
   4061 	lea		FP_SRC(%a6),%a0
   4062 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   4063 	mov.l		0x8+0x4(%a6),0x4(%a0)
   4064 	mov.l		0x8+0x8(%a6),0x8(%a0)
   4065 	bsr.l		tag			# fetch operand type
   4066 	mov.b		%d0,STAG(%a6)
   4067 	mov.b		%d0,%d1
   4068 
   4069 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4070 
   4071 	clr.l		%d0
   4072 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4073 
   4074 	tst.b		%d1
   4075 	bne.b		_L19_2x
   4076 	bsr.l		sgetman			# operand is a NORM
   4077 	bra.b		_L19_6x
   4078 _L19_2x:
   4079 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4080 	bne.b		_L19_3x			# no
   4081 	bsr.l		src_zero			# yes
   4082 	bra.b		_L19_6x
   4083 _L19_3x:
   4084 	cmpi.b		%d1,&INF		# is operand an INF?
   4085 	bne.b		_L19_4x			# no
   4086 	bsr.l		t_operr			# yes
   4087 	bra.b		_L19_6x
   4088 _L19_4x:
   4089 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4090 	bne.b		_L19_5x			# no
   4091 	bsr.l		src_qnan			# yes
   4092 	bra.b		_L19_6x
   4093 _L19_5x:
   4094 	bsr.l		sgetmand			# operand is a DENORM
   4095 _L19_6x:
   4096 
   4097 #
   4098 #	Result is now in FP0
   4099 #
   4100 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4101 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4102 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4103 	unlk		%a6
   4104 	rts
   4105 
   4106 
   4107 #########################################################################
   4108 # MONADIC TEMPLATE							#
   4109 #########################################################################
   4110 	global		_fsincoss_
   4111 _fsincoss_:
   4112 	link		%a6,&-LOCAL_SIZE
   4113 
   4114 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4115 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4116 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4117 
   4118 	fmov.l		&0x0,%fpcr		# zero FPCR
   4119 
   4120 #
   4121 #	copy, convert, and tag input argument
   4122 #
   4123 	fmov.s		0x8(%a6),%fp0		# load sgl input
   4124 	fmov.x		%fp0,FP_SRC(%a6)
   4125 	lea		FP_SRC(%a6),%a0
   4126 	bsr.l		tag			# fetch operand type
   4127 	mov.b		%d0,STAG(%a6)
   4128 	mov.b		%d0,%d1
   4129 
   4130 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4131 
   4132 	clr.l		%d0
   4133 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4134 
   4135 	tst.b		%d1
   4136 	bne.b		_L20_2s
   4137 	bsr.l		ssincos			# operand is a NORM
   4138 	bra.b		_L20_6s
   4139 _L20_2s:
   4140 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4141 	bne.b		_L20_3s			# no
   4142 	bsr.l		ssincosz			# yes
   4143 	bra.b		_L20_6s
   4144 _L20_3s:
   4145 	cmpi.b		%d1,&INF		# is operand an INF?
   4146 	bne.b		_L20_4s			# no
   4147 	bsr.l		ssincosi			# yes
   4148 	bra.b		_L20_6s
   4149 _L20_4s:
   4150 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4151 	bne.b		_L20_5s			# no
   4152 	bsr.l		ssincosqnan			# yes
   4153 	bra.b		_L20_6s
   4154 _L20_5s:
   4155 	bsr.l		ssincosd			# operand is a DENORM
   4156 _L20_6s:
   4157 
   4158 #
   4159 #	Result is now in FP0
   4160 #
   4161 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4162 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4163 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
   4164 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
   4165 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
   4166 	unlk		%a6
   4167 	rts
   4168 
   4169 	global		_fsincosd_
   4170 _fsincosd_:
   4171 	link		%a6,&-LOCAL_SIZE
   4172 
   4173 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4174 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4175 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4176 
   4177 	fmov.l		&0x0,%fpcr		# zero FPCR
   4178 
   4179 #
   4180 #	copy, convert, and tag input argument
   4181 #
   4182 	fmov.d		0x8(%a6),%fp0		# load dbl input
   4183 	fmov.x		%fp0,FP_SRC(%a6)
   4184 	lea		FP_SRC(%a6),%a0
   4185 	bsr.l		tag			# fetch operand type
   4186 	mov.b		%d0,STAG(%a6)
   4187 	mov.b		%d0,%d1
   4188 
   4189 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4190 
   4191 	clr.l		%d0
   4192 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4193 
   4194 	mov.b		%d1,STAG(%a6)
   4195 	tst.b		%d1
   4196 	bne.b		_L20_2d
   4197 	bsr.l		ssincos			# operand is a NORM
   4198 	bra.b		_L20_6d
   4199 _L20_2d:
   4200 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4201 	bne.b		_L20_3d			# no
   4202 	bsr.l		ssincosz			# yes
   4203 	bra.b		_L20_6d
   4204 _L20_3d:
   4205 	cmpi.b		%d1,&INF		# is operand an INF?
   4206 	bne.b		_L20_4d			# no
   4207 	bsr.l		ssincosi			# yes
   4208 	bra.b		_L20_6d
   4209 _L20_4d:
   4210 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4211 	bne.b		_L20_5d			# no
   4212 	bsr.l		ssincosqnan			# yes
   4213 	bra.b		_L20_6d
   4214 _L20_5d:
   4215 	bsr.l		ssincosd			# operand is a DENORM
   4216 _L20_6d:
   4217 
   4218 #
   4219 #	Result is now in FP0
   4220 #
   4221 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4222 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4223 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
   4224 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
   4225 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
   4226 	unlk		%a6
   4227 	rts
   4228 
   4229 	global		_fsincosx_
   4230 _fsincosx_:
   4231 	link		%a6,&-LOCAL_SIZE
   4232 
   4233 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4234 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4235 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4236 
   4237 	fmov.l		&0x0,%fpcr		# zero FPCR
   4238 
   4239 #
   4240 #	copy, convert, and tag input argument
   4241 #
   4242 	lea		FP_SRC(%a6),%a0
   4243 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext input
   4244 	mov.l		0x8+0x4(%a6),0x4(%a0)
   4245 	mov.l		0x8+0x8(%a6),0x8(%a0)
   4246 	bsr.l		tag			# fetch operand type
   4247 	mov.b		%d0,STAG(%a6)
   4248 	mov.b		%d0,%d1
   4249 
   4250 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4251 
   4252 	clr.l		%d0
   4253 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4254 
   4255 	tst.b		%d1
   4256 	bne.b		_L20_2x
   4257 	bsr.l		ssincos			# operand is a NORM
   4258 	bra.b		_L20_6x
   4259 _L20_2x:
   4260 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4261 	bne.b		_L20_3x			# no
   4262 	bsr.l		ssincosz			# yes
   4263 	bra.b		_L20_6x
   4264 _L20_3x:
   4265 	cmpi.b		%d1,&INF		# is operand an INF?
   4266 	bne.b		_L20_4x			# no
   4267 	bsr.l		ssincosi			# yes
   4268 	bra.b		_L20_6x
   4269 _L20_4x:
   4270 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4271 	bne.b		_L20_5x			# no
   4272 	bsr.l		ssincosqnan			# yes
   4273 	bra.b		_L20_6x
   4274 _L20_5x:
   4275 	bsr.l		ssincosd			# operand is a DENORM
   4276 _L20_6x:
   4277 
   4278 #
   4279 #	Result is now in FP0
   4280 #
   4281 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4282 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4283 	fmovm.x		&0x03,-(%sp)		# store off fp0/fp1
   4284 	fmovm.x		(%sp)+,&0x40		# fp0 now in fp1
   4285 	fmovm.x		(%sp)+,&0x80		# fp1 now in fp0
   4286 	unlk		%a6
   4287 	rts
   4288 
   4289 
   4290 #########################################################################
   4291 # DYADIC TEMPLATE							#
   4292 #########################################################################
   4293 	global		_frems_
   4294 _frems_:
   4295 	link		%a6,&-LOCAL_SIZE
   4296 
   4297 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4298 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4299 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4300 
   4301 	fmov.l		&0x0,%fpcr		# zero FPCR
   4302 
   4303 #
   4304 #	copy, convert, and tag input argument
   4305 #
   4306 	fmov.s		0x8(%a6),%fp0		# load sgl dst
   4307 	fmov.x		%fp0,FP_DST(%a6)
   4308 	lea		FP_DST(%a6),%a0
   4309 	bsr.l		tag			# fetch operand type
   4310 	mov.b		%d0,DTAG(%a6)
   4311 
   4312 	fmov.s		0xc(%a6),%fp0		# load sgl src
   4313 	fmov.x		%fp0,FP_SRC(%a6)
   4314 	lea		FP_SRC(%a6),%a0
   4315 	bsr.l		tag			# fetch operand type
   4316 	mov.b		%d0,STAG(%a6)
   4317 	mov.l		%d0,%d1
   4318 
   4319 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4320 
   4321 	clr.l		%d0
   4322 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4323 
   4324 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4325 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4326 
   4327 	tst.b		%d1
   4328 	bne.b		_L21_2s
   4329 	bsr.l		srem_snorm			# operand is a NORM
   4330 	bra.b		_L21_6s
   4331 _L21_2s:
   4332 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4333 	bne.b		_L21_3s			# no
   4334 	bsr.l		srem_szero			# yes
   4335 	bra.b		_L21_6s
   4336 _L21_3s:
   4337 	cmpi.b		%d1,&INF		# is operand an INF?
   4338 	bne.b		_L21_4s			# no
   4339 	bsr.l		srem_sinf			# yes
   4340 	bra.b		_L21_6s
   4341 _L21_4s:
   4342 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4343 	bne.b		_L21_5s			# no
   4344 	bsr.l		sop_sqnan			# yes
   4345 	bra.b		_L21_6s
   4346 _L21_5s:
   4347 	bsr.l		srem_sdnrm			# operand is a DENORM
   4348 _L21_6s:
   4349 
   4350 #
   4351 #	Result is now in FP0
   4352 #
   4353 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4354 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4355 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4356 	unlk		%a6
   4357 	rts
   4358 
   4359 	global		_fremd_
   4360 _fremd_:
   4361 	link		%a6,&-LOCAL_SIZE
   4362 
   4363 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4364 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4365 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4366 
   4367 	fmov.l		&0x0,%fpcr		# zero FPCR
   4368 
   4369 #
   4370 #	copy, convert, and tag input argument
   4371 #
   4372 	fmov.d		0x8(%a6),%fp0		# load dbl dst
   4373 	fmov.x		%fp0,FP_DST(%a6)
   4374 	lea		FP_DST(%a6),%a0
   4375 	bsr.l		tag			# fetch operand type
   4376 	mov.b		%d0,DTAG(%a6)
   4377 
   4378 	fmov.d		0x10(%a6),%fp0		# load dbl src
   4379 	fmov.x		%fp0,FP_SRC(%a6)
   4380 	lea		FP_SRC(%a6),%a0
   4381 	bsr.l		tag			# fetch operand type
   4382 	mov.b		%d0,STAG(%a6)
   4383 	mov.l		%d0,%d1
   4384 
   4385 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4386 
   4387 	clr.l		%d0
   4388 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4389 
   4390 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4391 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4392 
   4393 	tst.b		%d1
   4394 	bne.b		_L21_2d
   4395 	bsr.l		srem_snorm			# operand is a NORM
   4396 	bra.b		_L21_6d
   4397 _L21_2d:
   4398 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4399 	bne.b		_L21_3d			# no
   4400 	bsr.l		srem_szero			# yes
   4401 	bra.b		_L21_6d
   4402 _L21_3d:
   4403 	cmpi.b		%d1,&INF		# is operand an INF?
   4404 	bne.b		_L21_4d			# no
   4405 	bsr.l		srem_sinf			# yes
   4406 	bra.b		_L21_6d
   4407 _L21_4d:
   4408 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4409 	bne.b		_L21_5d			# no
   4410 	bsr.l		sop_sqnan			# yes
   4411 	bra.b		_L21_6d
   4412 _L21_5d:
   4413 	bsr.l		srem_sdnrm			# operand is a DENORM
   4414 _L21_6d:
   4415 
   4416 #
   4417 #	Result is now in FP0
   4418 #
   4419 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4420 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4421 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4422 	unlk		%a6
   4423 	rts
   4424 
   4425 	global		_fremx_
   4426 _fremx_:
   4427 	link		%a6,&-LOCAL_SIZE
   4428 
   4429 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4430 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4431 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4432 
   4433 	fmov.l		&0x0,%fpcr		# zero FPCR
   4434 
   4435 #
   4436 #	copy, convert, and tag input argument
   4437 #
   4438 	lea		FP_DST(%a6),%a0
   4439 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
   4440 	mov.l		0x8+0x4(%a6),0x4(%a0)
   4441 	mov.l		0x8+0x8(%a6),0x8(%a0)
   4442 	bsr.l		tag			# fetch operand type
   4443 	mov.b		%d0,DTAG(%a6)
   4444 
   4445 	lea		FP_SRC(%a6),%a0
   4446 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
   4447 	mov.l		0x14+0x4(%a6),0x4(%a0)
   4448 	mov.l		0x14+0x8(%a6),0x8(%a0)
   4449 	bsr.l		tag			# fetch operand type
   4450 	mov.b		%d0,STAG(%a6)
   4451 	mov.l		%d0,%d1
   4452 
   4453 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4454 
   4455 	clr.l		%d0
   4456 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4457 
   4458 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4459 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4460 
   4461 	tst.b		%d1
   4462 	bne.b		_L21_2x
   4463 	bsr.l		srem_snorm			# operand is a NORM
   4464 	bra.b		_L21_6x
   4465 _L21_2x:
   4466 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4467 	bne.b		_L21_3x			# no
   4468 	bsr.l		srem_szero			# yes
   4469 	bra.b		_L21_6x
   4470 _L21_3x:
   4471 	cmpi.b		%d1,&INF		# is operand an INF?
   4472 	bne.b		_L21_4x			# no
   4473 	bsr.l		srem_sinf			# yes
   4474 	bra.b		_L21_6x
   4475 _L21_4x:
   4476 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4477 	bne.b		_L21_5x			# no
   4478 	bsr.l		sop_sqnan			# yes
   4479 	bra.b		_L21_6x
   4480 _L21_5x:
   4481 	bsr.l		srem_sdnrm			# operand is a DENORM
   4482 _L21_6x:
   4483 
   4484 #
   4485 #	Result is now in FP0
   4486 #
   4487 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4488 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4489 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4490 	unlk		%a6
   4491 	rts
   4492 
   4493 
   4494 #########################################################################
   4495 # DYADIC TEMPLATE							#
   4496 #########################################################################
   4497 	global		_fmods_
   4498 _fmods_:
   4499 	link		%a6,&-LOCAL_SIZE
   4500 
   4501 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4502 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4503 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4504 
   4505 	fmov.l		&0x0,%fpcr		# zero FPCR
   4506 
   4507 #
   4508 #	copy, convert, and tag input argument
   4509 #
   4510 	fmov.s		0x8(%a6),%fp0		# load sgl dst
   4511 	fmov.x		%fp0,FP_DST(%a6)
   4512 	lea		FP_DST(%a6),%a0
   4513 	bsr.l		tag			# fetch operand type
   4514 	mov.b		%d0,DTAG(%a6)
   4515 
   4516 	fmov.s		0xc(%a6),%fp0		# load sgl src
   4517 	fmov.x		%fp0,FP_SRC(%a6)
   4518 	lea		FP_SRC(%a6),%a0
   4519 	bsr.l		tag			# fetch operand type
   4520 	mov.b		%d0,STAG(%a6)
   4521 	mov.l		%d0,%d1
   4522 
   4523 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4524 
   4525 	clr.l		%d0
   4526 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4527 
   4528 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4529 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4530 
   4531 	tst.b		%d1
   4532 	bne.b		_L22_2s
   4533 	bsr.l		smod_snorm			# operand is a NORM
   4534 	bra.b		_L22_6s
   4535 _L22_2s:
   4536 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4537 	bne.b		_L22_3s			# no
   4538 	bsr.l		smod_szero			# yes
   4539 	bra.b		_L22_6s
   4540 _L22_3s:
   4541 	cmpi.b		%d1,&INF		# is operand an INF?
   4542 	bne.b		_L22_4s			# no
   4543 	bsr.l		smod_sinf			# yes
   4544 	bra.b		_L22_6s
   4545 _L22_4s:
   4546 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4547 	bne.b		_L22_5s			# no
   4548 	bsr.l		sop_sqnan			# yes
   4549 	bra.b		_L22_6s
   4550 _L22_5s:
   4551 	bsr.l		smod_sdnrm			# operand is a DENORM
   4552 _L22_6s:
   4553 
   4554 #
   4555 #	Result is now in FP0
   4556 #
   4557 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4558 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4559 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4560 	unlk		%a6
   4561 	rts
   4562 
   4563 	global		_fmodd_
   4564 _fmodd_:
   4565 	link		%a6,&-LOCAL_SIZE
   4566 
   4567 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4568 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4569 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4570 
   4571 	fmov.l		&0x0,%fpcr		# zero FPCR
   4572 
   4573 #
   4574 #	copy, convert, and tag input argument
   4575 #
   4576 	fmov.d		0x8(%a6),%fp0		# load dbl dst
   4577 	fmov.x		%fp0,FP_DST(%a6)
   4578 	lea		FP_DST(%a6),%a0
   4579 	bsr.l		tag			# fetch operand type
   4580 	mov.b		%d0,DTAG(%a6)
   4581 
   4582 	fmov.d		0x10(%a6),%fp0		# load dbl src
   4583 	fmov.x		%fp0,FP_SRC(%a6)
   4584 	lea		FP_SRC(%a6),%a0
   4585 	bsr.l		tag			# fetch operand type
   4586 	mov.b		%d0,STAG(%a6)
   4587 	mov.l		%d0,%d1
   4588 
   4589 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4590 
   4591 	clr.l		%d0
   4592 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4593 
   4594 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4595 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4596 
   4597 	tst.b		%d1
   4598 	bne.b		_L22_2d
   4599 	bsr.l		smod_snorm			# operand is a NORM
   4600 	bra.b		_L22_6d
   4601 _L22_2d:
   4602 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4603 	bne.b		_L22_3d			# no
   4604 	bsr.l		smod_szero			# yes
   4605 	bra.b		_L22_6d
   4606 _L22_3d:
   4607 	cmpi.b		%d1,&INF		# is operand an INF?
   4608 	bne.b		_L22_4d			# no
   4609 	bsr.l		smod_sinf			# yes
   4610 	bra.b		_L22_6d
   4611 _L22_4d:
   4612 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4613 	bne.b		_L22_5d			# no
   4614 	bsr.l		sop_sqnan			# yes
   4615 	bra.b		_L22_6d
   4616 _L22_5d:
   4617 	bsr.l		smod_sdnrm			# operand is a DENORM
   4618 _L22_6d:
   4619 
   4620 #
   4621 #	Result is now in FP0
   4622 #
   4623 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4624 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4625 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4626 	unlk		%a6
   4627 	rts
   4628 
   4629 	global		_fmodx_
   4630 _fmodx_:
   4631 	link		%a6,&-LOCAL_SIZE
   4632 
   4633 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4634 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4635 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4636 
   4637 	fmov.l		&0x0,%fpcr		# zero FPCR
   4638 
   4639 #
   4640 #	copy, convert, and tag input argument
   4641 #
   4642 	lea		FP_DST(%a6),%a0
   4643 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
   4644 	mov.l		0x8+0x4(%a6),0x4(%a0)
   4645 	mov.l		0x8+0x8(%a6),0x8(%a0)
   4646 	bsr.l		tag			# fetch operand type
   4647 	mov.b		%d0,DTAG(%a6)
   4648 
   4649 	lea		FP_SRC(%a6),%a0
   4650 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
   4651 	mov.l		0x14+0x4(%a6),0x4(%a0)
   4652 	mov.l		0x14+0x8(%a6),0x8(%a0)
   4653 	bsr.l		tag			# fetch operand type
   4654 	mov.b		%d0,STAG(%a6)
   4655 	mov.l		%d0,%d1
   4656 
   4657 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4658 
   4659 	clr.l		%d0
   4660 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4661 
   4662 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4663 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4664 
   4665 	tst.b		%d1
   4666 	bne.b		_L22_2x
   4667 	bsr.l		smod_snorm			# operand is a NORM
   4668 	bra.b		_L22_6x
   4669 _L22_2x:
   4670 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4671 	bne.b		_L22_3x			# no
   4672 	bsr.l		smod_szero			# yes
   4673 	bra.b		_L22_6x
   4674 _L22_3x:
   4675 	cmpi.b		%d1,&INF		# is operand an INF?
   4676 	bne.b		_L22_4x			# no
   4677 	bsr.l		smod_sinf			# yes
   4678 	bra.b		_L22_6x
   4679 _L22_4x:
   4680 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4681 	bne.b		_L22_5x			# no
   4682 	bsr.l		sop_sqnan			# yes
   4683 	bra.b		_L22_6x
   4684 _L22_5x:
   4685 	bsr.l		smod_sdnrm			# operand is a DENORM
   4686 _L22_6x:
   4687 
   4688 #
   4689 #	Result is now in FP0
   4690 #
   4691 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4692 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4693 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4694 	unlk		%a6
   4695 	rts
   4696 
   4697 
   4698 #########################################################################
   4699 # DYADIC TEMPLATE							#
   4700 #########################################################################
   4701 	global		_fscales_
   4702 _fscales_:
   4703 	link		%a6,&-LOCAL_SIZE
   4704 
   4705 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4706 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4707 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4708 
   4709 	fmov.l		&0x0,%fpcr		# zero FPCR
   4710 
   4711 #
   4712 #	copy, convert, and tag input argument
   4713 #
   4714 	fmov.s		0x8(%a6),%fp0		# load sgl dst
   4715 	fmov.x		%fp0,FP_DST(%a6)
   4716 	lea		FP_DST(%a6),%a0
   4717 	bsr.l		tag			# fetch operand type
   4718 	mov.b		%d0,DTAG(%a6)
   4719 
   4720 	fmov.s		0xc(%a6),%fp0		# load sgl src
   4721 	fmov.x		%fp0,FP_SRC(%a6)
   4722 	lea		FP_SRC(%a6),%a0
   4723 	bsr.l		tag			# fetch operand type
   4724 	mov.b		%d0,STAG(%a6)
   4725 	mov.l		%d0,%d1
   4726 
   4727 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4728 
   4729 	clr.l		%d0
   4730 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4731 
   4732 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4733 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4734 
   4735 	tst.b		%d1
   4736 	bne.b		_L23_2s
   4737 	bsr.l		sscale_snorm			# operand is a NORM
   4738 	bra.b		_L23_6s
   4739 _L23_2s:
   4740 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4741 	bne.b		_L23_3s			# no
   4742 	bsr.l		sscale_szero			# yes
   4743 	bra.b		_L23_6s
   4744 _L23_3s:
   4745 	cmpi.b		%d1,&INF		# is operand an INF?
   4746 	bne.b		_L23_4s			# no
   4747 	bsr.l		sscale_sinf			# yes
   4748 	bra.b		_L23_6s
   4749 _L23_4s:
   4750 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4751 	bne.b		_L23_5s			# no
   4752 	bsr.l		sop_sqnan			# yes
   4753 	bra.b		_L23_6s
   4754 _L23_5s:
   4755 	bsr.l		sscale_sdnrm			# operand is a DENORM
   4756 _L23_6s:
   4757 
   4758 #
   4759 #	Result is now in FP0
   4760 #
   4761 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4762 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4763 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4764 	unlk		%a6
   4765 	rts
   4766 
   4767 	global		_fscaled_
   4768 _fscaled_:
   4769 	link		%a6,&-LOCAL_SIZE
   4770 
   4771 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4772 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4773 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4774 
   4775 	fmov.l		&0x0,%fpcr		# zero FPCR
   4776 
   4777 #
   4778 #	copy, convert, and tag input argument
   4779 #
   4780 	fmov.d		0x8(%a6),%fp0		# load dbl dst
   4781 	fmov.x		%fp0,FP_DST(%a6)
   4782 	lea		FP_DST(%a6),%a0
   4783 	bsr.l		tag			# fetch operand type
   4784 	mov.b		%d0,DTAG(%a6)
   4785 
   4786 	fmov.d		0x10(%a6),%fp0		# load dbl src
   4787 	fmov.x		%fp0,FP_SRC(%a6)
   4788 	lea		FP_SRC(%a6),%a0
   4789 	bsr.l		tag			# fetch operand type
   4790 	mov.b		%d0,STAG(%a6)
   4791 	mov.l		%d0,%d1
   4792 
   4793 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4794 
   4795 	clr.l		%d0
   4796 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4797 
   4798 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4799 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4800 
   4801 	tst.b		%d1
   4802 	bne.b		_L23_2d
   4803 	bsr.l		sscale_snorm			# operand is a NORM
   4804 	bra.b		_L23_6d
   4805 _L23_2d:
   4806 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4807 	bne.b		_L23_3d			# no
   4808 	bsr.l		sscale_szero			# yes
   4809 	bra.b		_L23_6d
   4810 _L23_3d:
   4811 	cmpi.b		%d1,&INF		# is operand an INF?
   4812 	bne.b		_L23_4d			# no
   4813 	bsr.l		sscale_sinf			# yes
   4814 	bra.b		_L23_6d
   4815 _L23_4d:
   4816 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4817 	bne.b		_L23_5d			# no
   4818 	bsr.l		sop_sqnan			# yes
   4819 	bra.b		_L23_6d
   4820 _L23_5d:
   4821 	bsr.l		sscale_sdnrm			# operand is a DENORM
   4822 _L23_6d:
   4823 
   4824 #
   4825 #	Result is now in FP0
   4826 #
   4827 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4828 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4829 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4830 	unlk		%a6
   4831 	rts
   4832 
   4833 	global		_fscalex_
   4834 _fscalex_:
   4835 	link		%a6,&-LOCAL_SIZE
   4836 
   4837 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4838 	fmovm.l		%fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
   4839 	fmovm.x		&0xc0,EXC_FP0(%a6)	# save fp0/fp1
   4840 
   4841 	fmov.l		&0x0,%fpcr		# zero FPCR
   4842 
   4843 #
   4844 #	copy, convert, and tag input argument
   4845 #
   4846 	lea		FP_DST(%a6),%a0
   4847 	mov.l		0x8+0x0(%a6),0x0(%a0)	# load ext dst
   4848 	mov.l		0x8+0x4(%a6),0x4(%a0)
   4849 	mov.l		0x8+0x8(%a6),0x8(%a0)
   4850 	bsr.l		tag			# fetch operand type
   4851 	mov.b		%d0,DTAG(%a6)
   4852 
   4853 	lea		FP_SRC(%a6),%a0
   4854 	mov.l		0x14+0x0(%a6),0x0(%a0)	# load ext src
   4855 	mov.l		0x14+0x4(%a6),0x4(%a0)
   4856 	mov.l		0x14+0x8(%a6),0x8(%a0)
   4857 	bsr.l		tag			# fetch operand type
   4858 	mov.b		%d0,STAG(%a6)
   4859 	mov.l		%d0,%d1
   4860 
   4861 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4862 
   4863 	clr.l		%d0
   4864 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd mode,prec
   4865 
   4866 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   4867 	lea		FP_DST(%a6),%a1		# pass ptr to dst
   4868 
   4869 	tst.b		%d1
   4870 	bne.b		_L23_2x
   4871 	bsr.l		sscale_snorm			# operand is a NORM
   4872 	bra.b		_L23_6x
   4873 _L23_2x:
   4874 	cmpi.b		%d1,&ZERO		# is operand a ZERO?
   4875 	bne.b		_L23_3x			# no
   4876 	bsr.l		sscale_szero			# yes
   4877 	bra.b		_L23_6x
   4878 _L23_3x:
   4879 	cmpi.b		%d1,&INF		# is operand an INF?
   4880 	bne.b		_L23_4x			# no
   4881 	bsr.l		sscale_sinf			# yes
   4882 	bra.b		_L23_6x
   4883 _L23_4x:
   4884 	cmpi.b		%d1,&QNAN		# is operand a QNAN?
   4885 	bne.b		_L23_5x			# no
   4886 	bsr.l		sop_sqnan			# yes
   4887 	bra.b		_L23_6x
   4888 _L23_5x:
   4889 	bsr.l		sscale_sdnrm			# operand is a DENORM
   4890 _L23_6x:
   4891 
   4892 #
   4893 #	Result is now in FP0
   4894 #
   4895 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4896 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
   4897 	fmovm.x		EXC_FP1(%a6),&0x40	# restore fp1
   4898 	unlk		%a6
   4899 	rts
   4900 
   4901 
   4902 #########################################################################
   4903 # ssin():     computes the sine of a normalized input			#
   4904 # ssind():    computes the sine of a denormalized input			#
   4905 # scos():     computes the cosine of a normalized input			#
   4906 # scosd():    computes the cosine of a denormalized input		#
   4907 # ssincos():  computes the sine and cosine of a normalized input	#
   4908 # ssincosd(): computes the sine and cosine of a denormalized input	#
   4909 #									#
   4910 # INPUT *************************************************************** #
   4911 #	a0 = pointer to extended precision input			#
   4912 #	d0 = round precision,mode					#
   4913 #									#
   4914 # OUTPUT ************************************************************** #
   4915 #	fp0 = sin(X) or cos(X) 						#
   4916 #									#
   4917 #    For ssincos(X):							#
   4918 #	fp0 = sin(X)							#
   4919 #	fp1 = cos(X)							#
   4920 #									#
   4921 # ACCURACY and MONOTONICITY ******************************************* #
   4922 #	The returned result is within 1 ulp in 64 significant bit, i.e.	#
   4923 #	within 0.5001 ulp to 53 bits if the result is subsequently 	#
   4924 #	rounded to double precision. The result is provably monotonic	#
   4925 #	in double precision.						#
   4926 #									#
   4927 # ALGORITHM ***********************************************************	#
   4928 #									#
   4929 #	SIN and COS:							#
   4930 #	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
   4931 #									#
   4932 #	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
   4933 #									#
   4934 #	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   4935 #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
   4936 #		Overwrite k by k := k + AdjN.				#
   4937 #									#
   4938 #	4. If k is even, go to 6.					#
   4939 #									#
   4940 #	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. 		#
   4941 #		Return sgn*cos(r) where cos(r) is approximated by an 	#
   4942 #		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
   4943 #		s = r*r.						#
   4944 #		Exit.							#
   4945 #									#
   4946 #	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
   4947 #		where sin(r) is approximated by an odd polynomial in r	#
   4948 #		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
   4949 #		Exit.							#
   4950 #									#
   4951 #	7. If |X| > 1, go to 9.						#
   4952 #									#
   4953 #	8. (|X|<2**(-40)) If SIN is invoked, return X; 			#
   4954 #		otherwise return 1.					#
   4955 #									#
   4956 #	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, 		#
   4957 #		go back to 3.						#
   4958 #									#
   4959 #	SINCOS:								#
   4960 #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
   4961 #									#
   4962 #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   4963 #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
   4964 #									#
   4965 #	3. If k is even, go to 5.					#
   4966 #									#
   4967 #	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
   4968 #		j1 exclusive or with the l.s.b. of k.			#
   4969 #		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
   4970 #		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
   4971 #		sin(r) and cos(r) are computed as odd and even 		#
   4972 #		polynomials in r, respectively. Exit			#
   4973 #									#
   4974 #	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
   4975 #		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
   4976 #		sin(r) and cos(r) are computed as odd and even 		#
   4977 #		polynomials in r, respectively. Exit			#
   4978 #									#
   4979 #	6. If |X| > 1, go to 8.						#
   4980 #									#
   4981 #	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
   4982 #									#
   4983 #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, 		#
   4984 #		go back to 2.						#
   4985 #									#
   4986 #########################################################################
   4987 
   4988 SINA7:	long		0xBD6AAA77,0xCCC994F5
   4989 SINA6:	long		0x3DE61209,0x7AAE8DA1
   4990 SINA5:	long		0xBE5AE645,0x2A118AE4
   4991 SINA4:	long		0x3EC71DE3,0xA5341531
   4992 SINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
   4993 SINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
   4994 SINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
   4995 
   4996 COSB8:	long		0x3D2AC4D0,0xD6011EE3
   4997 COSB7:	long		0xBDA9396F,0x9F45AC19
   4998 COSB6:	long		0x3E21EED9,0x0612C972
   4999 COSB5:	long		0xBE927E4F,0xB79D9FCF
   5000 COSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
   5001 COSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
   5002 COSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
   5003 COSB1:	long		0xBF000000
   5004 
   5005 	set		INARG,FP_SCR0
   5006 
   5007 	set		X,FP_SCR0
   5008 #	set		XDCARE,X+2
   5009 	set		XFRAC,X+4
   5010 
   5011 	set		RPRIME,FP_SCR0
   5012 	set		SPRIME,FP_SCR1
   5013 
   5014 	set		POSNEG1,L_SCR1
   5015 	set		TWOTO63,L_SCR1
   5016 
   5017 	set		ENDFLAG,L_SCR2
   5018 	set		INT,L_SCR2
   5019 
   5020 	set		ADJN,L_SCR3
   5021 
   5022 ############################################
   5023 	global		ssin
   5024 ssin:
   5025 	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
   5026 	bra.b		SINBGN
   5027 
   5028 ############################################
   5029 	global		scos
   5030 scos:
   5031 	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
   5032 
   5033 ############################################
   5034 SINBGN:
   5035 #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
   5036 
   5037 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5038 	fmov.x		%fp0,X(%a6)		# save input at X
   5039 
   5040 # "COMPACTIFY" X
   5041 	mov.l		(%a0),%d1		# put exp in hi word
   5042 	mov.w		4(%a0),%d1		# fetch hi(man)
   5043 	and.l		&0x7FFFFFFF,%d1		# strip sign
   5044 
   5045 	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
   5046 	bge.b		SOK1			# no
   5047 	bra.w		SINSM			# yes; input is very small
   5048 
   5049 SOK1:
   5050 	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
   5051 	blt.b		SINMAIN			# no
   5052 	bra.w		SREDUCEX		# yes; input is very large
   5053 
   5054 #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5055 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5056 SINMAIN:
   5057 	fmov.x		%fp0,%fp1
   5058 	fmul.d		TWOBYPI(%pc),%fp1 	# X*2/PI
   5059 
   5060 	lea		PITBL+0x200(%pc),%a1 	# TABLE OF N*PI/2, N = -32,...,32
   5061 
   5062 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
   5063 
   5064 	mov.l		INT(%a6),%d1		# make a copy of N
   5065 	asl.l		&4,%d1			# N *= 16
   5066 	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
   5067 
   5068 # A1 IS THE ADDRESS OF N*PIBY2
   5069 # ...WHICH IS IN TWO PIECES Y1 & Y2
   5070 	fsub.x		(%a1)+,%fp0 		# X-Y1
   5071 	fsub.s		(%a1),%fp0 		# fp0 = R = (X-Y1)-Y2
   5072 
   5073 SINCONT:
   5074 #--continuation from REDUCEX
   5075 
   5076 #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
   5077 	mov.l		INT(%a6),%d1
   5078 	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
   5079 	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
   5080 	cmp.l		%d1,&0
   5081 	blt.w		COSPOLY
   5082 
   5083 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
   5084 #--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
   5085 #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
   5086 #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
   5087 #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
   5088 #--WHERE T=S*S.
   5089 #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
   5090 #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
   5091 SINPOLY:
   5092 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   5093 
   5094 	fmov.x		%fp0,X(%a6)		# X IS R
   5095 	fmul.x		%fp0,%fp0		# FP0 IS S
   5096 
   5097 	fmov.d		SINA7(%pc),%fp3
   5098 	fmov.d		SINA6(%pc),%fp2
   5099 
   5100 	fmov.x		%fp0,%fp1
   5101 	fmul.x		%fp1,%fp1		# FP1 IS T
   5102 
   5103 	ror.l		&1,%d1
   5104 	and.l		&0x80000000,%d1
   5105 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
   5106 	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
   5107 
   5108 	fmul.x		%fp1,%fp3		# TA7
   5109 	fmul.x		%fp1,%fp2		# TA6
   5110 
   5111 	fadd.d		SINA5(%pc),%fp3		# A5+TA7
   5112 	fadd.d		SINA4(%pc),%fp2		# A4+TA6
   5113 
   5114 	fmul.x		%fp1,%fp3		# T(A5+TA7)
   5115 	fmul.x		%fp1,%fp2		# T(A4+TA6)
   5116 
   5117 	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
   5118 	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
   5119 
   5120 	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
   5121 
   5122 	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
   5123 	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
   5124 	fmul.x		X(%a6),%fp0		# R'*S
   5125 
   5126 	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
   5127 
   5128 	fmul.x		%fp1,%fp0		# SIN(R')-R'
   5129 
   5130 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   5131 
   5132 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5133 	fadd.x		X(%a6),%fp0		# last inst - possible exception set
   5134 	bra		t_inx2
   5135 
   5136 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
   5137 #--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
   5138 #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
   5139 #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
   5140 #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
   5141 #--WHERE T=S*S.
   5142 #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
   5143 #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
   5144 #--AND IS THEREFORE STORED AS SINGLE PRECISION.
   5145 COSPOLY:
   5146 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   5147 
   5148 	fmul.x		%fp0,%fp0		# FP0 IS S
   5149 
   5150 	fmov.d		COSB8(%pc),%fp2
   5151 	fmov.d		COSB7(%pc),%fp3
   5152 
   5153 	fmov.x		%fp0,%fp1
   5154 	fmul.x		%fp1,%fp1		# FP1 IS T
   5155 
   5156 	fmov.x		%fp0,X(%a6)		# X IS S
   5157 	ror.l		&1,%d1
   5158 	and.l		&0x80000000,%d1
   5159 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
   5160 
   5161 	fmul.x		%fp1,%fp2		# TB8
   5162 
   5163 	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
   5164 	and.l		&0x80000000,%d1
   5165 
   5166 	fmul.x		%fp1,%fp3		# TB7
   5167 
   5168 	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
   5169 	mov.l		%d1,POSNEG1(%a6)
   5170 
   5171 	fadd.d		COSB6(%pc),%fp2		# B6+TB8
   5172 	fadd.d		COSB5(%pc),%fp3		# B5+TB7
   5173 
   5174 	fmul.x		%fp1,%fp2		# T(B6+TB8)
   5175 	fmul.x		%fp1,%fp3		# T(B5+TB7)
   5176 
   5177 	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
   5178 	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
   5179 
   5180 	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
   5181 	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
   5182 
   5183 	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
   5184 	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
   5185 
   5186 	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
   5187 
   5188 	fadd.x		%fp1,%fp0
   5189 
   5190 	fmul.x		X(%a6),%fp0
   5191 
   5192 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   5193 
   5194 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5195 	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
   5196 	bra		t_inx2
   5197 
   5198 ##############################################
   5199 
   5200 # SINe: Big OR Small?
   5201 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
   5202 #--IF |X| < 2**(-40), RETURN X OR 1.
   5203 SINBORS:
   5204 	cmp.l		%d1,&0x3FFF8000
   5205 	bgt.l		SREDUCEX
   5206 
   5207 SINSM:
   5208 	mov.l		ADJN(%a6),%d1
   5209 	cmp.l		%d1,&0
   5210 	bgt.b		COSTINY
   5211 
   5212 # here, the operation may underflow iff the precision is sgl or dbl.
   5213 # extended denorms are handled through another entry point.
   5214 SINTINY:
   5215 #	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
   5216 
   5217 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5218 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5219 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   5220 	bra		t_catch
   5221 
   5222 COSTINY:
   5223 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
   5224 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5225 	fadd.s 		&0x80800000,%fp0	# last inst - possible exception set
   5226 	bra		t_pinx2
   5227 
   5228 ################################################
   5229 	global		ssind
   5230 #--SIN(X) = X FOR DENORMALIZED X
   5231 ssind:
   5232 	bra		t_extdnrm
   5233 
   5234 ############################################
   5235 	global		scosd
   5236 #--COS(X) = 1 FOR DENORMALIZED X
   5237 scosd:
   5238 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
   5239 	bra		t_pinx2
   5240 
   5241 ##################################################
   5242 
   5243 	global		ssincos
   5244 ssincos:
   5245 #--SET ADJN TO 4
   5246 	mov.l		&4,ADJN(%a6)
   5247 
   5248 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5249 	fmov.x		%fp0,X(%a6)
   5250 
   5251 	mov.l		(%a0),%d1
   5252 	mov.w		4(%a0),%d1
   5253 	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
   5254 
   5255 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
   5256 	bge.b		SCOK1
   5257 	bra.w		SCSM
   5258 
   5259 SCOK1:
   5260 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
   5261 	blt.b		SCMAIN
   5262 	bra.w		SREDUCEX
   5263 
   5264 
   5265 #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5266 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5267 SCMAIN:
   5268 	fmov.x		%fp0,%fp1
   5269 
   5270 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
   5271 
   5272 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
   5273 
   5274 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
   5275 
   5276 	mov.l		INT(%a6),%d1
   5277 	asl.l		&4,%d1
   5278 	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
   5279 
   5280 	fsub.x		(%a1)+,%fp0		# X-Y1
   5281 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
   5282 
   5283 SCCONT:
   5284 #--continuation point from REDUCEX
   5285 
   5286 	mov.l		INT(%a6),%d1
   5287 	ror.l		&1,%d1
   5288 	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
   5289 	bge.w		NEVEN
   5290 
   5291 SNODD:
   5292 #--REGISTERS SAVED SO FAR: D0, A0, FP2.
   5293 	fmovm.x		&0x04,-(%sp)		# save fp2
   5294 
   5295 	fmov.x		%fp0,RPRIME(%a6)
   5296 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
   5297 	fmov.d		SINA7(%pc),%fp1		# A7
   5298 	fmov.d		COSB8(%pc),%fp2		# B8
   5299 	fmul.x		%fp0,%fp1		# SA7
   5300 	fmul.x		%fp0,%fp2		# SB8
   5301 
   5302 	mov.l		%d2,-(%sp)
   5303 	mov.l		%d1,%d2
   5304 	ror.l		&1,%d2
   5305 	and.l		&0x80000000,%d2
   5306 	eor.l		%d1,%d2
   5307 	and.l		&0x80000000,%d2
   5308 
   5309 	fadd.d		SINA6(%pc),%fp1		# A6+SA7
   5310 	fadd.d		COSB7(%pc),%fp2		# B7+SB8
   5311 
   5312 	fmul.x		%fp0,%fp1		# S(A6+SA7)
   5313 	eor.l		%d2,RPRIME(%a6)
   5314 	mov.l		(%sp)+,%d2
   5315 	fmul.x		%fp0,%fp2		# S(B7+SB8)
   5316 	ror.l		&1,%d1
   5317 	and.l		&0x80000000,%d1
   5318 	mov.l		&0x3F800000,POSNEG1(%a6)
   5319 	eor.l		%d1,POSNEG1(%a6)
   5320 
   5321 	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
   5322 	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
   5323 
   5324 	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
   5325 	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
   5326 	fmov.x		%fp0,SPRIME(%a6)
   5327 
   5328 	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
   5329 	eor.l		%d1,SPRIME(%a6)
   5330 	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
   5331 
   5332 	fmul.x		%fp0,%fp1		# S(A4+...)
   5333 	fmul.x		%fp0,%fp2		# S(B5+...)
   5334 
   5335 	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
   5336 	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
   5337 
   5338 	fmul.x		%fp0,%fp1		# S(A3+...)
   5339 	fmul.x		%fp0,%fp2		# S(B4+...)
   5340 
   5341 	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
   5342 	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
   5343 
   5344 	fmul.x		%fp0,%fp1		# S(A2+...)
   5345 	fmul.x		%fp0,%fp2		# S(B3+...)
   5346 
   5347 	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
   5348 	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
   5349 
   5350 	fmul.x		%fp0,%fp1		# S(A1+...)
   5351 	fmul.x		%fp2,%fp0		# S(B2+...)
   5352 
   5353 	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
   5354 	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
   5355 	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
   5356 
   5357 	fmovm.x		(%sp)+,&0x20		# restore fp2
   5358 
   5359 	fmov.l		%d0,%fpcr
   5360 	fadd.x		RPRIME(%a6),%fp1	# COS(X)
   5361 	bsr		sto_cos			# store cosine result
   5362 	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
   5363 	bra		t_inx2
   5364 
   5365 NEVEN:
   5366 #--REGISTERS SAVED SO FAR: FP2.
   5367 	fmovm.x		&0x04,-(%sp)		# save fp2
   5368 
   5369 	fmov.x		%fp0,RPRIME(%a6)
   5370 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
   5371 
   5372 	fmov.d		COSB8(%pc),%fp1		# B8
   5373 	fmov.d		SINA7(%pc),%fp2		# A7
   5374 
   5375 	fmul.x		%fp0,%fp1		# SB8
   5376 	fmov.x		%fp0,SPRIME(%a6)
   5377 	fmul.x		%fp0,%fp2		# SA7
   5378 
   5379 	ror.l		&1,%d1
   5380 	and.l		&0x80000000,%d1
   5381 
   5382 	fadd.d		COSB7(%pc),%fp1		# B7+SB8
   5383 	fadd.d		SINA6(%pc),%fp2		# A6+SA7
   5384 
   5385 	eor.l		%d1,RPRIME(%a6)
   5386 	eor.l		%d1,SPRIME(%a6)
   5387 
   5388 	fmul.x		%fp0,%fp1		# S(B7+SB8)
   5389 
   5390 	or.l		&0x3F800000,%d1
   5391 	mov.l		%d1,POSNEG1(%a6)
   5392 
   5393 	fmul.x		%fp0,%fp2		# S(A6+SA7)
   5394 
   5395 	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
   5396 	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
   5397 
   5398 	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
   5399 	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
   5400 
   5401 	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
   5402 	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
   5403 
   5404 	fmul.x		%fp0,%fp1		# S(B5+...)
   5405 	fmul.x		%fp0,%fp2		# S(A4+...)
   5406 
   5407 	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
   5408 	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
   5409 
   5410 	fmul.x		%fp0,%fp1		# S(B4+...)
   5411 	fmul.x		%fp0,%fp2		# S(A3+...)
   5412 
   5413 	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
   5414 	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
   5415 
   5416 	fmul.x		%fp0,%fp1		# S(B3+...)
   5417 	fmul.x		%fp0,%fp2		# S(A2+...)
   5418 
   5419 	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
   5420 	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
   5421 
   5422 	fmul.x		%fp0,%fp1		# S(B2+...)
   5423 	fmul.x		%fp2,%fp0		# s(a1+...)
   5424 
   5425 
   5426 	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
   5427 	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
   5428 	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
   5429 
   5430 	fmovm.x		(%sp)+,&0x20		# restore fp2
   5431 
   5432 	fmov.l		%d0,%fpcr
   5433 	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
   5434 	bsr		sto_cos			# store cosine result
   5435 	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
   5436 	bra		t_inx2
   5437 
   5438 ################################################
   5439 
   5440 SCBORS:
   5441 	cmp.l		%d1,&0x3FFF8000
   5442 	bgt.w		SREDUCEX
   5443 
   5444 ################################################
   5445 
   5446 SCSM:
   5447 #	mov.w		&0x0000,XDCARE(%a6)
   5448 	fmov.s		&0x3F800000,%fp1
   5449 
   5450 	fmov.l		%d0,%fpcr
   5451 	fsub.s		&0x00800000,%fp1
   5452 	bsr		sto_cos			# store cosine result
   5453 	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
   5454 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5455 	fmov.x		X(%a6),%fp0
   5456 	bra		t_catch
   5457 
   5458 ##############################################
   5459 
   5460 	global		ssincosd
   5461 #--SIN AND COS OF X FOR DENORMALIZED X
   5462 ssincosd:
   5463 	mov.l		%d0,-(%sp)		# save d0
   5464 	fmov.s		&0x3F800000,%fp1
   5465 	bsr		sto_cos			# store cosine result
   5466 	mov.l		(%sp)+,%d0		# restore d0
   5467 	bra		t_extdnrm
   5468 
   5469 ############################################
   5470 
   5471 #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
   5472 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
   5473 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
   5474 SREDUCEX:
   5475 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
   5476 	mov.l		%d2,-(%sp)		# save d2
   5477 	fmov.s		&0x00000000,%fp1	# fp1 = 0
   5478 
   5479 #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
   5480 #--there is a danger of unwanted overflow in first LOOP iteration.  In this
   5481 #--case, reduce argument by one remainder step to make subsequent reduction
   5482 #--safe.
   5483 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
   5484 	bne.b		SLOOP			# no
   5485 
   5486 # yes; create 2**16383*PI/2
   5487 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
   5488 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
   5489 	clr.l		FP_SCR0_LO(%a6)
   5490 
   5491 # create low half of 2**16383*PI/2 at FP_SCR1
   5492 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
   5493 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
   5494 	clr.l		FP_SCR1_LO(%a6)
   5495 
   5496 	ftest.x		%fp0			# test sign of argument
   5497 	fblt.w		sred_neg
   5498 
   5499 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
   5500 	or.b		&0x80,FP_SCR1_EX(%a6)
   5501 sred_neg:
   5502 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
   5503 	fmov.x		%fp0,%fp1		# save high result in fp1
   5504 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
   5505 	fsub.x		%fp0,%fp1		# determine low component of result
   5506 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
   5507 
   5508 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
   5509 #--integer quotient will be stored in N
   5510 #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
   5511 SLOOP:
   5512 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
   5513 	mov.w		INARG(%a6),%d1
   5514 	mov.l		%d1,%a1			# save a copy of D0
   5515 	and.l		&0x00007FFF,%d1
   5516 	sub.l		&0x00003FFF,%d1		# d0 = K
   5517 	cmp.l		%d1,&28
   5518 	ble.b		SLASTLOOP
   5519 SCONTLOOP:
   5520 	sub.l		&27,%d1			# d0 = L := K-27
   5521 	mov.b		&0,ENDFLAG(%a6)
   5522 	bra.b		SWORK
   5523 SLASTLOOP:
   5524 	clr.l		%d1			# d0 = L := 0
   5525 	mov.b		&1,ENDFLAG(%a6)
   5526 
   5527 SWORK:
   5528 #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
   5529 #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
   5530 
   5531 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
   5532 #--2**L * (PIby2_1), 2**L * (PIby2_2)
   5533 
   5534 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
   5535 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
   5536 
   5537 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
   5538 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
   5539 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
   5540 
   5541 	fmov.x		%fp0,%fp2
   5542 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
   5543 
   5544 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
   5545 #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
   5546 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
   5547 #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
   5548 #--US THE DESIRED VALUE IN FLOATING POINT.
   5549 	mov.l		%a1,%d2
   5550 	swap		%d2
   5551 	and.l		&0x80000000,%d2
   5552 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
   5553 	mov.l		%d2,TWOTO63(%a6)
   5554 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
   5555 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
   5556 #	fint.x		%fp2
   5557 
   5558 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
   5559 	mov.l		%d1,%d2			# d2 = L
   5560 
   5561 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
   5562 	mov.w		%d2,FP_SCR0_EX(%a6)
   5563 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
   5564 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
   5565 
   5566 	add.l		&0x00003FDD,%d1
   5567 	mov.w		%d1,FP_SCR1_EX(%a6)
   5568 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
   5569 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
   5570 
   5571 	mov.b		ENDFLAG(%a6),%d1
   5572 
   5573 #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
   5574 #--P2 = 2**(L) * Piby2_2
   5575 	fmov.x		%fp2,%fp4		# fp4 = N
   5576 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
   5577 	fmov.x		%fp2,%fp5		# fp5 = N
   5578 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
   5579 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
   5580 
   5581 #--we want P+p = W+w  but  |p| <= half ulp of P
   5582 #--Then, we need to compute  A := R-P   and  a := r-p
   5583 	fadd.x		%fp5,%fp3		# fp3 = P
   5584 	fsub.x		%fp3,%fp4		# fp4 = W-P
   5585 
   5586 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
   5587 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
   5588 
   5589 	fmov.x		%fp0,%fp3		# fp3 = A
   5590 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
   5591 
   5592 #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
   5593 #--|r| <= half ulp of R.
   5594 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
   5595 #--No need to calculate r if this is the last loop
   5596 	cmp.b		%d1,&0
   5597 	bgt.w		SRESTORE
   5598 
   5599 #--Need to calculate r
   5600 	fsub.x		%fp0,%fp3		# fp3 = A-R
   5601 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
   5602 	bra.w		SLOOP
   5603 
   5604 SRESTORE:
   5605 	fmov.l		%fp2,INT(%a6)
   5606 	mov.l		(%sp)+,%d2		# restore d2
   5607 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
   5608 
   5609 	mov.l		ADJN(%a6),%d1
   5610 	cmp.l		%d1,&4
   5611 
   5612 	blt.w		SINCONT
   5613 	bra.w		SCCONT
   5614 
   5615 #########################################################################
   5616 # stan():  computes the tangent of a normalized input			#
   5617 # stand(): computes the tangent of a denormalized input			#
   5618 #									#
   5619 # INPUT *************************************************************** #
   5620 #	a0 = pointer to extended precision input			#
   5621 #	d0 = round precision,mode					#
   5622 #									#
   5623 # OUTPUT ************************************************************** #
   5624 #	fp0 = tan(X)							#
   5625 #									#
   5626 # ACCURACY and MONOTONICITY ******************************************* #
   5627 #	The returned result is within 3 ulp in 64 significant bit, i.e. #
   5628 #	within 0.5001 ulp to 53 bits if the result is subsequently	#
   5629 #	rounded to double precision. The result is provably monotonic	#
   5630 #	in double precision.						#
   5631 #									#
   5632 # ALGORITHM *********************************************************** #
   5633 #									#
   5634 #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
   5635 #									#
   5636 #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5637 #		k = N mod 2, so in particular, k = 0 or 1.		#
   5638 #									#
   5639 #	3. If k is odd, go to 5.					#
   5640 #									#
   5641 #	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
   5642 #		rational function U/V where				#
   5643 #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
   5644 #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
   5645 #		Exit.							#
   5646 #									#
   5647 #	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
   5648 #		a rational function U/V where				#
   5649 #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
   5650 #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
   5651 #		-Cot(r) = -V/U. Exit.					#
   5652 #									#
   5653 #	6. If |X| > 1, go to 8.						#
   5654 #									#
   5655 #	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
   5656 #									#
   5657 #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back 	#
   5658 #		to 2.							#
   5659 #									#
   5660 #########################################################################
   5661 
   5662 TANQ4:
   5663 	long		0x3EA0B759,0xF50F8688
   5664 TANP3:
   5665 	long		0xBEF2BAA5,0xA8924F04
   5666 
   5667 TANQ3:
   5668 	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
   5669 
   5670 TANP2:
   5671 	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
   5672 
   5673 TANQ2:
   5674 	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
   5675 
   5676 TANP1:
   5677 	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
   5678 
   5679 TANQ1:
   5680 	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
   5681 
   5682 INVTWOPI:
   5683 	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
   5684 
   5685 TWOPI1:
   5686 	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
   5687 TWOPI2:
   5688 	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
   5689 
   5690 #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
   5691 #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
   5692 #--MOST 69 BITS LONG.
   5693 #	global		PITBL
   5694 PITBL:
   5695 	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
   5696 	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
   5697 	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
   5698 	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
   5699 	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
   5700 	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
   5701 	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
   5702 	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
   5703 	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
   5704 	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
   5705 	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
   5706 	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
   5707 	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
   5708 	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
   5709 	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
   5710 	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
   5711 	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
   5712 	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
   5713 	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
   5714 	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
   5715 	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
   5716 	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
   5717 	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
   5718 	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
   5719 	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
   5720 	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
   5721 	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
   5722 	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
   5723 	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
   5724 	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
   5725 	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
   5726 	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
   5727 	long		0x00000000,0x00000000,0x00000000,0x00000000
   5728 	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
   5729 	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
   5730 	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
   5731 	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
   5732 	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
   5733 	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
   5734 	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
   5735 	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
   5736 	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
   5737 	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
   5738 	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
   5739 	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
   5740 	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
   5741 	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
   5742 	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
   5743 	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
   5744 	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
   5745 	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
   5746 	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
   5747 	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
   5748 	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
   5749 	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
   5750 	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
   5751 	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
   5752 	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
   5753 	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
   5754 	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
   5755 	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
   5756 	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
   5757 	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
   5758 	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
   5759 	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
   5760 
   5761 	set		INARG,FP_SCR0
   5762 
   5763 	set		TWOTO63,L_SCR1
   5764 	set		INT,L_SCR1
   5765 	set		ENDFLAG,L_SCR2
   5766 
   5767 	global		stan
   5768 stan:
   5769 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5770 
   5771 	mov.l		(%a0),%d1
   5772 	mov.w		4(%a0),%d1
   5773 	and.l		&0x7FFFFFFF,%d1
   5774 
   5775 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
   5776 	bge.b		TANOK1
   5777 	bra.w		TANSM
   5778 TANOK1:
   5779 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
   5780 	blt.b		TANMAIN
   5781 	bra.w		REDUCEX
   5782 
   5783 TANMAIN:
   5784 #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5785 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5786 	fmov.x		%fp0,%fp1
   5787 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
   5788 
   5789 	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
   5790 
   5791 	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
   5792 
   5793 	asl.l		&4,%d1
   5794 	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
   5795 
   5796 	fsub.x		(%a1)+,%fp0		# X-Y1
   5797 
   5798 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
   5799 
   5800 	ror.l		&5,%d1
   5801 	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
   5802 
   5803 TANCONT:
   5804 	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
   5805 
   5806 	cmp.l		%d1,&0
   5807 	blt.w		NODD
   5808 
   5809 	fmov.x		%fp0,%fp1
   5810 	fmul.x		%fp1,%fp1		# S = R*R
   5811 
   5812 	fmov.d		TANQ4(%pc),%fp3
   5813 	fmov.d		TANP3(%pc),%fp2
   5814 
   5815 	fmul.x		%fp1,%fp3		# SQ4
   5816 	fmul.x		%fp1,%fp2		# SP3
   5817 
   5818 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
   5819 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
   5820 
   5821 	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
   5822 	fmul.x		%fp1,%fp2		# S(P2+SP3)
   5823 
   5824 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
   5825 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
   5826 
   5827 	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
   5828 	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
   5829 
   5830 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
   5831 	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
   5832 
   5833 	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
   5834 
   5835 	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
   5836 
   5837 	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
   5838 
   5839 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
   5840 
   5841 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5842 	fdiv.x		%fp1,%fp0		# last inst - possible exception set
   5843 	bra		t_inx2
   5844 
   5845 NODD:
   5846 	fmov.x		%fp0,%fp1
   5847 	fmul.x		%fp0,%fp0		# S = R*R
   5848 
   5849 	fmov.d		TANQ4(%pc),%fp3
   5850 	fmov.d		TANP3(%pc),%fp2
   5851 
   5852 	fmul.x		%fp0,%fp3		# SQ4
   5853 	fmul.x		%fp0,%fp2		# SP3
   5854 
   5855 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
   5856 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
   5857 
   5858 	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
   5859 	fmul.x		%fp0,%fp2		# S(P2+SP3)
   5860 
   5861 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
   5862 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
   5863 
   5864 	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
   5865 	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
   5866 
   5867 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
   5868 	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
   5869 
   5870 	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
   5871 
   5872 	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
   5873 	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
   5874 
   5875 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
   5876 
   5877 	fmov.x		%fp1,-(%sp)
   5878 	eor.l		&0x80000000,(%sp)
   5879 
   5880 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5881 	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
   5882 	bra		t_inx2
   5883 
   5884 TANBORS:
   5885 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
   5886 #--IF |X| < 2**(-40), RETURN X OR 1.
   5887 	cmp.l		%d1,&0x3FFF8000
   5888 	bgt.b		REDUCEX
   5889 
   5890 TANSM:
   5891 	fmov.x		%fp0,-(%sp)
   5892 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5893 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5894 	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
   5895 	bra		t_catch
   5896 
   5897 	global		stand
   5898 #--TAN(X) = X FOR DENORMALIZED X
   5899 stand:
   5900 	bra		t_extdnrm
   5901 
   5902 #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
   5903 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
   5904 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
   5905 REDUCEX:
   5906 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
   5907 	mov.l		%d2,-(%sp)		# save d2
   5908 	fmov.s		&0x00000000,%fp1	# fp1 = 0
   5909 
   5910 #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
   5911 #--there is a danger of unwanted overflow in first LOOP iteration.  In this
   5912 #--case, reduce argument by one remainder step to make subsequent reduction
   5913 #--safe.
   5914 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
   5915 	bne.b		LOOP			# no
   5916 
   5917 # yes; create 2**16383*PI/2
   5918 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
   5919 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
   5920 	clr.l		FP_SCR0_LO(%a6)
   5921 
   5922 # create low half of 2**16383*PI/2 at FP_SCR1
   5923 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
   5924 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
   5925 	clr.l		FP_SCR1_LO(%a6)
   5926 
   5927 	ftest.x		%fp0			# test sign of argument
   5928 	fblt.w		red_neg
   5929 
   5930 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
   5931 	or.b		&0x80,FP_SCR1_EX(%a6)
   5932 red_neg:
   5933 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
   5934 	fmov.x		%fp0,%fp1		# save high result in fp1
   5935 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
   5936 	fsub.x		%fp0,%fp1		# determine low component of result
   5937 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
   5938 
   5939 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
   5940 #--integer quotient will be stored in N
   5941 #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
   5942 LOOP:
   5943 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
   5944 	mov.w		INARG(%a6),%d1
   5945 	mov.l		%d1,%a1			# save a copy of D0
   5946 	and.l		&0x00007FFF,%d1
   5947 	sub.l		&0x00003FFF,%d1		# d0 = K
   5948 	cmp.l		%d1,&28
   5949 	ble.b		LASTLOOP
   5950 CONTLOOP:
   5951 	sub.l		&27,%d1			# d0 = L := K-27
   5952 	mov.b		&0,ENDFLAG(%a6)
   5953 	bra.b		WORK
   5954 LASTLOOP:
   5955 	clr.l		%d1			# d0 = L := 0
   5956 	mov.b		&1,ENDFLAG(%a6)
   5957 
   5958 WORK:
   5959 #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
   5960 #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
   5961 
   5962 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
   5963 #--2**L * (PIby2_1), 2**L * (PIby2_2)
   5964 
   5965 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
   5966 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
   5967 
   5968 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
   5969 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
   5970 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
   5971 
   5972 	fmov.x		%fp0,%fp2
   5973 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
   5974 
   5975 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
   5976 #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
   5977 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
   5978 #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
   5979 #--US THE DESIRED VALUE IN FLOATING POINT.
   5980 	mov.l		%a1,%d2
   5981 	swap		%d2
   5982 	and.l		&0x80000000,%d2
   5983 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
   5984 	mov.l		%d2,TWOTO63(%a6)
   5985 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
   5986 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
   5987 #	fintrz.x	%fp2,%fp2
   5988 
   5989 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
   5990 	mov.l		%d1,%d2			# d2 = L
   5991 
   5992 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
   5993 	mov.w		%d2,FP_SCR0_EX(%a6)
   5994 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
   5995 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
   5996 
   5997 	add.l		&0x00003FDD,%d1
   5998 	mov.w		%d1,FP_SCR1_EX(%a6)
   5999 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
   6000 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
   6001 
   6002 	mov.b		ENDFLAG(%a6),%d1
   6003 
   6004 #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
   6005 #--P2 = 2**(L) * Piby2_2
   6006 	fmov.x		%fp2,%fp4		# fp4 = N
   6007 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
   6008 	fmov.x		%fp2,%fp5		# fp5 = N
   6009 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
   6010 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
   6011 
   6012 #--we want P+p = W+w  but  |p| <= half ulp of P
   6013 #--Then, we need to compute  A := R-P   and  a := r-p
   6014 	fadd.x		%fp5,%fp3		# fp3 = P
   6015 	fsub.x		%fp3,%fp4		# fp4 = W-P
   6016 
   6017 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
   6018 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
   6019 
   6020 	fmov.x		%fp0,%fp3		# fp3 = A
   6021 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
   6022 
   6023 #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
   6024 #--|r| <= half ulp of R.
   6025 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
   6026 #--No need to calculate r if this is the last loop
   6027 	cmp.b		%d1,&0
   6028 	bgt.w		RESTORE
   6029 
   6030 #--Need to calculate r
   6031 	fsub.x		%fp0,%fp3		# fp3 = A-R
   6032 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
   6033 	bra.w		LOOP
   6034 
   6035 RESTORE:
   6036 	fmov.l		%fp2,INT(%a6)
   6037 	mov.l		(%sp)+,%d2		# restore d2
   6038 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
   6039 
   6040 	mov.l		INT(%a6),%d1
   6041 	ror.l		&1,%d1
   6042 
   6043 	bra.w		TANCONT
   6044 
   6045 #########################################################################
   6046 # satan():  computes the arctangent of a normalized number		#
   6047 # satand(): computes the arctangent of a denormalized number		#
   6048 #									#
   6049 # INPUT	*************************************************************** #
   6050 #	a0 = pointer to extended precision input			#
   6051 #	d0 = round precision,mode					#
   6052 #									#
   6053 # OUTPUT ************************************************************** #
   6054 #	fp0 = arctan(X)							#
   6055 #									#
   6056 # ACCURACY and MONOTONICITY ******************************************* #
   6057 #	The returned result is within 2 ulps in	64 significant bit,	#
   6058 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6059 #	rounded to double precision. The result is provably monotonic	#
   6060 #	in double precision. 						#
   6061 #									#
   6062 # ALGORITHM *********************************************************** #
   6063 #	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
   6064 #									#
   6065 #	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. 			#
   6066 #		Note that k = -4, -3,..., or 3.				#
   6067 #		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 	#
   6068 #		significant bits of X with a bit-1 attached at the 6-th	#
   6069 #		bit position. Define u to be u = (X-F) / (1 + X*F).	#
   6070 #									#
   6071 #	Step 3. Approximate arctan(u) by a polynomial poly.		#
   6072 #									#
   6073 #	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a 	#
   6074 #		table of values calculated beforehand. Exit.		#
   6075 #									#
   6076 #	Step 5. If |X| >= 16, go to Step 7.				#
   6077 #									#
   6078 #	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
   6079 #									#
   6080 #	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd 	#
   6081 #		polynomial in X'.					#
   6082 #		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
   6083 #									#
   6084 #########################################################################
   6085 
   6086 ATANA3:	long		0xBFF6687E,0x314987D8
   6087 ATANA2:	long		0x4002AC69,0x34A26DB3
   6088 ATANA1:	long		0xBFC2476F,0x4E1DA28E
   6089 
   6090 ATANB6:	long		0x3FB34444,0x7F876989
   6091 ATANB5:	long		0xBFB744EE,0x7FAF45DB
   6092 ATANB4:	long		0x3FBC71C6,0x46940220
   6093 ATANB3:	long		0xBFC24924,0x921872F9
   6094 ATANB2:	long		0x3FC99999,0x99998FA9
   6095 ATANB1:	long		0xBFD55555,0x55555555
   6096 
   6097 ATANC5:	long		0xBFB70BF3,0x98539E6A
   6098 ATANC4:	long		0x3FBC7187,0x962D1D7D
   6099 ATANC3:	long		0xBFC24924,0x827107B8
   6100 ATANC2:	long		0x3FC99999,0x9996263E
   6101 ATANC1:	long		0xBFD55555,0x55555536
   6102 
   6103 PPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
   6104 NPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
   6105 
   6106 PTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
   6107 NTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
   6108 
   6109 ATANTBL:
   6110 	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
   6111 	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
   6112 	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
   6113 	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
   6114 	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
   6115 	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
   6116 	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
   6117 	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
   6118 	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
   6119 	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
   6120 	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
   6121 	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
   6122 	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
   6123 	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
   6124 	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
   6125 	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
   6126 	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
   6127 	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
   6128 	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
   6129 	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
   6130 	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
   6131 	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
   6132 	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
   6133 	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
   6134 	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
   6135 	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
   6136 	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
   6137 	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
   6138 	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
   6139 	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
   6140 	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
   6141 	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
   6142 	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
   6143 	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
   6144 	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
   6145 	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
   6146 	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
   6147 	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
   6148 	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
   6149 	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
   6150 	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
   6151 	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
   6152 	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
   6153 	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
   6154 	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
   6155 	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
   6156 	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
   6157 	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
   6158 	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
   6159 	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
   6160 	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
   6161 	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
   6162 	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
   6163 	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
   6164 	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
   6165 	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
   6166 	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
   6167 	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
   6168 	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
   6169 	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
   6170 	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
   6171 	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
   6172 	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
   6173 	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
   6174 	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
   6175 	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
   6176 	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
   6177 	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
   6178 	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
   6179 	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
   6180 	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
   6181 	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
   6182 	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
   6183 	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
   6184 	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
   6185 	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
   6186 	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
   6187 	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
   6188 	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
   6189 	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
   6190 	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
   6191 	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
   6192 	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
   6193 	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
   6194 	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
   6195 	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
   6196 	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
   6197 	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
   6198 	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
   6199 	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
   6200 	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
   6201 	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
   6202 	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
   6203 	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
   6204 	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
   6205 	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
   6206 	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
   6207 	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
   6208 	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
   6209 	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
   6210 	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
   6211 	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
   6212 	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
   6213 	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
   6214 	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
   6215 	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
   6216 	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
   6217 	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
   6218 	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
   6219 	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
   6220 	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
   6221 	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
   6222 	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
   6223 	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
   6224 	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
   6225 	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
   6226 	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
   6227 	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
   6228 	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
   6229 	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
   6230 	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
   6231 	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
   6232 	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
   6233 	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
   6234 	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
   6235 	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
   6236 	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
   6237 	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
   6238 
   6239 	set		X,FP_SCR0
   6240 	set		XDCARE,X+2
   6241 	set		XFRAC,X+4
   6242 	set		XFRACLO,X+8
   6243 
   6244 	set		ATANF,FP_SCR1
   6245 	set		ATANFHI,ATANF+4
   6246 	set		ATANFLO,ATANF+8
   6247 
   6248 	global		satan
   6249 #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   6250 satan:
   6251 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6252 
   6253 	mov.l		(%a0),%d1
   6254 	mov.w		4(%a0),%d1
   6255 	fmov.x		%fp0,X(%a6)
   6256 	and.l		&0x7FFFFFFF,%d1
   6257 
   6258 	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
   6259 	bge.b		ATANOK1
   6260 	bra.w		ATANSM
   6261 
   6262 ATANOK1:
   6263 	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
   6264 	ble.b		ATANMAIN
   6265 	bra.w		ATANBIG
   6266 
   6267 #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
   6268 #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
   6269 #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
   6270 #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
   6271 #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
   6272 #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
   6273 #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
   6274 #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
   6275 #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
   6276 #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
   6277 #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
   6278 #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
   6279 #--WILL INVOLVE A VERY LONG POLYNOMIAL.
   6280 
   6281 #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
   6282 #--WE CHOSE F TO BE +-2^K * 1.BBBB1
   6283 #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
   6284 #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
   6285 #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
   6286 #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
   6287 
   6288 ATANMAIN:
   6289 
   6290 	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
   6291 	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
   6292 	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
   6293 
   6294 	fmov.x		%fp0,%fp1		# FP1 IS X
   6295 	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
   6296 	fsub.x		X(%a6),%fp0		# FP0 IS X-F
   6297 	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
   6298 	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
   6299 
   6300 #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
   6301 #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
   6302 #--SAVE REGISTERS FP2.
   6303 
   6304 	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
   6305 	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
   6306 	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
   6307 	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
   6308 	sub.l		&0x3FFB0000,%d2		# K+4
   6309 	asr.l		&1,%d2
   6310 	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
   6311 	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
   6312 	lea		ATANTBL(%pc),%a1
   6313 	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
   6314 	mov.l		(%a1)+,ATANF(%a6)
   6315 	mov.l		(%a1)+,ATANFHI(%a6)
   6316 	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
   6317 	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
   6318 	and.l		&0x80000000,%d1		# SIGN(F)
   6319 	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
   6320 	mov.l		(%sp)+,%d2		# RESTORE d2
   6321 
   6322 #--THAT'S ALL I HAVE TO DO FOR NOW,
   6323 #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
   6324 
   6325 #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
   6326 #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
   6327 #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
   6328 #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
   6329 #--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
   6330 #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
   6331 #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
   6332 
   6333 	fmovm.x		&0x04,-(%sp)		# save fp2
   6334 
   6335 	fmov.x		%fp0,%fp1
   6336 	fmul.x		%fp1,%fp1
   6337 	fmov.d		ATANA3(%pc),%fp2
   6338 	fadd.x		%fp1,%fp2		# A3+V
   6339 	fmul.x		%fp1,%fp2		# V*(A3+V)
   6340 	fmul.x		%fp0,%fp1		# U*V
   6341 	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
   6342 	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
   6343 	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
   6344 	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
   6345 
   6346 	fmovm.x 	(%sp)+,&0x20		# restore fp2
   6347 
   6348 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6349 	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
   6350 	bra		t_inx2
   6351 
   6352 ATANBORS:
   6353 #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
   6354 #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
   6355 	cmp.l		%d1,&0x3FFF8000
   6356 	bgt.w		ATANBIG			# I.E. |X| >= 16
   6357 
   6358 ATANSM:
   6359 #--|X| <= 1/16
   6360 #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
   6361 #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
   6362 #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
   6363 #--WHERE Y = X*X, AND Z = Y*Y.
   6364 
   6365 	cmp.l		%d1,&0x3FD78000
   6366 	blt.w		ATANTINY
   6367 
   6368 #--COMPUTE POLYNOMIAL
   6369 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   6370 
   6371 	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
   6372 
   6373 	fmov.x		%fp0,%fp1
   6374 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
   6375 
   6376 	fmov.d		ATANB6(%pc),%fp2
   6377 	fmov.d		ATANB5(%pc),%fp3
   6378 
   6379 	fmul.x		%fp1,%fp2		# Z*B6
   6380 	fmul.x		%fp1,%fp3		# Z*B5
   6381 
   6382 	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
   6383 	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
   6384 
   6385 	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
   6386 	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
   6387 
   6388 	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
   6389 	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
   6390 
   6391 	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
   6392 	fmul.x		X(%a6),%fp0		# X*Y
   6393 
   6394 	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
   6395 
   6396 	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
   6397 
   6398 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   6399 
   6400 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6401 	fadd.x		X(%a6),%fp0
   6402 	bra		t_inx2
   6403 
   6404 ATANTINY:
   6405 #--|X| < 2^(-40), ATAN(X) = X
   6406 
   6407 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6408 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6409 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   6410 
   6411 	bra		t_catch
   6412 
   6413 ATANBIG:
   6414 #--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
   6415 #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
   6416 	cmp.l		%d1,&0x40638000
   6417 	bgt.w		ATANHUGE
   6418 
   6419 #--APPROXIMATE ATAN(-1/X) BY
   6420 #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
   6421 #--THIS CAN BE RE-WRITTEN AS
   6422 #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
   6423 
   6424 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   6425 
   6426 	fmov.s		&0xBF800000,%fp1	# LOAD -1
   6427 	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
   6428 
   6429 #--DIVIDE IS STILL CRANKING
   6430 
   6431 	fmov.x		%fp1,%fp0		# FP0 IS X'
   6432 	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
   6433 	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
   6434 
   6435 	fmov.x		%fp0,%fp1
   6436 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
   6437 
   6438 	fmov.d		ATANC5(%pc),%fp3
   6439 	fmov.d		ATANC4(%pc),%fp2
   6440 
   6441 	fmul.x		%fp1,%fp3		# Z*C5
   6442 	fmul.x		%fp1,%fp2		# Z*B4
   6443 
   6444 	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
   6445 	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
   6446 
   6447 	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
   6448 	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
   6449 
   6450 	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
   6451 	fmul.x		X(%a6),%fp0		# X'*Y
   6452 
   6453 	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
   6454 
   6455 	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
   6456 #					...	+[Y*(B2+Z*(B4+Z*B6))])
   6457 	fadd.x		X(%a6),%fp0
   6458 
   6459 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   6460 
   6461 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6462 	tst.b		(%a0)
   6463 	bpl.b		pos_big
   6464 
   6465 neg_big:
   6466 	fadd.x		NPIBY2(%pc),%fp0
   6467 	bra		t_minx2
   6468 
   6469 pos_big:
   6470 	fadd.x		PPIBY2(%pc),%fp0
   6471 	bra		t_pinx2
   6472 
   6473 ATANHUGE:
   6474 #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
   6475 	tst.b		(%a0)
   6476 	bpl.b		pos_huge
   6477 
   6478 neg_huge:
   6479 	fmov.x		NPIBY2(%pc),%fp0
   6480 	fmov.l		%d0,%fpcr
   6481 	fadd.x		PTINY(%pc),%fp0
   6482 	bra		t_minx2
   6483 
   6484 pos_huge:
   6485 	fmov.x		PPIBY2(%pc),%fp0
   6486 	fmov.l		%d0,%fpcr
   6487 	fadd.x		NTINY(%pc),%fp0
   6488 	bra		t_pinx2
   6489 
   6490 	global		satand
   6491 #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
   6492 satand:
   6493 	bra		t_extdnrm
   6494 
   6495 #########################################################################
   6496 # sasin():  computes the inverse sine of a normalized input		#
   6497 # sasind(): computes the inverse sine of a denormalized input		#
   6498 #									#
   6499 # INPUT ***************************************************************	#
   6500 #	a0 = pointer to extended precision input			#
   6501 #	d0 = round precision,mode					#
   6502 #									#
   6503 # OUTPUT **************************************************************	#
   6504 #	fp0 = arcsin(X)							#
   6505 #									#
   6506 # ACCURACY and MONOTONICITY *******************************************	#
   6507 #	The returned result is within 3 ulps in	64 significant bit,	#
   6508 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6509 #	rounded to double precision. The result is provably monotonic	#
   6510 #	in double precision.						#
   6511 #									#
   6512 # ALGORITHM ***********************************************************	#
   6513 #									#
   6514 #	ASIN								#
   6515 #	1. If |X| >= 1, go to 3.					#
   6516 #									#
   6517 #	2. (|X| < 1) Calculate asin(X) by				#
   6518 #		z := sqrt( [1-X][1+X] )					#
   6519 #		asin(X) = atan( x / z ).				#
   6520 #		Exit.							#
   6521 #									#
   6522 #	3. If |X| > 1, go to 5.						#
   6523 #									#
   6524 #	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
   6525 #									#
   6526 #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   6527 #		Exit.							#
   6528 #									#
   6529 #########################################################################
   6530 
   6531 	global		sasin
   6532 sasin:
   6533 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6534 
   6535 	mov.l		(%a0),%d1
   6536 	mov.w		4(%a0),%d1
   6537 	and.l		&0x7FFFFFFF,%d1
   6538 	cmp.l		%d1,&0x3FFF8000
   6539 	bge.b		ASINBIG
   6540 
   6541 # This catch is added here for the '060 QSP. Originally, the call to
   6542 # satan() would handle this case by causing the exception which would
   6543 # not be caught until gen_except(). Now, with the exceptions being
   6544 # detected inside of satan(), the exception would have been handled there
   6545 # instead of inside sasin() as expected.
   6546 	cmp.l		%d1,&0x3FD78000
   6547 	blt.w		ASINTINY
   6548 
   6549 #--THIS IS THE USUAL CASE, |X| < 1
   6550 #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
   6551 
   6552 ASINMAIN:
   6553 	fmov.s		&0x3F800000,%fp1
   6554 	fsub.x		%fp0,%fp1		# 1-X
   6555 	fmovm.x		&0x4,-(%sp)		#  {fp2}
   6556 	fmov.s		&0x3F800000,%fp2
   6557 	fadd.x		%fp0,%fp2		# 1+X
   6558 	fmul.x		%fp2,%fp1		# (1+X)(1-X)
   6559 	fmovm.x		(%sp)+,&0x20		#  {fp2}
   6560 	fsqrt.x		%fp1			# SQRT([1-X][1+X])
   6561 	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
   6562 	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
   6563 	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
   6564 	bsr		satan
   6565 	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
   6566 	bra		t_inx2
   6567 
   6568 ASINBIG:
   6569 	fabs.x		%fp0			# |X|
   6570 	fcmp.s		%fp0,&0x3F800000
   6571 	fbgt		t_operr			# cause an operr exception
   6572 
   6573 #--|X| = 1, ASIN(X) = +- PI/2.
   6574 ASINONE:
   6575 	fmov.x		PIBY2(%pc),%fp0
   6576 	mov.l		(%a0),%d1
   6577 	and.l		&0x80000000,%d1		# SIGN BIT OF X
   6578 	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
   6579 	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
   6580 	fmov.l		%d0,%fpcr
   6581 	fmul.s		(%sp)+,%fp0
   6582 	bra		t_inx2
   6583 
   6584 #--|X| < 2^(-40), ATAN(X) = X
   6585 ASINTINY:
   6586 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6587 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6588 	fmov.x		(%a0),%fp0		# last inst - possible exception
   6589 	bra		t_catch
   6590 
   6591 	global		sasind
   6592 #--ASIN(X) = X FOR DENORMALIZED X
   6593 sasind:
   6594 	bra		t_extdnrm
   6595 
   6596 #########################################################################
   6597 # sacos():  computes the inverse cosine of a normalized input		#
   6598 # sacosd(): computes the inverse cosine of a denormalized input		#
   6599 #									#
   6600 # INPUT ***************************************************************	#
   6601 #	a0 = pointer to extended precision input			#
   6602 #	d0 = round precision,mode					#
   6603 #									#
   6604 # OUTPUT ************************************************************** #
   6605 #	fp0 = arccos(X)							#
   6606 #									#
   6607 # ACCURACY and MONOTONICITY *******************************************	#
   6608 #	The returned result is within 3 ulps in	64 significant bit,	#
   6609 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6610 #	rounded to double precision. The result is provably monotonic	#
   6611 #	in double precision.						#
   6612 #									#
   6613 # ALGORITHM *********************************************************** #
   6614 #									#
   6615 #	ACOS								#
   6616 #	1. If |X| >= 1, go to 3.					#
   6617 #									#
   6618 #	2. (|X| < 1) Calculate acos(X) by				#
   6619 #		z := (1-X) / (1+X)					#
   6620 #		acos(X) = 2 * atan( sqrt(z) ).				#
   6621 #		Exit.							#
   6622 #									#
   6623 #	3. If |X| > 1, go to 5.						#
   6624 #									#
   6625 #	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
   6626 #									#
   6627 #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   6628 #		Exit.							#
   6629 #									#
   6630 #########################################################################
   6631 
   6632 	global		sacos
   6633 sacos:
   6634 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6635 
   6636 	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
   6637 	mov.w		4(%a0),%d1
   6638 	and.l		&0x7FFFFFFF,%d1
   6639 	cmp.l		%d1,&0x3FFF8000
   6640 	bge.b		ACOSBIG
   6641 
   6642 #--THIS IS THE USUAL CASE, |X| < 1
   6643 #--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
   6644 
   6645 ACOSMAIN:
   6646 	fmov.s		&0x3F800000,%fp1
   6647 	fadd.x		%fp0,%fp1		# 1+X
   6648 	fneg.x		%fp0			# -X
   6649 	fadd.s		&0x3F800000,%fp0	# 1-X
   6650 	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
   6651 	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
   6652 	mov.l		%d0,-(%sp)		# save original users fpcr
   6653 	clr.l		%d0
   6654 	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
   6655 	lea		(%sp),%a0		# pass ptr to sqrt
   6656 	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
   6657 	add.l		&0xc,%sp		# clear SQRT(...) from stack
   6658 
   6659 	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
   6660 	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
   6661 	bra		t_pinx2
   6662 
   6663 ACOSBIG:
   6664 	fabs.x		%fp0
   6665 	fcmp.s		%fp0,&0x3F800000
   6666 	fbgt		t_operr			# cause an operr exception
   6667 
   6668 #--|X| = 1, ACOS(X) = 0 OR PI
   6669 	tst.b		(%a0)			# is X positive or negative?
   6670 	bpl.b		ACOSP1
   6671 
   6672 #--X = -1
   6673 #Returns PI and inexact exception
   6674 ACOSM1:
   6675 	fmov.x		PI(%pc),%fp0		# load PI
   6676 	fmov.l		%d0,%fpcr		# load round mode,prec
   6677 	fadd.s		&0x00800000,%fp0	# add a small value
   6678 	bra		t_pinx2
   6679 
   6680 ACOSP1:
   6681 	bra		ld_pzero		# answer is positive zero
   6682 
   6683 	global		sacosd
   6684 #--ACOS(X) = PI/2 FOR DENORMALIZED X
   6685 sacosd:
   6686 	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
   6687 	fmov.x		PIBY2(%pc),%fp0
   6688 	bra		t_pinx2
   6689 
   6690 #########################################################################
   6691 # setox():    computes the exponential for a normalized input		#
   6692 # setoxd():   computes the exponential for a denormalized input		#
   6693 # setoxm1():  computes the exponential minus 1 for a normalized input	#
   6694 # setoxm1d(): computes the exponential minus 1 for a denormalized input	#
   6695 #									#
   6696 # INPUT	*************************************************************** #
   6697 #	a0 = pointer to extended precision input			#
   6698 #	d0 = round precision,mode					#
   6699 #									#
   6700 # OUTPUT ************************************************************** #
   6701 #	fp0 = exp(X) or exp(X)-1					#
   6702 #									#
   6703 # ACCURACY and MONOTONICITY ******************************************* #
   6704 #	The returned result is within 0.85 ulps in 64 significant bit, 	#
   6705 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   6706 #	rounded to double precision. The result is provably monotonic 	#
   6707 #	in double precision.						#
   6708 #									#
   6709 # ALGORITHM and IMPLEMENTATION **************************************** #
   6710 #									#
   6711 #	setoxd								#
   6712 #	------								#
   6713 #	Step 1.	Set ans := 1.0						#
   6714 #									#
   6715 #	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
   6716 #	Notes:	This will always generate one exception -- inexact.	#
   6717 #									#
   6718 #									#
   6719 #	setox								#
   6720 #	-----								#
   6721 #									#
   6722 #	Step 1.	Filter out extreme cases of input argument.		#
   6723 #		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
   6724 #		1.2	Go to Step 7.					#
   6725 #		1.3	If |X| < 16380 log(2), go to Step 2.		#
   6726 #		1.4	Go to Step 8.					#
   6727 #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
   6728 #		To avoid the use of floating-point comparisons, a	#
   6729 #		compact representation of |X| is used. This format is a	#
   6730 #		32-bit integer, the upper (more significant) 16 bits 	#
   6731 #		are the sign and biased exponent field of |X|; the 	#
   6732 #		lower 16 bits are the 16 most significant fraction	#
   6733 #		(including the explicit bit) bits of |X|. Consequently,	#
   6734 #		the comparisons in Steps 1.1 and 1.3 can be performed	#
   6735 #		by integer comparison. Note also that the constant	#
   6736 #		16380 log(2) used in Step 1.3 is also in the compact	#
   6737 #		form. Thus taking the branch to Step 2 guarantees 	#
   6738 #		|X| < 16380 log(2). There is no harm to have a small	#
   6739 #		number of cases where |X| is less than,	but close to,	#
   6740 #		16380 log(2) and the branch to Step 9 is taken.		#
   6741 #									#
   6742 #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
   6743 #		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
   6744 #			was taken)					#
   6745 #		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
   6746 #		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
   6747 #			or 63.						#
   6748 #		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
   6749 #		2.5	Calculate the address of the stored value of 	#
   6750 #			2^(J/64).					#
   6751 #		2.6	Create the value Scale = 2^M.			#
   6752 #	Notes:	The calculation in 2.2 is really performed by		#
   6753 #			Z := X * constant				#
   6754 #			N := round-to-nearest-integer(Z)		#
   6755 #		where							#
   6756 #			constant := single-precision( 64/log 2 ).	#
   6757 #									#
   6758 #		Using a single-precision constant avoids memory 	#
   6759 #		access. Another effect of using a single-precision	#
   6760 #		"constant" is that the calculated value Z is 		#
   6761 #									#
   6762 #			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
   6763 #									#
   6764 #		This error has to be considered later in Steps 3 and 4.	#
   6765 #									#
   6766 #	Step 3.	Calculate X - N*log2/64.				#
   6767 #		3.1	R := X + N*L1, 					#
   6768 #				where L1 := single-precision(-log2/64).	#
   6769 #		3.2	R := R + N*L2, 					#
   6770 #				L2 := extended-precision(-log2/64 - L1).#
   6771 #	Notes:	a) The way L1 and L2 are chosen ensures L1+L2 		#
   6772 #		approximate the value -log2/64 to 88 bits of accuracy.	#
   6773 #		b) N*L1 is exact because N is no longer than 22 bits	#
   6774 #		and L1 is no longer than 24 bits.			#
   6775 #		c) The calculation X+N*L1 is also exact due to 		#
   6776 #		cancellation. Thus, R is practically X+N(L1+L2) to full	#
   6777 #		64 bits. 						#
   6778 #		d) It is important to estimate how large can |R| be	#
   6779 #		after Step 3.2.						#
   6780 #									#
   6781 #		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
   6782 #		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
   6783 #		X*64/log2 - N	=	f - eps*X 64/log2		#
   6784 #		X - N*log2/64	=	f*log2/64 - eps*X		#
   6785 #									#
   6786 #									#
   6787 #		Now |X| <= 16446 log2, thus				#
   6788 #									#
   6789 #			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
   6790 #					<= 0.57 log2/64.		#
   6791 #		 This bound will be used in Step 4.			#
   6792 #									#
   6793 #	Step 4.	Approximate exp(R)-1 by a polynomial			#
   6794 #		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
   6795 #	Notes:	a) In order to reduce memory access, the coefficients 	#
   6796 #		are made as "short" as possible: A1 (which is 1/2), A4	#
   6797 #		and A5 are single precision; A2 and A3 are double	#
   6798 #		precision. 						#
   6799 #		b) Even with the restrictions above, 			#
   6800 #		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
   6801 #		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
   6802 #		c) To fully utilize the pipeline, p is separated into	#
   6803 #		two independent pieces of roughly equal complexities	#
   6804 #			p = [ R + R*S*(A2 + S*A4) ]	+		#
   6805 #				[ S*(A1 + S*(A3 + S*A5)) ]		#
   6806 #		where S = R*R.						#
   6807 #									#
   6808 #	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
   6809 #				ans := T + ( T*p + t)			#
   6810 #		where T and t are the stored values for 2^(J/64).	#
   6811 #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
   6812 #		2^(J/64) to roughly 85 bits; T is in extended precision	#
   6813 #		and t is in single precision. Note also that T is 	#
   6814 #		rounded to 62 bits so that the last two bits of T are 	#
   6815 #		zero. The reason for such a special form is that T-1, 	#
   6816 #		T-2, and T-8 will all be exact --- a property that will	#
   6817 #		give much more accurate computation of the function 	#
   6818 #		EXPM1.							#
   6819 #									#
   6820 #	Step 6.	Reconstruction of exp(X)				#
   6821 #			exp(X) = 2^M * 2^(J/64) * exp(R).		#
   6822 #		6.1	If AdjFlag = 0, go to 6.3			#
   6823 #		6.2	ans := ans * AdjScale				#
   6824 #		6.3	Restore the user FPCR				#
   6825 #		6.4	Return ans := ans * Scale. Exit.		#
   6826 #	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
   6827 #		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
   6828 #		neither overflow nor underflow. If AdjFlag = 1, that	#
   6829 #		means that						#
   6830 #			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
   6831 #		Hence, exp(X) may overflow or underflow or neither.	#
   6832 #		When that is the case, AdjScale = 2^(M1) where M1 is	#
   6833 #		approximately M. Thus 6.2 will never cause 		#
   6834 #		over/underflow. Possible exception in 6.4 is overflow	#
   6835 #		or underflow. The inexact exception is not generated in	#
   6836 #		6.4. Although one can argue that the inexact flag	#
   6837 #		should always be raised, to simulate that exception 	#
   6838 #		cost to much than the flag is worth in practical uses.	#
   6839 #									#
   6840 #	Step 7.	Return 1 + X.						#
   6841 #		7.1	ans := X					#
   6842 #		7.2	Restore user FPCR.				#
   6843 #		7.3	Return ans := 1 + ans. Exit			#
   6844 #	Notes:	For non-zero X, the inexact exception will always be	#
   6845 #		raised by 7.3. That is the only exception raised by 7.3.#
   6846 #		Note also that we use the FMOVEM instruction to move X	#
   6847 #		in Step 7.1 to avoid unnecessary trapping. (Although	#
   6848 #		the FMOVEM may not seem relevant since X is normalized,	#
   6849 #		the precaution will be useful in the library version of	#
   6850 #		this code where the separate entry for denormalized 	#
   6851 #		inputs will be done away with.)				#
   6852 #									#
   6853 #	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
   6854 #		8.1	If |X| > 16480 log2, go to Step 9.		#
   6855 #		(mimic 2.2 - 2.6)					#
   6856 #		8.2	N := round-to-integer( X * 64/log2 )		#
   6857 #		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
   6858 #		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1, 	#
   6859 #			AdjFlag := 1.					#
   6860 #		8.5	Calculate the address of the stored value 	#
   6861 #			2^(J/64).					#
   6862 #		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
   6863 #		8.7	Go to Step 3.					#
   6864 #	Notes:	Refer to notes for 2.2 - 2.6.				#
   6865 #									#
   6866 #	Step 9.	Handle exp(X), |X| > 16480 log2.			#
   6867 #		9.1	If X < 0, go to 9.3				#
   6868 #		9.2	ans := Huge, go to 9.4				#
   6869 #		9.3	ans := Tiny.					#
   6870 #		9.4	Restore user FPCR.				#
   6871 #		9.5	Return ans := ans * ans. Exit.			#
   6872 #	Notes:	Exp(X) will surely overflow or underflow, depending on	#
   6873 #		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
   6874 #		extended-precision numbers whose square over/underflow	#
   6875 #		with an inexact result. Thus, 9.5 always raises the	#
   6876 #		inexact together with either overflow or underflow.	#
   6877 #									#
   6878 #	setoxm1d							#
   6879 #	--------							#
   6880 #									#
   6881 #	Step 1.	Set ans := 0						#
   6882 #									#
   6883 #	Step 2.	Return	ans := X + ans. Exit.				#
   6884 #	Notes:	This will return X with the appropriate rounding	#
   6885 #		 precision prescribed by the user FPCR.			#
   6886 #									#
   6887 #	setoxm1								#
   6888 #	-------								#
   6889 #									#
   6890 #	Step 1.	Check |X|						#
   6891 #		1.1	If |X| >= 1/4, go to Step 1.3.			#
   6892 #		1.2	Go to Step 7.					#
   6893 #		1.3	If |X| < 70 log(2), go to Step 2.		#
   6894 #		1.4	Go to Step 10.					#
   6895 #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
   6896 #		However, it is conceivable |X| can be small very often	#
   6897 #		because EXPM1 is intended to evaluate exp(X)-1 		#
   6898 #		accurately when |X| is small. For further details on 	#
   6899 #		the comparisons, see the notes on Step 1 of setox.	#
   6900 #									#
   6901 #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
   6902 #		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
   6903 #		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
   6904 #			or 63.						#
   6905 #		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
   6906 #		2.4	Calculate the address of the stored value of 	#
   6907 #			2^(J/64).					#
   6908 #		2.5	Create the values Sc = 2^M and 			#
   6909 #			OnebySc := -2^(-M).				#
   6910 #	Notes:	See the notes on Step 2 of setox.			#
   6911 #									#
   6912 #	Step 3.	Calculate X - N*log2/64.				#
   6913 #		3.1	R := X + N*L1, 					#
   6914 #				where L1 := single-precision(-log2/64).	#
   6915 #		3.2	R := R + N*L2, 					#
   6916 #				L2 := extended-precision(-log2/64 - L1).#
   6917 #	Notes:	Applying the analysis of Step 3 of setox in this case	#
   6918 #		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
   6919 #		this case).						#
   6920 #									#
   6921 #	Step 4.	Approximate exp(R)-1 by a polynomial			#
   6922 #			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
   6923 #	Notes:	a) In order to reduce memory access, the coefficients 	#
   6924 #		are made as "short" as possible: A1 (which is 1/2), A5 	#
   6925 #		and A6 are single precision; A2, A3 and A4 are double 	#
   6926 #		precision. 						#
   6927 #		b) Even with the restriction above,			#
   6928 #			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
   6929 #		for all |R| <= 0.0055.					#
   6930 #		c) To fully utilize the pipeline, p is separated into	#
   6931 #		two independent pieces of roughly equal complexity	#
   6932 #			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
   6933 #				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
   6934 #		where S = R*R.						#
   6935 #									#
   6936 #	Step 5.	Compute 2^(J/64)*p by					#
   6937 #				p := T*p				#
   6938 #		where T and t are the stored values for 2^(J/64).	#
   6939 #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
   6940 #		2^(J/64) to roughly 85 bits; T is in extended precision	#
   6941 #		and t is in single precision. Note also that T is 	#
   6942 #		rounded to 62 bits so that the last two bits of T are 	#
   6943 #		zero. The reason for such a special form is that T-1, 	#
   6944 #		T-2, and T-8 will all be exact --- a property that will	#
   6945 #		be exploited in Step 6 below. The total relative error	#
   6946 #		in p is no bigger than 2^(-67.7) compared to the final	#
   6947 #		result.							#
   6948 #									#
   6949 #	Step 6.	Reconstruction of exp(X)-1				#
   6950 #			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
   6951 #		6.1	If M <= 63, go to Step 6.3.			#
   6952 #		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
   6953 #		6.3	If M >= -3, go to 6.5.				#
   6954 #		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
   6955 #		6.5	ans := (T + OnebySc) + (p + t).			#
   6956 #		6.6	Restore user FPCR.				#
   6957 #		6.7	Return ans := Sc * ans. Exit.			#
   6958 #	Notes:	The various arrangements of the expressions give 	#
   6959 #		accurate evaluations.					#
   6960 #									#
   6961 #	Step 7.	exp(X)-1 for |X| < 1/4.					#
   6962 #		7.1	If |X| >= 2^(-65), go to Step 9.		#
   6963 #		7.2	Go to Step 8.					#
   6964 #									#
   6965 #	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
   6966 #		8.1	If |X| < 2^(-16312), goto 8.3			#
   6967 #		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
   6968 #			Exit.						#
   6969 #		8.3	X := X * 2^(140).				#
   6970 #		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
   6971 #		 Return ans := ans*2^(140). Exit			#
   6972 #	Notes:	The idea is to return "X - tiny" under the user		#
   6973 #		precision and rounding modes. To avoid unnecessary	#
   6974 #		inefficiency, we stay away from denormalized numbers 	#
   6975 #		the best we can. For |X| >= 2^(-16312), the 		#
   6976 #		straightforward 8.2 generates the inexact exception as	#
   6977 #		the case warrants.					#
   6978 #									#
   6979 #	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
   6980 #			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
   6981 #	Notes:	a) In order to reduce memory access, the coefficients	#
   6982 #		are made as "short" as possible: B1 (which is 1/2), B9	#
   6983 #		to B12 are single precision; B3 to B8 are double 	#
   6984 #		precision; and B2 is double extended.			#
   6985 #		b) Even with the restriction above,			#
   6986 #			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
   6987 #		for all |X| <= 0.251.					#
   6988 #		Note that 0.251 is slightly bigger than 1/4.		#
   6989 #		c) To fully preserve accuracy, the polynomial is 	#
   6990 #		computed as						#
   6991 #			X + ( S*B1 +	Q ) where S = X*X and		#
   6992 #			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
   6993 #		d) To fully utilize the pipeline, Q is separated into	#
   6994 #		two independent pieces of roughly equal complexity	#
   6995 #			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
   6996 #				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
   6997 #									#
   6998 #	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
   6999 #		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all 	#
   7000 #		practical purposes. Therefore, go to Step 1 of setox.	#
   7001 #		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
   7002 #		purposes. 						#
   7003 #		ans := -1 						#
   7004 #		Restore user FPCR					#
   7005 #		Return ans := ans + 2^(-126). Exit.			#
   7006 #	Notes:	10.2 will always create an inexact and return -1 + tiny	#
   7007 #		in the user rounding precision and mode.		#
   7008 #									#
   7009 #########################################################################
   7010 
   7011 L2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
   7012 
   7013 EEXPA3:	long		0x3FA55555,0x55554CC1
   7014 EEXPA2:	long		0x3FC55555,0x55554A54
   7015 
   7016 EM1A4:	long		0x3F811111,0x11174385
   7017 EM1A3:	long		0x3FA55555,0x55554F5A
   7018 
   7019 EM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
   7020 
   7021 EM1B8:	long		0x3EC71DE3,0xA5774682
   7022 EM1B7:	long		0x3EFA01A0,0x19D7CB68
   7023 
   7024 EM1B6:	long		0x3F2A01A0,0x1A019DF3
   7025 EM1B5:	long		0x3F56C16C,0x16C170E2
   7026 
   7027 EM1B4:	long		0x3F811111,0x11111111
   7028 EM1B3:	long		0x3FA55555,0x55555555
   7029 
   7030 EM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
   7031 	long		0x00000000
   7032 
   7033 TWO140:	long		0x48B00000,0x00000000
   7034 TWON140:
   7035 	long		0x37300000,0x00000000
   7036 
   7037 EEXPTBL:
   7038 	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
   7039 	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
   7040 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
   7041 	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
   7042 	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
   7043 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
   7044 	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
   7045 	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
   7046 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
   7047 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
   7048 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
   7049 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
   7050 	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
   7051 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
   7052 	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
   7053 	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
   7054 	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
   7055 	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
   7056 	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
   7057 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
   7058 	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
   7059 	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
   7060 	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
   7061 	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
   7062 	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
   7063 	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
   7064 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
   7065 	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
   7066 	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
   7067 	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
   7068 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
   7069 	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
   7070 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
   7071 	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
   7072 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
   7073 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
   7074 	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
   7075 	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
   7076 	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
   7077 	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
   7078 	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
   7079 	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
   7080 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
   7081 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
   7082 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
   7083 	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
   7084 	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
   7085 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
   7086 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
   7087 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
   7088 	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
   7089 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
   7090 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
   7091 	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
   7092 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
   7093 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
   7094 	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
   7095 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
   7096 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
   7097 	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
   7098 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
   7099 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
   7100 	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
   7101 	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
   7102 
   7103 	set		ADJFLAG,L_SCR2
   7104 	set		SCALE,FP_SCR0
   7105 	set		ADJSCALE,FP_SCR1
   7106 	set		SC,FP_SCR0
   7107 	set		ONEBYSC,FP_SCR1
   7108 
   7109 	global		setox
   7110 setox:
   7111 #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
   7112 
   7113 #--Step 1.
   7114 	mov.l		(%a0),%d1		# load part of input X
   7115 	and.l		&0x7FFF0000,%d1		# biased expo. of X
   7116 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
   7117 	bge.b		EXPC1			# normal case
   7118 	bra		EXPSM
   7119 
   7120 EXPC1:
   7121 #--The case |X| >= 2^(-65)
   7122 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
   7123 	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
   7124 	blt.b		EXPMAIN			# normal case
   7125 	bra		EEXPBIG
   7126 
   7127 EXPMAIN:
   7128 #--Step 2.
   7129 #--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
   7130 	fmov.x		(%a0),%fp0		# load input from (a0)
   7131 
   7132 	fmov.x		%fp0,%fp1
   7133 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7134 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7135 	mov.l		&0,ADJFLAG(%a6)
   7136 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7137 	lea		EEXPTBL(%pc),%a1
   7138 	fmov.l		%d1,%fp0		# convert to floating-format
   7139 
   7140 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7141 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7142 	lsl.l		&4,%d1
   7143 	add.l		%d1,%a1			# address of 2^(J/64)
   7144 	mov.l		L_SCR1(%a6),%d1
   7145 	asr.l		&6,%d1			# D0 is M
   7146 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
   7147 	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
   7148 
   7149 EXPCONT1:
   7150 #--Step 3.
   7151 #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
   7152 #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
   7153 	fmov.x		%fp0,%fp2
   7154 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
   7155 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
   7156 	fadd.x		%fp1,%fp0		# X + N*L1
   7157 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
   7158 
   7159 #--Step 4.
   7160 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
   7161 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
   7162 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
   7163 #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
   7164 
   7165 	fmov.x		%fp0,%fp1
   7166 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
   7167 
   7168 	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
   7169 
   7170 	fmul.x		%fp1,%fp2		# fp2 IS S*A5
   7171 	fmov.x		%fp1,%fp3
   7172 	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
   7173 
   7174 	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
   7175 	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
   7176 
   7177 	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
   7178 	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
   7179 	mov.l		&0x80000000,SCALE+4(%a6)
   7180 	clr.l		SCALE+8(%a6)
   7181 
   7182 	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
   7183 
   7184 	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
   7185 	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
   7186 
   7187 	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
   7188 	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
   7189 
   7190 	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
   7191 	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
   7192 
   7193 #--Step 5
   7194 #--final reconstruction process
   7195 #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
   7196 
   7197 	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
   7198 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7199 	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
   7200 
   7201 	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
   7202 	mov.l		ADJFLAG(%a6),%d1
   7203 
   7204 #--Step 6
   7205 	tst.l		%d1
   7206 	beq.b		NORMAL
   7207 ADJUST:
   7208 	fmul.x		ADJSCALE(%a6),%fp0
   7209 NORMAL:
   7210 	fmov.l		%d0,%fpcr		# restore user FPCR
   7211 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7212 	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
   7213 	bra		t_catch
   7214 
   7215 EXPSM:
   7216 #--Step 7
   7217 	fmovm.x		(%a0),&0x80		# load X
   7218 	fmov.l		%d0,%fpcr
   7219 	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
   7220 	bra		t_pinx2
   7221 
   7222 EEXPBIG:
   7223 #--Step 8
   7224 	cmp.l		%d1,&0x400CB27C		# 16480 log2
   7225 	bgt.b		EXP2BIG
   7226 #--Steps 8.2 -- 8.6
   7227 	fmov.x		(%a0),%fp0		# load input from (a0)
   7228 
   7229 	fmov.x		%fp0,%fp1
   7230 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7231 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7232 	mov.l		&1,ADJFLAG(%a6)
   7233 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7234 	lea		EEXPTBL(%pc),%a1
   7235 	fmov.l		%d1,%fp0		# convert to floating-format
   7236 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7237 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7238 	lsl.l		&4,%d1
   7239 	add.l		%d1,%a1			# address of 2^(J/64)
   7240 	mov.l		L_SCR1(%a6),%d1
   7241 	asr.l		&6,%d1			# D0 is K
   7242 	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
   7243 	asr.l		&1,%d1			# D0 is M1
   7244 	sub.l		%d1,L_SCR1(%a6)		# a1 is M
   7245 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
   7246 	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
   7247 	mov.l		&0x80000000,ADJSCALE+4(%a6)
   7248 	clr.l		ADJSCALE+8(%a6)
   7249 	mov.l		L_SCR1(%a6),%d1		# D0 is M
   7250 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
   7251 	bra.w		EXPCONT1		# go back to Step 3
   7252 
   7253 EXP2BIG:
   7254 #--Step 9
   7255 	tst.b		(%a0)			# is X positive or negative?
   7256 	bmi		t_unfl2
   7257 	bra		t_ovfl2
   7258 
   7259 	global		setoxd
   7260 setoxd:
   7261 #--entry point for EXP(X), X is denormalized
   7262 	mov.l		(%a0),-(%sp)
   7263 	andi.l		&0x80000000,(%sp)
   7264 	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
   7265 
   7266 	fmov.s		&0x3F800000,%fp0
   7267 
   7268 	fmov.l		%d0,%fpcr
   7269 	fadd.s		(%sp)+,%fp0
   7270 	bra		t_pinx2
   7271 
   7272 	global		setoxm1
   7273 setoxm1:
   7274 #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
   7275 
   7276 #--Step 1.
   7277 #--Step 1.1
   7278 	mov.l		(%a0),%d1		# load part of input X
   7279 	and.l		&0x7FFF0000,%d1		# biased expo. of X
   7280 	cmp.l		%d1,&0x3FFD0000		# 1/4
   7281 	bge.b		EM1CON1			# |X| >= 1/4
   7282 	bra		EM1SM
   7283 
   7284 EM1CON1:
   7285 #--Step 1.3
   7286 #--The case |X| >= 1/4
   7287 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
   7288 	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
   7289 	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
   7290 	bra		EM1BIG
   7291 
   7292 EM1MAIN:
   7293 #--Step 2.
   7294 #--This is the case:	1/4 <= |X| <= 70 log2.
   7295 	fmov.x		(%a0),%fp0		# load input from (a0)
   7296 
   7297 	fmov.x		%fp0,%fp1
   7298 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7299 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7300 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7301 	lea		EEXPTBL(%pc),%a1
   7302 	fmov.l		%d1,%fp0		# convert to floating-format
   7303 
   7304 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7305 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7306 	lsl.l		&4,%d1
   7307 	add.l		%d1,%a1			# address of 2^(J/64)
   7308 	mov.l		L_SCR1(%a6),%d1
   7309 	asr.l		&6,%d1			# D0 is M
   7310 	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
   7311 
   7312 #--Step 3.
   7313 #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
   7314 #--a0 points to 2^(J/64), D0 and a1 both contain M
   7315 	fmov.x		%fp0,%fp2
   7316 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
   7317 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
   7318 	fadd.x		%fp1,%fp0		# X + N*L1
   7319 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
   7320 	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
   7321 
   7322 #--Step 4.
   7323 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
   7324 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
   7325 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
   7326 #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
   7327 
   7328 	fmov.x		%fp0,%fp1
   7329 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
   7330 
   7331 	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
   7332 
   7333 	fmul.x		%fp1,%fp2		# fp2 IS S*A6
   7334 	fmov.x		%fp1,%fp3
   7335 	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
   7336 
   7337 	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
   7338 	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
   7339 	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
   7340 	mov.l		&0x80000000,SC+4(%a6)
   7341 	clr.l		SC+8(%a6)
   7342 
   7343 	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
   7344 	mov.l		L_SCR1(%a6),%d1		# D0 is	M
   7345 	neg.w		%d1			# D0 is -M
   7346 	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
   7347 	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
   7348 	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
   7349 	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
   7350 
   7351 	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
   7352 	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
   7353 	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
   7354 	mov.l		&0x80000000,ONEBYSC+4(%a6)
   7355 	clr.l		ONEBYSC+8(%a6)
   7356 	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
   7357 
   7358 	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
   7359 	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
   7360 
   7361 	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
   7362 
   7363 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7364 
   7365 #--Step 5
   7366 #--Compute 2^(J/64)*p
   7367 
   7368 	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
   7369 
   7370 #--Step 6
   7371 #--Step 6.1
   7372 	mov.l		L_SCR1(%a6),%d1		# retrieve M
   7373 	cmp.l		%d1,&63
   7374 	ble.b		MLE63
   7375 #--Step 6.2	M >= 64
   7376 	fmov.s		12(%a1),%fp1		# fp1 is t
   7377 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
   7378 	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
   7379 	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
   7380 	bra		EM1SCALE
   7381 MLE63:
   7382 #--Step 6.3	M <= 63
   7383 	cmp.l		%d1,&-3
   7384 	bge.b		MGEN3
   7385 MLTN3:
   7386 #--Step 6.4	M <= -4
   7387 	fadd.s		12(%a1),%fp0		# p+t
   7388 	fadd.x		(%a1),%fp0		# T+(p+t)
   7389 	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
   7390 	bra		EM1SCALE
   7391 MGEN3:
   7392 #--Step 6.5	-3 <= M <= 63
   7393 	fmov.x		(%a1)+,%fp1		# fp1 is T
   7394 	fadd.s		(%a1),%fp0		# fp0 is p+t
   7395 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
   7396 	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
   7397 
   7398 EM1SCALE:
   7399 #--Step 6.6
   7400 	fmov.l		%d0,%fpcr
   7401 	fmul.x		SC(%a6),%fp0
   7402 	bra		t_inx2
   7403 
   7404 EM1SM:
   7405 #--Step 7	|X| < 1/4.
   7406 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
   7407 	bge.b		EM1POLY
   7408 
   7409 EM1TINY:
   7410 #--Step 8	|X| < 2^(-65)
   7411 	cmp.l		%d1,&0x00330000		# 2^(-16312)
   7412 	blt.b		EM12TINY
   7413 #--Step 8.2
   7414 	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
   7415 	mov.l		&0x80000000,SC+4(%a6)
   7416 	clr.l		SC+8(%a6)
   7417 	fmov.x		(%a0),%fp0
   7418 	fmov.l		%d0,%fpcr
   7419 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7420 	fadd.x		SC(%a6),%fp0
   7421 	bra		t_catch
   7422 
   7423 EM12TINY:
   7424 #--Step 8.3
   7425 	fmov.x		(%a0),%fp0
   7426 	fmul.d		TWO140(%pc),%fp0
   7427 	mov.l		&0x80010000,SC(%a6)
   7428 	mov.l		&0x80000000,SC+4(%a6)
   7429 	clr.l		SC+8(%a6)
   7430 	fadd.x		SC(%a6),%fp0
   7431 	fmov.l		%d0,%fpcr
   7432 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7433 	fmul.d		TWON140(%pc),%fp0
   7434 	bra		t_catch
   7435 
   7436 EM1POLY:
   7437 #--Step 9	exp(X)-1 by a simple polynomial
   7438 	fmov.x		(%a0),%fp0		# fp0 is X
   7439 	fmul.x		%fp0,%fp0		# fp0 is S := X*X
   7440 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7441 	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
   7442 	fmul.x		%fp0,%fp1		# fp1 is S*B12
   7443 	fmov.s		&0x310F8290,%fp2	# fp2 is B11
   7444 	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
   7445 
   7446 	fmul.x		%fp0,%fp2		# fp2 is S*B11
   7447 	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
   7448 
   7449 	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
   7450 	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
   7451 
   7452 	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
   7453 	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
   7454 
   7455 	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
   7456 	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
   7457 
   7458 	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
   7459 	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
   7460 
   7461 	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
   7462 	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
   7463 
   7464 	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
   7465 	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
   7466 
   7467 	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
   7468 	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
   7469 
   7470 	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
   7471 	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
   7472 
   7473 	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
   7474 	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
   7475 
   7476 	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
   7477 	fadd.x		%fp2,%fp1		# fp1 is Q
   7478 
   7479 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7480 
   7481 	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
   7482 
   7483 	fmov.l		%d0,%fpcr
   7484 	fadd.x		(%a0),%fp0
   7485 	bra		t_inx2
   7486 
   7487 EM1BIG:
   7488 #--Step 10	|X| > 70 log2
   7489 	mov.l		(%a0),%d1
   7490 	cmp.l		%d1,&0
   7491 	bgt.w		EXPC1
   7492 #--Step 10.2
   7493 	fmov.s		&0xBF800000,%fp0	# fp0 is -1
   7494 	fmov.l		%d0,%fpcr
   7495 	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
   7496 	bra		t_minx2
   7497 
   7498 	global		setoxm1d
   7499 setoxm1d:
   7500 #--entry point for EXPM1(X), here X is denormalized
   7501 #--Step 0.
   7502 	bra		t_extdnrm
   7503 
   7504 #########################################################################
   7505 # sgetexp():  returns the exponent portion of the input argument.	#
   7506 #	      The exponent bias is removed and the exponent value is	#
   7507 #	      returned as an extended precision number in fp0.		#
   7508 # sgetexpd(): handles denormalized numbers. 				#
   7509 #									#
   7510 # sgetman():  extracts the mantissa of the input argument. The 		#
   7511 #	      mantissa is converted to an extended precision number w/ 	#
   7512 #	      an exponent of $3fff and is returned in fp0. The range of #
   7513 #	      the result is [1.0 - 2.0).				#
   7514 # sgetmand(): handles denormalized numbers.				#
   7515 #									#
   7516 # INPUT *************************************************************** #
   7517 #	a0  = pointer to extended precision input			#
   7518 #									#
   7519 # OUTPUT ************************************************************** #
   7520 #	fp0 = exponent(X) or mantissa(X)				#
   7521 #									#
   7522 #########################################################################
   7523 
   7524 	global		sgetexp
   7525 sgetexp:
   7526 	mov.w		SRC_EX(%a0),%d0		# get the exponent
   7527 	bclr		&0xf,%d0		# clear the sign bit
   7528 	subi.w		&0x3fff,%d0		# subtract off the bias
   7529 	fmov.w		%d0,%fp0		# return exp in fp0
   7530 	blt.b		sgetexpn		# it's negative
   7531 	rts
   7532 
   7533 sgetexpn:
   7534 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7535 	rts
   7536 
   7537 	global		sgetexpd
   7538 sgetexpd:
   7539 	bsr.l		norm			# normalize
   7540 	neg.w		%d0			# new exp = -(shft amt)
   7541 	subi.w		&0x3fff,%d0		# subtract off the bias
   7542 	fmov.w		%d0,%fp0		# return exp in fp0
   7543 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7544 	rts
   7545 
   7546 	global		sgetman
   7547 sgetman:
   7548 	mov.w		SRC_EX(%a0),%d0		# get the exp
   7549 	ori.w		&0x7fff,%d0		# clear old exp
   7550 	bclr		&0xe,%d0		# make it the new exp +-3fff
   7551 
   7552 # here, we build the result in a tmp location so as not to disturb the input
   7553 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
   7554 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
   7555 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   7556 	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
   7557 	bmi.b		sgetmann		# it's negative
   7558 	rts
   7559 
   7560 sgetmann:
   7561 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7562 	rts
   7563 
   7564 #
   7565 # For denormalized numbers, shift the mantissa until the j-bit = 1,
   7566 # then load the exponent with +/1 $3fff.
   7567 #
   7568 	global		sgetmand
   7569 sgetmand:
   7570 	bsr.l		norm			# normalize exponent
   7571 	bra.b		sgetman
   7572 
   7573 #########################################################################
   7574 # scosh():  computes the hyperbolic cosine of a normalized input	#
   7575 # scoshd(): computes the hyperbolic cosine of a denormalized input	#
   7576 #									#
   7577 # INPUT ***************************************************************	#
   7578 #	a0 = pointer to extended precision input			#
   7579 #	d0 = round precision,mode					#
   7580 #									#
   7581 # OUTPUT **************************************************************	#
   7582 #	fp0 = cosh(X)							#
   7583 #									#
   7584 # ACCURACY and MONOTONICITY *******************************************	#
   7585 #	The returned result is within 3 ulps in 64 significant bit, 	#
   7586 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   7587 #	rounded to double precision. The result is provably monotonic 	#
   7588 #	in double precision.						#
   7589 #									#
   7590 # ALGORITHM ***********************************************************	#
   7591 #									#
   7592 #	COSH								#
   7593 #	1. If |X| > 16380 log2, go to 3.				#
   7594 #									#
   7595 #	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
   7596 #		y = |X|, z = exp(Y), and				#
   7597 #		cosh(X) = (1/2)*( z + 1/z ).				#
   7598 #		Exit.							#
   7599 #									#
   7600 #	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
   7601 #									#
   7602 #	4. (16380 log2 < |X| <= 16480 log2)				#
   7603 #		cosh(X) = sign(X) * exp(|X|)/2.				#
   7604 #		However, invoking exp(|X|) may cause premature 		#
   7605 #		overflow. Thus, we calculate sinh(X) as follows:	#
   7606 #		Y	:= |X|						#
   7607 #		Fact	:=	2**(16380)				#
   7608 #		Y'	:= Y - 16381 log2				#
   7609 #		cosh(X) := Fact * exp(Y').				#
   7610 #		Exit.							#
   7611 #									#
   7612 #	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
   7613 #		Huge*Huge to generate overflow and an infinity with	#
   7614 #		the appropriate sign. Huge is the largest finite number	#
   7615 #		in extended format. Exit.				#
   7616 #									#
   7617 #########################################################################
   7618 
   7619 TWO16380:
   7620 	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
   7621 
   7622 	global		scosh
   7623 scosh:
   7624 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7625 
   7626 	mov.l		(%a0),%d1
   7627 	mov.w		4(%a0),%d1
   7628 	and.l		&0x7FFFFFFF,%d1
   7629 	cmp.l		%d1,&0x400CB167
   7630 	bgt.b		COSHBIG
   7631 
   7632 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
   7633 #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
   7634 
   7635 	fabs.x		%fp0			# |X|
   7636 
   7637 	mov.l		%d0,-(%sp)
   7638 	clr.l		%d0
   7639 	fmovm.x		&0x01,-(%sp)		# save |X| to stack
   7640 	lea		(%sp),%a0		# pass ptr to |X|
   7641 	bsr		setox			# FP0 IS EXP(|X|)
   7642 	add.l		&0xc,%sp		# erase |X| from stack
   7643 	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
   7644 	mov.l		(%sp)+,%d0
   7645 
   7646 	fmov.s		&0x3E800000,%fp1	# (1/4)
   7647 	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
   7648 
   7649 	fmov.l		%d0,%fpcr
   7650 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7651 	fadd.x		%fp1,%fp0
   7652 	bra		t_catch
   7653 
   7654 COSHBIG:
   7655 	cmp.l		%d1,&0x400CB2B3
   7656 	bgt.b		COSHHUGE
   7657 
   7658 	fabs.x		%fp0
   7659 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
   7660 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
   7661 
   7662 	mov.l		%d0,-(%sp)
   7663 	clr.l		%d0
   7664 	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
   7665 	lea		(%sp),%a0		# pass ptr to fp0
   7666 	bsr		setox
   7667 	add.l		&0xc,%sp		# clear fp0 from stack
   7668 	mov.l		(%sp)+,%d0
   7669 
   7670 	fmov.l		%d0,%fpcr
   7671 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7672 	fmul.x		TWO16380(%pc),%fp0
   7673 	bra		t_catch
   7674 
   7675 COSHHUGE:
   7676 	bra		t_ovfl2
   7677 
   7678 	global		scoshd
   7679 #--COSH(X) = 1 FOR DENORMALIZED X
   7680 scoshd:
   7681 	fmov.s		&0x3F800000,%fp0
   7682 
   7683 	fmov.l		%d0,%fpcr
   7684 	fadd.s		&0x00800000,%fp0
   7685 	bra		t_pinx2
   7686 
   7687 #########################################################################
   7688 # ssinh():  computes the hyperbolic sine of a normalized input		#
   7689 # ssinhd(): computes the hyperbolic sine of a denormalized input	#
   7690 #									#
   7691 # INPUT *************************************************************** #
   7692 #	a0 = pointer to extended precision input			#
   7693 #	d0 = round precision,mode					#
   7694 #									#
   7695 # OUTPUT ************************************************************** #
   7696 #	fp0 = sinh(X)							#
   7697 #									#
   7698 # ACCURACY and MONOTONICITY *******************************************	#
   7699 #	The returned result is within 3 ulps in 64 significant bit, 	#
   7700 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   7701 #	rounded to double precision. The result is provably monotonic	#
   7702 #	in double precision.						#
   7703 #									#
   7704 # ALGORITHM *********************************************************** #
   7705 #									#
   7706 #       SINH								#
   7707 #       1. If |X| > 16380 log2, go to 3.				#
   7708 #									#
   7709 #       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
   7710 #               y = |X|, sgn = sign(X), and z = expm1(Y),		#
   7711 #               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
   7712 #          Exit.							#
   7713 #									#
   7714 #       3. If |X| > 16480 log2, go to 5.				#
   7715 #									#
   7716 #       4. (16380 log2 < |X| <= 16480 log2)				#
   7717 #               sinh(X) = sign(X) * exp(|X|)/2.				#
   7718 #          However, invoking exp(|X|) may cause premature overflow.	#
   7719 #          Thus, we calculate sinh(X) as follows:			#
   7720 #             Y       := |X|						#
   7721 #             sgn     := sign(X)					#
   7722 #             sgnFact := sgn * 2**(16380)				#
   7723 #             Y'      := Y - 16381 log2					#
   7724 #             sinh(X) := sgnFact * exp(Y').				#
   7725 #          Exit.							#
   7726 #									#
   7727 #       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
   7728 #          sign(X)*Huge*Huge to generate overflow and an infinity with	#
   7729 #          the appropriate sign. Huge is the largest finite number in	#
   7730 #          extended format. Exit.					#
   7731 #									#
   7732 #########################################################################
   7733 
   7734 	global		ssinh
   7735 ssinh:
   7736 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7737 
   7738 	mov.l		(%a0),%d1
   7739 	mov.w		4(%a0),%d1
   7740 	mov.l		%d1,%a1			# save (compacted) operand
   7741 	and.l		&0x7FFFFFFF,%d1
   7742 	cmp.l		%d1,&0x400CB167
   7743 	bgt.b		SINHBIG
   7744 
   7745 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
   7746 #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
   7747 
   7748 	fabs.x		%fp0			# Y = |X|
   7749 
   7750 	movm.l		&0x8040,-(%sp)		# {a1/d0}
   7751 	fmovm.x		&0x01,-(%sp)		# save Y on stack
   7752 	lea		(%sp),%a0		# pass ptr to Y
   7753 	clr.l		%d0
   7754 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
   7755 	add.l		&0xc,%sp		# clear Y from stack
   7756 	fmov.l		&0,%fpcr
   7757 	movm.l		(%sp)+,&0x0201		# {a1/d0}
   7758 
   7759 	fmov.x		%fp0,%fp1
   7760 	fadd.s		&0x3F800000,%fp1	# 1+Z
   7761 	fmov.x		%fp0,-(%sp)
   7762 	fdiv.x		%fp1,%fp0		# Z/(1+Z)
   7763 	mov.l		%a1,%d1
   7764 	and.l		&0x80000000,%d1
   7765 	or.l		&0x3F000000,%d1
   7766 	fadd.x		(%sp)+,%fp0
   7767 	mov.l		%d1,-(%sp)
   7768 
   7769 	fmov.l		%d0,%fpcr
   7770 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7771 	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
   7772 	bra		t_catch
   7773 
   7774 SINHBIG:
   7775 	cmp.l		%d1,&0x400CB2B3
   7776 	bgt		t_ovfl
   7777 	fabs.x		%fp0
   7778 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
   7779 	mov.l		&0,-(%sp)
   7780 	mov.l		&0x80000000,-(%sp)
   7781 	mov.l		%a1,%d1
   7782 	and.l		&0x80000000,%d1
   7783 	or.l		&0x7FFB0000,%d1
   7784 	mov.l		%d1,-(%sp)		# EXTENDED FMT
   7785 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
   7786 
   7787 	mov.l		%d0,-(%sp)
   7788 	clr.l		%d0
   7789 	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
   7790 	lea		(%sp),%a0		# pass ptr to fp0
   7791 	bsr		setox
   7792 	add.l		&0xc,%sp		# clear fp0 from stack
   7793 
   7794 	mov.l		(%sp)+,%d0
   7795 	fmov.l		%d0,%fpcr
   7796 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7797 	fmul.x		(%sp)+,%fp0		# possible exception
   7798 	bra		t_catch
   7799 
   7800 	global		ssinhd
   7801 #--SINH(X) = X FOR DENORMALIZED X
   7802 ssinhd:
   7803 	bra		t_extdnrm
   7804 
   7805 #########################################################################
   7806 # stanh():  computes the hyperbolic tangent of a normalized input	#
   7807 # stanhd(): computes the hyperbolic tangent of a denormalized input	#
   7808 #									#
   7809 # INPUT ***************************************************************	#
   7810 #	a0 = pointer to extended precision input			#
   7811 #	d0 = round precision,mode					#
   7812 #									#
   7813 # OUTPUT **************************************************************	#
   7814 #	fp0 = tanh(X)							#
   7815 #									#
   7816 # ACCURACY and MONOTONICITY *******************************************	#
   7817 #	The returned result is within 3 ulps in 64 significant bit, 	#
   7818 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   7819 #	rounded to double precision. The result is provably monotonic	#
   7820 #	in double precision.						#
   7821 #									#
   7822 # ALGORITHM ***********************************************************	#
   7823 #									#
   7824 #	TANH								#
   7825 #	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
   7826 #									#
   7827 #	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
   7828 #		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
   7829 #		tanh(X) = sgn*( z/(2+z) ).				#
   7830 #		Exit.							#
   7831 #									#
   7832 #	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
   7833 #		go to 7.						#
   7834 #									#
   7835 #	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
   7836 #									#
   7837 #	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
   7838 #		sgn := sign(X), y := 2|X|, z := exp(Y),			#
   7839 #		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
   7840 #		Exit.							#
   7841 #									#
   7842 #	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
   7843 #		calculate Tanh(X) by					#
   7844 #		sgn := sign(X), Tiny := 2**(-126),			#
   7845 #		tanh(X) := sgn - sgn*Tiny.				#
   7846 #		Exit.							#
   7847 #									#
   7848 #	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
   7849 #									#
   7850 #########################################################################
   7851 
   7852 	set		X,FP_SCR0
   7853 	set		XFRAC,X+4
   7854 
   7855 	set		SGN,L_SCR3
   7856 
   7857 	set		V,FP_SCR0
   7858 
   7859 	global		stanh
   7860 stanh:
   7861 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7862 
   7863 	fmov.x		%fp0,X(%a6)
   7864 	mov.l		(%a0),%d1
   7865 	mov.w		4(%a0),%d1
   7866 	mov.l		%d1,X(%a6)
   7867 	and.l		&0x7FFFFFFF,%d1
   7868 	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
   7869 	blt.w		TANHBORS		# yes
   7870 	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
   7871 	bgt.w		TANHBORS		# yes
   7872 
   7873 #--THIS IS THE USUAL CASE
   7874 #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
   7875 
   7876 	mov.l		X(%a6),%d1
   7877 	mov.l		%d1,SGN(%a6)
   7878 	and.l		&0x7FFF0000,%d1
   7879 	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
   7880 	mov.l		%d1,X(%a6)
   7881 	and.l		&0x80000000,SGN(%a6)
   7882 	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
   7883 
   7884 	mov.l		%d0,-(%sp)
   7885 	clr.l		%d0
   7886 	fmovm.x		&0x1,-(%sp)		# save Y on stack
   7887 	lea		(%sp),%a0		# pass ptr to Y
   7888 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
   7889 	add.l		&0xc,%sp		# clear Y from stack
   7890 	mov.l		(%sp)+,%d0
   7891 
   7892 	fmov.x		%fp0,%fp1
   7893 	fadd.s		&0x40000000,%fp1	# Z+2
   7894 	mov.l		SGN(%a6),%d1
   7895 	fmov.x		%fp1,V(%a6)
   7896 	eor.l		%d1,V(%a6)
   7897 
   7898 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   7899 	fdiv.x		V(%a6),%fp0
   7900 	bra		t_inx2
   7901 
   7902 TANHBORS:
   7903 	cmp.l		%d1,&0x3FFF8000
   7904 	blt.w		TANHSM
   7905 
   7906 	cmp.l		%d1,&0x40048AA1
   7907 	bgt.w		TANHHUGE
   7908 
   7909 #-- (5/2) LOG2 < |X| < 50 LOG2,
   7910 #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
   7911 #--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
   7912 
   7913 	mov.l		X(%a6),%d1
   7914 	mov.l		%d1,SGN(%a6)
   7915 	and.l		&0x7FFF0000,%d1
   7916 	add.l		&0x00010000,%d1		# EXPO OF 2|X|
   7917 	mov.l		%d1,X(%a6)		# Y = 2|X|
   7918 	and.l		&0x80000000,SGN(%a6)
   7919 	mov.l		SGN(%a6),%d1
   7920 	fmov.x		X(%a6),%fp0		# Y = 2|X|
   7921 
   7922 	mov.l		%d0,-(%sp)
   7923 	clr.l		%d0
   7924 	fmovm.x		&0x01,-(%sp)		# save Y on stack
   7925 	lea		(%sp),%a0		# pass ptr to Y
   7926 	bsr		setox			# FP0 IS EXP(Y)
   7927 	add.l		&0xc,%sp		# clear Y from stack
   7928 	mov.l		(%sp)+,%d0
   7929 	mov.l		SGN(%a6),%d1
   7930 	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
   7931 
   7932 	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
   7933 	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
   7934 	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
   7935 
   7936 	mov.l		SGN(%a6),%d1
   7937 	or.l		&0x3F800000,%d1		# SGN
   7938 	fmov.s		%d1,%fp0		# SGN IN SGL FMT
   7939 
   7940 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   7941 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7942 	fadd.x		%fp1,%fp0
   7943 	bra		t_inx2
   7944 
   7945 TANHSM:
   7946 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   7947 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   7948 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   7949 	bra		t_catch
   7950 
   7951 #---RETURN SGN(X) - SGN(X)EPS
   7952 TANHHUGE:
   7953 	mov.l		X(%a6),%d1
   7954 	and.l		&0x80000000,%d1
   7955 	or.l		&0x3F800000,%d1
   7956 	fmov.s		%d1,%fp0
   7957 	and.l		&0x80000000,%d1
   7958 	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
   7959 
   7960 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   7961 	fadd.s		%d1,%fp0
   7962 	bra		t_inx2
   7963 
   7964 	global		stanhd
   7965 #--TANH(X) = X FOR DENORMALIZED X
   7966 stanhd:
   7967 	bra		t_extdnrm
   7968 
   7969 #########################################################################
   7970 # slogn():    computes the natural logarithm of a normalized input	#
   7971 # slognd():   computes the natural logarithm of a denormalized input	#
   7972 # slognp1():  computes the log(1+X) of a normalized input		#
   7973 # slognp1d(): computes the log(1+X) of a denormalized input		#
   7974 #									#
   7975 # INPUT ***************************************************************	#
   7976 #	a0 = pointer to extended precision input			#
   7977 #	d0 = round precision,mode					#
   7978 #									#
   7979 # OUTPUT **************************************************************	#
   7980 #	fp0 = log(X) or log(1+X)					#
   7981 #									#
   7982 # ACCURACY and MONOTONICITY *******************************************	#
   7983 #	The returned result is within 2 ulps in 64 significant bit, 	#
   7984 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   7985 #	rounded to double precision. The result is provably monotonic	#
   7986 #	in double precision.						#
   7987 #									#
   7988 # ALGORITHM ***********************************************************	#
   7989 #	LOGN:								#
   7990 #	Step 1. If |X-1| < 1/16, approximate log(X) by an odd 		#
   7991 #		polynomial in u, where u = 2(X-1)/(X+1). Otherwise, 	#
   7992 #		move on to Step 2.					#
   7993 #									#
   7994 #	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
   7995 #		seven significant bits of Y plus 2**(-7), i.e. 		#
   7996 #		F = 1.xxxxxx1 in base 2 where the six "x" match those 	#
   7997 #		of Y. Note that |Y-F| <= 2**(-7).			#
   7998 #									#
   7999 #	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a 		#
   8000 #		polynomial in u, log(1+u) = poly.			#
   8001 #									#
   8002 #	Step 4. Reconstruct 						#
   8003 #		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
   8004 #		by k*log(2) + (log(F) + poly). The values of log(F) are	#
   8005 #		calculated beforehand and stored in the program.	#
   8006 #									#
   8007 #	lognp1:								#
   8008 #	Step 1: If |X| < 1/16, approximate log(1+X) by an odd 		#
   8009 #		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
   8010 #		to Step 2.						#
   8011 #									#
   8012 #	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
   8013 #		in Step 2 of the algorithm for LOGN and compute 	#
   8014 #		log(1+X) as k*log(2) + log(F) + poly where poly 	#
   8015 #		approximates log(1+u), u = (Y-F)/F. 			#
   8016 #									#
   8017 #	Implementation Notes:						#
   8018 #	Note 1. There are 64 different possible values for F, thus 64 	#
   8019 #		log(F)'s need to be tabulated. Moreover, the values of	#
   8020 #		1/F are also tabulated so that the division in (Y-F)/F	#
   8021 #		can be performed by a multiplication.			#
   8022 #									#
   8023 #	Note 2. In Step 2 of lognp1, in order to preserved accuracy, 	#
   8024 #		the value Y-F has to be calculated carefully when 	#
   8025 #		1/2 <= X < 3/2. 					#
   8026 #									#
   8027 #	Note 3. To fully exploit the pipeline, polynomials are usually 	#
   8028 #		separated into two parts evaluated independently before	#
   8029 #		being added up.						#
   8030 #									#
   8031 #########################################################################
   8032 LOGOF2:
   8033 	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
   8034 
   8035 one:
   8036 	long		0x3F800000
   8037 zero:
   8038 	long		0x00000000
   8039 infty:
   8040 	long		0x7F800000
   8041 negone:
   8042 	long		0xBF800000
   8043 
   8044 LOGA6:
   8045 	long		0x3FC2499A,0xB5E4040B
   8046 LOGA5:
   8047 	long		0xBFC555B5,0x848CB7DB
   8048 
   8049 LOGA4:
   8050 	long		0x3FC99999,0x987D8730
   8051 LOGA3:
   8052 	long		0xBFCFFFFF,0xFF6F7E97
   8053 
   8054 LOGA2:
   8055 	long		0x3FD55555,0x555555A4
   8056 LOGA1:
   8057 	long		0xBFE00000,0x00000008
   8058 
   8059 LOGB5:
   8060 	long		0x3F175496,0xADD7DAD6
   8061 LOGB4:
   8062 	long		0x3F3C71C2,0xFE80C7E0
   8063 
   8064 LOGB3:
   8065 	long		0x3F624924,0x928BCCFF
   8066 LOGB2:
   8067 	long		0x3F899999,0x999995EC
   8068 
   8069 LOGB1:
   8070 	long		0x3FB55555,0x55555555
   8071 TWO:
   8072 	long		0x40000000,0x00000000
   8073 
   8074 LTHOLD:
   8075 	long		0x3f990000,0x80000000,0x00000000,0x00000000
   8076 
   8077 LOGTBL:
   8078 	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
   8079 	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
   8080 	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
   8081 	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
   8082 	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
   8083 	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
   8084 	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
   8085 	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
   8086 	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
   8087 	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
   8088 	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
   8089 	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
   8090 	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
   8091 	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
   8092 	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
   8093 	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
   8094 	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
   8095 	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
   8096 	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
   8097 	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
   8098 	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
   8099 	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
   8100 	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
   8101 	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
   8102 	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
   8103 	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
   8104 	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
   8105 	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
   8106 	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
   8107 	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
   8108 	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
   8109 	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
   8110 	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
   8111 	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
   8112 	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
   8113 	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
   8114 	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
   8115 	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
   8116 	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
   8117 	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
   8118 	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
   8119 	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
   8120 	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
   8121 	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
   8122 	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
   8123 	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
   8124 	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
   8125 	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
   8126 	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
   8127 	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
   8128 	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
   8129 	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
   8130 	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
   8131 	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
   8132 	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
   8133 	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
   8134 	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
   8135 	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
   8136 	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
   8137 	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
   8138 	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
   8139 	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
   8140 	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
   8141 	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
   8142 	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
   8143 	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
   8144 	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
   8145 	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
   8146 	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
   8147 	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
   8148 	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
   8149 	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
   8150 	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
   8151 	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
   8152 	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
   8153 	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
   8154 	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
   8155 	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
   8156 	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
   8157 	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
   8158 	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
   8159 	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
   8160 	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
   8161 	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
   8162 	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
   8163 	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
   8164 	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
   8165 	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
   8166 	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
   8167 	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
   8168 	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
   8169 	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
   8170 	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
   8171 	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
   8172 	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
   8173 	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
   8174 	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
   8175 	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
   8176 	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
   8177 	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
   8178 	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
   8179 	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
   8180 	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
   8181 	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
   8182 	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
   8183 	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
   8184 	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
   8185 	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
   8186 	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
   8187 	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
   8188 	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
   8189 	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
   8190 	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
   8191 	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
   8192 	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
   8193 	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
   8194 	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
   8195 	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
   8196 	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
   8197 	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
   8198 	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
   8199 	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
   8200 	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
   8201 	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
   8202 	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
   8203 	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
   8204 	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
   8205 	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
   8206 
   8207 	set		ADJK,L_SCR1
   8208 
   8209 	set		X,FP_SCR0
   8210 	set		XDCARE,X+2
   8211 	set		XFRAC,X+4
   8212 
   8213 	set		F,FP_SCR1
   8214 	set		FFRAC,F+4
   8215 
   8216 	set		KLOG2,FP_SCR0
   8217 
   8218 	set		SAVEU,FP_SCR0
   8219 
   8220 	global		slogn
   8221 #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
   8222 slogn:
   8223 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8224 	mov.l		&0x00000000,ADJK(%a6)
   8225 
   8226 LOGBGN:
   8227 #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
   8228 #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
   8229 
   8230 	mov.l		(%a0),%d1
   8231 	mov.w		4(%a0),%d1
   8232 
   8233 	mov.l		(%a0),X(%a6)
   8234 	mov.l		4(%a0),X+4(%a6)
   8235 	mov.l		8(%a0),X+8(%a6)
   8236 
   8237 	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
   8238 	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
   8239 # X IS POSITIVE, CHECK IF X IS NEAR 1
   8240 	cmp.l		%d1,&0x3ffef07d 	# IS X < 15/16?
   8241 	blt.b		LOGMAIN			# YES
   8242 	cmp.l		%d1,&0x3fff8841 	# IS X > 17/16?
   8243 	ble.w		LOGNEAR1		# NO
   8244 
   8245 LOGMAIN:
   8246 #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
   8247 
   8248 #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
   8249 #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
   8250 #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
   8251 #--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
   8252 #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
   8253 #--LOG(1+U) CAN BE VERY EFFICIENT.
   8254 #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
   8255 #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
   8256 
   8257 #--GET K, Y, F, AND ADDRESS OF 1/F.
   8258 	asr.l		&8,%d1
   8259 	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
   8260 	sub.l		&0x3FFF,%d1		# THIS IS K
   8261 	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
   8262 	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
   8263 	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
   8264 
   8265 #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
   8266 	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
   8267 	mov.l		XFRAC(%a6),FFRAC(%a6)
   8268 	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
   8269 	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
   8270 	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
   8271 	and.l		&0x7E000000,%d1
   8272 	asr.l		&8,%d1
   8273 	asr.l		&8,%d1
   8274 	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
   8275 	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
   8276 
   8277 	fmov.x		X(%a6),%fp0
   8278 	mov.l		&0x3fff0000,F(%a6)
   8279 	clr.l		F+8(%a6)
   8280 	fsub.x		F(%a6),%fp0		# Y-F
   8281 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
   8282 #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
   8283 #--REGISTERS SAVED: FPCR, FP1, FP2
   8284 
   8285 LP1CONT1:
   8286 #--AN RE-ENTRY POINT FOR LOGNP1
   8287 	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
   8288 	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
   8289 	fmov.x		%fp0,%fp2
   8290 	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
   8291 	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
   8292 
   8293 #--LOG(1+U) IS APPROXIMATED BY
   8294 #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
   8295 #--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
   8296 
   8297 	fmov.x		%fp2,%fp3
   8298 	fmov.x		%fp2,%fp1
   8299 
   8300 	fmul.d		LOGA6(%pc),%fp1		# V*A6
   8301 	fmul.d		LOGA5(%pc),%fp2		# V*A5
   8302 
   8303 	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
   8304 	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
   8305 
   8306 	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
   8307 	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
   8308 
   8309 	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
   8310 	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
   8311 
   8312 	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
   8313 	add.l		&16,%a0			# ADDRESS OF LOG(F)
   8314 	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
   8315 
   8316 	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
   8317 	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
   8318 
   8319 	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
   8320 	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
   8321 	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
   8322 
   8323 	fmov.l		%d0,%fpcr
   8324 	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
   8325 	bra		t_inx2
   8326 
   8327 
   8328 LOGNEAR1:
   8329 
   8330 # if the input is exactly equal to one, then exit through ld_pzero.
   8331 # if these 2 lines weren't here, the correct answer would be returned
   8332 # but the INEX2 bit would be set.
   8333 	fcmp.b		%fp0,&0x1		# is it equal to one?
   8334 	fbeq.l		ld_pzero		# yes
   8335 
   8336 #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
   8337 	fmov.x		%fp0,%fp1
   8338 	fsub.s		one(%pc),%fp1		# FP1 IS X-1
   8339 	fadd.s		one(%pc),%fp0		# FP0 IS X+1
   8340 	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
   8341 #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
   8342 #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
   8343 
   8344 LP1CONT2:
   8345 #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
   8346 	fdiv.x		%fp0,%fp1		# FP1 IS U
   8347 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
   8348 #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
   8349 #--LET V=U*U, W=V*V, CALCULATE
   8350 #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
   8351 #--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
   8352 	fmov.x		%fp1,%fp0
   8353 	fmul.x		%fp0,%fp0		# FP0 IS V
   8354 	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
   8355 	fmov.x		%fp0,%fp1
   8356 	fmul.x		%fp1,%fp1		# FP1 IS W
   8357 
   8358 	fmov.d		LOGB5(%pc),%fp3
   8359 	fmov.d		LOGB4(%pc),%fp2
   8360 
   8361 	fmul.x		%fp1,%fp3		# W*B5
   8362 	fmul.x		%fp1,%fp2		# W*B4
   8363 
   8364 	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
   8365 	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
   8366 
   8367 	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
   8368 
   8369 	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
   8370 
   8371 	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
   8372 	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
   8373 
   8374 	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
   8375 	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
   8376 
   8377 	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
   8378 
   8379 	fmov.l		%d0,%fpcr
   8380 	fadd.x		SAVEU(%a6),%fp0
   8381 	bra		t_inx2
   8382 
   8383 #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
   8384 LOGNEG:
   8385 	bra		t_operr
   8386 
   8387 	global		slognd
   8388 slognd:
   8389 #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
   8390 
   8391 	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
   8392 
   8393 #----normalize the input value by left shifting k bits (k to be determined
   8394 #----below), adjusting exponent and storing -k to  ADJK
   8395 #----the value TWOTO100 is no longer needed.
   8396 #----Note that this code assumes the denormalized input is NON-ZERO.
   8397 
   8398 	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
   8399 	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
   8400 	mov.l		4(%a0),%d4
   8401 	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
   8402 	clr.l		%d2			# D2 used for holding K
   8403 
   8404 	tst.l		%d4
   8405 	bne.b		Hi_not0
   8406 
   8407 Hi_0:
   8408 	mov.l		%d5,%d4
   8409 	clr.l		%d5
   8410 	mov.l		&32,%d2
   8411 	clr.l		%d6
   8412 	bfffo		%d4{&0:&32},%d6
   8413 	lsl.l		%d6,%d4
   8414 	add.l		%d6,%d2			# (D3,D4,D5) is normalized
   8415 
   8416 	mov.l		%d3,X(%a6)
   8417 	mov.l		%d4,XFRAC(%a6)
   8418 	mov.l		%d5,XFRAC+4(%a6)
   8419 	neg.l		%d2
   8420 	mov.l		%d2,ADJK(%a6)
   8421 	fmov.x		X(%a6),%fp0
   8422 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
   8423 	lea		X(%a6),%a0
   8424 	bra.w		LOGBGN			# begin regular log(X)
   8425 
   8426 Hi_not0:
   8427 	clr.l		%d6
   8428 	bfffo		%d4{&0:&32},%d6		# find first 1
   8429 	mov.l		%d6,%d2			# get k
   8430 	lsl.l		%d6,%d4
   8431 	mov.l		%d5,%d7			# a copy of D5
   8432 	lsl.l		%d6,%d5
   8433 	neg.l		%d6
   8434 	add.l		&32,%d6
   8435 	lsr.l		%d6,%d7
   8436 	or.l		%d7,%d4			# (D3,D4,D5) normalized
   8437 
   8438 	mov.l		%d3,X(%a6)
   8439 	mov.l		%d4,XFRAC(%a6)
   8440 	mov.l		%d5,XFRAC+4(%a6)
   8441 	neg.l		%d2
   8442 	mov.l		%d2,ADJK(%a6)
   8443 	fmov.x		X(%a6),%fp0
   8444 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
   8445 	lea		X(%a6),%a0
   8446 	bra.w		LOGBGN			# begin regular log(X)
   8447 
   8448 	global		slognp1
   8449 #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
   8450 slognp1:
   8451 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8452 	fabs.x		%fp0			# test magnitude
   8453 	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
   8454 	fbgt.w		LP1REAL			# if greater, continue
   8455 	fmov.l		%d0,%fpcr
   8456 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   8457 	fmov.x		(%a0),%fp0		# return signed argument
   8458 	bra		t_catch
   8459 
   8460 LP1REAL:
   8461 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8462 	mov.l		&0x00000000,ADJK(%a6)
   8463 	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
   8464 	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
   8465 	fmov.x		%fp0,X(%a6)
   8466 	mov.w		XFRAC(%a6),XDCARE(%a6)
   8467 	mov.l		X(%a6),%d1
   8468 	cmp.l		%d1,&0
   8469 	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
   8470 	cmp.l		%d1,&0x3ffe8000 	# IS BOUNDS [1/2,3/2]?
   8471 	blt.w		LOGMAIN
   8472 	cmp.l		%d1,&0x3fffc000
   8473 	bgt.w		LOGMAIN
   8474 #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
   8475 #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
   8476 #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
   8477 
   8478 LP1NEAR1:
   8479 #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
   8480 	cmp.l		%d1,&0x3ffef07d
   8481 	blt.w		LP1CARE
   8482 	cmp.l		%d1,&0x3fff8841
   8483 	bgt.w		LP1CARE
   8484 
   8485 LP1ONE16:
   8486 #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
   8487 #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
   8488 	fadd.x		%fp1,%fp1		# FP1 IS 2Z
   8489 	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
   8490 #--U = FP1/FP0
   8491 	bra.w		LP1CONT2
   8492 
   8493 LP1CARE:
   8494 #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
   8495 #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
   8496 #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
   8497 #--THERE ARE ONLY TWO CASES.
   8498 #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
   8499 #--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
   8500 #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
   8501 #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
   8502 
   8503 	mov.l		XFRAC(%a6),FFRAC(%a6)
   8504 	and.l		&0xFE000000,FFRAC(%a6)
   8505 	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
   8506 	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
   8507 	bge.b		KISZERO
   8508 
   8509 KISNEG1:
   8510 	fmov.s		TWO(%pc),%fp0
   8511 	mov.l		&0x3fff0000,F(%a6)
   8512 	clr.l		F+8(%a6)
   8513 	fsub.x		F(%a6),%fp0		# 2-F
   8514 	mov.l		FFRAC(%a6),%d1
   8515 	and.l		&0x7E000000,%d1
   8516 	asr.l		&8,%d1
   8517 	asr.l		&8,%d1
   8518 	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
   8519 	fadd.x		%fp1,%fp1		# GET 2Z
   8520 	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
   8521 	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
   8522 	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
   8523 	add.l		%d1,%a0
   8524 	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
   8525 	bra.w		LP1CONT1
   8526 
   8527 KISZERO:
   8528 	fmov.s		one(%pc),%fp0
   8529 	mov.l		&0x3fff0000,F(%a6)
   8530 	clr.l		F+8(%a6)
   8531 	fsub.x		F(%a6),%fp0		# 1-F
   8532 	mov.l		FFRAC(%a6),%d1
   8533 	and.l		&0x7E000000,%d1
   8534 	asr.l		&8,%d1
   8535 	asr.l		&8,%d1
   8536 	asr.l		&4,%d1
   8537 	fadd.x		%fp1,%fp0		# FP0 IS Y-F
   8538 	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
   8539 	lea		LOGTBL(%pc),%a0
   8540 	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
   8541 	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
   8542 	bra.w		LP1CONT1
   8543 
   8544 LP1NEG0:
   8545 #--FPCR SAVED. D0 IS X IN COMPACT FORM.
   8546 	cmp.l		%d1,&0
   8547 	blt.b		LP1NEG
   8548 LP1ZERO:
   8549 	fmov.s		negone(%pc),%fp0
   8550 
   8551 	fmov.l		%d0,%fpcr
   8552 	bra		t_dz
   8553 
   8554 LP1NEG:
   8555 	fmov.s		zero(%pc),%fp0
   8556 
   8557 	fmov.l		%d0,%fpcr
   8558 	bra		t_operr
   8559 
   8560 	global		slognp1d
   8561 #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
   8562 # Simply return the denorm
   8563 slognp1d:
   8564 	bra		t_extdnrm
   8565 
   8566 #########################################################################
   8567 # satanh():  computes the inverse hyperbolic tangent of a norm input	#
   8568 # satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
   8569 #									#
   8570 # INPUT ***************************************************************	#
   8571 #	a0 = pointer to extended precision input			#
   8572 #	d0 = round precision,mode					#
   8573 #									#
   8574 # OUTPUT **************************************************************	#
   8575 #	fp0 = arctanh(X)						#
   8576 #									#
   8577 # ACCURACY and MONOTONICITY *******************************************	#
   8578 #	The returned result is within 3 ulps in	64 significant bit,	#
   8579 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8580 #	rounded to double precision. The result is provably monotonic	#
   8581 #	in double precision.						#
   8582 #									#
   8583 # ALGORITHM ***********************************************************	#
   8584 #									#
   8585 #	ATANH								#
   8586 #	1. If |X| >= 1, go to 3.					#
   8587 #									#
   8588 #	2. (|X| < 1) Calculate atanh(X) by				#
   8589 #		sgn := sign(X)						#
   8590 #		y := |X|						#
   8591 #		z := 2y/(1-y)						#
   8592 #		atanh(X) := sgn * (1/2) * logp1(z)			#
   8593 #		Exit.							#
   8594 #									#
   8595 #	3. If |X| > 1, go to 5.						#
   8596 #									#
   8597 #	4. (|X| = 1) Generate infinity with an appropriate sign and	#
   8598 #		divide-by-zero by					#
   8599 #		sgn := sign(X)						#
   8600 #		atan(X) := sgn / (+0).					#
   8601 #		Exit.							#
   8602 #									#
   8603 #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   8604 #		Exit.							#
   8605 #									#
   8606 #########################################################################
   8607 
   8608 	global		satanh
   8609 satanh:
   8610 	mov.l		(%a0),%d1
   8611 	mov.w		4(%a0),%d1
   8612 	and.l		&0x7FFFFFFF,%d1
   8613 	cmp.l		%d1,&0x3FFF8000
   8614 	bge.b		ATANHBIG
   8615 
   8616 #--THIS IS THE USUAL CASE, |X| < 1
   8617 #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
   8618 
   8619 	fabs.x		(%a0),%fp0		# Y = |X|
   8620 	fmov.x		%fp0,%fp1
   8621 	fneg.x		%fp1			# -Y
   8622 	fadd.x		%fp0,%fp0		# 2Y
   8623 	fadd.s		&0x3F800000,%fp1	# 1-Y
   8624 	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
   8625 	mov.l		(%a0),%d1
   8626 	and.l		&0x80000000,%d1
   8627 	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
   8628 	mov.l		%d1,-(%sp)
   8629 
   8630 	mov.l		%d0,-(%sp)		# save rnd prec,mode
   8631 	clr.l		%d0			# pass ext prec,RN
   8632 	fmovm.x		&0x01,-(%sp)		# save Z on stack
   8633 	lea		(%sp),%a0		# pass ptr to Z
   8634 	bsr		slognp1			# LOG1P(Z)
   8635 	add.l		&0xc,%sp		# clear Z from stack
   8636 
   8637 	mov.l		(%sp)+,%d0		# fetch old prec,mode
   8638 	fmov.l		%d0,%fpcr		# load it
   8639 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   8640 	fmul.s		(%sp)+,%fp0
   8641 	bra		t_catch
   8642 
   8643 ATANHBIG:
   8644 	fabs.x		(%a0),%fp0		# |X|
   8645 	fcmp.s		%fp0,&0x3F800000
   8646 	fbgt		t_operr
   8647 	bra		t_dz
   8648 
   8649 	global		satanhd
   8650 #--ATANH(X) = X FOR DENORMALIZED X
   8651 satanhd:
   8652 	bra		t_extdnrm
   8653 
   8654 #########################################################################
   8655 # slog10():  computes the base-10 logarithm of a normalized input	#
   8656 # slog10d(): computes the base-10 logarithm of a denormalized input	#
   8657 # slog2():   computes the base-2 logarithm of a normalized input	#
   8658 # slog2d():  computes the base-2 logarithm of a denormalized input	#
   8659 #									#
   8660 # INPUT *************************************************************** #
   8661 #	a0 = pointer to extended precision input			#
   8662 #	d0 = round precision,mode					#
   8663 #									#
   8664 # OUTPUT **************************************************************	#
   8665 #	fp0 = log_10(X) or log_2(X)					#
   8666 #									#
   8667 # ACCURACY and MONOTONICITY *******************************************	#
   8668 #	The returned result is within 1.7 ulps in 64 significant bit,	#
   8669 #	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
   8670 #	rounded to double precision. The result is provably monotonic	#
   8671 #	in double precision.						#
   8672 #									#
   8673 # ALGORITHM ***********************************************************	#
   8674 #									#
   8675 #       slog10d:							#
   8676 #									#
   8677 #       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
   8678 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8679 #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8680 #               traps, and precision control = double extended.		#
   8681 #									#
   8682 #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
   8683 #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
   8684 #									#
   8685 #       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
   8686 #            2.1 Restore the user FPCR					#
   8687 #            2.2 Return ans := Y * INV_L10.				#
   8688 #									#
   8689 #       slog10: 							#
   8690 #									#
   8691 #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8692 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8693 #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8694 #               traps, and precision control = double extended.		#
   8695 #									#
   8696 #       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
   8697 #									#
   8698 #       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
   8699 #            2.1  Restore the user FPCR					#
   8700 #            2.2  Return ans := Y * INV_L10.				#
   8701 #									#
   8702 #       sLog2d:								#
   8703 #									#
   8704 #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8705 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8706 #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8707 #               traps, and precision control = double extended.		#
   8708 #									#
   8709 #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
   8710 #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
   8711 #									#
   8712 #       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
   8713 #            2.1  Restore the user FPCR					#
   8714 #            2.2  Return ans := Y * INV_L2.				#
   8715 #									#
   8716 #       sLog2:								#
   8717 #									#
   8718 #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8719 #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8720 #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8721 #               traps, and precision control = double extended.		#
   8722 #									#
   8723 #       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
   8724 #               go to Step 3.						#
   8725 #									#
   8726 #       Step 2.   Return k.						#
   8727 #            2.1  Get integer k, X = 2^k.				#
   8728 #            2.2  Restore the user FPCR.				#
   8729 #            2.3  Return ans := convert-to-double-extended(k).		#
   8730 #									#
   8731 #       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
   8732 #									#
   8733 #       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
   8734 #            4.1  Restore the user FPCR					#
   8735 #            4.2  Return ans := Y * INV_L2.				#
   8736 #									#
   8737 #########################################################################
   8738 
   8739 INV_L10:
   8740 	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
   8741 
   8742 INV_L2:
   8743 	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
   8744 
   8745 	global		slog10
   8746 #--entry point for Log10(X), X is normalized
   8747 slog10:
   8748 	fmov.b		&0x1,%fp0
   8749 	fcmp.x		%fp0,(%a0)		# if operand == 1,
   8750 	fbeq.l		ld_pzero		# return an EXACT zero
   8751 
   8752 	mov.l		(%a0),%d1
   8753 	blt.w		invalid
   8754 	mov.l		%d0,-(%sp)
   8755 	clr.l		%d0
   8756 	bsr		slogn			# log(X), X normal.
   8757 	fmov.l		(%sp)+,%fpcr
   8758 	fmul.x		INV_L10(%pc),%fp0
   8759 	bra		t_inx2
   8760 
   8761 	global		slog10d
   8762 #--entry point for Log10(X), X is denormalized
   8763 slog10d:
   8764 	mov.l		(%a0),%d1
   8765 	blt.w		invalid
   8766 	mov.l		%d0,-(%sp)
   8767 	clr.l		%d0
   8768 	bsr		slognd			# log(X), X denorm.
   8769 	fmov.l		(%sp)+,%fpcr
   8770 	fmul.x		INV_L10(%pc),%fp0
   8771 	bra		t_minx2
   8772 
   8773 	global		slog2
   8774 #--entry point for Log2(X), X is normalized
   8775 slog2:
   8776 	mov.l		(%a0),%d1
   8777 	blt.w		invalid
   8778 
   8779 	mov.l		8(%a0),%d1
   8780 	bne.b		continue		# X is not 2^k
   8781 
   8782 	mov.l		4(%a0),%d1
   8783 	and.l		&0x7FFFFFFF,%d1
   8784 	bne.b		continue
   8785 
   8786 #--X = 2^k.
   8787 	mov.w		(%a0),%d1
   8788 	and.l		&0x00007FFF,%d1
   8789 	sub.l		&0x3FFF,%d1
   8790 	beq.l		ld_pzero
   8791 	fmov.l		%d0,%fpcr
   8792 	fmov.l		%d1,%fp0
   8793 	bra		t_inx2
   8794 
   8795 continue:
   8796 	mov.l		%d0,-(%sp)
   8797 	clr.l		%d0
   8798 	bsr		slogn			# log(X), X normal.
   8799 	fmov.l		(%sp)+,%fpcr
   8800 	fmul.x		INV_L2(%pc),%fp0
   8801 	bra		t_inx2
   8802 
   8803 invalid:
   8804 	bra		t_operr
   8805 
   8806 	global		slog2d
   8807 #--entry point for Log2(X), X is denormalized
   8808 slog2d:
   8809 	mov.l		(%a0),%d1
   8810 	blt.w		invalid
   8811 	mov.l		%d0,-(%sp)
   8812 	clr.l		%d0
   8813 	bsr		slognd			# log(X), X denorm.
   8814 	fmov.l		(%sp)+,%fpcr
   8815 	fmul.x		INV_L2(%pc),%fp0
   8816 	bra		t_minx2
   8817 
   8818 #########################################################################
   8819 # stwotox():  computes 2**X for a normalized input			#
   8820 # stwotoxd(): computes 2**X for a denormalized input			#
   8821 # stentox():  computes 10**X for a normalized input			#
   8822 # stentoxd(): computes 10**X for a denormalized input			#
   8823 #									#
   8824 # INPUT ***************************************************************	#
   8825 #	a0 = pointer to extended precision input			#
   8826 #	d0 = round precision,mode					#
   8827 #									#
   8828 # OUTPUT **************************************************************	#
   8829 #	fp0 = 2**X or 10**X						#
   8830 #									#
   8831 # ACCURACY and MONOTONICITY *******************************************	#
   8832 #	The returned result is within 2 ulps in 64 significant bit, 	#
   8833 #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8834 #	rounded to double precision. The result is provably monotonic	#
   8835 #	in double precision.						#
   8836 #									#
   8837 # ALGORITHM ***********************************************************	#
   8838 #									#
   8839 #	twotox								#
   8840 #	1. If |X| > 16480, go to ExpBig.				#
   8841 #									#
   8842 #	2. If |X| < 2**(-70), go to ExpSm.				#
   8843 #									#
   8844 #	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
   8845 #		decompose N as						#
   8846 #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
   8847 #									#
   8848 #	4. Overwrite r := r * log2. Then				#
   8849 #		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
   8850 #		Go to expr to compute that expression.			#
   8851 #									#
   8852 #	tentox								#
   8853 #	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
   8854 #									#
   8855 #	2. If |X| < 2**(-70), go to ExpSm.				#
   8856 #									#
   8857 #	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
   8858 #		N := round-to-int(y). Decompose N as			#
   8859 #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
   8860 #									#
   8861 #	4. Define r as							#
   8862 #		r := ((X - N*L1)-N*L2) * L10				#
   8863 #		where L1, L2 are the leading and trailing parts of 	#
   8864 #		log_10(2)/64 and L10 is the natural log of 10. Then	#
   8865 #		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
   8866 #		Go to expr to compute that expression.			#
   8867 #									#
   8868 #	expr								#
   8869 #	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
   8870 #									#
   8871 #	2. Overwrite Fact1 and Fact2 by					#
   8872 #		Fact1 := 2**(M) * Fact1					#
   8873 #		Fact2 := 2**(M) * Fact2					#
   8874 #		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
   8875 #									#
   8876 #	3. Calculate P where 1 + P approximates exp(r):			#
   8877 #		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
   8878 #									#
   8879 #	4. Let AdjFact := 2**(M'). Return				#
   8880 #		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
   8881 #		Exit.							#
   8882 #									#
   8883 #	ExpBig								#
   8884 #	1. Generate overflow by Huge * Huge if X > 0; otherwise, 	#
   8885 #	        generate underflow by Tiny * Tiny.			#
   8886 #									#
   8887 #	ExpSm								#
   8888 #	1. Return 1 + X.						#
   8889 #									#
   8890 #########################################################################
   8891 
   8892 L2TEN64:
   8893 	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
   8894 L10TWO1:
   8895 	long		0x3F734413,0x509F8000	# LOG2/64LOG10
   8896 
   8897 L10TWO2:
   8898 	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
   8899 
   8900 LOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
   8901 
   8902 LOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
   8903 
   8904 EXPA5:	long		0x3F56C16D,0x6F7BD0B2
   8905 EXPA4:	long		0x3F811112,0x302C712C
   8906 EXPA3:	long		0x3FA55555,0x55554CC1
   8907 EXPA2:	long		0x3FC55555,0x55554A54
   8908 EXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
   8909 
   8910 TEXPTBL:
   8911 	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
   8912 	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
   8913 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
   8914 	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
   8915 	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
   8916 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
   8917 	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
   8918 	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
   8919 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
   8920 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
   8921 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
   8922 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
   8923 	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
   8924 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
   8925 	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
   8926 	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
   8927 	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
   8928 	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
   8929 	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
   8930 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
   8931 	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
   8932 	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
   8933 	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
   8934 	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
   8935 	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
   8936 	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
   8937 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
   8938 	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
   8939 	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
   8940 	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
   8941 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
   8942 	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
   8943 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
   8944 	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
   8945 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
   8946 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
   8947 	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
   8948 	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
   8949 	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
   8950 	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
   8951 	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
   8952 	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
   8953 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
   8954 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
   8955 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
   8956 	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
   8957 	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
   8958 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
   8959 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
   8960 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
   8961 	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
   8962 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
   8963 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
   8964 	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
   8965 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
   8966 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
   8967 	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
   8968 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
   8969 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
   8970 	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
   8971 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
   8972 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
   8973 	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
   8974 	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
   8975 
   8976 	set		INT,L_SCR1
   8977 
   8978 	set		X,FP_SCR0
   8979 	set		XDCARE,X+2
   8980 	set		XFRAC,X+4
   8981 
   8982 	set		ADJFACT,FP_SCR0
   8983 
   8984 	set		FACT1,FP_SCR0
   8985 	set		FACT1HI,FACT1+4
   8986 	set		FACT1LOW,FACT1+8
   8987 
   8988 	set		FACT2,FP_SCR1
   8989 	set		FACT2HI,FACT2+4
   8990 	set		FACT2LOW,FACT2+8
   8991 
   8992 	global		stwotox
   8993 #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   8994 stwotox:
   8995 	fmovm.x		(%a0),&0x80		# LOAD INPUT
   8996 
   8997 	mov.l		(%a0),%d1
   8998 	mov.w		4(%a0),%d1
   8999 	fmov.x		%fp0,X(%a6)
   9000 	and.l		&0x7FFFFFFF,%d1
   9001 
   9002 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
   9003 	bge.b		TWOOK1
   9004 	bra.w		EXPBORS
   9005 
   9006 TWOOK1:
   9007 	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
   9008 	ble.b		TWOMAIN
   9009 	bra.w		EXPBORS
   9010 
   9011 TWOMAIN:
   9012 #--USUAL CASE, 2^(-70) <= |X| <= 16480
   9013 
   9014 	fmov.x		%fp0,%fp1
   9015 	fmul.s		&0x42800000,%fp1	# 64 * X
   9016 	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
   9017 	mov.l		%d2,-(%sp)
   9018 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
   9019 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
   9020 	mov.l		INT(%a6),%d1
   9021 	mov.l		%d1,%d2
   9022 	and.l		&0x3F,%d1		# D0 IS J
   9023 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
   9024 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
   9025 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
   9026 	mov.l		%d2,%d1
   9027 	asr.l		&1,%d1			# D0 IS M
   9028 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
   9029 	add.l		&0x3FFF,%d2
   9030 
   9031 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
   9032 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
   9033 #--ADJFACT = 2^(M').
   9034 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
   9035 
   9036 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   9037 
   9038 	fmul.s		&0x3C800000,%fp1	# (1/64)*N
   9039 	mov.l		(%a1)+,FACT1(%a6)
   9040 	mov.l		(%a1)+,FACT1HI(%a6)
   9041 	mov.l		(%a1)+,FACT1LOW(%a6)
   9042 	mov.w		(%a1)+,FACT2(%a6)
   9043 
   9044 	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
   9045 
   9046 	mov.w		(%a1)+,FACT2HI(%a6)
   9047 	clr.w		FACT2HI+2(%a6)
   9048 	clr.l		FACT2LOW(%a6)
   9049 	add.w		%d1,FACT1(%a6)
   9050 	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
   9051 	add.w		%d1,FACT2(%a6)
   9052 
   9053 	bra.w		expr
   9054 
   9055 EXPBORS:
   9056 #--FPCR, D0 SAVED
   9057 	cmp.l		%d1,&0x3FFF8000
   9058 	bgt.b		TEXPBIG
   9059 
   9060 #--|X| IS SMALL, RETURN 1 + X
   9061 
   9062 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   9063 	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
   9064 	bra		t_pinx2
   9065 
   9066 TEXPBIG:
   9067 #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
   9068 #--REGISTERS SAVE SO FAR ARE FPCR AND  D0
   9069 	mov.l		X(%a6),%d1
   9070 	cmp.l		%d1,&0
   9071 	blt.b		EXPNEG
   9072 
   9073 	bra		t_ovfl2			# t_ovfl expects positive value
   9074 
   9075 EXPNEG:
   9076 	bra		t_unfl2			# t_unfl expects positive value
   9077 
   9078 	global		stwotoxd
   9079 stwotoxd:
   9080 #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
   9081 
   9082 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
   9083 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
   9084 	mov.l		(%a0),%d1
   9085 	or.l		&0x00800001,%d1
   9086 	fadd.s		%d1,%fp0
   9087 	bra		t_pinx2
   9088 
   9089 	global		stentox
   9090 #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   9091 stentox:
   9092 	fmovm.x		(%a0),&0x80		# LOAD INPUT
   9093 
   9094 	mov.l		(%a0),%d1
   9095 	mov.w		4(%a0),%d1
   9096 	fmov.x		%fp0,X(%a6)
   9097 	and.l		&0x7FFFFFFF,%d1
   9098 
   9099 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
   9100 	bge.b		TENOK1
   9101 	bra.w		EXPBORS
   9102 
   9103 TENOK1:
   9104 	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
   9105 	ble.b		TENMAIN
   9106 	bra.w		EXPBORS
   9107 
   9108 TENMAIN:
   9109 #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
   9110 
   9111 	fmov.x		%fp0,%fp1
   9112 	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
   9113 	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
   9114 	mov.l		%d2,-(%sp)
   9115 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
   9116 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
   9117 	mov.l		INT(%a6),%d1
   9118 	mov.l		%d1,%d2
   9119 	and.l		&0x3F,%d1		# D0 IS J
   9120 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
   9121 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
   9122 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
   9123 	mov.l		%d2,%d1
   9124 	asr.l		&1,%d1			# D0 IS M
   9125 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
   9126 	add.l		&0x3FFF,%d2
   9127 
   9128 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
   9129 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
   9130 #--ADJFACT = 2^(M').
   9131 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
   9132 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   9133 
   9134 	fmov.x		%fp1,%fp2
   9135 
   9136 	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
   9137 	mov.l		(%a1)+,FACT1(%a6)
   9138 
   9139 	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
   9140 
   9141 	mov.l		(%a1)+,FACT1HI(%a6)
   9142 	mov.l		(%a1)+,FACT1LOW(%a6)
   9143 	fsub.x		%fp1,%fp0		# X - N L_LEAD
   9144 	mov.w		(%a1)+,FACT2(%a6)
   9145 
   9146 	fsub.x		%fp2,%fp0		# X - N L_TRAIL
   9147 
   9148 	mov.w		(%a1)+,FACT2HI(%a6)
   9149 	clr.w		FACT2HI+2(%a6)
   9150 	clr.l		FACT2LOW(%a6)
   9151 
   9152 	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
   9153 	add.w		%d1,FACT1(%a6)
   9154 	add.w		%d1,FACT2(%a6)
   9155 
   9156 expr:
   9157 #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
   9158 #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
   9159 #--FP0 IS R. THE FOLLOWING CODE COMPUTES
   9160 #--	2**(M'+M) * 2**(J/64) * EXP(R)
   9161 
   9162 	fmov.x		%fp0,%fp1
   9163 	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
   9164 
   9165 	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
   9166 	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
   9167 
   9168 	fmul.x		%fp1,%fp2		# FP2 IS S*A5
   9169 	fmul.x		%fp1,%fp3		# FP3 IS S*A4
   9170 
   9171 	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
   9172 	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
   9173 
   9174 	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
   9175 	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
   9176 
   9177 	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
   9178 	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
   9179 
   9180 	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
   9181 	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
   9182 	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
   9183 
   9184 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   9185 
   9186 #--FINAL RECONSTRUCTION PROCESS
   9187 #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
   9188 
   9189 	fmul.x		FACT1(%a6),%fp0
   9190 	fadd.x		FACT2(%a6),%fp0
   9191 	fadd.x		FACT1(%a6),%fp0
   9192 
   9193 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   9194 	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
   9195 	mov.l		(%sp)+,%d2
   9196 	mov.l		&0x80000000,ADJFACT+4(%a6)
   9197 	clr.l		ADJFACT+8(%a6)
   9198 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9199 	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
   9200 	bra		t_catch
   9201 
   9202 	global		stentoxd
   9203 stentoxd:
   9204 #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
   9205 
   9206 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
   9207 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
   9208 	mov.l		(%a0),%d1
   9209 	or.l		&0x00800001,%d1
   9210 	fadd.s		%d1,%fp0
   9211 	bra		t_pinx2
   9212 
   9213 #########################################################################
   9214 # sscale(): computes the destination operand scaled by the source	#
   9215 #	    operand. If the absoulute value of the source operand is 	#
   9216 #	    >= 2^14, an overflow or underflow is returned.		#
   9217 #									#
   9218 # INPUT *************************************************************** #
   9219 #	a0  = pointer to double-extended source operand X		#
   9220 #	a1  = pointer to double-extended destination operand Y		#
   9221 #									#
   9222 # OUTPUT ************************************************************** #
   9223 #	fp0 =  scale(X,Y)						#
   9224 #									#
   9225 #########################################################################
   9226 
   9227 set	SIGN,		L_SCR1
   9228 
   9229 	global		sscale
   9230 sscale:
   9231 	mov.l		%d0,-(%sp)		# store off ctrl bits for now
   9232 
   9233 	mov.w		DST_EX(%a1),%d1		# get dst exponent
   9234 	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
   9235 	andi.l		&0x00007fff,%d1		# strip sign from dst exp
   9236 
   9237 	mov.w		SRC_EX(%a0),%d0		# check src bounds
   9238 	andi.w		&0x7fff,%d0		# clr src sign bit
   9239 	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
   9240 	blt.w		src_small		# yes
   9241 	cmpi.w		%d0,&0x400c		# no; is src too big?
   9242 	bgt.w		src_out			# yes
   9243 
   9244 #
   9245 # Source is within 2^14 range.
   9246 #
   9247 src_ok:
   9248 	fintrz.x	SRC(%a0),%fp0		# calc int of src
   9249 	fmov.l		%fp0,%d0		# int src to d0
   9250 # don't want any accrued bits from the fintrz showing up later since
   9251 # we may need to read the fpsr for the last fp op in t_catch2().
   9252 	fmov.l		&0x0,%fpsr
   9253 
   9254 	tst.b		DST_HI(%a1)		# is dst denormalized?
   9255 	bmi.b		sok_norm
   9256 
   9257 # the dst is a DENORM. normalize the DENORM and add the adjustment to
   9258 # the src value. then, jump to the norm part of the routine.
   9259 sok_dnrm:
   9260 	mov.l		%d0,-(%sp)		# save src for now
   9261 
   9262 	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
   9263 	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
   9264 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
   9265 
   9266 	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
   9267 	bsr.l		norm			# normalize the DENORM
   9268 	neg.l		%d0
   9269 	add.l		(%sp)+,%d0		# add adjustment to src
   9270 
   9271 	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
   9272 
   9273 	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
   9274 	bge.b		sok_norm2		# thank goodness no
   9275 
   9276 # the multiply factor that we're trying to create should be a denorm
   9277 # for the multiply to work. therefore, we're going to actually do a
   9278 # multiply with a denorm which will cause an unimplemented data type
   9279 # exception to be put into the machine which will be caught and corrected
   9280 # later. we don't do this with the DENORMs above because this method
   9281 # is slower. but, don't fret, I don't see it being used much either.
   9282 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
   9283 	mov.l		&0x80000000,%d1		# load normalized mantissa
   9284 	subi.l		&-0x3fff,%d0		# how many should we shift?
   9285 	neg.l		%d0			# make it positive
   9286 	cmpi.b		%d0,&0x20		# is it > 32?
   9287 	bge.b		sok_dnrm_32		# yes
   9288 	lsr.l		%d0,%d1			# no; bit stays in upper lw
   9289 	clr.l		-(%sp)			# insert zero low mantissa
   9290 	mov.l		%d1,-(%sp)		# insert new high mantissa
   9291 	clr.l		-(%sp)			# make zero exponent
   9292 	bra.b		sok_norm_cont
   9293 sok_dnrm_32:
   9294 	subi.b		&0x20,%d0		# get shift count
   9295 	lsr.l		%d0,%d1			# make low mantissa longword
   9296 	mov.l		%d1,-(%sp)		# insert new low mantissa
   9297 	clr.l		-(%sp)			# insert zero high mantissa
   9298 	clr.l		-(%sp)			# make zero exponent
   9299 	bra.b		sok_norm_cont
   9300 
   9301 # the src will force the dst to a DENORM value or worse. so, let's
   9302 # create an fp multiply that will create the result.
   9303 sok_norm:
   9304 	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
   9305 sok_norm2:
   9306 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
   9307 
   9308 	addi.w		&0x3fff,%d0		# turn src amt into exp value
   9309 	swap		%d0			# put exponent in high word
   9310 	clr.l		-(%sp)			# insert new exponent
   9311 	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
   9312 	mov.l		%d0,-(%sp)		# insert new lo mantissa
   9313 
   9314 sok_norm_cont:
   9315 	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
   9316 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9317 	fmul.x		(%sp)+,%fp0		# do the multiply
   9318 	bra		t_catch2		# catch any exceptions
   9319 
   9320 #
   9321 # Source is outside of 2^14 range.  Test the sign and branch
   9322 # to the appropriate exception handler.
   9323 #
   9324 src_out:
   9325 	mov.l		(%sp)+,%d0		# restore ctrl bits
   9326 	exg		%a0,%a1			# swap src,dst ptrs
   9327 	tst.b		SRC_EX(%a1)		# is src negative?
   9328 	bmi		t_unfl			# yes; underflow
   9329 	bra		t_ovfl_sc		# no; overflow
   9330 
   9331 #
   9332 # The source input is below 1, so we check for denormalized numbers
   9333 # and set unfl.
   9334 #
   9335 src_small:
   9336 	tst.b		DST_HI(%a1)		# is dst denormalized?
   9337 	bpl.b		ssmall_done		# yes
   9338 
   9339 	mov.l		(%sp)+,%d0
   9340 	fmov.l		%d0,%fpcr		# no; load control bits
   9341 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   9342 	fmov.x		DST(%a1),%fp0		# simply return dest
   9343 	bra		t_catch2
   9344 ssmall_done:
   9345 	mov.l		(%sp)+,%d0		# load control bits into d1
   9346 	mov.l		%a1,%a0			# pass ptr to dst
   9347 	bra		t_resdnrm
   9348 
   9349 #########################################################################
   9350 # smod(): computes the fp MOD of the input values X,Y.			#
   9351 # srem(): computes the fp (IEEE) REM of the input values X,Y.		#
   9352 #									#
   9353 # INPUT *************************************************************** #
   9354 #	a0 = pointer to extended precision input X			#
   9355 #	a1 = pointer to extended precision input Y			#
   9356 #	d0 = round precision,mode					#
   9357 #									#
   9358 # 	The input operands X and Y can be either normalized or 		#
   9359 #	denormalized.							#
   9360 #									#
   9361 # OUTPUT ************************************************************** #
   9362 #      fp0 = FREM(X,Y) or FMOD(X,Y)					#
   9363 #									#
   9364 # ALGORITHM *********************************************************** #
   9365 #									#
   9366 #       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
   9367 #                signY := sign(Y), X := |X|, Y := |Y|, 			#
   9368 #                signQ := signX EOR signY. Record whether MOD or REM	#
   9369 #                is requested.						#
   9370 #									#
   9371 #       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
   9372 #                If (L < 0) then					#
   9373 #                   R := X, go to Step 4.				#
   9374 #                else							#
   9375 #                   R := 2^(-L)X, j := L.				#
   9376 #                endif							#
   9377 #									#
   9378 #       Step 3.  Perform MOD(X,Y)					#
   9379 #            3.1 If R = Y, go to Step 9.				#
   9380 #            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
   9381 #            3.3 If j = 0, go to Step 4.				#
   9382 #            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
   9383 #                Step 3.1.						#
   9384 #									#
   9385 #       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
   9386 #                Last_Subtract := false (used in Step 7 below). If	#
   9387 #                MOD is requested, go to Step 6. 			#
   9388 #									#
   9389 #       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
   9390 #            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
   9391 #                Step 6.						#
   9392 #            5.2 If R > Y/2, then { set Last_Subtract := true,		#
   9393 #                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
   9394 #            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
   9395 #                then { Q := Q + 1, signX := -signX }.			#
   9396 #									#
   9397 #       Step 6.  R := signX*R.						#
   9398 #									#
   9399 #       Step 7.  If Last_Subtract = true, R := R - Y.			#
   9400 #									#
   9401 #       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
   9402 #									#
   9403 #       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
   9404 #                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
   9405 #                R := 0. Return signQ, last 7 bits of Q, and R.		#
   9406 #									#
   9407 #########################################################################
   9408 
   9409 	set		Mod_Flag,L_SCR3
   9410 	set		Sc_Flag,L_SCR3+1
   9411 
   9412 	set		SignY,L_SCR2
   9413 	set		SignX,L_SCR2+2
   9414 	set		SignQ,L_SCR3+2
   9415 
   9416 	set		Y,FP_SCR0
   9417 	set		Y_Hi,Y+4
   9418 	set		Y_Lo,Y+8
   9419 
   9420 	set		R,FP_SCR1
   9421 	set		R_Hi,R+4
   9422 	set		R_Lo,R+8
   9423 
   9424 Scale:
   9425 	long		0x00010000,0x80000000,0x00000000,0x00000000
   9426 
   9427 	global		smod
   9428 smod:
   9429 	clr.b		FPSR_QBYTE(%a6)
   9430 	mov.l		%d0,-(%sp)		# save ctrl bits
   9431 	clr.b		Mod_Flag(%a6)
   9432 	bra.b		Mod_Rem
   9433 
   9434 	global		srem
   9435 srem:
   9436 	clr.b		FPSR_QBYTE(%a6)
   9437 	mov.l		%d0,-(%sp)		# save ctrl bits
   9438 	mov.b		&0x1,Mod_Flag(%a6)
   9439 
   9440 Mod_Rem:
   9441 #..Save sign of X and Y
   9442 	movm.l		&0x3f00,-(%sp)		# save data registers
   9443 	mov.w		SRC_EX(%a0),%d3
   9444 	mov.w		%d3,SignY(%a6)
   9445 	and.l		&0x00007FFF,%d3		# Y := |Y|
   9446 
   9447 #
   9448 	mov.l		SRC_HI(%a0),%d4
   9449 	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
   9450 
   9451 	tst.l		%d3
   9452 	bne.b		Y_Normal
   9453 
   9454 	mov.l		&0x00003FFE,%d3		# $3FFD + 1
   9455 	tst.l		%d4
   9456 	bne.b		HiY_not0
   9457 
   9458 HiY_0:
   9459 	mov.l		%d5,%d4
   9460 	clr.l		%d5
   9461 	sub.l		&32,%d3
   9462 	clr.l		%d6
   9463 	bfffo		%d4{&0:&32},%d6
   9464 	lsl.l		%d6,%d4
   9465 	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
   9466 #	                                        ...with bias $7FFD
   9467 	bra.b		Chk_X
   9468 
   9469 HiY_not0:
   9470 	clr.l		%d6
   9471 	bfffo		%d4{&0:&32},%d6
   9472 	sub.l		%d6,%d3
   9473 	lsl.l		%d6,%d4
   9474 	mov.l		%d5,%d7			# a copy of D5
   9475 	lsl.l		%d6,%d5
   9476 	neg.l		%d6
   9477 	add.l		&32,%d6
   9478 	lsr.l		%d6,%d7
   9479 	or.l		%d7,%d4			# (D3,D4,D5) normalized
   9480 #                                       ...with bias $7FFD
   9481 	bra.b		Chk_X
   9482 
   9483 Y_Normal:
   9484 	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
   9485 #                                       ...with bias $7FFD
   9486 
   9487 Chk_X:
   9488 	mov.w		DST_EX(%a1),%d0
   9489 	mov.w		%d0,SignX(%a6)
   9490 	mov.w		SignY(%a6),%d1
   9491 	eor.l		%d0,%d1
   9492 	and.l		&0x00008000,%d1
   9493 	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
   9494 	and.l		&0x00007FFF,%d0
   9495 	mov.l		DST_HI(%a1),%d1
   9496 	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
   9497 	tst.l		%d0
   9498 	bne.b		X_Normal
   9499 	mov.l		&0x00003FFE,%d0
   9500 	tst.l		%d1
   9501 	bne.b		HiX_not0
   9502 
   9503 HiX_0:
   9504 	mov.l		%d2,%d1
   9505 	clr.l		%d2
   9506 	sub.l		&32,%d0
   9507 	clr.l		%d6
   9508 	bfffo		%d1{&0:&32},%d6
   9509 	lsl.l		%d6,%d1
   9510 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
   9511 #                                       ...with bias $7FFD
   9512 	bra.b		Init
   9513 
   9514 HiX_not0:
   9515 	clr.l		%d6
   9516 	bfffo		%d1{&0:&32},%d6
   9517 	sub.l		%d6,%d0
   9518 	lsl.l		%d6,%d1
   9519 	mov.l		%d2,%d7			# a copy of D2
   9520 	lsl.l		%d6,%d2
   9521 	neg.l		%d6
   9522 	add.l		&32,%d6
   9523 	lsr.l		%d6,%d7
   9524 	or.l		%d7,%d1			# (D0,D1,D2) normalized
   9525 #                                       ...with bias $7FFD
   9526 	bra.b		Init
   9527 
   9528 X_Normal:
   9529 	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
   9530 #                                       ...with bias $7FFD
   9531 
   9532 Init:
   9533 #
   9534 	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
   9535 	mov.l		%d0,-(%sp)		# save biased exp(X)
   9536 	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
   9537 
   9538 	clr.l		%d6			# D6 := carry <- 0
   9539 	clr.l		%d3			# D3 is Q
   9540 	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
   9541 
   9542 #..(Carry,D1,D2) is R
   9543 	tst.l		%d0
   9544 	bge.b		Mod_Loop_pre
   9545 
   9546 #..expo(X) < expo(Y). Thus X = mod(X,Y)
   9547 #
   9548 	mov.l		(%sp)+,%d0		# restore d0
   9549 	bra.w		Get_Mod
   9550 
   9551 Mod_Loop_pre:
   9552 	addq.l		&0x4,%sp		# erase exp(X)
   9553 #..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
   9554 Mod_Loop:
   9555 	tst.l		%d6			# test carry bit
   9556 	bgt.b		R_GT_Y
   9557 
   9558 #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
   9559 	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
   9560 	bne.b		R_NE_Y
   9561 	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
   9562 	bne.b		R_NE_Y
   9563 
   9564 #..At this point, R = Y
   9565 	bra.w		Rem_is_0
   9566 
   9567 R_NE_Y:
   9568 #..use the borrow of the previous compare
   9569 	bcs.b		R_LT_Y			# borrow is set iff R < Y
   9570 
   9571 R_GT_Y:
   9572 #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
   9573 #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
   9574 	sub.l		%d5,%d2			# lo(R) - lo(Y)
   9575 	subx.l		%d4,%d1			# hi(R) - hi(Y)
   9576 	clr.l		%d6			# clear carry
   9577 	addq.l		&1,%d3			# Q := Q + 1
   9578 
   9579 R_LT_Y:
   9580 #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
   9581 	tst.l		%d0			# see if j = 0.
   9582 	beq.b		PostLoop
   9583 
   9584 	add.l		%d3,%d3			# Q := 2Q
   9585 	add.l		%d2,%d2			# lo(R) = 2lo(R)
   9586 	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
   9587 	scs		%d6			# set Carry if 2(R) overflows
   9588 	addq.l		&1,%a1			# k := k+1
   9589 	subq.l		&1,%d0			# j := j - 1
   9590 #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
   9591 
   9592 	bra.b		Mod_Loop
   9593 
   9594 PostLoop:
   9595 #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
   9596 
   9597 #..normalize R.
   9598 	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
   9599 	tst.l		%d1
   9600 	bne.b		HiR_not0
   9601 
   9602 HiR_0:
   9603 	mov.l		%d2,%d1
   9604 	clr.l		%d2
   9605 	sub.l		&32,%d0
   9606 	clr.l		%d6
   9607 	bfffo		%d1{&0:&32},%d6
   9608 	lsl.l		%d6,%d1
   9609 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
   9610 #                                       ...with bias $7FFD
   9611 	bra.b		Get_Mod
   9612 
   9613 HiR_not0:
   9614 	clr.l		%d6
   9615 	bfffo		%d1{&0:&32},%d6
   9616 	bmi.b		Get_Mod			# already normalized
   9617 	sub.l		%d6,%d0
   9618 	lsl.l		%d6,%d1
   9619 	mov.l		%d2,%d7			# a copy of D2
   9620 	lsl.l		%d6,%d2
   9621 	neg.l		%d6
   9622 	add.l		&32,%d6
   9623 	lsr.l		%d6,%d7
   9624 	or.l		%d7,%d1			# (D0,D1,D2) normalized
   9625 
   9626 #
   9627 Get_Mod:
   9628 	cmp.l		%d0,&0x000041FE
   9629 	bge.b		No_Scale
   9630 Do_Scale:
   9631 	mov.w		%d0,R(%a6)
   9632 	mov.l		%d1,R_Hi(%a6)
   9633 	mov.l		%d2,R_Lo(%a6)
   9634 	mov.l		L_SCR1(%a6),%d6
   9635 	mov.w		%d6,Y(%a6)
   9636 	mov.l		%d4,Y_Hi(%a6)
   9637 	mov.l		%d5,Y_Lo(%a6)
   9638 	fmov.x		R(%a6),%fp0		# no exception
   9639 	mov.b		&1,Sc_Flag(%a6)
   9640 	bra.b		ModOrRem
   9641 No_Scale:
   9642 	mov.l		%d1,R_Hi(%a6)
   9643 	mov.l		%d2,R_Lo(%a6)
   9644 	sub.l		&0x3FFE,%d0
   9645 	mov.w		%d0,R(%a6)
   9646 	mov.l		L_SCR1(%a6),%d6
   9647 	sub.l		&0x3FFE,%d6
   9648 	mov.l		%d6,L_SCR1(%a6)
   9649 	fmov.x		R(%a6),%fp0
   9650 	mov.w		%d6,Y(%a6)
   9651 	mov.l		%d4,Y_Hi(%a6)
   9652 	mov.l		%d5,Y_Lo(%a6)
   9653 	clr.b		Sc_Flag(%a6)
   9654 
   9655 #
   9656 ModOrRem:
   9657 	tst.b		Mod_Flag(%a6)
   9658 	beq.b		Fix_Sign
   9659 
   9660 	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
   9661 	subq.l		&1,%d6			# biased expo(Y/2)
   9662 	cmp.l		%d0,%d6
   9663 	blt.b		Fix_Sign
   9664 	bgt.b		Last_Sub
   9665 
   9666 	cmp.l		%d1,%d4
   9667 	bne.b		Not_EQ
   9668 	cmp.l		%d2,%d5
   9669 	bne.b		Not_EQ
   9670 	bra.w		Tie_Case
   9671 
   9672 Not_EQ:
   9673 	bcs.b		Fix_Sign
   9674 
   9675 Last_Sub:
   9676 #
   9677 	fsub.x		Y(%a6),%fp0		# no exceptions
   9678 	addq.l		&1,%d3			# Q := Q + 1
   9679 
   9680 #
   9681 Fix_Sign:
   9682 #..Get sign of X
   9683 	mov.w		SignX(%a6),%d6
   9684 	bge.b		Get_Q
   9685 	fneg.x		%fp0
   9686 
   9687 #..Get Q
   9688 #
   9689 Get_Q:
   9690 	clr.l		%d6
   9691 	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
   9692 	mov.l		&8,%d7
   9693 	lsr.l		%d7,%d6
   9694 	and.l		&0x0000007F,%d3		# 7 bits of Q
   9695 	or.l		%d6,%d3			# sign and bits of Q
   9696 #	swap		%d3
   9697 #	fmov.l		%fpsr,%d6
   9698 #	and.l		&0xFF00FFFF,%d6
   9699 #	or.l		%d3,%d6
   9700 #	fmov.l		%d6,%fpsr		# put Q in fpsr
   9701 	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
   9702 
   9703 #
   9704 Restore:
   9705 	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
   9706 	mov.l		(%sp)+,%d0
   9707 	fmov.l		%d0,%fpcr
   9708 	tst.b		Sc_Flag(%a6)
   9709 	beq.b		Finish
   9710 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9711 	fmul.x		Scale(%pc),%fp0		# may cause underflow
   9712 	bra		t_catch2
   9713 # the '040 package did this apparently to see if the dst operand for the
   9714 # preceding fmul was a denorm. but, it better not have been since the
   9715 # algorithm just got done playing with fp0 and expected no exceptions
   9716 # as a result. trust me...
   9717 #	bra		t_avoid_unsupp		# check for denorm as a
   9718 #						;result of the scaling
   9719 
   9720 Finish:
   9721 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   9722 	fmov.x		%fp0,%fp0		# capture exceptions & round
   9723 	bra		t_catch2
   9724 
   9725 Rem_is_0:
   9726 #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
   9727 	addq.l		&1,%d3
   9728 	cmp.l		%d0,&8			# D0 is j
   9729 	bge.b		Q_Big
   9730 
   9731 	lsl.l		%d0,%d3
   9732 	bra.b		Set_R_0
   9733 
   9734 Q_Big:
   9735 	clr.l		%d3
   9736 
   9737 Set_R_0:
   9738 	fmov.s		&0x00000000,%fp0
   9739 	clr.b		Sc_Flag(%a6)
   9740 	bra.w		Fix_Sign
   9741 
   9742 Tie_Case:
   9743 #..Check parity of Q
   9744 	mov.l		%d3,%d6
   9745 	and.l		&0x00000001,%d6
   9746 	tst.l		%d6
   9747 	beq.w		Fix_Sign		# Q is even
   9748 
   9749 #..Q is odd, Q := Q + 1, signX := -signX
   9750 	addq.l		&1,%d3
   9751 	mov.w		SignX(%a6),%d6
   9752 	eor.l		&0x00008000,%d6
   9753 	mov.w		%d6,SignX(%a6)
   9754 	bra.w		Fix_Sign
   9755 
   9756 #########################################################################
   9757 # XDEF ****************************************************************	#
   9758 # 	tag(): return the optype of the input ext fp number		#
   9759 #									#
   9760 #	This routine is used by the 060FPLSP.				#
   9761 #									#
   9762 # XREF ****************************************************************	#
   9763 #	None								#
   9764 #									#
   9765 # INPUT ***************************************************************	#
   9766 #	a0 = pointer to extended precision operand			#
   9767 # 									#
   9768 # OUTPUT **************************************************************	#
   9769 #	d0 = value of type tag						#
   9770 # 		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
   9771 #									#
   9772 # ALGORITHM ***********************************************************	#
   9773 #	Simply test the exponent, j-bit, and mantissa values to 	#
   9774 # determine the type of operand.					#
   9775 #	If it's an unnormalized zero, alter the operand and force it	#
   9776 # to be a normal zero.							#
   9777 #									#
   9778 #########################################################################
   9779 
   9780 	global		tag
   9781 tag:
   9782 	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
   9783 	andi.w		&0x7fff, %d0		# strip off sign
   9784 	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
   9785 	beq.b		inf_or_nan_x
   9786 not_inf_or_nan_x:
   9787 	btst		&0x7,FTEMP_HI(%a0)
   9788 	beq.b		not_norm_x
   9789 is_norm_x:
   9790 	mov.b		&NORM, %d0
   9791 	rts
   9792 not_norm_x:
   9793 	tst.w		%d0			# is exponent = 0?
   9794 	bne.b		is_unnorm_x
   9795 not_unnorm_x:
   9796 	tst.l		FTEMP_HI(%a0)
   9797 	bne.b		is_denorm_x
   9798 	tst.l		FTEMP_LO(%a0)
   9799 	bne.b		is_denorm_x
   9800 is_zero_x:
   9801 	mov.b		&ZERO, %d0
   9802 	rts
   9803 is_denorm_x:
   9804 	mov.b		&DENORM, %d0
   9805 	rts
   9806 is_unnorm_x:
   9807 	bsr.l		unnorm_fix		# convert to norm,denorm,or zero
   9808 	rts
   9809 is_unnorm_reg_x:
   9810 	mov.b		&UNNORM, %d0
   9811 	rts
   9812 inf_or_nan_x:
   9813 	tst.l		FTEMP_LO(%a0)
   9814 	bne.b		is_nan_x
   9815 	mov.l		FTEMP_HI(%a0), %d0
   9816 	and.l		&0x7fffffff, %d0	# msb is a don't care!
   9817 	bne.b		is_nan_x
   9818 is_inf_x:
   9819 	mov.b		&INF, %d0
   9820 	rts
   9821 is_nan_x:
   9822 	mov.b		&QNAN, %d0
   9823 	rts
   9824 
   9825 #############################################################
   9826 
   9827 qnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
   9828 
   9829 #########################################################################
   9830 # XDEF ****************************************************************	#
   9831 #	t_dz(): Handle 060FPLSP dz exception for "flogn" emulation.	#
   9832 #	t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation.	#
   9833 #									#
   9834 #	These rouitnes are used by the 060FPLSP package.		#
   9835 #									#
   9836 # XREF ****************************************************************	#
   9837 #	None								#
   9838 #									#
   9839 # INPUT ***************************************************************	#
   9840 #	a0 = pointer to extended precision source operand.		#
   9841 # 									#
   9842 # OUTPUT **************************************************************	#
   9843 #	fp0 = default DZ result.					#
   9844 #									#
   9845 # ALGORITHM ***********************************************************	#
   9846 #	Transcendental emulation for the 060FPLSP has detected that 	#
   9847 # a DZ exception should occur for the instruction. If DZ is disabled,	#
   9848 # return the default result.						#
   9849 # 	If DZ is enabled, the dst operand should be returned unscathed	#
   9850 # in fp0 while fp1 is used to create a DZ exception so that the		#
   9851 # operating system can log that such an event occurred.			#
   9852 #									#
   9853 #########################################################################
   9854 
   9855 	global		t_dz
   9856 t_dz:
   9857 	tst.b		SRC_EX(%a0)		# check sign for neg or pos
   9858 	bpl.b		dz_pinf			# branch if pos sign
   9859 
   9860 	global		t_dz2
   9861 t_dz2:
   9862 	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
   9863 
   9864 	btst		&dz_bit,FPCR_ENABLE(%a6)
   9865 	bne.b		dz_minf_ena
   9866 
   9867 # dz is disabled. return a -INF.
   9868 	fmov.s		&0xff800000,%fp0	# return -INF
   9869 	rts
   9870 
   9871 # dz is enabled. create a dz exception so the user can record it
   9872 # but use fp1 instead. return the dst operand unscathed in fp0.
   9873 dz_minf_ena:
   9874 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
   9875 	fmov.l		USER_FPCR(%a6),%fpcr
   9876 	fmov.s		&0xbf800000,%fp1	# load -1
   9877 	fdiv.s		&0x00000000,%fp1	# -1 / 0
   9878 	rts
   9879 
   9880 dz_pinf:
   9881 	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
   9882 
   9883 	btst		&dz_bit,FPCR_ENABLE(%a6)
   9884 	bne.b		dz_pinf_ena
   9885 
   9886 # dz is disabled. return a +INF.
   9887 	fmov.s		&0x7f800000,%fp0	# return +INF
   9888 	rts
   9889 
   9890 # dz is enabled. create a dz exception so the user can record it
   9891 # but use fp1 instead. return the dst operand unscathed in fp0.
   9892 dz_pinf_ena:
   9893 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
   9894 	fmov.l		USER_FPCR(%a6),%fpcr
   9895 	fmov.s		&0x3f800000,%fp1	# load +1
   9896 	fdiv.s		&0x00000000,%fp1	# +1 / 0
   9897 	rts
   9898 
   9899 #########################################################################
   9900 # XDEF ****************************************************************	#
   9901 #	t_operr(): Handle 060FPLSP OPERR exception during emulation.	#
   9902 #									#
   9903 #	This routine is used by the 060FPLSP package.			#
   9904 #									#
   9905 # XREF ****************************************************************	#
   9906 #	None.								#
   9907 #									#
   9908 # INPUT ***************************************************************	#
   9909 #	fp1 = source operand						#
   9910 # 									#
   9911 # OUTPUT **************************************************************	#
   9912 #	fp0 = default result						#
   9913 #	fp1 = unchanged							#
   9914 #									#
   9915 # ALGORITHM ***********************************************************	#
   9916 #	An operand error should occur as the result of transcendental	#
   9917 # emulation in the 060FPLSP. If OPERR is disabled, just return a NAN	#
   9918 # in fp0. If OPERR is enabled, return the dst operand unscathed in fp0	#
   9919 # and the source operand in fp1. Use fp2 to create an OPERR exception	#
   9920 # so that the operating system can log the event.			#
   9921 #									#
   9922 #########################################################################
   9923 
   9924 	global		t_operr
   9925 t_operr:
   9926 	ori.l		&opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
   9927 
   9928 	btst		&operr_bit,FPCR_ENABLE(%a6)
   9929 	bne.b		operr_ena
   9930 
   9931 # operr is disabled. return a QNAN in fp0
   9932 	fmovm.x		qnan(%pc),&0x80		# return QNAN
   9933 	rts
   9934 
   9935 # operr is enabled. create an operr exception so the user can record it
   9936 # but use fp2 instead. return the dst operand unscathed in fp0.
   9937 operr_ena:
   9938 	fmovm.x		EXC_FP0(%a6),&0x80	# return fp0 unscathed
   9939 	fmov.l		USER_FPCR(%a6),%fpcr
   9940 	fmovm.x		&0x04,-(%sp)		# save fp2
   9941 	fmov.s		&0x7f800000,%fp2	# load +INF
   9942 	fmul.s		&0x00000000,%fp2	# +INF x 0
   9943 	fmovm.x		(%sp)+,&0x20		# restore fp2
   9944 	rts
   9945 
   9946 pls_huge:
   9947 	long		0x7ffe0000,0xffffffff,0xffffffff
   9948 mns_huge:
   9949 	long		0xfffe0000,0xffffffff,0xffffffff
   9950 pls_tiny:
   9951 	long		0x00000000,0x80000000,0x00000000
   9952 mns_tiny:
   9953 	long		0x80000000,0x80000000,0x00000000
   9954 
   9955 #########################################################################
   9956 # XDEF ****************************************************************	#
   9957 #	t_unfl(): Handle 060FPLSP underflow exception during emulation.	#
   9958 #	t_unfl2(): Handle 060FPLSP underflow exception during		#
   9959 #	           emulation. result always positive.			#
   9960 #									#
   9961 #	This routine is used by the 060FPLSP package.			#
   9962 #									#
   9963 # XREF ****************************************************************	#
   9964 #	None.								#
   9965 #									#
   9966 # INPUT ***************************************************************	#
   9967 #	a0 = pointer to extended precision source operand		#
   9968 # 									#
   9969 # OUTPUT **************************************************************	#
   9970 #	fp0 = default underflow result					#
   9971 #									#
   9972 # ALGORITHM ***********************************************************	#
   9973 #	An underflow should occur as the result of transcendental	#
   9974 # emulation in the 060FPLSP. Create an underflow by using "fmul"	#
   9975 # and two very small numbers of appropriate sign so that the operating	#
   9976 # system can log the event.						#
   9977 #									#
   9978 #########################################################################
   9979 
   9980 	global		t_unfl
   9981 t_unfl:
   9982 	tst.b		SRC_EX(%a0)
   9983 	bpl.b		unf_pos
   9984 
   9985 	global		t_unfl2
   9986 t_unfl2:
   9987 	ori.l		&unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
   9988 
   9989 	fmov.l		USER_FPCR(%a6),%fpcr
   9990 	fmovm.x		mns_tiny(%pc),&0x80
   9991 	fmul.x		pls_tiny(%pc),%fp0
   9992 
   9993 	fmov.l		%fpsr,%d0
   9994 	rol.l		&0x8,%d0
   9995 	mov.b		%d0,FPSR_CC(%a6)
   9996 	rts
   9997 unf_pos:
   9998 	ori.w		&unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
   9999 
   10000 	fmov.l		USER_FPCR(%a6),%fpcr
   10001 	fmovm.x		pls_tiny(%pc),&0x80
   10002 	fmul.x		%fp0,%fp0
   10003 
   10004 	fmov.l		%fpsr,%d0
   10005 	rol.l		&0x8,%d0
   10006 	mov.b		%d0,FPSR_CC(%a6)
   10007 	rts
   10008 
   10009 #########################################################################
   10010 # XDEF ****************************************************************	#
   10011 #	t_ovfl(): Handle 060FPLSP overflow exception during emulation.	#
   10012 #		  (monadic)						#
   10013 #	t_ovfl2(): Handle 060FPLSP overflow exception during		#
   10014 #	           emulation. result always positive. (dyadic)		#
   10015 #	t_ovfl_sc(): Handle 060FPLSP overflow exception during 		#
   10016 #	             emulation for "fscale". 				#
   10017 #									#
   10018 #	This routine is used by the 060FPLSP package.			#
   10019 #									#
   10020 # XREF ****************************************************************	#
   10021 #	None.								#
   10022 #									#
   10023 # INPUT ***************************************************************	#
   10024 #	a0 = pointer to extended precision source operand		#
   10025 # 									#
   10026 # OUTPUT **************************************************************	#
   10027 #	fp0 = default underflow result					#
   10028 #									#
   10029 # ALGORITHM ***********************************************************	#
   10030 #	An overflow should occur as the result of transcendental	#
   10031 # emulation in the 060FPLSP. Create an overflow by using "fmul"		#
   10032 # and two very lareg numbers of appropriate sign so that the operating	#
   10033 # system can log the event.						#
   10034 #	For t_ovfl_sc() we take special care not to lose the INEX2 bit.	#
   10035 #									#
   10036 #########################################################################
   10037 
   10038 	global		t_ovfl_sc
   10039 t_ovfl_sc:
   10040 	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
   10041 
   10042 	mov.b		%d0,%d1			# fetch rnd prec,mode
   10043 	andi.b		&0xc0,%d1		# extract prec
   10044 	beq.w		ovfl_work
   10045 
   10046 # dst op is a DENORM. we have to normalize the mantissa to see if the
   10047 # result would be inexact for the given precision. make a copy of the
   10048 # dst so we don't screw up the version passed to us.
   10049 	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
   10050 	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
   10051 	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
   10052 	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
   10053 	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
   10054 	bsr.l		norm			# normalize mantissa
   10055 	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
   10056 
   10057 	cmpi.b		%d1,&0x40		# is precision sgl?
   10058 	bne.b		ovfl_sc_dbl		# no; dbl
   10059 ovfl_sc_sgl:
   10060 	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
   10061 	bne.b		ovfl_sc_inx		# yes
   10062 	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
   10063 	bne.b		ovfl_sc_inx		# yes
   10064 	bra.w		ovfl_work		# don't set INEX2
   10065 ovfl_sc_dbl:
   10066 	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
   10067 	andi.l		&0x7ff,%d1		# dbl mantissa set?
   10068 	beq.w		ovfl_work		# no; don't set INEX2
   10069 ovfl_sc_inx:
   10070 	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
   10071 	bra.b		ovfl_work		# continue
   10072 
   10073 	global		t_ovfl
   10074 t_ovfl:
   10075 	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
   10076 ovfl_work:
   10077 	tst.b		SRC_EX(%a0)
   10078 	bpl.b		ovfl_p
   10079 ovfl_m:
   10080 	fmov.l		USER_FPCR(%a6),%fpcr
   10081 	fmovm.x		mns_huge(%pc),&0x80
   10082 	fmul.x		pls_huge(%pc),%fp0
   10083 
   10084 	fmov.l		%fpsr,%d0
   10085 	rol.l		&0x8,%d0
   10086 	ori.b		&neg_mask,%d0
   10087 	mov.b		%d0,FPSR_CC(%a6)
   10088 	rts
   10089 ovfl_p:
   10090 	fmov.l		USER_FPCR(%a6),%fpcr
   10091 	fmovm.x		pls_huge(%pc),&0x80
   10092 	fmul.x		pls_huge(%pc),%fp0
   10093 
   10094 	fmov.l		%fpsr,%d0
   10095 	rol.l		&0x8,%d0
   10096 	mov.b		%d0,FPSR_CC(%a6)
   10097 	rts
   10098 
   10099 	global		t_ovfl2
   10100 t_ovfl2:
   10101 	ori.w		&ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
   10102 	fmov.l		USER_FPCR(%a6),%fpcr
   10103 	fmovm.x		pls_huge(%pc),&0x80
   10104 	fmul.x		pls_huge(%pc),%fp0
   10105 
   10106 	fmov.l		%fpsr,%d0
   10107 	rol.l		&0x8,%d0
   10108 	mov.b		%d0,FPSR_CC(%a6)
   10109 	rts
   10110 
   10111 #########################################################################
   10112 # XDEF ****************************************************************	#
   10113 #	t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
   10114 #		   emulation.						#
   10115 #	t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during	#
   10116 #		    emulation.						#
   10117 #									#
   10118 #	These routines are used by the 060FPLSP package.		#
   10119 #									#
   10120 # XREF ****************************************************************	#
   10121 #	None.								#
   10122 #									#
   10123 # INPUT ***************************************************************	#
   10124 #	fp0 = default underflow or overflow result			#
   10125 # 									#
   10126 # OUTPUT **************************************************************	#
   10127 #	fp0 = default result						#
   10128 #									#
   10129 # ALGORITHM ***********************************************************	#
   10130 # 	If an overflow or underflow occurred during the last 		#
   10131 # instruction of transcendental 060FPLSP emulation, then it has already	#
   10132 # occurred and has been logged. Now we need to see if an inexact	#
   10133 # exception should occur.						#
   10134 #									#
   10135 #########################################################################
   10136 
   10137 	global		t_catch2
   10138 t_catch2:
   10139 	fmov.l		%fpsr,%d0
   10140 	or.l		%d0,USER_FPSR(%a6)
   10141 	bra.b		inx2_work
   10142 
   10143 	global		t_catch
   10144 t_catch:
   10145 	fmov.l		%fpsr,%d0
   10146 	or.l		%d0,USER_FPSR(%a6)
   10147 
   10148 #########################################################################
   10149 # XDEF ****************************************************************	#
   10150 #	t_inx2(): Handle inexact 060FPLSP exception during emulation.	#
   10151 #	t_pinx2(): Handle inexact 060FPLSP exception for "+" results.	#
   10152 #	t_minx2(): Handle inexact 060FPLSP exception for "-" results.	#
   10153 #									#
   10154 # XREF ****************************************************************	#
   10155 #	None.								#
   10156 #									#
   10157 # INPUT ***************************************************************	#
   10158 #	fp0 = default result						#
   10159 # 									#
   10160 # OUTPUT **************************************************************	#
   10161 #	fp0 = default result						#
   10162 #									#
   10163 # ALGORITHM ***********************************************************	#
   10164 # 	The last instruction of transcendental emulation for the 	#
   10165 # 060FPLSP should be inexact. So, if inexact is enabled, then we create	#
   10166 # the event here by adding a large and very small number together	#
   10167 # so that the operating system can log the event.			#
   10168 # 	Must check, too, if the result was zero, in which case we just	#
   10169 # set the FPSR bits and return.						#
   10170 #									#
   10171 #########################################################################
   10172 
   10173 	global		t_inx2
   10174 t_inx2:
   10175 	fblt.w		t_minx2
   10176 	fbeq.w		inx2_zero
   10177 
   10178 	global		t_pinx2
   10179 t_pinx2:
   10180 	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
   10181 	bra.b		inx2_work
   10182 
   10183 	global		t_minx2
   10184 t_minx2:
   10185 	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6)
   10186 
   10187 inx2_work:
   10188 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
   10189 	bne.b		inx2_work_ena		# yes
   10190 	rts
   10191 inx2_work_ena:
   10192 	fmov.l		USER_FPCR(%a6),%fpcr	# insert user's exceptions
   10193 	fmov.s		&0x3f800000,%fp1	# load +1
   10194 	fadd.x		pls_tiny(%pc),%fp1	# cause exception
   10195 	rts
   10196 
   10197 inx2_zero:
   10198 	mov.b		&z_bmask,FPSR_CC(%a6)
   10199 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
   10200 	rts
   10201 
   10202 #########################################################################
   10203 # XDEF ****************************************************************	#
   10204 #	t_extdnrm(): Handle DENORM inputs in 060FPLSP.			#
   10205 #	t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale".	#
   10206 #									#
   10207 #	This routine is used by the 060FPLSP package.			#
   10208 #									#
   10209 # XREF ****************************************************************	#
   10210 #	None.								#
   10211 #									#
   10212 # INPUT ***************************************************************	#
   10213 #	a0 = pointer to extended precision input operand		#
   10214 # 									#
   10215 # OUTPUT **************************************************************	#
   10216 #	fp0 = default result						#
   10217 #									#
   10218 # ALGORITHM ***********************************************************	#
   10219 #	For all functions that have a denormalized input and that	#
   10220 # f(x)=x, this is the entry point.					#
   10221 #	DENORM value is moved using "fmove" which triggers an exception	#
   10222 # if enabled so the operating system can log the event.			#
   10223 #									#
   10224 #########################################################################
   10225 
   10226 	global		t_extdnrm
   10227 t_extdnrm:
   10228 	fmov.l		USER_FPCR(%a6),%fpcr
   10229 	fmov.x		SRC_EX(%a0),%fp0
   10230 	fmov.l		%fpsr,%d0
   10231 	ori.l		&unfinx_mask,%d0
   10232 	or.l		%d0,USER_FPSR(%a6)
   10233 	rts
   10234 
   10235 	global		t_resdnrm
   10236 t_resdnrm:
   10237 	fmov.l		USER_FPCR(%a6),%fpcr
   10238 	fmov.x		SRC_EX(%a0),%fp0
   10239 	fmov.l		%fpsr,%d0
   10240 	or.l		%d0,USER_FPSR(%a6)
   10241 	rts
   10242 
   10243 ##########################################
   10244 
   10245 #
   10246 # sto_cos:
   10247 # 	This is used by fsincos library emulation. The correct
   10248 # values are already in fp0 and fp1 so we do nothing here.
   10249 #
   10250 	global		sto_cos
   10251 sto_cos:
   10252 	rts
   10253 
   10254 ##########################################
   10255 
   10256 #
   10257 #	dst_qnan --- force result when destination is a NaN
   10258 #
   10259 	global		dst_qnan
   10260 dst_qnan:
   10261 	fmov.x		DST(%a1),%fp0
   10262 	tst.b		DST_EX(%a1)
   10263 	bmi.b		dst_qnan_m
   10264 dst_qnan_p:
   10265 	mov.b		&nan_bmask,FPSR_CC(%a6)
   10266 	rts
   10267 dst_qnan_m:
   10268 	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
   10269 	rts
   10270 
   10271 #
   10272 #	src_qnan --- force result when source is a NaN
   10273 #
   10274 	global		src_qnan
   10275 src_qnan:
   10276 	fmov.x		SRC(%a0),%fp0
   10277 	tst.b		SRC_EX(%a0)
   10278 	bmi.b		src_qnan_m
   10279 src_qnan_p:
   10280 	mov.b		&nan_bmask,FPSR_CC(%a6)
   10281 	rts
   10282 src_qnan_m:
   10283 	mov.b		&nan_bmask+neg_bmask,FPSR_CC(%a6)
   10284 	rts
   10285 
   10286 ##########################################
   10287 
   10288 #
   10289 #	Native instruction support
   10290 #
   10291 #	Some systems may need entry points even for 68060 native
   10292 #	instructions.  These routines are provided for
   10293 #	convenience.
   10294 #
   10295 	global		_fadds_
   10296 _fadds_:
   10297 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10298 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10299 	fmov.s		0x8(%sp),%fp0		# load sgl dst
   10300 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10301 	fadd.s		0x8(%sp),%fp0		# fadd w/ sgl src
   10302 	rts
   10303 
   10304 	global		_faddd_
   10305 _faddd_:
   10306 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10307 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10308 	fmov.d		0x8(%sp),%fp0		# load dbl dst
   10309 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10310 	fadd.d		0xc(%sp),%fp0		# fadd w/ dbl src
   10311 	rts
   10312 
   10313 	global		_faddx_
   10314 _faddx_:
   10315 	fmovm.x		0x4(%sp),&0x80		# load ext dst
   10316 	fadd.x		0x10(%sp),%fp0		# fadd w/ ext src
   10317 	rts
   10318 
   10319 	global		_fsubs_
   10320 _fsubs_:
   10321 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10322 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10323 	fmov.s		0x8(%sp),%fp0		# load sgl dst
   10324 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10325 	fsub.s		0x8(%sp),%fp0		# fsub w/ sgl src
   10326 	rts
   10327 
   10328 	global		_fsubd_
   10329 _fsubd_:
   10330 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10331 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10332 	fmov.d		0x8(%sp),%fp0		# load dbl dst
   10333 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10334 	fsub.d		0xc(%sp),%fp0		# fsub w/ dbl src
   10335 	rts
   10336 
   10337 	global		_fsubx_
   10338 _fsubx_:
   10339 	fmovm.x		0x4(%sp),&0x80		# load ext dst
   10340 	fsub.x		0x10(%sp),%fp0		# fsub w/ ext src
   10341 	rts
   10342 
   10343 	global		_fmuls_
   10344 _fmuls_:
   10345 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10346 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10347 	fmov.s		0x8(%sp),%fp0		# load sgl dst
   10348 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10349 	fmul.s		0x8(%sp),%fp0		# fmul w/ sgl src
   10350 	rts
   10351 
   10352 	global		_fmuld_
   10353 _fmuld_:
   10354 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10355 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10356 	fmov.d		0x8(%sp),%fp0		# load dbl dst
   10357 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10358 	fmul.d		0xc(%sp),%fp0		# fmul w/ dbl src
   10359 	rts
   10360 
   10361 	global		_fmulx_
   10362 _fmulx_:
   10363 	fmovm.x		0x4(%sp),&0x80		# load ext dst
   10364 	fmul.x		0x10(%sp),%fp0		# fmul w/ ext src
   10365 	rts
   10366 
   10367 	global		_fdivs_
   10368 _fdivs_:
   10369 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10370 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10371 	fmov.s		0x8(%sp),%fp0		# load sgl dst
   10372 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10373 	fdiv.s		0x8(%sp),%fp0		# fdiv w/ sgl src
   10374 	rts
   10375 
   10376 	global		_fdivd_
   10377 _fdivd_:
   10378 	fmov.l		%fpcr,-(%sp)		# save fpcr
   10379 	fmov.l		&0x00000000,%fpcr	# clear fpcr for load
   10380 	fmov.d		0x8(%sp),%fp0		# load dbl dst
   10381 	fmov.l		(%sp)+,%fpcr		# restore fpcr
   10382 	fdiv.d		0xc(%sp),%fp0		# fdiv w/ dbl src
   10383 	rts
   10384 
   10385 	global		_fdivx_
   10386 _fdivx_:
   10387 	fmovm.x		0x4(%sp),&0x80		# load ext dst
   10388 	fdiv.x		0x10(%sp),%fp0		# fdiv w/ ext src
   10389 	rts
   10390 
   10391 	global		_fabss_
   10392 _fabss_:
   10393 	fabs.s		0x4(%sp),%fp0		# fabs w/ sgl src
   10394 	rts
   10395 
   10396 	global		_fabsd_
   10397 _fabsd_:
   10398 	fabs.d		0x4(%sp),%fp0		# fabs w/ dbl src
   10399 	rts
   10400 
   10401 	global		_fabsx_
   10402 _fabsx_:
   10403 	fabs.x		0x4(%sp),%fp0		# fabs w/ ext src
   10404 	rts
   10405 
   10406 	global		_fnegs_
   10407 _fnegs_:
   10408 	fneg.s		0x4(%sp),%fp0		# fneg w/ sgl src
   10409 	rts
   10410 
   10411 	global		_fnegd_
   10412 _fnegd_:
   10413 	fneg.d		0x4(%sp),%fp0		# fneg w/ dbl src
   10414 	rts
   10415 
   10416 	global		_fnegx_
   10417 _fnegx_:
   10418 	fneg.x		0x4(%sp),%fp0		# fneg w/ ext src
   10419 	rts
   10420 
   10421 	global		_fsqrts_
   10422 _fsqrts_:
   10423 	fsqrt.s		0x4(%sp),%fp0		# fsqrt w/ sgl src
   10424 	rts
   10425 
   10426 	global		_fsqrtd_
   10427 _fsqrtd_:
   10428 	fsqrt.d		0x4(%sp),%fp0		# fsqrt w/ dbl src
   10429 	rts
   10430 
   10431 	global		_fsqrtx_
   10432 _fsqrtx_:
   10433 	fsqrt.x		0x4(%sp),%fp0		# fsqrt w/ ext src
   10434 	rts
   10435 
   10436 	global		_fints_
   10437 _fints_:
   10438 	fint.s		0x4(%sp),%fp0		# fint w/ sgl src
   10439 	rts
   10440 
   10441 	global		_fintd_
   10442 _fintd_:
   10443 	fint.d		0x4(%sp),%fp0		# fint w/ dbl src
   10444 	rts
   10445 
   10446 	global		_fintx_
   10447 _fintx_:
   10448 	fint.x		0x4(%sp),%fp0		# fint w/ ext src
   10449 	rts
   10450 
   10451 	global		_fintrzs_
   10452 _fintrzs_:
   10453 	fintrz.s	0x4(%sp),%fp0		# fintrz w/ sgl src
   10454 	rts
   10455 
   10456 	global		_fintrzd_
   10457 _fintrzd_:
   10458 	fintrz.d	0x4(%sp),%fp0		# fintrx w/ dbl src
   10459 	rts
   10460 
   10461 	global		_fintrzx_
   10462 _fintrzx_:
   10463 	fintrz.x	0x4(%sp),%fp0		# fintrz w/ ext src
   10464 	rts
   10465 
   10466 ########################################################################
   10467 
   10468 #########################################################################
   10469 # src_zero(): Return signed zero according to sign of src operand.	#
   10470 #########################################################################
   10471 	global		src_zero
   10472 src_zero:
   10473 	tst.b		SRC_EX(%a0)		# get sign of src operand
   10474 	bmi.b		ld_mzero		# if neg, load neg zero
   10475 
   10476 #
   10477 # ld_pzero(): return a positive zero.
   10478 #
   10479 	global		ld_pzero
   10480 ld_pzero:
   10481 	fmov.s		&0x00000000,%fp0	# load +0
   10482 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   10483 	rts
   10484 
   10485 # ld_mzero(): return a negative zero.
   10486 	global		ld_mzero
   10487 ld_mzero:
   10488 	fmov.s		&0x80000000,%fp0	# load -0
   10489 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
   10490 	rts
   10491 
   10492 #########################################################################
   10493 # dst_zero(): Return signed zero according to sign of dst operand.	#
   10494 #########################################################################
   10495 	global		dst_zero
   10496 dst_zero:
   10497 	tst.b		DST_EX(%a1) 		# get sign of dst operand
   10498 	bmi.b		ld_mzero		# if neg, load neg zero
   10499 	bra.b		ld_pzero		# load positive zero
   10500 
   10501 #########################################################################
   10502 # src_inf(): Return signed inf according to sign of src operand.	#
   10503 #########################################################################
   10504 	global		src_inf
   10505 src_inf:
   10506 	tst.b		SRC_EX(%a0) 		# get sign of src operand
   10507 	bmi.b		ld_minf			# if negative branch
   10508 
   10509 #
   10510 # ld_pinf(): return a positive infinity.
   10511 #
   10512 	global		ld_pinf
   10513 ld_pinf:
   10514 	fmov.s		&0x7f800000,%fp0	# load +INF
   10515 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
   10516 	rts
   10517 
   10518 #
   10519 # ld_minf():return a negative infinity.
   10520 #
   10521 	global		ld_minf
   10522 ld_minf:
   10523 	fmov.s		&0xff800000,%fp0	# load -INF
   10524 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   10525 	rts
   10526 
   10527 #########################################################################
   10528 # dst_inf(): Return signed inf according to sign of dst operand.	#
   10529 #########################################################################
   10530 	global		dst_inf
   10531 dst_inf:
   10532 	tst.b		DST_EX(%a1) 		# get sign of dst operand
   10533 	bmi.b		ld_minf			# if negative branch
   10534 	bra.b		ld_pinf
   10535 
   10536 	global		szr_inf
   10537 #################################################################
   10538 # szr_inf(): Return +ZERO for a negative src operand or		#
   10539 #	            +INF for a positive src operand.		#
   10540 #	     Routine used for fetox, ftwotox, and ftentox.	#
   10541 #################################################################
   10542 szr_inf:
   10543 	tst.b		SRC_EX(%a0)		# check sign of source
   10544 	bmi.b		ld_pzero
   10545 	bra.b		ld_pinf
   10546 
   10547 #########################################################################
   10548 # sopr_inf(): Return +INF for a positive src operand or			#
   10549 #	      jump to operand error routine for a negative src operand.	#
   10550 #	      Routine used for flogn, flognp1, flog10, and flog2.	#
   10551 #########################################################################
   10552 	global		sopr_inf
   10553 sopr_inf:
   10554 	tst.b		SRC_EX(%a0)		# check sign of source
   10555 	bmi.w		t_operr
   10556 	bra.b		ld_pinf
   10557 
   10558 #################################################################
   10559 # setoxm1i(): Return minus one for a negative src operand or	#
   10560 #	      positive infinity for a positive src operand.	#
   10561 #	      Routine used for fetoxm1.				#
   10562 #################################################################
   10563 	global		setoxm1i
   10564 setoxm1i:
   10565 	tst.b		SRC_EX(%a0)		# check sign of source
   10566 	bmi.b		ld_mone
   10567 	bra.b		ld_pinf
   10568 
   10569 #########################################################################
   10570 # src_one(): Return signed one according to sign of src operand.	#
   10571 #########################################################################
   10572 	global		src_one
   10573 src_one:
   10574 	tst.b		SRC_EX(%a0) 		# check sign of source
   10575 	bmi.b		ld_mone
   10576 
   10577 #
   10578 # ld_pone(): return positive one.
   10579 #
   10580 	global		ld_pone
   10581 ld_pone:
   10582 	fmov.s		&0x3f800000,%fp0	# load +1
   10583 	clr.b		FPSR_CC(%a6)
   10584 	rts
   10585 
   10586 #
   10587 # ld_mone(): return negative one.
   10588 #
   10589 	global		ld_mone
   10590 ld_mone:
   10591 	fmov.s		&0xbf800000,%fp0	# load -1
   10592 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   10593 	rts
   10594 
   10595 ppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
   10596 mpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
   10597 
   10598 #################################################################
   10599 # spi_2(): Return signed PI/2 according to sign of src operand.	#
   10600 #################################################################
   10601 	global		spi_2
   10602 spi_2:
   10603 	tst.b		SRC_EX(%a0) 		# check sign of source
   10604 	bmi.b		ld_mpi2
   10605 
   10606 #
   10607 # ld_ppi2(): return positive PI/2.
   10608 #
   10609 	global		ld_ppi2
   10610 ld_ppi2:
   10611 	fmov.l		%d0,%fpcr
   10612 	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
   10613 	bra.w		t_pinx2			# set INEX2
   10614 
   10615 #
   10616 # ld_mpi2(): return negative PI/2.
   10617 #
   10618 	global		ld_mpi2
   10619 ld_mpi2:
   10620 	fmov.l		%d0,%fpcr
   10621 	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
   10622 	bra.w		t_minx2			# set INEX2
   10623 
   10624 ####################################################
   10625 # The following routines give support for fsincos. #
   10626 ####################################################
   10627 
   10628 #
   10629 # ssincosz(): When the src operand is ZERO, store a one in the
   10630 # 	      cosine register and return a ZERO in fp0 w/ the same sign
   10631 #	      as the src operand.
   10632 #
   10633 	global		ssincosz
   10634 ssincosz:
   10635 	fmov.s		&0x3f800000,%fp1
   10636 	tst.b		SRC_EX(%a0)		# test sign
   10637 	bpl.b		sincoszp
   10638 	fmov.s		&0x80000000,%fp0	# return sin result in fp0
   10639 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
   10640 	rts
   10641 sincoszp:
   10642 	fmov.s		&0x00000000,%fp0	# return sin result in fp0
   10643 	mov.b		&z_bmask,FPSR_CC(%a6)
   10644 	rts
   10645 
   10646 #
   10647 # ssincosi(): When the src operand is INF, store a QNAN in the cosine
   10648 #	      register and jump to the operand error routine for negative
   10649 #	      src operands.
   10650 #
   10651 	global		ssincosi
   10652 ssincosi:
   10653 	fmov.x		qnan(%pc),%fp1		# load NAN
   10654 	bra.w		t_operr
   10655 
   10656 #
   10657 # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
   10658 # 		 register and branch to the src QNAN routine.
   10659 #
   10660 	global		ssincosqnan
   10661 ssincosqnan:
   10662 	fmov.x		LOCAL_EX(%a0),%fp1
   10663 	bra.w		src_qnan
   10664 
   10665 ########################################################################
   10666 
   10667 	global		smod_sdnrm
   10668 	global		smod_snorm
   10669 smod_sdnrm:
   10670 smod_snorm:
   10671 	mov.b		DTAG(%a6),%d1
   10672 	beq.l		smod
   10673 	cmpi.b		%d1,&ZERO
   10674 	beq.w		smod_zro
   10675 	cmpi.b		%d1,&INF
   10676 	beq.l		t_operr
   10677 	cmpi.b		%d1,&DENORM
   10678 	beq.l		smod
   10679 	bra.l		dst_qnan
   10680 
   10681 	global		smod_szero
   10682 smod_szero:
   10683 	mov.b		DTAG(%a6),%d1
   10684 	beq.l		t_operr
   10685 	cmpi.b		%d1,&ZERO
   10686 	beq.l		t_operr
   10687 	cmpi.b		%d1,&INF
   10688 	beq.l		t_operr
   10689 	cmpi.b		%d1,&DENORM
   10690 	beq.l		t_operr
   10691 	bra.l		dst_qnan
   10692 
   10693 	global		smod_sinf
   10694 smod_sinf:
   10695 	mov.b		DTAG(%a6),%d1
   10696 	beq.l		smod_fpn
   10697 	cmpi.b		%d1,&ZERO
   10698 	beq.l		smod_zro
   10699 	cmpi.b		%d1,&INF
   10700 	beq.l		t_operr
   10701 	cmpi.b		%d1,&DENORM
   10702 	beq.l		smod_fpn
   10703 	bra.l		dst_qnan
   10704 
   10705 smod_zro:
   10706 srem_zro:
   10707 	mov.b		SRC_EX(%a0),%d1		# get src sign
   10708 	mov.b		DST_EX(%a1),%d0		# get dst sign
   10709 	eor.b		%d0,%d1			# get qbyte sign
   10710 	andi.b		&0x80,%d1
   10711 	mov.b		%d1,FPSR_QBYTE(%a6)
   10712 	tst.b		%d0
   10713 	bpl.w		ld_pzero
   10714 	bra.w		ld_mzero
   10715 
   10716 smod_fpn:
   10717 srem_fpn:
   10718 	clr.b		FPSR_QBYTE(%a6)
   10719 	mov.l		%d0,-(%sp)
   10720 	mov.b		SRC_EX(%a0),%d1		# get src sign
   10721 	mov.b		DST_EX(%a1),%d0		# get dst sign
   10722 	eor.b		%d0,%d1			# get qbyte sign
   10723 	andi.b		&0x80,%d1
   10724 	mov.b		%d1,FPSR_QBYTE(%a6)
   10725 	cmpi.b		DTAG(%a6),&DENORM
   10726 	bne.b		smod_nrm
   10727 	lea		DST(%a1),%a0
   10728 	mov.l		(%sp)+,%d0
   10729 	bra		t_resdnrm
   10730 smod_nrm:
   10731 	fmov.l		(%sp)+,%fpcr
   10732 	fmov.x		DST(%a1),%fp0
   10733 	tst.b		DST_EX(%a1)
   10734 	bmi.b		smod_nrm_neg
   10735 	rts
   10736 
   10737 smod_nrm_neg:
   10738 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' code
   10739 	rts
   10740 
   10741 #########################################################################
   10742 	global		srem_snorm
   10743 	global		srem_sdnrm
   10744 srem_sdnrm:
   10745 srem_snorm:
   10746 	mov.b		DTAG(%a6),%d1
   10747 	beq.l		srem
   10748 	cmpi.b		%d1,&ZERO
   10749 	beq.w		srem_zro
   10750 	cmpi.b		%d1,&INF
   10751 	beq.l		t_operr
   10752 	cmpi.b		%d1,&DENORM
   10753 	beq.l		srem
   10754 	bra.l		dst_qnan
   10755 
   10756 	global		srem_szero
   10757 srem_szero:
   10758 	mov.b		DTAG(%a6),%d1
   10759 	beq.l		t_operr
   10760 	cmpi.b		%d1,&ZERO
   10761 	beq.l		t_operr
   10762 	cmpi.b		%d1,&INF
   10763 	beq.l		t_operr
   10764 	cmpi.b		%d1,&DENORM
   10765 	beq.l		t_operr
   10766 	bra.l		dst_qnan
   10767 
   10768 	global		srem_sinf
   10769 srem_sinf:
   10770 	mov.b		DTAG(%a6),%d1
   10771 	beq.w		srem_fpn
   10772 	cmpi.b		%d1,&ZERO
   10773 	beq.w		srem_zro
   10774 	cmpi.b		%d1,&INF
   10775 	beq.l		t_operr
   10776 	cmpi.b		%d1,&DENORM
   10777 	beq.l		srem_fpn
   10778 	bra.l		dst_qnan
   10779 
   10780 #########################################################################
   10781 
   10782 	global		sscale_snorm
   10783 	global		sscale_sdnrm
   10784 sscale_snorm:
   10785 sscale_sdnrm:
   10786 	mov.b		DTAG(%a6),%d1
   10787 	beq.l		sscale
   10788 	cmpi.b		%d1,&ZERO
   10789 	beq.l		dst_zero
   10790 	cmpi.b		%d1,&INF
   10791 	beq.l		dst_inf
   10792 	cmpi.b		%d1,&DENORM
   10793 	beq.l		sscale
   10794 	bra.l		dst_qnan
   10795 
   10796 	global		sscale_szero
   10797 sscale_szero:
   10798 	mov.b		DTAG(%a6),%d1
   10799 	beq.l		sscale
   10800 	cmpi.b		%d1,&ZERO
   10801 	beq.l		dst_zero
   10802 	cmpi.b		%d1,&INF
   10803 	beq.l		dst_inf
   10804 	cmpi.b		%d1,&DENORM
   10805 	beq.l		sscale
   10806 	bra.l		dst_qnan
   10807 
   10808 	global		sscale_sinf
   10809 sscale_sinf:
   10810 	mov.b		DTAG(%a6),%d1
   10811 	beq.l		t_operr
   10812 	cmpi.b		%d1,&QNAN
   10813 	beq.l		dst_qnan
   10814 	bra.l		t_operr
   10815 
   10816 ########################################################################
   10817 
   10818 	global		sop_sqnan
   10819 sop_sqnan:
   10820 	mov.b		DTAG(%a6),%d1
   10821 	cmpi.b		%d1,&QNAN
   10822 	beq.l		dst_qnan
   10823 	bra.l		src_qnan
   10824 
   10825 #########################################################################
   10826 # norm(): normalize the mantissa of an extended precision input. the	#
   10827 #	  input operand should not be normalized already.		#
   10828 #									#
   10829 # XDEF ****************************************************************	#
   10830 #	norm()								#
   10831 #									#
   10832 # XREF **************************************************************** #
   10833 #	none								#
   10834 #									#
   10835 # INPUT *************************************************************** #
   10836 #	a0 = pointer fp extended precision operand to normalize		#
   10837 #									#
   10838 # OUTPUT ************************************************************** #
   10839 # 	d0 = number of bit positions the mantissa was shifted		#
   10840 #	a0 = the input operand's mantissa is normalized; the exponent	#
   10841 #	     is unchanged.						#
   10842 #									#
   10843 #########################################################################
   10844 	global		norm
   10845 norm:
   10846 	mov.l		%d2, -(%sp)		# create some temp regs
   10847 	mov.l		%d3, -(%sp)
   10848 
   10849 	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
   10850 	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
   10851 
   10852 	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
   10853 	beq.b		norm_lo			# hi(man) is all zeroes!
   10854 
   10855 norm_hi:
   10856 	lsl.l		%d2, %d0		# left shift hi(man)
   10857 	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
   10858 
   10859 	or.l		%d3, %d0		# create hi(man)
   10860 	lsl.l		%d2, %d1		# create lo(man)
   10861 
   10862 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
   10863 	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
   10864 
   10865 	mov.l		%d2, %d0		# return shift amount
   10866 
   10867 	mov.l		(%sp)+, %d3		# restore temp regs
   10868 	mov.l		(%sp)+, %d2
   10869 
   10870 	rts
   10871 
   10872 norm_lo:
   10873 	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
   10874 	lsl.l		%d2, %d1		# shift lo(man)
   10875 	add.l		&32, %d2		# add 32 to shft amount
   10876 
   10877 	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
   10878 	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
   10879 
   10880 	mov.l		%d2, %d0		# return shift amount
   10881 
   10882 	mov.l		(%sp)+, %d3		# restore temp regs
   10883 	mov.l		(%sp)+, %d2
   10884 
   10885 	rts
   10886 
   10887 #########################################################################
   10888 # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
   10889 #		- returns corresponding optype tag			#
   10890 #									#
   10891 # XDEF ****************************************************************	#
   10892 #	unnorm_fix()							#
   10893 #									#
   10894 # XREF **************************************************************** #
   10895 #	norm() - normalize the mantissa					#
   10896 #									#
   10897 # INPUT *************************************************************** #
   10898 #	a0 = pointer to unnormalized extended precision number		#
   10899 #									#
   10900 # OUTPUT ************************************************************** #
   10901 #	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
   10902 #	a0 = input operand has been converted to a norm, denorm, or	#
   10903 #	     zero; both the exponent and mantissa are changed.		#
   10904 #									#
   10905 #########################################################################
   10906 
   10907 	global		unnorm_fix
   10908 unnorm_fix:
   10909 	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
   10910 	bne.b		unnorm_shift		# hi(man) is not all zeroes
   10911 
   10912 #
   10913 # hi(man) is all zeroes so see if any bits in lo(man) are set
   10914 #
   10915 unnorm_chk_lo:
   10916 	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
   10917 	beq.w		unnorm_zero		# yes
   10918 
   10919 	add.w		&32, %d0		# no; fix shift distance
   10920 
   10921 #
   10922 # d0 = # shifts needed for complete normalization
   10923 #
   10924 unnorm_shift:
   10925 	clr.l		%d1			# clear top word
   10926 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
   10927 	and.w		&0x7fff, %d1		# strip off sgn
   10928 
   10929 	cmp.w		%d0, %d1		# will denorm push exp < 0?
   10930 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
   10931 
   10932 #
   10933 # exponent would not go < 0. therefore, number stays normalized
   10934 #
   10935 	sub.w		%d0, %d1		# shift exponent value
   10936 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
   10937 	and.w		&0x8000, %d0		# save old sign
   10938 	or.w		%d0, %d1		# {sgn,new exp}
   10939 	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
   10940 
   10941 	bsr.l		norm			# normalize UNNORM
   10942 
   10943 	mov.b		&NORM, %d0		# return new optype tag
   10944 	rts
   10945 
   10946 #
   10947 # exponent would go < 0, so only denormalize until exp = 0
   10948 #
   10949 unnorm_nrm_zero:
   10950 	cmp.b		%d1, &32		# is exp <= 32?
   10951 	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
   10952 
   10953 	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
   10954 	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
   10955 
   10956 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
   10957 	lsl.l		%d1, %d0		# extract new lo(man)
   10958 	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
   10959 
   10960 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
   10961 
   10962 	mov.b		&DENORM, %d0		# return new optype tag
   10963 	rts
   10964 
   10965 #
   10966 # only mantissa bits set are in lo(man)
   10967 #
   10968 unnorm_nrm_zero_lrg:
   10969 	sub.w		&32, %d1		# adjust shft amt by 32
   10970 
   10971 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
   10972 	lsl.l		%d1, %d0		# left shift lo(man)
   10973 
   10974 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
   10975 	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
   10976 
   10977 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
   10978 
   10979 	mov.b		&DENORM, %d0		# return new optype tag
   10980 	rts
   10981 
   10982 #
   10983 # whole mantissa is zero so this UNNORM is actually a zero
   10984 #
   10985 unnorm_zero:
   10986 	and.w		&0x8000, FTEMP_EX(%a0) 	# force exponent to zero
   10987 
   10988 	mov.b		&ZERO, %d0		# fix optype tag
   10989 	rts
   10990