Home | History | Annotate | Line # | Download | only in dist
fpsp.s revision 1.4
      1  1.1     is #
      2  1.4    wiz # $NetBSD: fpsp.s,v 1.4 2004/02/24 15:05:54 wiz Exp $
      3  1.1     is #
      4  1.1     is 
      5  1.1     is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      6  1.1     is # MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      7  1.1     is # M68000 Hi-Performance Microprocessor Division
      8  1.1     is # M68060 Software Package Production Release
      9  1.1     is #
     10  1.1     is # M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc.
     11  1.1     is # All rights reserved.
     12  1.1     is #
     13  1.1     is # THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     14  1.1     is # To the maximum extent permitted by applicable law,
     15  1.1     is # MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     16  1.1     is # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
     17  1.1     is # FOR A PARTICULAR PURPOSE and any warranty against infringement with
     18  1.1     is # regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     19  1.1     is # and any accompanying written materials.
     20  1.1     is #
     21  1.1     is # To the maximum extent permitted by applicable law,
     22  1.1     is # IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     23  1.1     is # (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
     24  1.1     is # BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
     25  1.1     is # ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
     26  1.1     is #
     27  1.1     is # Motorola assumes no responsibility for the maintenance and support
     28  1.1     is # of the SOFTWARE.
     29  1.1     is #
     30  1.1     is # You are hereby granted a copyright license to use, modify, and distribute the
     31  1.1     is # SOFTWARE so long as this entire notice is retained without alteration
     32  1.1     is # in any modified and/or redistributed versions, and that such modified
     33  1.1     is # versions are clearly identified as such.
     34  1.1     is # No licenses are granted by implication, estoppel or otherwise under any
     35  1.1     is # patents or trademarks of Motorola, Inc.
     36  1.1     is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     37  1.1     is 
     38  1.1     is #
     39  1.1     is # freal.s:
     40  1.1     is #	This file is appended to the top of the 060FPSP package
     41  1.1     is # and contains the entry points into the package. The user, in
     42  1.1     is # effect, branches to one of the branch table entries located
     43  1.1     is # after _060FPSP_TABLE.
     44  1.1     is #	Also, subroutine stubs exist in this file (_fpsp_done for
     45  1.1     is # example) that are referenced by the FPSP package itself in order
     46  1.1     is # to call a given routine. The stub routine actually performs the
     47  1.1     is # callout. The FPSP code does a "bsr" to the stub routine. This
     48  1.1     is # extra layer of hierarchy adds a slight performance penalty but
     49  1.1     is # it makes the FPSP code easier to read and more mainatinable.
     50  1.1     is #
     51  1.1     is 
     52  1.1     is set	_off_bsun,	0x00
     53  1.1     is set	_off_snan,	0x04
     54  1.1     is set	_off_operr,	0x08
     55  1.1     is set	_off_ovfl,	0x0c
     56  1.1     is set	_off_unfl,	0x10
     57  1.1     is set	_off_dz,	0x14
     58  1.1     is set	_off_inex,	0x18
     59  1.1     is set	_off_fline,	0x1c
     60  1.1     is set	_off_fpu_dis,	0x20
     61  1.1     is set	_off_trap,	0x24
     62  1.1     is set	_off_trace,	0x28
     63  1.1     is set	_off_access,	0x2c
     64  1.1     is set	_off_done,	0x30
     65  1.1     is 
     66  1.1     is set	_off_imr,	0x40
     67  1.1     is set	_off_dmr,	0x44
     68  1.1     is set	_off_dmw,	0x48
     69  1.1     is set	_off_irw,	0x4c
     70  1.1     is set	_off_irl,	0x50
     71  1.1     is set	_off_drb,	0x54
     72  1.1     is set	_off_drw,	0x58
     73  1.1     is set	_off_drl,	0x5c
     74  1.1     is set	_off_dwb,	0x60
     75  1.1     is set	_off_dww,	0x64
     76  1.1     is set	_off_dwl,	0x68
     77  1.1     is 
     78  1.1     is _060FPSP_TABLE:
     79  1.1     is 
     80  1.1     is ###############################################################
     81  1.1     is 
     82  1.1     is # Here's the table of ENTRY POINTS for those linking the package.
     83  1.1     is 	bra.l		_fpsp_snan
     84  1.1     is 	short		0x0000
     85  1.1     is 	bra.l		_fpsp_operr
     86  1.1     is 	short		0x0000
     87  1.1     is 	bra.l		_fpsp_ovfl
     88  1.1     is 	short		0x0000
     89  1.1     is 	bra.l		_fpsp_unfl
     90  1.1     is 	short		0x0000
     91  1.1     is 	bra.l		_fpsp_dz
     92  1.1     is 	short		0x0000
     93  1.1     is 	bra.l		_fpsp_inex
     94  1.1     is 	short		0x0000
     95  1.1     is 	bra.l		_fpsp_fline
     96  1.1     is 	short		0x0000
     97  1.1     is 	bra.l		_fpsp_unsupp
     98  1.1     is 	short		0x0000
     99  1.1     is 	bra.l		_fpsp_effadd
    100  1.1     is 	short		0x0000
    101  1.1     is 
    102  1.1     is 	space 		56
    103  1.1     is 
    104  1.1     is ###############################################################
    105  1.1     is 	global		_fpsp_done
    106  1.1     is _fpsp_done:
    107  1.1     is 	mov.l		%d0,-(%sp)
    108  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_done,%pc),%d0
    109  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    110  1.1     is 	mov.l		0x4(%sp),%d0
    111  1.1     is 	rtd		&0x4
    112  1.1     is 
    113  1.1     is 	global		_real_ovfl
    114  1.1     is _real_ovfl:
    115  1.1     is 	mov.l		%d0,-(%sp)
    116  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_ovfl,%pc),%d0
    117  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    118  1.1     is 	mov.l		0x4(%sp),%d0
    119  1.1     is 	rtd		&0x4
    120  1.1     is 
    121  1.1     is 	global		_real_unfl
    122  1.1     is _real_unfl:
    123  1.1     is 	mov.l		%d0,-(%sp)
    124  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_unfl,%pc),%d0
    125  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    126  1.1     is 	mov.l		0x4(%sp),%d0
    127  1.1     is 	rtd		&0x4
    128  1.1     is 
    129  1.1     is 	global		_real_inex
    130  1.1     is _real_inex:
    131  1.1     is 	mov.l		%d0,-(%sp)
    132  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_inex,%pc),%d0
    133  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    134  1.1     is 	mov.l		0x4(%sp),%d0
    135  1.1     is 	rtd		&0x4
    136  1.1     is 
    137  1.1     is 	global		_real_bsun
    138  1.1     is _real_bsun:
    139  1.1     is 	mov.l		%d0,-(%sp)
    140  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_bsun,%pc),%d0
    141  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    142  1.1     is 	mov.l		0x4(%sp),%d0
    143  1.1     is 	rtd		&0x4
    144  1.1     is 
    145  1.1     is 	global		_real_operr
    146  1.1     is _real_operr:
    147  1.1     is 	mov.l		%d0,-(%sp)
    148  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_operr,%pc),%d0
    149  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    150  1.1     is 	mov.l		0x4(%sp),%d0
    151  1.1     is 	rtd		&0x4
    152  1.1     is 
    153  1.1     is 	global		_real_snan
    154  1.1     is _real_snan:
    155  1.1     is 	mov.l		%d0,-(%sp)
    156  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_snan,%pc),%d0
    157  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    158  1.1     is 	mov.l		0x4(%sp),%d0
    159  1.1     is 	rtd		&0x4
    160  1.1     is 
    161  1.1     is 	global		_real_dz
    162  1.1     is _real_dz:
    163  1.1     is 	mov.l		%d0,-(%sp)
    164  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_dz,%pc),%d0
    165  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    166  1.1     is 	mov.l		0x4(%sp),%d0
    167  1.1     is 	rtd		&0x4
    168  1.1     is 
    169  1.1     is 	global		_real_fline
    170  1.1     is _real_fline:
    171  1.1     is 	mov.l		%d0,-(%sp)
    172  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_fline,%pc),%d0
    173  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    174  1.1     is 	mov.l		0x4(%sp),%d0
    175  1.1     is 	rtd		&0x4
    176  1.1     is 
    177  1.1     is 	global		_real_fpu_disabled
    178  1.1     is _real_fpu_disabled:
    179  1.1     is 	mov.l		%d0,-(%sp)
    180  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_fpu_dis,%pc),%d0
    181  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    182  1.1     is 	mov.l		0x4(%sp),%d0
    183  1.1     is 	rtd		&0x4
    184  1.1     is 
    185  1.1     is 	global		_real_trap
    186  1.1     is _real_trap:
    187  1.1     is 	mov.l		%d0,-(%sp)
    188  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_trap,%pc),%d0
    189  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    190  1.1     is 	mov.l		0x4(%sp),%d0
    191  1.1     is 	rtd		&0x4
    192  1.1     is 
    193  1.1     is 	global		_real_trace
    194  1.1     is _real_trace:
    195  1.1     is 	mov.l		%d0,-(%sp)
    196  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_trace,%pc),%d0
    197  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    198  1.1     is 	mov.l		0x4(%sp),%d0
    199  1.1     is 	rtd		&0x4
    200  1.1     is 
    201  1.1     is 	global		_real_access
    202  1.1     is _real_access:
    203  1.1     is 	mov.l		%d0,-(%sp)
    204  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_access,%pc),%d0
    205  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    206  1.1     is 	mov.l		0x4(%sp),%d0
    207  1.1     is 	rtd		&0x4
    208  1.1     is 
    209  1.1     is #######################################
    210  1.1     is 
    211  1.1     is 	global		_imem_read
    212  1.1     is _imem_read:
    213  1.1     is 	mov.l		%d0,-(%sp)
    214  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_imr,%pc),%d0
    215  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    216  1.1     is 	mov.l		0x4(%sp),%d0
    217  1.1     is 	rtd		&0x4
    218  1.1     is 
    219  1.1     is 	global		_dmem_read
    220  1.1     is _dmem_read:
    221  1.1     is 	mov.l		%d0,-(%sp)
    222  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_dmr,%pc),%d0
    223  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    224  1.1     is 	mov.l		0x4(%sp),%d0
    225  1.1     is 	rtd		&0x4
    226  1.1     is 
    227  1.1     is 	global		_dmem_write
    228  1.1     is _dmem_write:
    229  1.1     is 	mov.l		%d0,-(%sp)
    230  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_dmw,%pc),%d0
    231  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    232  1.1     is 	mov.l		0x4(%sp),%d0
    233  1.1     is 	rtd		&0x4
    234  1.1     is 
    235  1.1     is 	global		_imem_read_word
    236  1.1     is _imem_read_word:
    237  1.1     is 	mov.l		%d0,-(%sp)
    238  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_irw,%pc),%d0
    239  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    240  1.1     is 	mov.l		0x4(%sp),%d0
    241  1.1     is 	rtd		&0x4
    242  1.1     is 
    243  1.1     is 	global		_imem_read_long
    244  1.1     is _imem_read_long:
    245  1.1     is 	mov.l		%d0,-(%sp)
    246  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_irl,%pc),%d0
    247  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    248  1.1     is 	mov.l		0x4(%sp),%d0
    249  1.1     is 	rtd		&0x4
    250  1.1     is 
    251  1.1     is 	global		_dmem_read_byte
    252  1.1     is _dmem_read_byte:
    253  1.1     is 	mov.l		%d0,-(%sp)
    254  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_drb,%pc),%d0
    255  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    256  1.1     is 	mov.l		0x4(%sp),%d0
    257  1.1     is 	rtd		&0x4
    258  1.1     is 
    259  1.1     is 	global		_dmem_read_word
    260  1.1     is _dmem_read_word:
    261  1.1     is 	mov.l		%d0,-(%sp)
    262  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_drw,%pc),%d0
    263  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    264  1.1     is 	mov.l		0x4(%sp),%d0
    265  1.1     is 	rtd		&0x4
    266  1.1     is 
    267  1.1     is 	global		_dmem_read_long
    268  1.1     is _dmem_read_long:
    269  1.1     is 	mov.l		%d0,-(%sp)
    270  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_drl,%pc),%d0
    271  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    272  1.1     is 	mov.l		0x4(%sp),%d0
    273  1.1     is 	rtd		&0x4
    274  1.1     is 
    275  1.1     is 	global		_dmem_write_byte
    276  1.1     is _dmem_write_byte:
    277  1.1     is 	mov.l		%d0,-(%sp)
    278  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_dwb,%pc),%d0
    279  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    280  1.1     is 	mov.l		0x4(%sp),%d0
    281  1.1     is 	rtd		&0x4
    282  1.1     is 
    283  1.1     is 	global		_dmem_write_word
    284  1.1     is _dmem_write_word:
    285  1.1     is 	mov.l		%d0,-(%sp)
    286  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_dww,%pc),%d0
    287  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    288  1.1     is 	mov.l		0x4(%sp),%d0
    289  1.1     is 	rtd		&0x4
    290  1.1     is 
    291  1.1     is 	global		_dmem_write_long
    292  1.1     is _dmem_write_long:
    293  1.1     is 	mov.l		%d0,-(%sp)
    294  1.1     is 	mov.l		(_060FPSP_TABLE-0x80+_off_dwl,%pc),%d0
    295  1.1     is 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    296  1.1     is 	mov.l		0x4(%sp),%d0
    297  1.1     is 	rtd		&0x4
    298  1.1     is 
    299  1.1     is #
    300  1.1     is # This file contains a set of define statements for constants
    301  1.1     is # in order to promote readability within the corecode itself.
    302  1.1     is #
    303  1.1     is 
    304  1.1     is set LOCAL_SIZE,		192			# stack frame size(bytes)
    305  1.1     is set LV,			-LOCAL_SIZE		# stack offset
    306  1.1     is 
    307  1.1     is set EXC_SR,		0x4			# stack status register
    308  1.1     is set EXC_PC,		0x6			# stack pc
    309  1.1     is set EXC_VOFF,		0xa			# stacked vector offset
    310  1.1     is set EXC_EA,		0xc			# stacked <ea>
    311  1.1     is 
    312  1.1     is set EXC_FP,		0x0			# frame pointer
    313  1.1     is 
    314  1.1     is set EXC_AREGS,		-68			# offset of all address regs
    315  1.1     is set EXC_DREGS,		-100			# offset of all data regs
    316  1.1     is set EXC_FPREGS,		-36			# offset of all fp regs
    317  1.1     is 
    318  1.1     is set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
    319  1.1     is set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
    320  1.1     is set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
    321  1.1     is set EXC_A5,		EXC_AREGS+(5*4)
    322  1.1     is set EXC_A4,		EXC_AREGS+(4*4)
    323  1.1     is set EXC_A3,		EXC_AREGS+(3*4)
    324  1.1     is set EXC_A2,		EXC_AREGS+(2*4)
    325  1.1     is set EXC_A1,		EXC_AREGS+(1*4)
    326  1.1     is set EXC_A0,		EXC_AREGS+(0*4)
    327  1.1     is set EXC_D7,		EXC_DREGS+(7*4)
    328  1.1     is set EXC_D6,		EXC_DREGS+(6*4)
    329  1.1     is set EXC_D5,		EXC_DREGS+(5*4)
    330  1.1     is set EXC_D4,		EXC_DREGS+(4*4)
    331  1.1     is set EXC_D3,		EXC_DREGS+(3*4)
    332  1.1     is set EXC_D2,		EXC_DREGS+(2*4)
    333  1.1     is set EXC_D1,		EXC_DREGS+(1*4)
    334  1.1     is set EXC_D0,		EXC_DREGS+(0*4)
    335  1.1     is 
    336  1.1     is set EXC_FP0, 		EXC_FPREGS+(0*12)	# offset of saved fp0
    337  1.1     is set EXC_FP1, 		EXC_FPREGS+(1*12)	# offset of saved fp1
    338  1.1     is set EXC_FP2, 		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
    339  1.1     is 
    340  1.1     is set FP_SCR1, 		LV+80			# fp scratch 1
    341  1.1     is set FP_SCR1_EX, 	FP_SCR1+0
    342  1.1     is set FP_SCR1_SGN,	FP_SCR1+2
    343  1.1     is set FP_SCR1_HI, 	FP_SCR1+4
    344  1.1     is set FP_SCR1_LO, 	FP_SCR1+8
    345  1.1     is 
    346  1.1     is set FP_SCR0, 		LV+68			# fp scratch 0
    347  1.1     is set FP_SCR0_EX, 	FP_SCR0+0
    348  1.1     is set FP_SCR0_SGN,	FP_SCR0+2
    349  1.1     is set FP_SCR0_HI, 	FP_SCR0+4
    350  1.1     is set FP_SCR0_LO, 	FP_SCR0+8
    351  1.1     is 
    352  1.1     is set FP_DST, 		LV+56			# fp destination operand
    353  1.1     is set FP_DST_EX, 		FP_DST+0
    354  1.1     is set FP_DST_SGN,		FP_DST+2
    355  1.1     is set FP_DST_HI, 		FP_DST+4
    356  1.1     is set FP_DST_LO, 		FP_DST+8
    357  1.1     is 
    358  1.1     is set FP_SRC, 		LV+44			# fp source operand
    359  1.1     is set FP_SRC_EX, 		FP_SRC+0
    360  1.1     is set FP_SRC_SGN,		FP_SRC+2
    361  1.1     is set FP_SRC_HI, 		FP_SRC+4
    362  1.1     is set FP_SRC_LO, 		FP_SRC+8
    363  1.1     is 
    364  1.1     is set USER_FPIAR,		LV+40			# FP instr address register
    365  1.1     is 
    366  1.1     is set USER_FPSR,		LV+36			# FP status register
    367  1.1     is set FPSR_CC,		USER_FPSR+0		# FPSR condition codes
    368  1.1     is set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
    369  1.1     is set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
    370  1.1     is set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
    371  1.1     is 
    372  1.1     is set USER_FPCR,		LV+32			# FP control register
    373  1.1     is set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
    374  1.1     is set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
    375  1.1     is 
    376  1.1     is set L_SCR3,		LV+28			# integer scratch 3
    377  1.1     is set L_SCR2,		LV+24			# integer scratch 2
    378  1.1     is set L_SCR1,		LV+20			# integer scratch 1
    379  1.1     is 
    380  1.1     is set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
    381  1.1     is 
    382  1.1     is set EXC_TEMP2,		LV+24			# temporary space
    383  1.1     is set EXC_TEMP,		LV+16			# temporary space
    384  1.1     is 
    385  1.1     is set DTAG,		LV+15			# destination operand type
    386  1.1     is set STAG, 		LV+14			# source operand type
    387  1.1     is 
    388  1.1     is set SPCOND_FLG,		LV+10			# flag: special case (see below)
    389  1.1     is 
    390  1.1     is set EXC_CC,		LV+8			# saved condition codes
    391  1.1     is set EXC_EXTWPTR,	LV+4			# saved current PC (active)
    392  1.1     is set EXC_EXTWORD,	LV+2			# saved extension word
    393  1.1     is set EXC_CMDREG,		LV+2			# saved extension word
    394  1.1     is set EXC_OPWORD,		LV+0			# saved operation word
    395  1.1     is 
    396  1.1     is ################################
    397  1.1     is 
    398  1.1     is # Helpful macros
    399  1.1     is 
    400  1.1     is set FTEMP,		0			# offsets within an
    401  1.1     is set FTEMP_EX, 		0			# extended precision
    402  1.1     is set FTEMP_SGN,		2			# value saved in memory.
    403  1.1     is set FTEMP_HI, 		4
    404  1.1     is set FTEMP_LO, 		8
    405  1.1     is set FTEMP_GRS,		12
    406  1.1     is 
    407  1.1     is set LOCAL,		0			# offsets within an
    408  1.1     is set LOCAL_EX, 		0			# extended precision
    409  1.1     is set LOCAL_SGN,		2			# value saved in memory.
    410  1.1     is set LOCAL_HI, 		4
    411  1.1     is set LOCAL_LO, 		8
    412  1.1     is set LOCAL_GRS,		12
    413  1.1     is 
    414  1.1     is set DST,		0			# offsets within an
    415  1.1     is set DST_EX,		0			# extended precision
    416  1.1     is set DST_HI,		4			# value saved in memory.
    417  1.1     is set DST_LO,		8
    418  1.1     is 
    419  1.1     is set SRC,		0			# offsets within an
    420  1.1     is set SRC_EX,		0			# extended precision
    421  1.1     is set SRC_HI,		4			# value saved in memory.
    422  1.1     is set SRC_LO,		8
    423  1.1     is 
    424  1.1     is set SGL_LO,		0x3f81			# min sgl prec exponent
    425  1.1     is set SGL_HI,		0x407e			# max sgl prec exponent
    426  1.1     is set DBL_LO,		0x3c01			# min dbl prec exponent
    427  1.1     is set DBL_HI,		0x43fe			# max dbl prec exponent
    428  1.1     is set EXT_LO,		0x0			# min ext prec exponent
    429  1.1     is set EXT_HI,		0x7ffe			# max ext prec exponent
    430  1.1     is 
    431  1.1     is set EXT_BIAS,		0x3fff			# extended precision bias
    432  1.1     is set SGL_BIAS,		0x007f			# single precision bias
    433  1.1     is set DBL_BIAS,		0x03ff			# double precision bias
    434  1.1     is 
    435  1.1     is set NORM,		0x00			# operand type for STAG/DTAG
    436  1.1     is set ZERO,		0x01			# operand type for STAG/DTAG
    437  1.1     is set INF,		0x02			# operand type for STAG/DTAG
    438  1.1     is set QNAN,		0x03			# operand type for STAG/DTAG
    439  1.1     is set DENORM,		0x04			# operand type for STAG/DTAG
    440  1.1     is set SNAN,		0x05			# operand type for STAG/DTAG
    441  1.1     is set UNNORM,		0x06			# operand type for STAG/DTAG
    442  1.1     is 
    443  1.1     is ##################
    444  1.1     is # FPSR/FPCR bits #
    445  1.1     is ##################
    446  1.1     is set neg_bit,		0x3			# negative result
    447  1.1     is set z_bit,		0x2			# zero result
    448  1.1     is set inf_bit,		0x1			# infinite result
    449  1.1     is set nan_bit,		0x0			# NAN result
    450  1.1     is 
    451  1.1     is set q_sn_bit,		0x7			# sign bit of quotient byte
    452  1.1     is 
    453  1.1     is set bsun_bit,		7			# branch on unordered
    454  1.1     is set snan_bit,		6			# signalling NAN
    455  1.1     is set operr_bit,		5			# operand error
    456  1.1     is set ovfl_bit,		4			# overflow
    457  1.1     is set unfl_bit,		3			# underflow
    458  1.1     is set dz_bit,		2			# divide by zero
    459  1.1     is set inex2_bit,		1			# inexact result 2
    460  1.1     is set inex1_bit,		0			# inexact result 1
    461  1.1     is 
    462  1.1     is set aiop_bit,		7			# accrued inexact operation bit
    463  1.1     is set aovfl_bit,		6			# accrued overflow bit
    464  1.1     is set aunfl_bit,		5			# accrued underflow bit
    465  1.1     is set adz_bit,		4			# accrued dz bit
    466  1.1     is set ainex_bit,		3			# accrued inexact bit
    467  1.1     is 
    468  1.1     is #############################
    469  1.1     is # FPSR individual bit masks #
    470  1.1     is #############################
    471  1.1     is set neg_mask,		0x08000000		# negative bit mask (lw)
    472  1.1     is set inf_mask,		0x02000000		# infinity bit mask (lw)
    473  1.1     is set z_mask,		0x04000000		# zero bit mask (lw)
    474  1.1     is set nan_mask,		0x01000000		# nan bit mask (lw)
    475  1.1     is 
    476  1.1     is set neg_bmask,		0x08			# negative bit mask (byte)
    477  1.1     is set inf_bmask,		0x02			# infinity bit mask (byte)
    478  1.1     is set z_bmask,		0x04			# zero bit mask (byte)
    479  1.1     is set nan_bmask,		0x01			# nan bit mask (byte)
    480  1.1     is 
    481  1.1     is set bsun_mask,		0x00008000		# bsun exception mask
    482  1.1     is set snan_mask,		0x00004000		# snan exception mask
    483  1.1     is set operr_mask,		0x00002000		# operr exception mask
    484  1.1     is set ovfl_mask,		0x00001000		# overflow exception mask
    485  1.1     is set unfl_mask,		0x00000800		# underflow exception mask
    486  1.1     is set dz_mask,		0x00000400		# dz exception mask
    487  1.1     is set inex2_mask,		0x00000200		# inex2 exception mask
    488  1.1     is set inex1_mask,		0x00000100		# inex1 exception mask
    489  1.1     is 
    490  1.1     is set aiop_mask,		0x00000080		# accrued illegal operation
    491  1.1     is set aovfl_mask,		0x00000040		# accrued overflow
    492  1.1     is set aunfl_mask,		0x00000020		# accrued underflow
    493  1.1     is set adz_mask,		0x00000010		# accrued divide by zero
    494  1.1     is set ainex_mask,		0x00000008		# accrued inexact
    495  1.1     is 
    496  1.1     is ######################################
    497  1.1     is # FPSR combinations used in the FPSP #
    498  1.1     is ######################################
    499  1.1     is set dzinf_mask,		inf_mask+dz_mask+adz_mask
    500  1.1     is set opnan_mask,		nan_mask+operr_mask+aiop_mask
    501  1.1     is set nzi_mask,		0x01ffffff 		#clears N, Z, and I
    502  1.1     is set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
    503  1.1     is set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
    504  1.1     is set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
    505  1.1     is set inx1a_mask,		inex1_mask+ainex_mask
    506  1.1     is set inx2a_mask,		inex2_mask+ainex_mask
    507  1.1     is set snaniop_mask, 	nan_mask+snan_mask+aiop_mask
    508  1.1     is set snaniop2_mask,	snan_mask+aiop_mask
    509  1.1     is set naniop_mask,	nan_mask+aiop_mask
    510  1.1     is set neginf_mask,	neg_mask+inf_mask
    511  1.1     is set infaiop_mask, 	inf_mask+aiop_mask
    512  1.1     is set negz_mask,		neg_mask+z_mask
    513  1.1     is set opaop_mask,		operr_mask+aiop_mask
    514  1.1     is set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
    515  1.1     is set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
    516  1.1     is 
    517  1.1     is #########
    518  1.1     is # misc. #
    519  1.1     is #########
    520  1.1     is set rnd_stky_bit,	29			# stky bit pos in longword
    521  1.1     is 
    522  1.1     is set sign_bit,		0x7			# sign bit
    523  1.1     is set signan_bit,		0x6			# signalling nan bit
    524  1.1     is 
    525  1.1     is set sgl_thresh,		0x3f81			# minimum sgl exponent
    526  1.1     is set dbl_thresh,		0x3c01			# minimum dbl exponent
    527  1.1     is 
    528  1.1     is set x_mode,		0x0			# extended precision
    529  1.1     is set s_mode,		0x4			# single precision
    530  1.1     is set d_mode,		0x8			# double precision
    531  1.1     is 
    532  1.1     is set rn_mode,		0x0			# round-to-nearest
    533  1.1     is set rz_mode,		0x1			# round-to-zero
    534  1.1     is set rm_mode,		0x2			# round-tp-minus-infinity
    535  1.1     is set rp_mode,		0x3			# round-to-plus-infinity
    536  1.1     is 
    537  1.1     is set mantissalen,	64			# length of mantissa in bits
    538  1.1     is 
    539  1.1     is set BYTE,		1			# len(byte) == 1 byte
    540  1.1     is set WORD, 		2			# len(word) == 2 bytes
    541  1.1     is set LONG, 		4			# len(longword) == 2 bytes
    542  1.1     is 
    543  1.1     is set BSUN_VEC,		0xc0			# bsun    vector offset
    544  1.1     is set INEX_VEC,		0xc4			# inexact vector offset
    545  1.1     is set DZ_VEC,		0xc8			# dz      vector offset
    546  1.1     is set UNFL_VEC,		0xcc			# unfl    vector offset
    547  1.1     is set OPERR_VEC,		0xd0			# operr   vector offset
    548  1.1     is set OVFL_VEC,		0xd4			# ovfl    vector offset
    549  1.1     is set SNAN_VEC,		0xd8			# snan    vector offset
    550  1.1     is 
    551  1.1     is ###########################
    552  1.1     is # SPecial CONDition FLaGs #
    553  1.1     is ###########################
    554  1.1     is set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
    555  1.1     is set fbsun_flg,		0x02			# flag bit: bsun exception
    556  1.1     is set mia7_flg,		0x04			# flag bit: (a7)+ <ea>
    557  1.1     is set mda7_flg,		0x08			# flag bit: -(a7) <ea>
    558  1.1     is set fmovm_flg,		0x40			# flag bit: fmovm instruction
    559  1.1     is set immed_flg,		0x80			# flag bit: &<data> <ea>
    560  1.1     is 
    561  1.1     is set ftrapcc_bit,	0x0
    562  1.1     is set fbsun_bit,		0x1
    563  1.1     is set mia7_bit,		0x2
    564  1.1     is set mda7_bit,		0x3
    565  1.1     is set immed_bit,		0x7
    566  1.1     is 
    567  1.1     is ##################################
    568  1.1     is # TRANSCENDENTAL "LAST-OP" FLAGS #
    569  1.1     is ##################################
    570  1.1     is set FMUL_OP,		0x0			# fmul instr performed last
    571  1.1     is set FDIV_OP,		0x1			# fdiv performed last
    572  1.1     is set FADD_OP,		0x2			# fadd performed last
    573  1.1     is set FMOV_OP,		0x3			# fmov performed last
    574  1.1     is 
    575  1.1     is #############
    576  1.1     is # CONSTANTS #
    577  1.1     is #############
    578  1.1     is T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
    579  1.1     is T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
    580  1.1     is 
    581  1.1     is PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
    582  1.1     is PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
    583  1.1     is 
    584  1.1     is TWOBYPI:
    585  1.1     is 	long		0x3FE45F30,0x6DC9C883
    586  1.1     is 
    587  1.1     is #########################################################################
    588  1.1     is # XDEF ****************************************************************	#
    589  1.1     is #	_fpsp_ovfl(): 060FPSP entry point for FP Overflow exception.	#
    590  1.1     is #									#
    591  1.1     is #	This handler should be the first code executed upon taking the	#
    592  1.1     is #	FP Overflow exception in an operating system.			#
    593  1.1     is #									#
    594  1.1     is # XREF ****************************************************************	#
    595  1.1     is #	_imem_read_long() - read instruction longword			#
    596  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
    597  1.1     is #	set_tag_x() - determine optype of src/dst operands		#
    598  1.1     is #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
    599  1.1     is #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
    600  1.1     is #	load_fpn2() - load dst operand from FP regfile			#
    601  1.1     is #	fout() - emulate an opclass 3 instruction			#
    602  1.1     is #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
    603  1.1     is #	_fpsp_done() - "callout" for 060FPSP exit (all work done!)	#
    604  1.1     is #	_real_ovfl() - "callout" for Overflow exception enabled code	#
    605  1.1     is #	_real_inex() - "callout" for Inexact exception enabled code	#
    606  1.1     is #	_real_trace() - "callout" for Trace exception code		#
    607  1.1     is #									#
    608  1.1     is # INPUT ***************************************************************	#
    609  1.1     is #	- The system stack contains the FP Ovfl exception stack frame	#
    610  1.1     is #	- The fsave frame contains the source operand			#
    611  1.1     is # 									#
    612  1.1     is # OUTPUT **************************************************************	#
    613  1.1     is #	Overflow Exception enabled:					#
    614  1.1     is #	- The system stack is unchanged					#
    615  1.1     is #	- The fsave frame contains the adjusted src op for opclass 0,2	#
    616  1.1     is #	Overflow Exception disabled:					#
    617  1.1     is #	- The system stack is unchanged					#
    618  1.1     is #	- The "exception present" flag in the fsave frame is cleared	#
    619  1.1     is #									#
    620  1.1     is # ALGORITHM ***********************************************************	#
    621  1.1     is #	On the 060, if an FP overflow is present as the result of any	#
    622  1.1     is # instruction, the 060 will take an overflow exception whether the 	#
    623  1.1     is # exception is enabled or disabled in the FPCR. For the disabled case, 	#
    624  1.1     is # This handler emulates the instruction to determine what the correct	#
    625  1.1     is # default result should be for the operation. This default result is	#
    626  1.1     is # then stored in either the FP regfile, data regfile, or memory. 	#
    627  1.1     is # Finally, the handler exits through the "callout" _fpsp_done() 	#
    628  1.1     is # denoting that no exceptional conditions exist within the machine.	#
    629  1.1     is # 	If the exception is enabled, then this handler must create the	#
    630  1.1     is # exceptional operand and plave it in the fsave state frame, and store	#
    631  1.1     is # the default result (only if the instruction is opclass 3). For 	#
    632  1.1     is # exceptions enabled, this handler must exit through the "callout" 	#
    633  1.1     is # _real_ovfl() so that the operating system enabled overflow handler	#
    634  1.1     is # can handle this case.							#
    635  1.1     is #	Two other conditions exist. First, if overflow was disabled 	#
    636  1.1     is # but the inexact exception was enabled, this handler must exit 	#
    637  1.1     is # through the "callout" _real_inex() regardless of whether the result	#
    638  1.1     is # was inexact.								#
    639  1.1     is #	Also, in the case of an opclass three instruction where 	#
    640  1.1     is # overflow was disabled and the trace exception was enabled, this	#
    641  1.1     is # handler must exit through the "callout" _real_trace().		#
    642  1.1     is #									#
    643  1.1     is #########################################################################
    644  1.1     is 
    645  1.1     is 	global		_fpsp_ovfl
    646  1.1     is _fpsp_ovfl:
    647  1.1     is 
    648  1.1     is #$#	sub.l		&24,%sp			# make room for src/dst
    649  1.1     is 
    650  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
    651  1.1     is 
    652  1.1     is 	fsave		FP_SRC(%a6)		# grab the "busy" frame
    653  1.1     is 
    654  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    655  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
    656  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
    657  1.1     is 
    658  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
    659  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
    660  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
    661  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
    662  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
    663  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
    664  1.1     is 
    665  1.1     is ##############################################################################
    666  1.1     is 
    667  1.1     is 	btst		&0x5,EXC_CMDREG(%a6)	# is instr an fmove out?
    668  1.1     is 	bne.w		fovfl_out
    669  1.1     is 
    670  1.1     is 
    671  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    672  1.1     is 	bsr.l		fix_skewed_ops		# fix src op
    673  1.1     is 
    674  1.1     is # since, I believe, only NORMs and DENORMs can come through here,
    675  1.1     is # maybe we can avoid the subroutine call.
    676  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    677  1.1     is 	bsr.l		set_tag_x		# tag the operand type
    678  1.1     is 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
    679  1.1     is 
    680  1.1     is # bit five of the fp extension word separates the monadic and dyadic operations
    681  1.1     is # that can pass through fpsp_ovfl(). remember that fcmp, ftst, and fsincos
    682  1.1     is # will never take this exception.
    683  1.1     is 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
    684  1.1     is 	beq.b		fovfl_extract		# monadic
    685  1.1     is 
    686  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
    687  1.1     is 	bsr.l		load_fpn2		# load dst into FP_DST
    688  1.1     is 
    689  1.1     is 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
    690  1.1     is 	bsr.l		set_tag_x		# tag the operand type
    691  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
    692  1.1     is 	bne.b		fovfl_op2_done		# no
    693  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
    694  1.1     is fovfl_op2_done:
    695  1.1     is 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
    696  1.1     is 
    697  1.1     is fovfl_extract:
    698  1.1     is 
    699  1.1     is #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
    700  1.1     is #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
    701  1.1     is #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
    702  1.1     is #$#	mov.l		FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
    703  1.1     is #$#	mov.l		FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
    704  1.1     is #$#	mov.l		FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
    705  1.1     is 
    706  1.1     is 	clr.l		%d0
    707  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
    708  1.1     is 
    709  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
    710  1.1     is 	andi.w		&0x007f,%d1		# extract extension
    711  1.1     is 
    712  1.1     is 	andi.l		&0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
    713  1.1     is 
    714  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
    715  1.1     is 	fmov.l		&0x0,%fpsr
    716  1.1     is 
    717  1.1     is 	lea		FP_SRC(%a6),%a0
    718  1.1     is 	lea		FP_DST(%a6),%a1
    719  1.1     is 
    720  1.1     is # maybe we can make these entry points ONLY the OVFL entry points of each routine.
    721  1.1     is 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
    722  1.1     is 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
    723  1.1     is 
    724  1.1     is # the operation has been emulated. the result is in fp0.
    725  1.1     is # the EXOP, if an exception occurred, is in fp1.
    726  1.1     is # we must save the default result regardless of whether
    727  1.1     is # traps are enabled or disabled.
    728  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
    729  1.1     is 	bsr.l		store_fpreg
    730  1.1     is 
    731  1.1     is # the exceptional possibilities we have left ourselves with are ONLY overflow
    732  1.1     is # and inexact. and, the inexact is such that overflow occurred and was disabled
    733  1.1     is # but inexact was enabled.
    734  1.1     is 	btst		&ovfl_bit,FPCR_ENABLE(%a6)
    735  1.1     is 	bne.b		fovfl_ovfl_on
    736  1.1     is 
    737  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6)
    738  1.1     is 	bne.b		fovfl_inex_on
    739  1.1     is 
    740  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    741  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    742  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    743  1.1     is 
    744  1.1     is 	unlk		%a6
    745  1.1     is #$#	add.l		&24,%sp
    746  1.1     is 	bra.l		_fpsp_done
    747  1.1     is 
    748  1.1     is # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
    749  1.1     is # in fp1. now, simply jump to _real_ovfl()!
    750  1.1     is fovfl_ovfl_on:
    751  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
    752  1.1     is 
    753  1.1     is 	mov.w		&0xe005,2+FP_SRC(%a6) 	# save exc status
    754  1.1     is 
    755  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    756  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    757  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    758  1.1     is 
    759  1.1     is 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
    760  1.1     is 
    761  1.1     is 	unlk		%a6
    762  1.1     is 
    763  1.1     is 	bra.l		_real_ovfl
    764  1.1     is 
    765  1.1     is # overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
    766  1.1     is # we must jump to real_inex().
    767  1.1     is fovfl_inex_on:
    768  1.1     is 
    769  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6) 	# save EXOP (fp1) to stack
    770  1.1     is 
    771  1.1     is 	mov.b		&0xc4,1+EXC_VOFF(%a6)	# vector offset = 0xc4
    772  1.1     is 	mov.w		&0xe001,2+FP_SRC(%a6) 	# save exc status
    773  1.1     is 
    774  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    775  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    776  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    777  1.1     is 
    778  1.1     is 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
    779  1.1     is 
    780  1.1     is 	unlk		%a6
    781  1.1     is 
    782  1.1     is 	bra.l		_real_inex
    783  1.1     is 
    784  1.1     is ########################################################################
    785  1.1     is fovfl_out:
    786  1.1     is 
    787  1.1     is 
    788  1.1     is #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
    789  1.1     is #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
    790  1.1     is #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
    791  1.1     is 
    792  1.1     is # the src operand is definitely a NORM(!), so tag it as such
    793  1.1     is 	mov.b		&NORM,STAG(%a6)		# set src optype tag
    794  1.1     is 
    795  1.1     is 	clr.l		%d0
    796  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
    797  1.1     is 
    798  1.1     is 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero all but accured field
    799  1.1     is 
    800  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
    801  1.1     is 	fmov.l		&0x0,%fpsr
    802  1.1     is 
    803  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
    804  1.1     is 
    805  1.1     is 	bsr.l		fout
    806  1.1     is 
    807  1.1     is 	btst		&ovfl_bit,FPCR_ENABLE(%a6)
    808  1.1     is 	bne.w		fovfl_ovfl_on
    809  1.1     is 
    810  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6)
    811  1.1     is 	bne.w		fovfl_inex_on
    812  1.1     is 
    813  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    814  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    815  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    816  1.1     is 
    817  1.1     is 	unlk		%a6
    818  1.1     is #$#	add.l		&24,%sp
    819  1.1     is 
    820  1.1     is 	btst		&0x7,(%sp)		# is trace on?
    821  1.1     is 	beq.l		_fpsp_done		# no
    822  1.1     is 
    823  1.1     is 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
    824  1.1     is 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
    825  1.1     is 	bra.l		_real_trace
    826  1.1     is 
    827  1.1     is #########################################################################
    828  1.1     is # XDEF ****************************************************************	#
    829  1.1     is #	_fpsp_unfl(): 060FPSP entry point for FP Underflow exception.	#
    830  1.1     is #									#
    831  1.1     is #	This handler should be the first code executed upon taking the	#
    832  1.1     is #	FP Underflow exception in an operating system.			#
    833  1.1     is #									#
    834  1.1     is # XREF ****************************************************************	#
    835  1.1     is #	_imem_read_long() - read instruction longword			#
    836  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
    837  1.1     is #	set_tag_x() - determine optype of src/dst operands		#
    838  1.1     is #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
    839  1.1     is #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
    840  1.1     is #	load_fpn2() - load dst operand from FP regfile			#
    841  1.1     is #	fout() - emulate an opclass 3 instruction			#
    842  1.1     is #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
    843  1.1     is #	_fpsp_done() - "callout" for 060FPSP exit (all work done!)	#
    844  1.1     is #	_real_ovfl() - "callout" for Overflow exception enabled code	#
    845  1.1     is #	_real_inex() - "callout" for Inexact exception enabled code	#
    846  1.1     is #	_real_trace() - "callout" for Trace exception code		#
    847  1.1     is #									#
    848  1.1     is # INPUT ***************************************************************	#
    849  1.1     is #	- The system stack contains the FP Unfl exception stack frame	#
    850  1.1     is #	- The fsave frame contains the source operand			#
    851  1.1     is # 									#
    852  1.1     is # OUTPUT **************************************************************	#
    853  1.1     is #	Underflow Exception enabled:					#
    854  1.1     is #	- The system stack is unchanged					#
    855  1.1     is #	- The fsave frame contains the adjusted src op for opclass 0,2	#
    856  1.1     is #	Underflow Exception disabled:					#
    857  1.1     is #	- The system stack is unchanged					#
    858  1.1     is #	- The "exception present" flag in the fsave frame is cleared	#
    859  1.1     is #									#
    860  1.1     is # ALGORITHM ***********************************************************	#
    861  1.1     is #	On the 060, if an FP underflow is present as the result of any	#
    862  1.1     is # instruction, the 060 will take an underflow exception whether the 	#
    863  1.1     is # exception is enabled or disabled in the FPCR. For the disabled case, 	#
    864  1.1     is # This handler emulates the instruction to determine what the correct	#
    865  1.1     is # default result should be for the operation. This default result is	#
    866  1.1     is # then stored in either the FP regfile, data regfile, or memory. 	#
    867  1.1     is # Finally, the handler exits through the "callout" _fpsp_done() 	#
    868  1.1     is # denoting that no exceptional conditions exist within the machine.	#
    869  1.1     is # 	If the exception is enabled, then this handler must create the	#
    870  1.1     is # exceptional operand and plave it in the fsave state frame, and store	#
    871  1.1     is # the default result (only if the instruction is opclass 3). For 	#
    872  1.1     is # exceptions enabled, this handler must exit through the "callout" 	#
    873  1.1     is # _real_unfl() so that the operating system enabled overflow handler	#
    874  1.1     is # can handle this case.							#
    875  1.1     is #	Two other conditions exist. First, if underflow was disabled 	#
    876  1.1     is # but the inexact exception was enabled and the result was inexact, 	#
    877  1.1     is # this handler must exit through the "callout" _real_inex().		#
    878  1.1     is # was inexact.								#
    879  1.1     is #	Also, in the case of an opclass three instruction where 	#
    880  1.1     is # underflow was disabled and the trace exception was enabled, this	#
    881  1.1     is # handler must exit through the "callout" _real_trace().		#
    882  1.1     is #									#
    883  1.1     is #########################################################################
    884  1.1     is 
    885  1.1     is 	global		_fpsp_unfl
    886  1.1     is _fpsp_unfl:
    887  1.1     is 
    888  1.1     is #$#	sub.l		&24,%sp			# make room for src/dst
    889  1.1     is 
    890  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
    891  1.1     is 
    892  1.1     is 	fsave		FP_SRC(%a6)		# grab the "busy" frame
    893  1.1     is 
    894  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    895  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
    896  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
    897  1.1     is 
    898  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
    899  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
    900  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
    901  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
    902  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
    903  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
    904  1.1     is 
    905  1.1     is ##############################################################################
    906  1.1     is 
    907  1.1     is 	btst		&0x5,EXC_CMDREG(%a6)	# is instr an fmove out?
    908  1.1     is 	bne.w		funfl_out
    909  1.1     is 
    910  1.1     is 
    911  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    912  1.1     is 	bsr.l		fix_skewed_ops		# fix src op
    913  1.1     is 
    914  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    915  1.1     is 	bsr.l		set_tag_x		# tag the operand type
    916  1.1     is 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
    917  1.1     is 
    918  1.1     is # bit five of the fp ext word separates the monadic and dyadic operations
    919  1.1     is # that can pass through fpsp_unfl(). remember that fcmp, and ftst
    920  1.1     is # will never take this exception.
    921  1.1     is 	btst		&0x5,1+EXC_CMDREG(%a6)	# is op monadic or dyadic?
    922  1.1     is 	beq.b		funfl_extract		# monadic
    923  1.1     is 
    924  1.1     is # now, what's left that's not dyadic is fsincos. we can distinguish it
    925  1.1     is # from all dyadics by the '0110xxx pattern
    926  1.1     is 	btst		&0x4,1+EXC_CMDREG(%a6)	# is op an fsincos?
    927  1.1     is 	bne.b		funfl_extract		# yes
    928  1.1     is 
    929  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
    930  1.1     is 	bsr.l		load_fpn2		# load dst into FP_DST
    931  1.1     is 
    932  1.1     is 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
    933  1.1     is 	bsr.l		set_tag_x		# tag the operand type
    934  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
    935  1.1     is 	bne.b		funfl_op2_done		# no
    936  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
    937  1.1     is funfl_op2_done:
    938  1.1     is 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
    939  1.1     is 
    940  1.1     is funfl_extract:
    941  1.1     is 
    942  1.1     is #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
    943  1.1     is #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
    944  1.1     is #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
    945  1.1     is #$#	mov.l		FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
    946  1.1     is #$#	mov.l		FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
    947  1.1     is #$#	mov.l		FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
    948  1.1     is 
    949  1.1     is 	clr.l		%d0
    950  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
    951  1.1     is 
    952  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
    953  1.1     is 	andi.w		&0x007f,%d1		# extract extension
    954  1.1     is 
    955  1.1     is 	andi.l		&0x00ff01ff,USER_FPSR(%a6)
    956  1.1     is 
    957  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
    958  1.1     is 	fmov.l		&0x0,%fpsr
    959  1.1     is 
    960  1.1     is 	lea		FP_SRC(%a6),%a0
    961  1.1     is 	lea		FP_DST(%a6),%a1
    962  1.1     is 
    963  1.1     is # maybe we can make these entry points ONLY the OVFL entry points of each routine.
    964  1.1     is 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
    965  1.1     is 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
    966  1.1     is 
    967  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
    968  1.1     is 	bsr.l		store_fpreg
    969  1.1     is 
    970  1.1     is # The `060 FPU multiplier hardware is such that if the result of a
    971  1.1     is # multiply operation is the smallest possible normalized number
    972  1.1     is # (0x00000000_80000000_00000000), then the machine will take an
    973  1.1     is # underflow exception. Since this is incorrect, we need to check
    974  1.1     is # if our emulation, after re-doing the operation, decided that
    975  1.1     is # no underflow was called for. We do these checks only in
    976  1.1     is # funfl_{unfl,inex}_on() because w/ both exceptions disabled, this
    977  1.1     is # special case will simply exit gracefully with the correct result.
    978  1.1     is 
    979  1.1     is # the exceptional possibilities we have left ourselves with are ONLY overflow
    980  1.1     is # and inexact. and, the inexact is such that overflow occurred and was disabled
    981  1.1     is # but inexact was enabled.
    982  1.1     is 	btst		&unfl_bit,FPCR_ENABLE(%a6)
    983  1.1     is 	bne.b		funfl_unfl_on
    984  1.1     is 
    985  1.1     is funfl_chkinex:
    986  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6)
    987  1.1     is 	bne.b		funfl_inex_on
    988  1.1     is 
    989  1.1     is funfl_exit:
    990  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    991  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    992  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    993  1.1     is 
    994  1.1     is 	unlk		%a6
    995  1.1     is #$#	add.l		&24,%sp
    996  1.1     is 	bra.l		_fpsp_done
    997  1.1     is 
    998  1.1     is # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
    999  1.1     is # in fp1 (don't forget to save fp0). what to do now?
   1000  1.1     is # well, we simply have to get to go to _real_unfl()!
   1001  1.1     is funfl_unfl_on:
   1002  1.1     is 
   1003  1.1     is # The `060 FPU multiplier hardware is such that if the result of a
   1004  1.1     is # multiply operation is the smallest possible normalized number
   1005  1.1     is # (0x00000000_80000000_00000000), then the machine will take an
   1006  1.1     is # underflow exception. Since this is incorrect, we check here to see
   1007  1.1     is # if our emulation, after re-doing the operation, decided that
   1008  1.1     is # no underflow was called for.
   1009  1.1     is 	btst		&unfl_bit,FPSR_EXCEPT(%a6)
   1010  1.1     is 	beq.w		funfl_chkinex
   1011  1.1     is 
   1012  1.1     is funfl_unfl_on2:
   1013  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
   1014  1.1     is 
   1015  1.1     is 	mov.w		&0xe003,2+FP_SRC(%a6) 	# save exc status
   1016  1.1     is 
   1017  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   1018  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1019  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1020  1.1     is 
   1021  1.1     is 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
   1022  1.1     is 
   1023  1.1     is 	unlk		%a6
   1024  1.1     is 
   1025  1.1     is 	bra.l		_real_unfl
   1026  1.1     is 
   1027  1.1     is # undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
   1028  1.1     is # we must jump to real_inex().
   1029  1.1     is funfl_inex_on:
   1030  1.1     is 
   1031  1.1     is # The `060 FPU multiplier hardware is such that if the result of a
   1032  1.1     is # multiply operation is the smallest possible normalized number
   1033  1.1     is # (0x00000000_80000000_00000000), then the machine will take an
   1034  1.1     is # underflow exception.
   1035  1.1     is # But, whether bogus or not, if inexact is enabled AND it occurred,
   1036  1.1     is # then we have to branch to real_inex.
   1037  1.1     is 
   1038  1.1     is 	btst		&inex2_bit,FPSR_EXCEPT(%a6)
   1039  1.1     is 	beq.w		funfl_exit
   1040  1.1     is 
   1041  1.1     is funfl_inex_on2:
   1042  1.1     is 
   1043  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6) 	# save EXOP to stack
   1044  1.1     is 
   1045  1.1     is 	mov.b		&0xc4,1+EXC_VOFF(%a6)	# vector offset = 0xc4
   1046  1.1     is 	mov.w		&0xe001,2+FP_SRC(%a6) 	# save exc status
   1047  1.1     is 
   1048  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   1049  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1050  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1051  1.1     is 
   1052  1.1     is 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
   1053  1.1     is 
   1054  1.1     is 	unlk		%a6
   1055  1.1     is 
   1056  1.1     is 	bra.l		_real_inex
   1057  1.1     is 
   1058  1.1     is #######################################################################
   1059  1.1     is funfl_out:
   1060  1.1     is 
   1061  1.1     is 
   1062  1.1     is #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
   1063  1.1     is #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
   1064  1.1     is #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
   1065  1.1     is 
   1066  1.1     is # the src operand is definitely a NORM(!), so tag it as such
   1067  1.1     is 	mov.b		&NORM,STAG(%a6)		# set src optype tag
   1068  1.1     is 
   1069  1.1     is 	clr.l		%d0
   1070  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
   1071  1.1     is 
   1072  1.1     is 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero all but accured field
   1073  1.1     is 
   1074  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
   1075  1.1     is 	fmov.l		&0x0,%fpsr
   1076  1.1     is 
   1077  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   1078  1.1     is 
   1079  1.1     is 	bsr.l		fout
   1080  1.1     is 
   1081  1.1     is 	btst		&unfl_bit,FPCR_ENABLE(%a6)
   1082  1.1     is 	bne.w		funfl_unfl_on2
   1083  1.1     is 
   1084  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6)
   1085  1.1     is 	bne.w		funfl_inex_on2
   1086  1.1     is 
   1087  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   1088  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1089  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1090  1.1     is 
   1091  1.1     is 	unlk		%a6
   1092  1.1     is #$#	add.l		&24,%sp
   1093  1.1     is 
   1094  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   1095  1.1     is 	beq.l		_fpsp_done		# no
   1096  1.1     is 
   1097  1.1     is 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
   1098  1.1     is 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
   1099  1.1     is 	bra.l		_real_trace
   1100  1.1     is 
   1101  1.1     is #########################################################################
   1102  1.1     is # XDEF ****************************************************************	#
   1103  1.1     is #	_fpsp_unsupp(): 060FPSP entry point for FP "Unimplemented	#
   1104  1.1     is #		        Data Type" exception.				#
   1105  1.1     is #									#
   1106  1.1     is #	This handler should be the first code executed upon taking the	#
   1107  1.1     is #	FP Unimplemented Data Type exception in an operating system.	#
   1108  1.1     is #									#
   1109  1.1     is # XREF ****************************************************************	#
   1110  1.1     is #	_imem_read_{word,long}() - read instruction word/longword	#
   1111  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
   1112  1.1     is #	set_tag_x() - determine optype of src/dst operands		#
   1113  1.1     is #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   1114  1.1     is #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
   1115  1.1     is #	load_fpn2() - load dst operand from FP regfile			#
   1116  1.1     is #	load_fpn1() - load src operand from FP regfile			#
   1117  1.1     is #	fout() - emulate an opclass 3 instruction			#
   1118  1.1     is #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
   1119  1.1     is #	_real_inex() - "callout" to operating system inexact handler	#
   1120  1.1     is #	_fpsp_done() - "callout" for exit; work all done		#
   1121  1.1     is #	_real_trace() - "callout" for Trace enabled exception		#
   1122  1.1     is #	funimp_skew() - adjust fsave src ops to "incorrect" value	#
   1123  1.1     is #	_real_snan() - "callout" for SNAN exception			#
   1124  1.1     is #	_real_operr() - "callout" for OPERR exception			#
   1125  1.1     is #	_real_ovfl() - "callout" for OVFL exception			#
   1126  1.1     is #	_real_unfl() - "callout" for UNFL exception			#
   1127  1.1     is #	get_packed() - fetch packed operand from memory			#
   1128  1.1     is #									#
   1129  1.1     is # INPUT ***************************************************************	#
   1130  1.1     is #	- The system stack contains the "Unimp Data Type" stk frame	#
   1131  1.1     is #	- The fsave frame contains the ssrc op (for UNNORM/DENORM)	#
   1132  1.1     is # 									#
   1133  1.1     is # OUTPUT **************************************************************	#
   1134  1.1     is #	If Inexact exception (opclass 3):				#
   1135  1.1     is #	- The system stack is changed to an Inexact exception stk frame	#
   1136  1.1     is #	If SNAN exception (opclass 3):					#
   1137  1.1     is #	- The system stack is changed to an SNAN exception stk frame	#
   1138  1.1     is #	If OPERR exception (opclass 3):					#
   1139  1.1     is #	- The system stack is changed to an OPERR exception stk frame	#
   1140  1.1     is #	If OVFL exception (opclass 3):					#
   1141  1.1     is #	- The system stack is changed to an OVFL exception stk frame	#
   1142  1.1     is #	If UNFL exception (opclass 3):					#
   1143  1.1     is #	- The system stack is changed to an UNFL exception stack frame	#
   1144  1.1     is #	If Trace exception enabled:					#
   1145  1.1     is #	- The system stack is changed to a Trace exception stack frame	#
   1146  1.1     is #	Else: (normal case)						#
   1147  1.1     is #	- Correct result has been stored as appropriate			#
   1148  1.1     is #									#
   1149  1.1     is # ALGORITHM ***********************************************************	#
   1150  1.1     is #	Two main instruction types can enter here: (1) DENORM or UNNORM	#
   1151  1.1     is # unimplemented data types. These can be either opclass 0,2 or 3 	#
   1152  1.1     is # instructions, and (2) PACKED unimplemented data format instructions	#
   1153  1.1     is # also of opclasses 0,2, or 3.						#
   1154  1.1     is #	For UNNORM/DENORM opclass 0 and 2, the handler fetches the src	#
   1155  1.1     is # operand from the fsave state frame and the dst operand (if dyadic)	#
   1156  1.1     is # from the FP register file. The instruction is then emulated by 	#
   1157  1.1     is # choosing an emulation routine from a table of routines indexed by	#
   1158  1.1     is # instruction type. Once the instruction has been emulated and result	#
   1159  1.1     is # saved, then we check to see if any enabled exceptions resulted from	#
   1160  1.1     is # instruction emulation. If none, then we exit through the "callout"	#
   1161  1.1     is # _fpsp_done(). If there is an enabled FP exception, then we insert	#
   1162  1.1     is # this exception into the FPU in the fsave state frame and then exit	#
   1163  1.1     is # through _fpsp_done().							#
   1164  1.1     is #	PACKED opclass 0 and 2 is similar in how the instruction is	#
   1165  1.1     is # emulated and exceptions handled. The differences occur in how the	#
   1166  1.1     is # handler loads the packed op (by calling get_packed() routine) and	#
   1167  1.1     is # by the fact that a Trace exception could be pending for PACKED ops.	#
   1168  1.1     is # If a Trace exception is pending, then the current exception stack	#
   1169  1.1     is # frame is changed to a Trace exception stack frame and an exit is	#
   1170  1.1     is # made through _real_trace().						#
   1171  1.1     is #	For UNNORM/DENORM opclass 3, the actual move out to memory is	#
   1172  1.1     is # performed by calling the routine fout(). If no exception should occur	#
   1173  1.1     is # as the result of emulation, then an exit either occurs through	#
   1174  1.1     is # _fpsp_done() or through _real_trace() if a Trace exception is pending	#
   1175  1.1     is # (a Trace stack frame must be created here, too). If an FP exception	#
   1176  1.1     is # should occur, then we must create an exception stack frame of that	#
   1177  1.1     is # type and jump to either _real_snan(), _real_operr(), _real_inex(),	#
   1178  1.1     is # _real_unfl(), or _real_ovfl() as appropriate. PACKED opclass 3 	#
   1179  1.1     is # emulation is performed in a similar manner.				#
   1180  1.1     is #									#
   1181  1.1     is #########################################################################
   1182  1.1     is 
   1183  1.1     is #
   1184  1.1     is # (1) DENORM and UNNORM (unimplemented) data types:
   1185  1.1     is #
   1186  1.1     is #				post-instruction
   1187  1.1     is #				*****************
   1188  1.1     is #				*      EA	*
   1189  1.1     is #	 pre-instruction	*		*
   1190  1.1     is # 	*****************	*****************
   1191  1.1     is #	* 0x0 *  0x0dc  *	* 0x3 *  0x0dc  *
   1192  1.1     is #	*****************	*****************
   1193  1.1     is #	*     Next	*	*     Next	*
   1194  1.1     is #	*      PC	*	*      PC	*
   1195  1.1     is #	*****************	*****************
   1196  1.1     is #	*      SR	*	*      SR	*
   1197  1.1     is #	*****************	*****************
   1198  1.1     is #
   1199  1.1     is # (2) PACKED format (unsupported) opclasses two and three:
   1200  1.1     is #	*****************
   1201  1.1     is #	*      EA	*
   1202  1.1     is #	*		*
   1203  1.1     is #	*****************
   1204  1.1     is #	* 0x2 *  0x0dc	*
   1205  1.1     is #	*****************
   1206  1.1     is #	*     Next	*
   1207  1.1     is #	*      PC	*
   1208  1.1     is #	*****************
   1209  1.1     is #	*      SR	*
   1210  1.1     is #	*****************
   1211  1.1     is #
   1212  1.1     is 	global		_fpsp_unsupp
   1213  1.1     is _fpsp_unsupp:
   1214  1.1     is 
   1215  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   1216  1.1     is 
   1217  1.1     is 	fsave		FP_SRC(%a6)		# save fp state
   1218  1.1     is 
   1219  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1220  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   1221  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   1222  1.1     is 
   1223  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode?
   1224  1.1     is 	bne.b		fu_s
   1225  1.1     is fu_u:
   1226  1.1     is 	mov.l		%usp,%a0		# fetch user stack pointer
   1227  1.1     is 	mov.l		%a0,EXC_A7(%a6)		# save on stack
   1228  1.1     is 	bra.b		fu_cont
   1229  1.1     is # if the exception is an opclass zero or two unimplemented data type
   1230  1.1     is # exception, then the a7' calculated here is wrong since it doesn't
   1231  1.1     is # stack an ea. however, we don't need an a7' for this case anyways.
   1232  1.1     is fu_s:
   1233  1.1     is 	lea		0x4+EXC_EA(%a6),%a0	# load old a7'
   1234  1.1     is 	mov.l		%a0,EXC_A7(%a6)		# save on stack
   1235  1.1     is 
   1236  1.1     is fu_cont:
   1237  1.1     is 
   1238  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
   1239  1.1     is # the FPIAR should be set correctly for ALL exceptions passing through
   1240  1.1     is # this point.
   1241  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   1242  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   1243  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   1244  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   1245  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
   1246  1.1     is 
   1247  1.1     is ############################
   1248  1.1     is 
   1249  1.1     is 	clr.b		SPCOND_FLG(%a6)		# clear special condition flag
   1250  1.1     is 
   1251  1.1     is # Separate opclass three (fpn-to-mem) ops since they have a different
   1252  1.1     is # stack frame and protocol.
   1253  1.1     is 	btst		&0x5,EXC_CMDREG(%a6)	# is it an fmove out?
   1254  1.1     is 	bne.w		fu_out			# yes
   1255  1.1     is 
   1256  1.1     is # Separate packed opclass two instructions.
   1257  1.1     is 	bfextu		EXC_CMDREG(%a6){&0:&6},%d0
   1258  1.1     is 	cmpi.b		%d0,&0x13
   1259  1.1     is 	beq.w		fu_in_pack
   1260  1.1     is 
   1261  1.1     is 
   1262  1.1     is # I'm not sure at this point what FPSR bits are valid for this instruction.
   1263  1.1     is # so, since the emulation routines re-create them anyways, zero exception field
   1264  1.1     is 	andi.l		&0x00ff00ff,USER_FPSR(%a6) # zero exception field
   1265  1.1     is 
   1266  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
   1267  1.1     is 	fmov.l		&0x0,%fpsr
   1268  1.1     is 
   1269  1.1     is # Opclass two w/ memory-to-fpn operation will have an incorrect extended
   1270  1.1     is # precision format if the src format was single or double and the
   1271  1.1     is # source data type was an INF, NAN, DENORM, or UNNORM
   1272  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to input
   1273  1.1     is 	bsr.l		fix_skewed_ops
   1274  1.1     is 
   1275  1.1     is # we don't know whether the src operand or the dst operand (or both) is the
   1276  1.1     is # UNNORM or DENORM. call the function that tags the operand type. if the
   1277  1.1     is # input is an UNNORM, then convert it to a NORM, DENORM, or ZERO.
   1278  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   1279  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   1280  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   1281  1.1     is 	bne.b		fu_op2			# no
   1282  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   1283  1.1     is 
   1284  1.1     is fu_op2:
   1285  1.1     is 	mov.b		%d0,STAG(%a6)		# save src optype tag
   1286  1.1     is 
   1287  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1288  1.1     is 
   1289  1.1     is # bit five of the fp extension word separates the monadic and dyadic operations
   1290  1.1     is # at this point
   1291  1.1     is 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   1292  1.1     is 	beq.b		fu_extract		# monadic
   1293  1.1     is 	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?
   1294  1.1     is 	beq.b		fu_extract		# yes, so it's monadic, too
   1295  1.1     is 
   1296  1.1     is 	bsr.l		load_fpn2		# load dst into FP_DST
   1297  1.1     is 
   1298  1.1     is 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   1299  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   1300  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   1301  1.1     is 	bne.b		fu_op2_done		# no
   1302  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   1303  1.1     is fu_op2_done:
   1304  1.1     is 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
   1305  1.1     is 
   1306  1.1     is fu_extract:
   1307  1.1     is 	clr.l		%d0
   1308  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   1309  1.1     is 
   1310  1.1     is 	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
   1311  1.1     is 
   1312  1.1     is 	lea		FP_SRC(%a6),%a0
   1313  1.1     is 	lea		FP_DST(%a6),%a1
   1314  1.1     is 
   1315  1.1     is 	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
   1316  1.1     is 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   1317  1.1     is 
   1318  1.1     is #
   1319  1.1     is # Exceptions in order of precedence:
   1320  1.1     is # 	BSUN	: none
   1321  1.1     is #	SNAN	: all dyadic ops
   1322  1.1     is #	OPERR	: fsqrt(-NORM)
   1323  1.1     is #	OVFL	: all except ftst,fcmp
   1324  1.1     is #	UNFL	: all except ftst,fcmp
   1325  1.1     is #	DZ	: fdiv
   1326  1.1     is # 	INEX2	: all except ftst,fcmp
   1327  1.1     is #	INEX1	: none (packed doesn't go through here)
   1328  1.1     is #
   1329  1.1     is 
   1330  1.1     is # we determine the highest priority exception(if any) set by the
   1331  1.1     is # emulation routine that has also been enabled by the user.
   1332  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions set
   1333  1.1     is 	bne.b		fu_in_ena		# some are enabled
   1334  1.1     is 
   1335  1.1     is fu_in_cont:
   1336  1.1     is # fcmp and ftst do not store any result.
   1337  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension
   1338  1.1     is 	andi.b		&0x38,%d0		# extract bits 3-5
   1339  1.1     is 	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?
   1340  1.1     is 	beq.b		fu_in_exit		# yes
   1341  1.1     is 
   1342  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1343  1.1     is 	bsr.l		store_fpreg		# store the result
   1344  1.1     is 
   1345  1.1     is fu_in_exit:
   1346  1.1     is 
   1347  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1348  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1349  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1350  1.1     is 
   1351  1.1     is 	unlk		%a6
   1352  1.1     is 
   1353  1.1     is 	bra.l		_fpsp_done
   1354  1.1     is 
   1355  1.1     is fu_in_ena:
   1356  1.1     is 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
   1357  1.1     is 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   1358  1.1     is 	bne.b		fu_in_exc		# there is at least one set
   1359  1.1     is 
   1360  1.1     is #
   1361  1.1     is # No exceptions occurred that were also enabled. Now:
   1362  1.1     is #
   1363  1.1     is #   	if (OVFL && ovfl_disabled && inexact_enabled) {
   1364  1.1     is #	    branch to _real_inex() (even if the result was exact!);
   1365  1.1     is #     	} else {
   1366  1.1     is #	    save the result in the proper fp reg (unless the op is fcmp or ftst);
   1367  1.1     is #	    return;
   1368  1.1     is #     	}
   1369  1.1     is #
   1370  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
   1371  1.1     is 	beq.b		fu_in_cont		# no
   1372  1.1     is 
   1373  1.1     is fu_in_ovflchk:
   1374  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
   1375  1.1     is 	beq.b		fu_in_cont		# no
   1376  1.1     is 	bra.w		fu_in_exc_ovfl		# go insert overflow frame
   1377  1.1     is 
   1378  1.1     is #
   1379  1.1     is # An exception occurred and that exception was enabled:
   1380  1.1     is #
   1381  1.1     is #	shift enabled exception field into lo byte of d0;
   1382  1.1     is #	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
   1383  1.1     is #	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
   1384  1.1     is #		/*
   1385  1.1     is #		 * this is the case where we must call _real_inex() now or else
   1386  1.1     is #		 * there will be no other way to pass it the exceptional operand
   1387  1.1     is #		 */
   1388  1.1     is #		call _real_inex();
   1389  1.1     is #	} else {
   1390  1.1     is #		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
   1391  1.1     is #	}
   1392  1.1     is #
   1393  1.1     is fu_in_exc:
   1394  1.1     is 	subi.l		&24,%d0			# fix offset to be 0-8
   1395  1.1     is 	cmpi.b		%d0,&0x6		# is exception INEX? (6)
   1396  1.1     is 	bne.b		fu_in_exc_exit		# no
   1397  1.1     is 
   1398  1.1     is # the enabled exception was inexact
   1399  1.1     is 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
   1400  1.1     is 	bne.w		fu_in_exc_unfl		# yes
   1401  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
   1402  1.1     is 	bne.w		fu_in_exc_ovfl		# yes
   1403  1.1     is 
   1404  1.1     is # here, we insert the correct fsave status value into the fsave frame for the
   1405  1.1     is # corresponding exception. the operand in the fsave frame should be the original
   1406  1.1     is # src operand.
   1407  1.1     is fu_in_exc_exit:
   1408  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   1409  1.1     is 	bsr.l		funimp_skew		# skew sgl or dbl inputs
   1410  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   1411  1.1     is 
   1412  1.1     is 	mov.w		(tbl_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) # create exc status
   1413  1.1     is 
   1414  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1415  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1416  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1417  1.1     is 
   1418  1.1     is 	frestore	FP_SRC(%a6)		# restore src op
   1419  1.1     is 
   1420  1.1     is 	unlk		%a6
   1421  1.1     is 
   1422  1.1     is 	bra.l		_fpsp_done
   1423  1.1     is 
   1424  1.1     is tbl_except:
   1425  1.1     is 	short		0xe000,0xe006,0xe004,0xe005
   1426  1.1     is 	short		0xe003,0xe002,0xe001,0xe001
   1427  1.1     is 
   1428  1.1     is fu_in_exc_unfl:
   1429  1.1     is 	mov.w		&0x4,%d0
   1430  1.1     is 	bra.b		fu_in_exc_exit
   1431  1.1     is fu_in_exc_ovfl:
   1432  1.1     is 	mov.w		&0x03,%d0
   1433  1.1     is 	bra.b		fu_in_exc_exit
   1434  1.1     is 
   1435  1.1     is # If the input operand to this operation was opclass two and a single
   1436  1.1     is # or double precision denorm, inf, or nan, the operand needs to be
   1437  1.1     is # "corrected" in order to have the proper equivalent extended precision
   1438  1.1     is # number.
   1439  1.1     is 	global		fix_skewed_ops
   1440  1.1     is fix_skewed_ops:
   1441  1.1     is 	bfextu		EXC_CMDREG(%a6){&0:&6},%d0 # extract opclass,src fmt
   1442  1.1     is 	cmpi.b		%d0,&0x11		# is class = 2 & fmt = sgl?
   1443  1.1     is 	beq.b		fso_sgl			# yes
   1444  1.1     is 	cmpi.b		%d0,&0x15		# is class = 2 & fmt = dbl?
   1445  1.1     is 	beq.b		fso_dbl			# yes
   1446  1.1     is 	rts					# no
   1447  1.1     is 
   1448  1.1     is fso_sgl:
   1449  1.1     is 	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent
   1450  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   1451  1.1     is 	cmpi.w		%d0,&0x3f80		# is |exp| == $3f80?
   1452  1.1     is 	beq.b		fso_sgl_dnrm_zero	# yes
   1453  1.1     is 	cmpi.w		%d0,&0x407f		# no; is |exp| == $407f?
   1454  1.1     is 	beq.b		fso_infnan		# yes
   1455  1.1     is 	rts					# no
   1456  1.1     is 
   1457  1.1     is fso_sgl_dnrm_zero:
   1458  1.1     is 	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit
   1459  1.1     is 	beq.b		fso_zero		# it's a skewed zero
   1460  1.1     is fso_sgl_dnrm:
   1461  1.1     is # here, we count on norm not to alter a0...
   1462  1.1     is 	bsr.l		norm			# normalize mantissa
   1463  1.1     is 	neg.w		%d0			# -shft amt
   1464  1.1     is 	addi.w		&0x3f81,%d0		# adjust new exponent
   1465  1.1     is 	andi.w		&0x8000,LOCAL_EX(%a0) 	# clear old exponent
   1466  1.1     is 	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent
   1467  1.1     is 	rts
   1468  1.1     is 
   1469  1.1     is fso_zero:
   1470  1.1     is 	andi.w		&0x8000,LOCAL_EX(%a0)	# clear bogus exponent
   1471  1.1     is 	rts
   1472  1.1     is 
   1473  1.1     is fso_infnan:
   1474  1.1     is 	andi.b		&0x7f,LOCAL_HI(%a0) 	# clear j-bit
   1475  1.1     is 	ori.w		&0x7fff,LOCAL_EX(%a0)	# make exponent = $7fff
   1476  1.1     is 	rts
   1477  1.1     is 
   1478  1.1     is fso_dbl:
   1479  1.1     is 	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent
   1480  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   1481  1.1     is 	cmpi.w		%d0,&0x3c00		# is |exp| == $3c00?
   1482  1.1     is 	beq.b		fso_dbl_dnrm_zero	# yes
   1483  1.1     is 	cmpi.w		%d0,&0x43ff		# no; is |exp| == $43ff?
   1484  1.1     is 	beq.b		fso_infnan		# yes
   1485  1.1     is 	rts					# no
   1486  1.1     is 
   1487  1.1     is fso_dbl_dnrm_zero:
   1488  1.1     is 	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit
   1489  1.1     is 	bne.b		fso_dbl_dnrm		# it's a skewed denorm
   1490  1.1     is 	tst.l		LOCAL_LO(%a0)		# is it a zero?
   1491  1.1     is 	beq.b		fso_zero		# yes
   1492  1.1     is fso_dbl_dnrm:
   1493  1.1     is # here, we count on norm not to alter a0...
   1494  1.1     is 	bsr.l		norm			# normalize mantissa
   1495  1.1     is 	neg.w		%d0			# -shft amt
   1496  1.1     is 	addi.w		&0x3c01,%d0		# adjust new exponent
   1497  1.1     is 	andi.w		&0x8000,LOCAL_EX(%a0) 	# clear old exponent
   1498  1.1     is 	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent
   1499  1.1     is 	rts
   1500  1.1     is 
   1501  1.1     is #################################################################
   1502  1.1     is 
   1503  1.1     is # fmove out took an unimplemented data type exception.
   1504  1.1     is # the src operand is in FP_SRC. Call _fout() to write out the result and
   1505  1.1     is # to determine which exceptions, if any, to take.
   1506  1.1     is fu_out:
   1507  1.1     is 
   1508  1.1     is # Separate packed move outs from the UNNORM and DENORM move outs.
   1509  1.1     is 	bfextu		EXC_CMDREG(%a6){&3:&3},%d0
   1510  1.1     is 	cmpi.b		%d0,&0x3
   1511  1.1     is 	beq.w		fu_out_pack
   1512  1.1     is 	cmpi.b		%d0,&0x7
   1513  1.1     is 	beq.w		fu_out_pack
   1514  1.1     is 
   1515  1.1     is 
   1516  1.1     is # I'm not sure at this point what FPSR bits are valid for this instruction.
   1517  1.1     is # so, since the emulation routines re-create them anyways, zero exception field.
   1518  1.1     is # fmove out doesn't affect ccodes.
   1519  1.1     is 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
   1520  1.1     is 
   1521  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
   1522  1.1     is 	fmov.l		&0x0,%fpsr
   1523  1.1     is 
   1524  1.1     is # the src can ONLY be a DENORM or an UNNORM! so, don't make any big subroutine
   1525  1.1     is # call here. just figure out what it is...
   1526  1.1     is 	mov.w		FP_SRC_EX(%a6),%d0	# get exponent
   1527  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   1528  1.1     is 	beq.b		fu_out_denorm		# it's a DENORM
   1529  1.1     is 
   1530  1.1     is 	lea		FP_SRC(%a6),%a0
   1531  1.1     is 	bsr.l		unnorm_fix		# yes; fix it
   1532  1.1     is 
   1533  1.1     is 	mov.b		%d0,STAG(%a6)
   1534  1.1     is 
   1535  1.1     is 	bra.b		fu_out_cont
   1536  1.1     is fu_out_denorm:
   1537  1.1     is 	mov.b		&DENORM,STAG(%a6)
   1538  1.1     is fu_out_cont:
   1539  1.1     is 
   1540  1.1     is 	clr.l		%d0
   1541  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   1542  1.1     is 
   1543  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   1544  1.1     is 
   1545  1.1     is 	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes
   1546  1.1     is 	bsr.l		fout			# call fmove out routine
   1547  1.1     is 
   1548  1.1     is # Exceptions in order of precedence:
   1549  1.1     is # 	BSUN	: none
   1550  1.1     is #	SNAN	: none
   1551  1.1     is #	OPERR	: fmove.{b,w,l} out of large UNNORM
   1552  1.1     is #	OVFL	: fmove.{s,d}
   1553  1.1     is #	UNFL	: fmove.{s,d,x}
   1554  1.1     is #	DZ	: none
   1555  1.1     is # 	INEX2	: all
   1556  1.1     is #	INEX1	: none (packed doesn't travel through here)
   1557  1.1     is 
   1558  1.1     is # determine the highest priority exception(if any) set by the
   1559  1.1     is # emulation routine that has also been enabled by the user.
   1560  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   1561  1.1     is 	bne.w		fu_out_ena		# some are enabled
   1562  1.1     is 
   1563  1.1     is fu_out_done:
   1564  1.1     is 
   1565  1.1     is 	mov.l		EXC_A6(%a6),(%a6)	# in case a6 changed
   1566  1.1     is 
   1567  1.1     is # on extended precision opclass three instructions using pre-decrement or
   1568  1.1     is # post-increment addressing mode, the address register is not updated. is the
   1569  1.1     is # address register was the stack pointer used from user mode, then let's update
   1570  1.1     is # it here. if it was used from supervisor mode, then we have to handle this
   1571  1.1     is # as a special case.
   1572  1.1     is 	btst		&0x5,EXC_SR(%a6)
   1573  1.1     is 	bne.b		fu_out_done_s
   1574  1.1     is 
   1575  1.1     is 	mov.l		EXC_A7(%a6),%a0		# restore a7
   1576  1.1     is 	mov.l		%a0,%usp
   1577  1.1     is 
   1578  1.1     is fu_out_done_cont:
   1579  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1580  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1581  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1582  1.1     is 
   1583  1.1     is 	unlk		%a6
   1584  1.1     is 
   1585  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   1586  1.1     is 	bne.b		fu_out_trace		# yes
   1587  1.1     is 
   1588  1.1     is 	bra.l		_fpsp_done
   1589  1.1     is 
   1590  1.1     is # is the ea mode pre-decrement of the stack pointer from supervisor mode?
   1591  1.1     is # ("fmov.x fpm,-(a7)") if so,
   1592  1.1     is fu_out_done_s:
   1593  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   1594  1.1     is 	bne.b		fu_out_done_cont
   1595  1.1     is 
   1596  1.1     is # the extended precision result is still in fp0. but, we need to save it
   1597  1.1     is # somewhere on the stack until we can copy it to its final resting place.
   1598  1.1     is # here, we're counting on the top of the stack to be the old place-holders
   1599  1.1     is # for fp0/fp1 which have already been restored. that way, we can write
   1600  1.1     is # over those destinations with the shifted stack frame.
   1601  1.1     is 	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack
   1602  1.1     is 
   1603  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1604  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1605  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1606  1.1     is 
   1607  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   1608  1.1     is 
   1609  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   1610  1.1     is 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   1611  1.1     is 
   1612  1.1     is # now, copy the result to the proper place on the stack
   1613  1.1     is 	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
   1614  1.1     is 	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
   1615  1.1     is 	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
   1616  1.1     is 
   1617  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   1618  1.1     is 
   1619  1.1     is 	btst		&0x7,(%sp)
   1620  1.1     is 	bne.b		fu_out_trace
   1621  1.1     is 
   1622  1.1     is 	bra.l		_fpsp_done
   1623  1.1     is 
   1624  1.1     is fu_out_ena:
   1625  1.1     is 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
   1626  1.1     is 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   1627  1.1     is 	bne.b		fu_out_exc		# there is at least one set
   1628  1.1     is 
   1629  1.1     is # no exceptions were set.
   1630  1.1     is # if a disabled overflow occurred and inexact was enabled but the result
   1631  1.1     is # was exact, then a branch to _real_inex() is made.
   1632  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
   1633  1.1     is 	beq.w		fu_out_done		# no
   1634  1.1     is 
   1635  1.1     is fu_out_ovflchk:
   1636  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
   1637  1.1     is 	beq.w		fu_out_done		# no
   1638  1.1     is 	bra.w		fu_inex			# yes
   1639  1.1     is 
   1640  1.1     is #
   1641  1.1     is # The fp move out that took the "Unimplemented Data Type" exception was
   1642  1.1     is # being traced. Since the stack frames are similar, get the "current" PC
   1643  1.1     is # from FPIAR and put it in the trace stack frame then jump to _real_trace().
   1644  1.1     is #
   1645  1.1     is #		  UNSUPP FRAME		   TRACE FRAME
   1646  1.1     is # 		*****************	*****************
   1647  1.1     is #		*      EA	*	*    Current	*
   1648  1.1     is #		*		*	*      PC	*
   1649  1.1     is #		*****************	*****************
   1650  1.1     is #		* 0x3 *  0x0dc	*	* 0x2 *  0x024	*
   1651  1.1     is #		*****************	*****************
   1652  1.1     is #		*     Next	*	*     Next	*
   1653  1.1     is #		*      PC	*	*      PC	*
   1654  1.1     is #		*****************	*****************
   1655  1.1     is #		*      SR	*	*      SR	*
   1656  1.1     is #		*****************	*****************
   1657  1.1     is #
   1658  1.1     is fu_out_trace:
   1659  1.1     is 	mov.w		&0x2024,0x6(%sp)
   1660  1.1     is 	fmov.l		%fpiar,0x8(%sp)
   1661  1.1     is 	bra.l		_real_trace
   1662  1.1     is 
   1663  1.1     is # an exception occurred and that exception was enabled.
   1664  1.1     is fu_out_exc:
   1665  1.1     is 	subi.l		&24,%d0			# fix offset to be 0-8
   1666  1.1     is 
   1667  1.1     is # we don't mess with the existing fsave frame. just re-insert it and
   1668  1.1     is # jump to the "_real_{}()" handler...
   1669  1.1     is 	mov.w		(tbl_fu_out.b,%pc,%d0.w*2),%d0
   1670  1.1     is 	jmp		(tbl_fu_out.b,%pc,%d0.w*1)
   1671  1.1     is 
   1672  1.1     is 	swbeg		&0x8
   1673  1.1     is tbl_fu_out:
   1674  1.1     is 	short		tbl_fu_out	- tbl_fu_out	# BSUN can't happen
   1675  1.1     is 	short		tbl_fu_out 	- tbl_fu_out	# SNAN can't happen
   1676  1.1     is 	short		fu_operr	- tbl_fu_out	# OPERR
   1677  1.1     is 	short		fu_ovfl 	- tbl_fu_out	# OVFL
   1678  1.1     is 	short		fu_unfl 	- tbl_fu_out	# UNFL
   1679  1.1     is 	short		tbl_fu_out	- tbl_fu_out	# DZ can't happen
   1680  1.1     is 	short		fu_inex 	- tbl_fu_out	# INEX2
   1681  1.1     is 	short		tbl_fu_out	- tbl_fu_out	# INEX1 won't make it here
   1682  1.1     is 
   1683  1.1     is # for snan,operr,ovfl,unfl, src op is still in FP_SRC so just
   1684  1.1     is # frestore it.
   1685  1.1     is fu_snan:
   1686  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1687  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1688  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1689  1.1     is 
   1690  1.1     is 	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd8
   1691  1.1     is 	mov.w		&0xe006,2+FP_SRC(%a6)
   1692  1.1     is 
   1693  1.1     is 	frestore	FP_SRC(%a6)
   1694  1.1     is 
   1695  1.1     is 	unlk		%a6
   1696  1.1     is 
   1697  1.1     is 
   1698  1.1     is 	bra.l		_real_snan
   1699  1.1     is 
   1700  1.1     is fu_operr:
   1701  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1702  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1703  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1704  1.1     is 
   1705  1.1     is 	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0
   1706  1.1     is 	mov.w		&0xe004,2+FP_SRC(%a6)
   1707  1.1     is 
   1708  1.1     is 	frestore	FP_SRC(%a6)
   1709  1.1     is 
   1710  1.1     is 	unlk		%a6
   1711  1.1     is 
   1712  1.1     is 
   1713  1.1     is 	bra.l		_real_operr
   1714  1.1     is 
   1715  1.1     is fu_ovfl:
   1716  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
   1717  1.1     is 
   1718  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1719  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1720  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1721  1.1     is 
   1722  1.1     is 	mov.w		&0x30d4,EXC_VOFF(%a6)	# vector offset = 0xd4
   1723  1.1     is 	mov.w		&0xe005,2+FP_SRC(%a6)
   1724  1.1     is 
   1725  1.1     is 	frestore	FP_SRC(%a6)		# restore EXOP
   1726  1.1     is 
   1727  1.1     is 	unlk		%a6
   1728  1.1     is 
   1729  1.1     is 	bra.l		_real_ovfl
   1730  1.1     is 
   1731  1.1     is # underflow can happen for extended precision. extended precision opclass
   1732  1.1     is # three instruction exceptions don't update the stack pointer. so, if the
   1733  1.1     is # exception occurred from user mode, then simply update a7 and exit normally.
   1734  1.1     is # if the exception occurred from supervisor mode, check if
   1735  1.1     is fu_unfl:
   1736  1.1     is 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
   1737  1.1     is 
   1738  1.1     is 	btst		&0x5,EXC_SR(%a6)
   1739  1.1     is 	bne.w		fu_unfl_s
   1740  1.1     is 
   1741  1.1     is 	mov.l		EXC_A7(%a6),%a0		# restore a7 whether we need
   1742  1.1     is 	mov.l		%a0,%usp		# to or not...
   1743  1.1     is 
   1744  1.1     is fu_unfl_cont:
   1745  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
   1746  1.1     is 
   1747  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1748  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1749  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1750  1.1     is 
   1751  1.1     is 	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc
   1752  1.1     is 	mov.w		&0xe003,2+FP_SRC(%a6)
   1753  1.1     is 
   1754  1.1     is 	frestore	FP_SRC(%a6)		# restore EXOP
   1755  1.1     is 
   1756  1.1     is 	unlk		%a6
   1757  1.1     is 
   1758  1.1     is 	bra.l		_real_unfl
   1759  1.1     is 
   1760  1.1     is fu_unfl_s:
   1761  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was the <ea> mode -(sp)?
   1762  1.1     is 	bne.b		fu_unfl_cont
   1763  1.1     is 
   1764  1.1     is # the extended precision result is still in fp0. but, we need to save it
   1765  1.1     is # somewhere on the stack until we can copy it to its final resting place
   1766  1.1     is # (where the exc frame is currently). make sure it's not at the top of the
   1767  1.1     is # frame or it will get overwritten when the exc stack frame is shifted "down".
   1768  1.1     is 	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack
   1769  1.1     is 	fmovm.x		&0x40,FP_DST(%a6)	# put EXOP on stack
   1770  1.1     is 
   1771  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1772  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1773  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1774  1.1     is 
   1775  1.1     is 	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc
   1776  1.1     is 	mov.w		&0xe003,2+FP_DST(%a6)
   1777  1.1     is 
   1778  1.1     is 	frestore	FP_DST(%a6)		# restore EXOP
   1779  1.1     is 
   1780  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   1781  1.1     is 
   1782  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   1783  1.1     is 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   1784  1.1     is 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   1785  1.1     is 
   1786  1.1     is # now, copy the result to the proper place on the stack
   1787  1.1     is 	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
   1788  1.1     is 	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
   1789  1.1     is 	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
   1790  1.1     is 
   1791  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   1792  1.1     is 
   1793  1.1     is 	bra.l		_real_unfl
   1794  1.1     is 
   1795  1.1     is # fmove in and out enter here.
   1796  1.1     is fu_inex:
   1797  1.1     is 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
   1798  1.1     is 
   1799  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1800  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1801  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1802  1.1     is 
   1803  1.1     is 	mov.w		&0x30c4,EXC_VOFF(%a6)	# vector offset = 0xc4
   1804  1.1     is 	mov.w		&0xe001,2+FP_SRC(%a6)
   1805  1.1     is 
   1806  1.1     is 	frestore	FP_SRC(%a6)		# restore EXOP
   1807  1.1     is 
   1808  1.1     is 	unlk		%a6
   1809  1.1     is 
   1810  1.1     is 
   1811  1.1     is 	bra.l		_real_inex
   1812  1.1     is 
   1813  1.1     is #########################################################################
   1814  1.1     is #########################################################################
   1815  1.1     is fu_in_pack:
   1816  1.1     is 
   1817  1.1     is 
   1818  1.1     is # I'm not sure at this point what FPSR bits are valid for this instruction.
   1819  1.1     is # so, since the emulation routines re-create them anyways, zero exception field
   1820  1.1     is 	andi.l		&0x0ff00ff,USER_FPSR(%a6) # zero exception field
   1821  1.1     is 
   1822  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
   1823  1.1     is 	fmov.l		&0x0,%fpsr
   1824  1.1     is 
   1825  1.1     is 	bsr.l		get_packed		# fetch packed src operand
   1826  1.1     is 
   1827  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   1828  1.1     is 	bsr.l		set_tag_x		# set src optype tag
   1829  1.1     is 
   1830  1.1     is 	mov.b		%d0,STAG(%a6)		# save src optype tag
   1831  1.1     is 
   1832  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1833  1.1     is 
   1834  1.1     is # bit five of the fp extension word separates the monadic and dyadic operations
   1835  1.1     is # at this point
   1836  1.1     is 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   1837  1.1     is 	beq.b		fu_extract_p		# monadic
   1838  1.1     is 	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?
   1839  1.1     is 	beq.b		fu_extract_p		# yes, so it's monadic, too
   1840  1.1     is 
   1841  1.1     is 	bsr.l		load_fpn2		# load dst into FP_DST
   1842  1.1     is 
   1843  1.1     is 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   1844  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   1845  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   1846  1.1     is 	bne.b		fu_op2_done_p		# no
   1847  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   1848  1.1     is fu_op2_done_p:
   1849  1.1     is 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
   1850  1.1     is 
   1851  1.1     is fu_extract_p:
   1852  1.1     is 	clr.l		%d0
   1853  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   1854  1.1     is 
   1855  1.1     is 	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
   1856  1.1     is 
   1857  1.1     is 	lea		FP_SRC(%a6),%a0
   1858  1.1     is 	lea		FP_DST(%a6),%a1
   1859  1.1     is 
   1860  1.1     is 	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
   1861  1.1     is 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   1862  1.1     is 
   1863  1.1     is #
   1864  1.1     is # Exceptions in order of precedence:
   1865  1.1     is # 	BSUN	: none
   1866  1.1     is #	SNAN	: all dyadic ops
   1867  1.1     is #	OPERR	: fsqrt(-NORM)
   1868  1.1     is #	OVFL	: all except ftst,fcmp
   1869  1.1     is #	UNFL	: all except ftst,fcmp
   1870  1.1     is #	DZ	: fdiv
   1871  1.1     is # 	INEX2	: all except ftst,fcmp
   1872  1.1     is #	INEX1	: all
   1873  1.1     is #
   1874  1.1     is 
   1875  1.1     is # we determine the highest priority exception(if any) set by the
   1876  1.1     is # emulation routine that has also been enabled by the user.
   1877  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   1878  1.1     is 	bne.w		fu_in_ena_p		# some are enabled
   1879  1.1     is 
   1880  1.1     is fu_in_cont_p:
   1881  1.1     is # fcmp and ftst do not store any result.
   1882  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension
   1883  1.1     is 	andi.b		&0x38,%d0		# extract bits 3-5
   1884  1.1     is 	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?
   1885  1.1     is 	beq.b		fu_in_exit_p		# yes
   1886  1.1     is 
   1887  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1888  1.1     is 	bsr.l		store_fpreg		# store the result
   1889  1.1     is 
   1890  1.1     is fu_in_exit_p:
   1891  1.1     is 
   1892  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   1893  1.1     is 	bne.w		fu_in_exit_s_p		# supervisor
   1894  1.1     is 
   1895  1.1     is 	mov.l		EXC_A7(%a6),%a0		# update user a7
   1896  1.1     is 	mov.l		%a0,%usp
   1897  1.1     is 
   1898  1.1     is fu_in_exit_cont_p:
   1899  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1900  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1901  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1902  1.1     is 
   1903  1.1     is 	unlk		%a6			# unravel stack frame
   1904  1.1     is 
   1905  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   1906  1.1     is 	bne.w		fu_trace_p		# yes
   1907  1.1     is 
   1908  1.1     is 	bra.l		_fpsp_done		# exit to os
   1909  1.1     is 
   1910  1.1     is # the exception occurred in supervisor mode. check to see if the
   1911  1.1     is # addressing mode was (a7)+. if so, we'll need to shift the
   1912  1.1     is # stack frame "up".
   1913  1.1     is fu_in_exit_s_p:
   1914  1.1     is 	btst		&mia7_bit,SPCOND_FLG(%a6) # was ea mode (a7)+
   1915  1.1     is 	beq.b		fu_in_exit_cont_p	# no
   1916  1.1     is 
   1917  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1918  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1919  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1920  1.1     is 
   1921  1.1     is 	unlk		%a6			# unravel stack frame
   1922  1.1     is 
   1923  1.1     is # shift the stack frame "up". we don't really care about the <ea> field.
   1924  1.1     is 	mov.l		0x4(%sp),0x10(%sp)
   1925  1.1     is 	mov.l		0x0(%sp),0xc(%sp)
   1926  1.1     is 	add.l		&0xc,%sp
   1927  1.1     is 
   1928  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   1929  1.1     is 	bne.w		fu_trace_p		# yes
   1930  1.1     is 
   1931  1.1     is 	bra.l		_fpsp_done		# exit to os
   1932  1.1     is 
   1933  1.1     is fu_in_ena_p:
   1934  1.1     is 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled & set
   1935  1.1     is 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   1936  1.1     is 	bne.b		fu_in_exc_p		# at least one was set
   1937  1.1     is 
   1938  1.1     is #
   1939  1.1     is # No exceptions occurred that were also enabled. Now:
   1940  1.1     is #
   1941  1.1     is #   	if (OVFL && ovfl_disabled && inexact_enabled) {
   1942  1.1     is #	    branch to _real_inex() (even if the result was exact!);
   1943  1.1     is #     	} else {
   1944  1.1     is #	    save the result in the proper fp reg (unless the op is fcmp or ftst);
   1945  1.1     is #	    return;
   1946  1.1     is #     	}
   1947  1.1     is #
   1948  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
   1949  1.1     is 	beq.w		fu_in_cont_p		# no
   1950  1.1     is 
   1951  1.1     is fu_in_ovflchk_p:
   1952  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
   1953  1.1     is 	beq.w		fu_in_cont_p		# no
   1954  1.1     is 	bra.w		fu_in_exc_ovfl_p	# do _real_inex() now
   1955  1.1     is 
   1956  1.1     is #
   1957  1.1     is # An exception occurred and that exception was enabled:
   1958  1.1     is #
   1959  1.1     is #	shift enabled exception field into lo byte of d0;
   1960  1.1     is #	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
   1961  1.1     is #	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
   1962  1.1     is #		/*
   1963  1.1     is #		 * this is the case where we must call _real_inex() now or else
   1964  1.1     is #		 * there will be no other way to pass it the exceptional operand
   1965  1.1     is #		 */
   1966  1.1     is #		call _real_inex();
   1967  1.1     is #	} else {
   1968  1.1     is #		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
   1969  1.1     is #	}
   1970  1.1     is #
   1971  1.1     is fu_in_exc_p:
   1972  1.1     is 	subi.l		&24,%d0			# fix offset to be 0-8
   1973  1.1     is 	cmpi.b		%d0,&0x6		# is exception INEX? (6 or 7)
   1974  1.1     is 	blt.b		fu_in_exc_exit_p	# no
   1975  1.1     is 
   1976  1.1     is # the enabled exception was inexact
   1977  1.1     is 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
   1978  1.1     is 	bne.w		fu_in_exc_unfl_p	# yes
   1979  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
   1980  1.1     is 	bne.w		fu_in_exc_ovfl_p	# yes
   1981  1.1     is 
   1982  1.1     is # here, we insert the correct fsave status value into the fsave frame for the
   1983  1.1     is # corresponding exception. the operand in the fsave frame should be the original
   1984  1.1     is # src operand.
   1985  1.1     is # as a reminder for future predicted pain and agony, we are passing in fsave the
   1986  1.1     is # "non-skewed" operand for cases of sgl and dbl src INFs,NANs, and DENORMs.
   1987  1.1     is # this is INCORRECT for enabled SNAN which would give to the user the skewed SNAN!!!
   1988  1.1     is fu_in_exc_exit_p:
   1989  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   1990  1.1     is 	bne.w		fu_in_exc_exit_s_p	# supervisor
   1991  1.1     is 
   1992  1.1     is 	mov.l		EXC_A7(%a6),%a0		# update user a7
   1993  1.1     is 	mov.l		%a0,%usp
   1994  1.1     is 
   1995  1.1     is fu_in_exc_exit_cont_p:
   1996  1.1     is 	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   1997  1.1     is 
   1998  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1999  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2000  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2001  1.1     is 
   2002  1.1     is 	frestore	FP_SRC(%a6)		# restore src op
   2003  1.1     is 
   2004  1.1     is 	unlk		%a6
   2005  1.1     is 
   2006  1.1     is 	btst		&0x7,(%sp)		# is trace enabled?
   2007  1.1     is 	bne.w		fu_trace_p		# yes
   2008  1.1     is 
   2009  1.1     is 	bra.l		_fpsp_done
   2010  1.1     is 
   2011  1.1     is tbl_except_p:
   2012  1.1     is 	short		0xe000,0xe006,0xe004,0xe005
   2013  1.1     is 	short		0xe003,0xe002,0xe001,0xe001
   2014  1.1     is 
   2015  1.1     is fu_in_exc_ovfl_p:
   2016  1.1     is 	mov.w		&0x3,%d0
   2017  1.1     is 	bra.w		fu_in_exc_exit_p
   2018  1.1     is 
   2019  1.1     is fu_in_exc_unfl_p:
   2020  1.1     is 	mov.w		&0x4,%d0
   2021  1.1     is 	bra.w		fu_in_exc_exit_p
   2022  1.1     is 
   2023  1.1     is fu_in_exc_exit_s_p:
   2024  1.1     is 	btst		&mia7_bit,SPCOND_FLG(%a6)
   2025  1.1     is 	beq.b		fu_in_exc_exit_cont_p
   2026  1.1     is 
   2027  1.1     is 	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   2028  1.1     is 
   2029  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2030  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2031  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2032  1.1     is 
   2033  1.1     is 	frestore	FP_SRC(%a6)		# restore src op
   2034  1.1     is 
   2035  1.1     is 	unlk		%a6			# unravel stack frame
   2036  1.1     is 
   2037  1.1     is # shift stack frame "up". who cares about <ea> field.
   2038  1.1     is 	mov.l		0x4(%sp),0x10(%sp)
   2039  1.1     is 	mov.l		0x0(%sp),0xc(%sp)
   2040  1.1     is 	add.l		&0xc,%sp
   2041  1.1     is 
   2042  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   2043  1.1     is 	bne.b		fu_trace_p		# yes
   2044  1.1     is 
   2045  1.1     is 	bra.l		_fpsp_done		# exit to os
   2046  1.1     is 
   2047  1.1     is #
   2048  1.1     is # The opclass two PACKED instruction that took an "Unimplemented Data Type"
   2049  1.1     is # exception was being traced. Make the "current" PC the FPIAR and put it in the
   2050  1.1     is # trace stack frame then jump to _real_trace().
   2051  1.1     is #
   2052  1.1     is #		  UNSUPP FRAME		   TRACE FRAME
   2053  1.1     is #		*****************	*****************
   2054  1.1     is #		*      EA	*	*    Current	*
   2055  1.1     is #		*		*	*      PC	*
   2056  1.1     is #		*****************	*****************
   2057  1.1     is #		* 0x2 *	0x0dc	* 	* 0x2 *  0x024	*
   2058  1.1     is #		*****************	*****************
   2059  1.1     is #		*     Next	*	*     Next	*
   2060  1.1     is #		*      PC	*      	*      PC	*
   2061  1.1     is #		*****************	*****************
   2062  1.1     is #		*      SR	*	*      SR	*
   2063  1.1     is #		*****************	*****************
   2064  1.1     is fu_trace_p:
   2065  1.1     is 	mov.w		&0x2024,0x6(%sp)
   2066  1.1     is 	fmov.l		%fpiar,0x8(%sp)
   2067  1.1     is 
   2068  1.1     is 	bra.l		_real_trace
   2069  1.1     is 
   2070  1.1     is #########################################################
   2071  1.1     is #########################################################
   2072  1.1     is fu_out_pack:
   2073  1.1     is 
   2074  1.1     is 
   2075  1.1     is # I'm not sure at this point what FPSR bits are valid for this instruction.
   2076  1.1     is # so, since the emulation routines re-create them anyways, zero exception field.
   2077  1.1     is # fmove out doesn't affect ccodes.
   2078  1.1     is 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
   2079  1.1     is 
   2080  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
   2081  1.1     is 	fmov.l		&0x0,%fpsr
   2082  1.1     is 
   2083  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
   2084  1.1     is 	bsr.l		load_fpn1
   2085  1.1     is 
   2086  1.1     is # unlike other opclass 3, unimplemented data type exceptions, packed must be
   2087  1.1     is # able to detect all operand types.
   2088  1.1     is 	lea		FP_SRC(%a6),%a0
   2089  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   2090  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   2091  1.1     is 	bne.b		fu_op2_p		# no
   2092  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   2093  1.1     is 
   2094  1.1     is fu_op2_p:
   2095  1.1     is 	mov.b		%d0,STAG(%a6)		# save src optype tag
   2096  1.1     is 
   2097  1.1     is 	clr.l		%d0
   2098  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   2099  1.1     is 
   2100  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   2101  1.1     is 
   2102  1.1     is 	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes
   2103  1.1     is 	bsr.l		fout			# call fmove out routine
   2104  1.1     is 
   2105  1.1     is # Exceptions in order of precedence:
   2106  1.1     is # 	BSUN	: no
   2107  1.1     is #	SNAN	: yes
   2108  1.1     is #	OPERR	: if ((k_factor > +17) || (dec. exp exceeds 3 digits))
   2109  1.1     is #	OVFL	: no
   2110  1.1     is #	UNFL	: no
   2111  1.1     is #	DZ	: no
   2112  1.1     is # 	INEX2	: yes
   2113  1.1     is #	INEX1	: no
   2114  1.1     is 
   2115  1.1     is # determine the highest priority exception(if any) set by the
   2116  1.1     is # emulation routine that has also been enabled by the user.
   2117  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   2118  1.1     is 	bne.w		fu_out_ena_p		# some are enabled
   2119  1.1     is 
   2120  1.1     is fu_out_exit_p:
   2121  1.1     is 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
   2122  1.1     is 
   2123  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   2124  1.1     is 	bne.b		fu_out_exit_s_p		# supervisor
   2125  1.1     is 
   2126  1.1     is 	mov.l		EXC_A7(%a6),%a0		# update user a7
   2127  1.1     is 	mov.l		%a0,%usp
   2128  1.1     is 
   2129  1.1     is fu_out_exit_cont_p:
   2130  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2131  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2132  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2133  1.1     is 
   2134  1.1     is 	unlk		%a6			# unravel stack frame
   2135  1.1     is 
   2136  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   2137  1.1     is 	bne.w		fu_trace_p		# yes
   2138  1.1     is 
   2139  1.1     is 	bra.l		_fpsp_done		# exit to os
   2140  1.1     is 
   2141  1.1     is # the exception occurred in supervisor mode. check to see if the
   2142  1.1     is # addressing mode was -(a7). if so, we'll need to shift the
   2143  1.1     is # stack frame "down".
   2144  1.1     is fu_out_exit_s_p:
   2145  1.1     is 	btst		&mda7_bit,SPCOND_FLG(%a6) # was ea mode -(a7)
   2146  1.1     is 	beq.b		fu_out_exit_cont_p	# no
   2147  1.1     is 
   2148  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2149  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2150  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2151  1.1     is 
   2152  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   2153  1.1     is 
   2154  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2155  1.1     is 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2156  1.1     is 
   2157  1.1     is # now, copy the result to the proper place on the stack
   2158  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
   2159  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
   2160  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
   2161  1.1     is 
   2162  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   2163  1.1     is 
   2164  1.1     is 	btst		&0x7,(%sp)
   2165  1.1     is 	bne.w		fu_trace_p
   2166  1.1     is 
   2167  1.1     is 	bra.l		_fpsp_done
   2168  1.1     is 
   2169  1.1     is fu_out_ena_p:
   2170  1.1     is 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
   2171  1.1     is 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   2172  1.1     is 	beq.w		fu_out_exit_p
   2173  1.1     is 
   2174  1.1     is 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
   2175  1.1     is 
   2176  1.1     is # an exception occurred and that exception was enabled.
   2177  1.1     is # the only exception possible on packed move out are INEX, OPERR, and SNAN.
   2178  1.1     is fu_out_exc_p:
   2179  1.1     is 	cmpi.b		%d0,&0x1a
   2180  1.1     is 	bgt.w		fu_inex_p2
   2181  1.1     is 	beq.w		fu_operr_p
   2182  1.1     is 
   2183  1.1     is fu_snan_p:
   2184  1.1     is 	btst		&0x5,EXC_SR(%a6)
   2185  1.1     is 	bne.b		fu_snan_s_p
   2186  1.1     is 
   2187  1.1     is 	mov.l		EXC_A7(%a6),%a0
   2188  1.1     is 	mov.l		%a0,%usp
   2189  1.1     is 	bra.w		fu_snan
   2190  1.1     is 
   2191  1.1     is fu_snan_s_p:
   2192  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2193  1.1     is 	bne.w		fu_snan
   2194  1.1     is 
   2195  1.1     is # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
   2196  1.1     is # the strategy is to move the exception frame "down" 12 bytes. then, we
   2197  1.1     is # can store the default result where the exception frame was.
   2198  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2199  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2200  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2201  1.1     is 
   2202  1.1     is 	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd0
   2203  1.1     is 	mov.w		&0xe006,2+FP_SRC(%a6) 	# set fsave status
   2204  1.1     is 
   2205  1.1     is 	frestore	FP_SRC(%a6)		# restore src operand
   2206  1.1     is 
   2207  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   2208  1.1     is 
   2209  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2210  1.1     is 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2211  1.1     is 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   2212  1.1     is 
   2213  1.1     is # now, we copy the default result to it's proper location
   2214  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
   2215  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
   2216  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
   2217  1.1     is 
   2218  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   2219  1.1     is 
   2220  1.1     is 
   2221  1.1     is 	bra.l		_real_snan
   2222  1.1     is 
   2223  1.1     is fu_operr_p:
   2224  1.1     is 	btst		&0x5,EXC_SR(%a6)
   2225  1.1     is 	bne.w		fu_operr_p_s
   2226  1.1     is 
   2227  1.1     is 	mov.l		EXC_A7(%a6),%a0
   2228  1.1     is 	mov.l		%a0,%usp
   2229  1.1     is 	bra.w		fu_operr
   2230  1.1     is 
   2231  1.1     is fu_operr_p_s:
   2232  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2233  1.1     is 	bne.w		fu_operr
   2234  1.1     is 
   2235  1.1     is # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
   2236  1.1     is # the strategy is to move the exception frame "down" 12 bytes. then, we
   2237  1.1     is # can store the default result where the exception frame was.
   2238  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2239  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2240  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2241  1.1     is 
   2242  1.1     is 	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0
   2243  1.1     is 	mov.w		&0xe004,2+FP_SRC(%a6) 	# set fsave status
   2244  1.1     is 
   2245  1.1     is 	frestore	FP_SRC(%a6)		# restore src operand
   2246  1.1     is 
   2247  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   2248  1.1     is 
   2249  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2250  1.1     is 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2251  1.1     is 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   2252  1.1     is 
   2253  1.1     is # now, we copy the default result to it's proper location
   2254  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
   2255  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
   2256  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
   2257  1.1     is 
   2258  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   2259  1.1     is 
   2260  1.1     is 
   2261  1.1     is 	bra.l		_real_operr
   2262  1.1     is 
   2263  1.1     is fu_inex_p2:
   2264  1.1     is 	btst		&0x5,EXC_SR(%a6)
   2265  1.1     is 	bne.w		fu_inex_s_p2
   2266  1.1     is 
   2267  1.1     is 	mov.l		EXC_A7(%a6),%a0
   2268  1.1     is 	mov.l		%a0,%usp
   2269  1.1     is 	bra.w		fu_inex
   2270  1.1     is 
   2271  1.1     is fu_inex_s_p2:
   2272  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2273  1.1     is 	bne.w		fu_inex
   2274  1.1     is 
   2275  1.1     is # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
   2276  1.1     is # the strategy is to move the exception frame "down" 12 bytes. then, we
   2277  1.1     is # can store the default result where the exception frame was.
   2278  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2279  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2280  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2281  1.1     is 
   2282  1.1     is 	mov.w		&0x30c4,EXC_VOFF(%a6) 	# vector offset = 0xc4
   2283  1.1     is 	mov.w		&0xe001,2+FP_SRC(%a6) 	# set fsave status
   2284  1.1     is 
   2285  1.1     is 	frestore	FP_SRC(%a6)		# restore src operand
   2286  1.1     is 
   2287  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   2288  1.1     is 
   2289  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2290  1.1     is 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2291  1.1     is 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   2292  1.1     is 
   2293  1.1     is # now, we copy the default result to it's proper location
   2294  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
   2295  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
   2296  1.1     is 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
   2297  1.1     is 
   2298  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   2299  1.1     is 
   2300  1.1     is 
   2301  1.1     is 	bra.l		_real_inex
   2302  1.1     is 
   2303  1.1     is #########################################################################
   2304  1.1     is 
   2305  1.1     is #
   2306  1.1     is # if we're stuffing a source operand back into an fsave frame then we
   2307  1.1     is # have to make sure that for single or double source operands that the
   2308  1.1     is # format stuffed is as weird as the hardware usually makes it.
   2309  1.1     is #
   2310  1.1     is 	global		funimp_skew
   2311  1.1     is funimp_skew:
   2312  1.1     is 	bfextu		EXC_EXTWORD(%a6){&3:&3},%d0 # extract src specifier
   2313  1.1     is 	cmpi.b		%d0,&0x1		# was src sgl?
   2314  1.1     is 	beq.b		funimp_skew_sgl		# yes
   2315  1.1     is 	cmpi.b		%d0,&0x5		# was src dbl?
   2316  1.1     is 	beq.b		funimp_skew_dbl		# yes
   2317  1.1     is 	rts
   2318  1.1     is 
   2319  1.1     is funimp_skew_sgl:
   2320  1.1     is 	mov.w		FP_SRC_EX(%a6),%d0	# fetch DENORM exponent
   2321  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   2322  1.1     is 	beq.b		funimp_skew_sgl_not
   2323  1.1     is 	cmpi.w		%d0,&0x3f80
   2324  1.1     is 	bgt.b		funimp_skew_sgl_not
   2325  1.1     is 	neg.w		%d0			# make exponent negative
   2326  1.1     is 	addi.w		&0x3f81,%d0		# find amt to shift
   2327  1.1     is 	mov.l		FP_SRC_HI(%a6),%d1	# fetch DENORM hi(man)
   2328  1.1     is 	lsr.l		%d0,%d1			# shift it
   2329  1.1     is 	bset		&31,%d1			# set j-bit
   2330  1.1     is 	mov.l		%d1,FP_SRC_HI(%a6)	# insert new hi(man)
   2331  1.1     is 	andi.w		&0x8000,FP_SRC_EX(%a6)	# clear old exponent
   2332  1.1     is 	ori.w		&0x3f80,FP_SRC_EX(%a6)	# insert new "skewed" exponent
   2333  1.1     is funimp_skew_sgl_not:
   2334  1.1     is 	rts
   2335  1.1     is 
   2336  1.1     is funimp_skew_dbl:
   2337  1.1     is 	mov.w		FP_SRC_EX(%a6),%d0	# fetch DENORM exponent
   2338  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   2339  1.1     is 	beq.b		funimp_skew_dbl_not
   2340  1.1     is 	cmpi.w		%d0,&0x3c00
   2341  1.1     is 	bgt.b		funimp_skew_dbl_not
   2342  1.1     is 
   2343  1.1     is 	tst.b		FP_SRC_EX(%a6)		# make "internal format"
   2344  1.1     is 	smi.b		0x2+FP_SRC(%a6)
   2345  1.1     is 	mov.w		%d0,FP_SRC_EX(%a6)	# insert exponent with cleared sign
   2346  1.1     is 	clr.l		%d0			# clear g,r,s
   2347  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src op
   2348  1.1     is 	mov.w		&0x3c01,%d1		# pass denorm threshold
   2349  1.1     is 	bsr.l		dnrm_lp			# denorm it
   2350  1.1     is 	mov.w		&0x3c00,%d0		# new exponent
   2351  1.1     is 	tst.b		0x2+FP_SRC(%a6)		# is sign set?
   2352  1.1     is 	beq.b		fss_dbl_denorm_done	# no
   2353  1.1     is 	bset		&15,%d0			# set sign
   2354  1.1     is fss_dbl_denorm_done:
   2355  1.1     is 	bset		&0x7,FP_SRC_HI(%a6)	# set j-bit
   2356  1.1     is 	mov.w		%d0,FP_SRC_EX(%a6)	# insert new exponent
   2357  1.1     is funimp_skew_dbl_not:
   2358  1.1     is 	rts
   2359  1.1     is 
   2360  1.1     is #########################################################################
   2361  1.1     is 	global		_mem_write2
   2362  1.1     is _mem_write2:
   2363  1.1     is 	btst		&0x5,EXC_SR(%a6)
   2364  1.1     is 	beq.l		_dmem_write
   2365  1.1     is 	mov.l		0x0(%a0),FP_DST_EX(%a6)
   2366  1.1     is 	mov.l		0x4(%a0),FP_DST_HI(%a6)
   2367  1.1     is 	mov.l		0x8(%a0),FP_DST_LO(%a6)
   2368  1.1     is 	clr.l		%d1
   2369  1.1     is 	rts
   2370  1.1     is 
   2371  1.1     is #########################################################################
   2372  1.1     is # XDEF ****************************************************************	#
   2373  1.1     is #	_fpsp_effadd(): 060FPSP entry point for FP "Unimplemented	#
   2374  1.1     is #		     	effective address" exception.			#
   2375  1.1     is #									#
   2376  1.1     is #	This handler should be the first code executed upon taking the	#
   2377  1.1     is #	FP Unimplemented Effective Address exception in an operating	#
   2378  1.1     is #	system.								#
   2379  1.1     is #									#
   2380  1.1     is # XREF ****************************************************************	#
   2381  1.1     is #	_imem_read_long() - read instruction longword			#
   2382  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
   2383  1.1     is #	set_tag_x() - determine optype of src/dst operands		#
   2384  1.1     is #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   2385  1.1     is #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
   2386  1.1     is #	load_fpn2() - load dst operand from FP regfile			#
   2387  1.1     is #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
   2388  1.1     is #	decbin() - convert packed data to FP binary data		#
   2389  1.1     is #	_real_fpu_disabled() - "callout" for "FPU disabled" exception	#
   2390  1.1     is #	_real_access() - "callout" for access error exception		#
   2391  1.1     is #	_mem_read() - read extended immediate operand from memory	#
   2392  1.1     is #	_fpsp_done() - "callout" for exit; work all done		#
   2393  1.1     is #	_real_trace() - "callout" for Trace enabled exception		#
   2394  1.1     is #	fmovm_dynamic() - emulate dynamic fmovm instruction		#
   2395  1.1     is #	fmovm_ctrl() - emulate fmovm control instruction		#
   2396  1.1     is #									#
   2397  1.1     is # INPUT ***************************************************************	#
   2398  1.1     is #	- The system stack contains the "Unimplemented <ea>" stk frame	#
   2399  1.1     is # 									#
   2400  1.1     is # OUTPUT **************************************************************	#
   2401  1.1     is #	If access error:						#
   2402  1.1     is #	- The system stack is changed to an access error stack frame	#
   2403  1.1     is #	If FPU disabled:						#
   2404  1.1     is #	- The system stack is changed to an FPU disabled stack frame	#
   2405  1.1     is #	If Trace exception enabled:					#
   2406  1.1     is #	- The system stack is changed to a Trace exception stack frame	#
   2407  1.1     is #	Else: (normal case)						#
   2408  1.1     is #	- None (correct result has been stored as appropriate)		#
   2409  1.1     is #									#
   2410  1.1     is # ALGORITHM ***********************************************************	#
   2411  1.1     is #	This exception handles 3 types of operations:			#
   2412  1.1     is # (1) FP Instructions using extended precision or packed immediate	#
   2413  1.1     is #     addressing mode.							#
   2414  1.1     is # (2) The "fmovm.x" instruction w/ dynamic register specification.	#
   2415  1.1     is # (3) The "fmovm.l" instruction w/ 2 or 3 control registers.		#
   2416  1.1     is #									#
   2417  1.1     is #	For immediate data operations, the data is read in w/ a		#
   2418  1.1     is # _mem_read() "callout", converted to FP binary (if packed), and used	#
   2419  1.1     is # as the source operand to the instruction specified by the instruction	#
   2420  1.1     is # word. If no FP exception should be reported ads a result of the 	#
   2421  1.1     is # emulation, then the result is stored to the destination register and	#
   2422  1.1     is # the handler exits through _fpsp_done(). If an enabled exc has been	#
   2423  1.1     is # signalled as a result of emulation, then an fsave state frame		#
   2424  1.1     is # corresponding to the FP exception type must be entered into the 060	#
   2425  1.1     is # FPU before exiting. In either the enabled or disabled cases, we 	#
   2426  1.1     is # must also check if a Trace exception is pending, in which case, we	#
   2427  1.1     is # must create a Trace exception stack frame from the current exception	#
   2428  1.1     is # stack frame. If no Trace is pending, we simply exit through		#
   2429  1.1     is # _fpsp_done().								#
   2430  1.1     is #	For "fmovm.x", call the routine fmovm_dynamic() which will 	#
   2431  1.1     is # decode and emulate the instruction. No FP exceptions can be pending	#
   2432  1.1     is # as a result of this operation emulation. A Trace exception can be	#
   2433  1.1     is # pending, though, which means the current stack frame must be changed	#
   2434  1.1     is # to a Trace stack frame and an exit made through _real_trace().	#
   2435  1.1     is # For the case of "fmovm.x Dn,-(a7)", where the offending instruction	#
   2436  1.1     is # was executed from supervisor mode, this handler must store the FP	#
   2437  1.1     is # register file values to the system stack by itself since		#
   2438  1.1     is # fmovm_dynamic() can't handle this. A normal exit is made through	#
   2439  1.1     is # fpsp_done().								#
   2440  1.1     is #	For "fmovm.l", fmovm_ctrl() is used to emulate the instruction.	#
   2441  1.1     is # Again, a Trace exception may be pending and an exit made through	#
   2442  1.1     is # _real_trace(). Else, a normal exit is made through _fpsp_done().	#
   2443  1.1     is #									#
   2444  1.1     is #	Before any of the above is attempted, it must be checked to	#
   2445  1.1     is # see if the FPU is disabled. Since the "Unimp <ea>" exception is taken	#
   2446  1.1     is # before the "FPU disabled" exception, but the "FPU disabled" exception	#
   2447  1.1     is # has higher priority, we check the disabled bit in the PCR. If set,	#
   2448  1.1     is # then we must create an 8 word "FPU disabled" exception stack frame	#
   2449  1.1     is # from the current 4 word exception stack frame. This includes 		#
   2450  1.1     is # reproducing the effective address of the instruction to put on the 	#
   2451  1.1     is # new stack frame.							#
   2452  1.1     is #									#
   2453  1.1     is # 	In the process of all emulation work, if a _mem_read()		#
   2454  1.1     is # "callout" returns a failing result indicating an access error, then	#
   2455  1.1     is # we must create an access error stack frame from the current stack	#
   2456  1.1     is # frame. This information includes a faulting address and a fault-	#
   2457  1.1     is # status-longword. These are created within this handler.		#
   2458  1.1     is #									#
   2459  1.1     is #########################################################################
   2460  1.1     is 
   2461  1.1     is 	global		_fpsp_effadd
   2462  1.1     is _fpsp_effadd:
   2463  1.1     is 
   2464  1.1     is # This exception type takes priority over the "Line F Emulator"
   2465  1.1     is # exception. Therefore, the FPU could be disabled when entering here.
   2466  1.1     is # So, we must check to see if it's disabled and handle that case separately.
   2467  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   2468  1.1     is 	movc		%pcr,%d0		# load proc cr
   2469  1.1     is 	btst		&0x1,%d0		# is FPU disabled?
   2470  1.1     is 	bne.w		iea_disabled		# yes
   2471  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   2472  1.1     is 
   2473  1.1     is 	link		%a6,&-LOCAL_SIZE	# init stack frame
   2474  1.1     is 
   2475  1.1     is 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2476  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   2477  1.1     is 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   2478  1.1     is 
   2479  1.1     is # PC of instruction that took the exception is the PC in the frame
   2480  1.1     is 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
   2481  1.1     is 
   2482  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   2483  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   2484  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   2485  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
   2486  1.1     is 
   2487  1.1     is #########################################################################
   2488  1.1     is 
   2489  1.1     is 	tst.w		%d0			# is operation fmovem?
   2490  1.1     is 	bmi.w		iea_fmovm		# yes
   2491  1.1     is 
   2492  1.1     is #
   2493  1.1     is # here, we will have:
   2494  1.1     is # 	fabs	fdabs	fsabs		facos		fmod
   2495  1.1     is #	fadd	fdadd	fsadd		fasin		frem
   2496  1.1     is # 	fcmp				fatan		fscale
   2497  1.1     is #	fdiv	fddiv	fsdiv		fatanh		fsin
   2498  1.1     is #	fint				fcos		fsincos
   2499  1.1     is #	fintrz				fcosh		fsinh
   2500  1.1     is #	fmove	fdmove	fsmove		fetox		ftan
   2501  1.1     is # 	fmul	fdmul	fsmul		fetoxm1		ftanh
   2502  1.1     is #	fneg	fdneg	fsneg		fgetexp		ftentox
   2503  1.1     is #	fsgldiv				fgetman		ftwotox
   2504  1.1     is # 	fsglmul				flog10
   2505  1.1     is # 	fsqrt				flog2
   2506  1.1     is #	fsub	fdsub	fssub		flogn
   2507  1.1     is #	ftst				flognp1
   2508  1.1     is # which can all use f<op>.{x,p}
   2509  1.1     is # so, now it's immediate data extended precision AND PACKED FORMAT!
   2510  1.1     is #
   2511  1.1     is iea_op:
   2512  1.1     is 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2513  1.1     is 
   2514  1.1     is 	btst		&0xa,%d0		# is src fmt x or p?
   2515  1.1     is 	bne.b		iea_op_pack		# packed
   2516  1.1     is 
   2517  1.1     is 
   2518  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# pass: ptr to #<data>
   2519  1.1     is 	lea		FP_SRC(%a6),%a1		# pass: ptr to super addr
   2520  1.1     is 	mov.l		&0xc,%d0		# pass: 12 bytes
   2521  1.1     is 	bsr.l		_imem_read		# read extended immediate
   2522  1.1     is 
   2523  1.1     is 	tst.l		%d1			# did ifetch fail?
   2524  1.1     is 	bne.w		iea_iacc		# yes
   2525  1.1     is 
   2526  1.1     is 	bra.b		iea_op_setsrc
   2527  1.1     is 
   2528  1.1     is iea_op_pack:
   2529  1.1     is 
   2530  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# pass: ptr to #<data>
   2531  1.1     is 	lea		FP_SRC(%a6),%a1		# pass: ptr to super dst
   2532  1.1     is 	mov.l		&0xc,%d0		# pass: 12 bytes
   2533  1.1     is 	bsr.l		_imem_read		# read packed operand
   2534  1.1     is 
   2535  1.1     is 	tst.l		%d1			# did ifetch fail?
   2536  1.1     is 	bne.w		iea_iacc		# yes
   2537  1.1     is 
   2538  1.1     is # The packed operand is an INF or a NAN if the exponent field is all ones.
   2539  1.1     is 	bfextu		FP_SRC(%a6){&1:&15},%d0	# get exp
   2540  1.1     is 	cmpi.w		%d0,&0x7fff		# INF or NAN?
   2541  1.1     is 	beq.b		iea_op_setsrc		# operand is an INF or NAN
   2542  1.1     is 
   2543  1.1     is # The packed operand is a zero if the mantissa is all zero, else it's
   2544  1.1     is # a normal packed op.
   2545  1.1     is 	mov.b		3+FP_SRC(%a6),%d0	# get byte 4
   2546  1.1     is 	andi.b		&0x0f,%d0		# clear all but last nybble
   2547  1.1     is 	bne.b		iea_op_gp_not_spec	# not a zero
   2548  1.1     is 	tst.l		FP_SRC_HI(%a6)		# is lw 2 zero?
   2549  1.1     is 	bne.b		iea_op_gp_not_spec	# not a zero
   2550  1.1     is 	tst.l		FP_SRC_LO(%a6)		# is lw 3 zero?
   2551  1.1     is 	beq.b		iea_op_setsrc		# operand is a ZERO
   2552  1.1     is iea_op_gp_not_spec:
   2553  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to packed op
   2554  1.1     is 	bsr.l		decbin			# convert to extended
   2555  1.1     is 	fmovm.x		&0x80,FP_SRC(%a6)	# make this the srcop
   2556  1.1     is 
   2557  1.1     is iea_op_setsrc:
   2558  1.1     is 	addi.l		&0xc,EXC_EXTWPTR(%a6)	# update extension word pointer
   2559  1.1     is 
   2560  1.1     is # FP_SRC now holds the src operand.
   2561  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   2562  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   2563  1.1     is 	mov.b		%d0,STAG(%a6)		# could be ANYTHING!!!
   2564  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   2565  1.1     is 	bne.b		iea_op_getdst		# no
   2566  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM/DENORM/ZERO
   2567  1.1     is 	mov.b		%d0,STAG(%a6)		# set new optype tag
   2568  1.1     is iea_op_getdst:
   2569  1.1     is 	clr.b		STORE_FLG(%a6)		# clear "store result" boolean
   2570  1.1     is 
   2571  1.1     is 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   2572  1.1     is 	beq.b		iea_op_extract		# monadic
   2573  1.1     is 	btst		&0x4,1+EXC_CMDREG(%a6)	# is operation fsincos,ftst,fcmp?
   2574  1.1     is 	bne.b		iea_op_spec		# yes
   2575  1.1     is 
   2576  1.1     is iea_op_loaddst:
   2577  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
   2578  1.1     is 	bsr.l		load_fpn2		# load dst operand
   2579  1.1     is 
   2580  1.1     is 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   2581  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   2582  1.1     is 	mov.b		%d0,DTAG(%a6)		# could be ANYTHING!!!
   2583  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   2584  1.1     is 	bne.b		iea_op_extract		# no
   2585  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM/DENORM/ZERO
   2586  1.1     is 	mov.b		%d0,DTAG(%a6)		# set new optype tag
   2587  1.1     is 	bra.b		iea_op_extract
   2588  1.1     is 
   2589  1.1     is # the operation is fsincos, ftst, or fcmp. only fcmp is dyadic
   2590  1.1     is iea_op_spec:
   2591  1.1     is 	btst		&0x3,1+EXC_CMDREG(%a6)	# is operation fsincos?
   2592  1.1     is 	beq.b		iea_op_extract		# yes
   2593  1.1     is # now, we're left with ftst and fcmp. so, first let's tag them so that they don't
   2594  1.1     is # store a result. then, only fcmp will branch back and pick up a dst operand.
   2595  1.1     is 	st		STORE_FLG(%a6)		# don't store a final result
   2596  1.1     is 	btst		&0x1,1+EXC_CMDREG(%a6)	# is operation fcmp?
   2597  1.1     is 	beq.b		iea_op_loaddst		# yes
   2598  1.1     is 
   2599  1.1     is iea_op_extract:
   2600  1.1     is 	clr.l		%d0
   2601  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass: rnd mode,prec
   2602  1.1     is 
   2603  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
   2604  1.1     is 	andi.w		&0x007f,%d1		# extract extension
   2605  1.1     is 
   2606  1.1     is 	fmov.l		&0x0,%fpcr
   2607  1.1     is 	fmov.l		&0x0,%fpsr
   2608  1.1     is 
   2609  1.1     is 	lea		FP_SRC(%a6),%a0
   2610  1.1     is 	lea		FP_DST(%a6),%a1
   2611  1.1     is 
   2612  1.1     is 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
   2613  1.1     is 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   2614  1.1     is 
   2615  1.1     is #
   2616  1.1     is # Exceptions in order of precedence:
   2617  1.1     is #	BSUN	: none
   2618  1.1     is #	SNAN	: all operations
   2619  1.1     is #	OPERR	: all reg-reg or mem-reg operations that can normally operr
   2620  1.1     is #	OVFL	: same as OPERR
   2621  1.1     is #	UNFL	: same as OPERR
   2622  1.1     is #	DZ	: same as OPERR
   2623  1.1     is #	INEX2	: same as OPERR
   2624  1.1     is #	INEX1	: all packed immediate operations
   2625  1.1     is #
   2626  1.1     is 
   2627  1.1     is # we determine the highest priority exception(if any) set by the
   2628  1.1     is # emulation routine that has also been enabled by the user.
   2629  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   2630  1.1     is 	bne.b		iea_op_ena		# some are enabled
   2631  1.1     is 
   2632  1.1     is # now, we save the result, unless, of course, the operation was ftst or fcmp.
   2633  1.1     is # these don't save results.
   2634  1.1     is iea_op_save:
   2635  1.1     is 	tst.b		STORE_FLG(%a6)		# does this op store a result?
   2636  1.1     is 	bne.b		iea_op_exit1		# exit with no frestore
   2637  1.1     is 
   2638  1.1     is iea_op_store:
   2639  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
   2640  1.1     is 	bsr.l		store_fpreg		# store the result
   2641  1.1     is 
   2642  1.1     is iea_op_exit1:
   2643  1.1     is 	mov.l		EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
   2644  1.1     is 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
   2645  1.1     is 
   2646  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   2647  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2648  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2649  1.1     is 
   2650  1.1     is 	unlk		%a6			# unravel the frame
   2651  1.1     is 
   2652  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   2653  1.1     is 	bne.w		iea_op_trace		# yes
   2654  1.1     is 
   2655  1.1     is 	bra.l		_fpsp_done		# exit to os
   2656  1.1     is 
   2657  1.1     is iea_op_ena:
   2658  1.1     is 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enable and set
   2659  1.1     is 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   2660  1.1     is 	bne.b		iea_op_exc		# at least one was set
   2661  1.1     is 
   2662  1.1     is # no exception occurred. now, did a disabled, exact overflow occur with inexact
   2663  1.1     is # enabled? if so, then we have to stuff an overflow frame into the FPU.
   2664  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   2665  1.1     is 	beq.b		iea_op_save
   2666  1.1     is 
   2667  1.1     is iea_op_ovfl:
   2668  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
   2669  1.1     is 	beq.b		iea_op_store		# no
   2670  1.1     is 	bra.b		iea_op_exc_ovfl		# yes
   2671  1.1     is 
   2672  1.1     is # an enabled exception occurred. we have to insert the exception type back into
   2673  1.1     is # the machine.
   2674  1.1     is iea_op_exc:
   2675  1.1     is 	subi.l		&24,%d0			# fix offset to be 0-8
   2676  1.1     is 	cmpi.b		%d0,&0x6		# is exception INEX?
   2677  1.1     is 	bne.b		iea_op_exc_force	# no
   2678  1.1     is 
   2679  1.1     is # the enabled exception was inexact. so, if it occurs with an overflow
   2680  1.1     is # or underflow that was disabled, then we have to force an overflow or
   2681  1.1     is # underflow frame.
   2682  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   2683  1.1     is 	bne.b		iea_op_exc_ovfl		# yes
   2684  1.1     is 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
   2685  1.1     is 	bne.b		iea_op_exc_unfl		# yes
   2686  1.1     is 
   2687  1.1     is iea_op_exc_force:
   2688  1.1     is 	mov.w		(tbl_iea_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   2689  1.1     is 	bra.b		iea_op_exit2		# exit with frestore
   2690  1.1     is 
   2691  1.1     is tbl_iea_except:
   2692  1.1     is 	short		0xe002, 0xe006, 0xe004, 0xe005
   2693  1.1     is 	short		0xe003, 0xe002, 0xe001, 0xe001
   2694  1.1     is 
   2695  1.1     is iea_op_exc_ovfl:
   2696  1.1     is 	mov.w		&0xe005,2+FP_SRC(%a6)
   2697  1.1     is 	bra.b		iea_op_exit2
   2698  1.1     is 
   2699  1.1     is iea_op_exc_unfl:
   2700  1.1     is 	mov.w		&0xe003,2+FP_SRC(%a6)
   2701  1.1     is 
   2702  1.1     is iea_op_exit2:
   2703  1.1     is 	mov.l		EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
   2704  1.1     is 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
   2705  1.1     is 
   2706  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   2707  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2708  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2709  1.1     is 
   2710  1.1     is 	frestore 	FP_SRC(%a6)		# restore exceptional state
   2711  1.1     is 
   2712  1.1     is 	unlk		%a6			# unravel the frame
   2713  1.1     is 
   2714  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   2715  1.1     is 	bne.b		iea_op_trace		# yes
   2716  1.1     is 
   2717  1.1     is 	bra.l		_fpsp_done		# exit to os
   2718  1.1     is 
   2719  1.1     is #
   2720  1.1     is # The opclass two instruction that took an "Unimplemented Effective Address"
   2721  1.1     is # exception was being traced. Make the "current" PC the FPIAR and put it in
   2722  1.1     is # the trace stack frame then jump to _real_trace().
   2723  1.1     is #
   2724  1.1     is #		 UNIMP EA FRAME		   TRACE FRAME
   2725  1.1     is #		*****************	*****************
   2726  1.1     is #		* 0x0 *  0x0f0	*	*    Current	*
   2727  1.1     is #		*****************	*      PC	*
   2728  1.1     is #		*    Current	*	*****************
   2729  1.1     is #		*      PC	*	* 0x2 *  0x024	*
   2730  1.1     is #		*****************	*****************
   2731  1.1     is #		*      SR	*	*     Next	*
   2732  1.1     is #		*****************	*      PC	*
   2733  1.1     is #					*****************
   2734  1.1     is #					*      SR	*
   2735  1.1     is #					*****************
   2736  1.1     is iea_op_trace:
   2737  1.1     is 	mov.l		(%sp),-(%sp)		# shift stack frame "down"
   2738  1.1     is 	mov.w		0x8(%sp),0x4(%sp)
   2739  1.1     is 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
   2740  1.1     is 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
   2741  1.1     is 
   2742  1.1     is 	bra.l		_real_trace
   2743  1.1     is 
   2744  1.1     is #########################################################################
   2745  1.1     is iea_fmovm:
   2746  1.1     is 	btst		&14,%d0			# ctrl or data reg
   2747  1.1     is 	beq.w		iea_fmovm_ctrl
   2748  1.1     is 
   2749  1.1     is iea_fmovm_data:
   2750  1.1     is 
   2751  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode
   2752  1.1     is 	bne.b		iea_fmovm_data_s
   2753  1.1     is 
   2754  1.1     is iea_fmovm_data_u:
   2755  1.1     is 	mov.l		%usp,%a0
   2756  1.1     is 	mov.l		%a0,EXC_A7(%a6)		# store current a7
   2757  1.1     is 	bsr.l		fmovm_dynamic		# do dynamic fmovm
   2758  1.1     is 	mov.l		EXC_A7(%a6),%a0		# load possibly new a7
   2759  1.1     is 	mov.l		%a0,%usp		# update usp
   2760  1.1     is 	bra.w		iea_fmovm_exit
   2761  1.1     is 
   2762  1.1     is iea_fmovm_data_s:
   2763  1.1     is 	clr.b		SPCOND_FLG(%a6)
   2764  1.1     is 	lea		0x2+EXC_VOFF(%a6),%a0
   2765  1.1     is 	mov.l		%a0,EXC_A7(%a6)
   2766  1.1     is 	bsr.l		fmovm_dynamic		# do dynamic fmovm
   2767  1.1     is 
   2768  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2769  1.1     is 	beq.w		iea_fmovm_data_predec
   2770  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mia7_flg
   2771  1.1     is 	bne.w		iea_fmovm_exit
   2772  1.1     is 
   2773  1.1     is # right now, d0 = the size.
   2774  1.1     is # the data has been fetched from the supervisor stack, but we have not
   2775  1.1     is # incremented the stack pointer by the appropriate number of bytes.
   2776  1.1     is # do it here.
   2777  1.1     is iea_fmovm_data_postinc:
   2778  1.1     is 	btst		&0x7,EXC_SR(%a6)
   2779  1.1     is 	bne.b		iea_fmovm_data_pi_trace
   2780  1.1     is 
   2781  1.1     is 	mov.w		EXC_SR(%a6),(EXC_SR,%a6,%d0)
   2782  1.1     is 	mov.l		EXC_EXTWPTR(%a6),(EXC_PC,%a6,%d0)
   2783  1.1     is 	mov.w		&0x00f0,(EXC_VOFF,%a6,%d0)
   2784  1.1     is 
   2785  1.1     is 	lea		(EXC_SR,%a6,%d0),%a0
   2786  1.1     is 	mov.l		%a0,EXC_SR(%a6)
   2787  1.1     is 
   2788  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   2789  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2790  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   2791  1.1     is 
   2792  1.1     is 	unlk		%a6
   2793  1.1     is 	mov.l		(%sp)+,%sp
   2794  1.1     is 	bra.l		_fpsp_done
   2795  1.1     is 
   2796  1.1     is iea_fmovm_data_pi_trace:
   2797  1.1     is 	mov.w		EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
   2798  1.1     is 	mov.l		EXC_EXTWPTR(%a6),(EXC_PC-0x4,%a6,%d0)
   2799  1.1     is 	mov.w		&0x2024,(EXC_VOFF-0x4,%a6,%d0)
   2800  1.1     is 	mov.l		EXC_PC(%a6),(EXC_VOFF+0x2-0x4,%a6,%d0)
   2801  1.1     is 
   2802  1.1     is 	lea		(EXC_SR-0x4,%a6,%d0),%a0
   2803  1.1     is 	mov.l		%a0,EXC_SR(%a6)
   2804  1.1     is 
   2805  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   2806  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2807  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   2808  1.1     is 
   2809  1.1     is 	unlk		%a6
   2810  1.1     is 	mov.l		(%sp)+,%sp
   2811  1.1     is 	bra.l		_real_trace
   2812  1.1     is 
   2813  1.1     is # right now, d1 = size and d0 = the strg.
   2814  1.1     is iea_fmovm_data_predec:
   2815  1.1     is 	mov.b		%d1,EXC_VOFF(%a6)	# store strg
   2816  1.1     is 	mov.b		%d0,0x1+EXC_VOFF(%a6)	# store size
   2817  1.1     is 
   2818  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   2819  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2820  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   2821  1.1     is 
   2822  1.1     is 	mov.l		(%a6),-(%sp)		# make a copy of a6
   2823  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   2824  1.1     is 	mov.l		%d1,-(%sp)		# save d1
   2825  1.1     is 	mov.l		EXC_EXTWPTR(%a6),-(%sp)	# make a copy of Next PC
   2826  1.1     is 
   2827  1.1     is 	clr.l		%d0
   2828  1.1     is 	mov.b		0x1+EXC_VOFF(%a6),%d0	# fetch size
   2829  1.1     is 	neg.l		%d0			# get negative of size
   2830  1.1     is 
   2831  1.1     is 	btst		&0x7,EXC_SR(%a6)	# is trace enabled?
   2832  1.1     is 	beq.b		iea_fmovm_data_p2
   2833  1.1     is 
   2834  1.1     is 	mov.w		EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
   2835  1.1     is 	mov.l		EXC_PC(%a6),(EXC_VOFF-0x2,%a6,%d0)
   2836  1.1     is 	mov.l		(%sp)+,(EXC_PC-0x4,%a6,%d0)
   2837  1.1     is 	mov.w		&0x2024,(EXC_VOFF-0x4,%a6,%d0)
   2838  1.1     is 
   2839  1.1     is 	pea		(%a6,%d0)		# create final sp
   2840  1.1     is 	bra.b		iea_fmovm_data_p3
   2841  1.1     is 
   2842  1.1     is iea_fmovm_data_p2:
   2843  1.1     is 	mov.w		EXC_SR(%a6),(EXC_SR,%a6,%d0)
   2844  1.1     is 	mov.l		(%sp)+,(EXC_PC,%a6,%d0)
   2845  1.1     is 	mov.w		&0x00f0,(EXC_VOFF,%a6,%d0)
   2846  1.1     is 
   2847  1.1     is 	pea		(0x4,%a6,%d0)		# create final sp
   2848  1.1     is 
   2849  1.1     is iea_fmovm_data_p3:
   2850  1.1     is 	clr.l		%d1
   2851  1.1     is 	mov.b		EXC_VOFF(%a6),%d1	# fetch strg
   2852  1.1     is 
   2853  1.1     is 	tst.b		%d1
   2854  1.1     is 	bpl.b		fm_1
   2855  1.1     is 	fmovm.x		&0x80,(0x4+0x8,%a6,%d0)
   2856  1.1     is 	addi.l		&0xc,%d0
   2857  1.1     is fm_1:
   2858  1.1     is 	lsl.b		&0x1,%d1
   2859  1.1     is 	bpl.b		fm_2
   2860  1.1     is 	fmovm.x		&0x40,(0x4+0x8,%a6,%d0)
   2861  1.1     is 	addi.l		&0xc,%d0
   2862  1.1     is fm_2:
   2863  1.1     is 	lsl.b		&0x1,%d1
   2864  1.1     is 	bpl.b		fm_3
   2865  1.1     is 	fmovm.x		&0x20,(0x4+0x8,%a6,%d0)
   2866  1.1     is 	addi.l		&0xc,%d0
   2867  1.1     is fm_3:
   2868  1.1     is 	lsl.b		&0x1,%d1
   2869  1.1     is 	bpl.b		fm_4
   2870  1.1     is 	fmovm.x		&0x10,(0x4+0x8,%a6,%d0)
   2871  1.1     is 	addi.l		&0xc,%d0
   2872  1.1     is fm_4:
   2873  1.1     is 	lsl.b		&0x1,%d1
   2874  1.1     is 	bpl.b		fm_5
   2875  1.1     is 	fmovm.x		&0x08,(0x4+0x8,%a6,%d0)
   2876  1.1     is 	addi.l		&0xc,%d0
   2877  1.1     is fm_5:
   2878  1.1     is 	lsl.b		&0x1,%d1
   2879  1.1     is 	bpl.b		fm_6
   2880  1.1     is 	fmovm.x		&0x04,(0x4+0x8,%a6,%d0)
   2881  1.1     is 	addi.l		&0xc,%d0
   2882  1.1     is fm_6:
   2883  1.1     is 	lsl.b		&0x1,%d1
   2884  1.1     is 	bpl.b		fm_7
   2885  1.1     is 	fmovm.x		&0x02,(0x4+0x8,%a6,%d0)
   2886  1.1     is 	addi.l		&0xc,%d0
   2887  1.1     is fm_7:
   2888  1.1     is 	lsl.b		&0x1,%d1
   2889  1.1     is 	bpl.b		fm_end
   2890  1.1     is 	fmovm.x		&0x01,(0x4+0x8,%a6,%d0)
   2891  1.1     is fm_end:
   2892  1.1     is 	mov.l		0x4(%sp),%d1
   2893  1.1     is 	mov.l		0x8(%sp),%d0
   2894  1.1     is 	mov.l		0xc(%sp),%a6
   2895  1.1     is 	mov.l		(%sp)+,%sp
   2896  1.1     is 
   2897  1.1     is 	btst		&0x7,(%sp)		# is trace enabled?
   2898  1.1     is 	beq.l		_fpsp_done
   2899  1.1     is 	bra.l		_real_trace
   2900  1.1     is 
   2901  1.1     is #########################################################################
   2902  1.1     is iea_fmovm_ctrl:
   2903  1.1     is 
   2904  1.1     is 	bsr.l		fmovm_ctrl		# load ctrl regs
   2905  1.1     is 
   2906  1.1     is iea_fmovm_exit:
   2907  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   2908  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2909  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2910  1.1     is 
   2911  1.1     is 	btst		&0x7,EXC_SR(%a6)	# is trace on?
   2912  1.1     is 	bne.b		iea_fmovm_trace		# yes
   2913  1.1     is 
   2914  1.1     is 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set Next PC
   2915  1.1     is 
   2916  1.1     is 	unlk		%a6			# unravel the frame
   2917  1.1     is 
   2918  1.1     is 	bra.l		_fpsp_done		# exit to os
   2919  1.1     is 
   2920  1.1     is #
   2921  1.1     is # The control reg instruction that took an "Unimplemented Effective Address"
   2922  1.1     is # exception was being traced. The "Current PC" for the trace frame is the
   2923  1.1     is # PC stacked for Unimp EA. The "Next PC" is in EXC_EXTWPTR.
   2924  1.1     is # After fixing the stack frame, jump to _real_trace().
   2925  1.1     is #
   2926  1.1     is #		 UNIMP EA FRAME		   TRACE FRAME
   2927  1.1     is #		*****************	*****************
   2928  1.1     is #		* 0x0 *  0x0f0	*	*    Current	*
   2929  1.1     is #		*****************	*      PC	*
   2930  1.1     is #		*    Current	*	*****************
   2931  1.1     is #		*      PC	*	* 0x2 *  0x024	*
   2932  1.1     is #		*****************	*****************
   2933  1.1     is #		*      SR	*	*     Next	*
   2934  1.1     is #		*****************	*      PC	*
   2935  1.1     is #					*****************
   2936  1.1     is #					*      SR	*
   2937  1.1     is #					*****************
   2938  1.1     is # this ain't a pretty solution, but it works:
   2939  1.1     is # -restore a6 (not with unlk)
   2940  1.1     is # -shift stack frame down over where old a6 used to be
   2941  1.1     is # -add LOCAL_SIZE to stack pointer
   2942  1.1     is iea_fmovm_trace:
   2943  1.1     is 	mov.l		(%a6),%a6		# restore frame pointer
   2944  1.1     is 	mov.w		EXC_SR+LOCAL_SIZE(%sp),0x0+LOCAL_SIZE(%sp)
   2945  1.1     is 	mov.l		EXC_PC+LOCAL_SIZE(%sp),0x8+LOCAL_SIZE(%sp)
   2946  1.1     is 	mov.l		EXC_EXTWPTR+LOCAL_SIZE(%sp),0x2+LOCAL_SIZE(%sp)
   2947  1.1     is 	mov.w		&0x2024,0x6+LOCAL_SIZE(%sp) # stk fmt = 0x2; voff = 0x024
   2948  1.1     is 	add.l		&LOCAL_SIZE,%sp		# clear stack frame
   2949  1.1     is 
   2950  1.1     is 	bra.l		_real_trace
   2951  1.1     is 
   2952  1.1     is #########################################################################
   2953  1.1     is # The FPU is disabled and so we should really have taken the "Line
   2954  1.1     is # F Emulator" exception. So, here we create an 8-word stack frame
   2955  1.1     is # from our 4-word stack frame. This means we must calculate the length
   2956  1.1     is # of the faulting instruction to get the "next PC". This is trivial for
   2957  1.1     is # immediate operands but requires some extra work for fmovm dynamic
   2958  1.1     is # which can use most addressing modes.
   2959  1.1     is iea_disabled:
   2960  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   2961  1.1     is 
   2962  1.1     is 	link		%a6,&-LOCAL_SIZE	# init stack frame
   2963  1.1     is 
   2964  1.1     is 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2965  1.1     is 
   2966  1.1     is # PC of instruction that took the exception is the PC in the frame
   2967  1.1     is 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
   2968  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   2969  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   2970  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   2971  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
   2972  1.1     is 
   2973  1.1     is 	tst.w		%d0			# is instr fmovm?
   2974  1.1     is 	bmi.b		iea_dis_fmovm		# yes
   2975  1.1     is # instruction is using an extended precision immediate operand. therefore,
   2976  1.1     is # the total instruction length is 16 bytes.
   2977  1.1     is iea_dis_immed:
   2978  1.1     is 	mov.l		&0x10,%d0		# 16 bytes of instruction
   2979  1.1     is 	bra.b		iea_dis_cont
   2980  1.1     is iea_dis_fmovm:
   2981  1.1     is 	btst		&0xe,%d0		# is instr fmovm ctrl
   2982  1.1     is 	bne.b		iea_dis_fmovm_data	# no
   2983  1.1     is # the instruction is a fmovm.l with 2 or 3 registers.
   2984  1.1     is 	bfextu		%d0{&19:&3},%d1
   2985  1.1     is 	mov.l		&0xc,%d0
   2986  1.1     is 	cmpi.b		%d1,&0x7		# move all regs?
   2987  1.1     is 	bne.b		iea_dis_cont
   2988  1.1     is 	addq.l		&0x4,%d0
   2989  1.1     is 	bra.b		iea_dis_cont
   2990  1.1     is # the instruction is an fmovm.x dynamic which can use many addressing
   2991  1.1     is # modes and thus can have several different total instruction lengths.
   2992  1.1     is # call fmovm_calc_ea which will go through the ea calc process and,
   2993  1.1     is # as a by-product, will tell us how long the instruction is.
   2994  1.1     is iea_dis_fmovm_data:
   2995  1.1     is 	clr.l		%d0
   2996  1.1     is 	bsr.l		fmovm_calc_ea
   2997  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%d0
   2998  1.1     is 	sub.l		EXC_PC(%a6),%d0
   2999  1.1     is iea_dis_cont:
   3000  1.1     is 	mov.w		%d0,EXC_VOFF(%a6)	# store stack shift value
   3001  1.1     is 
   3002  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3003  1.1     is 
   3004  1.1     is 	unlk		%a6
   3005  1.1     is 
   3006  1.1     is # here, we actually create the 8-word frame from the 4-word frame,
   3007  1.1     is # with the "next PC" as additional info.
   3008  1.1     is # the <ea> field is let as undefined.
   3009  1.1     is 	subq.l		&0x8,%sp		# make room for new stack
   3010  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   3011  1.1     is 	mov.w		0xc(%sp),0x4(%sp)	# move SR
   3012  1.1     is 	mov.l		0xe(%sp),0x6(%sp)	# move Current PC
   3013  1.1     is 	clr.l		%d0
   3014  1.1     is 	mov.w		0x12(%sp),%d0
   3015  1.1     is 	mov.l		0x6(%sp),0x10(%sp)	# move Current PC
   3016  1.1     is 	add.l		%d0,0x6(%sp)		# make Next PC
   3017  1.1     is 	mov.w		&0x402c,0xa(%sp)	# insert offset,frame format
   3018  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   3019  1.1     is 
   3020  1.1     is 	bra.l		_real_fpu_disabled
   3021  1.1     is 
   3022  1.1     is ##########
   3023  1.1     is 
   3024  1.1     is iea_iacc:
   3025  1.1     is 	movc		%pcr,%d0
   3026  1.1     is 	btst		&0x1,%d0
   3027  1.1     is 	bne.b		iea_iacc_cont
   3028  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3029  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1 on stack
   3030  1.1     is iea_iacc_cont:
   3031  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3032  1.1     is 
   3033  1.1     is 	unlk		%a6
   3034  1.1     is 
   3035  1.1     is 	subq.w		&0x8,%sp		# make stack frame bigger
   3036  1.1     is 	mov.l		0x8(%sp),(%sp)		# store SR,hi(PC)
   3037  1.1     is 	mov.w		0xc(%sp),0x4(%sp)	# store lo(PC)
   3038  1.1     is 	mov.w		&0x4008,0x6(%sp)	# store voff
   3039  1.1     is 	mov.l		0x2(%sp),0x8(%sp)	# store ea
   3040  1.1     is 	mov.l		&0x09428001,0xc(%sp)	# store fslw
   3041  1.1     is 
   3042  1.1     is iea_acc_done:
   3043  1.1     is 	btst		&0x5,(%sp)		# user or supervisor mode?
   3044  1.1     is 	beq.b		iea_acc_done2		# user
   3045  1.1     is 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
   3046  1.1     is 
   3047  1.1     is iea_acc_done2:
   3048  1.1     is 	bra.l		_real_access
   3049  1.1     is 
   3050  1.1     is iea_dacc:
   3051  1.1     is 	lea		-LOCAL_SIZE(%a6),%sp
   3052  1.1     is 
   3053  1.1     is 	movc		%pcr,%d1
   3054  1.1     is 	btst		&0x1,%d1
   3055  1.1     is 	bne.b		iea_dacc_cont
   3056  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1 on stack
   3057  1.1     is 	fmovm.l		LOCAL_SIZE+USER_FPCR(%sp),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3058  1.1     is iea_dacc_cont:
   3059  1.1     is 	mov.l		(%a6),%a6
   3060  1.1     is 
   3061  1.1     is 	mov.l		0x4+LOCAL_SIZE(%sp),-0x8+0x4+LOCAL_SIZE(%sp)
   3062  1.1     is 	mov.w		0x8+LOCAL_SIZE(%sp),-0x8+0x8+LOCAL_SIZE(%sp)
   3063  1.1     is 	mov.w		&0x4008,-0x8+0xa+LOCAL_SIZE(%sp)
   3064  1.1     is 	mov.l		%a0,-0x8+0xc+LOCAL_SIZE(%sp)
   3065  1.1     is 	mov.w		%d0,-0x8+0x10+LOCAL_SIZE(%sp)
   3066  1.1     is 	mov.w		&0x0001,-0x8+0x12+LOCAL_SIZE(%sp)
   3067  1.1     is 
   3068  1.1     is 	movm.l		LOCAL_SIZE+EXC_DREGS(%sp),&0x0303 # restore d0-d1/a0-a1
   3069  1.1     is 	add.w		&LOCAL_SIZE-0x4,%sp
   3070  1.1     is 
   3071  1.1     is 	bra.b		iea_acc_done
   3072  1.1     is 
   3073  1.1     is #########################################################################
   3074  1.1     is # XDEF ****************************************************************	#
   3075  1.1     is #	_fpsp_operr(): 060FPSP entry point for FP Operr exception.	#
   3076  1.1     is #									#
   3077  1.1     is #	This handler should be the first code executed upon taking the	#
   3078  1.1     is # 	FP Operand Error exception in an operating system.		#
   3079  1.1     is #									#
   3080  1.1     is # XREF ****************************************************************	#
   3081  1.1     is #	_imem_read_long() - read instruction longword			#
   3082  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
   3083  1.1     is #	_real_operr() - "callout" to operating system operr handler	#
   3084  1.1     is #	_dmem_write_{byte,word,long}() - store data to mem (opclass 3)	#
   3085  1.1     is #	store_dreg_{b,w,l}() - store data to data regfile (opclass 3)	#
   3086  1.1     is #	facc_out_{b,w,l}() - store to memory took access error (opcl 3)	#
   3087  1.1     is #									#
   3088  1.1     is # INPUT ***************************************************************	#
   3089  1.1     is #	- The system stack contains the FP Operr exception frame	#
   3090  1.1     is #	- The fsave frame contains the source operand			#
   3091  1.1     is # 									#
   3092  1.1     is # OUTPUT **************************************************************	#
   3093  1.1     is #	No access error:						#
   3094  1.1     is #	- The system stack is unchanged					#
   3095  1.1     is #	- The fsave frame contains the adjusted src op for opclass 0,2	#
   3096  1.1     is #									#
   3097  1.1     is # ALGORITHM ***********************************************************	#
   3098  1.1     is #	In a system where the FP Operr exception is enabled, the goal	#
   3099  1.1     is # is to get to the handler specified at _real_operr(). But, on the 060,	#
   3100  1.1     is # for opclass zero and two instruction taking this exception, the 	#
   3101  1.1     is # input operand in the fsave frame may be incorrect for some cases	#
   3102  1.1     is # and needs to be corrected. This handler calls fix_skewed_ops() to	#
   3103  1.1     is # do just this and then exits through _real_operr().			#
   3104  1.1     is #	For opclass 3 instructions, the 060 doesn't store the default	#
   3105  1.1     is # operr result out to memory or data register file as it should.	#
   3106  1.1     is # This code must emulate the move out before finally exiting through	#
   3107  1.1     is # _real_inex(). The move out, if to memory, is performed using 		#
   3108  1.1     is # _mem_write() "callout" routines that may return a failing result.	#
   3109  1.1     is # In this special case, the handler must exit through facc_out() 	#
   3110  1.1     is # which creates an access error stack frame from the current operr	#
   3111  1.1     is # stack frame.								#
   3112  1.1     is #									#
   3113  1.1     is #########################################################################
   3114  1.1     is 
   3115  1.1     is 	global		_fpsp_operr
   3116  1.1     is _fpsp_operr:
   3117  1.1     is 
   3118  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3119  1.1     is 
   3120  1.1     is 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3121  1.1     is 
   3122  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3123  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3124  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3125  1.1     is 
   3126  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
   3127  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3128  1.1     is 
   3129  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3130  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3131  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   3132  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
   3133  1.1     is 
   3134  1.1     is ##############################################################################
   3135  1.1     is 
   3136  1.1     is 	btst		&13,%d0			# is instr an fmove out?
   3137  1.1     is 	bne.b		foperr_out		# fmove out
   3138  1.1     is 
   3139  1.1     is 
   3140  1.1     is # here, we simply see if the operand in the fsave frame needs to be "unskewed".
   3141  1.1     is # this would be the case for opclass two operations with a source infinity or
   3142  1.1     is # denorm operand in the sgl or dbl format. NANs also become skewed, but can't
   3143  1.1     is # cause an operr so we don't need to check for them here.
   3144  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3145  1.1     is 	bsr.l		fix_skewed_ops		# fix src op
   3146  1.1     is 
   3147  1.1     is foperr_exit:
   3148  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3149  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3150  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3151  1.1     is 
   3152  1.1     is 	frestore	FP_SRC(%a6)
   3153  1.1     is 
   3154  1.1     is 	unlk		%a6
   3155  1.1     is 	bra.l		_real_operr
   3156  1.1     is 
   3157  1.1     is ########################################################################
   3158  1.1     is 
   3159  1.1     is #
   3160  1.1     is # the hardware does not save the default result to memory on enabled
   3161  1.1     is # operand error exceptions. we do this here before passing control to
   3162  1.1     is # the user operand error handler.
   3163  1.1     is #
   3164  1.1     is # byte, word, and long destination format operations can pass
   3165  1.1     is # through here. we simply need to test the sign of the src
   3166  1.1     is # operand and save the appropriate minimum or maximum integer value
   3167  1.1     is # to the effective address as pointed to by the stacked effective address.
   3168  1.1     is #
   3169  1.1     is # although packed opclass three operations can take operand error
   3170  1.1     is # exceptions, they won't pass through here since they are caught
   3171  1.1     is # first by the unsupported data format exception handler. that handler
   3172  1.1     is # sends them directly to _real_operr() if necessary.
   3173  1.1     is #
   3174  1.1     is foperr_out:
   3175  1.1     is 
   3176  1.1     is 	mov.w		FP_SRC_EX(%a6),%d1	# fetch exponent
   3177  1.1     is 	andi.w		&0x7fff,%d1
   3178  1.1     is 	cmpi.w		%d1,&0x7fff
   3179  1.1     is 	bne.b		foperr_out_not_qnan
   3180  1.1     is # the operand is either an infinity or a QNAN.
   3181  1.1     is 	tst.l		FP_SRC_LO(%a6)
   3182  1.1     is 	bne.b		foperr_out_qnan
   3183  1.1     is 	mov.l		FP_SRC_HI(%a6),%d1
   3184  1.1     is 	andi.l		&0x7fffffff,%d1
   3185  1.1     is 	beq.b		foperr_out_not_qnan
   3186  1.1     is foperr_out_qnan:
   3187  1.1     is 	mov.l		FP_SRC_HI(%a6),L_SCR1(%a6)
   3188  1.1     is 	bra.b		foperr_out_jmp
   3189  1.1     is 
   3190  1.1     is foperr_out_not_qnan:
   3191  1.1     is 	mov.l		&0x7fffffff,%d1
   3192  1.1     is 	tst.b		FP_SRC_EX(%a6)
   3193  1.1     is 	bpl.b		foperr_out_not_qnan2
   3194  1.1     is 	addq.l		&0x1,%d1
   3195  1.1     is foperr_out_not_qnan2:
   3196  1.1     is 	mov.l		%d1,L_SCR1(%a6)
   3197  1.1     is 
   3198  1.1     is foperr_out_jmp:
   3199  1.1     is 	bfextu		%d0{&19:&3},%d0		# extract dst format field
   3200  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract <ea> mode,reg
   3201  1.1     is 	mov.w		(tbl_operr.b,%pc,%d0.w*2),%a0
   3202  1.1     is 	jmp		(tbl_operr.b,%pc,%a0)
   3203  1.1     is 
   3204  1.1     is tbl_operr:
   3205  1.1     is 	short		foperr_out_l - tbl_operr # long word integer
   3206  1.1     is 	short		tbl_operr    - tbl_operr # sgl prec shouldn't happen
   3207  1.1     is 	short		tbl_operr    - tbl_operr # ext prec shouldn't happen
   3208  1.1     is 	short		foperr_exit  - tbl_operr # packed won't enter here
   3209  1.1     is 	short		foperr_out_w - tbl_operr # word integer
   3210  1.1     is 	short		tbl_operr    - tbl_operr # dbl prec shouldn't happen
   3211  1.1     is 	short		foperr_out_b - tbl_operr # byte integer
   3212  1.1     is 	short		tbl_operr    - tbl_operr # packed won't enter here
   3213  1.1     is 
   3214  1.1     is foperr_out_b:
   3215  1.1     is 	mov.b		L_SCR1(%a6),%d0		# load positive default result
   3216  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3217  1.1     is 	ble.b		foperr_out_b_save_dn	# yes
   3218  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3219  1.1     is 	bsr.l		_dmem_write_byte	# write the default result
   3220  1.1     is 
   3221  1.1     is 	tst.l		%d1			# did dstore fail?
   3222  1.1     is 	bne.l		facc_out_b		# yes
   3223  1.1     is 
   3224  1.1     is 	bra.w		foperr_exit
   3225  1.1     is foperr_out_b_save_dn:
   3226  1.1     is 	andi.w		&0x0007,%d1
   3227  1.1     is 	bsr.l		store_dreg_b		# store result to regfile
   3228  1.1     is 	bra.w		foperr_exit
   3229  1.1     is 
   3230  1.1     is foperr_out_w:
   3231  1.1     is 	mov.w		L_SCR1(%a6),%d0		# load positive default result
   3232  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3233  1.1     is 	ble.b		foperr_out_w_save_dn	# yes
   3234  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3235  1.1     is 	bsr.l		_dmem_write_word	# write the default result
   3236  1.1     is 
   3237  1.1     is 	tst.l		%d1			# did dstore fail?
   3238  1.1     is 	bne.l		facc_out_w		# yes
   3239  1.1     is 
   3240  1.1     is 	bra.w		foperr_exit
   3241  1.1     is foperr_out_w_save_dn:
   3242  1.1     is 	andi.w		&0x0007,%d1
   3243  1.1     is 	bsr.l		store_dreg_w		# store result to regfile
   3244  1.1     is 	bra.w		foperr_exit
   3245  1.1     is 
   3246  1.1     is foperr_out_l:
   3247  1.1     is 	mov.l		L_SCR1(%a6),%d0		# load positive default result
   3248  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3249  1.1     is 	ble.b		foperr_out_l_save_dn	# yes
   3250  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3251  1.1     is 	bsr.l		_dmem_write_long	# write the default result
   3252  1.1     is 
   3253  1.1     is 	tst.l		%d1			# did dstore fail?
   3254  1.1     is 	bne.l		facc_out_l		# yes
   3255  1.1     is 
   3256  1.1     is 	bra.w		foperr_exit
   3257  1.1     is foperr_out_l_save_dn:
   3258  1.1     is 	andi.w		&0x0007,%d1
   3259  1.1     is 	bsr.l		store_dreg_l		# store result to regfile
   3260  1.1     is 	bra.w		foperr_exit
   3261  1.1     is 
   3262  1.1     is #########################################################################
   3263  1.1     is # XDEF ****************************************************************	#
   3264  1.1     is #	_fpsp_snan(): 060FPSP entry point for FP SNAN exception.	#
   3265  1.1     is #									#
   3266  1.1     is #	This handler should be the first code executed upon taking the	#
   3267  1.1     is # 	FP Signalling NAN exception in an operating system.		#
   3268  1.1     is #									#
   3269  1.1     is # XREF ****************************************************************	#
   3270  1.1     is #	_imem_read_long() - read instruction longword			#
   3271  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
   3272  1.1     is #	_real_snan() - "callout" to operating system SNAN handler	#
   3273  1.1     is #	_dmem_write_{byte,word,long}() - store data to mem (opclass 3)	#
   3274  1.1     is #	store_dreg_{b,w,l}() - store data to data regfile (opclass 3)	#
   3275  1.1     is #	facc_out_{b,w,l,d,x}() - store to mem took acc error (opcl 3)	#
   3276  1.1     is #	_calc_ea_fout() - fix An if <ea> is -() or ()+; also get <ea>	#
   3277  1.1     is #									#
   3278  1.1     is # INPUT ***************************************************************	#
   3279  1.1     is #	- The system stack contains the FP SNAN exception frame		#
   3280  1.1     is #	- The fsave frame contains the source operand			#
   3281  1.1     is # 									#
   3282  1.1     is # OUTPUT **************************************************************	#
   3283  1.1     is #	No access error:						#
   3284  1.1     is #	- The system stack is unchanged					#
   3285  1.1     is #	- The fsave frame contains the adjusted src op for opclass 0,2	#
   3286  1.1     is #									#
   3287  1.1     is # ALGORITHM ***********************************************************	#
   3288  1.1     is #	In a system where the FP SNAN exception is enabled, the goal	#
   3289  1.1     is # is to get to the handler specified at _real_snan(). But, on the 060,	#
   3290  1.1     is # for opclass zero and two instructions taking this exception, the 	#
   3291  1.1     is # input operand in the fsave frame may be incorrect for some cases	#
   3292  1.1     is # and needs to be corrected. This handler calls fix_skewed_ops() to	#
   3293  1.1     is # do just this and then exits through _real_snan().			#
   3294  1.1     is #	For opclass 3 instructions, the 060 doesn't store the default	#
   3295  1.1     is # SNAN result out to memory or data register file as it should.		#
   3296  1.1     is # This code must emulate the move out before finally exiting through	#
   3297  1.1     is # _real_snan(). The move out, if to memory, is performed using 		#
   3298  1.1     is # _mem_write() "callout" routines that may return a failing result.	#
   3299  1.1     is # In this special case, the handler must exit through facc_out() 	#
   3300  1.1     is # which creates an access error stack frame from the current SNAN	#
   3301  1.1     is # stack frame.								#
   3302  1.1     is #	For the case of an extended precision opclass 3 instruction,	#
   3303  1.1     is # if the effective addressing mode was -() or ()+, then the address	#
   3304  1.1     is # register must get updated by calling _calc_ea_fout(). If the <ea>	#
   3305  1.1     is # was -(a7) from supervisor mode, then the exception frame currently	#
   3306  1.1     is # on the system stack must be carefully moved "down" to make room	#
   3307  1.1     is # for the operand being moved.						#
   3308  1.1     is #									#
   3309  1.1     is #########################################################################
   3310  1.1     is 
   3311  1.1     is 	global		_fpsp_snan
   3312  1.1     is _fpsp_snan:
   3313  1.1     is 
   3314  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3315  1.1     is 
   3316  1.1     is 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3317  1.1     is 
   3318  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3319  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3320  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3321  1.1     is 
   3322  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
   3323  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3324  1.1     is 
   3325  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3326  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3327  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   3328  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
   3329  1.1     is 
   3330  1.1     is ##############################################################################
   3331  1.1     is 
   3332  1.1     is 	btst		&13,%d0			# is instr an fmove out?
   3333  1.1     is 	bne.w		fsnan_out		# fmove out
   3334  1.1     is 
   3335  1.1     is 
   3336  1.1     is # here, we simply see if the operand in the fsave frame needs to be "unskewed".
   3337  1.1     is # this would be the case for opclass two operations with a source infinity or
   3338  1.1     is # denorm operand in the sgl or dbl format. NANs also become skewed and must be
   3339  1.1     is # fixed here.
   3340  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3341  1.1     is 	bsr.l		fix_skewed_ops		# fix src op
   3342  1.1     is 
   3343  1.1     is fsnan_exit:
   3344  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3345  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3346  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3347  1.1     is 
   3348  1.1     is 	frestore	FP_SRC(%a6)
   3349  1.1     is 
   3350  1.1     is 	unlk		%a6
   3351  1.1     is 	bra.l		_real_snan
   3352  1.1     is 
   3353  1.1     is ########################################################################
   3354  1.1     is 
   3355  1.1     is #
   3356  1.1     is # the hardware does not save the default result to memory on enabled
   3357  1.1     is # snan exceptions. we do this here before passing control to
   3358  1.1     is # the user snan handler.
   3359  1.1     is #
   3360  1.1     is # byte, word, long, and packed destination format operations can pass
   3361  1.1     is # through here. since packed format operations already were handled by
   3362  1.1     is # fpsp_unsupp(), then we need to do nothing else for them here.
   3363  1.1     is # for byte, word, and long, we simply need to test the sign of the src
   3364  1.1     is # operand and save the appropriate minimum or maximum integer value
   3365  1.1     is # to the effective address as pointed to by the stacked effective address.
   3366  1.1     is #
   3367  1.1     is fsnan_out:
   3368  1.1     is 
   3369  1.1     is 	bfextu		%d0{&19:&3},%d0		# extract dst format field
   3370  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract <ea> mode,reg
   3371  1.1     is 	mov.w		(tbl_snan.b,%pc,%d0.w*2),%a0
   3372  1.1     is 	jmp		(tbl_snan.b,%pc,%a0)
   3373  1.1     is 
   3374  1.1     is tbl_snan:
   3375  1.1     is 	short		fsnan_out_l - tbl_snan # long word integer
   3376  1.1     is 	short		fsnan_out_s - tbl_snan # sgl prec shouldn't happen
   3377  1.1     is 	short		fsnan_out_x - tbl_snan # ext prec shouldn't happen
   3378  1.1     is 	short		tbl_snan    - tbl_snan # packed needs no help
   3379  1.1     is 	short		fsnan_out_w - tbl_snan # word integer
   3380  1.1     is 	short		fsnan_out_d - tbl_snan # dbl prec shouldn't happen
   3381  1.1     is 	short		fsnan_out_b - tbl_snan # byte integer
   3382  1.1     is 	short		tbl_snan    - tbl_snan # packed needs no help
   3383  1.1     is 
   3384  1.1     is fsnan_out_b:
   3385  1.1     is 	mov.b		FP_SRC_HI(%a6),%d0	# load upper byte of SNAN
   3386  1.1     is 	bset		&6,%d0			# set SNAN bit
   3387  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3388  1.1     is 	ble.b		fsnan_out_b_dn		# yes
   3389  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3390  1.1     is 	bsr.l		_dmem_write_byte	# write the default result
   3391  1.1     is 
   3392  1.1     is 	tst.l		%d1			# did dstore fail?
   3393  1.1     is 	bne.l		facc_out_b		# yes
   3394  1.1     is 
   3395  1.1     is 	bra.w		fsnan_exit
   3396  1.1     is fsnan_out_b_dn:
   3397  1.1     is 	andi.w		&0x0007,%d1
   3398  1.1     is 	bsr.l		store_dreg_b		# store result to regfile
   3399  1.1     is 	bra.w		fsnan_exit
   3400  1.1     is 
   3401  1.1     is fsnan_out_w:
   3402  1.1     is 	mov.w		FP_SRC_HI(%a6),%d0	# load upper word of SNAN
   3403  1.1     is 	bset		&14,%d0			# set SNAN bit
   3404  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3405  1.1     is 	ble.b		fsnan_out_w_dn		# yes
   3406  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3407  1.1     is 	bsr.l		_dmem_write_word	# write the default result
   3408  1.1     is 
   3409  1.1     is 	tst.l		%d1			# did dstore fail?
   3410  1.1     is 	bne.l		facc_out_w		# yes
   3411  1.1     is 
   3412  1.1     is 	bra.w		fsnan_exit
   3413  1.1     is fsnan_out_w_dn:
   3414  1.1     is 	andi.w		&0x0007,%d1
   3415  1.1     is 	bsr.l		store_dreg_w		# store result to regfile
   3416  1.1     is 	bra.w		fsnan_exit
   3417  1.1     is 
   3418  1.1     is fsnan_out_l:
   3419  1.1     is 	mov.l		FP_SRC_HI(%a6),%d0	# load upper longword of SNAN
   3420  1.1     is 	bset		&30,%d0			# set SNAN bit
   3421  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3422  1.1     is 	ble.b		fsnan_out_l_dn		# yes
   3423  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3424  1.1     is 	bsr.l		_dmem_write_long	# write the default result
   3425  1.1     is 
   3426  1.1     is 	tst.l		%d1			# did dstore fail?
   3427  1.1     is 	bne.l		facc_out_l		# yes
   3428  1.1     is 
   3429  1.1     is 	bra.w		fsnan_exit
   3430  1.1     is fsnan_out_l_dn:
   3431  1.1     is 	andi.w		&0x0007,%d1
   3432  1.1     is 	bsr.l		store_dreg_l		# store result to regfile
   3433  1.1     is 	bra.w		fsnan_exit
   3434  1.1     is 
   3435  1.1     is fsnan_out_s:
   3436  1.1     is 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3437  1.1     is 	ble.b		fsnan_out_d_dn		# yes
   3438  1.1     is 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
   3439  1.1     is 	andi.l		&0x80000000,%d0		# keep sign
   3440  1.1     is 	ori.l		&0x7fc00000,%d0		# insert new exponent,SNAN bit
   3441  1.1     is 	mov.l		FP_SRC_HI(%a6),%d1	# load mantissa
   3442  1.1     is 	lsr.l		&0x8,%d1		# shift mantissa for sgl
   3443  1.1     is 	or.l		%d1,%d0			# create sgl SNAN
   3444  1.1     is 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3445  1.1     is 	bsr.l		_dmem_write_long	# write the default result
   3446  1.1     is 
   3447  1.1     is 	tst.l		%d1			# did dstore fail?
   3448  1.1     is 	bne.l		facc_out_l		# yes
   3449  1.1     is 
   3450  1.1     is 	bra.w		fsnan_exit
   3451  1.1     is fsnan_out_d_dn:
   3452  1.1     is 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
   3453  1.1     is 	andi.l		&0x80000000,%d0		# keep sign
   3454  1.1     is 	ori.l		&0x7fc00000,%d0		# insert new exponent,SNAN bit
   3455  1.1     is 	mov.l		%d1,-(%sp)
   3456  1.1     is 	mov.l		FP_SRC_HI(%a6),%d1	# load mantissa
   3457  1.1     is 	lsr.l		&0x8,%d1		# shift mantissa for sgl
   3458  1.1     is 	or.l		%d1,%d0			# create sgl SNAN
   3459  1.1     is 	mov.l		(%sp)+,%d1
   3460  1.1     is 	andi.w		&0x0007,%d1
   3461  1.1     is 	bsr.l		store_dreg_l		# store result to regfile
   3462  1.1     is 	bra.w		fsnan_exit
   3463  1.1     is 
   3464  1.1     is fsnan_out_d:
   3465  1.1     is 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
   3466  1.1     is 	andi.l		&0x80000000,%d0		# keep sign
   3467  1.1     is 	ori.l		&0x7ff80000,%d0		# insert new exponent,SNAN bit
   3468  1.1     is 	mov.l		FP_SRC_HI(%a6),%d1	# load hi mantissa
   3469  1.1     is 	mov.l		%d0,FP_SCR0_EX(%a6)	# store to temp space
   3470  1.1     is 	mov.l		&11,%d0			# load shift amt
   3471  1.1     is 	lsr.l		%d0,%d1
   3472  1.1     is 	or.l		%d1,FP_SCR0_EX(%a6)	# create dbl hi
   3473  1.1     is 	mov.l		FP_SRC_HI(%a6),%d1	# load hi mantissa
   3474  1.1     is 	andi.l		&0x000007ff,%d1
   3475  1.1     is 	ror.l		%d0,%d1
   3476  1.1     is 	mov.l		%d1,FP_SCR0_HI(%a6)	# store to temp space
   3477  1.1     is 	mov.l		FP_SRC_LO(%a6),%d1	# load lo mantissa
   3478  1.1     is 	lsr.l		%d0,%d1
   3479  1.1     is 	or.l		%d1,FP_SCR0_HI(%a6)	# create dbl lo
   3480  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   3481  1.1     is 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   3482  1.1     is 	movq.l		&0x8,%d0		# pass: size of 8 bytes
   3483  1.1     is 	bsr.l		_dmem_write		# write the default result
   3484  1.1     is 
   3485  1.1     is 	tst.l		%d1			# did dstore fail?
   3486  1.1     is 	bne.l		facc_out_d		# yes
   3487  1.1     is 
   3488  1.1     is 	bra.w		fsnan_exit
   3489  1.1     is 
   3490  1.1     is # for extended precision, if the addressing mode is pre-decrement or
   3491  1.1     is # post-increment, then the address register did not get updated.
   3492  1.1     is # in addition, for pre-decrement, the stacked <ea> is incorrect.
   3493  1.1     is fsnan_out_x:
   3494  1.1     is 	clr.b		SPCOND_FLG(%a6)		# clear special case flag
   3495  1.1     is 
   3496  1.1     is 	mov.w		FP_SRC_EX(%a6),FP_SCR0_EX(%a6)
   3497  1.1     is 	clr.w		2+FP_SCR0(%a6)
   3498  1.1     is 	mov.l		FP_SRC_HI(%a6),%d0
   3499  1.1     is 	bset		&30,%d0
   3500  1.1     is 	mov.l		%d0,FP_SCR0_HI(%a6)
   3501  1.1     is 	mov.l		FP_SRC_LO(%a6),FP_SCR0_LO(%a6)
   3502  1.1     is 
   3503  1.1     is 	btst		&0x5,EXC_SR(%a6)	# supervisor mode exception?
   3504  1.1     is 	bne.b		fsnan_out_x_s		# yes
   3505  1.1     is 
   3506  1.1     is 	mov.l		%usp,%a0		# fetch user stack pointer
   3507  1.1     is 	mov.l		%a0,EXC_A7(%a6)		# save on stack for calc_ea()
   3508  1.1     is 	mov.l		(%a6),EXC_A6(%a6)
   3509  1.1     is 
   3510  1.1     is 	bsr.l		_calc_ea_fout		# find the correct ea,update An
   3511  1.1     is 	mov.l		%a0,%a1
   3512  1.1     is 	mov.l		%a0,EXC_EA(%a6)		# stack correct <ea>
   3513  1.1     is 
   3514  1.1     is 	mov.l		EXC_A7(%a6),%a0
   3515  1.1     is 	mov.l		%a0,%usp		# restore user stack pointer
   3516  1.1     is 	mov.l		EXC_A6(%a6),(%a6)
   3517  1.1     is 
   3518  1.1     is fsnan_out_x_save:
   3519  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   3520  1.1     is 	movq.l		&0xc,%d0		# pass: size of extended
   3521  1.1     is 	bsr.l		_dmem_write		# write the default result
   3522  1.1     is 
   3523  1.1     is 	tst.l		%d1			# did dstore fail?
   3524  1.1     is 	bne.l		facc_out_x		# yes
   3525  1.1     is 
   3526  1.1     is 	bra.w		fsnan_exit
   3527  1.1     is 
   3528  1.1     is fsnan_out_x_s:
   3529  1.1     is 	mov.l		(%a6),EXC_A6(%a6)
   3530  1.1     is 
   3531  1.1     is 	bsr.l		_calc_ea_fout		# find the correct ea,update An
   3532  1.1     is 	mov.l		%a0,%a1
   3533  1.1     is 	mov.l		%a0,EXC_EA(%a6)		# stack correct <ea>
   3534  1.1     is 
   3535  1.1     is 	mov.l		EXC_A6(%a6),(%a6)
   3536  1.1     is 
   3537  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
   3538  1.1     is 	bne.b		fsnan_out_x_save	# no
   3539  1.1     is 
   3540  1.1     is # the operation was "fmove.x SNAN,-(a7)" from supervisor mode.
   3541  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3542  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3543  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3544  1.1     is 
   3545  1.1     is 	frestore	FP_SRC(%a6)
   3546  1.1     is 
   3547  1.1     is 	mov.l		EXC_A6(%a6),%a6		# restore frame pointer
   3548  1.1     is 
   3549  1.1     is 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   3550  1.1     is 	mov.l		LOCAL_SIZE+EXC_PC+0x2(%sp),LOCAL_SIZE+EXC_PC+0x2-0xc(%sp)
   3551  1.1     is 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   3552  1.1     is 
   3553  1.1     is 	mov.l		LOCAL_SIZE+FP_SCR0_EX(%sp),LOCAL_SIZE+EXC_SR(%sp)
   3554  1.1     is 	mov.l		LOCAL_SIZE+FP_SCR0_HI(%sp),LOCAL_SIZE+EXC_PC+0x2(%sp)
   3555  1.1     is 	mov.l		LOCAL_SIZE+FP_SCR0_LO(%sp),LOCAL_SIZE+EXC_EA(%sp)
   3556  1.1     is 
   3557  1.1     is 	add.l		&LOCAL_SIZE-0x8,%sp
   3558  1.1     is 
   3559  1.1     is 	bra.l		_real_snan
   3560  1.1     is 
   3561  1.1     is #########################################################################
   3562  1.1     is # XDEF ****************************************************************	#
   3563  1.1     is #	_fpsp_inex(): 060FPSP entry point for FP Inexact exception.	#
   3564  1.1     is #									#
   3565  1.1     is #	This handler should be the first code executed upon taking the	#
   3566  1.1     is # 	FP Inexact exception in an operating system.			#
   3567  1.1     is #									#
   3568  1.1     is # XREF ****************************************************************	#
   3569  1.1     is #	_imem_read_long() - read instruction longword			#
   3570  1.1     is #	fix_skewed_ops() - adjust src operand in fsave frame		#
   3571  1.1     is #	set_tag_x() - determine optype of src/dst operands		#
   3572  1.1     is #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   3573  1.1     is #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
   3574  1.1     is #	load_fpn2() - load dst operand from FP regfile			#
   3575  1.1     is #	smovcr() - emulate an "fmovcr" instruction			#
   3576  1.1     is #	fout() - emulate an opclass 3 instruction			#
   3577  1.1     is #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
   3578  1.1     is #	_real_inex() - "callout" to operating system inexact handler	#
   3579  1.1     is #									#
   3580  1.1     is # INPUT ***************************************************************	#
   3581  1.1     is #	- The system stack contains the FP Inexact exception frame	#
   3582  1.1     is #	- The fsave frame contains the source operand			#
   3583  1.1     is # 									#
   3584  1.1     is # OUTPUT **************************************************************	#
   3585  1.1     is #	- The system stack is unchanged					#
   3586  1.1     is #	- The fsave frame contains the adjusted src op for opclass 0,2	#
   3587  1.1     is #									#
   3588  1.1     is # ALGORITHM ***********************************************************	#
   3589  1.1     is #	In a system where the FP Inexact exception is enabled, the goal	#
   3590  1.1     is # is to get to the handler specified at _real_inex(). But, on the 060,	#
   3591  1.1     is # for opclass zero and two instruction taking this exception, the 	#
   3592  1.1     is # hardware doesn't store the correct result to the destination FP	#
   3593  1.1     is # register as did the '040 and '881/2. This handler must emulate the 	#
   3594  1.1     is # instruction in order to get this value and then store it to the 	#
   3595  1.1     is # correct register before calling _real_inex().				#
   3596  1.1     is #	For opclass 3 instructions, the 060 doesn't store the default	#
   3597  1.1     is # inexact result out to memory or data register file as it should.	#
   3598  1.1     is # This code must emulate the move out by calling fout() before finally	#
   3599  1.1     is # exiting through _real_inex().						#
   3600  1.1     is #									#
   3601  1.1     is #########################################################################
   3602  1.1     is 
   3603  1.1     is 	global		_fpsp_inex
   3604  1.1     is _fpsp_inex:
   3605  1.1     is 
   3606  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3607  1.1     is 
   3608  1.1     is 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3609  1.1     is 
   3610  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3611  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3612  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3613  1.1     is 
   3614  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
   3615  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3616  1.1     is 
   3617  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3618  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3619  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   3620  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
   3621  1.1     is 
   3622  1.1     is ##############################################################################
   3623  1.1     is 
   3624  1.1     is 	btst		&13,%d0			# is instr an fmove out?
   3625  1.1     is 	bne.w		finex_out		# fmove out
   3626  1.1     is 
   3627  1.1     is 
   3628  1.1     is # the hardware, for "fabs" and "fneg" w/ a long source format, puts the
   3629  1.1     is # longword integer directly into the upper longword of the mantissa along
   3630  1.1     is # w/ an exponent value of 0x401e. we convert this to extended precision here.
   3631  1.1     is 	bfextu		%d0{&19:&3},%d0		# fetch instr size
   3632  1.1     is 	bne.b		finex_cont		# instr size is not long
   3633  1.1     is 	cmpi.w		FP_SRC_EX(%a6),&0x401e	# is exponent 0x401e?
   3634  1.1     is 	bne.b		finex_cont		# no
   3635  1.1     is 	fmov.l		&0x0,%fpcr
   3636  1.1     is 	fmov.l		FP_SRC_HI(%a6),%fp0	# load integer src
   3637  1.1     is 	fmov.x		%fp0,FP_SRC(%a6)	# store integer as extended precision
   3638  1.1     is 	mov.w		&0xe001,0x2+FP_SRC(%a6)
   3639  1.1     is 
   3640  1.1     is finex_cont:
   3641  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3642  1.1     is 	bsr.l		fix_skewed_ops		# fix src op
   3643  1.1     is 
   3644  1.1     is # Here, we zero the ccode and exception byte field since we're going to
   3645  1.1     is # emulate the whole instruction. Notice, though, that we don't kill the
   3646  1.1     is # INEX1 bit. This is because a packed op has long since been converted
   3647  1.1     is # to extended before arriving here. Therefore, we need to retain the
   3648  1.1     is # INEX1 bit from when the operand was first converted.
   3649  1.1     is 	andi.l		&0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
   3650  1.1     is 
   3651  1.1     is 	fmov.l		&0x0,%fpcr		# zero current control regs
   3652  1.1     is 	fmov.l		&0x0,%fpsr
   3653  1.1     is 
   3654  1.1     is 	bfextu		EXC_EXTWORD(%a6){&0:&6},%d1 # extract upper 6 of cmdreg
   3655  1.1     is 	cmpi.b		%d1,&0x17		# is op an fmovecr?
   3656  1.1     is 	beq.w		finex_fmovcr		# yes
   3657  1.1     is 
   3658  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3659  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   3660  1.1     is 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
   3661  1.1     is 
   3662  1.1     is # bits four and five of the fp extension word separate the monadic and dyadic
   3663  1.1     is # operations that can pass through fpsp_inex(). remember that fcmp and ftst
   3664  1.1     is # will never take this exception, but fsincos will.
   3665  1.1     is 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   3666  1.1     is 	beq.b		finex_extract		# monadic
   3667  1.1     is 
   3668  1.1     is 	btst		&0x4,1+EXC_CMDREG(%a6)	# is operation an fsincos?
   3669  1.1     is 	bne.b		finex_extract		# yes
   3670  1.1     is 
   3671  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   3672  1.1     is 	bsr.l		load_fpn2		# load dst into FP_DST
   3673  1.1     is 
   3674  1.1     is 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   3675  1.1     is 	bsr.l		set_tag_x		# tag the operand type
   3676  1.1     is 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   3677  1.1     is 	bne.b		finex_op2_done		# no
   3678  1.1     is 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   3679  1.1     is finex_op2_done:
   3680  1.1     is 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
   3681  1.1     is 
   3682  1.1     is finex_extract:
   3683  1.1     is 	clr.l		%d0
   3684  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
   3685  1.1     is 
   3686  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
   3687  1.1     is 	andi.w		&0x007f,%d1		# extract extension
   3688  1.1     is 
   3689  1.1     is 	lea		FP_SRC(%a6),%a0
   3690  1.1     is 	lea		FP_DST(%a6),%a1
   3691  1.1     is 
   3692  1.1     is 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
   3693  1.1     is 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   3694  1.1     is 
   3695  1.1     is # the operation has been emulated. the result is in fp0.
   3696  1.1     is finex_save:
   3697  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
   3698  1.1     is 	bsr.l		store_fpreg
   3699  1.1     is 
   3700  1.1     is finex_exit:
   3701  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3702  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3703  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3704  1.1     is 
   3705  1.1     is 	frestore	FP_SRC(%a6)
   3706  1.1     is 
   3707  1.1     is 	unlk		%a6
   3708  1.1     is 	bra.l		_real_inex
   3709  1.1     is 
   3710  1.1     is finex_fmovcr:
   3711  1.1     is 	clr.l		%d0
   3712  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec,mode
   3713  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
   3714  1.1     is 	andi.l		&0x0000007f,%d1		# pass rom offset
   3715  1.1     is 	bsr.l		smovcr
   3716  1.1     is 	bra.b		finex_save
   3717  1.1     is 
   3718  1.1     is ########################################################################
   3719  1.1     is 
   3720  1.1     is #
   3721  1.1     is # the hardware does not save the default result to memory on enabled
   3722  1.1     is # inexact exceptions. we do this here before passing control to
   3723  1.1     is # the user inexact handler.
   3724  1.1     is #
   3725  1.1     is # byte, word, and long destination format operations can pass
   3726  1.1     is # through here. so can double and single precision.
   3727  1.1     is # although packed opclass three operations can take inexact
   3728  1.1     is # exceptions, they won't pass through here since they are caught
   3729  1.1     is # first by the unsupported data format exception handler. that handler
   3730  1.1     is # sends them directly to _real_inex() if necessary.
   3731  1.1     is #
   3732  1.1     is finex_out:
   3733  1.1     is 
   3734  1.1     is 	mov.b		&NORM,STAG(%a6)		# src is a NORM
   3735  1.1     is 
   3736  1.1     is 	clr.l		%d0
   3737  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec,mode
   3738  1.1     is 
   3739  1.1     is 	andi.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
   3740  1.1     is 
   3741  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   3742  1.1     is 
   3743  1.1     is 	bsr.l		fout			# store the default result
   3744  1.1     is 
   3745  1.1     is 	bra.b		finex_exit
   3746  1.1     is 
   3747  1.1     is #########################################################################
   3748  1.1     is # XDEF ****************************************************************	#
   3749  1.1     is #	_fpsp_dz(): 060FPSP entry point for FP DZ exception.		#
   3750  1.1     is #									#
   3751  1.1     is #	This handler should be the first code executed upon taking	#
   3752  1.1     is #	the FP DZ exception in an operating system.			#
   3753  1.1     is #									#
   3754  1.1     is # XREF ****************************************************************	#
   3755  1.1     is #	_imem_read_long() - read instruction longword from memory	#
   3756  1.1     is #	fix_skewed_ops() - adjust fsave operand				#
   3757  1.1     is #	_real_dz() - "callout" exit point from FP DZ handler		#
   3758  1.1     is #									#
   3759  1.1     is # INPUT ***************************************************************	#
   3760  1.1     is #	- The system stack contains the FP DZ exception stack.		#
   3761  1.1     is #	- The fsave frame contains the source operand.			#
   3762  1.1     is # 									#
   3763  1.1     is # OUTPUT **************************************************************	#
   3764  1.1     is #	- The system stack contains the FP DZ exception stack.		#
   3765  1.1     is #	- The fsave frame contains the adjusted source operand.		#
   3766  1.1     is #									#
   3767  1.1     is # ALGORITHM ***********************************************************	#
   3768  1.1     is #	In a system where the DZ exception is enabled, the goal is to	#
   3769  1.1     is # get to the handler specified at _real_dz(). But, on the 060, when the	#
   3770  1.1     is # exception is taken, the input operand in the fsave state frame may	#
   3771  1.1     is # be incorrect for some cases and need to be adjusted. So, this package	#
   3772  1.1     is # adjusts the operand using fix_skewed_ops() and then branches to	#
   3773  1.1     is # _real_dz(). 								#
   3774  1.1     is #									#
   3775  1.1     is #########################################################################
   3776  1.1     is 
   3777  1.1     is 	global		_fpsp_dz
   3778  1.1     is _fpsp_dz:
   3779  1.1     is 
   3780  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3781  1.1     is 
   3782  1.1     is 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3783  1.1     is 
   3784  1.1     is  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3785  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3786  1.1     is  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3787  1.1     is 
   3788  1.1     is # the FPIAR holds the "current PC" of the faulting instruction
   3789  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3790  1.1     is 
   3791  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3792  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3793  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   3794  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
   3795  1.1     is 
   3796  1.1     is ##############################################################################
   3797  1.1     is 
   3798  1.1     is 
   3799  1.1     is # here, we simply see if the operand in the fsave frame needs to be "unskewed".
   3800  1.1     is # this would be the case for opclass two operations with a source zero
   3801  1.1     is # in the sgl or dbl format.
   3802  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3803  1.1     is 	bsr.l		fix_skewed_ops		# fix src op
   3804  1.1     is 
   3805  1.1     is fdz_exit:
   3806  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3807  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3808  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3809  1.1     is 
   3810  1.1     is 	frestore	FP_SRC(%a6)
   3811  1.1     is 
   3812  1.1     is 	unlk		%a6
   3813  1.1     is 	bra.l		_real_dz
   3814  1.1     is 
   3815  1.1     is #########################################################################
   3816  1.1     is # XDEF ****************************************************************	#
   3817  1.1     is #	_fpsp_fline(): 060FPSP entry point for "Line F emulator" exc.	#
   3818  1.1     is #									#
   3819  1.1     is #	This handler should be the first code executed upon taking the	#
   3820  1.1     is #	"Line F Emulator" exception in an operating system.		#
   3821  1.1     is #									#
   3822  1.1     is # XREF ****************************************************************	#
   3823  1.1     is #	_fpsp_unimp() - handle "FP Unimplemented" exceptions		#
   3824  1.1     is #	_real_fpu_disabled() - handle "FPU disabled" exceptions		#
   3825  1.1     is #	_real_fline() - handle "FLINE" exceptions			#
   3826  1.1     is #	_imem_read_long() - read instruction longword			#
   3827  1.1     is #									#
   3828  1.1     is # INPUT ***************************************************************	#
   3829  1.1     is #	- The system stack contains a "Line F Emulator" exception	#
   3830  1.1     is #	  stack frame.							#
   3831  1.1     is # 									#
   3832  1.1     is # OUTPUT **************************************************************	#
   3833  1.1     is #	- The system stack is unchanged					#
   3834  1.1     is #									#
   3835  1.1     is # ALGORITHM ***********************************************************	#
   3836  1.1     is #	When a "Line F Emulator" exception occurs, there are 3 possible	#
   3837  1.1     is # exception types, denoted by the exception stack frame format number:	#
   3838  1.1     is #	(1) FPU unimplemented instruction (6 word stack frame)		#
   3839  1.1     is #	(2) FPU disabled (8 word stack frame)				#
   3840  1.1     is #	(3) Line F (4 word stack frame)					#
   3841  1.1     is #									#
   3842  1.1     is #	This module determines which and forks the flow off to the 	#
   3843  1.1     is # appropriate "callout" (for "disabled" and "Line F") or to the		#
   3844  1.1     is # correct emulation code (for "FPU unimplemented").			#
   3845  1.1     is #	This code also must check for "fmovecr" instructions w/ a	#
   3846  1.1     is # non-zero <ea> field. These may get flagged as "Line F" but should	#
   3847  1.1     is # really be flagged as "FPU Unimplemented". (This is a "feature" on	#
   3848  1.1     is # the '060.								#
   3849  1.1     is #									#
   3850  1.1     is #########################################################################
   3851  1.1     is 
   3852  1.1     is 	global		_fpsp_fline
   3853  1.1     is _fpsp_fline:
   3854  1.1     is 
   3855  1.1     is # check to see if this exception is a "FP Unimplemented Instruction"
   3856  1.1     is # exception. if so, branch directly to that handler's entry point.
   3857  1.1     is 	cmpi.w		0x6(%sp),&0x202c
   3858  1.1     is 	beq.l		_fpsp_unimp
   3859  1.1     is 
   3860  1.1     is # check to see if the FPU is disabled. if so, jump to the OS entry
   3861  1.1     is # point for that condition.
   3862  1.1     is 	cmpi.w		0x6(%sp),&0x402c
   3863  1.1     is 	beq.l		_real_fpu_disabled
   3864  1.1     is 
   3865  1.1     is # the exception was an "F-Line Illegal" exception. we check to see
   3866  1.1     is # if the F-Line instruction is an "fmovecr" w/ a non-zero <ea>. if
   3867  1.1     is # so, convert the F-Line exception stack frame to an FP Unimplemented
   3868  1.1     is # Instruction exception stack frame else branch to the OS entry
   3869  1.1     is # point for the F-Line exception handler.
   3870  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3871  1.1     is 
   3872  1.1     is 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3873  1.1     is 
   3874  1.1     is 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
   3875  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3876  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3877  1.1     is 	bsr.l		_imem_read_long		# fetch instruction words
   3878  1.1     is 
   3879  1.1     is 	bfextu		%d0{&0:&10},%d1		# is it an fmovecr?
   3880  1.1     is 	cmpi.w		%d1,&0x03c8
   3881  1.1     is 	bne.b		fline_fline		# no
   3882  1.1     is 
   3883  1.1     is 	bfextu		%d0{&16:&6},%d1		# is it an fmovecr?
   3884  1.1     is 	cmpi.b		%d1,&0x17
   3885  1.1     is 	bne.b		fline_fline		# no
   3886  1.1     is 
   3887  1.1     is # it's an fmovecr w/ a non-zero <ea> that has entered through
   3888  1.1     is # the F-Line Illegal exception.
   3889  1.1     is # so, we need to convert the F-Line exception stack frame into an
   3890  1.1     is # FP Unimplemented Instruction stack frame and jump to that entry
   3891  1.1     is # point.
   3892  1.1     is #
   3893  1.1     is # but, if the FPU is disabled, then we need to jump to the FPU diabled
   3894  1.1     is # entry point.
   3895  1.1     is 	movc		%pcr,%d0
   3896  1.1     is 	btst		&0x1,%d0
   3897  1.1     is 	beq.b		fline_fmovcr
   3898  1.1     is 
   3899  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3900  1.1     is 
   3901  1.1     is 	unlk		%a6
   3902  1.1     is 
   3903  1.1     is 	sub.l		&0x8,%sp		# make room for "Next PC", <ea>
   3904  1.1     is 	mov.w		0x8(%sp),(%sp)
   3905  1.1     is 	mov.l		0xa(%sp),0x2(%sp)	# move "Current PC"
   3906  1.1     is 	mov.w		&0x402c,0x6(%sp)
   3907  1.1     is 	mov.l		0x2(%sp),0xc(%sp)
   3908  1.1     is 	addq.l		&0x4,0x2(%sp)		# set "Next PC"
   3909  1.1     is 
   3910  1.1     is 	bra.l		_real_fpu_disabled
   3911  1.1     is 
   3912  1.1     is fline_fmovcr:
   3913  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3914  1.1     is 
   3915  1.1     is 	unlk		%a6
   3916  1.1     is 
   3917  1.1     is 	fmov.l		0x2(%sp),%fpiar		# set current PC
   3918  1.1     is 	addq.l		&0x4,0x2(%sp)		# set Next PC
   3919  1.1     is 
   3920  1.1     is 	mov.l		(%sp),-(%sp)
   3921  1.1     is 	mov.l		0x8(%sp),0x4(%sp)
   3922  1.1     is 	mov.b		&0x20,0x6(%sp)
   3923  1.1     is 
   3924  1.1     is 	bra.l		_fpsp_unimp
   3925  1.1     is 
   3926  1.1     is fline_fline:
   3927  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3928  1.1     is 
   3929  1.1     is 	unlk		%a6
   3930  1.1     is 
   3931  1.1     is 	bra.l		_real_fline
   3932  1.1     is 
   3933  1.1     is #########################################################################
   3934  1.1     is # XDEF ****************************************************************	#
   3935  1.1     is #	_fpsp_unimp(): 060FPSP entry point for FP "Unimplemented	#
   3936  1.1     is #		       Instruction" exception.				#
   3937  1.1     is #									#
   3938  1.1     is #	This handler should be the first code executed upon taking the	#
   3939  1.1     is #	FP Unimplemented Instruction exception in an operating system.	#
   3940  1.1     is #									#
   3941  1.1     is # XREF ****************************************************************	#
   3942  1.1     is #	_imem_read_{word,long}() - read instruction word/longword	#
   3943  1.1     is #	load_fop() - load src/dst ops from memory and/or FP regfile	#
   3944  1.1     is #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   3945  1.1     is #	tbl_trans - addr of table of emulation routines for trnscndls	#
   3946  1.1     is #	_real_access() - "callout" for access error exception		#
   3947  1.1     is #	_fpsp_done() - "callout" for exit; work all done		#
   3948  1.1     is #	_real_trace() - "callout" for Trace enabled exception		#
   3949  1.1     is #	smovcr() - emulate "fmovecr" instruction			#
   3950  1.1     is #	funimp_skew() - adjust fsave src ops to "incorrect" value	#
   3951  1.1     is #	_ftrapcc() - emulate an "ftrapcc" instruction			#
   3952  1.1     is #	_fdbcc() - emulate an "fdbcc" instruction			#
   3953  1.1     is #	_fscc() - emulate an "fscc" instruction				#
   3954  1.1     is #	_real_trap() - "callout" for Trap exception			#
   3955  1.1     is # 	_real_bsun() - "callout" for enabled Bsun exception		#
   3956  1.1     is #									#
   3957  1.1     is # INPUT ***************************************************************	#
   3958  1.1     is #	- The system stack contains the "Unimplemented Instr" stk frame	#
   3959  1.1     is # 									#
   3960  1.1     is # OUTPUT **************************************************************	#
   3961  1.1     is #	If access error:						#
   3962  1.1     is #	- The system stack is changed to an access error stack frame	#
   3963  1.1     is #	If Trace exception enabled:					#
   3964  1.1     is #	- The system stack is changed to a Trace exception stack frame	#
   3965  1.1     is #	Else: (normal case)						#
   3966  1.1     is #	- Correct result has been stored as appropriate			#
   3967  1.1     is #									#
   3968  1.1     is # ALGORITHM ***********************************************************	#
   3969  1.1     is #	There are two main cases of instructions that may enter here to	#
   3970  1.1     is # be emulated: (1) the FPgen instructions, most of which were also	#
   3971  1.1     is # unimplemented on the 040, and (2) "ftrapcc", "fscc", and "fdbcc".	#
   3972  1.1     is #	For the first set, this handler calls the routine load_fop()	#
   3973  1.1     is # to load the source and destination (for dyadic) operands to be used	#
   3974  1.1     is # for instruction emulation. The correct emulation routine is then 	#
   3975  1.1     is # chosen by decoding the instruction type and indexing into an 		#
   3976  1.1     is # emulation subroutine index table. After emulation returns, this 	#
   3977  1.1     is # handler checks to see if an exception should occur as a result of the #
   3978  1.1     is # FP instruction emulation. If so, then an FP exception of the correct	#
   3979  1.1     is # type is inserted into the FPU state frame using the "frestore"	#
   3980  1.1     is # instruction before exiting through _fpsp_done(). In either the 	#
   3981  1.1     is # exceptional or non-exceptional cases, we must check to see if the	#
   3982  1.1     is # Trace exception is enabled. If so, then we must create a Trace	#
   3983  1.1     is # exception frame from the current exception frame and exit through	#
   3984  1.1     is # _real_trace().							#
   3985  1.1     is # 	For "fdbcc", "ftrapcc", and "fscc", the emulation subroutines	#
   3986  1.1     is # _fdbcc(), _ftrapcc(), and _fscc() respectively are used. All three	#
   3987  1.1     is # may flag that a BSUN exception should be taken. If so, then the 	#
   3988  1.1     is # current exception stack frame is converted into a BSUN exception 	#
   3989  1.1     is # stack frame and an exit is made through _real_bsun(). If the		#
   3990  1.1     is # instruction was "ftrapcc" and a Trap exception should result, a Trap	#
   3991  1.1     is # exception stack frame is created from the current frame and an exit	#
   3992  1.1     is # is made through _real_trap(). If a Trace exception is pending, then	#
   3993  1.1     is # a Trace exception frame is created from the current frame and a jump	#
   3994  1.1     is # is made to _real_trace(). Finally, if none of these conditions exist,	#
   3995  1.1     is # then the handler exits though the callout _fpsp_done().		#
   3996  1.1     is #									#
   3997  1.1     is # 	In any of the above scenarios, if a _mem_read() or _mem_write()	#
   3998  1.1     is # "callout" returns a failing value, then an access error stack frame	#
   3999  1.1     is # is created from the current stack frame and an exit is made through	#
   4000  1.1     is # _real_access().							#
   4001  1.1     is #									#
   4002  1.1     is #########################################################################
   4003  1.1     is 
   4004  1.1     is #
   4005  1.1     is # FP UNIMPLEMENTED INSTRUCTION STACK FRAME:
   4006  1.1     is #
   4007  1.1     is #	*****************
   4008  1.1     is #	*		* => <ea> of fp unimp instr.
   4009  1.1     is #	-      EA	-
   4010  1.1     is #	*		*
   4011  1.1     is #	*****************
   4012  1.1     is #	* 0x2 *  0x02c	* => frame format and vector offset(vector #11)
   4013  1.1     is #	*****************
   4014  1.1     is #	*		*
   4015  1.1     is #	-    Next PC	- => PC of instr to execute after exc handling
   4016  1.1     is #	*		*
   4017  1.1     is #	*****************
   4018  1.1     is #	*      SR	* => SR at the time the exception was taken
   4019  1.1     is #	*****************
   4020  1.1     is #
   4021  1.1     is # Note: the !NULL bit does not get set in the fsave frame when the
   4022  1.1     is # machine encounters an fp unimp exception. Therefore, it must be set
   4023  1.1     is # before leaving this handler.
   4024  1.1     is #
   4025  1.1     is 	global		_fpsp_unimp
   4026  1.1     is _fpsp_unimp:
   4027  1.1     is 
   4028  1.1     is 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   4029  1.1     is 
   4030  1.1     is 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4031  1.1     is 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   4032  1.1     is 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1
   4033  1.1     is 
   4034  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user mode exception?
   4035  1.1     is 	bne.b		funimp_s		# no; supervisor mode
   4036  1.1     is 
   4037  1.1     is # save the value of the user stack pointer onto the stack frame
   4038  1.1     is funimp_u:
   4039  1.1     is 	mov.l		%usp,%a0		# fetch user stack pointer
   4040  1.1     is 	mov.l		%a0,EXC_A7(%a6)		# store in stack frame
   4041  1.1     is 	bra.b		funimp_cont
   4042  1.1     is 
   4043  1.1     is # store the value of the supervisor stack pointer BEFORE the exc occurred.
   4044  1.1     is # old_sp is address just above stacked effective address.
   4045  1.1     is funimp_s:
   4046  1.1     is 	lea		4+EXC_EA(%a6),%a0	# load old a7'
   4047  1.1     is 	mov.l		%a0,EXC_A7(%a6)		# store a7'
   4048  1.1     is 	mov.l		%a0,OLD_A7(%a6)		# make a copy
   4049  1.1     is 
   4050  1.1     is funimp_cont:
   4051  1.1     is 
   4052  1.1     is # the FPIAR holds the "current PC" of the faulting instruction.
   4053  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   4054  1.1     is 
   4055  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   4056  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   4057  1.1     is 	bsr.l		_imem_read_long		# fetch the instruction words
   4058  1.1     is 	mov.l		%d0,EXC_OPWORD(%a6)
   4059  1.1     is 
   4060  1.1     is ############################################################################
   4061  1.1     is 
   4062  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   4063  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   4064  1.1     is 
   4065  1.1     is 	clr.b		SPCOND_FLG(%a6)		# clear "special case" flag
   4066  1.1     is 
   4067  1.1     is # Divide the fp instructions into 8 types based on the TYPE field in
   4068  1.1     is # bits 6-8 of the opword(classes 6,7 are undefined).
   4069  1.1     is # (for the '060, only two types  can take this exception)
   4070  1.1     is #	bftst		%d0{&7:&3}		# test TYPE
   4071  1.1     is 	btst		&22,%d0			# type 0 or 1 ?
   4072  1.1     is 	bne.w		funimp_misc		# type 1
   4073  1.1     is 
   4074  1.1     is #########################################
   4075  1.1     is # TYPE == 0: General instructions	#
   4076  1.1     is #########################################
   4077  1.1     is funimp_gen:
   4078  1.1     is 
   4079  1.1     is 	clr.b		STORE_FLG(%a6)		# clear "store result" flag
   4080  1.1     is 
   4081  1.1     is # clear the ccode byte and exception status byte
   4082  1.1     is 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4083  1.1     is 
   4084  1.1     is 	bfextu		%d0{&16:&6},%d1		# extract upper 6 of cmdreg
   4085  1.1     is 	cmpi.b		%d1,&0x17		# is op an fmovecr?
   4086  1.1     is 	beq.w		funimp_fmovcr		# yes
   4087  1.1     is 
   4088  1.1     is funimp_gen_op:
   4089  1.1     is 	bsr.l		_load_fop		# load
   4090  1.1     is 
   4091  1.1     is 	clr.l		%d0
   4092  1.1     is 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode
   4093  1.1     is 
   4094  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
   4095  1.1     is 	andi.w		&0x003f,%d1		# extract extension bits
   4096  1.1     is 	lsl.w		&0x3,%d1		# shift right 3 bits
   4097  1.1     is 	or.b		STAG(%a6),%d1		# insert src optag bits
   4098  1.1     is 
   4099  1.1     is 	lea		FP_DST(%a6),%a1		# pass dst ptr in a1
   4100  1.1     is 	lea		FP_SRC(%a6),%a0		# pass src ptr in a0
   4101  1.1     is 
   4102  1.1     is 	mov.w		(tbl_trans.w,%pc,%d1.w*2),%d1
   4103  1.1     is 	jsr		(tbl_trans.w,%pc,%d1.w*1) # emulate
   4104  1.1     is 
   4105  1.1     is funimp_fsave:
   4106  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   4107  1.1     is 	bne.w		funimp_ena		# some are enabled
   4108  1.1     is 
   4109  1.1     is funimp_store:
   4110  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch Dn
   4111  1.1     is 	bsr.l		store_fpreg		# store result to fp regfile
   4112  1.1     is 
   4113  1.1     is funimp_gen_exit:
   4114  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4115  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4116  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4117  1.1     is 
   4118  1.1     is funimp_gen_exit_cmp:
   4119  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mia7_flg # was the ea mode (sp)+ ?
   4120  1.1     is 	beq.b		funimp_gen_exit_a7	# yes
   4121  1.1     is 
   4122  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was the ea mode -(sp) ?
   4123  1.1     is 	beq.b		funimp_gen_exit_a7	# yes
   4124  1.1     is 
   4125  1.1     is funimp_gen_exit_cont:
   4126  1.1     is 	unlk		%a6
   4127  1.1     is 
   4128  1.1     is funimp_gen_exit_cont2:
   4129  1.1     is 	btst		&0x7,(%sp)		# is trace on?
   4130  1.1     is 	beq.l		_fpsp_done		# no
   4131  1.1     is 
   4132  1.1     is # this catches a problem with the case where an exception will be re-inserted
   4133  1.1     is # into the machine. the frestore has already been executed...so, the fmov.l
   4134  1.1     is # alone of the control register would trigger an unwanted exception.
   4135  1.1     is # until I feel like fixing this, we'll sidestep the exception.
   4136  1.1     is 	fsave		-(%sp)
   4137  1.1     is 	fmov.l		%fpiar,0x14(%sp)	# "Current PC" is in FPIAR
   4138  1.1     is 	frestore	(%sp)+
   4139  1.1     is 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x24
   4140  1.1     is 	bra.l		_real_trace
   4141  1.1     is 
   4142  1.1     is funimp_gen_exit_a7:
   4143  1.1     is 	btst		&0x5,EXC_SR(%a6)	# supervisor or user mode?
   4144  1.1     is 	bne.b		funimp_gen_exit_a7_s	# supervisor
   4145  1.1     is 
   4146  1.1     is 	mov.l		%a0,-(%sp)
   4147  1.1     is 	mov.l		EXC_A7(%a6),%a0
   4148  1.1     is 	mov.l		%a0,%usp
   4149  1.1     is 	mov.l		(%sp)+,%a0
   4150  1.1     is 	bra.b		funimp_gen_exit_cont
   4151  1.1     is 
   4152  1.1     is # if the instruction was executed from supervisor mode and the addressing
   4153  1.1     is # mode was (a7)+, then the stack frame for the rte must be shifted "up"
   4154  1.1     is # "n" bytes where "n" is the size of the src operand type.
   4155  1.1     is # f<op>.{b,w,l,s,d,x,p}
   4156  1.1     is funimp_gen_exit_a7_s:
   4157  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   4158  1.1     is 	mov.l		EXC_A7(%a6),%d0		# load new a7'
   4159  1.1     is 	sub.l		OLD_A7(%a6),%d0		# subtract old a7'
   4160  1.1     is 	mov.l		0x2+EXC_PC(%a6),(0x2+EXC_PC,%a6,%d0) # shift stack frame
   4161  1.1     is 	mov.l		EXC_SR(%a6),(EXC_SR,%a6,%d0) # shift stack frame
   4162  1.1     is 	mov.w		%d0,EXC_SR(%a6)		# store incr number
   4163  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   4164  1.1     is 
   4165  1.1     is 	unlk		%a6
   4166  1.1     is 
   4167  1.1     is 	add.w		(%sp),%sp		# stack frame shifted
   4168  1.1     is 	bra.b		funimp_gen_exit_cont2
   4169  1.1     is 
   4170  1.1     is ######################
   4171  1.1     is # fmovecr.x #ccc,fpn #
   4172  1.1     is ######################
   4173  1.1     is funimp_fmovcr:
   4174  1.1     is 	clr.l		%d0
   4175  1.1     is 	mov.b		FPCR_MODE(%a6),%d0
   4176  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1
   4177  1.1     is 	andi.l		&0x0000007f,%d1		# pass rom offset in d1
   4178  1.1     is 	bsr.l		smovcr
   4179  1.1     is 	bra.w		funimp_fsave
   4180  1.1     is 
   4181  1.1     is #########################################################################
   4182  1.1     is 
   4183  1.1     is #
   4184  1.1     is # the user has enabled some exceptions. we figure not to see this too
   4185  1.1     is # often so that's why it gets lower priority.
   4186  1.1     is #
   4187  1.1     is funimp_ena:
   4188  1.1     is 
   4189  1.1     is # was an exception set that was also enabled?
   4190  1.1     is 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled and set
   4191  1.1     is 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   4192  1.1     is 	bne.b		funimp_exc		# at least one was set
   4193  1.1     is 
   4194  1.1     is # no exception that was enabled was set BUT if we got an exact overflow
   4195  1.1     is # and overflow wasn't enabled but inexact was (yech!) then this is
   4196  1.1     is # an inexact exception; otherwise, return to normal non-exception flow.
   4197  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   4198  1.1     is 	beq.w		funimp_store		# no; return to normal flow
   4199  1.1     is 
   4200  1.1     is # the overflow w/ exact result happened but was inexact set in the FPCR?
   4201  1.1     is funimp_ovfl:
   4202  1.1     is 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
   4203  1.1     is 	beq.w		funimp_store		# no; return to normal flow
   4204  1.1     is 	bra.b		funimp_exc_ovfl		# yes
   4205  1.1     is 
   4206  1.1     is # some exception happened that was actually enabled.
   4207  1.1     is # we'll insert this new exception into the FPU and then return.
   4208  1.1     is funimp_exc:
   4209  1.1     is 	subi.l		&24,%d0			# fix offset to be 0-8
   4210  1.1     is 	cmpi.b		%d0,&0x6		# is exception INEX?
   4211  1.1     is 	bne.b		funimp_exc_force	# no
   4212  1.1     is 
   4213  1.1     is # the enabled exception was inexact. so, if it occurs with an overflow
   4214  1.1     is # or underflow that was disabled, then we have to force an overflow or
   4215  1.1     is # underflow frame. the eventual overflow or underflow handler will see that
   4216  1.1     is # it's actually an inexact and act appropriately. this is the only easy
   4217  1.1     is # way to have the EXOP available for the enabled inexact handler when
   4218  1.1     is # a disabled overflow or underflow has also happened.
   4219  1.1     is 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   4220  1.1     is 	bne.b		funimp_exc_ovfl		# yes
   4221  1.1     is 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
   4222  1.1     is 	bne.b		funimp_exc_unfl		# yes
   4223  1.1     is 
   4224  1.1     is # force the fsave exception status bits to signal an exception of the
   4225  1.1     is # appropriate type. don't forget to "skew" the source operand in case we
   4226  1.1     is # "unskewed" the one the hardware initially gave us.
   4227  1.1     is funimp_exc_force:
   4228  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   4229  1.1     is 	bsr.l		funimp_skew		# check for special case
   4230  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   4231  1.1     is 	mov.w		(tbl_funimp_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   4232  1.1     is 	bra.b		funimp_gen_exit2	# exit with frestore
   4233  1.1     is 
   4234  1.1     is tbl_funimp_except:
   4235  1.1     is 	short		0xe002, 0xe006, 0xe004, 0xe005
   4236  1.1     is 	short		0xe003, 0xe002, 0xe001, 0xe001
   4237  1.1     is 
   4238  1.1     is # insert an overflow frame
   4239  1.1     is funimp_exc_ovfl:
   4240  1.1     is 	bsr.l		funimp_skew		# check for special case
   4241  1.1     is 	mov.w		&0xe005,2+FP_SRC(%a6)
   4242  1.1     is 	bra.b		funimp_gen_exit2
   4243  1.1     is 
   4244  1.1     is # insert an underflow frame
   4245  1.1     is funimp_exc_unfl:
   4246  1.1     is 	bsr.l		funimp_skew		# check for special case
   4247  1.1     is 	mov.w		&0xe003,2+FP_SRC(%a6)
   4248  1.1     is 
   4249  1.1     is # this is the general exit point for an enabled exception that will be
   4250  1.1     is # restored into the machine for the instruction just emulated.
   4251  1.1     is funimp_gen_exit2:
   4252  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4253  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4254  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4255  1.1     is 
   4256  1.1     is 	frestore	FP_SRC(%a6)		# insert exceptional status
   4257  1.1     is 
   4258  1.1     is 	bra.w		funimp_gen_exit_cmp
   4259  1.1     is 
   4260  1.1     is ############################################################################
   4261  1.1     is 
   4262  1.1     is #
   4263  1.1     is # TYPE == 1: FDB<cc>, FS<cc>, FTRAP<cc>
   4264  1.1     is #
   4265  1.1     is # These instructions were implemented on the '881/2 and '040 in hardware but
   4266  1.1     is # are emulated in software on the '060.
   4267  1.1     is #
   4268  1.1     is funimp_misc:
   4269  1.1     is 	bfextu		%d0{&10:&3},%d1		# extract mode field
   4270  1.1     is 	cmpi.b		%d1,&0x1		# is it an fdb<cc>?
   4271  1.1     is 	beq.w		funimp_fdbcc		# yes
   4272  1.1     is 	cmpi.b		%d1,&0x7		# is it an fs<cc>?
   4273  1.1     is 	bne.w		funimp_fscc		# yes
   4274  1.1     is 	bfextu		%d0{&13:&3},%d1
   4275  1.1     is 	cmpi.b		%d1,&0x2		# is it an fs<cc>?
   4276  1.1     is 	blt.w		funimp_fscc		# yes
   4277  1.1     is 
   4278  1.1     is #########################
   4279  1.1     is # ftrap<cc>		#
   4280  1.1     is # ftrap<cc>.w #<data>	#
   4281  1.1     is # ftrap<cc>.l #<data>	#
   4282  1.1     is #########################
   4283  1.1     is funimp_ftrapcc:
   4284  1.1     is 
   4285  1.1     is 	bsr.l		_ftrapcc		# FTRAP<cc>()
   4286  1.1     is 
   4287  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
   4288  1.1     is 	beq.w		funimp_bsun		# yes
   4289  1.1     is 
   4290  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&ftrapcc_flg # should a trap occur?
   4291  1.1     is 	bne.w		funimp_done		# no
   4292  1.1     is 
   4293  1.1     is #	 FP UNIMP FRAME		   TRAP  FRAME
   4294  1.1     is #	*****************	*****************
   4295  1.1     is #	**    <EA>     **	**  Current PC **
   4296  1.1     is #	*****************	*****************
   4297  1.1     is #	* 0x2 *  0x02c	*	* 0x2 *  0x01c  *
   4298  1.1     is #	*****************	*****************
   4299  1.1     is #	**   Next PC   **	**   Next PC   **
   4300  1.1     is #	*****************	*****************
   4301  1.1     is #	*      SR	*	*      SR	*
   4302  1.1     is #	*****************	*****************
   4303  1.1     is #	    (6 words)		    (6 words)
   4304  1.1     is #
   4305  1.1     is # the ftrapcc instruction should take a trap. so, here we must create a
   4306  1.1     is # trap stack frame from an unimplemented fp instruction stack frame and
   4307  1.1     is # jump to the user supplied entry point for the trap exception
   4308  1.1     is funimp_ftrapcc_tp:
   4309  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_EA(%a6) # Address = Current PC
   4310  1.1     is 	mov.w		&0x201c,EXC_VOFF(%a6)	# Vector Offset = 0x01c
   4311  1.1     is 
   4312  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4313  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4314  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4315  1.1     is 
   4316  1.1     is 	unlk		%a6
   4317  1.1     is 	bra.l		_real_trap
   4318  1.1     is 
   4319  1.1     is #########################
   4320  1.1     is # fdb<cc> Dn,<label>	#
   4321  1.1     is #########################
   4322  1.1     is funimp_fdbcc:
   4323  1.1     is 
   4324  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   4325  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   4326  1.1     is 	bsr.l		_imem_read_word		# read displacement
   4327  1.1     is 
   4328  1.1     is 	tst.l		%d1			# did ifetch fail?
   4329  1.1     is 	bne.w		funimp_iacc		# yes
   4330  1.1     is 
   4331  1.1     is 	ext.l		%d0			# sign extend displacement
   4332  1.1     is 
   4333  1.1     is 	bsr.l		_fdbcc			# FDB<cc>()
   4334  1.1     is 
   4335  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
   4336  1.1     is 	beq.w		funimp_bsun
   4337  1.1     is 
   4338  1.1     is 	bra.w		funimp_done		# branch to finish
   4339  1.1     is 
   4340  1.1     is #################
   4341  1.1     is # fs<cc>.b <ea>	#
   4342  1.1     is #################
   4343  1.1     is funimp_fscc:
   4344  1.1     is 
   4345  1.1     is 	bsr.l		_fscc			# FS<cc>()
   4346  1.1     is 
   4347  1.1     is # I am assuming here that an "fs<cc>.b -(An)" or "fs<cc>.b (An)+" instruction
   4348  1.1     is # does not need to update "An" before taking a bsun exception.
   4349  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
   4350  1.1     is 	beq.w		funimp_bsun
   4351  1.1     is 
   4352  1.1     is 	btst		&0x5,EXC_SR(%a6)	# yes; is it a user mode exception?
   4353  1.1     is 	bne.b		funimp_fscc_s		# no
   4354  1.1     is 
   4355  1.1     is funimp_fscc_u:
   4356  1.1     is 	mov.l		EXC_A7(%a6),%a0		# yes; set new USP
   4357  1.1     is 	mov.l		%a0,%usp
   4358  1.1     is 	bra.w		funimp_done		# branch to finish
   4359  1.1     is 
   4360  1.1     is # remember, I'm assuming that post-increment is bogus...(it IS!!!)
   4361  1.1     is # so, the least significant WORD of the stacked effective address got
   4362  1.1     is # overwritten by the "fs<cc> -(An)". We must shift the stack frame "down"
   4363  1.1     is # so that the rte will work correctly without destroying the result.
   4364  1.1     is # even though the operation size is byte, the stack ptr is decr by 2.
   4365  1.1     is #
   4366  1.1     is # remember, also, this instruction may be traced.
   4367  1.1     is funimp_fscc_s:
   4368  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was a7 modified?
   4369  1.1     is 	bne.w		funimp_done		# no
   4370  1.1     is 
   4371  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4372  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4373  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4374  1.1     is 
   4375  1.1     is 	unlk		%a6
   4376  1.1     is 
   4377  1.1     is 	btst		&0x7,(%sp)		# is trace enabled?
   4378  1.1     is 	bne.b		funimp_fscc_s_trace	# yes
   4379  1.1     is 
   4380  1.1     is 	subq.l		&0x2,%sp
   4381  1.1     is 	mov.l		0x2(%sp),(%sp)		# shift SR,hi(PC) "down"
   4382  1.1     is 	mov.l		0x6(%sp),0x4(%sp)	# shift lo(PC),voff "down"
   4383  1.1     is 	bra.l		_fpsp_done
   4384  1.1     is 
   4385  1.1     is funimp_fscc_s_trace:
   4386  1.1     is 	subq.l		&0x2,%sp
   4387  1.1     is 	mov.l		0x2(%sp),(%sp)		# shift SR,hi(PC) "down"
   4388  1.1     is 	mov.w		0x6(%sp),0x4(%sp)	# shift lo(PC)
   4389  1.1     is 	mov.w		&0x2024,0x6(%sp)	# fmt/voff = $2024
   4390  1.1     is 	fmov.l		%fpiar,0x8(%sp)		# insert "current PC"
   4391  1.1     is 
   4392  1.1     is 	bra.l		_real_trace
   4393  1.1     is 
   4394  1.1     is #
   4395  1.1     is # The ftrap<cc>, fs<cc>, or fdb<cc> is to take an enabled bsun. we must convert
   4396  1.1     is # the fp unimplemented instruction exception stack frame into a bsun stack frame,
   4397  1.1     is # restore a bsun exception into the machine, and branch to the user
   4398  1.1     is # supplied bsun hook.
   4399  1.1     is #
   4400  1.1     is #	 FP UNIMP FRAME		   BSUN FRAME
   4401  1.1     is #	*****************	*****************
   4402  1.1     is #	**    <EA>     **	* 0x0 * 0x0c0	*
   4403  1.1     is #	*****************	*****************
   4404  1.1     is #	* 0x2 *  0x02c  *	** Current PC  **
   4405  1.1     is #	*****************	*****************
   4406  1.1     is #	**   Next PC   **	*      SR	*
   4407  1.1     is #	*****************	*****************
   4408  1.1     is #	*      SR	*	    (4 words)
   4409  1.1     is #	*****************
   4410  1.1     is #	    (6 words)
   4411  1.1     is #
   4412  1.1     is funimp_bsun:
   4413  1.1     is 	mov.w		&0x00c0,2+EXC_EA(%a6)	# Fmt = 0x0; Vector Offset = 0x0c0
   4414  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_VOFF(%a6) # PC = Current PC
   4415  1.1     is 	mov.w		EXC_SR(%a6),2+EXC_PC(%a6) # shift SR "up"
   4416  1.1     is 
   4417  1.1     is 	mov.w		&0xe000,2+FP_SRC(%a6)	# bsun exception enabled
   4418  1.1     is 
   4419  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4420  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4421  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4422  1.1     is 
   4423  1.1     is 	frestore	FP_SRC(%a6)		# restore bsun exception
   4424  1.1     is 
   4425  1.1     is 	unlk		%a6
   4426  1.1     is 
   4427  1.1     is 	addq.l		&0x4,%sp		# erase sludge
   4428  1.1     is 
   4429  1.1     is 	bra.l		_real_bsun		# branch to user bsun hook
   4430  1.1     is 
   4431  1.1     is #
   4432  1.1     is # all ftrapcc/fscc/fdbcc processing has been completed. unwind the stack frame
   4433  1.1     is # and return.
   4434  1.1     is #
   4435  1.1     is # as usual, we have to check for trace mode being on here. since instructions
   4436  1.1     is # modifying the supervisor stack frame don't pass through here, this is a
   4437  1.1     is # relatively easy task.
   4438  1.1     is #
   4439  1.1     is funimp_done:
   4440  1.1     is 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4441  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4442  1.1     is  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4443  1.1     is 
   4444  1.1     is 	unlk		%a6
   4445  1.1     is 
   4446  1.1     is 	btst		&0x7,(%sp)		# is trace enabled?
   4447  1.1     is 	bne.b		funimp_trace		# yes
   4448  1.1     is 
   4449  1.1     is 	bra.l		_fpsp_done
   4450  1.1     is 
   4451  1.1     is #	 FP UNIMP FRAME		  TRACE  FRAME
   4452  1.1     is #	*****************	*****************
   4453  1.1     is #	**    <EA>     **	**  Current PC **
   4454  1.1     is #	*****************	*****************
   4455  1.1     is #	* 0x2 *  0x02c	*	* 0x2 *  0x024  *
   4456  1.1     is #	*****************	*****************
   4457  1.1     is #	**   Next PC   **	**   Next PC   **
   4458  1.1     is #	*****************	*****************
   4459  1.1     is #	*      SR	*	*      SR	*
   4460  1.1     is #	*****************	*****************
   4461  1.1     is #	    (6 words)		    (6 words)
   4462  1.1     is #
   4463  1.1     is # the fscc instruction should take a trace trap. so, here we must create a
   4464  1.1     is # trace stack frame from an unimplemented fp instruction stack frame and
   4465  1.1     is # jump to the user supplied entry point for the trace exception
   4466  1.1     is funimp_trace:
   4467  1.1     is 	fmov.l		%fpiar,0x8(%sp)		# current PC is in fpiar
   4468  1.1     is 	mov.b		&0x24,0x7(%sp)		# vector offset = 0x024
   4469  1.1     is 
   4470  1.1     is 	bra.l		_real_trace
   4471  1.1     is 
   4472  1.1     is ################################################################
   4473  1.1     is 
   4474  1.1     is 	global		tbl_trans
   4475  1.1     is 	swbeg		&0x1c0
   4476  1.1     is tbl_trans:
   4477  1.1     is 	short 		tbl_trans - tbl_trans	# $00-0 fmovecr all
   4478  1.1     is 	short 		tbl_trans - tbl_trans	# $00-1 fmovecr all
   4479  1.1     is 	short 		tbl_trans - tbl_trans	# $00-2 fmovecr all
   4480  1.1     is 	short 		tbl_trans - tbl_trans	# $00-3 fmovecr all
   4481  1.1     is 	short 		tbl_trans - tbl_trans	# $00-4 fmovecr all
   4482  1.1     is 	short 		tbl_trans - tbl_trans	# $00-5 fmovecr all
   4483  1.1     is 	short 		tbl_trans - tbl_trans	# $00-6 fmovecr all
   4484  1.1     is 	short 		tbl_trans - tbl_trans	# $00-7 fmovecr all
   4485  1.1     is 
   4486  1.1     is 	short 		tbl_trans - tbl_trans	# $01-0 fint norm
   4487  1.1     is 	short		tbl_trans - tbl_trans	# $01-1 fint zero
   4488  1.1     is 	short		tbl_trans - tbl_trans	# $01-2 fint inf
   4489  1.1     is 	short		tbl_trans - tbl_trans	# $01-3 fint qnan
   4490  1.1     is 	short		tbl_trans - tbl_trans	# $01-5 fint denorm
   4491  1.1     is 	short		tbl_trans - tbl_trans	# $01-4 fint snan
   4492  1.1     is 	short		tbl_trans - tbl_trans	# $01-6 fint unnorm
   4493  1.1     is 	short		tbl_trans - tbl_trans	# $01-7 ERROR
   4494  1.1     is 
   4495  1.1     is 	short		ssinh	 - tbl_trans	# $02-0 fsinh norm
   4496  1.1     is 	short		src_zero - tbl_trans	# $02-1 fsinh zero
   4497  1.1     is 	short		src_inf	 - tbl_trans	# $02-2 fsinh inf
   4498  1.1     is 	short		src_qnan - tbl_trans	# $02-3 fsinh qnan
   4499  1.1     is 	short		ssinhd	 - tbl_trans	# $02-5 fsinh denorm
   4500  1.1     is 	short		src_snan - tbl_trans	# $02-4 fsinh snan
   4501  1.1     is 	short		tbl_trans - tbl_trans	# $02-6 fsinh unnorm
   4502  1.1     is 	short		tbl_trans - tbl_trans	# $02-7 ERROR
   4503  1.1     is 
   4504  1.1     is 	short		tbl_trans - tbl_trans	# $03-0 fintrz norm
   4505  1.1     is 	short		tbl_trans - tbl_trans	# $03-1 fintrz zero
   4506  1.1     is 	short		tbl_trans - tbl_trans	# $03-2 fintrz inf
   4507  1.1     is 	short		tbl_trans - tbl_trans	# $03-3 fintrz qnan
   4508  1.1     is 	short		tbl_trans - tbl_trans	# $03-5 fintrz denorm
   4509  1.1     is 	short		tbl_trans - tbl_trans	# $03-4 fintrz snan
   4510  1.1     is 	short		tbl_trans - tbl_trans	# $03-6 fintrz unnorm
   4511  1.1     is 	short		tbl_trans - tbl_trans	# $03-7 ERROR
   4512  1.1     is 
   4513  1.1     is 	short		tbl_trans - tbl_trans	# $04-0 fsqrt norm
   4514  1.1     is 	short		tbl_trans - tbl_trans	# $04-1 fsqrt zero
   4515  1.1     is 	short		tbl_trans - tbl_trans	# $04-2 fsqrt inf
   4516  1.1     is 	short		tbl_trans - tbl_trans	# $04-3 fsqrt qnan
   4517  1.1     is 	short		tbl_trans - tbl_trans	# $04-5 fsqrt denorm
   4518  1.1     is 	short		tbl_trans - tbl_trans	# $04-4 fsqrt snan
   4519  1.1     is 	short		tbl_trans - tbl_trans	# $04-6 fsqrt unnorm
   4520  1.1     is 	short		tbl_trans - tbl_trans	# $04-7 ERROR
   4521  1.1     is 
   4522  1.1     is 	short		tbl_trans - tbl_trans	# $05-0 ERROR
   4523  1.1     is 	short		tbl_trans - tbl_trans	# $05-1 ERROR
   4524  1.1     is 	short		tbl_trans - tbl_trans	# $05-2 ERROR
   4525  1.1     is 	short		tbl_trans - tbl_trans	# $05-3 ERROR
   4526  1.1     is 	short		tbl_trans - tbl_trans	# $05-4 ERROR
   4527  1.1     is 	short		tbl_trans - tbl_trans	# $05-5 ERROR
   4528  1.1     is 	short		tbl_trans - tbl_trans	# $05-6 ERROR
   4529  1.1     is 	short		tbl_trans - tbl_trans	# $05-7 ERROR
   4530  1.1     is 
   4531  1.1     is 	short		slognp1	 - tbl_trans	# $06-0 flognp1 norm
   4532  1.1     is 	short		src_zero - tbl_trans	# $06-1 flognp1 zero
   4533  1.1     is 	short		sopr_inf - tbl_trans	# $06-2 flognp1 inf
   4534  1.1     is 	short		src_qnan - tbl_trans	# $06-3 flognp1 qnan
   4535  1.1     is 	short		slognp1d - tbl_trans	# $06-5 flognp1 denorm
   4536  1.1     is 	short		src_snan - tbl_trans	# $06-4 flognp1 snan
   4537  1.1     is 	short		tbl_trans - tbl_trans	# $06-6 flognp1 unnorm
   4538  1.1     is 	short		tbl_trans - tbl_trans	# $06-7 ERROR
   4539  1.1     is 
   4540  1.1     is 	short		tbl_trans - tbl_trans	# $07-0 ERROR
   4541  1.1     is 	short		tbl_trans - tbl_trans	# $07-1 ERROR
   4542  1.1     is 	short		tbl_trans - tbl_trans	# $07-2 ERROR
   4543  1.1     is 	short		tbl_trans - tbl_trans	# $07-3 ERROR
   4544  1.1     is 	short		tbl_trans - tbl_trans	# $07-4 ERROR
   4545  1.1     is 	short		tbl_trans - tbl_trans	# $07-5 ERROR
   4546  1.1     is 	short		tbl_trans - tbl_trans	# $07-6 ERROR
   4547  1.1     is 	short		tbl_trans - tbl_trans	# $07-7 ERROR
   4548  1.1     is 
   4549  1.1     is 	short		setoxm1	 - tbl_trans	# $08-0 fetoxm1 norm
   4550  1.1     is 	short		src_zero - tbl_trans	# $08-1 fetoxm1 zero
   4551  1.1     is 	short		setoxm1i - tbl_trans	# $08-2 fetoxm1 inf
   4552  1.1     is 	short		src_qnan - tbl_trans	# $08-3 fetoxm1 qnan
   4553  1.1     is 	short		setoxm1d - tbl_trans	# $08-5 fetoxm1 denorm
   4554  1.1     is 	short		src_snan - tbl_trans	# $08-4 fetoxm1 snan
   4555  1.1     is 	short		tbl_trans - tbl_trans	# $08-6 fetoxm1 unnorm
   4556  1.1     is 	short		tbl_trans - tbl_trans	# $08-7 ERROR
   4557  1.1     is 
   4558  1.1     is 	short		stanh	 - tbl_trans	# $09-0 ftanh norm
   4559  1.1     is 	short		src_zero - tbl_trans	# $09-1 ftanh zero
   4560  1.1     is 	short		src_one	 - tbl_trans	# $09-2 ftanh inf
   4561  1.1     is 	short		src_qnan - tbl_trans	# $09-3 ftanh qnan
   4562  1.1     is 	short		stanhd	 - tbl_trans	# $09-5 ftanh denorm
   4563  1.1     is 	short		src_snan - tbl_trans	# $09-4 ftanh snan
   4564  1.1     is 	short		tbl_trans - tbl_trans	# $09-6 ftanh unnorm
   4565  1.1     is 	short		tbl_trans - tbl_trans	# $09-7 ERROR
   4566  1.1     is 
   4567  1.1     is 	short		satan	 - tbl_trans	# $0a-0 fatan norm
   4568  1.1     is 	short		src_zero - tbl_trans	# $0a-1 fatan zero
   4569  1.1     is 	short		spi_2	 - tbl_trans	# $0a-2 fatan inf
   4570  1.1     is 	short		src_qnan - tbl_trans	# $0a-3 fatan qnan
   4571  1.1     is 	short		satand	 - tbl_trans	# $0a-5 fatan denorm
   4572  1.1     is 	short		src_snan - tbl_trans	# $0a-4 fatan snan
   4573  1.1     is 	short		tbl_trans - tbl_trans	# $0a-6 fatan unnorm
   4574  1.1     is 	short		tbl_trans - tbl_trans	# $0a-7 ERROR
   4575  1.1     is 
   4576  1.1     is 	short		tbl_trans - tbl_trans	# $0b-0 ERROR
   4577  1.1     is 	short		tbl_trans - tbl_trans	# $0b-1 ERROR
   4578  1.1     is 	short		tbl_trans - tbl_trans	# $0b-2 ERROR
   4579  1.1     is 	short		tbl_trans - tbl_trans	# $0b-3 ERROR
   4580  1.1     is 	short		tbl_trans - tbl_trans	# $0b-4 ERROR
   4581  1.1     is 	short		tbl_trans - tbl_trans	# $0b-5 ERROR
   4582  1.1     is 	short		tbl_trans - tbl_trans	# $0b-6 ERROR
   4583  1.1     is 	short		tbl_trans - tbl_trans	# $0b-7 ERROR
   4584  1.1     is 
   4585  1.1     is 	short		sasin	 - tbl_trans	# $0c-0 fasin norm
   4586  1.1     is 	short		src_zero - tbl_trans	# $0c-1 fasin zero
   4587  1.1     is 	short		t_operr	 - tbl_trans	# $0c-2 fasin inf
   4588  1.1     is 	short		src_qnan - tbl_trans	# $0c-3 fasin qnan
   4589  1.1     is 	short		sasind	 - tbl_trans	# $0c-5 fasin denorm
   4590  1.1     is 	short		src_snan - tbl_trans	# $0c-4 fasin snan
   4591  1.1     is 	short		tbl_trans - tbl_trans	# $0c-6 fasin unnorm
   4592  1.1     is 	short		tbl_trans - tbl_trans	# $0c-7 ERROR
   4593  1.1     is 
   4594  1.1     is 	short		satanh	 - tbl_trans	# $0d-0 fatanh norm
   4595  1.1     is 	short		src_zero - tbl_trans	# $0d-1 fatanh zero
   4596  1.1     is 	short		t_operr	 - tbl_trans	# $0d-2 fatanh inf
   4597  1.1     is 	short		src_qnan - tbl_trans	# $0d-3 fatanh qnan
   4598  1.1     is 	short		satanhd	 - tbl_trans	# $0d-5 fatanh denorm
   4599  1.1     is 	short		src_snan - tbl_trans	# $0d-4 fatanh snan
   4600  1.1     is 	short		tbl_trans - tbl_trans	# $0d-6 fatanh unnorm
   4601  1.1     is 	short		tbl_trans - tbl_trans	# $0d-7 ERROR
   4602  1.1     is 
   4603  1.1     is 	short		ssin	 - tbl_trans	# $0e-0 fsin norm
   4604  1.1     is 	short		src_zero - tbl_trans	# $0e-1 fsin zero
   4605  1.1     is 	short		t_operr	 - tbl_trans	# $0e-2 fsin inf
   4606  1.1     is 	short		src_qnan - tbl_trans	# $0e-3 fsin qnan
   4607  1.1     is 	short		ssind	 - tbl_trans	# $0e-5 fsin denorm
   4608  1.1     is 	short		src_snan - tbl_trans	# $0e-4 fsin snan
   4609  1.1     is 	short		tbl_trans - tbl_trans	# $0e-6 fsin unnorm
   4610  1.1     is 	short		tbl_trans - tbl_trans	# $0e-7 ERROR
   4611  1.1     is 
   4612  1.1     is 	short		stan	 - tbl_trans	# $0f-0 ftan norm
   4613  1.1     is 	short		src_zero - tbl_trans	# $0f-1 ftan zero
   4614  1.1     is 	short		t_operr	 - tbl_trans	# $0f-2 ftan inf
   4615  1.1     is 	short		src_qnan - tbl_trans	# $0f-3 ftan qnan
   4616  1.1     is 	short		stand	 - tbl_trans	# $0f-5 ftan denorm
   4617  1.1     is 	short		src_snan - tbl_trans	# $0f-4 ftan snan
   4618  1.1     is 	short		tbl_trans - tbl_trans	# $0f-6 ftan unnorm
   4619  1.1     is 	short		tbl_trans - tbl_trans	# $0f-7 ERROR
   4620  1.1     is 
   4621  1.1     is 	short		setox	 - tbl_trans	# $10-0 fetox norm
   4622  1.1     is 	short		ld_pone	 - tbl_trans	# $10-1 fetox zero
   4623  1.1     is 	short		szr_inf	 - tbl_trans	# $10-2 fetox inf
   4624  1.1     is 	short		src_qnan - tbl_trans	# $10-3 fetox qnan
   4625  1.1     is 	short		setoxd	 - tbl_trans	# $10-5 fetox denorm
   4626  1.1     is 	short		src_snan - tbl_trans	# $10-4 fetox snan
   4627  1.1     is 	short		tbl_trans - tbl_trans	# $10-6 fetox unnorm
   4628  1.1     is 	short		tbl_trans - tbl_trans	# $10-7 ERROR
   4629  1.1     is 
   4630  1.1     is 	short		stwotox	 - tbl_trans	# $11-0 ftwotox norm
   4631  1.1     is 	short		ld_pone	 - tbl_trans	# $11-1 ftwotox zero
   4632  1.1     is 	short		szr_inf	 - tbl_trans	# $11-2 ftwotox inf
   4633  1.1     is 	short		src_qnan - tbl_trans	# $11-3 ftwotox qnan
   4634  1.1     is 	short		stwotoxd - tbl_trans	# $11-5 ftwotox denorm
   4635  1.1     is 	short		src_snan - tbl_trans	# $11-4 ftwotox snan
   4636  1.1     is 	short		tbl_trans - tbl_trans	# $11-6 ftwotox unnorm
   4637  1.1     is 	short		tbl_trans - tbl_trans	# $11-7 ERROR
   4638  1.1     is 
   4639  1.1     is 	short		stentox	 - tbl_trans	# $12-0 ftentox norm
   4640  1.1     is 	short		ld_pone	 - tbl_trans	# $12-1 ftentox zero
   4641  1.1     is 	short		szr_inf	 - tbl_trans	# $12-2 ftentox inf
   4642  1.1     is 	short		src_qnan - tbl_trans	# $12-3 ftentox qnan
   4643  1.1     is 	short		stentoxd - tbl_trans	# $12-5 ftentox denorm
   4644  1.1     is 	short		src_snan - tbl_trans	# $12-4 ftentox snan
   4645  1.1     is 	short		tbl_trans - tbl_trans	# $12-6 ftentox unnorm
   4646  1.1     is 	short		tbl_trans - tbl_trans	# $12-7 ERROR
   4647  1.1     is 
   4648  1.1     is 	short		tbl_trans - tbl_trans	# $13-0 ERROR
   4649  1.1     is 	short		tbl_trans - tbl_trans	# $13-1 ERROR
   4650  1.1     is 	short		tbl_trans - tbl_trans	# $13-2 ERROR
   4651  1.1     is 	short		tbl_trans - tbl_trans	# $13-3 ERROR
   4652  1.1     is 	short		tbl_trans - tbl_trans	# $13-4 ERROR
   4653  1.1     is 	short		tbl_trans - tbl_trans	# $13-5 ERROR
   4654  1.1     is 	short		tbl_trans - tbl_trans	# $13-6 ERROR
   4655  1.1     is 	short		tbl_trans - tbl_trans	# $13-7 ERROR
   4656  1.1     is 
   4657  1.1     is 	short		slogn	 - tbl_trans	# $14-0 flogn norm
   4658  1.1     is 	short		t_dz2	 - tbl_trans	# $14-1 flogn zero
   4659  1.1     is 	short		sopr_inf - tbl_trans	# $14-2 flogn inf
   4660  1.1     is 	short		src_qnan - tbl_trans	# $14-3 flogn qnan
   4661  1.1     is 	short		slognd	 - tbl_trans	# $14-5 flogn denorm
   4662  1.1     is 	short		src_snan - tbl_trans	# $14-4 flogn snan
   4663  1.1     is 	short		tbl_trans - tbl_trans	# $14-6 flogn unnorm
   4664  1.1     is 	short		tbl_trans - tbl_trans	# $14-7 ERROR
   4665  1.1     is 
   4666  1.1     is 	short		slog10	 - tbl_trans	# $15-0 flog10 norm
   4667  1.1     is 	short		t_dz2	 - tbl_trans	# $15-1 flog10 zero
   4668  1.1     is 	short		sopr_inf - tbl_trans	# $15-2 flog10 inf
   4669  1.1     is 	short		src_qnan - tbl_trans	# $15-3 flog10 qnan
   4670  1.1     is 	short		slog10d	 - tbl_trans	# $15-5 flog10 denorm
   4671  1.1     is 	short		src_snan - tbl_trans	# $15-4 flog10 snan
   4672  1.1     is 	short		tbl_trans - tbl_trans	# $15-6 flog10 unnorm
   4673  1.1     is 	short		tbl_trans - tbl_trans	# $15-7 ERROR
   4674  1.1     is 
   4675  1.1     is 	short		slog2	 - tbl_trans	# $16-0 flog2 norm
   4676  1.1     is 	short		t_dz2	 - tbl_trans	# $16-1 flog2 zero
   4677  1.1     is 	short		sopr_inf - tbl_trans	# $16-2 flog2 inf
   4678  1.1     is 	short		src_qnan - tbl_trans	# $16-3 flog2 qnan
   4679  1.1     is 	short		slog2d	 - tbl_trans	# $16-5 flog2 denorm
   4680  1.1     is 	short		src_snan - tbl_trans	# $16-4 flog2 snan
   4681  1.1     is 	short		tbl_trans - tbl_trans	# $16-6 flog2 unnorm
   4682  1.1     is 	short		tbl_trans - tbl_trans	# $16-7 ERROR
   4683  1.1     is 
   4684  1.1     is 	short		tbl_trans - tbl_trans	# $17-0 ERROR
   4685  1.1     is 	short		tbl_trans - tbl_trans	# $17-1 ERROR
   4686  1.1     is 	short		tbl_trans - tbl_trans	# $17-2 ERROR
   4687  1.1     is 	short		tbl_trans - tbl_trans	# $17-3 ERROR
   4688  1.1     is 	short		tbl_trans - tbl_trans	# $17-4 ERROR
   4689  1.1     is 	short		tbl_trans - tbl_trans	# $17-5 ERROR
   4690  1.1     is 	short		tbl_trans - tbl_trans	# $17-6 ERROR
   4691  1.1     is 	short		tbl_trans - tbl_trans	# $17-7 ERROR
   4692  1.1     is 
   4693  1.1     is 	short		tbl_trans - tbl_trans	# $18-0 fabs norm
   4694  1.1     is 	short		tbl_trans - tbl_trans	# $18-1 fabs zero
   4695  1.1     is 	short		tbl_trans - tbl_trans	# $18-2 fabs inf
   4696  1.1     is 	short		tbl_trans - tbl_trans	# $18-3 fabs qnan
   4697  1.1     is 	short		tbl_trans - tbl_trans	# $18-5 fabs denorm
   4698  1.1     is 	short		tbl_trans - tbl_trans	# $18-4 fabs snan
   4699  1.1     is 	short		tbl_trans - tbl_trans	# $18-6 fabs unnorm
   4700  1.1     is 	short		tbl_trans - tbl_trans	# $18-7 ERROR
   4701  1.1     is 
   4702  1.1     is 	short		scosh	 - tbl_trans	# $19-0 fcosh norm
   4703  1.1     is 	short		ld_pone	 - tbl_trans	# $19-1 fcosh zero
   4704  1.1     is 	short		ld_pinf	 - tbl_trans	# $19-2 fcosh inf
   4705  1.1     is 	short		src_qnan - tbl_trans	# $19-3 fcosh qnan
   4706  1.1     is 	short		scoshd	 - tbl_trans	# $19-5 fcosh denorm
   4707  1.1     is 	short		src_snan - tbl_trans	# $19-4 fcosh snan
   4708  1.1     is 	short		tbl_trans - tbl_trans	# $19-6 fcosh unnorm
   4709  1.1     is 	short		tbl_trans - tbl_trans	# $19-7 ERROR
   4710  1.1     is 
   4711  1.1     is 	short		tbl_trans - tbl_trans	# $1a-0 fneg norm
   4712  1.1     is 	short		tbl_trans - tbl_trans	# $1a-1 fneg zero
   4713  1.1     is 	short		tbl_trans - tbl_trans	# $1a-2 fneg inf
   4714  1.1     is 	short		tbl_trans - tbl_trans	# $1a-3 fneg qnan
   4715  1.1     is 	short		tbl_trans - tbl_trans	# $1a-5 fneg denorm
   4716  1.1     is 	short		tbl_trans - tbl_trans	# $1a-4 fneg snan
   4717  1.1     is 	short		tbl_trans - tbl_trans	# $1a-6 fneg unnorm
   4718  1.1     is 	short		tbl_trans - tbl_trans	# $1a-7 ERROR
   4719  1.1     is 
   4720  1.1     is 	short		tbl_trans - tbl_trans	# $1b-0 ERROR
   4721  1.1     is 	short		tbl_trans - tbl_trans	# $1b-1 ERROR
   4722  1.1     is 	short		tbl_trans - tbl_trans	# $1b-2 ERROR
   4723  1.1     is 	short		tbl_trans - tbl_trans	# $1b-3 ERROR
   4724  1.1     is 	short		tbl_trans - tbl_trans	# $1b-4 ERROR
   4725  1.1     is 	short		tbl_trans - tbl_trans	# $1b-5 ERROR
   4726  1.1     is 	short		tbl_trans - tbl_trans	# $1b-6 ERROR
   4727  1.1     is 	short		tbl_trans - tbl_trans	# $1b-7 ERROR
   4728  1.1     is 
   4729  1.1     is 	short		sacos	 - tbl_trans	# $1c-0 facos norm
   4730  1.1     is 	short		ld_ppi2	 - tbl_trans	# $1c-1 facos zero
   4731  1.1     is 	short		t_operr	 - tbl_trans	# $1c-2 facos inf
   4732  1.1     is 	short		src_qnan - tbl_trans	# $1c-3 facos qnan
   4733  1.1     is 	short		sacosd	 - tbl_trans	# $1c-5 facos denorm
   4734  1.1     is 	short		src_snan - tbl_trans	# $1c-4 facos snan
   4735  1.1     is 	short		tbl_trans - tbl_trans	# $1c-6 facos unnorm
   4736  1.1     is 	short		tbl_trans - tbl_trans	# $1c-7 ERROR
   4737  1.1     is 
   4738  1.1     is 	short		scos	 - tbl_trans	# $1d-0 fcos norm
   4739  1.1     is 	short		ld_pone	 - tbl_trans	# $1d-1 fcos zero
   4740  1.1     is 	short		t_operr	 - tbl_trans	# $1d-2 fcos inf
   4741  1.1     is 	short		src_qnan - tbl_trans	# $1d-3 fcos qnan
   4742  1.1     is 	short		scosd	 - tbl_trans	# $1d-5 fcos denorm
   4743  1.1     is 	short		src_snan - tbl_trans	# $1d-4 fcos snan
   4744  1.1     is 	short		tbl_trans - tbl_trans	# $1d-6 fcos unnorm
   4745  1.1     is 	short		tbl_trans - tbl_trans	# $1d-7 ERROR
   4746  1.1     is 
   4747  1.1     is 	short		sgetexp	 - tbl_trans	# $1e-0 fgetexp norm
   4748  1.1     is 	short		src_zero - tbl_trans	# $1e-1 fgetexp zero
   4749  1.1     is 	short		t_operr	 - tbl_trans	# $1e-2 fgetexp inf
   4750  1.1     is 	short		src_qnan - tbl_trans	# $1e-3 fgetexp qnan
   4751  1.1     is 	short		sgetexpd - tbl_trans	# $1e-5 fgetexp denorm
   4752  1.1     is 	short		src_snan - tbl_trans	# $1e-4 fgetexp snan
   4753  1.1     is 	short		tbl_trans - tbl_trans	# $1e-6 fgetexp unnorm
   4754  1.1     is 	short		tbl_trans - tbl_trans	# $1e-7 ERROR
   4755  1.1     is 
   4756  1.1     is 	short		sgetman	 - tbl_trans	# $1f-0 fgetman norm
   4757  1.1     is 	short		src_zero - tbl_trans	# $1f-1 fgetman zero
   4758  1.1     is 	short		t_operr	 - tbl_trans	# $1f-2 fgetman inf
   4759  1.1     is 	short		src_qnan - tbl_trans	# $1f-3 fgetman qnan
   4760  1.1     is 	short		sgetmand - tbl_trans	# $1f-5 fgetman denorm
   4761  1.1     is 	short		src_snan - tbl_trans	# $1f-4 fgetman snan
   4762  1.1     is 	short		tbl_trans - tbl_trans	# $1f-6 fgetman unnorm
   4763  1.1     is 	short		tbl_trans - tbl_trans	# $1f-7 ERROR
   4764  1.1     is 
   4765  1.1     is 	short		tbl_trans - tbl_trans	# $20-0 fdiv norm
   4766  1.1     is 	short		tbl_trans - tbl_trans	# $20-1 fdiv zero
   4767  1.1     is 	short		tbl_trans - tbl_trans	# $20-2 fdiv inf
   4768  1.1     is 	short		tbl_trans - tbl_trans	# $20-3 fdiv qnan
   4769  1.1     is 	short		tbl_trans - tbl_trans	# $20-5 fdiv denorm
   4770  1.1     is 	short		tbl_trans - tbl_trans	# $20-4 fdiv snan
   4771  1.1     is 	short		tbl_trans - tbl_trans	# $20-6 fdiv unnorm
   4772  1.1     is 	short		tbl_trans - tbl_trans	# $20-7 ERROR
   4773  1.1     is 
   4774  1.1     is 	short		smod_snorm - tbl_trans	# $21-0 fmod norm
   4775  1.1     is 	short		smod_szero - tbl_trans	# $21-1 fmod zero
   4776  1.1     is 	short		smod_sinf - tbl_trans	# $21-2 fmod inf
   4777  1.1     is 	short		sop_sqnan - tbl_trans	# $21-3 fmod qnan
   4778  1.1     is 	short		smod_sdnrm - tbl_trans	# $21-5 fmod denorm
   4779  1.1     is 	short		sop_ssnan - tbl_trans	# $21-4 fmod snan
   4780  1.1     is 	short		tbl_trans - tbl_trans	# $21-6 fmod unnorm
   4781  1.1     is 	short		tbl_trans - tbl_trans	# $21-7 ERROR
   4782  1.1     is 
   4783  1.1     is 	short		tbl_trans - tbl_trans	# $22-0 fadd norm
   4784  1.1     is 	short		tbl_trans - tbl_trans	# $22-1 fadd zero
   4785  1.1     is 	short		tbl_trans - tbl_trans	# $22-2 fadd inf
   4786  1.1     is 	short		tbl_trans - tbl_trans	# $22-3 fadd qnan
   4787  1.1     is 	short		tbl_trans - tbl_trans	# $22-5 fadd denorm
   4788  1.1     is 	short		tbl_trans - tbl_trans	# $22-4 fadd snan
   4789  1.1     is 	short		tbl_trans - tbl_trans	# $22-6 fadd unnorm
   4790  1.1     is 	short		tbl_trans - tbl_trans	# $22-7 ERROR
   4791  1.1     is 
   4792  1.1     is 	short		tbl_trans - tbl_trans	# $23-0 fmul norm
   4793  1.1     is 	short		tbl_trans - tbl_trans	# $23-1 fmul zero
   4794  1.1     is 	short		tbl_trans - tbl_trans	# $23-2 fmul inf
   4795  1.1     is 	short		tbl_trans - tbl_trans	# $23-3 fmul qnan
   4796  1.1     is 	short		tbl_trans - tbl_trans	# $23-5 fmul denorm
   4797  1.1     is 	short		tbl_trans - tbl_trans	# $23-4 fmul snan
   4798  1.1     is 	short		tbl_trans - tbl_trans	# $23-6 fmul unnorm
   4799  1.1     is 	short		tbl_trans - tbl_trans	# $23-7 ERROR
   4800  1.1     is 
   4801  1.1     is 	short		tbl_trans - tbl_trans	# $24-0 fsgldiv norm
   4802  1.1     is 	short		tbl_trans - tbl_trans	# $24-1 fsgldiv zero
   4803  1.1     is 	short		tbl_trans - tbl_trans	# $24-2 fsgldiv inf
   4804  1.1     is 	short		tbl_trans - tbl_trans	# $24-3 fsgldiv qnan
   4805  1.1     is 	short		tbl_trans - tbl_trans	# $24-5 fsgldiv denorm
   4806  1.1     is 	short		tbl_trans - tbl_trans	# $24-4 fsgldiv snan
   4807  1.1     is 	short		tbl_trans - tbl_trans	# $24-6 fsgldiv unnorm
   4808  1.1     is 	short		tbl_trans - tbl_trans	# $24-7 ERROR
   4809  1.1     is 
   4810  1.1     is 	short		srem_snorm - tbl_trans	# $25-0 frem norm
   4811  1.1     is 	short		srem_szero - tbl_trans	# $25-1 frem zero
   4812  1.1     is 	short		srem_sinf - tbl_trans	# $25-2 frem inf
   4813  1.1     is 	short		sop_sqnan - tbl_trans	# $25-3 frem qnan
   4814  1.1     is 	short		srem_sdnrm - tbl_trans	# $25-5 frem denorm
   4815  1.1     is 	short		sop_ssnan - tbl_trans	# $25-4 frem snan
   4816  1.1     is 	short		tbl_trans - tbl_trans	# $25-6 frem unnorm
   4817  1.1     is 	short		tbl_trans - tbl_trans	# $25-7 ERROR
   4818  1.1     is 
   4819  1.1     is 	short		sscale_snorm - tbl_trans # $26-0 fscale norm
   4820  1.1     is 	short		sscale_szero - tbl_trans # $26-1 fscale zero
   4821  1.1     is 	short		sscale_sinf - tbl_trans	# $26-2 fscale inf
   4822  1.1     is 	short		sop_sqnan - tbl_trans	# $26-3 fscale qnan
   4823  1.1     is 	short		sscale_sdnrm - tbl_trans # $26-5 fscale denorm
   4824  1.1     is 	short		sop_ssnan - tbl_trans	# $26-4 fscale snan
   4825  1.1     is 	short		tbl_trans - tbl_trans	# $26-6 fscale unnorm
   4826  1.1     is 	short		tbl_trans - tbl_trans	# $26-7 ERROR
   4827  1.1     is 
   4828  1.1     is 	short		tbl_trans - tbl_trans	# $27-0 fsglmul norm
   4829  1.1     is 	short		tbl_trans - tbl_trans	# $27-1 fsglmul zero
   4830  1.1     is 	short		tbl_trans - tbl_trans	# $27-2 fsglmul inf
   4831  1.1     is 	short		tbl_trans - tbl_trans	# $27-3 fsglmul qnan
   4832  1.1     is 	short		tbl_trans - tbl_trans	# $27-5 fsglmul denorm
   4833  1.1     is 	short		tbl_trans - tbl_trans	# $27-4 fsglmul snan
   4834  1.1     is 	short		tbl_trans - tbl_trans	# $27-6 fsglmul unnorm
   4835  1.1     is 	short		tbl_trans - tbl_trans	# $27-7 ERROR
   4836  1.1     is 
   4837  1.1     is 	short		tbl_trans - tbl_trans	# $28-0 fsub norm
   4838  1.1     is 	short		tbl_trans - tbl_trans	# $28-1 fsub zero
   4839  1.1     is 	short		tbl_trans - tbl_trans	# $28-2 fsub inf
   4840  1.1     is 	short		tbl_trans - tbl_trans	# $28-3 fsub qnan
   4841  1.1     is 	short		tbl_trans - tbl_trans	# $28-5 fsub denorm
   4842  1.1     is 	short		tbl_trans - tbl_trans	# $28-4 fsub snan
   4843  1.1     is 	short		tbl_trans - tbl_trans	# $28-6 fsub unnorm
   4844  1.1     is 	short		tbl_trans - tbl_trans	# $28-7 ERROR
   4845  1.1     is 
   4846  1.1     is 	short		tbl_trans - tbl_trans	# $29-0 ERROR
   4847  1.1     is 	short		tbl_trans - tbl_trans	# $29-1 ERROR
   4848  1.1     is 	short		tbl_trans - tbl_trans	# $29-2 ERROR
   4849  1.1     is 	short		tbl_trans - tbl_trans	# $29-3 ERROR
   4850  1.1     is 	short		tbl_trans - tbl_trans	# $29-4 ERROR
   4851  1.1     is 	short		tbl_trans - tbl_trans	# $29-5 ERROR
   4852  1.1     is 	short		tbl_trans - tbl_trans	# $29-6 ERROR
   4853  1.1     is 	short		tbl_trans - tbl_trans	# $29-7 ERROR
   4854  1.1     is 
   4855  1.1     is 	short		tbl_trans - tbl_trans	# $2a-0 ERROR
   4856  1.1     is 	short		tbl_trans - tbl_trans	# $2a-1 ERROR
   4857  1.1     is 	short		tbl_trans - tbl_trans	# $2a-2 ERROR
   4858  1.1     is 	short		tbl_trans - tbl_trans	# $2a-3 ERROR
   4859  1.1     is 	short		tbl_trans - tbl_trans	# $2a-4 ERROR
   4860  1.1     is 	short		tbl_trans - tbl_trans	# $2a-5 ERROR
   4861  1.1     is 	short		tbl_trans - tbl_trans	# $2a-6 ERROR
   4862  1.1     is 	short		tbl_trans - tbl_trans	# $2a-7 ERROR
   4863  1.1     is 
   4864  1.1     is 	short		tbl_trans - tbl_trans	# $2b-0 ERROR
   4865  1.1     is 	short		tbl_trans - tbl_trans	# $2b-1 ERROR
   4866  1.1     is 	short		tbl_trans - tbl_trans	# $2b-2 ERROR
   4867  1.1     is 	short		tbl_trans - tbl_trans	# $2b-3 ERROR
   4868  1.1     is 	short		tbl_trans - tbl_trans	# $2b-4 ERROR
   4869  1.1     is 	short		tbl_trans - tbl_trans	# $2b-5 ERROR
   4870  1.1     is 	short		tbl_trans - tbl_trans	# $2b-6 ERROR
   4871  1.1     is 	short		tbl_trans - tbl_trans	# $2b-7 ERROR
   4872  1.1     is 
   4873  1.1     is 	short		tbl_trans - tbl_trans	# $2c-0 ERROR
   4874  1.1     is 	short		tbl_trans - tbl_trans	# $2c-1 ERROR
   4875  1.1     is 	short		tbl_trans - tbl_trans	# $2c-2 ERROR
   4876  1.1     is 	short		tbl_trans - tbl_trans	# $2c-3 ERROR
   4877  1.1     is 	short		tbl_trans - tbl_trans	# $2c-4 ERROR
   4878  1.1     is 	short		tbl_trans - tbl_trans	# $2c-5 ERROR
   4879  1.1     is 	short		tbl_trans - tbl_trans	# $2c-6 ERROR
   4880  1.1     is 	short		tbl_trans - tbl_trans	# $2c-7 ERROR
   4881  1.1     is 
   4882  1.1     is 	short		tbl_trans - tbl_trans	# $2d-0 ERROR
   4883  1.1     is 	short		tbl_trans - tbl_trans	# $2d-1 ERROR
   4884  1.1     is 	short		tbl_trans - tbl_trans	# $2d-2 ERROR
   4885  1.1     is 	short		tbl_trans - tbl_trans	# $2d-3 ERROR
   4886  1.1     is 	short		tbl_trans - tbl_trans	# $2d-4 ERROR
   4887  1.1     is 	short		tbl_trans - tbl_trans	# $2d-5 ERROR
   4888  1.1     is 	short		tbl_trans - tbl_trans	# $2d-6 ERROR
   4889  1.1     is 	short		tbl_trans - tbl_trans	# $2d-7 ERROR
   4890  1.1     is 
   4891  1.1     is 	short		tbl_trans - tbl_trans	# $2e-0 ERROR
   4892  1.1     is 	short		tbl_trans - tbl_trans	# $2e-1 ERROR
   4893  1.1     is 	short		tbl_trans - tbl_trans	# $2e-2 ERROR
   4894  1.1     is 	short		tbl_trans - tbl_trans	# $2e-3 ERROR
   4895  1.1     is 	short		tbl_trans - tbl_trans	# $2e-4 ERROR
   4896  1.1     is 	short		tbl_trans - tbl_trans	# $2e-5 ERROR
   4897  1.1     is 	short		tbl_trans - tbl_trans	# $2e-6 ERROR
   4898  1.1     is 	short		tbl_trans - tbl_trans	# $2e-7 ERROR
   4899  1.1     is 
   4900  1.1     is 	short		tbl_trans - tbl_trans	# $2f-0 ERROR
   4901  1.1     is 	short		tbl_trans - tbl_trans	# $2f-1 ERROR
   4902  1.1     is 	short		tbl_trans - tbl_trans	# $2f-2 ERROR
   4903  1.1     is 	short		tbl_trans - tbl_trans	# $2f-3 ERROR
   4904  1.1     is 	short		tbl_trans - tbl_trans	# $2f-4 ERROR
   4905  1.1     is 	short		tbl_trans - tbl_trans	# $2f-5 ERROR
   4906  1.1     is 	short		tbl_trans - tbl_trans	# $2f-6 ERROR
   4907  1.1     is 	short		tbl_trans - tbl_trans	# $2f-7 ERROR
   4908  1.1     is 
   4909  1.1     is 	short		ssincos	 - tbl_trans	# $30-0 fsincos norm
   4910  1.1     is 	short		ssincosz - tbl_trans	# $30-1 fsincos zero
   4911  1.1     is 	short		ssincosi - tbl_trans	# $30-2 fsincos inf
   4912  1.1     is 	short		ssincosqnan - tbl_trans	# $30-3 fsincos qnan
   4913  1.1     is 	short		ssincosd - tbl_trans	# $30-5 fsincos denorm
   4914  1.1     is 	short		ssincossnan - tbl_trans	# $30-4 fsincos snan
   4915  1.1     is 	short		tbl_trans - tbl_trans	# $30-6 fsincos unnorm
   4916  1.1     is 	short		tbl_trans - tbl_trans	# $30-7 ERROR
   4917  1.1     is 
   4918  1.1     is 	short		ssincos	 - tbl_trans	# $31-0 fsincos norm
   4919  1.1     is 	short		ssincosz - tbl_trans	# $31-1 fsincos zero
   4920  1.1     is 	short		ssincosi - tbl_trans	# $31-2 fsincos inf
   4921  1.1     is 	short		ssincosqnan - tbl_trans	# $31-3 fsincos qnan
   4922  1.1     is 	short		ssincosd - tbl_trans	# $31-5 fsincos denorm
   4923  1.1     is 	short		ssincossnan - tbl_trans	# $31-4 fsincos snan
   4924  1.1     is 	short		tbl_trans - tbl_trans	# $31-6 fsincos unnorm
   4925  1.1     is 	short		tbl_trans - tbl_trans	# $31-7 ERROR
   4926  1.1     is 
   4927  1.1     is 	short		ssincos	 - tbl_trans	# $32-0 fsincos norm
   4928  1.1     is 	short		ssincosz - tbl_trans	# $32-1 fsincos zero
   4929  1.1     is 	short		ssincosi - tbl_trans	# $32-2 fsincos inf
   4930  1.1     is 	short		ssincosqnan - tbl_trans	# $32-3 fsincos qnan
   4931  1.1     is 	short		ssincosd - tbl_trans	# $32-5 fsincos denorm
   4932  1.1     is 	short		ssincossnan - tbl_trans	# $32-4 fsincos snan
   4933  1.1     is 	short		tbl_trans - tbl_trans	# $32-6 fsincos unnorm
   4934  1.1     is 	short		tbl_trans - tbl_trans	# $32-7 ERROR
   4935  1.1     is 
   4936  1.1     is 	short		ssincos	 - tbl_trans	# $33-0 fsincos norm
   4937  1.1     is 	short		ssincosz - tbl_trans	# $33-1 fsincos zero
   4938  1.1     is 	short		ssincosi - tbl_trans	# $33-2 fsincos inf
   4939  1.1     is 	short		ssincosqnan - tbl_trans	# $33-3 fsincos qnan
   4940  1.1     is 	short		ssincosd - tbl_trans	# $33-5 fsincos denorm
   4941  1.1     is 	short		ssincossnan - tbl_trans	# $33-4 fsincos snan
   4942  1.1     is 	short		tbl_trans - tbl_trans	# $33-6 fsincos unnorm
   4943  1.1     is 	short		tbl_trans - tbl_trans	# $33-7 ERROR
   4944  1.1     is 
   4945  1.1     is 	short		ssincos	 - tbl_trans	# $34-0 fsincos norm
   4946  1.1     is 	short		ssincosz - tbl_trans	# $34-1 fsincos zero
   4947  1.1     is 	short		ssincosi - tbl_trans	# $34-2 fsincos inf
   4948  1.1     is 	short		ssincosqnan - tbl_trans	# $34-3 fsincos qnan
   4949  1.1     is 	short		ssincosd - tbl_trans	# $34-5 fsincos denorm
   4950  1.1     is 	short		ssincossnan - tbl_trans	# $34-4 fsincos snan
   4951  1.1     is 	short		tbl_trans - tbl_trans	# $34-6 fsincos unnorm
   4952  1.1     is 	short		tbl_trans - tbl_trans	# $34-7 ERROR
   4953  1.1     is 
   4954  1.1     is 	short		ssincos	 - tbl_trans	# $35-0 fsincos norm
   4955  1.1     is 	short		ssincosz - tbl_trans	# $35-1 fsincos zero
   4956  1.1     is 	short		ssincosi - tbl_trans	# $35-2 fsincos inf
   4957  1.1     is 	short		ssincosqnan - tbl_trans	# $35-3 fsincos qnan
   4958  1.1     is 	short		ssincosd - tbl_trans	# $35-5 fsincos denorm
   4959  1.1     is 	short		ssincossnan - tbl_trans	# $35-4 fsincos snan
   4960  1.1     is 	short		tbl_trans - tbl_trans	# $35-6 fsincos unnorm
   4961  1.1     is 	short		tbl_trans - tbl_trans	# $35-7 ERROR
   4962  1.1     is 
   4963  1.1     is 	short		ssincos	 - tbl_trans	# $36-0 fsincos norm
   4964  1.1     is 	short		ssincosz - tbl_trans	# $36-1 fsincos zero
   4965  1.1     is 	short		ssincosi - tbl_trans	# $36-2 fsincos inf
   4966  1.1     is 	short		ssincosqnan - tbl_trans	# $36-3 fsincos qnan
   4967  1.1     is 	short		ssincosd - tbl_trans	# $36-5 fsincos denorm
   4968  1.1     is 	short		ssincossnan - tbl_trans	# $36-4 fsincos snan
   4969  1.1     is 	short		tbl_trans - tbl_trans	# $36-6 fsincos unnorm
   4970  1.1     is 	short		tbl_trans - tbl_trans	# $36-7 ERROR
   4971  1.1     is 
   4972  1.1     is 	short		ssincos	 - tbl_trans	# $37-0 fsincos norm
   4973  1.1     is 	short		ssincosz - tbl_trans	# $37-1 fsincos zero
   4974  1.1     is 	short		ssincosi - tbl_trans	# $37-2 fsincos inf
   4975  1.1     is 	short		ssincosqnan - tbl_trans	# $37-3 fsincos qnan
   4976  1.1     is 	short		ssincosd - tbl_trans	# $37-5 fsincos denorm
   4977  1.1     is 	short		ssincossnan - tbl_trans	# $37-4 fsincos snan
   4978  1.1     is 	short		tbl_trans - tbl_trans	# $37-6 fsincos unnorm
   4979  1.1     is 	short		tbl_trans - tbl_trans	# $37-7 ERROR
   4980  1.1     is 
   4981  1.1     is ##########
   4982  1.1     is 
   4983  1.1     is # the instruction fetch access for the displacement word for the
   4984  1.1     is # fdbcc emulation failed. here, we create an access error frame
   4985  1.1     is # from the current frame and branch to _real_access().
   4986  1.1     is funimp_iacc:
   4987  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4988  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4989  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   4990  1.1     is 
   4991  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
   4992  1.1     is 
   4993  1.1     is 	unlk		%a6
   4994  1.1     is 
   4995  1.1     is 	mov.l		(%sp),-(%sp)		# store SR,hi(PC)
   4996  1.1     is 	mov.w		0x8(%sp),0x4(%sp)	# store lo(PC)
   4997  1.1     is 	mov.w		&0x4008,0x6(%sp)	# store voff
   4998  1.1     is 	mov.l		0x2(%sp),0x8(%sp)	# store EA
   4999  1.1     is 	mov.l		&0x09428001,0xc(%sp)	# store FSLW
   5000  1.1     is 
   5001  1.1     is 	btst		&0x5,(%sp)		# user or supervisor mode?
   5002  1.1     is 	beq.b		funimp_iacc_end		# user
   5003  1.1     is 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
   5004  1.1     is 
   5005  1.1     is funimp_iacc_end:
   5006  1.1     is 	bra.l		_real_access
   5007  1.1     is 
   5008  1.1     is #########################################################################
   5009  1.1     is # ssin():     computes the sine of a normalized input			#
   5010  1.1     is # ssind():    computes the sine of a denormalized input			#
   5011  1.1     is # scos():     computes the cosine of a normalized input			#
   5012  1.1     is # scosd():    computes the cosine of a denormalized input		#
   5013  1.1     is # ssincos():  computes the sine and cosine of a normalized input	#
   5014  1.1     is # ssincosd(): computes the sine and cosine of a denormalized input	#
   5015  1.1     is #									#
   5016  1.1     is # INPUT *************************************************************** #
   5017  1.1     is #	a0 = pointer to extended precision input			#
   5018  1.1     is #	d0 = round precision,mode					#
   5019  1.1     is #									#
   5020  1.1     is # OUTPUT ************************************************************** #
   5021  1.1     is #	fp0 = sin(X) or cos(X) 						#
   5022  1.1     is #									#
   5023  1.1     is #    For ssincos(X):							#
   5024  1.1     is #	fp0 = sin(X)							#
   5025  1.1     is #	fp1 = cos(X)							#
   5026  1.1     is #									#
   5027  1.1     is # ACCURACY and MONOTONICITY ******************************************* #
   5028  1.1     is #	The returned result is within 1 ulp in 64 significant bit, i.e.	#
   5029  1.1     is #	within 0.5001 ulp to 53 bits if the result is subsequently 	#
   5030  1.1     is #	rounded to double precision. The result is provably monotonic	#
   5031  1.1     is #	in double precision.						#
   5032  1.1     is #									#
   5033  1.1     is # ALGORITHM ***********************************************************	#
   5034  1.1     is #									#
   5035  1.1     is #	SIN and COS:							#
   5036  1.1     is #	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
   5037  1.1     is #									#
   5038  1.1     is #	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
   5039  1.1     is #									#
   5040  1.1     is #	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5041  1.1     is #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
   5042  1.1     is #		Overwrite k by k := k + AdjN.				#
   5043  1.1     is #									#
   5044  1.1     is #	4. If k is even, go to 6.					#
   5045  1.1     is #									#
   5046  1.1     is #	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. 		#
   5047  1.1     is #		Return sgn*cos(r) where cos(r) is approximated by an 	#
   5048  1.1     is #		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
   5049  1.1     is #		s = r*r.						#
   5050  1.1     is #		Exit.							#
   5051  1.1     is #									#
   5052  1.1     is #	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
   5053  1.1     is #		where sin(r) is approximated by an odd polynomial in r	#
   5054  1.1     is #		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
   5055  1.1     is #		Exit.							#
   5056  1.1     is #									#
   5057  1.1     is #	7. If |X| > 1, go to 9.						#
   5058  1.1     is #									#
   5059  1.1     is #	8. (|X|<2**(-40)) If SIN is invoked, return X; 			#
   5060  1.1     is #		otherwise return 1.					#
   5061  1.1     is #									#
   5062  1.1     is #	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, 		#
   5063  1.1     is #		go back to 3.						#
   5064  1.1     is #									#
   5065  1.1     is #	SINCOS:								#
   5066  1.1     is #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
   5067  1.1     is #									#
   5068  1.1     is #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5069  1.1     is #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
   5070  1.1     is #									#
   5071  1.1     is #	3. If k is even, go to 5.					#
   5072  1.1     is #									#
   5073  1.1     is #	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
   5074  1.1     is #		j1 exclusive or with the l.s.b. of k.			#
   5075  1.1     is #		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
   5076  1.1     is #		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
   5077  1.1     is #		sin(r) and cos(r) are computed as odd and even 		#
   5078  1.1     is #		polynomials in r, respectively. Exit			#
   5079  1.1     is #									#
   5080  1.1     is #	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
   5081  1.1     is #		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
   5082  1.1     is #		sin(r) and cos(r) are computed as odd and even 		#
   5083  1.1     is #		polynomials in r, respectively. Exit			#
   5084  1.1     is #									#
   5085  1.1     is #	6. If |X| > 1, go to 8.						#
   5086  1.1     is #									#
   5087  1.1     is #	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
   5088  1.1     is #									#
   5089  1.1     is #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, 		#
   5090  1.1     is #		go back to 2.						#
   5091  1.1     is #									#
   5092  1.1     is #########################################################################
   5093  1.1     is 
   5094  1.1     is SINA7:	long		0xBD6AAA77,0xCCC994F5
   5095  1.1     is SINA6:	long		0x3DE61209,0x7AAE8DA1
   5096  1.1     is SINA5:	long		0xBE5AE645,0x2A118AE4
   5097  1.1     is SINA4:	long		0x3EC71DE3,0xA5341531
   5098  1.1     is SINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
   5099  1.1     is SINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
   5100  1.1     is SINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
   5101  1.1     is 
   5102  1.1     is COSB8:	long		0x3D2AC4D0,0xD6011EE3
   5103  1.1     is COSB7:	long		0xBDA9396F,0x9F45AC19
   5104  1.1     is COSB6:	long		0x3E21EED9,0x0612C972
   5105  1.1     is COSB5:	long		0xBE927E4F,0xB79D9FCF
   5106  1.1     is COSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
   5107  1.1     is COSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
   5108  1.1     is COSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
   5109  1.1     is COSB1:	long		0xBF000000
   5110  1.1     is 
   5111  1.1     is 	set		INARG,FP_SCR0
   5112  1.1     is 
   5113  1.1     is 	set		X,FP_SCR0
   5114  1.1     is #	set		XDCARE,X+2
   5115  1.1     is 	set		XFRAC,X+4
   5116  1.1     is 
   5117  1.1     is 	set		RPRIME,FP_SCR0
   5118  1.1     is 	set		SPRIME,FP_SCR1
   5119  1.1     is 
   5120  1.1     is 	set		POSNEG1,L_SCR1
   5121  1.1     is 	set		TWOTO63,L_SCR1
   5122  1.1     is 
   5123  1.1     is 	set		ENDFLAG,L_SCR2
   5124  1.1     is 	set		INT,L_SCR2
   5125  1.1     is 
   5126  1.1     is 	set		ADJN,L_SCR3
   5127  1.1     is 
   5128  1.1     is ############################################
   5129  1.1     is 	global		ssin
   5130  1.1     is ssin:
   5131  1.1     is 	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
   5132  1.1     is 	bra.b		SINBGN
   5133  1.1     is 
   5134  1.1     is ############################################
   5135  1.1     is 	global		scos
   5136  1.1     is scos:
   5137  1.1     is 	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
   5138  1.1     is 
   5139  1.1     is ############################################
   5140  1.1     is SINBGN:
   5141  1.1     is #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
   5142  1.1     is 
   5143  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5144  1.1     is 	fmov.x		%fp0,X(%a6)		# save input at X
   5145  1.1     is 
   5146  1.1     is # "COMPACTIFY" X
   5147  1.1     is 	mov.l		(%a0),%d1		# put exp in hi word
   5148  1.1     is 	mov.w		4(%a0),%d1		# fetch hi(man)
   5149  1.1     is 	and.l		&0x7FFFFFFF,%d1		# strip sign
   5150  1.1     is 
   5151  1.1     is 	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
   5152  1.1     is 	bge.b		SOK1			# no
   5153  1.1     is 	bra.w		SINSM			# yes; input is very small
   5154  1.1     is 
   5155  1.1     is SOK1:
   5156  1.1     is 	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
   5157  1.1     is 	blt.b		SINMAIN			# no
   5158  1.1     is 	bra.w		SREDUCEX		# yes; input is very large
   5159  1.1     is 
   5160  1.1     is #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5161  1.1     is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5162  1.1     is SINMAIN:
   5163  1.1     is 	fmov.x		%fp0,%fp1
   5164  1.1     is 	fmul.d		TWOBYPI(%pc),%fp1 	# X*2/PI
   5165  1.1     is 
   5166  1.1     is 	lea		PITBL+0x200(%pc),%a1 	# TABLE OF N*PI/2, N = -32,...,32
   5167  1.1     is 
   5168  1.1     is 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
   5169  1.1     is 
   5170  1.1     is 	mov.l		INT(%a6),%d1		# make a copy of N
   5171  1.1     is 	asl.l		&4,%d1			# N *= 16
   5172  1.1     is 	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
   5173  1.1     is 
   5174  1.1     is # A1 IS THE ADDRESS OF N*PIBY2
   5175  1.1     is # ...WHICH IS IN TWO PIECES Y1 & Y2
   5176  1.1     is 	fsub.x		(%a1)+,%fp0 		# X-Y1
   5177  1.1     is 	fsub.s		(%a1),%fp0 		# fp0 = R = (X-Y1)-Y2
   5178  1.1     is 
   5179  1.1     is SINCONT:
   5180  1.1     is #--continuation from REDUCEX
   5181  1.1     is 
   5182  1.1     is #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
   5183  1.1     is 	mov.l		INT(%a6),%d1
   5184  1.1     is 	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
   5185  1.1     is 	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
   5186  1.1     is 	cmp.l		%d1,&0
   5187  1.1     is 	blt.w		COSPOLY
   5188  1.1     is 
   5189  1.1     is #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
   5190  1.1     is #--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
   5191  1.1     is #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
   5192  1.1     is #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
   5193  1.1     is #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
   5194  1.1     is #--WHERE T=S*S.
   5195  1.1     is #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
   5196  1.1     is #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
   5197  1.1     is SINPOLY:
   5198  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   5199  1.1     is 
   5200  1.1     is 	fmov.x		%fp0,X(%a6)		# X IS R
   5201  1.1     is 	fmul.x		%fp0,%fp0		# FP0 IS S
   5202  1.1     is 
   5203  1.1     is 	fmov.d		SINA7(%pc),%fp3
   5204  1.1     is 	fmov.d		SINA6(%pc),%fp2
   5205  1.1     is 
   5206  1.1     is 	fmov.x		%fp0,%fp1
   5207  1.1     is 	fmul.x		%fp1,%fp1		# FP1 IS T
   5208  1.1     is 
   5209  1.1     is 	ror.l		&1,%d1
   5210  1.1     is 	and.l		&0x80000000,%d1
   5211  1.1     is # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
   5212  1.1     is 	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
   5213  1.1     is 
   5214  1.1     is 	fmul.x		%fp1,%fp3		# TA7
   5215  1.1     is 	fmul.x		%fp1,%fp2		# TA6
   5216  1.1     is 
   5217  1.1     is 	fadd.d		SINA5(%pc),%fp3		# A5+TA7
   5218  1.1     is 	fadd.d		SINA4(%pc),%fp2		# A4+TA6
   5219  1.1     is 
   5220  1.1     is 	fmul.x		%fp1,%fp3		# T(A5+TA7)
   5221  1.1     is 	fmul.x		%fp1,%fp2		# T(A4+TA6)
   5222  1.1     is 
   5223  1.1     is 	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
   5224  1.1     is 	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
   5225  1.1     is 
   5226  1.1     is 	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
   5227  1.1     is 
   5228  1.1     is 	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
   5229  1.1     is 	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
   5230  1.1     is 	fmul.x		X(%a6),%fp0		# R'*S
   5231  1.1     is 
   5232  1.1     is 	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
   5233  1.1     is 
   5234  1.1     is 	fmul.x		%fp1,%fp0		# SIN(R')-R'
   5235  1.1     is 
   5236  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   5237  1.1     is 
   5238  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5239  1.1     is 	fadd.x		X(%a6),%fp0		# last inst - possible exception set
   5240  1.1     is 	bra		t_inx2
   5241  1.1     is 
   5242  1.1     is #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
   5243  1.1     is #--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
   5244  1.1     is #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
   5245  1.1     is #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
   5246  1.1     is #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
   5247  1.1     is #--WHERE T=S*S.
   5248  1.1     is #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
   5249  1.1     is #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
   5250  1.1     is #--AND IS THEREFORE STORED AS SINGLE PRECISION.
   5251  1.1     is COSPOLY:
   5252  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   5253  1.1     is 
   5254  1.1     is 	fmul.x		%fp0,%fp0		# FP0 IS S
   5255  1.1     is 
   5256  1.1     is 	fmov.d		COSB8(%pc),%fp2
   5257  1.1     is 	fmov.d		COSB7(%pc),%fp3
   5258  1.1     is 
   5259  1.1     is 	fmov.x		%fp0,%fp1
   5260  1.1     is 	fmul.x		%fp1,%fp1		# FP1 IS T
   5261  1.1     is 
   5262  1.1     is 	fmov.x		%fp0,X(%a6)		# X IS S
   5263  1.1     is 	ror.l		&1,%d1
   5264  1.1     is 	and.l		&0x80000000,%d1
   5265  1.1     is # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
   5266  1.1     is 
   5267  1.1     is 	fmul.x		%fp1,%fp2		# TB8
   5268  1.1     is 
   5269  1.1     is 	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
   5270  1.1     is 	and.l		&0x80000000,%d1
   5271  1.1     is 
   5272  1.1     is 	fmul.x		%fp1,%fp3		# TB7
   5273  1.1     is 
   5274  1.1     is 	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
   5275  1.1     is 	mov.l		%d1,POSNEG1(%a6)
   5276  1.1     is 
   5277  1.1     is 	fadd.d		COSB6(%pc),%fp2		# B6+TB8
   5278  1.1     is 	fadd.d		COSB5(%pc),%fp3		# B5+TB7
   5279  1.1     is 
   5280  1.1     is 	fmul.x		%fp1,%fp2		# T(B6+TB8)
   5281  1.1     is 	fmul.x		%fp1,%fp3		# T(B5+TB7)
   5282  1.1     is 
   5283  1.1     is 	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
   5284  1.1     is 	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
   5285  1.1     is 
   5286  1.1     is 	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
   5287  1.1     is 	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
   5288  1.1     is 
   5289  1.1     is 	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
   5290  1.1     is 	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
   5291  1.1     is 
   5292  1.1     is 	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
   5293  1.1     is 
   5294  1.1     is 	fadd.x		%fp1,%fp0
   5295  1.1     is 
   5296  1.1     is 	fmul.x		X(%a6),%fp0
   5297  1.1     is 
   5298  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   5299  1.1     is 
   5300  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5301  1.1     is 	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
   5302  1.1     is 	bra		t_inx2
   5303  1.1     is 
   5304  1.1     is ##############################################
   5305  1.1     is 
   5306  1.1     is # SINe: Big OR Small?
   5307  1.1     is #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
   5308  1.1     is #--IF |X| < 2**(-40), RETURN X OR 1.
   5309  1.1     is SINBORS:
   5310  1.1     is 	cmp.l		%d1,&0x3FFF8000
   5311  1.1     is 	bgt.l		SREDUCEX
   5312  1.1     is 
   5313  1.1     is SINSM:
   5314  1.1     is 	mov.l		ADJN(%a6),%d1
   5315  1.1     is 	cmp.l		%d1,&0
   5316  1.1     is 	bgt.b		COSTINY
   5317  1.1     is 
   5318  1.1     is # here, the operation may underflow iff the precision is sgl or dbl.
   5319  1.1     is # extended denorms are handled through another entry point.
   5320  1.1     is SINTINY:
   5321  1.1     is #	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
   5322  1.1     is 
   5323  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5324  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5325  1.1     is 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   5326  1.1     is 	bra		t_catch
   5327  1.1     is 
   5328  1.1     is COSTINY:
   5329  1.1     is 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
   5330  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5331  1.1     is 	fadd.s 		&0x80800000,%fp0	# last inst - possible exception set
   5332  1.1     is 	bra		t_pinx2
   5333  1.1     is 
   5334  1.1     is ################################################
   5335  1.1     is 	global		ssind
   5336  1.1     is #--SIN(X) = X FOR DENORMALIZED X
   5337  1.1     is ssind:
   5338  1.1     is 	bra		t_extdnrm
   5339  1.1     is 
   5340  1.1     is ############################################
   5341  1.1     is 	global		scosd
   5342  1.1     is #--COS(X) = 1 FOR DENORMALIZED X
   5343  1.1     is scosd:
   5344  1.1     is 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
   5345  1.1     is 	bra		t_pinx2
   5346  1.1     is 
   5347  1.1     is ##################################################
   5348  1.1     is 
   5349  1.1     is 	global		ssincos
   5350  1.1     is ssincos:
   5351  1.1     is #--SET ADJN TO 4
   5352  1.1     is 	mov.l		&4,ADJN(%a6)
   5353  1.1     is 
   5354  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5355  1.1     is 	fmov.x		%fp0,X(%a6)
   5356  1.1     is 
   5357  1.1     is 	mov.l		(%a0),%d1
   5358  1.1     is 	mov.w		4(%a0),%d1
   5359  1.1     is 	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
   5360  1.1     is 
   5361  1.1     is 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
   5362  1.1     is 	bge.b		SCOK1
   5363  1.1     is 	bra.w		SCSM
   5364  1.1     is 
   5365  1.1     is SCOK1:
   5366  1.1     is 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
   5367  1.1     is 	blt.b		SCMAIN
   5368  1.1     is 	bra.w		SREDUCEX
   5369  1.1     is 
   5370  1.1     is 
   5371  1.1     is #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5372  1.1     is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5373  1.1     is SCMAIN:
   5374  1.1     is 	fmov.x		%fp0,%fp1
   5375  1.1     is 
   5376  1.1     is 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
   5377  1.1     is 
   5378  1.1     is 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
   5379  1.1     is 
   5380  1.1     is 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
   5381  1.1     is 
   5382  1.1     is 	mov.l		INT(%a6),%d1
   5383  1.1     is 	asl.l		&4,%d1
   5384  1.1     is 	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
   5385  1.1     is 
   5386  1.1     is 	fsub.x		(%a1)+,%fp0		# X-Y1
   5387  1.1     is 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
   5388  1.1     is 
   5389  1.1     is SCCONT:
   5390  1.1     is #--continuation point from REDUCEX
   5391  1.1     is 
   5392  1.1     is 	mov.l		INT(%a6),%d1
   5393  1.1     is 	ror.l		&1,%d1
   5394  1.1     is 	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
   5395  1.1     is 	bge.w		NEVEN
   5396  1.1     is 
   5397  1.1     is SNODD:
   5398  1.1     is #--REGISTERS SAVED SO FAR: D0, A0, FP2.
   5399  1.1     is 	fmovm.x		&0x04,-(%sp)		# save fp2
   5400  1.1     is 
   5401  1.1     is 	fmov.x		%fp0,RPRIME(%a6)
   5402  1.1     is 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
   5403  1.1     is 	fmov.d		SINA7(%pc),%fp1		# A7
   5404  1.1     is 	fmov.d		COSB8(%pc),%fp2		# B8
   5405  1.1     is 	fmul.x		%fp0,%fp1		# SA7
   5406  1.1     is 	fmul.x		%fp0,%fp2		# SB8
   5407  1.1     is 
   5408  1.1     is 	mov.l		%d2,-(%sp)
   5409  1.1     is 	mov.l		%d1,%d2
   5410  1.1     is 	ror.l		&1,%d2
   5411  1.1     is 	and.l		&0x80000000,%d2
   5412  1.1     is 	eor.l		%d1,%d2
   5413  1.1     is 	and.l		&0x80000000,%d2
   5414  1.1     is 
   5415  1.1     is 	fadd.d		SINA6(%pc),%fp1		# A6+SA7
   5416  1.1     is 	fadd.d		COSB7(%pc),%fp2		# B7+SB8
   5417  1.1     is 
   5418  1.1     is 	fmul.x		%fp0,%fp1		# S(A6+SA7)
   5419  1.1     is 	eor.l		%d2,RPRIME(%a6)
   5420  1.1     is 	mov.l		(%sp)+,%d2
   5421  1.1     is 	fmul.x		%fp0,%fp2		# S(B7+SB8)
   5422  1.1     is 	ror.l		&1,%d1
   5423  1.1     is 	and.l		&0x80000000,%d1
   5424  1.1     is 	mov.l		&0x3F800000,POSNEG1(%a6)
   5425  1.1     is 	eor.l		%d1,POSNEG1(%a6)
   5426  1.1     is 
   5427  1.1     is 	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
   5428  1.1     is 	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
   5429  1.1     is 
   5430  1.1     is 	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
   5431  1.1     is 	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
   5432  1.1     is 	fmov.x		%fp0,SPRIME(%a6)
   5433  1.1     is 
   5434  1.1     is 	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
   5435  1.1     is 	eor.l		%d1,SPRIME(%a6)
   5436  1.1     is 	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
   5437  1.1     is 
   5438  1.1     is 	fmul.x		%fp0,%fp1		# S(A4+...)
   5439  1.1     is 	fmul.x		%fp0,%fp2		# S(B5+...)
   5440  1.1     is 
   5441  1.1     is 	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
   5442  1.1     is 	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
   5443  1.1     is 
   5444  1.1     is 	fmul.x		%fp0,%fp1		# S(A3+...)
   5445  1.1     is 	fmul.x		%fp0,%fp2		# S(B4+...)
   5446  1.1     is 
   5447  1.1     is 	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
   5448  1.1     is 	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
   5449  1.1     is 
   5450  1.1     is 	fmul.x		%fp0,%fp1		# S(A2+...)
   5451  1.1     is 	fmul.x		%fp0,%fp2		# S(B3+...)
   5452  1.1     is 
   5453  1.1     is 	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
   5454  1.1     is 	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
   5455  1.1     is 
   5456  1.1     is 	fmul.x		%fp0,%fp1		# S(A1+...)
   5457  1.1     is 	fmul.x		%fp2,%fp0		# S(B2+...)
   5458  1.1     is 
   5459  1.1     is 	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
   5460  1.1     is 	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
   5461  1.1     is 	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
   5462  1.1     is 
   5463  1.1     is 	fmovm.x		(%sp)+,&0x20		# restore fp2
   5464  1.1     is 
   5465  1.1     is 	fmov.l		%d0,%fpcr
   5466  1.1     is 	fadd.x		RPRIME(%a6),%fp1	# COS(X)
   5467  1.1     is 	bsr		sto_cos			# store cosine result
   5468  1.1     is 	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
   5469  1.1     is 	bra		t_inx2
   5470  1.1     is 
   5471  1.1     is NEVEN:
   5472  1.1     is #--REGISTERS SAVED SO FAR: FP2.
   5473  1.1     is 	fmovm.x		&0x04,-(%sp)		# save fp2
   5474  1.1     is 
   5475  1.1     is 	fmov.x		%fp0,RPRIME(%a6)
   5476  1.1     is 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
   5477  1.1     is 
   5478  1.1     is 	fmov.d		COSB8(%pc),%fp1		# B8
   5479  1.1     is 	fmov.d		SINA7(%pc),%fp2		# A7
   5480  1.1     is 
   5481  1.1     is 	fmul.x		%fp0,%fp1		# SB8
   5482  1.1     is 	fmov.x		%fp0,SPRIME(%a6)
   5483  1.1     is 	fmul.x		%fp0,%fp2		# SA7
   5484  1.1     is 
   5485  1.1     is 	ror.l		&1,%d1
   5486  1.1     is 	and.l		&0x80000000,%d1
   5487  1.1     is 
   5488  1.1     is 	fadd.d		COSB7(%pc),%fp1		# B7+SB8
   5489  1.1     is 	fadd.d		SINA6(%pc),%fp2		# A6+SA7
   5490  1.1     is 
   5491  1.1     is 	eor.l		%d1,RPRIME(%a6)
   5492  1.1     is 	eor.l		%d1,SPRIME(%a6)
   5493  1.1     is 
   5494  1.1     is 	fmul.x		%fp0,%fp1		# S(B7+SB8)
   5495  1.1     is 
   5496  1.1     is 	or.l		&0x3F800000,%d1
   5497  1.1     is 	mov.l		%d1,POSNEG1(%a6)
   5498  1.1     is 
   5499  1.1     is 	fmul.x		%fp0,%fp2		# S(A6+SA7)
   5500  1.1     is 
   5501  1.1     is 	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
   5502  1.1     is 	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
   5503  1.1     is 
   5504  1.1     is 	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
   5505  1.1     is 	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
   5506  1.1     is 
   5507  1.1     is 	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
   5508  1.1     is 	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
   5509  1.1     is 
   5510  1.1     is 	fmul.x		%fp0,%fp1		# S(B5+...)
   5511  1.1     is 	fmul.x		%fp0,%fp2		# S(A4+...)
   5512  1.1     is 
   5513  1.1     is 	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
   5514  1.1     is 	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
   5515  1.1     is 
   5516  1.1     is 	fmul.x		%fp0,%fp1		# S(B4+...)
   5517  1.1     is 	fmul.x		%fp0,%fp2		# S(A3+...)
   5518  1.1     is 
   5519  1.1     is 	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
   5520  1.1     is 	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
   5521  1.1     is 
   5522  1.1     is 	fmul.x		%fp0,%fp1		# S(B3+...)
   5523  1.1     is 	fmul.x		%fp0,%fp2		# S(A2+...)
   5524  1.1     is 
   5525  1.1     is 	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
   5526  1.1     is 	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
   5527  1.1     is 
   5528  1.1     is 	fmul.x		%fp0,%fp1		# S(B2+...)
   5529  1.1     is 	fmul.x		%fp2,%fp0		# s(a1+...)
   5530  1.1     is 
   5531  1.1     is 
   5532  1.1     is 	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
   5533  1.1     is 	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
   5534  1.1     is 	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
   5535  1.1     is 
   5536  1.1     is 	fmovm.x		(%sp)+,&0x20		# restore fp2
   5537  1.1     is 
   5538  1.1     is 	fmov.l		%d0,%fpcr
   5539  1.1     is 	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
   5540  1.1     is 	bsr		sto_cos			# store cosine result
   5541  1.1     is 	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
   5542  1.1     is 	bra		t_inx2
   5543  1.1     is 
   5544  1.1     is ################################################
   5545  1.1     is 
   5546  1.1     is SCBORS:
   5547  1.1     is 	cmp.l		%d1,&0x3FFF8000
   5548  1.1     is 	bgt.w		SREDUCEX
   5549  1.1     is 
   5550  1.1     is ################################################
   5551  1.1     is 
   5552  1.1     is SCSM:
   5553  1.1     is #	mov.w		&0x0000,XDCARE(%a6)
   5554  1.1     is 	fmov.s		&0x3F800000,%fp1
   5555  1.1     is 
   5556  1.1     is 	fmov.l		%d0,%fpcr
   5557  1.1     is 	fsub.s		&0x00800000,%fp1
   5558  1.1     is 	bsr		sto_cos			# store cosine result
   5559  1.1     is 	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
   5560  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5561  1.1     is 	fmov.x		X(%a6),%fp0
   5562  1.1     is 	bra		t_catch
   5563  1.1     is 
   5564  1.1     is ##############################################
   5565  1.1     is 
   5566  1.1     is 	global		ssincosd
   5567  1.1     is #--SIN AND COS OF X FOR DENORMALIZED X
   5568  1.1     is ssincosd:
   5569  1.1     is 	mov.l		%d0,-(%sp)		# save d0
   5570  1.1     is 	fmov.s		&0x3F800000,%fp1
   5571  1.1     is 	bsr		sto_cos			# store cosine result
   5572  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   5573  1.1     is 	bra		t_extdnrm
   5574  1.1     is 
   5575  1.1     is ############################################
   5576  1.1     is 
   5577  1.1     is #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
   5578  1.1     is #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
   5579  1.1     is #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
   5580  1.1     is SREDUCEX:
   5581  1.1     is 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
   5582  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   5583  1.1     is 	fmov.s		&0x00000000,%fp1	# fp1 = 0
   5584  1.1     is 
   5585  1.1     is #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
   5586  1.1     is #--there is a danger of unwanted overflow in first LOOP iteration.  In this
   5587  1.1     is #--case, reduce argument by one remainder step to make subsequent reduction
   5588  1.1     is #--safe.
   5589  1.1     is 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
   5590  1.1     is 	bne.b		SLOOP			# no
   5591  1.1     is 
   5592  1.1     is # yes; create 2**16383*PI/2
   5593  1.1     is 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
   5594  1.1     is 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
   5595  1.1     is 	clr.l		FP_SCR0_LO(%a6)
   5596  1.1     is 
   5597  1.1     is # create low half of 2**16383*PI/2 at FP_SCR1
   5598  1.1     is 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
   5599  1.1     is 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
   5600  1.1     is 	clr.l		FP_SCR1_LO(%a6)
   5601  1.1     is 
   5602  1.1     is 	ftest.x		%fp0			# test sign of argument
   5603  1.1     is 	fblt.w		sred_neg
   5604  1.1     is 
   5605  1.1     is 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
   5606  1.1     is 	or.b		&0x80,FP_SCR1_EX(%a6)
   5607  1.1     is sred_neg:
   5608  1.1     is 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
   5609  1.1     is 	fmov.x		%fp0,%fp1		# save high result in fp1
   5610  1.1     is 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
   5611  1.1     is 	fsub.x		%fp0,%fp1		# determine low component of result
   5612  1.1     is 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
   5613  1.1     is 
   5614  1.1     is #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
   5615  1.1     is #--integer quotient will be stored in N
   5616  1.1     is #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
   5617  1.1     is SLOOP:
   5618  1.1     is 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
   5619  1.1     is 	mov.w		INARG(%a6),%d1
   5620  1.1     is 	mov.l		%d1,%a1			# save a copy of D0
   5621  1.1     is 	and.l		&0x00007FFF,%d1
   5622  1.1     is 	sub.l		&0x00003FFF,%d1		# d0 = K
   5623  1.1     is 	cmp.l		%d1,&28
   5624  1.1     is 	ble.b		SLASTLOOP
   5625  1.1     is SCONTLOOP:
   5626  1.1     is 	sub.l		&27,%d1			# d0 = L := K-27
   5627  1.1     is 	mov.b		&0,ENDFLAG(%a6)
   5628  1.1     is 	bra.b		SWORK
   5629  1.1     is SLASTLOOP:
   5630  1.1     is 	clr.l		%d1			# d0 = L := 0
   5631  1.1     is 	mov.b		&1,ENDFLAG(%a6)
   5632  1.1     is 
   5633  1.1     is SWORK:
   5634  1.1     is #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
   5635  1.1     is #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
   5636  1.1     is 
   5637  1.1     is #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
   5638  1.1     is #--2**L * (PIby2_1), 2**L * (PIby2_2)
   5639  1.1     is 
   5640  1.1     is 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
   5641  1.1     is 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
   5642  1.1     is 
   5643  1.1     is 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
   5644  1.1     is 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
   5645  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
   5646  1.1     is 
   5647  1.1     is 	fmov.x		%fp0,%fp2
   5648  1.1     is 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
   5649  1.1     is 
   5650  1.1     is #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
   5651  1.1     is #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
   5652  1.1     is #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
   5653  1.1     is #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
   5654  1.1     is #--US THE DESIRED VALUE IN FLOATING POINT.
   5655  1.1     is 	mov.l		%a1,%d2
   5656  1.1     is 	swap		%d2
   5657  1.1     is 	and.l		&0x80000000,%d2
   5658  1.1     is 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
   5659  1.1     is 	mov.l		%d2,TWOTO63(%a6)
   5660  1.1     is 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
   5661  1.1     is 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
   5662  1.1     is #	fint.x		%fp2
   5663  1.1     is 
   5664  1.1     is #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
   5665  1.1     is 	mov.l		%d1,%d2			# d2 = L
   5666  1.1     is 
   5667  1.1     is 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
   5668  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)
   5669  1.1     is 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
   5670  1.1     is 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
   5671  1.1     is 
   5672  1.1     is 	add.l		&0x00003FDD,%d1
   5673  1.1     is 	mov.w		%d1,FP_SCR1_EX(%a6)
   5674  1.1     is 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
   5675  1.1     is 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
   5676  1.1     is 
   5677  1.1     is 	mov.b		ENDFLAG(%a6),%d1
   5678  1.1     is 
   5679  1.1     is #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
   5680  1.1     is #--P2 = 2**(L) * Piby2_2
   5681  1.1     is 	fmov.x		%fp2,%fp4		# fp4 = N
   5682  1.1     is 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
   5683  1.1     is 	fmov.x		%fp2,%fp5		# fp5 = N
   5684  1.1     is 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
   5685  1.1     is 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
   5686  1.1     is 
   5687  1.1     is #--we want P+p = W+w  but  |p| <= half ulp of P
   5688  1.1     is #--Then, we need to compute  A := R-P   and  a := r-p
   5689  1.1     is 	fadd.x		%fp5,%fp3		# fp3 = P
   5690  1.1     is 	fsub.x		%fp3,%fp4		# fp4 = W-P
   5691  1.1     is 
   5692  1.1     is 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
   5693  1.1     is 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
   5694  1.1     is 
   5695  1.1     is 	fmov.x		%fp0,%fp3		# fp3 = A
   5696  1.1     is 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
   5697  1.1     is 
   5698  1.1     is #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
   5699  1.1     is #--|r| <= half ulp of R.
   5700  1.1     is 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
   5701  1.1     is #--No need to calculate r if this is the last loop
   5702  1.1     is 	cmp.b		%d1,&0
   5703  1.1     is 	bgt.w		SRESTORE
   5704  1.1     is 
   5705  1.1     is #--Need to calculate r
   5706  1.1     is 	fsub.x		%fp0,%fp3		# fp3 = A-R
   5707  1.1     is 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
   5708  1.1     is 	bra.w		SLOOP
   5709  1.1     is 
   5710  1.1     is SRESTORE:
   5711  1.1     is 	fmov.l		%fp2,INT(%a6)
   5712  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   5713  1.1     is 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
   5714  1.1     is 
   5715  1.1     is 	mov.l		ADJN(%a6),%d1
   5716  1.1     is 	cmp.l		%d1,&4
   5717  1.1     is 
   5718  1.1     is 	blt.w		SINCONT
   5719  1.1     is 	bra.w		SCCONT
   5720  1.1     is 
   5721  1.1     is #########################################################################
   5722  1.1     is # stan():  computes the tangent of a normalized input			#
   5723  1.1     is # stand(): computes the tangent of a denormalized input			#
   5724  1.1     is #									#
   5725  1.1     is # INPUT *************************************************************** #
   5726  1.1     is #	a0 = pointer to extended precision input			#
   5727  1.1     is #	d0 = round precision,mode					#
   5728  1.1     is #									#
   5729  1.1     is # OUTPUT ************************************************************** #
   5730  1.1     is #	fp0 = tan(X)							#
   5731  1.1     is #									#
   5732  1.1     is # ACCURACY and MONOTONICITY ******************************************* #
   5733  1.1     is #	The returned result is within 3 ulp in 64 significant bit, i.e. #
   5734  1.1     is #	within 0.5001 ulp to 53 bits if the result is subsequently	#
   5735  1.1     is #	rounded to double precision. The result is provably monotonic	#
   5736  1.1     is #	in double precision.						#
   5737  1.1     is #									#
   5738  1.1     is # ALGORITHM *********************************************************** #
   5739  1.1     is #									#
   5740  1.1     is #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
   5741  1.1     is #									#
   5742  1.1     is #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5743  1.1     is #		k = N mod 2, so in particular, k = 0 or 1.		#
   5744  1.1     is #									#
   5745  1.1     is #	3. If k is odd, go to 5.					#
   5746  1.1     is #									#
   5747  1.1     is #	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
   5748  1.1     is #		rational function U/V where				#
   5749  1.1     is #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
   5750  1.1     is #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
   5751  1.1     is #		Exit.							#
   5752  1.1     is #									#
   5753  1.1     is #	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
   5754  1.1     is #		a rational function U/V where				#
   5755  1.1     is #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
   5756  1.1     is #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
   5757  1.1     is #		-Cot(r) = -V/U. Exit.					#
   5758  1.1     is #									#
   5759  1.1     is #	6. If |X| > 1, go to 8.						#
   5760  1.1     is #									#
   5761  1.1     is #	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
   5762  1.1     is #									#
   5763  1.1     is #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back 	#
   5764  1.1     is #		to 2.							#
   5765  1.1     is #									#
   5766  1.1     is #########################################################################
   5767  1.1     is 
   5768  1.1     is TANQ4:
   5769  1.1     is 	long		0x3EA0B759,0xF50F8688
   5770  1.1     is TANP3:
   5771  1.1     is 	long		0xBEF2BAA5,0xA8924F04
   5772  1.1     is 
   5773  1.1     is TANQ3:
   5774  1.1     is 	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
   5775  1.1     is 
   5776  1.1     is TANP2:
   5777  1.1     is 	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
   5778  1.1     is 
   5779  1.1     is TANQ2:
   5780  1.1     is 	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
   5781  1.1     is 
   5782  1.1     is TANP1:
   5783  1.1     is 	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
   5784  1.1     is 
   5785  1.1     is TANQ1:
   5786  1.1     is 	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
   5787  1.1     is 
   5788  1.1     is INVTWOPI:
   5789  1.1     is 	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
   5790  1.1     is 
   5791  1.1     is TWOPI1:
   5792  1.1     is 	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
   5793  1.1     is TWOPI2:
   5794  1.1     is 	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
   5795  1.1     is 
   5796  1.1     is #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
   5797  1.1     is #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
   5798  1.1     is #--MOST 69 BITS LONG.
   5799  1.1     is #	global		PITBL
   5800  1.1     is PITBL:
   5801  1.1     is 	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
   5802  1.1     is 	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
   5803  1.1     is 	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
   5804  1.1     is 	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
   5805  1.1     is 	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
   5806  1.1     is 	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
   5807  1.1     is 	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
   5808  1.1     is 	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
   5809  1.1     is 	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
   5810  1.1     is 	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
   5811  1.1     is 	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
   5812  1.1     is 	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
   5813  1.1     is 	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
   5814  1.1     is 	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
   5815  1.1     is 	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
   5816  1.1     is 	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
   5817  1.1     is 	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
   5818  1.1     is 	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
   5819  1.1     is 	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
   5820  1.1     is 	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
   5821  1.1     is 	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
   5822  1.1     is 	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
   5823  1.1     is 	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
   5824  1.1     is 	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
   5825  1.1     is 	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
   5826  1.1     is 	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
   5827  1.1     is 	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
   5828  1.1     is 	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
   5829  1.1     is 	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
   5830  1.1     is 	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
   5831  1.1     is 	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
   5832  1.1     is 	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
   5833  1.1     is 	long		0x00000000,0x00000000,0x00000000,0x00000000
   5834  1.1     is 	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
   5835  1.1     is 	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
   5836  1.1     is 	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
   5837  1.1     is 	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
   5838  1.1     is 	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
   5839  1.1     is 	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
   5840  1.1     is 	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
   5841  1.1     is 	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
   5842  1.1     is 	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
   5843  1.1     is 	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
   5844  1.1     is 	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
   5845  1.1     is 	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
   5846  1.1     is 	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
   5847  1.1     is 	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
   5848  1.1     is 	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
   5849  1.1     is 	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
   5850  1.1     is 	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
   5851  1.1     is 	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
   5852  1.1     is 	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
   5853  1.1     is 	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
   5854  1.1     is 	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
   5855  1.1     is 	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
   5856  1.1     is 	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
   5857  1.1     is 	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
   5858  1.1     is 	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
   5859  1.1     is 	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
   5860  1.1     is 	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
   5861  1.1     is 	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
   5862  1.1     is 	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
   5863  1.1     is 	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
   5864  1.1     is 	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
   5865  1.1     is 	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
   5866  1.1     is 
   5867  1.1     is 	set		INARG,FP_SCR0
   5868  1.1     is 
   5869  1.1     is 	set		TWOTO63,L_SCR1
   5870  1.1     is 	set		INT,L_SCR1
   5871  1.1     is 	set		ENDFLAG,L_SCR2
   5872  1.1     is 
   5873  1.1     is 	global		stan
   5874  1.1     is stan:
   5875  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5876  1.1     is 
   5877  1.1     is 	mov.l		(%a0),%d1
   5878  1.1     is 	mov.w		4(%a0),%d1
   5879  1.1     is 	and.l		&0x7FFFFFFF,%d1
   5880  1.1     is 
   5881  1.1     is 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
   5882  1.1     is 	bge.b		TANOK1
   5883  1.1     is 	bra.w		TANSM
   5884  1.1     is TANOK1:
   5885  1.1     is 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
   5886  1.1     is 	blt.b		TANMAIN
   5887  1.1     is 	bra.w		REDUCEX
   5888  1.1     is 
   5889  1.1     is TANMAIN:
   5890  1.1     is #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5891  1.1     is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5892  1.1     is 	fmov.x		%fp0,%fp1
   5893  1.1     is 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
   5894  1.1     is 
   5895  1.1     is 	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
   5896  1.1     is 
   5897  1.1     is 	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
   5898  1.1     is 
   5899  1.1     is 	asl.l		&4,%d1
   5900  1.1     is 	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
   5901  1.1     is 
   5902  1.1     is 	fsub.x		(%a1)+,%fp0		# X-Y1
   5903  1.1     is 
   5904  1.1     is 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
   5905  1.1     is 
   5906  1.1     is 	ror.l		&5,%d1
   5907  1.1     is 	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
   5908  1.1     is 
   5909  1.1     is TANCONT:
   5910  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
   5911  1.1     is 
   5912  1.1     is 	cmp.l		%d1,&0
   5913  1.1     is 	blt.w		NODD
   5914  1.1     is 
   5915  1.1     is 	fmov.x		%fp0,%fp1
   5916  1.1     is 	fmul.x		%fp1,%fp1		# S = R*R
   5917  1.1     is 
   5918  1.1     is 	fmov.d		TANQ4(%pc),%fp3
   5919  1.1     is 	fmov.d		TANP3(%pc),%fp2
   5920  1.1     is 
   5921  1.1     is 	fmul.x		%fp1,%fp3		# SQ4
   5922  1.1     is 	fmul.x		%fp1,%fp2		# SP3
   5923  1.1     is 
   5924  1.1     is 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
   5925  1.1     is 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
   5926  1.1     is 
   5927  1.1     is 	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
   5928  1.1     is 	fmul.x		%fp1,%fp2		# S(P2+SP3)
   5929  1.1     is 
   5930  1.1     is 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
   5931  1.1     is 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
   5932  1.1     is 
   5933  1.1     is 	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
   5934  1.1     is 	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
   5935  1.1     is 
   5936  1.1     is 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
   5937  1.1     is 	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
   5938  1.1     is 
   5939  1.1     is 	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
   5940  1.1     is 
   5941  1.1     is 	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
   5942  1.1     is 
   5943  1.1     is 	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
   5944  1.1     is 
   5945  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
   5946  1.1     is 
   5947  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5948  1.1     is 	fdiv.x		%fp1,%fp0		# last inst - possible exception set
   5949  1.1     is 	bra		t_inx2
   5950  1.1     is 
   5951  1.1     is NODD:
   5952  1.1     is 	fmov.x		%fp0,%fp1
   5953  1.1     is 	fmul.x		%fp0,%fp0		# S = R*R
   5954  1.1     is 
   5955  1.1     is 	fmov.d		TANQ4(%pc),%fp3
   5956  1.1     is 	fmov.d		TANP3(%pc),%fp2
   5957  1.1     is 
   5958  1.1     is 	fmul.x		%fp0,%fp3		# SQ4
   5959  1.1     is 	fmul.x		%fp0,%fp2		# SP3
   5960  1.1     is 
   5961  1.1     is 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
   5962  1.1     is 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
   5963  1.1     is 
   5964  1.1     is 	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
   5965  1.1     is 	fmul.x		%fp0,%fp2		# S(P2+SP3)
   5966  1.1     is 
   5967  1.1     is 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
   5968  1.1     is 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
   5969  1.1     is 
   5970  1.1     is 	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
   5971  1.1     is 	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
   5972  1.1     is 
   5973  1.1     is 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
   5974  1.1     is 	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
   5975  1.1     is 
   5976  1.1     is 	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
   5977  1.1     is 
   5978  1.1     is 	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
   5979  1.1     is 	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
   5980  1.1     is 
   5981  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
   5982  1.1     is 
   5983  1.1     is 	fmov.x		%fp1,-(%sp)
   5984  1.1     is 	eor.l		&0x80000000,(%sp)
   5985  1.1     is 
   5986  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5987  1.1     is 	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
   5988  1.1     is 	bra		t_inx2
   5989  1.1     is 
   5990  1.1     is TANBORS:
   5991  1.1     is #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
   5992  1.1     is #--IF |X| < 2**(-40), RETURN X OR 1.
   5993  1.1     is 	cmp.l		%d1,&0x3FFF8000
   5994  1.1     is 	bgt.b		REDUCEX
   5995  1.1     is 
   5996  1.1     is TANSM:
   5997  1.1     is 	fmov.x		%fp0,-(%sp)
   5998  1.1     is 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5999  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6000  1.1     is 	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
   6001  1.1     is 	bra		t_catch
   6002  1.1     is 
   6003  1.1     is 	global		stand
   6004  1.1     is #--TAN(X) = X FOR DENORMALIZED X
   6005  1.1     is stand:
   6006  1.1     is 	bra		t_extdnrm
   6007  1.1     is 
   6008  1.1     is #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
   6009  1.1     is #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
   6010  1.1     is #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
   6011  1.1     is REDUCEX:
   6012  1.1     is 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
   6013  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   6014  1.1     is 	fmov.s		&0x00000000,%fp1	# fp1 = 0
   6015  1.1     is 
   6016  1.1     is #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
   6017  1.1     is #--there is a danger of unwanted overflow in first LOOP iteration.  In this
   6018  1.1     is #--case, reduce argument by one remainder step to make subsequent reduction
   6019  1.1     is #--safe.
   6020  1.1     is 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
   6021  1.1     is 	bne.b		LOOP			# no
   6022  1.1     is 
   6023  1.1     is # yes; create 2**16383*PI/2
   6024  1.1     is 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
   6025  1.1     is 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
   6026  1.1     is 	clr.l		FP_SCR0_LO(%a6)
   6027  1.1     is 
   6028  1.1     is # create low half of 2**16383*PI/2 at FP_SCR1
   6029  1.1     is 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
   6030  1.1     is 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
   6031  1.1     is 	clr.l		FP_SCR1_LO(%a6)
   6032  1.1     is 
   6033  1.1     is 	ftest.x		%fp0			# test sign of argument
   6034  1.1     is 	fblt.w		red_neg
   6035  1.1     is 
   6036  1.1     is 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
   6037  1.1     is 	or.b		&0x80,FP_SCR1_EX(%a6)
   6038  1.1     is red_neg:
   6039  1.1     is 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
   6040  1.1     is 	fmov.x		%fp0,%fp1		# save high result in fp1
   6041  1.1     is 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
   6042  1.1     is 	fsub.x		%fp0,%fp1		# determine low component of result
   6043  1.1     is 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
   6044  1.1     is 
   6045  1.1     is #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
   6046  1.1     is #--integer quotient will be stored in N
   6047  1.1     is #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
   6048  1.1     is LOOP:
   6049  1.1     is 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
   6050  1.1     is 	mov.w		INARG(%a6),%d1
   6051  1.1     is 	mov.l		%d1,%a1			# save a copy of D0
   6052  1.1     is 	and.l		&0x00007FFF,%d1
   6053  1.1     is 	sub.l		&0x00003FFF,%d1		# d0 = K
   6054  1.1     is 	cmp.l		%d1,&28
   6055  1.1     is 	ble.b		LASTLOOP
   6056  1.1     is CONTLOOP:
   6057  1.1     is 	sub.l		&27,%d1			# d0 = L := K-27
   6058  1.1     is 	mov.b		&0,ENDFLAG(%a6)
   6059  1.1     is 	bra.b		WORK
   6060  1.1     is LASTLOOP:
   6061  1.1     is 	clr.l		%d1			# d0 = L := 0
   6062  1.1     is 	mov.b		&1,ENDFLAG(%a6)
   6063  1.1     is 
   6064  1.1     is WORK:
   6065  1.1     is #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
   6066  1.1     is #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
   6067  1.1     is 
   6068  1.1     is #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
   6069  1.1     is #--2**L * (PIby2_1), 2**L * (PIby2_2)
   6070  1.1     is 
   6071  1.1     is 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
   6072  1.1     is 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
   6073  1.1     is 
   6074  1.1     is 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
   6075  1.1     is 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
   6076  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
   6077  1.1     is 
   6078  1.1     is 	fmov.x		%fp0,%fp2
   6079  1.1     is 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
   6080  1.1     is 
   6081  1.1     is #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
   6082  1.1     is #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
   6083  1.1     is #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
   6084  1.1     is #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
   6085  1.1     is #--US THE DESIRED VALUE IN FLOATING POINT.
   6086  1.1     is 	mov.l		%a1,%d2
   6087  1.1     is 	swap		%d2
   6088  1.1     is 	and.l		&0x80000000,%d2
   6089  1.1     is 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
   6090  1.1     is 	mov.l		%d2,TWOTO63(%a6)
   6091  1.1     is 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
   6092  1.1     is 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
   6093  1.1     is #	fintrz.x	%fp2,%fp2
   6094  1.1     is 
   6095  1.1     is #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
   6096  1.1     is 	mov.l		%d1,%d2			# d2 = L
   6097  1.1     is 
   6098  1.1     is 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
   6099  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)
   6100  1.1     is 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
   6101  1.1     is 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
   6102  1.1     is 
   6103  1.1     is 	add.l		&0x00003FDD,%d1
   6104  1.1     is 	mov.w		%d1,FP_SCR1_EX(%a6)
   6105  1.1     is 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
   6106  1.1     is 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
   6107  1.1     is 
   6108  1.1     is 	mov.b		ENDFLAG(%a6),%d1
   6109  1.1     is 
   6110  1.1     is #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
   6111  1.1     is #--P2 = 2**(L) * Piby2_2
   6112  1.1     is 	fmov.x		%fp2,%fp4		# fp4 = N
   6113  1.1     is 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
   6114  1.1     is 	fmov.x		%fp2,%fp5		# fp5 = N
   6115  1.1     is 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
   6116  1.1     is 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
   6117  1.1     is 
   6118  1.1     is #--we want P+p = W+w  but  |p| <= half ulp of P
   6119  1.1     is #--Then, we need to compute  A := R-P   and  a := r-p
   6120  1.1     is 	fadd.x		%fp5,%fp3		# fp3 = P
   6121  1.1     is 	fsub.x		%fp3,%fp4		# fp4 = W-P
   6122  1.1     is 
   6123  1.1     is 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
   6124  1.1     is 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
   6125  1.1     is 
   6126  1.1     is 	fmov.x		%fp0,%fp3		# fp3 = A
   6127  1.1     is 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
   6128  1.1     is 
   6129  1.1     is #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
   6130  1.1     is #--|r| <= half ulp of R.
   6131  1.1     is 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
   6132  1.1     is #--No need to calculate r if this is the last loop
   6133  1.1     is 	cmp.b		%d1,&0
   6134  1.1     is 	bgt.w		RESTORE
   6135  1.1     is 
   6136  1.1     is #--Need to calculate r
   6137  1.1     is 	fsub.x		%fp0,%fp3		# fp3 = A-R
   6138  1.1     is 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
   6139  1.1     is 	bra.w		LOOP
   6140  1.1     is 
   6141  1.1     is RESTORE:
   6142  1.1     is 	fmov.l		%fp2,INT(%a6)
   6143  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   6144  1.1     is 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
   6145  1.1     is 
   6146  1.1     is 	mov.l		INT(%a6),%d1
   6147  1.1     is 	ror.l		&1,%d1
   6148  1.1     is 
   6149  1.1     is 	bra.w		TANCONT
   6150  1.1     is 
   6151  1.1     is #########################################################################
   6152  1.1     is # satan():  computes the arctangent of a normalized number		#
   6153  1.1     is # satand(): computes the arctangent of a denormalized number		#
   6154  1.1     is #									#
   6155  1.1     is # INPUT	*************************************************************** #
   6156  1.1     is #	a0 = pointer to extended precision input			#
   6157  1.1     is #	d0 = round precision,mode					#
   6158  1.1     is #									#
   6159  1.1     is # OUTPUT ************************************************************** #
   6160  1.1     is #	fp0 = arctan(X)							#
   6161  1.1     is #									#
   6162  1.1     is # ACCURACY and MONOTONICITY ******************************************* #
   6163  1.1     is #	The returned result is within 2 ulps in	64 significant bit,	#
   6164  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6165  1.1     is #	rounded to double precision. The result is provably monotonic	#
   6166  1.1     is #	in double precision. 						#
   6167  1.1     is #									#
   6168  1.1     is # ALGORITHM *********************************************************** #
   6169  1.1     is #	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
   6170  1.1     is #									#
   6171  1.1     is #	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. 			#
   6172  1.1     is #		Note that k = -4, -3,..., or 3.				#
   6173  1.1     is #		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 	#
   6174  1.1     is #		significant bits of X with a bit-1 attached at the 6-th	#
   6175  1.1     is #		bit position. Define u to be u = (X-F) / (1 + X*F).	#
   6176  1.1     is #									#
   6177  1.1     is #	Step 3. Approximate arctan(u) by a polynomial poly.		#
   6178  1.1     is #									#
   6179  1.1     is #	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a 	#
   6180  1.1     is #		table of values calculated beforehand. Exit.		#
   6181  1.1     is #									#
   6182  1.1     is #	Step 5. If |X| >= 16, go to Step 7.				#
   6183  1.1     is #									#
   6184  1.1     is #	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
   6185  1.1     is #									#
   6186  1.1     is #	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd 	#
   6187  1.1     is #		polynomial in X'.					#
   6188  1.1     is #		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
   6189  1.1     is #									#
   6190  1.1     is #########################################################################
   6191  1.1     is 
   6192  1.1     is ATANA3:	long		0xBFF6687E,0x314987D8
   6193  1.1     is ATANA2:	long		0x4002AC69,0x34A26DB3
   6194  1.1     is ATANA1:	long		0xBFC2476F,0x4E1DA28E
   6195  1.1     is 
   6196  1.1     is ATANB6:	long		0x3FB34444,0x7F876989
   6197  1.1     is ATANB5:	long		0xBFB744EE,0x7FAF45DB
   6198  1.1     is ATANB4:	long		0x3FBC71C6,0x46940220
   6199  1.1     is ATANB3:	long		0xBFC24924,0x921872F9
   6200  1.1     is ATANB2:	long		0x3FC99999,0x99998FA9
   6201  1.1     is ATANB1:	long		0xBFD55555,0x55555555
   6202  1.1     is 
   6203  1.1     is ATANC5:	long		0xBFB70BF3,0x98539E6A
   6204  1.1     is ATANC4:	long		0x3FBC7187,0x962D1D7D
   6205  1.1     is ATANC3:	long		0xBFC24924,0x827107B8
   6206  1.1     is ATANC2:	long		0x3FC99999,0x9996263E
   6207  1.1     is ATANC1:	long		0xBFD55555,0x55555536
   6208  1.1     is 
   6209  1.1     is PPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
   6210  1.1     is NPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
   6211  1.1     is 
   6212  1.1     is PTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
   6213  1.1     is NTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
   6214  1.1     is 
   6215  1.1     is ATANTBL:
   6216  1.1     is 	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
   6217  1.1     is 	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
   6218  1.1     is 	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
   6219  1.1     is 	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
   6220  1.1     is 	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
   6221  1.1     is 	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
   6222  1.1     is 	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
   6223  1.1     is 	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
   6224  1.1     is 	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
   6225  1.1     is 	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
   6226  1.1     is 	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
   6227  1.1     is 	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
   6228  1.1     is 	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
   6229  1.1     is 	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
   6230  1.1     is 	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
   6231  1.1     is 	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
   6232  1.1     is 	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
   6233  1.1     is 	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
   6234  1.1     is 	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
   6235  1.1     is 	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
   6236  1.1     is 	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
   6237  1.1     is 	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
   6238  1.1     is 	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
   6239  1.1     is 	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
   6240  1.1     is 	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
   6241  1.1     is 	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
   6242  1.1     is 	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
   6243  1.1     is 	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
   6244  1.1     is 	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
   6245  1.1     is 	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
   6246  1.1     is 	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
   6247  1.1     is 	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
   6248  1.1     is 	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
   6249  1.1     is 	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
   6250  1.1     is 	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
   6251  1.1     is 	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
   6252  1.1     is 	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
   6253  1.1     is 	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
   6254  1.1     is 	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
   6255  1.1     is 	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
   6256  1.1     is 	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
   6257  1.1     is 	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
   6258  1.1     is 	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
   6259  1.1     is 	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
   6260  1.1     is 	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
   6261  1.1     is 	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
   6262  1.1     is 	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
   6263  1.1     is 	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
   6264  1.1     is 	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
   6265  1.1     is 	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
   6266  1.1     is 	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
   6267  1.1     is 	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
   6268  1.1     is 	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
   6269  1.1     is 	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
   6270  1.1     is 	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
   6271  1.1     is 	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
   6272  1.1     is 	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
   6273  1.1     is 	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
   6274  1.1     is 	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
   6275  1.1     is 	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
   6276  1.1     is 	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
   6277  1.1     is 	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
   6278  1.1     is 	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
   6279  1.1     is 	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
   6280  1.1     is 	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
   6281  1.1     is 	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
   6282  1.1     is 	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
   6283  1.1     is 	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
   6284  1.1     is 	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
   6285  1.1     is 	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
   6286  1.1     is 	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
   6287  1.1     is 	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
   6288  1.1     is 	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
   6289  1.1     is 	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
   6290  1.1     is 	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
   6291  1.1     is 	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
   6292  1.1     is 	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
   6293  1.1     is 	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
   6294  1.1     is 	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
   6295  1.1     is 	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
   6296  1.1     is 	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
   6297  1.1     is 	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
   6298  1.1     is 	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
   6299  1.1     is 	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
   6300  1.1     is 	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
   6301  1.1     is 	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
   6302  1.1     is 	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
   6303  1.1     is 	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
   6304  1.1     is 	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
   6305  1.1     is 	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
   6306  1.1     is 	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
   6307  1.1     is 	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
   6308  1.1     is 	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
   6309  1.1     is 	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
   6310  1.1     is 	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
   6311  1.1     is 	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
   6312  1.1     is 	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
   6313  1.1     is 	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
   6314  1.1     is 	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
   6315  1.1     is 	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
   6316  1.1     is 	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
   6317  1.1     is 	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
   6318  1.1     is 	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
   6319  1.1     is 	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
   6320  1.1     is 	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
   6321  1.1     is 	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
   6322  1.1     is 	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
   6323  1.1     is 	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
   6324  1.1     is 	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
   6325  1.1     is 	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
   6326  1.1     is 	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
   6327  1.1     is 	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
   6328  1.1     is 	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
   6329  1.1     is 	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
   6330  1.1     is 	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
   6331  1.1     is 	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
   6332  1.1     is 	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
   6333  1.1     is 	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
   6334  1.1     is 	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
   6335  1.1     is 	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
   6336  1.1     is 	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
   6337  1.1     is 	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
   6338  1.1     is 	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
   6339  1.1     is 	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
   6340  1.1     is 	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
   6341  1.1     is 	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
   6342  1.1     is 	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
   6343  1.1     is 	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
   6344  1.1     is 
   6345  1.1     is 	set		X,FP_SCR0
   6346  1.1     is 	set		XDCARE,X+2
   6347  1.1     is 	set		XFRAC,X+4
   6348  1.1     is 	set		XFRACLO,X+8
   6349  1.1     is 
   6350  1.1     is 	set		ATANF,FP_SCR1
   6351  1.1     is 	set		ATANFHI,ATANF+4
   6352  1.1     is 	set		ATANFLO,ATANF+8
   6353  1.1     is 
   6354  1.1     is 	global		satan
   6355  1.1     is #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   6356  1.1     is satan:
   6357  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6358  1.1     is 
   6359  1.1     is 	mov.l		(%a0),%d1
   6360  1.1     is 	mov.w		4(%a0),%d1
   6361  1.1     is 	fmov.x		%fp0,X(%a6)
   6362  1.1     is 	and.l		&0x7FFFFFFF,%d1
   6363  1.1     is 
   6364  1.1     is 	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
   6365  1.1     is 	bge.b		ATANOK1
   6366  1.1     is 	bra.w		ATANSM
   6367  1.1     is 
   6368  1.1     is ATANOK1:
   6369  1.1     is 	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
   6370  1.1     is 	ble.b		ATANMAIN
   6371  1.1     is 	bra.w		ATANBIG
   6372  1.1     is 
   6373  1.1     is #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
   6374  1.1     is #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
   6375  1.1     is #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
   6376  1.1     is #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
   6377  1.1     is #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
   6378  1.1     is #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
   6379  1.1     is #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
   6380  1.1     is #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
   6381  1.1     is #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
   6382  1.1     is #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
   6383  1.1     is #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
   6384  1.1     is #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
   6385  1.1     is #--WILL INVOLVE A VERY LONG POLYNOMIAL.
   6386  1.1     is 
   6387  1.1     is #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
   6388  1.1     is #--WE CHOSE F TO BE +-2^K * 1.BBBB1
   6389  1.1     is #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
   6390  1.1     is #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
   6391  1.1     is #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
   6392  1.1     is #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
   6393  1.1     is 
   6394  1.1     is ATANMAIN:
   6395  1.1     is 
   6396  1.1     is 	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
   6397  1.1     is 	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
   6398  1.1     is 	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
   6399  1.1     is 
   6400  1.1     is 	fmov.x		%fp0,%fp1		# FP1 IS X
   6401  1.1     is 	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
   6402  1.1     is 	fsub.x		X(%a6),%fp0		# FP0 IS X-F
   6403  1.1     is 	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
   6404  1.1     is 	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
   6405  1.1     is 
   6406  1.1     is #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
   6407  1.1     is #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
   6408  1.1     is #--SAVE REGISTERS FP2.
   6409  1.1     is 
   6410  1.1     is 	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
   6411  1.1     is 	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
   6412  1.1     is 	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
   6413  1.1     is 	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
   6414  1.1     is 	sub.l		&0x3FFB0000,%d2		# K+4
   6415  1.1     is 	asr.l		&1,%d2
   6416  1.1     is 	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
   6417  1.1     is 	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
   6418  1.1     is 	lea		ATANTBL(%pc),%a1
   6419  1.1     is 	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
   6420  1.1     is 	mov.l		(%a1)+,ATANF(%a6)
   6421  1.1     is 	mov.l		(%a1)+,ATANFHI(%a6)
   6422  1.1     is 	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
   6423  1.1     is 	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
   6424  1.1     is 	and.l		&0x80000000,%d1		# SIGN(F)
   6425  1.1     is 	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
   6426  1.1     is 	mov.l		(%sp)+,%d2		# RESTORE d2
   6427  1.1     is 
   6428  1.1     is #--THAT'S ALL I HAVE TO DO FOR NOW,
   6429  1.1     is #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
   6430  1.1     is 
   6431  1.1     is #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
   6432  1.1     is #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
   6433  1.1     is #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
   6434  1.1     is #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
   6435  1.1     is #--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
   6436  1.1     is #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
   6437  1.1     is #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
   6438  1.1     is 
   6439  1.1     is 	fmovm.x		&0x04,-(%sp)		# save fp2
   6440  1.1     is 
   6441  1.1     is 	fmov.x		%fp0,%fp1
   6442  1.1     is 	fmul.x		%fp1,%fp1
   6443  1.1     is 	fmov.d		ATANA3(%pc),%fp2
   6444  1.1     is 	fadd.x		%fp1,%fp2		# A3+V
   6445  1.1     is 	fmul.x		%fp1,%fp2		# V*(A3+V)
   6446  1.1     is 	fmul.x		%fp0,%fp1		# U*V
   6447  1.1     is 	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
   6448  1.1     is 	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
   6449  1.1     is 	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
   6450  1.1     is 	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
   6451  1.1     is 
   6452  1.1     is 	fmovm.x 	(%sp)+,&0x20		# restore fp2
   6453  1.1     is 
   6454  1.1     is 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6455  1.1     is 	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
   6456  1.1     is 	bra		t_inx2
   6457  1.1     is 
   6458  1.1     is ATANBORS:
   6459  1.1     is #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
   6460  1.1     is #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
   6461  1.1     is 	cmp.l		%d1,&0x3FFF8000
   6462  1.1     is 	bgt.w		ATANBIG			# I.E. |X| >= 16
   6463  1.1     is 
   6464  1.1     is ATANSM:
   6465  1.1     is #--|X| <= 1/16
   6466  1.1     is #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
   6467  1.1     is #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
   6468  1.1     is #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
   6469  1.1     is #--WHERE Y = X*X, AND Z = Y*Y.
   6470  1.1     is 
   6471  1.1     is 	cmp.l		%d1,&0x3FD78000
   6472  1.1     is 	blt.w		ATANTINY
   6473  1.1     is 
   6474  1.1     is #--COMPUTE POLYNOMIAL
   6475  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   6476  1.1     is 
   6477  1.1     is 	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
   6478  1.1     is 
   6479  1.1     is 	fmov.x		%fp0,%fp1
   6480  1.1     is 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
   6481  1.1     is 
   6482  1.1     is 	fmov.d		ATANB6(%pc),%fp2
   6483  1.1     is 	fmov.d		ATANB5(%pc),%fp3
   6484  1.1     is 
   6485  1.1     is 	fmul.x		%fp1,%fp2		# Z*B6
   6486  1.1     is 	fmul.x		%fp1,%fp3		# Z*B5
   6487  1.1     is 
   6488  1.1     is 	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
   6489  1.1     is 	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
   6490  1.1     is 
   6491  1.1     is 	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
   6492  1.1     is 	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
   6493  1.1     is 
   6494  1.1     is 	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
   6495  1.1     is 	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
   6496  1.1     is 
   6497  1.1     is 	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
   6498  1.1     is 	fmul.x		X(%a6),%fp0		# X*Y
   6499  1.1     is 
   6500  1.1     is 	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
   6501  1.1     is 
   6502  1.1     is 	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
   6503  1.1     is 
   6504  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   6505  1.1     is 
   6506  1.1     is 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6507  1.1     is 	fadd.x		X(%a6),%fp0
   6508  1.1     is 	bra		t_inx2
   6509  1.1     is 
   6510  1.1     is ATANTINY:
   6511  1.1     is #--|X| < 2^(-40), ATAN(X) = X
   6512  1.1     is 
   6513  1.1     is 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6514  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6515  1.1     is 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   6516  1.1     is 
   6517  1.1     is 	bra		t_catch
   6518  1.1     is 
   6519  1.1     is ATANBIG:
   6520  1.1     is #--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
   6521  1.1     is #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
   6522  1.1     is 	cmp.l		%d1,&0x40638000
   6523  1.1     is 	bgt.w		ATANHUGE
   6524  1.1     is 
   6525  1.1     is #--APPROXIMATE ATAN(-1/X) BY
   6526  1.1     is #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
   6527  1.1     is #--THIS CAN BE RE-WRITTEN AS
   6528  1.1     is #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
   6529  1.1     is 
   6530  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   6531  1.1     is 
   6532  1.1     is 	fmov.s		&0xBF800000,%fp1	# LOAD -1
   6533  1.1     is 	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
   6534  1.1     is 
   6535  1.1     is #--DIVIDE IS STILL CRANKING
   6536  1.1     is 
   6537  1.1     is 	fmov.x		%fp1,%fp0		# FP0 IS X'
   6538  1.1     is 	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
   6539  1.1     is 	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
   6540  1.1     is 
   6541  1.1     is 	fmov.x		%fp0,%fp1
   6542  1.1     is 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
   6543  1.1     is 
   6544  1.1     is 	fmov.d		ATANC5(%pc),%fp3
   6545  1.1     is 	fmov.d		ATANC4(%pc),%fp2
   6546  1.1     is 
   6547  1.1     is 	fmul.x		%fp1,%fp3		# Z*C5
   6548  1.1     is 	fmul.x		%fp1,%fp2		# Z*B4
   6549  1.1     is 
   6550  1.1     is 	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
   6551  1.1     is 	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
   6552  1.1     is 
   6553  1.1     is 	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
   6554  1.1     is 	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
   6555  1.1     is 
   6556  1.1     is 	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
   6557  1.1     is 	fmul.x		X(%a6),%fp0		# X'*Y
   6558  1.1     is 
   6559  1.1     is 	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
   6560  1.1     is 
   6561  1.1     is 	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
   6562  1.1     is #					...	+[Y*(B2+Z*(B4+Z*B6))])
   6563  1.1     is 	fadd.x		X(%a6),%fp0
   6564  1.1     is 
   6565  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   6566  1.1     is 
   6567  1.1     is 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6568  1.1     is 	tst.b		(%a0)
   6569  1.1     is 	bpl.b		pos_big
   6570  1.1     is 
   6571  1.1     is neg_big:
   6572  1.1     is 	fadd.x		NPIBY2(%pc),%fp0
   6573  1.1     is 	bra		t_minx2
   6574  1.1     is 
   6575  1.1     is pos_big:
   6576  1.1     is 	fadd.x		PPIBY2(%pc),%fp0
   6577  1.1     is 	bra		t_pinx2
   6578  1.1     is 
   6579  1.1     is ATANHUGE:
   6580  1.1     is #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
   6581  1.1     is 	tst.b		(%a0)
   6582  1.1     is 	bpl.b		pos_huge
   6583  1.1     is 
   6584  1.1     is neg_huge:
   6585  1.1     is 	fmov.x		NPIBY2(%pc),%fp0
   6586  1.1     is 	fmov.l		%d0,%fpcr
   6587  1.1     is 	fadd.x		PTINY(%pc),%fp0
   6588  1.1     is 	bra		t_minx2
   6589  1.1     is 
   6590  1.1     is pos_huge:
   6591  1.1     is 	fmov.x		PPIBY2(%pc),%fp0
   6592  1.1     is 	fmov.l		%d0,%fpcr
   6593  1.1     is 	fadd.x		NTINY(%pc),%fp0
   6594  1.1     is 	bra		t_pinx2
   6595  1.1     is 
   6596  1.1     is 	global		satand
   6597  1.1     is #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
   6598  1.1     is satand:
   6599  1.1     is 	bra		t_extdnrm
   6600  1.1     is 
   6601  1.1     is #########################################################################
   6602  1.1     is # sasin():  computes the inverse sine of a normalized input		#
   6603  1.1     is # sasind(): computes the inverse sine of a denormalized input		#
   6604  1.1     is #									#
   6605  1.1     is # INPUT ***************************************************************	#
   6606  1.1     is #	a0 = pointer to extended precision input			#
   6607  1.1     is #	d0 = round precision,mode					#
   6608  1.1     is #									#
   6609  1.1     is # OUTPUT **************************************************************	#
   6610  1.1     is #	fp0 = arcsin(X)							#
   6611  1.1     is #									#
   6612  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   6613  1.1     is #	The returned result is within 3 ulps in	64 significant bit,	#
   6614  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6615  1.1     is #	rounded to double precision. The result is provably monotonic	#
   6616  1.1     is #	in double precision.						#
   6617  1.1     is #									#
   6618  1.1     is # ALGORITHM ***********************************************************	#
   6619  1.1     is #									#
   6620  1.1     is #	ASIN								#
   6621  1.1     is #	1. If |X| >= 1, go to 3.					#
   6622  1.1     is #									#
   6623  1.1     is #	2. (|X| < 1) Calculate asin(X) by				#
   6624  1.1     is #		z := sqrt( [1-X][1+X] )					#
   6625  1.1     is #		asin(X) = atan( x / z ).				#
   6626  1.1     is #		Exit.							#
   6627  1.1     is #									#
   6628  1.1     is #	3. If |X| > 1, go to 5.						#
   6629  1.1     is #									#
   6630  1.1     is #	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
   6631  1.1     is #									#
   6632  1.1     is #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   6633  1.1     is #		Exit.							#
   6634  1.1     is #									#
   6635  1.1     is #########################################################################
   6636  1.1     is 
   6637  1.1     is 	global		sasin
   6638  1.1     is sasin:
   6639  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6640  1.1     is 
   6641  1.1     is 	mov.l		(%a0),%d1
   6642  1.1     is 	mov.w		4(%a0),%d1
   6643  1.1     is 	and.l		&0x7FFFFFFF,%d1
   6644  1.1     is 	cmp.l		%d1,&0x3FFF8000
   6645  1.1     is 	bge.b		ASINBIG
   6646  1.1     is 
   6647  1.1     is # This catch is added here for the '060 QSP. Originally, the call to
   6648  1.1     is # satan() would handle this case by causing the exception which would
   6649  1.1     is # not be caught until gen_except(). Now, with the exceptions being
   6650  1.1     is # detected inside of satan(), the exception would have been handled there
   6651  1.1     is # instead of inside sasin() as expected.
   6652  1.1     is 	cmp.l		%d1,&0x3FD78000
   6653  1.1     is 	blt.w		ASINTINY
   6654  1.1     is 
   6655  1.1     is #--THIS IS THE USUAL CASE, |X| < 1
   6656  1.1     is #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
   6657  1.1     is 
   6658  1.1     is ASINMAIN:
   6659  1.1     is 	fmov.s		&0x3F800000,%fp1
   6660  1.1     is 	fsub.x		%fp0,%fp1		# 1-X
   6661  1.1     is 	fmovm.x		&0x4,-(%sp)		#  {fp2}
   6662  1.1     is 	fmov.s		&0x3F800000,%fp2
   6663  1.1     is 	fadd.x		%fp0,%fp2		# 1+X
   6664  1.1     is 	fmul.x		%fp2,%fp1		# (1+X)(1-X)
   6665  1.1     is 	fmovm.x		(%sp)+,&0x20		#  {fp2}
   6666  1.1     is 	fsqrt.x		%fp1			# SQRT([1-X][1+X])
   6667  1.1     is 	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
   6668  1.1     is 	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
   6669  1.1     is 	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
   6670  1.1     is 	bsr		satan
   6671  1.1     is 	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
   6672  1.1     is 	bra		t_inx2
   6673  1.1     is 
   6674  1.1     is ASINBIG:
   6675  1.1     is 	fabs.x		%fp0			# |X|
   6676  1.1     is 	fcmp.s		%fp0,&0x3F800000
   6677  1.1     is 	fbgt		t_operr			# cause an operr exception
   6678  1.1     is 
   6679  1.1     is #--|X| = 1, ASIN(X) = +- PI/2.
   6680  1.1     is ASINONE:
   6681  1.1     is 	fmov.x		PIBY2(%pc),%fp0
   6682  1.1     is 	mov.l		(%a0),%d1
   6683  1.1     is 	and.l		&0x80000000,%d1		# SIGN BIT OF X
   6684  1.1     is 	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
   6685  1.1     is 	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
   6686  1.1     is 	fmov.l		%d0,%fpcr
   6687  1.1     is 	fmul.s		(%sp)+,%fp0
   6688  1.1     is 	bra		t_inx2
   6689  1.1     is 
   6690  1.1     is #--|X| < 2^(-40), ATAN(X) = X
   6691  1.1     is ASINTINY:
   6692  1.1     is 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6693  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6694  1.1     is 	fmov.x		(%a0),%fp0		# last inst - possible exception
   6695  1.1     is 	bra		t_catch
   6696  1.1     is 
   6697  1.1     is 	global		sasind
   6698  1.1     is #--ASIN(X) = X FOR DENORMALIZED X
   6699  1.1     is sasind:
   6700  1.1     is 	bra		t_extdnrm
   6701  1.1     is 
   6702  1.1     is #########################################################################
   6703  1.1     is # sacos():  computes the inverse cosine of a normalized input		#
   6704  1.1     is # sacosd(): computes the inverse cosine of a denormalized input		#
   6705  1.1     is #									#
   6706  1.1     is # INPUT ***************************************************************	#
   6707  1.1     is #	a0 = pointer to extended precision input			#
   6708  1.1     is #	d0 = round precision,mode					#
   6709  1.1     is #									#
   6710  1.1     is # OUTPUT ************************************************************** #
   6711  1.1     is #	fp0 = arccos(X)							#
   6712  1.1     is #									#
   6713  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   6714  1.1     is #	The returned result is within 3 ulps in	64 significant bit,	#
   6715  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6716  1.1     is #	rounded to double precision. The result is provably monotonic	#
   6717  1.1     is #	in double precision.						#
   6718  1.1     is #									#
   6719  1.1     is # ALGORITHM *********************************************************** #
   6720  1.1     is #									#
   6721  1.1     is #	ACOS								#
   6722  1.1     is #	1. If |X| >= 1, go to 3.					#
   6723  1.1     is #									#
   6724  1.1     is #	2. (|X| < 1) Calculate acos(X) by				#
   6725  1.1     is #		z := (1-X) / (1+X)					#
   6726  1.1     is #		acos(X) = 2 * atan( sqrt(z) ).				#
   6727  1.1     is #		Exit.							#
   6728  1.1     is #									#
   6729  1.1     is #	3. If |X| > 1, go to 5.						#
   6730  1.1     is #									#
   6731  1.1     is #	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
   6732  1.1     is #									#
   6733  1.1     is #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   6734  1.1     is #		Exit.							#
   6735  1.1     is #									#
   6736  1.1     is #########################################################################
   6737  1.1     is 
   6738  1.1     is 	global		sacos
   6739  1.1     is sacos:
   6740  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6741  1.1     is 
   6742  1.1     is 	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
   6743  1.1     is 	mov.w		4(%a0),%d1
   6744  1.1     is 	and.l		&0x7FFFFFFF,%d1
   6745  1.1     is 	cmp.l		%d1,&0x3FFF8000
   6746  1.1     is 	bge.b		ACOSBIG
   6747  1.1     is 
   6748  1.1     is #--THIS IS THE USUAL CASE, |X| < 1
   6749  1.1     is #--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
   6750  1.1     is 
   6751  1.1     is ACOSMAIN:
   6752  1.1     is 	fmov.s		&0x3F800000,%fp1
   6753  1.1     is 	fadd.x		%fp0,%fp1		# 1+X
   6754  1.1     is 	fneg.x		%fp0			# -X
   6755  1.1     is 	fadd.s		&0x3F800000,%fp0	# 1-X
   6756  1.1     is 	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
   6757  1.1     is 	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
   6758  1.1     is 	mov.l		%d0,-(%sp)		# save original users fpcr
   6759  1.1     is 	clr.l		%d0
   6760  1.1     is 	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
   6761  1.1     is 	lea		(%sp),%a0		# pass ptr to sqrt
   6762  1.1     is 	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
   6763  1.1     is 	add.l		&0xc,%sp		# clear SQRT(...) from stack
   6764  1.1     is 
   6765  1.1     is 	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
   6766  1.1     is 	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
   6767  1.1     is 	bra		t_pinx2
   6768  1.1     is 
   6769  1.1     is ACOSBIG:
   6770  1.1     is 	fabs.x		%fp0
   6771  1.1     is 	fcmp.s		%fp0,&0x3F800000
   6772  1.1     is 	fbgt		t_operr			# cause an operr exception
   6773  1.1     is 
   6774  1.1     is #--|X| = 1, ACOS(X) = 0 OR PI
   6775  1.1     is 	tst.b		(%a0)			# is X positive or negative?
   6776  1.1     is 	bpl.b		ACOSP1
   6777  1.1     is 
   6778  1.1     is #--X = -1
   6779  1.1     is #Returns PI and inexact exception
   6780  1.1     is ACOSM1:
   6781  1.1     is 	fmov.x		PI(%pc),%fp0		# load PI
   6782  1.1     is 	fmov.l		%d0,%fpcr		# load round mode,prec
   6783  1.1     is 	fadd.s		&0x00800000,%fp0	# add a small value
   6784  1.1     is 	bra		t_pinx2
   6785  1.1     is 
   6786  1.1     is ACOSP1:
   6787  1.1     is 	bra		ld_pzero		# answer is positive zero
   6788  1.1     is 
   6789  1.1     is 	global		sacosd
   6790  1.1     is #--ACOS(X) = PI/2 FOR DENORMALIZED X
   6791  1.1     is sacosd:
   6792  1.1     is 	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
   6793  1.1     is 	fmov.x		PIBY2(%pc),%fp0
   6794  1.1     is 	bra		t_pinx2
   6795  1.1     is 
   6796  1.1     is #########################################################################
   6797  1.1     is # setox():    computes the exponential for a normalized input		#
   6798  1.1     is # setoxd():   computes the exponential for a denormalized input		#
   6799  1.1     is # setoxm1():  computes the exponential minus 1 for a normalized input	#
   6800  1.1     is # setoxm1d(): computes the exponential minus 1 for a denormalized input	#
   6801  1.1     is #									#
   6802  1.1     is # INPUT	*************************************************************** #
   6803  1.1     is #	a0 = pointer to extended precision input			#
   6804  1.1     is #	d0 = round precision,mode					#
   6805  1.1     is #									#
   6806  1.1     is # OUTPUT ************************************************************** #
   6807  1.1     is #	fp0 = exp(X) or exp(X)-1					#
   6808  1.1     is #									#
   6809  1.1     is # ACCURACY and MONOTONICITY ******************************************* #
   6810  1.1     is #	The returned result is within 0.85 ulps in 64 significant bit, 	#
   6811  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   6812  1.1     is #	rounded to double precision. The result is provably monotonic 	#
   6813  1.1     is #	in double precision.						#
   6814  1.1     is #									#
   6815  1.1     is # ALGORITHM and IMPLEMENTATION **************************************** #
   6816  1.1     is #									#
   6817  1.1     is #	setoxd								#
   6818  1.1     is #	------								#
   6819  1.1     is #	Step 1.	Set ans := 1.0						#
   6820  1.1     is #									#
   6821  1.1     is #	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
   6822  1.1     is #	Notes:	This will always generate one exception -- inexact.	#
   6823  1.1     is #									#
   6824  1.1     is #									#
   6825  1.1     is #	setox								#
   6826  1.1     is #	-----								#
   6827  1.1     is #									#
   6828  1.1     is #	Step 1.	Filter out extreme cases of input argument.		#
   6829  1.1     is #		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
   6830  1.1     is #		1.2	Go to Step 7.					#
   6831  1.1     is #		1.3	If |X| < 16380 log(2), go to Step 2.		#
   6832  1.1     is #		1.4	Go to Step 8.					#
   6833  1.1     is #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
   6834  1.1     is #		To avoid the use of floating-point comparisons, a	#
   6835  1.1     is #		compact representation of |X| is used. This format is a	#
   6836  1.1     is #		32-bit integer, the upper (more significant) 16 bits 	#
   6837  1.1     is #		are the sign and biased exponent field of |X|; the 	#
   6838  1.1     is #		lower 16 bits are the 16 most significant fraction	#
   6839  1.1     is #		(including the explicit bit) bits of |X|. Consequently,	#
   6840  1.1     is #		the comparisons in Steps 1.1 and 1.3 can be performed	#
   6841  1.1     is #		by integer comparison. Note also that the constant	#
   6842  1.1     is #		16380 log(2) used in Step 1.3 is also in the compact	#
   6843  1.1     is #		form. Thus taking the branch to Step 2 guarantees 	#
   6844  1.1     is #		|X| < 16380 log(2). There is no harm to have a small	#
   6845  1.1     is #		number of cases where |X| is less than,	but close to,	#
   6846  1.1     is #		16380 log(2) and the branch to Step 9 is taken.		#
   6847  1.1     is #									#
   6848  1.1     is #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
   6849  1.1     is #		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
   6850  1.1     is #			was taken)					#
   6851  1.1     is #		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
   6852  1.1     is #		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
   6853  1.1     is #			or 63.						#
   6854  1.1     is #		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
   6855  1.1     is #		2.5	Calculate the address of the stored value of 	#
   6856  1.1     is #			2^(J/64).					#
   6857  1.1     is #		2.6	Create the value Scale = 2^M.			#
   6858  1.1     is #	Notes:	The calculation in 2.2 is really performed by		#
   6859  1.1     is #			Z := X * constant				#
   6860  1.1     is #			N := round-to-nearest-integer(Z)		#
   6861  1.1     is #		where							#
   6862  1.1     is #			constant := single-precision( 64/log 2 ).	#
   6863  1.1     is #									#
   6864  1.1     is #		Using a single-precision constant avoids memory 	#
   6865  1.1     is #		access. Another effect of using a single-precision	#
   6866  1.1     is #		"constant" is that the calculated value Z is 		#
   6867  1.1     is #									#
   6868  1.1     is #			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
   6869  1.1     is #									#
   6870  1.1     is #		This error has to be considered later in Steps 3 and 4.	#
   6871  1.1     is #									#
   6872  1.1     is #	Step 3.	Calculate X - N*log2/64.				#
   6873  1.1     is #		3.1	R := X + N*L1, 					#
   6874  1.1     is #				where L1 := single-precision(-log2/64).	#
   6875  1.1     is #		3.2	R := R + N*L2, 					#
   6876  1.1     is #				L2 := extended-precision(-log2/64 - L1).#
   6877  1.1     is #	Notes:	a) The way L1 and L2 are chosen ensures L1+L2 		#
   6878  1.1     is #		approximate the value -log2/64 to 88 bits of accuracy.	#
   6879  1.1     is #		b) N*L1 is exact because N is no longer than 22 bits	#
   6880  1.1     is #		and L1 is no longer than 24 bits.			#
   6881  1.1     is #		c) The calculation X+N*L1 is also exact due to 		#
   6882  1.1     is #		cancellation. Thus, R is practically X+N(L1+L2) to full	#
   6883  1.1     is #		64 bits. 						#
   6884  1.1     is #		d) It is important to estimate how large can |R| be	#
   6885  1.1     is #		after Step 3.2.						#
   6886  1.1     is #									#
   6887  1.1     is #		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
   6888  1.1     is #		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
   6889  1.1     is #		X*64/log2 - N	=	f - eps*X 64/log2		#
   6890  1.1     is #		X - N*log2/64	=	f*log2/64 - eps*X		#
   6891  1.1     is #									#
   6892  1.1     is #									#
   6893  1.1     is #		Now |X| <= 16446 log2, thus				#
   6894  1.1     is #									#
   6895  1.1     is #			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
   6896  1.1     is #					<= 0.57 log2/64.		#
   6897  1.1     is #		 This bound will be used in Step 4.			#
   6898  1.1     is #									#
   6899  1.1     is #	Step 4.	Approximate exp(R)-1 by a polynomial			#
   6900  1.1     is #		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
   6901  1.1     is #	Notes:	a) In order to reduce memory access, the coefficients 	#
   6902  1.1     is #		are made as "short" as possible: A1 (which is 1/2), A4	#
   6903  1.1     is #		and A5 are single precision; A2 and A3 are double	#
   6904  1.1     is #		precision. 						#
   6905  1.1     is #		b) Even with the restrictions above, 			#
   6906  1.1     is #		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
   6907  1.1     is #		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
   6908  1.3  perry #		c) To fully use the pipeline, p is separated into	#
   6909  1.1     is #		two independent pieces of roughly equal complexities	#
   6910  1.1     is #			p = [ R + R*S*(A2 + S*A4) ]	+		#
   6911  1.1     is #				[ S*(A1 + S*(A3 + S*A5)) ]		#
   6912  1.1     is #		where S = R*R.						#
   6913  1.1     is #									#
   6914  1.1     is #	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
   6915  1.1     is #				ans := T + ( T*p + t)			#
   6916  1.1     is #		where T and t are the stored values for 2^(J/64).	#
   6917  1.1     is #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
   6918  1.1     is #		2^(J/64) to roughly 85 bits; T is in extended precision	#
   6919  1.1     is #		and t is in single precision. Note also that T is 	#
   6920  1.1     is #		rounded to 62 bits so that the last two bits of T are 	#
   6921  1.1     is #		zero. The reason for such a special form is that T-1, 	#
   6922  1.1     is #		T-2, and T-8 will all be exact --- a property that will	#
   6923  1.1     is #		give much more accurate computation of the function 	#
   6924  1.1     is #		EXPM1.							#
   6925  1.1     is #									#
   6926  1.1     is #	Step 6.	Reconstruction of exp(X)				#
   6927  1.1     is #			exp(X) = 2^M * 2^(J/64) * exp(R).		#
   6928  1.1     is #		6.1	If AdjFlag = 0, go to 6.3			#
   6929  1.1     is #		6.2	ans := ans * AdjScale				#
   6930  1.1     is #		6.3	Restore the user FPCR				#
   6931  1.1     is #		6.4	Return ans := ans * Scale. Exit.		#
   6932  1.1     is #	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
   6933  1.1     is #		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
   6934  1.1     is #		neither overflow nor underflow. If AdjFlag = 1, that	#
   6935  1.1     is #		means that						#
   6936  1.1     is #			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
   6937  1.1     is #		Hence, exp(X) may overflow or underflow or neither.	#
   6938  1.1     is #		When that is the case, AdjScale = 2^(M1) where M1 is	#
   6939  1.1     is #		approximately M. Thus 6.2 will never cause 		#
   6940  1.1     is #		over/underflow. Possible exception in 6.4 is overflow	#
   6941  1.1     is #		or underflow. The inexact exception is not generated in	#
   6942  1.1     is #		6.4. Although one can argue that the inexact flag	#
   6943  1.1     is #		should always be raised, to simulate that exception 	#
   6944  1.1     is #		cost to much than the flag is worth in practical uses.	#
   6945  1.1     is #									#
   6946  1.1     is #	Step 7.	Return 1 + X.						#
   6947  1.1     is #		7.1	ans := X					#
   6948  1.1     is #		7.2	Restore user FPCR.				#
   6949  1.1     is #		7.3	Return ans := 1 + ans. Exit			#
   6950  1.1     is #	Notes:	For non-zero X, the inexact exception will always be	#
   6951  1.1     is #		raised by 7.3. That is the only exception raised by 7.3.#
   6952  1.1     is #		Note also that we use the FMOVEM instruction to move X	#
   6953  1.1     is #		in Step 7.1 to avoid unnecessary trapping. (Although	#
   6954  1.1     is #		the FMOVEM may not seem relevant since X is normalized,	#
   6955  1.1     is #		the precaution will be useful in the library version of	#
   6956  1.1     is #		this code where the separate entry for denormalized 	#
   6957  1.1     is #		inputs will be done away with.)				#
   6958  1.1     is #									#
   6959  1.1     is #	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
   6960  1.1     is #		8.1	If |X| > 16480 log2, go to Step 9.		#
   6961  1.1     is #		(mimic 2.2 - 2.6)					#
   6962  1.1     is #		8.2	N := round-to-integer( X * 64/log2 )		#
   6963  1.1     is #		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
   6964  1.1     is #		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1, 	#
   6965  1.1     is #			AdjFlag := 1.					#
   6966  1.1     is #		8.5	Calculate the address of the stored value 	#
   6967  1.1     is #			2^(J/64).					#
   6968  1.1     is #		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
   6969  1.1     is #		8.7	Go to Step 3.					#
   6970  1.1     is #	Notes:	Refer to notes for 2.2 - 2.6.				#
   6971  1.1     is #									#
   6972  1.1     is #	Step 9.	Handle exp(X), |X| > 16480 log2.			#
   6973  1.1     is #		9.1	If X < 0, go to 9.3				#
   6974  1.1     is #		9.2	ans := Huge, go to 9.4				#
   6975  1.1     is #		9.3	ans := Tiny.					#
   6976  1.1     is #		9.4	Restore user FPCR.				#
   6977  1.1     is #		9.5	Return ans := ans * ans. Exit.			#
   6978  1.1     is #	Notes:	Exp(X) will surely overflow or underflow, depending on	#
   6979  1.1     is #		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
   6980  1.1     is #		extended-precision numbers whose square over/underflow	#
   6981  1.1     is #		with an inexact result. Thus, 9.5 always raises the	#
   6982  1.1     is #		inexact together with either overflow or underflow.	#
   6983  1.1     is #									#
   6984  1.1     is #	setoxm1d							#
   6985  1.1     is #	--------							#
   6986  1.1     is #									#
   6987  1.1     is #	Step 1.	Set ans := 0						#
   6988  1.1     is #									#
   6989  1.1     is #	Step 2.	Return	ans := X + ans. Exit.				#
   6990  1.1     is #	Notes:	This will return X with the appropriate rounding	#
   6991  1.1     is #		 precision prescribed by the user FPCR.			#
   6992  1.1     is #									#
   6993  1.1     is #	setoxm1								#
   6994  1.1     is #	-------								#
   6995  1.1     is #									#
   6996  1.1     is #	Step 1.	Check |X|						#
   6997  1.1     is #		1.1	If |X| >= 1/4, go to Step 1.3.			#
   6998  1.1     is #		1.2	Go to Step 7.					#
   6999  1.1     is #		1.3	If |X| < 70 log(2), go to Step 2.		#
   7000  1.1     is #		1.4	Go to Step 10.					#
   7001  1.1     is #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
   7002  1.1     is #		However, it is conceivable |X| can be small very often	#
   7003  1.1     is #		because EXPM1 is intended to evaluate exp(X)-1 		#
   7004  1.1     is #		accurately when |X| is small. For further details on 	#
   7005  1.1     is #		the comparisons, see the notes on Step 1 of setox.	#
   7006  1.1     is #									#
   7007  1.1     is #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
   7008  1.1     is #		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
   7009  1.1     is #		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
   7010  1.1     is #			or 63.						#
   7011  1.1     is #		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
   7012  1.1     is #		2.4	Calculate the address of the stored value of 	#
   7013  1.1     is #			2^(J/64).					#
   7014  1.1     is #		2.5	Create the values Sc = 2^M and 			#
   7015  1.1     is #			OnebySc := -2^(-M).				#
   7016  1.1     is #	Notes:	See the notes on Step 2 of setox.			#
   7017  1.1     is #									#
   7018  1.1     is #	Step 3.	Calculate X - N*log2/64.				#
   7019  1.1     is #		3.1	R := X + N*L1, 					#
   7020  1.1     is #				where L1 := single-precision(-log2/64).	#
   7021  1.1     is #		3.2	R := R + N*L2, 					#
   7022  1.1     is #				L2 := extended-precision(-log2/64 - L1).#
   7023  1.1     is #	Notes:	Applying the analysis of Step 3 of setox in this case	#
   7024  1.1     is #		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
   7025  1.1     is #		this case).						#
   7026  1.1     is #									#
   7027  1.1     is #	Step 4.	Approximate exp(R)-1 by a polynomial			#
   7028  1.1     is #			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
   7029  1.1     is #	Notes:	a) In order to reduce memory access, the coefficients 	#
   7030  1.1     is #		are made as "short" as possible: A1 (which is 1/2), A5 	#
   7031  1.1     is #		and A6 are single precision; A2, A3 and A4 are double 	#
   7032  1.1     is #		precision. 						#
   7033  1.1     is #		b) Even with the restriction above,			#
   7034  1.1     is #			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
   7035  1.1     is #		for all |R| <= 0.0055.					#
   7036  1.3  perry #		c) To fully use the pipeline, p is separated into	#
   7037  1.1     is #		two independent pieces of roughly equal complexity	#
   7038  1.1     is #			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
   7039  1.1     is #				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
   7040  1.1     is #		where S = R*R.						#
   7041  1.1     is #									#
   7042  1.1     is #	Step 5.	Compute 2^(J/64)*p by					#
   7043  1.1     is #				p := T*p				#
   7044  1.1     is #		where T and t are the stored values for 2^(J/64).	#
   7045  1.1     is #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
   7046  1.1     is #		2^(J/64) to roughly 85 bits; T is in extended precision	#
   7047  1.1     is #		and t is in single precision. Note also that T is 	#
   7048  1.1     is #		rounded to 62 bits so that the last two bits of T are 	#
   7049  1.1     is #		zero. The reason for such a special form is that T-1, 	#
   7050  1.1     is #		T-2, and T-8 will all be exact --- a property that will	#
   7051  1.1     is #		be exploited in Step 6 below. The total relative error	#
   7052  1.1     is #		in p is no bigger than 2^(-67.7) compared to the final	#
   7053  1.1     is #		result.							#
   7054  1.1     is #									#
   7055  1.1     is #	Step 6.	Reconstruction of exp(X)-1				#
   7056  1.1     is #			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
   7057  1.1     is #		6.1	If M <= 63, go to Step 6.3.			#
   7058  1.1     is #		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
   7059  1.1     is #		6.3	If M >= -3, go to 6.5.				#
   7060  1.1     is #		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
   7061  1.1     is #		6.5	ans := (T + OnebySc) + (p + t).			#
   7062  1.1     is #		6.6	Restore user FPCR.				#
   7063  1.1     is #		6.7	Return ans := Sc * ans. Exit.			#
   7064  1.1     is #	Notes:	The various arrangements of the expressions give 	#
   7065  1.1     is #		accurate evaluations.					#
   7066  1.1     is #									#
   7067  1.1     is #	Step 7.	exp(X)-1 for |X| < 1/4.					#
   7068  1.1     is #		7.1	If |X| >= 2^(-65), go to Step 9.		#
   7069  1.1     is #		7.2	Go to Step 8.					#
   7070  1.1     is #									#
   7071  1.1     is #	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
   7072  1.1     is #		8.1	If |X| < 2^(-16312), goto 8.3			#
   7073  1.1     is #		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
   7074  1.1     is #			Exit.						#
   7075  1.1     is #		8.3	X := X * 2^(140).				#
   7076  1.1     is #		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
   7077  1.1     is #		 Return ans := ans*2^(140). Exit			#
   7078  1.1     is #	Notes:	The idea is to return "X - tiny" under the user		#
   7079  1.1     is #		precision and rounding modes. To avoid unnecessary	#
   7080  1.1     is #		inefficiency, we stay away from denormalized numbers 	#
   7081  1.1     is #		the best we can. For |X| >= 2^(-16312), the 		#
   7082  1.1     is #		straightforward 8.2 generates the inexact exception as	#
   7083  1.1     is #		the case warrants.					#
   7084  1.1     is #									#
   7085  1.1     is #	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
   7086  1.1     is #			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
   7087  1.1     is #	Notes:	a) In order to reduce memory access, the coefficients	#
   7088  1.1     is #		are made as "short" as possible: B1 (which is 1/2), B9	#
   7089  1.1     is #		to B12 are single precision; B3 to B8 are double 	#
   7090  1.1     is #		precision; and B2 is double extended.			#
   7091  1.1     is #		b) Even with the restriction above,			#
   7092  1.1     is #			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
   7093  1.1     is #		for all |X| <= 0.251.					#
   7094  1.1     is #		Note that 0.251 is slightly bigger than 1/4.		#
   7095  1.1     is #		c) To fully preserve accuracy, the polynomial is 	#
   7096  1.1     is #		computed as						#
   7097  1.1     is #			X + ( S*B1 +	Q ) where S = X*X and		#
   7098  1.1     is #			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
   7099  1.3  perry #		d) To fully use the pipeline, Q is separated into	#
   7100  1.1     is #		two independent pieces of roughly equal complexity	#
   7101  1.1     is #			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
   7102  1.1     is #				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
   7103  1.1     is #									#
   7104  1.1     is #	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
   7105  1.1     is #		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all 	#
   7106  1.1     is #		practical purposes. Therefore, go to Step 1 of setox.	#
   7107  1.1     is #		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
   7108  1.1     is #		purposes. 						#
   7109  1.1     is #		ans := -1 						#
   7110  1.1     is #		Restore user FPCR					#
   7111  1.1     is #		Return ans := ans + 2^(-126). Exit.			#
   7112  1.1     is #	Notes:	10.2 will always create an inexact and return -1 + tiny	#
   7113  1.1     is #		in the user rounding precision and mode.		#
   7114  1.1     is #									#
   7115  1.1     is #########################################################################
   7116  1.1     is 
   7117  1.1     is L2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
   7118  1.1     is 
   7119  1.1     is EEXPA3:	long		0x3FA55555,0x55554CC1
   7120  1.1     is EEXPA2:	long		0x3FC55555,0x55554A54
   7121  1.1     is 
   7122  1.1     is EM1A4:	long		0x3F811111,0x11174385
   7123  1.1     is EM1A3:	long		0x3FA55555,0x55554F5A
   7124  1.1     is 
   7125  1.1     is EM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
   7126  1.1     is 
   7127  1.1     is EM1B8:	long		0x3EC71DE3,0xA5774682
   7128  1.1     is EM1B7:	long		0x3EFA01A0,0x19D7CB68
   7129  1.1     is 
   7130  1.1     is EM1B6:	long		0x3F2A01A0,0x1A019DF3
   7131  1.1     is EM1B5:	long		0x3F56C16C,0x16C170E2
   7132  1.1     is 
   7133  1.1     is EM1B4:	long		0x3F811111,0x11111111
   7134  1.1     is EM1B3:	long		0x3FA55555,0x55555555
   7135  1.1     is 
   7136  1.1     is EM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
   7137  1.1     is 	long		0x00000000
   7138  1.1     is 
   7139  1.1     is TWO140:	long		0x48B00000,0x00000000
   7140  1.1     is TWON140:
   7141  1.1     is 	long		0x37300000,0x00000000
   7142  1.1     is 
   7143  1.1     is EEXPTBL:
   7144  1.1     is 	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
   7145  1.1     is 	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
   7146  1.1     is 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
   7147  1.1     is 	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
   7148  1.1     is 	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
   7149  1.1     is 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
   7150  1.1     is 	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
   7151  1.1     is 	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
   7152  1.1     is 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
   7153  1.1     is 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
   7154  1.1     is 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
   7155  1.1     is 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
   7156  1.1     is 	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
   7157  1.1     is 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
   7158  1.1     is 	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
   7159  1.1     is 	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
   7160  1.1     is 	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
   7161  1.1     is 	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
   7162  1.1     is 	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
   7163  1.1     is 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
   7164  1.1     is 	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
   7165  1.1     is 	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
   7166  1.1     is 	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
   7167  1.1     is 	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
   7168  1.1     is 	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
   7169  1.1     is 	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
   7170  1.1     is 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
   7171  1.1     is 	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
   7172  1.1     is 	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
   7173  1.1     is 	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
   7174  1.1     is 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
   7175  1.1     is 	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
   7176  1.1     is 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
   7177  1.1     is 	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
   7178  1.1     is 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
   7179  1.1     is 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
   7180  1.1     is 	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
   7181  1.1     is 	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
   7182  1.1     is 	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
   7183  1.1     is 	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
   7184  1.1     is 	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
   7185  1.1     is 	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
   7186  1.1     is 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
   7187  1.1     is 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
   7188  1.1     is 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
   7189  1.1     is 	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
   7190  1.1     is 	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
   7191  1.1     is 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
   7192  1.1     is 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
   7193  1.1     is 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
   7194  1.1     is 	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
   7195  1.1     is 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
   7196  1.1     is 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
   7197  1.1     is 	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
   7198  1.1     is 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
   7199  1.1     is 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
   7200  1.1     is 	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
   7201  1.1     is 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
   7202  1.1     is 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
   7203  1.1     is 	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
   7204  1.1     is 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
   7205  1.1     is 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
   7206  1.1     is 	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
   7207  1.1     is 	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
   7208  1.1     is 
   7209  1.1     is 	set		ADJFLAG,L_SCR2
   7210  1.1     is 	set		SCALE,FP_SCR0
   7211  1.1     is 	set		ADJSCALE,FP_SCR1
   7212  1.1     is 	set		SC,FP_SCR0
   7213  1.1     is 	set		ONEBYSC,FP_SCR1
   7214  1.1     is 
   7215  1.1     is 	global		setox
   7216  1.1     is setox:
   7217  1.1     is #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
   7218  1.1     is 
   7219  1.1     is #--Step 1.
   7220  1.1     is 	mov.l		(%a0),%d1		# load part of input X
   7221  1.1     is 	and.l		&0x7FFF0000,%d1		# biased expo. of X
   7222  1.1     is 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
   7223  1.1     is 	bge.b		EXPC1			# normal case
   7224  1.1     is 	bra		EXPSM
   7225  1.1     is 
   7226  1.1     is EXPC1:
   7227  1.1     is #--The case |X| >= 2^(-65)
   7228  1.1     is 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
   7229  1.1     is 	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
   7230  1.1     is 	blt.b		EXPMAIN			# normal case
   7231  1.1     is 	bra		EEXPBIG
   7232  1.1     is 
   7233  1.1     is EXPMAIN:
   7234  1.1     is #--Step 2.
   7235  1.1     is #--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
   7236  1.1     is 	fmov.x		(%a0),%fp0		# load input from (a0)
   7237  1.1     is 
   7238  1.1     is 	fmov.x		%fp0,%fp1
   7239  1.1     is 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7240  1.1     is 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7241  1.1     is 	mov.l		&0,ADJFLAG(%a6)
   7242  1.1     is 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7243  1.1     is 	lea		EEXPTBL(%pc),%a1
   7244  1.1     is 	fmov.l		%d1,%fp0		# convert to floating-format
   7245  1.1     is 
   7246  1.1     is 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7247  1.1     is 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7248  1.1     is 	lsl.l		&4,%d1
   7249  1.1     is 	add.l		%d1,%a1			# address of 2^(J/64)
   7250  1.1     is 	mov.l		L_SCR1(%a6),%d1
   7251  1.1     is 	asr.l		&6,%d1			# D0 is M
   7252  1.1     is 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
   7253  1.1     is 	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
   7254  1.1     is 
   7255  1.1     is EXPCONT1:
   7256  1.1     is #--Step 3.
   7257  1.1     is #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
   7258  1.1     is #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
   7259  1.1     is 	fmov.x		%fp0,%fp2
   7260  1.1     is 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
   7261  1.1     is 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
   7262  1.1     is 	fadd.x		%fp1,%fp0		# X + N*L1
   7263  1.1     is 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
   7264  1.1     is 
   7265  1.1     is #--Step 4.
   7266  1.1     is #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
   7267  1.1     is #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
   7268  1.3  perry #--TO FULLY USE THE PIPELINE, WE COMPUTE S = R*R
   7269  1.1     is #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
   7270  1.1     is 
   7271  1.1     is 	fmov.x		%fp0,%fp1
   7272  1.1     is 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
   7273  1.1     is 
   7274  1.1     is 	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
   7275  1.1     is 
   7276  1.1     is 	fmul.x		%fp1,%fp2		# fp2 IS S*A5
   7277  1.1     is 	fmov.x		%fp1,%fp3
   7278  1.1     is 	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
   7279  1.1     is 
   7280  1.1     is 	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
   7281  1.1     is 	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
   7282  1.1     is 
   7283  1.1     is 	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
   7284  1.1     is 	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
   7285  1.1     is 	mov.l		&0x80000000,SCALE+4(%a6)
   7286  1.1     is 	clr.l		SCALE+8(%a6)
   7287  1.1     is 
   7288  1.1     is 	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
   7289  1.1     is 
   7290  1.1     is 	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
   7291  1.1     is 	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
   7292  1.1     is 
   7293  1.1     is 	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
   7294  1.1     is 	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
   7295  1.1     is 
   7296  1.1     is 	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
   7297  1.1     is 	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
   7298  1.1     is 
   7299  1.1     is #--Step 5
   7300  1.1     is #--final reconstruction process
   7301  1.1     is #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
   7302  1.1     is 
   7303  1.1     is 	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
   7304  1.1     is 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7305  1.1     is 	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
   7306  1.1     is 
   7307  1.1     is 	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
   7308  1.1     is 	mov.l		ADJFLAG(%a6),%d1
   7309  1.1     is 
   7310  1.1     is #--Step 6
   7311  1.1     is 	tst.l		%d1
   7312  1.1     is 	beq.b		NORMAL
   7313  1.1     is ADJUST:
   7314  1.1     is 	fmul.x		ADJSCALE(%a6),%fp0
   7315  1.1     is NORMAL:
   7316  1.1     is 	fmov.l		%d0,%fpcr		# restore user FPCR
   7317  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7318  1.1     is 	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
   7319  1.1     is 	bra		t_catch
   7320  1.1     is 
   7321  1.1     is EXPSM:
   7322  1.1     is #--Step 7
   7323  1.1     is 	fmovm.x		(%a0),&0x80		# load X
   7324  1.1     is 	fmov.l		%d0,%fpcr
   7325  1.1     is 	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
   7326  1.1     is 	bra		t_pinx2
   7327  1.1     is 
   7328  1.1     is EEXPBIG:
   7329  1.1     is #--Step 8
   7330  1.1     is 	cmp.l		%d1,&0x400CB27C		# 16480 log2
   7331  1.1     is 	bgt.b		EXP2BIG
   7332  1.1     is #--Steps 8.2 -- 8.6
   7333  1.1     is 	fmov.x		(%a0),%fp0		# load input from (a0)
   7334  1.1     is 
   7335  1.1     is 	fmov.x		%fp0,%fp1
   7336  1.1     is 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7337  1.1     is 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7338  1.1     is 	mov.l		&1,ADJFLAG(%a6)
   7339  1.1     is 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7340  1.1     is 	lea		EEXPTBL(%pc),%a1
   7341  1.1     is 	fmov.l		%d1,%fp0		# convert to floating-format
   7342  1.1     is 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7343  1.1     is 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7344  1.1     is 	lsl.l		&4,%d1
   7345  1.1     is 	add.l		%d1,%a1			# address of 2^(J/64)
   7346  1.1     is 	mov.l		L_SCR1(%a6),%d1
   7347  1.1     is 	asr.l		&6,%d1			# D0 is K
   7348  1.1     is 	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
   7349  1.1     is 	asr.l		&1,%d1			# D0 is M1
   7350  1.1     is 	sub.l		%d1,L_SCR1(%a6)		# a1 is M
   7351  1.1     is 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
   7352  1.1     is 	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
   7353  1.1     is 	mov.l		&0x80000000,ADJSCALE+4(%a6)
   7354  1.1     is 	clr.l		ADJSCALE+8(%a6)
   7355  1.1     is 	mov.l		L_SCR1(%a6),%d1		# D0 is M
   7356  1.1     is 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
   7357  1.1     is 	bra.w		EXPCONT1		# go back to Step 3
   7358  1.1     is 
   7359  1.1     is EXP2BIG:
   7360  1.1     is #--Step 9
   7361  1.1     is 	tst.b		(%a0)			# is X positive or negative?
   7362  1.1     is 	bmi		t_unfl2
   7363  1.1     is 	bra		t_ovfl2
   7364  1.1     is 
   7365  1.1     is 	global		setoxd
   7366  1.1     is setoxd:
   7367  1.1     is #--entry point for EXP(X), X is denormalized
   7368  1.1     is 	mov.l		(%a0),-(%sp)
   7369  1.1     is 	andi.l		&0x80000000,(%sp)
   7370  1.1     is 	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
   7371  1.1     is 
   7372  1.1     is 	fmov.s		&0x3F800000,%fp0
   7373  1.1     is 
   7374  1.1     is 	fmov.l		%d0,%fpcr
   7375  1.1     is 	fadd.s		(%sp)+,%fp0
   7376  1.1     is 	bra		t_pinx2
   7377  1.1     is 
   7378  1.1     is 	global		setoxm1
   7379  1.1     is setoxm1:
   7380  1.1     is #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
   7381  1.1     is 
   7382  1.1     is #--Step 1.
   7383  1.1     is #--Step 1.1
   7384  1.1     is 	mov.l		(%a0),%d1		# load part of input X
   7385  1.1     is 	and.l		&0x7FFF0000,%d1		# biased expo. of X
   7386  1.1     is 	cmp.l		%d1,&0x3FFD0000		# 1/4
   7387  1.1     is 	bge.b		EM1CON1			# |X| >= 1/4
   7388  1.1     is 	bra		EM1SM
   7389  1.1     is 
   7390  1.1     is EM1CON1:
   7391  1.1     is #--Step 1.3
   7392  1.1     is #--The case |X| >= 1/4
   7393  1.1     is 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
   7394  1.1     is 	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
   7395  1.1     is 	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
   7396  1.1     is 	bra		EM1BIG
   7397  1.1     is 
   7398  1.1     is EM1MAIN:
   7399  1.1     is #--Step 2.
   7400  1.1     is #--This is the case:	1/4 <= |X| <= 70 log2.
   7401  1.1     is 	fmov.x		(%a0),%fp0		# load input from (a0)
   7402  1.1     is 
   7403  1.1     is 	fmov.x		%fp0,%fp1
   7404  1.1     is 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7405  1.1     is 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7406  1.1     is 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7407  1.1     is 	lea		EEXPTBL(%pc),%a1
   7408  1.1     is 	fmov.l		%d1,%fp0		# convert to floating-format
   7409  1.1     is 
   7410  1.1     is 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7411  1.1     is 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7412  1.1     is 	lsl.l		&4,%d1
   7413  1.1     is 	add.l		%d1,%a1			# address of 2^(J/64)
   7414  1.1     is 	mov.l		L_SCR1(%a6),%d1
   7415  1.1     is 	asr.l		&6,%d1			# D0 is M
   7416  1.1     is 	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
   7417  1.1     is 
   7418  1.1     is #--Step 3.
   7419  1.1     is #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
   7420  1.1     is #--a0 points to 2^(J/64), D0 and a1 both contain M
   7421  1.1     is 	fmov.x		%fp0,%fp2
   7422  1.1     is 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
   7423  1.1     is 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
   7424  1.1     is 	fadd.x		%fp1,%fp0		# X + N*L1
   7425  1.1     is 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
   7426  1.1     is 	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
   7427  1.1     is 
   7428  1.1     is #--Step 4.
   7429  1.1     is #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
   7430  1.1     is #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
   7431  1.3  perry #--TO FULLY USE THE PIPELINE, WE COMPUTE S = R*R
   7432  1.1     is #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
   7433  1.1     is 
   7434  1.1     is 	fmov.x		%fp0,%fp1
   7435  1.1     is 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
   7436  1.1     is 
   7437  1.1     is 	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
   7438  1.1     is 
   7439  1.1     is 	fmul.x		%fp1,%fp2		# fp2 IS S*A6
   7440  1.1     is 	fmov.x		%fp1,%fp3
   7441  1.1     is 	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
   7442  1.1     is 
   7443  1.1     is 	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
   7444  1.1     is 	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
   7445  1.1     is 	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
   7446  1.1     is 	mov.l		&0x80000000,SC+4(%a6)
   7447  1.1     is 	clr.l		SC+8(%a6)
   7448  1.1     is 
   7449  1.1     is 	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
   7450  1.1     is 	mov.l		L_SCR1(%a6),%d1		# D0 is	M
   7451  1.1     is 	neg.w		%d1			# D0 is -M
   7452  1.1     is 	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
   7453  1.1     is 	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
   7454  1.1     is 	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
   7455  1.1     is 	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
   7456  1.1     is 
   7457  1.1     is 	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
   7458  1.1     is 	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
   7459  1.1     is 	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
   7460  1.1     is 	mov.l		&0x80000000,ONEBYSC+4(%a6)
   7461  1.1     is 	clr.l		ONEBYSC+8(%a6)
   7462  1.1     is 	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
   7463  1.1     is 
   7464  1.1     is 	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
   7465  1.1     is 	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
   7466  1.1     is 
   7467  1.1     is 	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
   7468  1.1     is 
   7469  1.1     is 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7470  1.1     is 
   7471  1.1     is #--Step 5
   7472  1.1     is #--Compute 2^(J/64)*p
   7473  1.1     is 
   7474  1.1     is 	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
   7475  1.1     is 
   7476  1.1     is #--Step 6
   7477  1.1     is #--Step 6.1
   7478  1.1     is 	mov.l		L_SCR1(%a6),%d1		# retrieve M
   7479  1.1     is 	cmp.l		%d1,&63
   7480  1.1     is 	ble.b		MLE63
   7481  1.1     is #--Step 6.2	M >= 64
   7482  1.1     is 	fmov.s		12(%a1),%fp1		# fp1 is t
   7483  1.1     is 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
   7484  1.1     is 	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
   7485  1.1     is 	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
   7486  1.1     is 	bra		EM1SCALE
   7487  1.1     is MLE63:
   7488  1.1     is #--Step 6.3	M <= 63
   7489  1.1     is 	cmp.l		%d1,&-3
   7490  1.1     is 	bge.b		MGEN3
   7491  1.1     is MLTN3:
   7492  1.1     is #--Step 6.4	M <= -4
   7493  1.1     is 	fadd.s		12(%a1),%fp0		# p+t
   7494  1.1     is 	fadd.x		(%a1),%fp0		# T+(p+t)
   7495  1.1     is 	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
   7496  1.1     is 	bra		EM1SCALE
   7497  1.1     is MGEN3:
   7498  1.1     is #--Step 6.5	-3 <= M <= 63
   7499  1.1     is 	fmov.x		(%a1)+,%fp1		# fp1 is T
   7500  1.1     is 	fadd.s		(%a1),%fp0		# fp0 is p+t
   7501  1.1     is 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
   7502  1.1     is 	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
   7503  1.1     is 
   7504  1.1     is EM1SCALE:
   7505  1.1     is #--Step 6.6
   7506  1.1     is 	fmov.l		%d0,%fpcr
   7507  1.1     is 	fmul.x		SC(%a6),%fp0
   7508  1.1     is 	bra		t_inx2
   7509  1.1     is 
   7510  1.1     is EM1SM:
   7511  1.1     is #--Step 7	|X| < 1/4.
   7512  1.1     is 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
   7513  1.1     is 	bge.b		EM1POLY
   7514  1.1     is 
   7515  1.1     is EM1TINY:
   7516  1.1     is #--Step 8	|X| < 2^(-65)
   7517  1.1     is 	cmp.l		%d1,&0x00330000		# 2^(-16312)
   7518  1.1     is 	blt.b		EM12TINY
   7519  1.1     is #--Step 8.2
   7520  1.1     is 	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
   7521  1.1     is 	mov.l		&0x80000000,SC+4(%a6)
   7522  1.1     is 	clr.l		SC+8(%a6)
   7523  1.1     is 	fmov.x		(%a0),%fp0
   7524  1.1     is 	fmov.l		%d0,%fpcr
   7525  1.1     is 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7526  1.1     is 	fadd.x		SC(%a6),%fp0
   7527  1.1     is 	bra		t_catch
   7528  1.1     is 
   7529  1.1     is EM12TINY:
   7530  1.1     is #--Step 8.3
   7531  1.1     is 	fmov.x		(%a0),%fp0
   7532  1.1     is 	fmul.d		TWO140(%pc),%fp0
   7533  1.1     is 	mov.l		&0x80010000,SC(%a6)
   7534  1.1     is 	mov.l		&0x80000000,SC+4(%a6)
   7535  1.1     is 	clr.l		SC+8(%a6)
   7536  1.1     is 	fadd.x		SC(%a6),%fp0
   7537  1.1     is 	fmov.l		%d0,%fpcr
   7538  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7539  1.1     is 	fmul.d		TWON140(%pc),%fp0
   7540  1.1     is 	bra		t_catch
   7541  1.1     is 
   7542  1.1     is EM1POLY:
   7543  1.1     is #--Step 9	exp(X)-1 by a simple polynomial
   7544  1.1     is 	fmov.x		(%a0),%fp0		# fp0 is X
   7545  1.1     is 	fmul.x		%fp0,%fp0		# fp0 is S := X*X
   7546  1.1     is 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7547  1.1     is 	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
   7548  1.1     is 	fmul.x		%fp0,%fp1		# fp1 is S*B12
   7549  1.1     is 	fmov.s		&0x310F8290,%fp2	# fp2 is B11
   7550  1.1     is 	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
   7551  1.1     is 
   7552  1.1     is 	fmul.x		%fp0,%fp2		# fp2 is S*B11
   7553  1.1     is 	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
   7554  1.1     is 
   7555  1.1     is 	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
   7556  1.1     is 	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
   7557  1.1     is 
   7558  1.1     is 	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
   7559  1.1     is 	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
   7560  1.1     is 
   7561  1.1     is 	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
   7562  1.1     is 	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
   7563  1.1     is 
   7564  1.1     is 	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
   7565  1.1     is 	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
   7566  1.1     is 
   7567  1.1     is 	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
   7568  1.1     is 	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
   7569  1.1     is 
   7570  1.1     is 	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
   7571  1.1     is 	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
   7572  1.1     is 
   7573  1.1     is 	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
   7574  1.1     is 	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
   7575  1.1     is 
   7576  1.1     is 	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
   7577  1.1     is 	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
   7578  1.1     is 
   7579  1.1     is 	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
   7580  1.1     is 	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
   7581  1.1     is 
   7582  1.1     is 	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
   7583  1.1     is 	fadd.x		%fp2,%fp1		# fp1 is Q
   7584  1.1     is 
   7585  1.1     is 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7586  1.1     is 
   7587  1.1     is 	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
   7588  1.1     is 
   7589  1.1     is 	fmov.l		%d0,%fpcr
   7590  1.1     is 	fadd.x		(%a0),%fp0
   7591  1.1     is 	bra		t_inx2
   7592  1.1     is 
   7593  1.1     is EM1BIG:
   7594  1.1     is #--Step 10	|X| > 70 log2
   7595  1.1     is 	mov.l		(%a0),%d1
   7596  1.1     is 	cmp.l		%d1,&0
   7597  1.1     is 	bgt.w		EXPC1
   7598  1.1     is #--Step 10.2
   7599  1.1     is 	fmov.s		&0xBF800000,%fp0	# fp0 is -1
   7600  1.1     is 	fmov.l		%d0,%fpcr
   7601  1.1     is 	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
   7602  1.1     is 	bra		t_minx2
   7603  1.1     is 
   7604  1.1     is 	global		setoxm1d
   7605  1.1     is setoxm1d:
   7606  1.1     is #--entry point for EXPM1(X), here X is denormalized
   7607  1.1     is #--Step 0.
   7608  1.1     is 	bra		t_extdnrm
   7609  1.1     is 
   7610  1.1     is #########################################################################
   7611  1.1     is # sgetexp():  returns the exponent portion of the input argument.	#
   7612  1.1     is #	      The exponent bias is removed and the exponent value is	#
   7613  1.1     is #	      returned as an extended precision number in fp0.		#
   7614  1.1     is # sgetexpd(): handles denormalized numbers. 				#
   7615  1.1     is #									#
   7616  1.1     is # sgetman():  extracts the mantissa of the input argument. The 		#
   7617  1.1     is #	      mantissa is converted to an extended precision number w/ 	#
   7618  1.1     is #	      an exponent of $3fff and is returned in fp0. The range of #
   7619  1.1     is #	      the result is [1.0 - 2.0).				#
   7620  1.1     is # sgetmand(): handles denormalized numbers.				#
   7621  1.1     is #									#
   7622  1.1     is # INPUT *************************************************************** #
   7623  1.1     is #	a0  = pointer to extended precision input			#
   7624  1.1     is #									#
   7625  1.1     is # OUTPUT ************************************************************** #
   7626  1.1     is #	fp0 = exponent(X) or mantissa(X)				#
   7627  1.1     is #									#
   7628  1.1     is #########################################################################
   7629  1.1     is 
   7630  1.1     is 	global		sgetexp
   7631  1.1     is sgetexp:
   7632  1.1     is 	mov.w		SRC_EX(%a0),%d0		# get the exponent
   7633  1.1     is 	bclr		&0xf,%d0		# clear the sign bit
   7634  1.1     is 	subi.w		&0x3fff,%d0		# subtract off the bias
   7635  1.1     is 	fmov.w		%d0,%fp0		# return exp in fp0
   7636  1.1     is 	blt.b		sgetexpn		# it's negative
   7637  1.1     is 	rts
   7638  1.1     is 
   7639  1.1     is sgetexpn:
   7640  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7641  1.1     is 	rts
   7642  1.1     is 
   7643  1.1     is 	global		sgetexpd
   7644  1.1     is sgetexpd:
   7645  1.1     is 	bsr.l		norm			# normalize
   7646  1.1     is 	neg.w		%d0			# new exp = -(shft amt)
   7647  1.1     is 	subi.w		&0x3fff,%d0		# subtract off the bias
   7648  1.1     is 	fmov.w		%d0,%fp0		# return exp in fp0
   7649  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7650  1.1     is 	rts
   7651  1.1     is 
   7652  1.1     is 	global		sgetman
   7653  1.1     is sgetman:
   7654  1.1     is 	mov.w		SRC_EX(%a0),%d0		# get the exp
   7655  1.1     is 	ori.w		&0x7fff,%d0		# clear old exp
   7656  1.1     is 	bclr		&0xe,%d0		# make it the new exp +-3fff
   7657  1.1     is 
   7658  1.1     is # here, we build the result in a tmp location so as not to disturb the input
   7659  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
   7660  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
   7661  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   7662  1.1     is 	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
   7663  1.1     is 	bmi.b		sgetmann		# it's negative
   7664  1.1     is 	rts
   7665  1.1     is 
   7666  1.1     is sgetmann:
   7667  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7668  1.1     is 	rts
   7669  1.1     is 
   7670  1.1     is #
   7671  1.1     is # For denormalized numbers, shift the mantissa until the j-bit = 1,
   7672  1.1     is # then load the exponent with +/1 $3fff.
   7673  1.1     is #
   7674  1.1     is 	global		sgetmand
   7675  1.1     is sgetmand:
   7676  1.1     is 	bsr.l		norm			# normalize exponent
   7677  1.1     is 	bra.b		sgetman
   7678  1.1     is 
   7679  1.1     is #########################################################################
   7680  1.1     is # scosh():  computes the hyperbolic cosine of a normalized input	#
   7681  1.1     is # scoshd(): computes the hyperbolic cosine of a denormalized input	#
   7682  1.1     is #									#
   7683  1.1     is # INPUT ***************************************************************	#
   7684  1.1     is #	a0 = pointer to extended precision input			#
   7685  1.1     is #	d0 = round precision,mode					#
   7686  1.1     is #									#
   7687  1.1     is # OUTPUT **************************************************************	#
   7688  1.1     is #	fp0 = cosh(X)							#
   7689  1.1     is #									#
   7690  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   7691  1.1     is #	The returned result is within 3 ulps in 64 significant bit, 	#
   7692  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   7693  1.1     is #	rounded to double precision. The result is provably monotonic 	#
   7694  1.1     is #	in double precision.						#
   7695  1.1     is #									#
   7696  1.1     is # ALGORITHM ***********************************************************	#
   7697  1.1     is #									#
   7698  1.1     is #	COSH								#
   7699  1.1     is #	1. If |X| > 16380 log2, go to 3.				#
   7700  1.1     is #									#
   7701  1.1     is #	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
   7702  1.1     is #		y = |X|, z = exp(Y), and				#
   7703  1.1     is #		cosh(X) = (1/2)*( z + 1/z ).				#
   7704  1.1     is #		Exit.							#
   7705  1.1     is #									#
   7706  1.1     is #	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
   7707  1.1     is #									#
   7708  1.1     is #	4. (16380 log2 < |X| <= 16480 log2)				#
   7709  1.1     is #		cosh(X) = sign(X) * exp(|X|)/2.				#
   7710  1.1     is #		However, invoking exp(|X|) may cause premature 		#
   7711  1.1     is #		overflow. Thus, we calculate sinh(X) as follows:	#
   7712  1.1     is #		Y	:= |X|						#
   7713  1.1     is #		Fact	:=	2**(16380)				#
   7714  1.1     is #		Y'	:= Y - 16381 log2				#
   7715  1.1     is #		cosh(X) := Fact * exp(Y').				#
   7716  1.1     is #		Exit.							#
   7717  1.1     is #									#
   7718  1.1     is #	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
   7719  1.1     is #		Huge*Huge to generate overflow and an infinity with	#
   7720  1.1     is #		the appropriate sign. Huge is the largest finite number	#
   7721  1.1     is #		in extended format. Exit.				#
   7722  1.1     is #									#
   7723  1.1     is #########################################################################
   7724  1.1     is 
   7725  1.1     is TWO16380:
   7726  1.1     is 	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
   7727  1.1     is 
   7728  1.1     is 	global		scosh
   7729  1.1     is scosh:
   7730  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7731  1.1     is 
   7732  1.1     is 	mov.l		(%a0),%d1
   7733  1.1     is 	mov.w		4(%a0),%d1
   7734  1.1     is 	and.l		&0x7FFFFFFF,%d1
   7735  1.1     is 	cmp.l		%d1,&0x400CB167
   7736  1.1     is 	bgt.b		COSHBIG
   7737  1.1     is 
   7738  1.1     is #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
   7739  1.1     is #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
   7740  1.1     is 
   7741  1.1     is 	fabs.x		%fp0			# |X|
   7742  1.1     is 
   7743  1.1     is 	mov.l		%d0,-(%sp)
   7744  1.1     is 	clr.l		%d0
   7745  1.1     is 	fmovm.x		&0x01,-(%sp)		# save |X| to stack
   7746  1.1     is 	lea		(%sp),%a0		# pass ptr to |X|
   7747  1.1     is 	bsr		setox			# FP0 IS EXP(|X|)
   7748  1.1     is 	add.l		&0xc,%sp		# erase |X| from stack
   7749  1.1     is 	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
   7750  1.1     is 	mov.l		(%sp)+,%d0
   7751  1.1     is 
   7752  1.1     is 	fmov.s		&0x3E800000,%fp1	# (1/4)
   7753  1.1     is 	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
   7754  1.1     is 
   7755  1.1     is 	fmov.l		%d0,%fpcr
   7756  1.1     is 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7757  1.1     is 	fadd.x		%fp1,%fp0
   7758  1.1     is 	bra		t_catch
   7759  1.1     is 
   7760  1.1     is COSHBIG:
   7761  1.1     is 	cmp.l		%d1,&0x400CB2B3
   7762  1.1     is 	bgt.b		COSHHUGE
   7763  1.1     is 
   7764  1.1     is 	fabs.x		%fp0
   7765  1.1     is 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
   7766  1.1     is 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
   7767  1.1     is 
   7768  1.1     is 	mov.l		%d0,-(%sp)
   7769  1.1     is 	clr.l		%d0
   7770  1.1     is 	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
   7771  1.1     is 	lea		(%sp),%a0		# pass ptr to fp0
   7772  1.1     is 	bsr		setox
   7773  1.1     is 	add.l		&0xc,%sp		# clear fp0 from stack
   7774  1.1     is 	mov.l		(%sp)+,%d0
   7775  1.1     is 
   7776  1.1     is 	fmov.l		%d0,%fpcr
   7777  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7778  1.1     is 	fmul.x		TWO16380(%pc),%fp0
   7779  1.1     is 	bra		t_catch
   7780  1.1     is 
   7781  1.1     is COSHHUGE:
   7782  1.1     is 	bra		t_ovfl2
   7783  1.1     is 
   7784  1.1     is 	global		scoshd
   7785  1.1     is #--COSH(X) = 1 FOR DENORMALIZED X
   7786  1.1     is scoshd:
   7787  1.1     is 	fmov.s		&0x3F800000,%fp0
   7788  1.1     is 
   7789  1.1     is 	fmov.l		%d0,%fpcr
   7790  1.1     is 	fadd.s		&0x00800000,%fp0
   7791  1.1     is 	bra		t_pinx2
   7792  1.1     is 
   7793  1.1     is #########################################################################
   7794  1.1     is # ssinh():  computes the hyperbolic sine of a normalized input		#
   7795  1.1     is # ssinhd(): computes the hyperbolic sine of a denormalized input	#
   7796  1.1     is #									#
   7797  1.1     is # INPUT *************************************************************** #
   7798  1.1     is #	a0 = pointer to extended precision input			#
   7799  1.1     is #	d0 = round precision,mode					#
   7800  1.1     is #									#
   7801  1.1     is # OUTPUT ************************************************************** #
   7802  1.1     is #	fp0 = sinh(X)							#
   7803  1.1     is #									#
   7804  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   7805  1.1     is #	The returned result is within 3 ulps in 64 significant bit, 	#
   7806  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   7807  1.1     is #	rounded to double precision. The result is provably monotonic	#
   7808  1.1     is #	in double precision.						#
   7809  1.1     is #									#
   7810  1.1     is # ALGORITHM *********************************************************** #
   7811  1.1     is #									#
   7812  1.1     is #       SINH								#
   7813  1.1     is #       1. If |X| > 16380 log2, go to 3.				#
   7814  1.1     is #									#
   7815  1.1     is #       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
   7816  1.1     is #               y = |X|, sgn = sign(X), and z = expm1(Y),		#
   7817  1.1     is #               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
   7818  1.1     is #          Exit.							#
   7819  1.1     is #									#
   7820  1.1     is #       3. If |X| > 16480 log2, go to 5.				#
   7821  1.1     is #									#
   7822  1.1     is #       4. (16380 log2 < |X| <= 16480 log2)				#
   7823  1.1     is #               sinh(X) = sign(X) * exp(|X|)/2.				#
   7824  1.1     is #          However, invoking exp(|X|) may cause premature overflow.	#
   7825  1.1     is #          Thus, we calculate sinh(X) as follows:			#
   7826  1.1     is #             Y       := |X|						#
   7827  1.1     is #             sgn     := sign(X)					#
   7828  1.1     is #             sgnFact := sgn * 2**(16380)				#
   7829  1.1     is #             Y'      := Y - 16381 log2					#
   7830  1.1     is #             sinh(X) := sgnFact * exp(Y').				#
   7831  1.1     is #          Exit.							#
   7832  1.1     is #									#
   7833  1.1     is #       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
   7834  1.1     is #          sign(X)*Huge*Huge to generate overflow and an infinity with	#
   7835  1.1     is #          the appropriate sign. Huge is the largest finite number in	#
   7836  1.1     is #          extended format. Exit.					#
   7837  1.1     is #									#
   7838  1.1     is #########################################################################
   7839  1.1     is 
   7840  1.1     is 	global		ssinh
   7841  1.1     is ssinh:
   7842  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7843  1.1     is 
   7844  1.1     is 	mov.l		(%a0),%d1
   7845  1.1     is 	mov.w		4(%a0),%d1
   7846  1.1     is 	mov.l		%d1,%a1			# save (compacted) operand
   7847  1.1     is 	and.l		&0x7FFFFFFF,%d1
   7848  1.1     is 	cmp.l		%d1,&0x400CB167
   7849  1.1     is 	bgt.b		SINHBIG
   7850  1.1     is 
   7851  1.1     is #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
   7852  1.1     is #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
   7853  1.1     is 
   7854  1.1     is 	fabs.x		%fp0			# Y = |X|
   7855  1.1     is 
   7856  1.1     is 	movm.l		&0x8040,-(%sp)		# {a1/d0}
   7857  1.1     is 	fmovm.x		&0x01,-(%sp)		# save Y on stack
   7858  1.1     is 	lea		(%sp),%a0		# pass ptr to Y
   7859  1.1     is 	clr.l		%d0
   7860  1.1     is 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
   7861  1.1     is 	add.l		&0xc,%sp		# clear Y from stack
   7862  1.1     is 	fmov.l		&0,%fpcr
   7863  1.1     is 	movm.l		(%sp)+,&0x0201		# {a1/d0}
   7864  1.1     is 
   7865  1.1     is 	fmov.x		%fp0,%fp1
   7866  1.1     is 	fadd.s		&0x3F800000,%fp1	# 1+Z
   7867  1.1     is 	fmov.x		%fp0,-(%sp)
   7868  1.1     is 	fdiv.x		%fp1,%fp0		# Z/(1+Z)
   7869  1.1     is 	mov.l		%a1,%d1
   7870  1.1     is 	and.l		&0x80000000,%d1
   7871  1.1     is 	or.l		&0x3F000000,%d1
   7872  1.1     is 	fadd.x		(%sp)+,%fp0
   7873  1.1     is 	mov.l		%d1,-(%sp)
   7874  1.1     is 
   7875  1.1     is 	fmov.l		%d0,%fpcr
   7876  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7877  1.1     is 	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
   7878  1.1     is 	bra		t_catch
   7879  1.1     is 
   7880  1.1     is SINHBIG:
   7881  1.1     is 	cmp.l		%d1,&0x400CB2B3
   7882  1.1     is 	bgt		t_ovfl
   7883  1.1     is 	fabs.x		%fp0
   7884  1.1     is 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
   7885  1.1     is 	mov.l		&0,-(%sp)
   7886  1.1     is 	mov.l		&0x80000000,-(%sp)
   7887  1.1     is 	mov.l		%a1,%d1
   7888  1.1     is 	and.l		&0x80000000,%d1
   7889  1.1     is 	or.l		&0x7FFB0000,%d1
   7890  1.1     is 	mov.l		%d1,-(%sp)		# EXTENDED FMT
   7891  1.1     is 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
   7892  1.1     is 
   7893  1.1     is 	mov.l		%d0,-(%sp)
   7894  1.1     is 	clr.l		%d0
   7895  1.1     is 	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
   7896  1.1     is 	lea		(%sp),%a0		# pass ptr to fp0
   7897  1.1     is 	bsr		setox
   7898  1.1     is 	add.l		&0xc,%sp		# clear fp0 from stack
   7899  1.1     is 
   7900  1.1     is 	mov.l		(%sp)+,%d0
   7901  1.1     is 	fmov.l		%d0,%fpcr
   7902  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7903  1.1     is 	fmul.x		(%sp)+,%fp0		# possible exception
   7904  1.1     is 	bra		t_catch
   7905  1.1     is 
   7906  1.1     is 	global		ssinhd
   7907  1.1     is #--SINH(X) = X FOR DENORMALIZED X
   7908  1.1     is ssinhd:
   7909  1.1     is 	bra		t_extdnrm
   7910  1.1     is 
   7911  1.1     is #########################################################################
   7912  1.1     is # stanh():  computes the hyperbolic tangent of a normalized input	#
   7913  1.1     is # stanhd(): computes the hyperbolic tangent of a denormalized input	#
   7914  1.1     is #									#
   7915  1.1     is # INPUT ***************************************************************	#
   7916  1.1     is #	a0 = pointer to extended precision input			#
   7917  1.1     is #	d0 = round precision,mode					#
   7918  1.1     is #									#
   7919  1.1     is # OUTPUT **************************************************************	#
   7920  1.1     is #	fp0 = tanh(X)							#
   7921  1.1     is #									#
   7922  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   7923  1.1     is #	The returned result is within 3 ulps in 64 significant bit, 	#
   7924  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   7925  1.1     is #	rounded to double precision. The result is provably monotonic	#
   7926  1.1     is #	in double precision.						#
   7927  1.1     is #									#
   7928  1.1     is # ALGORITHM ***********************************************************	#
   7929  1.1     is #									#
   7930  1.1     is #	TANH								#
   7931  1.1     is #	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
   7932  1.1     is #									#
   7933  1.1     is #	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
   7934  1.1     is #		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
   7935  1.1     is #		tanh(X) = sgn*( z/(2+z) ).				#
   7936  1.1     is #		Exit.							#
   7937  1.1     is #									#
   7938  1.1     is #	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
   7939  1.1     is #		go to 7.						#
   7940  1.1     is #									#
   7941  1.1     is #	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
   7942  1.1     is #									#
   7943  1.1     is #	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
   7944  1.1     is #		sgn := sign(X), y := 2|X|, z := exp(Y),			#
   7945  1.1     is #		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
   7946  1.1     is #		Exit.							#
   7947  1.1     is #									#
   7948  1.1     is #	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
   7949  1.1     is #		calculate Tanh(X) by					#
   7950  1.1     is #		sgn := sign(X), Tiny := 2**(-126),			#
   7951  1.1     is #		tanh(X) := sgn - sgn*Tiny.				#
   7952  1.1     is #		Exit.							#
   7953  1.1     is #									#
   7954  1.1     is #	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
   7955  1.1     is #									#
   7956  1.1     is #########################################################################
   7957  1.1     is 
   7958  1.1     is 	set		X,FP_SCR0
   7959  1.1     is 	set		XFRAC,X+4
   7960  1.1     is 
   7961  1.1     is 	set		SGN,L_SCR3
   7962  1.1     is 
   7963  1.1     is 	set		V,FP_SCR0
   7964  1.1     is 
   7965  1.1     is 	global		stanh
   7966  1.1     is stanh:
   7967  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7968  1.1     is 
   7969  1.1     is 	fmov.x		%fp0,X(%a6)
   7970  1.1     is 	mov.l		(%a0),%d1
   7971  1.1     is 	mov.w		4(%a0),%d1
   7972  1.1     is 	mov.l		%d1,X(%a6)
   7973  1.1     is 	and.l		&0x7FFFFFFF,%d1
   7974  1.1     is 	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
   7975  1.1     is 	blt.w		TANHBORS		# yes
   7976  1.1     is 	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
   7977  1.1     is 	bgt.w		TANHBORS		# yes
   7978  1.1     is 
   7979  1.1     is #--THIS IS THE USUAL CASE
   7980  1.1     is #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
   7981  1.1     is 
   7982  1.1     is 	mov.l		X(%a6),%d1
   7983  1.1     is 	mov.l		%d1,SGN(%a6)
   7984  1.1     is 	and.l		&0x7FFF0000,%d1
   7985  1.1     is 	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
   7986  1.1     is 	mov.l		%d1,X(%a6)
   7987  1.1     is 	and.l		&0x80000000,SGN(%a6)
   7988  1.1     is 	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
   7989  1.1     is 
   7990  1.1     is 	mov.l		%d0,-(%sp)
   7991  1.1     is 	clr.l		%d0
   7992  1.1     is 	fmovm.x		&0x1,-(%sp)		# save Y on stack
   7993  1.1     is 	lea		(%sp),%a0		# pass ptr to Y
   7994  1.1     is 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
   7995  1.1     is 	add.l		&0xc,%sp		# clear Y from stack
   7996  1.1     is 	mov.l		(%sp)+,%d0
   7997  1.1     is 
   7998  1.1     is 	fmov.x		%fp0,%fp1
   7999  1.1     is 	fadd.s		&0x40000000,%fp1	# Z+2
   8000  1.1     is 	mov.l		SGN(%a6),%d1
   8001  1.1     is 	fmov.x		%fp1,V(%a6)
   8002  1.1     is 	eor.l		%d1,V(%a6)
   8003  1.1     is 
   8004  1.1     is 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8005  1.1     is 	fdiv.x		V(%a6),%fp0
   8006  1.1     is 	bra		t_inx2
   8007  1.1     is 
   8008  1.1     is TANHBORS:
   8009  1.1     is 	cmp.l		%d1,&0x3FFF8000
   8010  1.1     is 	blt.w		TANHSM
   8011  1.1     is 
   8012  1.1     is 	cmp.l		%d1,&0x40048AA1
   8013  1.1     is 	bgt.w		TANHHUGE
   8014  1.1     is 
   8015  1.1     is #-- (5/2) LOG2 < |X| < 50 LOG2,
   8016  1.1     is #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
   8017  1.1     is #--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
   8018  1.1     is 
   8019  1.1     is 	mov.l		X(%a6),%d1
   8020  1.1     is 	mov.l		%d1,SGN(%a6)
   8021  1.1     is 	and.l		&0x7FFF0000,%d1
   8022  1.1     is 	add.l		&0x00010000,%d1		# EXPO OF 2|X|
   8023  1.1     is 	mov.l		%d1,X(%a6)		# Y = 2|X|
   8024  1.1     is 	and.l		&0x80000000,SGN(%a6)
   8025  1.1     is 	mov.l		SGN(%a6),%d1
   8026  1.1     is 	fmov.x		X(%a6),%fp0		# Y = 2|X|
   8027  1.1     is 
   8028  1.1     is 	mov.l		%d0,-(%sp)
   8029  1.1     is 	clr.l		%d0
   8030  1.1     is 	fmovm.x		&0x01,-(%sp)		# save Y on stack
   8031  1.1     is 	lea		(%sp),%a0		# pass ptr to Y
   8032  1.1     is 	bsr		setox			# FP0 IS EXP(Y)
   8033  1.1     is 	add.l		&0xc,%sp		# clear Y from stack
   8034  1.1     is 	mov.l		(%sp)+,%d0
   8035  1.1     is 	mov.l		SGN(%a6),%d1
   8036  1.1     is 	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
   8037  1.1     is 
   8038  1.1     is 	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
   8039  1.1     is 	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
   8040  1.1     is 	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
   8041  1.1     is 
   8042  1.1     is 	mov.l		SGN(%a6),%d1
   8043  1.1     is 	or.l		&0x3F800000,%d1		# SGN
   8044  1.1     is 	fmov.s		%d1,%fp0		# SGN IN SGL FMT
   8045  1.1     is 
   8046  1.1     is 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8047  1.1     is 	mov.b		&FADD_OP,%d1		# last inst is ADD
   8048  1.1     is 	fadd.x		%fp1,%fp0
   8049  1.1     is 	bra		t_inx2
   8050  1.1     is 
   8051  1.1     is TANHSM:
   8052  1.1     is 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8053  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   8054  1.1     is 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   8055  1.1     is 	bra		t_catch
   8056  1.1     is 
   8057  1.1     is #---RETURN SGN(X) - SGN(X)EPS
   8058  1.1     is TANHHUGE:
   8059  1.1     is 	mov.l		X(%a6),%d1
   8060  1.1     is 	and.l		&0x80000000,%d1
   8061  1.1     is 	or.l		&0x3F800000,%d1
   8062  1.1     is 	fmov.s		%d1,%fp0
   8063  1.1     is 	and.l		&0x80000000,%d1
   8064  1.1     is 	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
   8065  1.1     is 
   8066  1.1     is 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8067  1.1     is 	fadd.s		%d1,%fp0
   8068  1.1     is 	bra		t_inx2
   8069  1.1     is 
   8070  1.1     is 	global		stanhd
   8071  1.1     is #--TANH(X) = X FOR DENORMALIZED X
   8072  1.1     is stanhd:
   8073  1.1     is 	bra		t_extdnrm
   8074  1.1     is 
   8075  1.1     is #########################################################################
   8076  1.1     is # slogn():    computes the natural logarithm of a normalized input	#
   8077  1.1     is # slognd():   computes the natural logarithm of a denormalized input	#
   8078  1.1     is # slognp1():  computes the log(1+X) of a normalized input		#
   8079  1.1     is # slognp1d(): computes the log(1+X) of a denormalized input		#
   8080  1.1     is #									#
   8081  1.1     is # INPUT ***************************************************************	#
   8082  1.1     is #	a0 = pointer to extended precision input			#
   8083  1.1     is #	d0 = round precision,mode					#
   8084  1.1     is #									#
   8085  1.1     is # OUTPUT **************************************************************	#
   8086  1.1     is #	fp0 = log(X) or log(1+X)					#
   8087  1.1     is #									#
   8088  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   8089  1.1     is #	The returned result is within 2 ulps in 64 significant bit, 	#
   8090  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8091  1.1     is #	rounded to double precision. The result is provably monotonic	#
   8092  1.1     is #	in double precision.						#
   8093  1.1     is #									#
   8094  1.1     is # ALGORITHM ***********************************************************	#
   8095  1.1     is #	LOGN:								#
   8096  1.1     is #	Step 1. If |X-1| < 1/16, approximate log(X) by an odd 		#
   8097  1.1     is #		polynomial in u, where u = 2(X-1)/(X+1). Otherwise, 	#
   8098  1.1     is #		move on to Step 2.					#
   8099  1.1     is #									#
   8100  1.1     is #	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
   8101  1.1     is #		seven significant bits of Y plus 2**(-7), i.e. 		#
   8102  1.1     is #		F = 1.xxxxxx1 in base 2 where the six "x" match those 	#
   8103  1.1     is #		of Y. Note that |Y-F| <= 2**(-7).			#
   8104  1.1     is #									#
   8105  1.1     is #	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a 		#
   8106  1.1     is #		polynomial in u, log(1+u) = poly.			#
   8107  1.1     is #									#
   8108  1.1     is #	Step 4. Reconstruct 						#
   8109  1.1     is #		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
   8110  1.1     is #		by k*log(2) + (log(F) + poly). The values of log(F) are	#
   8111  1.1     is #		calculated beforehand and stored in the program.	#
   8112  1.1     is #									#
   8113  1.1     is #	lognp1:								#
   8114  1.1     is #	Step 1: If |X| < 1/16, approximate log(1+X) by an odd 		#
   8115  1.1     is #		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
   8116  1.1     is #		to Step 2.						#
   8117  1.1     is #									#
   8118  1.1     is #	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
   8119  1.1     is #		in Step 2 of the algorithm for LOGN and compute 	#
   8120  1.1     is #		log(1+X) as k*log(2) + log(F) + poly where poly 	#
   8121  1.1     is #		approximates log(1+u), u = (Y-F)/F. 			#
   8122  1.1     is #									#
   8123  1.1     is #	Implementation Notes:						#
   8124  1.1     is #	Note 1. There are 64 different possible values for F, thus 64 	#
   8125  1.1     is #		log(F)'s need to be tabulated. Moreover, the values of	#
   8126  1.1     is #		1/F are also tabulated so that the division in (Y-F)/F	#
   8127  1.1     is #		can be performed by a multiplication.			#
   8128  1.1     is #									#
   8129  1.1     is #	Note 2. In Step 2 of lognp1, in order to preserved accuracy, 	#
   8130  1.1     is #		the value Y-F has to be calculated carefully when 	#
   8131  1.1     is #		1/2 <= X < 3/2. 					#
   8132  1.1     is #									#
   8133  1.1     is #	Note 3. To fully exploit the pipeline, polynomials are usually 	#
   8134  1.1     is #		separated into two parts evaluated independently before	#
   8135  1.1     is #		being added up.						#
   8136  1.1     is #									#
   8137  1.1     is #########################################################################
   8138  1.1     is LOGOF2:
   8139  1.1     is 	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
   8140  1.1     is 
   8141  1.1     is one:
   8142  1.1     is 	long		0x3F800000
   8143  1.1     is zero:
   8144  1.1     is 	long		0x00000000
   8145  1.1     is infty:
   8146  1.1     is 	long		0x7F800000
   8147  1.1     is negone:
   8148  1.1     is 	long		0xBF800000
   8149  1.1     is 
   8150  1.1     is LOGA6:
   8151  1.1     is 	long		0x3FC2499A,0xB5E4040B
   8152  1.1     is LOGA5:
   8153  1.1     is 	long		0xBFC555B5,0x848CB7DB
   8154  1.1     is 
   8155  1.1     is LOGA4:
   8156  1.1     is 	long		0x3FC99999,0x987D8730
   8157  1.1     is LOGA3:
   8158  1.1     is 	long		0xBFCFFFFF,0xFF6F7E97
   8159  1.1     is 
   8160  1.1     is LOGA2:
   8161  1.1     is 	long		0x3FD55555,0x555555A4
   8162  1.1     is LOGA1:
   8163  1.1     is 	long		0xBFE00000,0x00000008
   8164  1.1     is 
   8165  1.1     is LOGB5:
   8166  1.1     is 	long		0x3F175496,0xADD7DAD6
   8167  1.1     is LOGB4:
   8168  1.1     is 	long		0x3F3C71C2,0xFE80C7E0
   8169  1.1     is 
   8170  1.1     is LOGB3:
   8171  1.1     is 	long		0x3F624924,0x928BCCFF
   8172  1.1     is LOGB2:
   8173  1.1     is 	long		0x3F899999,0x999995EC
   8174  1.1     is 
   8175  1.1     is LOGB1:
   8176  1.1     is 	long		0x3FB55555,0x55555555
   8177  1.1     is TWO:
   8178  1.1     is 	long		0x40000000,0x00000000
   8179  1.1     is 
   8180  1.1     is LTHOLD:
   8181  1.1     is 	long		0x3f990000,0x80000000,0x00000000,0x00000000
   8182  1.1     is 
   8183  1.1     is LOGTBL:
   8184  1.1     is 	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
   8185  1.1     is 	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
   8186  1.1     is 	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
   8187  1.1     is 	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
   8188  1.1     is 	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
   8189  1.1     is 	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
   8190  1.1     is 	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
   8191  1.1     is 	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
   8192  1.1     is 	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
   8193  1.1     is 	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
   8194  1.1     is 	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
   8195  1.1     is 	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
   8196  1.1     is 	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
   8197  1.1     is 	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
   8198  1.1     is 	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
   8199  1.1     is 	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
   8200  1.1     is 	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
   8201  1.1     is 	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
   8202  1.1     is 	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
   8203  1.1     is 	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
   8204  1.1     is 	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
   8205  1.1     is 	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
   8206  1.1     is 	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
   8207  1.1     is 	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
   8208  1.1     is 	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
   8209  1.1     is 	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
   8210  1.1     is 	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
   8211  1.1     is 	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
   8212  1.1     is 	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
   8213  1.1     is 	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
   8214  1.1     is 	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
   8215  1.1     is 	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
   8216  1.1     is 	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
   8217  1.1     is 	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
   8218  1.1     is 	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
   8219  1.1     is 	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
   8220  1.1     is 	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
   8221  1.1     is 	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
   8222  1.1     is 	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
   8223  1.1     is 	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
   8224  1.1     is 	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
   8225  1.1     is 	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
   8226  1.1     is 	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
   8227  1.1     is 	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
   8228  1.1     is 	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
   8229  1.1     is 	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
   8230  1.1     is 	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
   8231  1.1     is 	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
   8232  1.1     is 	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
   8233  1.1     is 	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
   8234  1.1     is 	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
   8235  1.1     is 	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
   8236  1.1     is 	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
   8237  1.1     is 	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
   8238  1.1     is 	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
   8239  1.1     is 	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
   8240  1.1     is 	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
   8241  1.1     is 	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
   8242  1.1     is 	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
   8243  1.1     is 	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
   8244  1.1     is 	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
   8245  1.1     is 	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
   8246  1.1     is 	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
   8247  1.1     is 	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
   8248  1.1     is 	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
   8249  1.1     is 	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
   8250  1.1     is 	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
   8251  1.1     is 	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
   8252  1.1     is 	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
   8253  1.1     is 	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
   8254  1.1     is 	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
   8255  1.1     is 	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
   8256  1.1     is 	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
   8257  1.1     is 	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
   8258  1.1     is 	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
   8259  1.1     is 	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
   8260  1.1     is 	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
   8261  1.1     is 	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
   8262  1.1     is 	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
   8263  1.1     is 	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
   8264  1.1     is 	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
   8265  1.1     is 	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
   8266  1.1     is 	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
   8267  1.1     is 	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
   8268  1.1     is 	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
   8269  1.1     is 	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
   8270  1.1     is 	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
   8271  1.1     is 	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
   8272  1.1     is 	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
   8273  1.1     is 	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
   8274  1.1     is 	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
   8275  1.1     is 	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
   8276  1.1     is 	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
   8277  1.1     is 	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
   8278  1.1     is 	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
   8279  1.1     is 	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
   8280  1.1     is 	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
   8281  1.1     is 	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
   8282  1.1     is 	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
   8283  1.1     is 	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
   8284  1.1     is 	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
   8285  1.1     is 	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
   8286  1.1     is 	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
   8287  1.1     is 	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
   8288  1.1     is 	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
   8289  1.1     is 	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
   8290  1.1     is 	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
   8291  1.1     is 	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
   8292  1.1     is 	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
   8293  1.1     is 	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
   8294  1.1     is 	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
   8295  1.1     is 	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
   8296  1.1     is 	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
   8297  1.1     is 	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
   8298  1.1     is 	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
   8299  1.1     is 	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
   8300  1.1     is 	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
   8301  1.1     is 	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
   8302  1.1     is 	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
   8303  1.1     is 	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
   8304  1.1     is 	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
   8305  1.1     is 	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
   8306  1.1     is 	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
   8307  1.1     is 	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
   8308  1.1     is 	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
   8309  1.1     is 	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
   8310  1.1     is 	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
   8311  1.1     is 	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
   8312  1.1     is 
   8313  1.1     is 	set		ADJK,L_SCR1
   8314  1.1     is 
   8315  1.1     is 	set		X,FP_SCR0
   8316  1.1     is 	set		XDCARE,X+2
   8317  1.1     is 	set		XFRAC,X+4
   8318  1.1     is 
   8319  1.1     is 	set		F,FP_SCR1
   8320  1.1     is 	set		FFRAC,F+4
   8321  1.1     is 
   8322  1.1     is 	set		KLOG2,FP_SCR0
   8323  1.1     is 
   8324  1.1     is 	set		SAVEU,FP_SCR0
   8325  1.1     is 
   8326  1.1     is 	global		slogn
   8327  1.1     is #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
   8328  1.1     is slogn:
   8329  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8330  1.1     is 	mov.l		&0x00000000,ADJK(%a6)
   8331  1.1     is 
   8332  1.1     is LOGBGN:
   8333  1.1     is #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
   8334  1.1     is #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
   8335  1.1     is 
   8336  1.1     is 	mov.l		(%a0),%d1
   8337  1.1     is 	mov.w		4(%a0),%d1
   8338  1.1     is 
   8339  1.1     is 	mov.l		(%a0),X(%a6)
   8340  1.1     is 	mov.l		4(%a0),X+4(%a6)
   8341  1.1     is 	mov.l		8(%a0),X+8(%a6)
   8342  1.1     is 
   8343  1.1     is 	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
   8344  1.1     is 	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
   8345  1.1     is # X IS POSITIVE, CHECK IF X IS NEAR 1
   8346  1.1     is 	cmp.l		%d1,&0x3ffef07d 	# IS X < 15/16?
   8347  1.1     is 	blt.b		LOGMAIN			# YES
   8348  1.1     is 	cmp.l		%d1,&0x3fff8841 	# IS X > 17/16?
   8349  1.1     is 	ble.w		LOGNEAR1		# NO
   8350  1.1     is 
   8351  1.1     is LOGMAIN:
   8352  1.1     is #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
   8353  1.1     is 
   8354  1.1     is #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
   8355  1.1     is #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
   8356  1.1     is #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
   8357  1.1     is #--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
   8358  1.1     is #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
   8359  1.1     is #--LOG(1+U) CAN BE VERY EFFICIENT.
   8360  1.1     is #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
   8361  1.1     is #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
   8362  1.1     is 
   8363  1.1     is #--GET K, Y, F, AND ADDRESS OF 1/F.
   8364  1.1     is 	asr.l		&8,%d1
   8365  1.1     is 	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
   8366  1.1     is 	sub.l		&0x3FFF,%d1		# THIS IS K
   8367  1.1     is 	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
   8368  1.1     is 	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
   8369  1.1     is 	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
   8370  1.1     is 
   8371  1.1     is #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
   8372  1.1     is 	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
   8373  1.1     is 	mov.l		XFRAC(%a6),FFRAC(%a6)
   8374  1.1     is 	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
   8375  1.1     is 	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
   8376  1.1     is 	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
   8377  1.1     is 	and.l		&0x7E000000,%d1
   8378  1.1     is 	asr.l		&8,%d1
   8379  1.1     is 	asr.l		&8,%d1
   8380  1.1     is 	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
   8381  1.1     is 	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
   8382  1.1     is 
   8383  1.1     is 	fmov.x		X(%a6),%fp0
   8384  1.1     is 	mov.l		&0x3fff0000,F(%a6)
   8385  1.1     is 	clr.l		F+8(%a6)
   8386  1.1     is 	fsub.x		F(%a6),%fp0		# Y-F
   8387  1.1     is 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
   8388  1.1     is #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
   8389  1.1     is #--REGISTERS SAVED: FPCR, FP1, FP2
   8390  1.1     is 
   8391  1.1     is LP1CONT1:
   8392  1.1     is #--AN RE-ENTRY POINT FOR LOGNP1
   8393  1.1     is 	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
   8394  1.1     is 	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
   8395  1.1     is 	fmov.x		%fp0,%fp2
   8396  1.1     is 	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
   8397  1.1     is 	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
   8398  1.1     is 
   8399  1.1     is #--LOG(1+U) IS APPROXIMATED BY
   8400  1.1     is #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
   8401  1.1     is #--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
   8402  1.1     is 
   8403  1.1     is 	fmov.x		%fp2,%fp3
   8404  1.1     is 	fmov.x		%fp2,%fp1
   8405  1.1     is 
   8406  1.1     is 	fmul.d		LOGA6(%pc),%fp1		# V*A6
   8407  1.1     is 	fmul.d		LOGA5(%pc),%fp2		# V*A5
   8408  1.1     is 
   8409  1.1     is 	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
   8410  1.1     is 	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
   8411  1.1     is 
   8412  1.1     is 	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
   8413  1.1     is 	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
   8414  1.1     is 
   8415  1.1     is 	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
   8416  1.1     is 	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
   8417  1.1     is 
   8418  1.1     is 	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
   8419  1.1     is 	add.l		&16,%a0			# ADDRESS OF LOG(F)
   8420  1.1     is 	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
   8421  1.1     is 
   8422  1.1     is 	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
   8423  1.1     is 	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
   8424  1.1     is 
   8425  1.1     is 	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
   8426  1.1     is 	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
   8427  1.1     is 	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
   8428  1.1     is 
   8429  1.1     is 	fmov.l		%d0,%fpcr
   8430  1.1     is 	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
   8431  1.1     is 	bra		t_inx2
   8432  1.1     is 
   8433  1.1     is 
   8434  1.1     is LOGNEAR1:
   8435  1.1     is 
   8436  1.1     is # if the input is exactly equal to one, then exit through ld_pzero.
   8437  1.1     is # if these 2 lines weren't here, the correct answer would be returned
   8438  1.1     is # but the INEX2 bit would be set.
   8439  1.1     is 	fcmp.b		%fp0,&0x1		# is it equal to one?
   8440  1.1     is 	fbeq.l		ld_pzero		# yes
   8441  1.1     is 
   8442  1.1     is #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
   8443  1.1     is 	fmov.x		%fp0,%fp1
   8444  1.1     is 	fsub.s		one(%pc),%fp1		# FP1 IS X-1
   8445  1.1     is 	fadd.s		one(%pc),%fp0		# FP0 IS X+1
   8446  1.1     is 	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
   8447  1.1     is #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
   8448  1.1     is #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
   8449  1.1     is 
   8450  1.1     is LP1CONT2:
   8451  1.1     is #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
   8452  1.1     is 	fdiv.x		%fp0,%fp1		# FP1 IS U
   8453  1.1     is 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
   8454  1.1     is #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
   8455  1.1     is #--LET V=U*U, W=V*V, CALCULATE
   8456  1.1     is #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
   8457  1.1     is #--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
   8458  1.1     is 	fmov.x		%fp1,%fp0
   8459  1.1     is 	fmul.x		%fp0,%fp0		# FP0 IS V
   8460  1.1     is 	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
   8461  1.1     is 	fmov.x		%fp0,%fp1
   8462  1.1     is 	fmul.x		%fp1,%fp1		# FP1 IS W
   8463  1.1     is 
   8464  1.1     is 	fmov.d		LOGB5(%pc),%fp3
   8465  1.1     is 	fmov.d		LOGB4(%pc),%fp2
   8466  1.1     is 
   8467  1.1     is 	fmul.x		%fp1,%fp3		# W*B5
   8468  1.1     is 	fmul.x		%fp1,%fp2		# W*B4
   8469  1.1     is 
   8470  1.1     is 	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
   8471  1.1     is 	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
   8472  1.1     is 
   8473  1.1     is 	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
   8474  1.1     is 
   8475  1.1     is 	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
   8476  1.1     is 
   8477  1.1     is 	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
   8478  1.1     is 	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
   8479  1.1     is 
   8480  1.1     is 	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
   8481  1.1     is 	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
   8482  1.1     is 
   8483  1.1     is 	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
   8484  1.1     is 
   8485  1.1     is 	fmov.l		%d0,%fpcr
   8486  1.1     is 	fadd.x		SAVEU(%a6),%fp0
   8487  1.1     is 	bra		t_inx2
   8488  1.1     is 
   8489  1.1     is #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
   8490  1.1     is LOGNEG:
   8491  1.1     is 	bra		t_operr
   8492  1.1     is 
   8493  1.1     is 	global		slognd
   8494  1.1     is slognd:
   8495  1.1     is #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
   8496  1.1     is 
   8497  1.1     is 	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
   8498  1.1     is 
   8499  1.1     is #----normalize the input value by left shifting k bits (k to be determined
   8500  1.1     is #----below), adjusting exponent and storing -k to  ADJK
   8501  1.1     is #----the value TWOTO100 is no longer needed.
   8502  1.1     is #----Note that this code assumes the denormalized input is NON-ZERO.
   8503  1.1     is 
   8504  1.1     is 	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
   8505  1.1     is 	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
   8506  1.1     is 	mov.l		4(%a0),%d4
   8507  1.1     is 	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
   8508  1.1     is 	clr.l		%d2			# D2 used for holding K
   8509  1.1     is 
   8510  1.1     is 	tst.l		%d4
   8511  1.1     is 	bne.b		Hi_not0
   8512  1.1     is 
   8513  1.1     is Hi_0:
   8514  1.1     is 	mov.l		%d5,%d4
   8515  1.1     is 	clr.l		%d5
   8516  1.1     is 	mov.l		&32,%d2
   8517  1.1     is 	clr.l		%d6
   8518  1.1     is 	bfffo		%d4{&0:&32},%d6
   8519  1.1     is 	lsl.l		%d6,%d4
   8520  1.1     is 	add.l		%d6,%d2			# (D3,D4,D5) is normalized
   8521  1.1     is 
   8522  1.1     is 	mov.l		%d3,X(%a6)
   8523  1.1     is 	mov.l		%d4,XFRAC(%a6)
   8524  1.1     is 	mov.l		%d5,XFRAC+4(%a6)
   8525  1.1     is 	neg.l		%d2
   8526  1.1     is 	mov.l		%d2,ADJK(%a6)
   8527  1.1     is 	fmov.x		X(%a6),%fp0
   8528  1.1     is 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
   8529  1.1     is 	lea		X(%a6),%a0
   8530  1.1     is 	bra.w		LOGBGN			# begin regular log(X)
   8531  1.1     is 
   8532  1.1     is Hi_not0:
   8533  1.1     is 	clr.l		%d6
   8534  1.1     is 	bfffo		%d4{&0:&32},%d6		# find first 1
   8535  1.1     is 	mov.l		%d6,%d2			# get k
   8536  1.1     is 	lsl.l		%d6,%d4
   8537  1.1     is 	mov.l		%d5,%d7			# a copy of D5
   8538  1.1     is 	lsl.l		%d6,%d5
   8539  1.1     is 	neg.l		%d6
   8540  1.1     is 	add.l		&32,%d6
   8541  1.1     is 	lsr.l		%d6,%d7
   8542  1.1     is 	or.l		%d7,%d4			# (D3,D4,D5) normalized
   8543  1.1     is 
   8544  1.1     is 	mov.l		%d3,X(%a6)
   8545  1.1     is 	mov.l		%d4,XFRAC(%a6)
   8546  1.1     is 	mov.l		%d5,XFRAC+4(%a6)
   8547  1.1     is 	neg.l		%d2
   8548  1.1     is 	mov.l		%d2,ADJK(%a6)
   8549  1.1     is 	fmov.x		X(%a6),%fp0
   8550  1.1     is 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
   8551  1.1     is 	lea		X(%a6),%a0
   8552  1.1     is 	bra.w		LOGBGN			# begin regular log(X)
   8553  1.1     is 
   8554  1.1     is 	global		slognp1
   8555  1.1     is #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
   8556  1.1     is slognp1:
   8557  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8558  1.1     is 	fabs.x		%fp0			# test magnitude
   8559  1.1     is 	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
   8560  1.1     is 	fbgt.w		LP1REAL			# if greater, continue
   8561  1.1     is 	fmov.l		%d0,%fpcr
   8562  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   8563  1.1     is 	fmov.x		(%a0),%fp0		# return signed argument
   8564  1.1     is 	bra		t_catch
   8565  1.1     is 
   8566  1.1     is LP1REAL:
   8567  1.1     is 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8568  1.1     is 	mov.l		&0x00000000,ADJK(%a6)
   8569  1.1     is 	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
   8570  1.1     is 	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
   8571  1.1     is 	fmov.x		%fp0,X(%a6)
   8572  1.1     is 	mov.w		XFRAC(%a6),XDCARE(%a6)
   8573  1.1     is 	mov.l		X(%a6),%d1
   8574  1.1     is 	cmp.l		%d1,&0
   8575  1.1     is 	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
   8576  1.1     is 	cmp.l		%d1,&0x3ffe8000 	# IS BOUNDS [1/2,3/2]?
   8577  1.1     is 	blt.w		LOGMAIN
   8578  1.1     is 	cmp.l		%d1,&0x3fffc000
   8579  1.1     is 	bgt.w		LOGMAIN
   8580  1.1     is #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
   8581  1.1     is #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
   8582  1.1     is #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
   8583  1.1     is 
   8584  1.1     is LP1NEAR1:
   8585  1.1     is #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
   8586  1.1     is 	cmp.l		%d1,&0x3ffef07d
   8587  1.1     is 	blt.w		LP1CARE
   8588  1.1     is 	cmp.l		%d1,&0x3fff8841
   8589  1.1     is 	bgt.w		LP1CARE
   8590  1.1     is 
   8591  1.1     is LP1ONE16:
   8592  1.1     is #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
   8593  1.1     is #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
   8594  1.1     is 	fadd.x		%fp1,%fp1		# FP1 IS 2Z
   8595  1.1     is 	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
   8596  1.1     is #--U = FP1/FP0
   8597  1.1     is 	bra.w		LP1CONT2
   8598  1.1     is 
   8599  1.1     is LP1CARE:
   8600  1.1     is #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
   8601  1.1     is #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
   8602  1.1     is #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
   8603  1.1     is #--THERE ARE ONLY TWO CASES.
   8604  1.1     is #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
   8605  1.1     is #--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
   8606  1.1     is #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
   8607  1.1     is #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
   8608  1.1     is 
   8609  1.1     is 	mov.l		XFRAC(%a6),FFRAC(%a6)
   8610  1.1     is 	and.l		&0xFE000000,FFRAC(%a6)
   8611  1.1     is 	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
   8612  1.1     is 	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
   8613  1.1     is 	bge.b		KISZERO
   8614  1.1     is 
   8615  1.1     is KISNEG1:
   8616  1.1     is 	fmov.s		TWO(%pc),%fp0
   8617  1.1     is 	mov.l		&0x3fff0000,F(%a6)
   8618  1.1     is 	clr.l		F+8(%a6)
   8619  1.1     is 	fsub.x		F(%a6),%fp0		# 2-F
   8620  1.1     is 	mov.l		FFRAC(%a6),%d1
   8621  1.1     is 	and.l		&0x7E000000,%d1
   8622  1.1     is 	asr.l		&8,%d1
   8623  1.1     is 	asr.l		&8,%d1
   8624  1.1     is 	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
   8625  1.1     is 	fadd.x		%fp1,%fp1		# GET 2Z
   8626  1.1     is 	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
   8627  1.1     is 	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
   8628  1.1     is 	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
   8629  1.1     is 	add.l		%d1,%a0
   8630  1.1     is 	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
   8631  1.1     is 	bra.w		LP1CONT1
   8632  1.1     is 
   8633  1.1     is KISZERO:
   8634  1.1     is 	fmov.s		one(%pc),%fp0
   8635  1.1     is 	mov.l		&0x3fff0000,F(%a6)
   8636  1.1     is 	clr.l		F+8(%a6)
   8637  1.1     is 	fsub.x		F(%a6),%fp0		# 1-F
   8638  1.1     is 	mov.l		FFRAC(%a6),%d1
   8639  1.1     is 	and.l		&0x7E000000,%d1
   8640  1.1     is 	asr.l		&8,%d1
   8641  1.1     is 	asr.l		&8,%d1
   8642  1.1     is 	asr.l		&4,%d1
   8643  1.1     is 	fadd.x		%fp1,%fp0		# FP0 IS Y-F
   8644  1.1     is 	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
   8645  1.1     is 	lea		LOGTBL(%pc),%a0
   8646  1.1     is 	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
   8647  1.1     is 	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
   8648  1.1     is 	bra.w		LP1CONT1
   8649  1.1     is 
   8650  1.1     is LP1NEG0:
   8651  1.1     is #--FPCR SAVED. D0 IS X IN COMPACT FORM.
   8652  1.1     is 	cmp.l		%d1,&0
   8653  1.1     is 	blt.b		LP1NEG
   8654  1.1     is LP1ZERO:
   8655  1.1     is 	fmov.s		negone(%pc),%fp0
   8656  1.1     is 
   8657  1.1     is 	fmov.l		%d0,%fpcr
   8658  1.1     is 	bra		t_dz
   8659  1.1     is 
   8660  1.1     is LP1NEG:
   8661  1.1     is 	fmov.s		zero(%pc),%fp0
   8662  1.1     is 
   8663  1.1     is 	fmov.l		%d0,%fpcr
   8664  1.1     is 	bra		t_operr
   8665  1.1     is 
   8666  1.1     is 	global		slognp1d
   8667  1.1     is #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
   8668  1.1     is # Simply return the denorm
   8669  1.1     is slognp1d:
   8670  1.1     is 	bra		t_extdnrm
   8671  1.1     is 
   8672  1.1     is #########################################################################
   8673  1.1     is # satanh():  computes the inverse hyperbolic tangent of a norm input	#
   8674  1.1     is # satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
   8675  1.1     is #									#
   8676  1.1     is # INPUT ***************************************************************	#
   8677  1.1     is #	a0 = pointer to extended precision input			#
   8678  1.1     is #	d0 = round precision,mode					#
   8679  1.1     is #									#
   8680  1.1     is # OUTPUT **************************************************************	#
   8681  1.1     is #	fp0 = arctanh(X)						#
   8682  1.1     is #									#
   8683  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   8684  1.1     is #	The returned result is within 3 ulps in	64 significant bit,	#
   8685  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8686  1.1     is #	rounded to double precision. The result is provably monotonic	#
   8687  1.1     is #	in double precision.						#
   8688  1.1     is #									#
   8689  1.1     is # ALGORITHM ***********************************************************	#
   8690  1.1     is #									#
   8691  1.1     is #	ATANH								#
   8692  1.1     is #	1. If |X| >= 1, go to 3.					#
   8693  1.1     is #									#
   8694  1.1     is #	2. (|X| < 1) Calculate atanh(X) by				#
   8695  1.1     is #		sgn := sign(X)						#
   8696  1.1     is #		y := |X|						#
   8697  1.1     is #		z := 2y/(1-y)						#
   8698  1.1     is #		atanh(X) := sgn * (1/2) * logp1(z)			#
   8699  1.1     is #		Exit.							#
   8700  1.1     is #									#
   8701  1.1     is #	3. If |X| > 1, go to 5.						#
   8702  1.1     is #									#
   8703  1.1     is #	4. (|X| = 1) Generate infinity with an appropriate sign and	#
   8704  1.1     is #		divide-by-zero by					#
   8705  1.1     is #		sgn := sign(X)						#
   8706  1.1     is #		atan(X) := sgn / (+0).					#
   8707  1.1     is #		Exit.							#
   8708  1.1     is #									#
   8709  1.1     is #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   8710  1.1     is #		Exit.							#
   8711  1.1     is #									#
   8712  1.1     is #########################################################################
   8713  1.1     is 
   8714  1.1     is 	global		satanh
   8715  1.1     is satanh:
   8716  1.1     is 	mov.l		(%a0),%d1
   8717  1.1     is 	mov.w		4(%a0),%d1
   8718  1.1     is 	and.l		&0x7FFFFFFF,%d1
   8719  1.1     is 	cmp.l		%d1,&0x3FFF8000
   8720  1.1     is 	bge.b		ATANHBIG
   8721  1.1     is 
   8722  1.1     is #--THIS IS THE USUAL CASE, |X| < 1
   8723  1.1     is #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
   8724  1.1     is 
   8725  1.1     is 	fabs.x		(%a0),%fp0		# Y = |X|
   8726  1.1     is 	fmov.x		%fp0,%fp1
   8727  1.1     is 	fneg.x		%fp1			# -Y
   8728  1.1     is 	fadd.x		%fp0,%fp0		# 2Y
   8729  1.1     is 	fadd.s		&0x3F800000,%fp1	# 1-Y
   8730  1.1     is 	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
   8731  1.1     is 	mov.l		(%a0),%d1
   8732  1.1     is 	and.l		&0x80000000,%d1
   8733  1.1     is 	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
   8734  1.1     is 	mov.l		%d1,-(%sp)
   8735  1.1     is 
   8736  1.1     is 	mov.l		%d0,-(%sp)		# save rnd prec,mode
   8737  1.1     is 	clr.l		%d0			# pass ext prec,RN
   8738  1.1     is 	fmovm.x		&0x01,-(%sp)		# save Z on stack
   8739  1.1     is 	lea		(%sp),%a0		# pass ptr to Z
   8740  1.1     is 	bsr		slognp1			# LOG1P(Z)
   8741  1.1     is 	add.l		&0xc,%sp		# clear Z from stack
   8742  1.1     is 
   8743  1.1     is 	mov.l		(%sp)+,%d0		# fetch old prec,mode
   8744  1.1     is 	fmov.l		%d0,%fpcr		# load it
   8745  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   8746  1.1     is 	fmul.s		(%sp)+,%fp0
   8747  1.1     is 	bra		t_catch
   8748  1.1     is 
   8749  1.1     is ATANHBIG:
   8750  1.1     is 	fabs.x		(%a0),%fp0		# |X|
   8751  1.1     is 	fcmp.s		%fp0,&0x3F800000
   8752  1.1     is 	fbgt		t_operr
   8753  1.1     is 	bra		t_dz
   8754  1.1     is 
   8755  1.1     is 	global		satanhd
   8756  1.1     is #--ATANH(X) = X FOR DENORMALIZED X
   8757  1.1     is satanhd:
   8758  1.1     is 	bra		t_extdnrm
   8759  1.1     is 
   8760  1.1     is #########################################################################
   8761  1.1     is # slog10():  computes the base-10 logarithm of a normalized input	#
   8762  1.1     is # slog10d(): computes the base-10 logarithm of a denormalized input	#
   8763  1.1     is # slog2():   computes the base-2 logarithm of a normalized input	#
   8764  1.1     is # slog2d():  computes the base-2 logarithm of a denormalized input	#
   8765  1.1     is #									#
   8766  1.1     is # INPUT *************************************************************** #
   8767  1.1     is #	a0 = pointer to extended precision input			#
   8768  1.1     is #	d0 = round precision,mode					#
   8769  1.1     is #									#
   8770  1.1     is # OUTPUT **************************************************************	#
   8771  1.1     is #	fp0 = log_10(X) or log_2(X)					#
   8772  1.1     is #									#
   8773  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   8774  1.1     is #	The returned result is within 1.7 ulps in 64 significant bit,	#
   8775  1.1     is #	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
   8776  1.1     is #	rounded to double precision. The result is provably monotonic	#
   8777  1.1     is #	in double precision.						#
   8778  1.1     is #									#
   8779  1.1     is # ALGORITHM ***********************************************************	#
   8780  1.1     is #									#
   8781  1.1     is #       slog10d:							#
   8782  1.1     is #									#
   8783  1.1     is #       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
   8784  1.1     is #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8785  1.1     is #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8786  1.1     is #               traps, and precision control = double extended.		#
   8787  1.1     is #									#
   8788  1.1     is #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
   8789  1.1     is #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
   8790  1.1     is #									#
   8791  1.1     is #       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
   8792  1.1     is #            2.1 Restore the user FPCR					#
   8793  1.1     is #            2.2 Return ans := Y * INV_L10.				#
   8794  1.1     is #									#
   8795  1.1     is #       slog10: 							#
   8796  1.1     is #									#
   8797  1.1     is #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8798  1.1     is #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8799  1.1     is #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8800  1.1     is #               traps, and precision control = double extended.		#
   8801  1.1     is #									#
   8802  1.1     is #       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
   8803  1.1     is #									#
   8804  1.1     is #       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
   8805  1.1     is #            2.1  Restore the user FPCR					#
   8806  1.1     is #            2.2  Return ans := Y * INV_L10.				#
   8807  1.1     is #									#
   8808  1.1     is #       sLog2d:								#
   8809  1.1     is #									#
   8810  1.1     is #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8811  1.1     is #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8812  1.1     is #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8813  1.1     is #               traps, and precision control = double extended.		#
   8814  1.1     is #									#
   8815  1.1     is #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
   8816  1.1     is #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
   8817  1.1     is #									#
   8818  1.1     is #       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
   8819  1.1     is #            2.1  Restore the user FPCR					#
   8820  1.1     is #            2.2  Return ans := Y * INV_L2.				#
   8821  1.1     is #									#
   8822  1.1     is #       sLog2:								#
   8823  1.1     is #									#
   8824  1.1     is #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8825  1.1     is #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8826  1.1     is #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8827  1.1     is #               traps, and precision control = double extended.		#
   8828  1.1     is #									#
   8829  1.1     is #       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
   8830  1.1     is #               go to Step 3.						#
   8831  1.1     is #									#
   8832  1.1     is #       Step 2.   Return k.						#
   8833  1.1     is #            2.1  Get integer k, X = 2^k.				#
   8834  1.1     is #            2.2  Restore the user FPCR.				#
   8835  1.1     is #            2.3  Return ans := convert-to-double-extended(k).		#
   8836  1.1     is #									#
   8837  1.1     is #       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
   8838  1.1     is #									#
   8839  1.1     is #       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
   8840  1.1     is #            4.1  Restore the user FPCR					#
   8841  1.1     is #            4.2  Return ans := Y * INV_L2.				#
   8842  1.1     is #									#
   8843  1.1     is #########################################################################
   8844  1.1     is 
   8845  1.1     is INV_L10:
   8846  1.1     is 	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
   8847  1.1     is 
   8848  1.1     is INV_L2:
   8849  1.1     is 	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
   8850  1.1     is 
   8851  1.1     is 	global		slog10
   8852  1.1     is #--entry point for Log10(X), X is normalized
   8853  1.1     is slog10:
   8854  1.1     is 	fmov.b		&0x1,%fp0
   8855  1.1     is 	fcmp.x		%fp0,(%a0)		# if operand == 1,
   8856  1.1     is 	fbeq.l		ld_pzero		# return an EXACT zero
   8857  1.1     is 
   8858  1.1     is 	mov.l		(%a0),%d1
   8859  1.1     is 	blt.w		invalid
   8860  1.1     is 	mov.l		%d0,-(%sp)
   8861  1.1     is 	clr.l		%d0
   8862  1.1     is 	bsr		slogn			# log(X), X normal.
   8863  1.1     is 	fmov.l		(%sp)+,%fpcr
   8864  1.1     is 	fmul.x		INV_L10(%pc),%fp0
   8865  1.1     is 	bra		t_inx2
   8866  1.1     is 
   8867  1.1     is 	global		slog10d
   8868  1.1     is #--entry point for Log10(X), X is denormalized
   8869  1.1     is slog10d:
   8870  1.1     is 	mov.l		(%a0),%d1
   8871  1.1     is 	blt.w		invalid
   8872  1.1     is 	mov.l		%d0,-(%sp)
   8873  1.1     is 	clr.l		%d0
   8874  1.1     is 	bsr		slognd			# log(X), X denorm.
   8875  1.1     is 	fmov.l		(%sp)+,%fpcr
   8876  1.1     is 	fmul.x		INV_L10(%pc),%fp0
   8877  1.1     is 	bra		t_minx2
   8878  1.1     is 
   8879  1.1     is 	global		slog2
   8880  1.1     is #--entry point for Log2(X), X is normalized
   8881  1.1     is slog2:
   8882  1.1     is 	mov.l		(%a0),%d1
   8883  1.1     is 	blt.w		invalid
   8884  1.1     is 
   8885  1.1     is 	mov.l		8(%a0),%d1
   8886  1.1     is 	bne.b		continue		# X is not 2^k
   8887  1.1     is 
   8888  1.1     is 	mov.l		4(%a0),%d1
   8889  1.1     is 	and.l		&0x7FFFFFFF,%d1
   8890  1.1     is 	bne.b		continue
   8891  1.1     is 
   8892  1.1     is #--X = 2^k.
   8893  1.1     is 	mov.w		(%a0),%d1
   8894  1.1     is 	and.l		&0x00007FFF,%d1
   8895  1.1     is 	sub.l		&0x3FFF,%d1
   8896  1.1     is 	beq.l		ld_pzero
   8897  1.1     is 	fmov.l		%d0,%fpcr
   8898  1.1     is 	fmov.l		%d1,%fp0
   8899  1.1     is 	bra		t_inx2
   8900  1.1     is 
   8901  1.1     is continue:
   8902  1.1     is 	mov.l		%d0,-(%sp)
   8903  1.1     is 	clr.l		%d0
   8904  1.1     is 	bsr		slogn			# log(X), X normal.
   8905  1.1     is 	fmov.l		(%sp)+,%fpcr
   8906  1.1     is 	fmul.x		INV_L2(%pc),%fp0
   8907  1.1     is 	bra		t_inx2
   8908  1.1     is 
   8909  1.1     is invalid:
   8910  1.1     is 	bra		t_operr
   8911  1.1     is 
   8912  1.1     is 	global		slog2d
   8913  1.1     is #--entry point for Log2(X), X is denormalized
   8914  1.1     is slog2d:
   8915  1.1     is 	mov.l		(%a0),%d1
   8916  1.1     is 	blt.w		invalid
   8917  1.1     is 	mov.l		%d0,-(%sp)
   8918  1.1     is 	clr.l		%d0
   8919  1.1     is 	bsr		slognd			# log(X), X denorm.
   8920  1.1     is 	fmov.l		(%sp)+,%fpcr
   8921  1.1     is 	fmul.x		INV_L2(%pc),%fp0
   8922  1.1     is 	bra		t_minx2
   8923  1.1     is 
   8924  1.1     is #########################################################################
   8925  1.1     is # stwotox():  computes 2**X for a normalized input			#
   8926  1.1     is # stwotoxd(): computes 2**X for a denormalized input			#
   8927  1.1     is # stentox():  computes 10**X for a normalized input			#
   8928  1.1     is # stentoxd(): computes 10**X for a denormalized input			#
   8929  1.1     is #									#
   8930  1.1     is # INPUT ***************************************************************	#
   8931  1.1     is #	a0 = pointer to extended precision input			#
   8932  1.1     is #	d0 = round precision,mode					#
   8933  1.1     is #									#
   8934  1.1     is # OUTPUT **************************************************************	#
   8935  1.1     is #	fp0 = 2**X or 10**X						#
   8936  1.1     is #									#
   8937  1.1     is # ACCURACY and MONOTONICITY *******************************************	#
   8938  1.1     is #	The returned result is within 2 ulps in 64 significant bit, 	#
   8939  1.1     is #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8940  1.1     is #	rounded to double precision. The result is provably monotonic	#
   8941  1.1     is #	in double precision.						#
   8942  1.1     is #									#
   8943  1.1     is # ALGORITHM ***********************************************************	#
   8944  1.1     is #									#
   8945  1.1     is #	twotox								#
   8946  1.1     is #	1. If |X| > 16480, go to ExpBig.				#
   8947  1.1     is #									#
   8948  1.1     is #	2. If |X| < 2**(-70), go to ExpSm.				#
   8949  1.1     is #									#
   8950  1.1     is #	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
   8951  1.1     is #		decompose N as						#
   8952  1.1     is #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
   8953  1.1     is #									#
   8954  1.1     is #	4. Overwrite r := r * log2. Then				#
   8955  1.1     is #		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
   8956  1.1     is #		Go to expr to compute that expression.			#
   8957  1.1     is #									#
   8958  1.1     is #	tentox								#
   8959  1.1     is #	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
   8960  1.1     is #									#
   8961  1.1     is #	2. If |X| < 2**(-70), go to ExpSm.				#
   8962  1.1     is #									#
   8963  1.1     is #	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
   8964  1.1     is #		N := round-to-int(y). Decompose N as			#
   8965  1.1     is #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
   8966  1.1     is #									#
   8967  1.1     is #	4. Define r as							#
   8968  1.1     is #		r := ((X - N*L1)-N*L2) * L10				#
   8969  1.1     is #		where L1, L2 are the leading and trailing parts of 	#
   8970  1.1     is #		log_10(2)/64 and L10 is the natural log of 10. Then	#
   8971  1.1     is #		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
   8972  1.1     is #		Go to expr to compute that expression.			#
   8973  1.1     is #									#
   8974  1.1     is #	expr								#
   8975  1.1     is #	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
   8976  1.1     is #									#
   8977  1.1     is #	2. Overwrite Fact1 and Fact2 by					#
   8978  1.1     is #		Fact1 := 2**(M) * Fact1					#
   8979  1.1     is #		Fact2 := 2**(M) * Fact2					#
   8980  1.1     is #		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
   8981  1.1     is #									#
   8982  1.1     is #	3. Calculate P where 1 + P approximates exp(r):			#
   8983  1.1     is #		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
   8984  1.1     is #									#
   8985  1.1     is #	4. Let AdjFact := 2**(M'). Return				#
   8986  1.1     is #		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
   8987  1.1     is #		Exit.							#
   8988  1.1     is #									#
   8989  1.1     is #	ExpBig								#
   8990  1.1     is #	1. Generate overflow by Huge * Huge if X > 0; otherwise, 	#
   8991  1.1     is #	        generate underflow by Tiny * Tiny.			#
   8992  1.1     is #									#
   8993  1.1     is #	ExpSm								#
   8994  1.1     is #	1. Return 1 + X.						#
   8995  1.1     is #									#
   8996  1.1     is #########################################################################
   8997  1.1     is 
   8998  1.1     is L2TEN64:
   8999  1.1     is 	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
   9000  1.1     is L10TWO1:
   9001  1.1     is 	long		0x3F734413,0x509F8000	# LOG2/64LOG10
   9002  1.1     is 
   9003  1.1     is L10TWO2:
   9004  1.1     is 	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
   9005  1.1     is 
   9006  1.1     is LOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
   9007  1.1     is 
   9008  1.1     is LOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
   9009  1.1     is 
   9010  1.1     is EXPA5:	long		0x3F56C16D,0x6F7BD0B2
   9011  1.1     is EXPA4:	long		0x3F811112,0x302C712C
   9012  1.1     is EXPA3:	long		0x3FA55555,0x55554CC1
   9013  1.1     is EXPA2:	long		0x3FC55555,0x55554A54
   9014  1.1     is EXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
   9015  1.1     is 
   9016  1.1     is TEXPTBL:
   9017  1.1     is 	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
   9018  1.1     is 	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
   9019  1.1     is 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
   9020  1.1     is 	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
   9021  1.1     is 	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
   9022  1.1     is 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
   9023  1.1     is 	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
   9024  1.1     is 	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
   9025  1.1     is 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
   9026  1.1     is 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
   9027  1.1     is 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
   9028  1.1     is 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
   9029  1.1     is 	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
   9030  1.1     is 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
   9031  1.1     is 	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
   9032  1.1     is 	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
   9033  1.1     is 	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
   9034  1.1     is 	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
   9035  1.1     is 	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
   9036  1.1     is 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
   9037  1.1     is 	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
   9038  1.1     is 	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
   9039  1.1     is 	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
   9040  1.1     is 	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
   9041  1.1     is 	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
   9042  1.1     is 	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
   9043  1.1     is 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
   9044  1.1     is 	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
   9045  1.1     is 	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
   9046  1.1     is 	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
   9047  1.1     is 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
   9048  1.1     is 	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
   9049  1.1     is 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
   9050  1.1     is 	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
   9051  1.1     is 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
   9052  1.1     is 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
   9053  1.1     is 	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
   9054  1.1     is 	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
   9055  1.1     is 	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
   9056  1.1     is 	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
   9057  1.1     is 	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
   9058  1.1     is 	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
   9059  1.1     is 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
   9060  1.1     is 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
   9061  1.1     is 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
   9062  1.1     is 	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
   9063  1.1     is 	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
   9064  1.1     is 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
   9065  1.1     is 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
   9066  1.1     is 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
   9067  1.1     is 	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
   9068  1.1     is 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
   9069  1.1     is 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
   9070  1.1     is 	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
   9071  1.1     is 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
   9072  1.1     is 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
   9073  1.1     is 	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
   9074  1.1     is 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
   9075  1.1     is 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
   9076  1.1     is 	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
   9077  1.1     is 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
   9078  1.1     is 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
   9079  1.1     is 	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
   9080  1.1     is 	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
   9081  1.1     is 
   9082  1.1     is 	set		INT,L_SCR1
   9083  1.1     is 
   9084  1.1     is 	set		X,FP_SCR0
   9085  1.1     is 	set		XDCARE,X+2
   9086  1.1     is 	set		XFRAC,X+4
   9087  1.1     is 
   9088  1.1     is 	set		ADJFACT,FP_SCR0
   9089  1.1     is 
   9090  1.1     is 	set		FACT1,FP_SCR0
   9091  1.1     is 	set		FACT1HI,FACT1+4
   9092  1.1     is 	set		FACT1LOW,FACT1+8
   9093  1.1     is 
   9094  1.1     is 	set		FACT2,FP_SCR1
   9095  1.1     is 	set		FACT2HI,FACT2+4
   9096  1.1     is 	set		FACT2LOW,FACT2+8
   9097  1.1     is 
   9098  1.1     is 	global		stwotox
   9099  1.1     is #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   9100  1.1     is stwotox:
   9101  1.1     is 	fmovm.x		(%a0),&0x80		# LOAD INPUT
   9102  1.1     is 
   9103  1.1     is 	mov.l		(%a0),%d1
   9104  1.1     is 	mov.w		4(%a0),%d1
   9105  1.1     is 	fmov.x		%fp0,X(%a6)
   9106  1.1     is 	and.l		&0x7FFFFFFF,%d1
   9107  1.1     is 
   9108  1.1     is 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
   9109  1.1     is 	bge.b		TWOOK1
   9110  1.1     is 	bra.w		EXPBORS
   9111  1.1     is 
   9112  1.1     is TWOOK1:
   9113  1.1     is 	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
   9114  1.1     is 	ble.b		TWOMAIN
   9115  1.1     is 	bra.w		EXPBORS
   9116  1.1     is 
   9117  1.1     is TWOMAIN:
   9118  1.1     is #--USUAL CASE, 2^(-70) <= |X| <= 16480
   9119  1.1     is 
   9120  1.1     is 	fmov.x		%fp0,%fp1
   9121  1.1     is 	fmul.s		&0x42800000,%fp1	# 64 * X
   9122  1.1     is 	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
   9123  1.1     is 	mov.l		%d2,-(%sp)
   9124  1.1     is 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
   9125  1.1     is 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
   9126  1.1     is 	mov.l		INT(%a6),%d1
   9127  1.1     is 	mov.l		%d1,%d2
   9128  1.1     is 	and.l		&0x3F,%d1		# D0 IS J
   9129  1.1     is 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
   9130  1.1     is 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
   9131  1.1     is 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
   9132  1.1     is 	mov.l		%d2,%d1
   9133  1.1     is 	asr.l		&1,%d1			# D0 IS M
   9134  1.1     is 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
   9135  1.1     is 	add.l		&0x3FFF,%d2
   9136  1.1     is 
   9137  1.1     is #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
   9138  1.1     is #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
   9139  1.1     is #--ADJFACT = 2^(M').
   9140  1.1     is #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
   9141  1.1     is 
   9142  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   9143  1.1     is 
   9144  1.1     is 	fmul.s		&0x3C800000,%fp1	# (1/64)*N
   9145  1.1     is 	mov.l		(%a1)+,FACT1(%a6)
   9146  1.1     is 	mov.l		(%a1)+,FACT1HI(%a6)
   9147  1.1     is 	mov.l		(%a1)+,FACT1LOW(%a6)
   9148  1.1     is 	mov.w		(%a1)+,FACT2(%a6)
   9149  1.1     is 
   9150  1.1     is 	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
   9151  1.1     is 
   9152  1.1     is 	mov.w		(%a1)+,FACT2HI(%a6)
   9153  1.1     is 	clr.w		FACT2HI+2(%a6)
   9154  1.1     is 	clr.l		FACT2LOW(%a6)
   9155  1.1     is 	add.w		%d1,FACT1(%a6)
   9156  1.1     is 	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
   9157  1.1     is 	add.w		%d1,FACT2(%a6)
   9158  1.1     is 
   9159  1.1     is 	bra.w		expr
   9160  1.1     is 
   9161  1.1     is EXPBORS:
   9162  1.1     is #--FPCR, D0 SAVED
   9163  1.1     is 	cmp.l		%d1,&0x3FFF8000
   9164  1.1     is 	bgt.b		TEXPBIG
   9165  1.1     is 
   9166  1.1     is #--|X| IS SMALL, RETURN 1 + X
   9167  1.1     is 
   9168  1.1     is 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   9169  1.1     is 	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
   9170  1.1     is 	bra		t_pinx2
   9171  1.1     is 
   9172  1.1     is TEXPBIG:
   9173  1.1     is #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
   9174  1.1     is #--REGISTERS SAVE SO FAR ARE FPCR AND  D0
   9175  1.1     is 	mov.l		X(%a6),%d1
   9176  1.1     is 	cmp.l		%d1,&0
   9177  1.1     is 	blt.b		EXPNEG
   9178  1.1     is 
   9179  1.1     is 	bra		t_ovfl2			# t_ovfl expects positive value
   9180  1.1     is 
   9181  1.1     is EXPNEG:
   9182  1.1     is 	bra		t_unfl2			# t_unfl expects positive value
   9183  1.1     is 
   9184  1.1     is 	global		stwotoxd
   9185  1.1     is stwotoxd:
   9186  1.1     is #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
   9187  1.1     is 
   9188  1.1     is 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
   9189  1.1     is 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
   9190  1.1     is 	mov.l		(%a0),%d1
   9191  1.1     is 	or.l		&0x00800001,%d1
   9192  1.1     is 	fadd.s		%d1,%fp0
   9193  1.1     is 	bra		t_pinx2
   9194  1.1     is 
   9195  1.1     is 	global		stentox
   9196  1.1     is #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   9197  1.1     is stentox:
   9198  1.1     is 	fmovm.x		(%a0),&0x80		# LOAD INPUT
   9199  1.1     is 
   9200  1.1     is 	mov.l		(%a0),%d1
   9201  1.1     is 	mov.w		4(%a0),%d1
   9202  1.1     is 	fmov.x		%fp0,X(%a6)
   9203  1.1     is 	and.l		&0x7FFFFFFF,%d1
   9204  1.1     is 
   9205  1.1     is 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
   9206  1.1     is 	bge.b		TENOK1
   9207  1.1     is 	bra.w		EXPBORS
   9208  1.1     is 
   9209  1.1     is TENOK1:
   9210  1.1     is 	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
   9211  1.1     is 	ble.b		TENMAIN
   9212  1.1     is 	bra.w		EXPBORS
   9213  1.1     is 
   9214  1.1     is TENMAIN:
   9215  1.1     is #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
   9216  1.1     is 
   9217  1.1     is 	fmov.x		%fp0,%fp1
   9218  1.1     is 	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
   9219  1.1     is 	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
   9220  1.1     is 	mov.l		%d2,-(%sp)
   9221  1.1     is 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
   9222  1.1     is 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
   9223  1.1     is 	mov.l		INT(%a6),%d1
   9224  1.1     is 	mov.l		%d1,%d2
   9225  1.1     is 	and.l		&0x3F,%d1		# D0 IS J
   9226  1.1     is 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
   9227  1.1     is 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
   9228  1.1     is 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
   9229  1.1     is 	mov.l		%d2,%d1
   9230  1.1     is 	asr.l		&1,%d1			# D0 IS M
   9231  1.1     is 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
   9232  1.1     is 	add.l		&0x3FFF,%d2
   9233  1.1     is 
   9234  1.1     is #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
   9235  1.1     is #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
   9236  1.1     is #--ADJFACT = 2^(M').
   9237  1.1     is #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
   9238  1.1     is 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   9239  1.1     is 
   9240  1.1     is 	fmov.x		%fp1,%fp2
   9241  1.1     is 
   9242  1.1     is 	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
   9243  1.1     is 	mov.l		(%a1)+,FACT1(%a6)
   9244  1.1     is 
   9245  1.1     is 	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
   9246  1.1     is 
   9247  1.1     is 	mov.l		(%a1)+,FACT1HI(%a6)
   9248  1.1     is 	mov.l		(%a1)+,FACT1LOW(%a6)
   9249  1.1     is 	fsub.x		%fp1,%fp0		# X - N L_LEAD
   9250  1.1     is 	mov.w		(%a1)+,FACT2(%a6)
   9251  1.1     is 
   9252  1.1     is 	fsub.x		%fp2,%fp0		# X - N L_TRAIL
   9253  1.1     is 
   9254  1.1     is 	mov.w		(%a1)+,FACT2HI(%a6)
   9255  1.1     is 	clr.w		FACT2HI+2(%a6)
   9256  1.1     is 	clr.l		FACT2LOW(%a6)
   9257  1.1     is 
   9258  1.1     is 	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
   9259  1.1     is 	add.w		%d1,FACT1(%a6)
   9260  1.1     is 	add.w		%d1,FACT2(%a6)
   9261  1.1     is 
   9262  1.1     is expr:
   9263  1.1     is #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
   9264  1.1     is #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
   9265  1.1     is #--FP0 IS R. THE FOLLOWING CODE COMPUTES
   9266  1.1     is #--	2**(M'+M) * 2**(J/64) * EXP(R)
   9267  1.1     is 
   9268  1.1     is 	fmov.x		%fp0,%fp1
   9269  1.1     is 	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
   9270  1.1     is 
   9271  1.1     is 	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
   9272  1.1     is 	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
   9273  1.1     is 
   9274  1.1     is 	fmul.x		%fp1,%fp2		# FP2 IS S*A5
   9275  1.1     is 	fmul.x		%fp1,%fp3		# FP3 IS S*A4
   9276  1.1     is 
   9277  1.1     is 	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
   9278  1.1     is 	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
   9279  1.1     is 
   9280  1.1     is 	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
   9281  1.1     is 	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
   9282  1.1     is 
   9283  1.1     is 	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
   9284  1.1     is 	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
   9285  1.1     is 
   9286  1.1     is 	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
   9287  1.1     is 	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
   9288  1.1     is 	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
   9289  1.1     is 
   9290  1.1     is 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   9291  1.1     is 
   9292  1.1     is #--FINAL RECONSTRUCTION PROCESS
   9293  1.1     is #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
   9294  1.1     is 
   9295  1.1     is 	fmul.x		FACT1(%a6),%fp0
   9296  1.1     is 	fadd.x		FACT2(%a6),%fp0
   9297  1.1     is 	fadd.x		FACT1(%a6),%fp0
   9298  1.1     is 
   9299  1.1     is 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   9300  1.1     is 	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
   9301  1.1     is 	mov.l		(%sp)+,%d2
   9302  1.1     is 	mov.l		&0x80000000,ADJFACT+4(%a6)
   9303  1.1     is 	clr.l		ADJFACT+8(%a6)
   9304  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9305  1.1     is 	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
   9306  1.1     is 	bra		t_catch
   9307  1.1     is 
   9308  1.1     is 	global		stentoxd
   9309  1.1     is stentoxd:
   9310  1.1     is #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
   9311  1.1     is 
   9312  1.1     is 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
   9313  1.1     is 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
   9314  1.1     is 	mov.l		(%a0),%d1
   9315  1.1     is 	or.l		&0x00800001,%d1
   9316  1.1     is 	fadd.s		%d1,%fp0
   9317  1.1     is 	bra		t_pinx2
   9318  1.1     is 
   9319  1.1     is #########################################################################
   9320  1.1     is # smovcr(): returns the ROM constant at the offset specified in d1	#
   9321  1.1     is #	    rounded to the mode and precision specified in d0. 		#
   9322  1.1     is #									#
   9323  1.1     is # INPUT	***************************************************************	#
   9324  1.1     is # 	d0 = rnd prec,mode						#
   9325  1.1     is #	d1 = ROM offset							#
   9326  1.1     is #									#
   9327  1.1     is # OUTPUT **************************************************************	#
   9328  1.1     is #	fp0 = the ROM constant rounded to the user's rounding mode,prec	#
   9329  1.1     is #									#
   9330  1.1     is #########################################################################
   9331  1.1     is 
   9332  1.1     is 	global		smovcr
   9333  1.1     is smovcr:
   9334  1.1     is 	mov.l		%d1,-(%sp)		# save rom offset for a sec
   9335  1.1     is 
   9336  1.1     is 	lsr.b		&0x4,%d0		# shift ctrl bits to lo
   9337  1.1     is 	mov.l		%d0,%d1			# make a copy
   9338  1.1     is 	andi.w		&0x3,%d1		# extract rnd mode
   9339  1.1     is 	andi.w		&0xc,%d0		# extract rnd prec
   9340  1.1     is 	swap		%d0			# put rnd prec in hi
   9341  1.1     is 	mov.w		%d1,%d0			# put rnd mode in lo
   9342  1.1     is 
   9343  1.1     is 	mov.l		(%sp)+,%d1		# get rom offset
   9344  1.1     is 
   9345  1.1     is #
   9346  1.1     is # check range of offset
   9347  1.1     is #
   9348  1.1     is 	tst.b		%d1			# if zero, offset is to pi
   9349  1.1     is 	beq.b		pi_tbl			# it is pi
   9350  1.1     is 	cmpi.b		%d1,&0x0a		# check range $01 - $0a
   9351  1.1     is 	ble.b		z_val			# if in this range, return zero
   9352  1.1     is 	cmpi.b		%d1,&0x0e		# check range $0b - $0e
   9353  1.1     is 	ble.b		sm_tbl			# valid constants in this range
   9354  1.1     is 	cmpi.b		%d1,&0x2f		# check range $10 - $2f
   9355  1.1     is 	ble.b		z_val			# if in this range, return zero
   9356  1.1     is 	cmpi.b		%d1,&0x3f		# check range $30 - $3f
   9357  1.1     is 	ble.b		bg_tbl			# valid constants in this range
   9358  1.1     is 
   9359  1.1     is z_val:
   9360  1.1     is 	bra.l		ld_pzero		# return a zero
   9361  1.1     is 
   9362  1.1     is #
   9363  1.1     is # the answer is PI rounded to the proper precision.
   9364  1.1     is #
   9365  1.1     is # fetch a pointer to the answer table relating to the proper rounding
   9366  1.1     is # precision.
   9367  1.1     is #
   9368  1.1     is pi_tbl:
   9369  1.1     is 	tst.b		%d0			# is rmode RN?
   9370  1.1     is 	bne.b		pi_not_rn		# no
   9371  1.1     is pi_rn:
   9372  1.1     is 	lea.l		PIRN(%pc),%a0		# yes; load PI RN table addr
   9373  1.1     is 	bra.w		set_finx
   9374  1.1     is pi_not_rn:
   9375  1.1     is 	cmpi.b		%d0,&rp_mode		# is rmode RP?
   9376  1.1     is 	beq.b		pi_rp			# yes
   9377  1.1     is pi_rzrm:
   9378  1.1     is 	lea.l		PIRZRM(%pc),%a0		# no; load PI RZ,RM table addr
   9379  1.1     is 	bra.b		set_finx
   9380  1.1     is pi_rp:
   9381  1.1     is 	lea.l		PIRP(%pc),%a0		# load PI RP table addr
   9382  1.1     is 	bra.b		set_finx
   9383  1.1     is 
   9384  1.1     is #
   9385  1.1     is # the answer is one of:
   9386  1.1     is #	$0B	log10(2)	(inexact)
   9387  1.1     is #	$0C	e		(inexact)
   9388  1.1     is #	$0D	log2(e)		(inexact)
   9389  1.1     is #	$0E	log10(e)	(exact)
   9390  1.1     is #
   9391  1.1     is # fetch a pointer to the answer table relating to the proper rounding
   9392  1.1     is # precision.
   9393  1.1     is #
   9394  1.1     is sm_tbl:
   9395  1.1     is 	subi.b		&0xb,%d1		# make offset in 0-4 range
   9396  1.1     is 	tst.b		%d0			# is rmode RN?
   9397  1.1     is 	bne.b		sm_not_rn		# no
   9398  1.1     is sm_rn:
   9399  1.1     is 	lea.l		SMALRN(%pc),%a0		# yes; load RN table addr
   9400  1.1     is sm_tbl_cont:
   9401  1.1     is 	cmpi.b		%d1,&0x2		# is result log10(e)?
   9402  1.1     is 	ble.b		set_finx		# no; answer is inexact
   9403  1.1     is 	bra.b		no_finx			# yes; answer is exact
   9404  1.1     is sm_not_rn:
   9405  1.1     is 	cmpi.b		%d0,&rp_mode		# is rmode RP?
   9406  1.1     is 	beq.b		sm_rp			# yes
   9407  1.1     is sm_rzrm:
   9408  1.1     is 	lea.l		SMALRZRM(%pc),%a0	# no; load RZ,RM table addr
   9409  1.1     is 	bra.b		sm_tbl_cont
   9410  1.1     is sm_rp:
   9411  1.1     is 	lea.l		SMALRP(%pc),%a0		# load RP table addr
   9412  1.1     is 	bra.b		sm_tbl_cont
   9413  1.1     is 
   9414  1.1     is #
   9415  1.1     is # the answer is one of:
   9416  1.1     is #	$30	ln(2)		(inexact)
   9417  1.1     is #	$31	ln(10)		(inexact)
   9418  1.1     is #	$32	10^0		(exact)
   9419  1.1     is #	$33	10^1		(exact)
   9420  1.1     is #	$34	10^2		(exact)
   9421  1.1     is #	$35	10^4		(exact)
   9422  1.1     is #	$36	10^8		(exact)
   9423  1.1     is #	$37	10^16		(exact)
   9424  1.1     is #	$38	10^32		(inexact)
   9425  1.1     is #	$39	10^64		(inexact)
   9426  1.1     is #	$3A	10^128		(inexact)
   9427  1.1     is #	$3B	10^256		(inexact)
   9428  1.1     is #	$3C	10^512		(inexact)
   9429  1.1     is #	$3D	10^1024		(inexact)
   9430  1.1     is #	$3E	10^2048		(inexact)
   9431  1.1     is #	$3F	10^4096		(inexact)
   9432  1.1     is #
   9433  1.1     is # fetch a pointer to the answer table relating to the proper rounding
   9434  1.1     is # precision.
   9435  1.1     is #
   9436  1.1     is bg_tbl:
   9437  1.1     is 	subi.b		&0x30,%d1		# make offset in 0-f range
   9438  1.1     is 	tst.b		%d0			# is rmode RN?
   9439  1.1     is 	bne.b		bg_not_rn		# no
   9440  1.1     is bg_rn:
   9441  1.1     is 	lea.l		BIGRN(%pc),%a0		# yes; load RN table addr
   9442  1.1     is bg_tbl_cont:
   9443  1.1     is 	cmpi.b		%d1,&0x1		# is offset <= $31?
   9444  1.1     is 	ble.b		set_finx		# yes; answer is inexact
   9445  1.1     is 	cmpi.b		%d1,&0x7		# is $32 <= offset <= $37?
   9446  1.1     is 	ble.b		no_finx			# yes; answer is exact
   9447  1.1     is 	bra.b		set_finx		# no; answer is inexact
   9448  1.1     is bg_not_rn:
   9449  1.1     is 	cmpi.b		%d0,&rp_mode		# is rmode RP?
   9450  1.1     is 	beq.b		bg_rp			# yes
   9451  1.1     is bg_rzrm:
   9452  1.1     is 	lea.l		BIGRZRM(%pc),%a0	# no; load RZ,RM table addr
   9453  1.1     is 	bra.b		bg_tbl_cont
   9454  1.1     is bg_rp:
   9455  1.1     is 	lea.l		BIGRP(%pc),%a0		# load RP table addr
   9456  1.1     is 	bra.b		bg_tbl_cont
   9457  1.1     is 
   9458  1.1     is # answer is inexact, so set INEX2 and AINEX in the user's FPSR.
   9459  1.1     is set_finx:
   9460  1.1     is 	ori.l		&inx2a_mask,USER_FPSR(%a6) # set INEX2/AINEX
   9461  1.1     is no_finx:
   9462  1.1     is 	mulu.w		&0xc,%d1		# offset points into tables
   9463  1.1     is 	swap		%d0			# put rnd prec in lo word
   9464  1.1     is 	tst.b		%d0			# is precision extended?
   9465  1.1     is 
   9466  1.1     is 	bne.b		not_ext			# if xprec, do not call round
   9467  1.1     is 
   9468  1.1     is # Precision is extended
   9469  1.1     is 	fmovm.x		(%a0,%d1.w),&0x80	# return result in fp0
   9470  1.1     is 	rts
   9471  1.1     is 
   9472  1.1     is # Precision is single or double
   9473  1.1     is not_ext:
   9474  1.1     is 	swap		%d0			# rnd prec in upper word
   9475  1.1     is 
   9476  1.1     is # call round() to round the answer to the proper precision.
   9477  1.1     is # exponents out of range for single or double DO NOT cause underflow
   9478  1.1     is # or overflow.
   9479  1.1     is 	mov.w		0x0(%a0,%d1.w),FP_SCR1_EX(%a6) # load first word
   9480  1.1     is 	mov.l		0x4(%a0,%d1.w),FP_SCR1_HI(%a6) # load second word
   9481  1.1     is 	mov.l		0x8(%a0,%d1.w),FP_SCR1_LO(%a6) # load third word
   9482  1.1     is 	mov.l		%d0,%d1
   9483  1.1     is 	clr.l		%d0			# clear g,r,s
   9484  1.1     is 	lea		FP_SCR1(%a6),%a0	# pass ptr to answer
   9485  1.1     is 	clr.w		LOCAL_SGN(%a0)		# sign always positive
   9486  1.1     is 	bsr.l		_round			# round the mantissa
   9487  1.1     is 
   9488  1.1     is 	fmovm.x		(%a0),&0x80		# return rounded result in fp0
   9489  1.1     is 	rts
   9490  1.1     is 
   9491  1.1     is 	align		0x4
   9492  1.1     is 
   9493  1.1     is PIRN:	long		0x40000000,0xc90fdaa2,0x2168c235	# pi
   9494  1.1     is PIRZRM:	long		0x40000000,0xc90fdaa2,0x2168c234	# pi
   9495  1.1     is PIRP:	long		0x40000000,0xc90fdaa2,0x2168c235	# pi
   9496  1.1     is 
   9497  1.1     is SMALRN:	long		0x3ffd0000,0x9a209a84,0xfbcff798	# log10(2)
   9498  1.1     is 	long		0x40000000,0xadf85458,0xa2bb4a9a	# e
   9499  1.1     is 	long		0x3fff0000,0xb8aa3b29,0x5c17f0bc	# log2(e)
   9500  1.1     is 	long		0x3ffd0000,0xde5bd8a9,0x37287195	# log10(e)
   9501  1.1     is 	long		0x00000000,0x00000000,0x00000000	# 0.0
   9502  1.1     is 
   9503  1.1     is SMALRZRM:
   9504  1.1     is 	long		0x3ffd0000,0x9a209a84,0xfbcff798	# log10(2)
   9505  1.1     is 	long		0x40000000,0xadf85458,0xa2bb4a9a	# e
   9506  1.1     is 	long		0x3fff0000,0xb8aa3b29,0x5c17f0bb	# log2(e)
   9507  1.1     is 	long		0x3ffd0000,0xde5bd8a9,0x37287195	# log10(e)
   9508  1.1     is 	long		0x00000000,0x00000000,0x00000000	# 0.0
   9509  1.1     is 
   9510  1.1     is SMALRP:	long		0x3ffd0000,0x9a209a84,0xfbcff799	# log10(2)
   9511  1.1     is 	long		0x40000000,0xadf85458,0xa2bb4a9b	# e
   9512  1.1     is 	long		0x3fff0000,0xb8aa3b29,0x5c17f0bc	# log2(e)
   9513  1.1     is 	long		0x3ffd0000,0xde5bd8a9,0x37287195	# log10(e)
   9514  1.1     is 	long		0x00000000,0x00000000,0x00000000	# 0.0
   9515  1.1     is 
   9516  1.1     is BIGRN:	long		0x3ffe0000,0xb17217f7,0xd1cf79ac	# ln(2)
   9517  1.1     is 	long		0x40000000,0x935d8ddd,0xaaa8ac17	# ln(10)
   9518  1.1     is 
   9519  1.1     is 	long		0x3fff0000,0x80000000,0x00000000	# 10 ^ 0
   9520  1.1     is 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   9521  1.1     is 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   9522  1.1     is 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   9523  1.1     is 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   9524  1.1     is 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   9525  1.1     is 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   9526  1.1     is 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   9527  1.1     is 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   9528  1.1     is 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   9529  1.1     is 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   9530  1.1     is 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   9531  1.1     is 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   9532  1.1     is 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   9533  1.1     is 
   9534  1.1     is BIGRZRM:
   9535  1.1     is 	long		0x3ffe0000,0xb17217f7,0xd1cf79ab	# ln(2)
   9536  1.1     is 	long		0x40000000,0x935d8ddd,0xaaa8ac16	# ln(10)
   9537  1.1     is 
   9538  1.1     is 	long		0x3fff0000,0x80000000,0x00000000	# 10 ^ 0
   9539  1.1     is 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   9540  1.1     is 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   9541  1.1     is 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   9542  1.1     is 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   9543  1.1     is 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   9544  1.1     is 	long		0x40690000,0x9DC5ADA8,0x2B70B59D	# 10 ^ 32
   9545  1.1     is 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   9546  1.1     is 	long		0x41A80000,0x93BA47C9,0x80E98CDF	# 10 ^ 128
   9547  1.1     is 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8D	# 10 ^ 256
   9548  1.1     is 	long		0x46A30000,0xE319A0AE,0xA60E91C6	# 10 ^ 512
   9549  1.1     is 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   9550  1.1     is 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE4	# 10 ^ 2048
   9551  1.1     is 	long		0x75250000,0xC4605202,0x8A20979A	# 10 ^ 4096
   9552  1.1     is 
   9553  1.1     is BIGRP:
   9554  1.1     is 	long		0x3ffe0000,0xb17217f7,0xd1cf79ac	# ln(2)
   9555  1.1     is 	long		0x40000000,0x935d8ddd,0xaaa8ac17	# ln(10)
   9556  1.1     is 
   9557  1.1     is 	long		0x3fff0000,0x80000000,0x00000000	# 10 ^ 0
   9558  1.1     is 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   9559  1.1     is 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   9560  1.1     is 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   9561  1.1     is 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   9562  1.1     is 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   9563  1.1     is 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   9564  1.1     is 	long		0x40D30000,0xC2781F49,0xFFCFA6D6	# 10 ^ 64
   9565  1.1     is 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   9566  1.1     is 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   9567  1.1     is 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   9568  1.1     is 	long		0x4D480000,0xC9767586,0x81750C18	# 10 ^ 1024
   9569  1.1     is 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   9570  1.1     is 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   9571  1.1     is 
   9572  1.1     is #########################################################################
   9573  1.1     is # sscale(): computes the destination operand scaled by the source	#
   9574  1.1     is #	    operand. If the absoulute value of the source operand is 	#
   9575  1.1     is #	    >= 2^14, an overflow or underflow is returned.		#
   9576  1.1     is #									#
   9577  1.1     is # INPUT *************************************************************** #
   9578  1.1     is #	a0  = pointer to double-extended source operand X		#
   9579  1.1     is #	a1  = pointer to double-extended destination operand Y		#
   9580  1.1     is #									#
   9581  1.1     is # OUTPUT ************************************************************** #
   9582  1.1     is #	fp0 =  scale(X,Y)						#
   9583  1.1     is #									#
   9584  1.1     is #########################################################################
   9585  1.1     is 
   9586  1.1     is set	SIGN,		L_SCR1
   9587  1.1     is 
   9588  1.1     is 	global		sscale
   9589  1.1     is sscale:
   9590  1.1     is 	mov.l		%d0,-(%sp)		# store off ctrl bits for now
   9591  1.1     is 
   9592  1.1     is 	mov.w		DST_EX(%a1),%d1		# get dst exponent
   9593  1.1     is 	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
   9594  1.1     is 	andi.l		&0x00007fff,%d1		# strip sign from dst exp
   9595  1.1     is 
   9596  1.1     is 	mov.w		SRC_EX(%a0),%d0		# check src bounds
   9597  1.1     is 	andi.w		&0x7fff,%d0		# clr src sign bit
   9598  1.1     is 	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
   9599  1.1     is 	blt.w		src_small		# yes
   9600  1.1     is 	cmpi.w		%d0,&0x400c		# no; is src too big?
   9601  1.1     is 	bgt.w		src_out			# yes
   9602  1.1     is 
   9603  1.1     is #
   9604  1.1     is # Source is within 2^14 range.
   9605  1.1     is #
   9606  1.1     is src_ok:
   9607  1.1     is 	fintrz.x	SRC(%a0),%fp0		# calc int of src
   9608  1.1     is 	fmov.l		%fp0,%d0		# int src to d0
   9609  1.1     is # don't want any accrued bits from the fintrz showing up later since
   9610  1.1     is # we may need to read the fpsr for the last fp op in t_catch2().
   9611  1.1     is 	fmov.l		&0x0,%fpsr
   9612  1.1     is 
   9613  1.1     is 	tst.b		DST_HI(%a1)		# is dst denormalized?
   9614  1.1     is 	bmi.b		sok_norm
   9615  1.1     is 
   9616  1.1     is # the dst is a DENORM. normalize the DENORM and add the adjustment to
   9617  1.1     is # the src value. then, jump to the norm part of the routine.
   9618  1.1     is sok_dnrm:
   9619  1.1     is 	mov.l		%d0,-(%sp)		# save src for now
   9620  1.1     is 
   9621  1.1     is 	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
   9622  1.1     is 	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
   9623  1.1     is 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
   9624  1.1     is 
   9625  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
   9626  1.1     is 	bsr.l		norm			# normalize the DENORM
   9627  1.1     is 	neg.l		%d0
   9628  1.1     is 	add.l		(%sp)+,%d0		# add adjustment to src
   9629  1.1     is 
   9630  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
   9631  1.1     is 
   9632  1.1     is 	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
   9633  1.1     is 	bge.b		sok_norm2		# thank goodness no
   9634  1.1     is 
   9635  1.1     is # the multiply factor that we're trying to create should be a denorm
   9636  1.1     is # for the multiply to work. therefore, we're going to actually do a
   9637  1.1     is # multiply with a denorm which will cause an unimplemented data type
   9638  1.1     is # exception to be put into the machine which will be caught and corrected
   9639  1.1     is # later. we don't do this with the DENORMs above because this method
   9640  1.1     is # is slower. but, don't fret, I don't see it being used much either.
   9641  1.1     is 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
   9642  1.1     is 	mov.l		&0x80000000,%d1		# load normalized mantissa
   9643  1.1     is 	subi.l		&-0x3fff,%d0		# how many should we shift?
   9644  1.1     is 	neg.l		%d0			# make it positive
   9645  1.1     is 	cmpi.b		%d0,&0x20		# is it > 32?
   9646  1.1     is 	bge.b		sok_dnrm_32		# yes
   9647  1.1     is 	lsr.l		%d0,%d1			# no; bit stays in upper lw
   9648  1.1     is 	clr.l		-(%sp)			# insert zero low mantissa
   9649  1.1     is 	mov.l		%d1,-(%sp)		# insert new high mantissa
   9650  1.1     is 	clr.l		-(%sp)			# make zero exponent
   9651  1.1     is 	bra.b		sok_norm_cont
   9652  1.1     is sok_dnrm_32:
   9653  1.1     is 	subi.b		&0x20,%d0		# get shift count
   9654  1.1     is 	lsr.l		%d0,%d1			# make low mantissa longword
   9655  1.1     is 	mov.l		%d1,-(%sp)		# insert new low mantissa
   9656  1.1     is 	clr.l		-(%sp)			# insert zero high mantissa
   9657  1.1     is 	clr.l		-(%sp)			# make zero exponent
   9658  1.1     is 	bra.b		sok_norm_cont
   9659  1.1     is 
   9660  1.1     is # the src will force the dst to a DENORM value or worse. so, let's
   9661  1.1     is # create an fp multiply that will create the result.
   9662  1.1     is sok_norm:
   9663  1.1     is 	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
   9664  1.1     is sok_norm2:
   9665  1.1     is 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
   9666  1.1     is 
   9667  1.1     is 	addi.w		&0x3fff,%d0		# turn src amt into exp value
   9668  1.1     is 	swap		%d0			# put exponent in high word
   9669  1.1     is 	clr.l		-(%sp)			# insert new exponent
   9670  1.1     is 	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
   9671  1.1     is 	mov.l		%d0,-(%sp)		# insert new lo mantissa
   9672  1.1     is 
   9673  1.1     is sok_norm_cont:
   9674  1.1     is 	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
   9675  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9676  1.1     is 	fmul.x		(%sp)+,%fp0		# do the multiply
   9677  1.1     is 	bra		t_catch2		# catch any exceptions
   9678  1.1     is 
   9679  1.1     is #
   9680  1.1     is # Source is outside of 2^14 range.  Test the sign and branch
   9681  1.1     is # to the appropriate exception handler.
   9682  1.1     is #
   9683  1.1     is src_out:
   9684  1.1     is 	mov.l		(%sp)+,%d0		# restore ctrl bits
   9685  1.1     is 	exg		%a0,%a1			# swap src,dst ptrs
   9686  1.1     is 	tst.b		SRC_EX(%a1)		# is src negative?
   9687  1.1     is 	bmi		t_unfl			# yes; underflow
   9688  1.1     is 	bra		t_ovfl_sc		# no; overflow
   9689  1.1     is 
   9690  1.1     is #
   9691  1.1     is # The source input is below 1, so we check for denormalized numbers
   9692  1.1     is # and set unfl.
   9693  1.1     is #
   9694  1.1     is src_small:
   9695  1.1     is 	tst.b		DST_HI(%a1)		# is dst denormalized?
   9696  1.1     is 	bpl.b		ssmall_done		# yes
   9697  1.1     is 
   9698  1.1     is 	mov.l		(%sp)+,%d0
   9699  1.1     is 	fmov.l		%d0,%fpcr		# no; load control bits
   9700  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   9701  1.1     is 	fmov.x		DST(%a1),%fp0		# simply return dest
   9702  1.1     is 	bra		t_catch2
   9703  1.1     is ssmall_done:
   9704  1.1     is 	mov.l		(%sp)+,%d0		# load control bits into d1
   9705  1.1     is 	mov.l		%a1,%a0			# pass ptr to dst
   9706  1.1     is 	bra		t_resdnrm
   9707  1.1     is 
   9708  1.1     is #########################################################################
   9709  1.1     is # smod(): computes the fp MOD of the input values X,Y.			#
   9710  1.1     is # srem(): computes the fp (IEEE) REM of the input values X,Y.		#
   9711  1.1     is #									#
   9712  1.1     is # INPUT *************************************************************** #
   9713  1.1     is #	a0 = pointer to extended precision input X			#
   9714  1.1     is #	a1 = pointer to extended precision input Y			#
   9715  1.1     is #	d0 = round precision,mode					#
   9716  1.1     is #									#
   9717  1.1     is # 	The input operands X and Y can be either normalized or 		#
   9718  1.1     is #	denormalized.							#
   9719  1.1     is #									#
   9720  1.1     is # OUTPUT ************************************************************** #
   9721  1.1     is #      fp0 = FREM(X,Y) or FMOD(X,Y)					#
   9722  1.1     is #									#
   9723  1.1     is # ALGORITHM *********************************************************** #
   9724  1.1     is #									#
   9725  1.1     is #       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
   9726  1.1     is #                signY := sign(Y), X := |X|, Y := |Y|, 			#
   9727  1.1     is #                signQ := signX EOR signY. Record whether MOD or REM	#
   9728  1.1     is #                is requested.						#
   9729  1.1     is #									#
   9730  1.1     is #       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
   9731  1.1     is #                If (L < 0) then					#
   9732  1.1     is #                   R := X, go to Step 4.				#
   9733  1.1     is #                else							#
   9734  1.1     is #                   R := 2^(-L)X, j := L.				#
   9735  1.1     is #                endif							#
   9736  1.1     is #									#
   9737  1.1     is #       Step 3.  Perform MOD(X,Y)					#
   9738  1.1     is #            3.1 If R = Y, go to Step 9.				#
   9739  1.1     is #            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
   9740  1.1     is #            3.3 If j = 0, go to Step 4.				#
   9741  1.1     is #            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
   9742  1.1     is #                Step 3.1.						#
   9743  1.1     is #									#
   9744  1.1     is #       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
   9745  1.1     is #                Last_Subtract := false (used in Step 7 below). If	#
   9746  1.1     is #                MOD is requested, go to Step 6. 			#
   9747  1.1     is #									#
   9748  1.1     is #       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
   9749  1.1     is #            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
   9750  1.1     is #                Step 6.						#
   9751  1.1     is #            5.2 If R > Y/2, then { set Last_Subtract := true,		#
   9752  1.1     is #                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
   9753  1.1     is #            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
   9754  1.1     is #                then { Q := Q + 1, signX := -signX }.			#
   9755  1.1     is #									#
   9756  1.1     is #       Step 6.  R := signX*R.						#
   9757  1.1     is #									#
   9758  1.1     is #       Step 7.  If Last_Subtract = true, R := R - Y.			#
   9759  1.1     is #									#
   9760  1.1     is #       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
   9761  1.1     is #									#
   9762  1.1     is #       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
   9763  1.1     is #                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
   9764  1.1     is #                R := 0. Return signQ, last 7 bits of Q, and R.		#
   9765  1.1     is #									#
   9766  1.1     is #########################################################################
   9767  1.1     is 
   9768  1.1     is 	set		Mod_Flag,L_SCR3
   9769  1.1     is 	set		Sc_Flag,L_SCR3+1
   9770  1.1     is 
   9771  1.1     is 	set		SignY,L_SCR2
   9772  1.1     is 	set		SignX,L_SCR2+2
   9773  1.1     is 	set		SignQ,L_SCR3+2
   9774  1.1     is 
   9775  1.1     is 	set		Y,FP_SCR0
   9776  1.1     is 	set		Y_Hi,Y+4
   9777  1.1     is 	set		Y_Lo,Y+8
   9778  1.1     is 
   9779  1.1     is 	set		R,FP_SCR1
   9780  1.1     is 	set		R_Hi,R+4
   9781  1.1     is 	set		R_Lo,R+8
   9782  1.1     is 
   9783  1.1     is Scale:
   9784  1.1     is 	long		0x00010000,0x80000000,0x00000000,0x00000000
   9785  1.1     is 
   9786  1.1     is 	global		smod
   9787  1.1     is smod:
   9788  1.1     is 	clr.b		FPSR_QBYTE(%a6)
   9789  1.1     is 	mov.l		%d0,-(%sp)		# save ctrl bits
   9790  1.1     is 	clr.b		Mod_Flag(%a6)
   9791  1.1     is 	bra.b		Mod_Rem
   9792  1.1     is 
   9793  1.1     is 	global		srem
   9794  1.1     is srem:
   9795  1.1     is 	clr.b		FPSR_QBYTE(%a6)
   9796  1.1     is 	mov.l		%d0,-(%sp)		# save ctrl bits
   9797  1.1     is 	mov.b		&0x1,Mod_Flag(%a6)
   9798  1.1     is 
   9799  1.1     is Mod_Rem:
   9800  1.1     is #..Save sign of X and Y
   9801  1.1     is 	movm.l		&0x3f00,-(%sp)		# save data registers
   9802  1.1     is 	mov.w		SRC_EX(%a0),%d3
   9803  1.1     is 	mov.w		%d3,SignY(%a6)
   9804  1.1     is 	and.l		&0x00007FFF,%d3		# Y := |Y|
   9805  1.1     is 
   9806  1.1     is #
   9807  1.1     is 	mov.l		SRC_HI(%a0),%d4
   9808  1.1     is 	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
   9809  1.1     is 
   9810  1.1     is 	tst.l		%d3
   9811  1.1     is 	bne.b		Y_Normal
   9812  1.1     is 
   9813  1.1     is 	mov.l		&0x00003FFE,%d3		# $3FFD + 1
   9814  1.1     is 	tst.l		%d4
   9815  1.1     is 	bne.b		HiY_not0
   9816  1.1     is 
   9817  1.1     is HiY_0:
   9818  1.1     is 	mov.l		%d5,%d4
   9819  1.1     is 	clr.l		%d5
   9820  1.1     is 	sub.l		&32,%d3
   9821  1.1     is 	clr.l		%d6
   9822  1.1     is 	bfffo		%d4{&0:&32},%d6
   9823  1.1     is 	lsl.l		%d6,%d4
   9824  1.1     is 	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
   9825  1.1     is #	                                        ...with bias $7FFD
   9826  1.1     is 	bra.b		Chk_X
   9827  1.1     is 
   9828  1.1     is HiY_not0:
   9829  1.1     is 	clr.l		%d6
   9830  1.1     is 	bfffo		%d4{&0:&32},%d6
   9831  1.1     is 	sub.l		%d6,%d3
   9832  1.1     is 	lsl.l		%d6,%d4
   9833  1.1     is 	mov.l		%d5,%d7			# a copy of D5
   9834  1.1     is 	lsl.l		%d6,%d5
   9835  1.1     is 	neg.l		%d6
   9836  1.1     is 	add.l		&32,%d6
   9837  1.1     is 	lsr.l		%d6,%d7
   9838  1.1     is 	or.l		%d7,%d4			# (D3,D4,D5) normalized
   9839  1.1     is #                                       ...with bias $7FFD
   9840  1.1     is 	bra.b		Chk_X
   9841  1.1     is 
   9842  1.1     is Y_Normal:
   9843  1.1     is 	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
   9844  1.1     is #                                       ...with bias $7FFD
   9845  1.1     is 
   9846  1.1     is Chk_X:
   9847  1.1     is 	mov.w		DST_EX(%a1),%d0
   9848  1.1     is 	mov.w		%d0,SignX(%a6)
   9849  1.1     is 	mov.w		SignY(%a6),%d1
   9850  1.1     is 	eor.l		%d0,%d1
   9851  1.1     is 	and.l		&0x00008000,%d1
   9852  1.1     is 	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
   9853  1.1     is 	and.l		&0x00007FFF,%d0
   9854  1.1     is 	mov.l		DST_HI(%a1),%d1
   9855  1.1     is 	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
   9856  1.1     is 	tst.l		%d0
   9857  1.1     is 	bne.b		X_Normal
   9858  1.1     is 	mov.l		&0x00003FFE,%d0
   9859  1.1     is 	tst.l		%d1
   9860  1.1     is 	bne.b		HiX_not0
   9861  1.1     is 
   9862  1.1     is HiX_0:
   9863  1.1     is 	mov.l		%d2,%d1
   9864  1.1     is 	clr.l		%d2
   9865  1.1     is 	sub.l		&32,%d0
   9866  1.1     is 	clr.l		%d6
   9867  1.1     is 	bfffo		%d1{&0:&32},%d6
   9868  1.1     is 	lsl.l		%d6,%d1
   9869  1.1     is 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
   9870  1.1     is #                                       ...with bias $7FFD
   9871  1.1     is 	bra.b		Init
   9872  1.1     is 
   9873  1.1     is HiX_not0:
   9874  1.1     is 	clr.l		%d6
   9875  1.1     is 	bfffo		%d1{&0:&32},%d6
   9876  1.1     is 	sub.l		%d6,%d0
   9877  1.1     is 	lsl.l		%d6,%d1
   9878  1.1     is 	mov.l		%d2,%d7			# a copy of D2
   9879  1.1     is 	lsl.l		%d6,%d2
   9880  1.1     is 	neg.l		%d6
   9881  1.1     is 	add.l		&32,%d6
   9882  1.1     is 	lsr.l		%d6,%d7
   9883  1.1     is 	or.l		%d7,%d1			# (D0,D1,D2) normalized
   9884  1.1     is #                                       ...with bias $7FFD
   9885  1.1     is 	bra.b		Init
   9886  1.1     is 
   9887  1.1     is X_Normal:
   9888  1.1     is 	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
   9889  1.1     is #                                       ...with bias $7FFD
   9890  1.1     is 
   9891  1.1     is Init:
   9892  1.1     is #
   9893  1.1     is 	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
   9894  1.1     is 	mov.l		%d0,-(%sp)		# save biased exp(X)
   9895  1.1     is 	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
   9896  1.1     is 
   9897  1.1     is 	clr.l		%d6			# D6 := carry <- 0
   9898  1.1     is 	clr.l		%d3			# D3 is Q
   9899  1.1     is 	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
   9900  1.1     is 
   9901  1.1     is #..(Carry,D1,D2) is R
   9902  1.1     is 	tst.l		%d0
   9903  1.1     is 	bge.b		Mod_Loop_pre
   9904  1.1     is 
   9905  1.1     is #..expo(X) < expo(Y). Thus X = mod(X,Y)
   9906  1.1     is #
   9907  1.1     is 	mov.l		(%sp)+,%d0		# restore d0
   9908  1.1     is 	bra.w		Get_Mod
   9909  1.1     is 
   9910  1.1     is Mod_Loop_pre:
   9911  1.1     is 	addq.l		&0x4,%sp		# erase exp(X)
   9912  1.1     is #..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
   9913  1.1     is Mod_Loop:
   9914  1.1     is 	tst.l		%d6			# test carry bit
   9915  1.1     is 	bgt.b		R_GT_Y
   9916  1.1     is 
   9917  1.1     is #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
   9918  1.1     is 	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
   9919  1.1     is 	bne.b		R_NE_Y
   9920  1.1     is 	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
   9921  1.1     is 	bne.b		R_NE_Y
   9922  1.1     is 
   9923  1.1     is #..At this point, R = Y
   9924  1.1     is 	bra.w		Rem_is_0
   9925  1.1     is 
   9926  1.1     is R_NE_Y:
   9927  1.1     is #..use the borrow of the previous compare
   9928  1.1     is 	bcs.b		R_LT_Y			# borrow is set iff R < Y
   9929  1.1     is 
   9930  1.1     is R_GT_Y:
   9931  1.1     is #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
   9932  1.1     is #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
   9933  1.1     is 	sub.l		%d5,%d2			# lo(R) - lo(Y)
   9934  1.1     is 	subx.l		%d4,%d1			# hi(R) - hi(Y)
   9935  1.1     is 	clr.l		%d6			# clear carry
   9936  1.1     is 	addq.l		&1,%d3			# Q := Q + 1
   9937  1.1     is 
   9938  1.1     is R_LT_Y:
   9939  1.1     is #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
   9940  1.1     is 	tst.l		%d0			# see if j = 0.
   9941  1.1     is 	beq.b		PostLoop
   9942  1.1     is 
   9943  1.1     is 	add.l		%d3,%d3			# Q := 2Q
   9944  1.1     is 	add.l		%d2,%d2			# lo(R) = 2lo(R)
   9945  1.1     is 	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
   9946  1.1     is 	scs		%d6			# set Carry if 2(R) overflows
   9947  1.1     is 	addq.l		&1,%a1			# k := k+1
   9948  1.1     is 	subq.l		&1,%d0			# j := j - 1
   9949  1.1     is #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
   9950  1.1     is 
   9951  1.1     is 	bra.b		Mod_Loop
   9952  1.1     is 
   9953  1.1     is PostLoop:
   9954  1.1     is #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
   9955  1.1     is 
   9956  1.1     is #..normalize R.
   9957  1.1     is 	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
   9958  1.1     is 	tst.l		%d1
   9959  1.1     is 	bne.b		HiR_not0
   9960  1.1     is 
   9961  1.1     is HiR_0:
   9962  1.1     is 	mov.l		%d2,%d1
   9963  1.1     is 	clr.l		%d2
   9964  1.1     is 	sub.l		&32,%d0
   9965  1.1     is 	clr.l		%d6
   9966  1.1     is 	bfffo		%d1{&0:&32},%d6
   9967  1.1     is 	lsl.l		%d6,%d1
   9968  1.1     is 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
   9969  1.1     is #                                       ...with bias $7FFD
   9970  1.1     is 	bra.b		Get_Mod
   9971  1.1     is 
   9972  1.1     is HiR_not0:
   9973  1.1     is 	clr.l		%d6
   9974  1.1     is 	bfffo		%d1{&0:&32},%d6
   9975  1.1     is 	bmi.b		Get_Mod			# already normalized
   9976  1.1     is 	sub.l		%d6,%d0
   9977  1.1     is 	lsl.l		%d6,%d1
   9978  1.1     is 	mov.l		%d2,%d7			# a copy of D2
   9979  1.1     is 	lsl.l		%d6,%d2
   9980  1.1     is 	neg.l		%d6
   9981  1.1     is 	add.l		&32,%d6
   9982  1.1     is 	lsr.l		%d6,%d7
   9983  1.1     is 	or.l		%d7,%d1			# (D0,D1,D2) normalized
   9984  1.1     is 
   9985  1.1     is #
   9986  1.1     is Get_Mod:
   9987  1.1     is 	cmp.l		%d0,&0x000041FE
   9988  1.1     is 	bge.b		No_Scale
   9989  1.1     is Do_Scale:
   9990  1.1     is 	mov.w		%d0,R(%a6)
   9991  1.1     is 	mov.l		%d1,R_Hi(%a6)
   9992  1.1     is 	mov.l		%d2,R_Lo(%a6)
   9993  1.1     is 	mov.l		L_SCR1(%a6),%d6
   9994  1.1     is 	mov.w		%d6,Y(%a6)
   9995  1.1     is 	mov.l		%d4,Y_Hi(%a6)
   9996  1.1     is 	mov.l		%d5,Y_Lo(%a6)
   9997  1.1     is 	fmov.x		R(%a6),%fp0		# no exception
   9998  1.1     is 	mov.b		&1,Sc_Flag(%a6)
   9999  1.1     is 	bra.b		ModOrRem
   10000  1.1     is No_Scale:
   10001  1.1     is 	mov.l		%d1,R_Hi(%a6)
   10002  1.1     is 	mov.l		%d2,R_Lo(%a6)
   10003  1.1     is 	sub.l		&0x3FFE,%d0
   10004  1.1     is 	mov.w		%d0,R(%a6)
   10005  1.1     is 	mov.l		L_SCR1(%a6),%d6
   10006  1.1     is 	sub.l		&0x3FFE,%d6
   10007  1.1     is 	mov.l		%d6,L_SCR1(%a6)
   10008  1.1     is 	fmov.x		R(%a6),%fp0
   10009  1.1     is 	mov.w		%d6,Y(%a6)
   10010  1.1     is 	mov.l		%d4,Y_Hi(%a6)
   10011  1.1     is 	mov.l		%d5,Y_Lo(%a6)
   10012  1.1     is 	clr.b		Sc_Flag(%a6)
   10013  1.1     is 
   10014  1.1     is #
   10015  1.1     is ModOrRem:
   10016  1.1     is 	tst.b		Mod_Flag(%a6)
   10017  1.1     is 	beq.b		Fix_Sign
   10018  1.1     is 
   10019  1.1     is 	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
   10020  1.1     is 	subq.l		&1,%d6			# biased expo(Y/2)
   10021  1.1     is 	cmp.l		%d0,%d6
   10022  1.1     is 	blt.b		Fix_Sign
   10023  1.1     is 	bgt.b		Last_Sub
   10024  1.1     is 
   10025  1.1     is 	cmp.l		%d1,%d4
   10026  1.1     is 	bne.b		Not_EQ
   10027  1.1     is 	cmp.l		%d2,%d5
   10028  1.1     is 	bne.b		Not_EQ
   10029  1.1     is 	bra.w		Tie_Case
   10030  1.1     is 
   10031  1.1     is Not_EQ:
   10032  1.1     is 	bcs.b		Fix_Sign
   10033  1.1     is 
   10034  1.1     is Last_Sub:
   10035  1.1     is #
   10036  1.1     is 	fsub.x		Y(%a6),%fp0		# no exceptions
   10037  1.1     is 	addq.l		&1,%d3			# Q := Q + 1
   10038  1.1     is 
   10039  1.1     is #
   10040  1.1     is Fix_Sign:
   10041  1.1     is #..Get sign of X
   10042  1.1     is 	mov.w		SignX(%a6),%d6
   10043  1.1     is 	bge.b		Get_Q
   10044  1.1     is 	fneg.x		%fp0
   10045  1.1     is 
   10046  1.1     is #..Get Q
   10047  1.1     is #
   10048  1.1     is Get_Q:
   10049  1.1     is 	clr.l		%d6
   10050  1.1     is 	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
   10051  1.1     is 	mov.l		&8,%d7
   10052  1.1     is 	lsr.l		%d7,%d6
   10053  1.1     is 	and.l		&0x0000007F,%d3		# 7 bits of Q
   10054  1.1     is 	or.l		%d6,%d3			# sign and bits of Q
   10055  1.1     is #	swap		%d3
   10056  1.1     is #	fmov.l		%fpsr,%d6
   10057  1.1     is #	and.l		&0xFF00FFFF,%d6
   10058  1.1     is #	or.l		%d3,%d6
   10059  1.1     is #	fmov.l		%d6,%fpsr		# put Q in fpsr
   10060  1.1     is 	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
   10061  1.1     is 
   10062  1.1     is #
   10063  1.1     is Restore:
   10064  1.1     is 	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
   10065  1.1     is 	mov.l		(%sp)+,%d0
   10066  1.1     is 	fmov.l		%d0,%fpcr
   10067  1.1     is 	tst.b		Sc_Flag(%a6)
   10068  1.1     is 	beq.b		Finish
   10069  1.1     is 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   10070  1.1     is 	fmul.x		Scale(%pc),%fp0		# may cause underflow
   10071  1.1     is 	bra		t_catch2
   10072  1.1     is # the '040 package did this apparently to see if the dst operand for the
   10073  1.1     is # preceding fmul was a denorm. but, it better not have been since the
   10074  1.1     is # algorithm just got done playing with fp0 and expected no exceptions
   10075  1.1     is # as a result. trust me...
   10076  1.1     is #	bra		t_avoid_unsupp		# check for denorm as a
   10077  1.1     is #						;result of the scaling
   10078  1.1     is 
   10079  1.1     is Finish:
   10080  1.1     is 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   10081  1.1     is 	fmov.x		%fp0,%fp0		# capture exceptions & round
   10082  1.1     is 	bra		t_catch2
   10083  1.1     is 
   10084  1.1     is Rem_is_0:
   10085  1.1     is #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
   10086  1.1     is 	addq.l		&1,%d3
   10087  1.1     is 	cmp.l		%d0,&8			# D0 is j
   10088  1.1     is 	bge.b		Q_Big
   10089  1.1     is 
   10090  1.1     is 	lsl.l		%d0,%d3
   10091  1.1     is 	bra.b		Set_R_0
   10092  1.1     is 
   10093  1.1     is Q_Big:
   10094  1.1     is 	clr.l		%d3
   10095  1.1     is 
   10096  1.1     is Set_R_0:
   10097  1.1     is 	fmov.s		&0x00000000,%fp0
   10098  1.1     is 	clr.b		Sc_Flag(%a6)
   10099  1.1     is 	bra.w		Fix_Sign
   10100  1.1     is 
   10101  1.1     is Tie_Case:
   10102  1.1     is #..Check parity of Q
   10103  1.1     is 	mov.l		%d3,%d6
   10104  1.1     is 	and.l		&0x00000001,%d6
   10105  1.1     is 	tst.l		%d6
   10106  1.1     is 	beq.w		Fix_Sign		# Q is even
   10107  1.1     is 
   10108  1.1     is #..Q is odd, Q := Q + 1, signX := -signX
   10109  1.1     is 	addq.l		&1,%d3
   10110  1.1     is 	mov.w		SignX(%a6),%d6
   10111  1.1     is 	eor.l		&0x00008000,%d6
   10112  1.1     is 	mov.w		%d6,SignX(%a6)
   10113  1.1     is 	bra.w		Fix_Sign
   10114  1.1     is 
   10115  1.1     is qnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
   10116  1.1     is 
   10117  1.1     is #########################################################################
   10118  1.1     is # XDEF ****************************************************************	#
   10119  1.1     is #	t_dz(): Handle DZ exception during transcendental emulation.	#
   10120  1.1     is #	        Sets N bit according to sign of source operand.		#
   10121  1.1     is #	t_dz2(): Handle DZ exception during transcendental emulation.	#
   10122  1.1     is #		 Sets N bit always.					#
   10123  1.1     is #									#
   10124  1.1     is # XREF ****************************************************************	#
   10125  1.1     is #	None								#
   10126  1.1     is #									#
   10127  1.1     is # INPUT ***************************************************************	#
   10128  1.1     is #	a0 = pointer to source operand					#
   10129  1.1     is # 									#
   10130  1.1     is # OUTPUT **************************************************************	#
   10131  1.1     is #	fp0 = default result						#
   10132  1.1     is #									#
   10133  1.1     is # ALGORITHM ***********************************************************	#
   10134  1.1     is #	- Store properly signed INF into fp0.				#
   10135  1.1     is #	- Set FPSR exception status dz bit, ccode inf bit, and 		#
   10136  1.1     is #	  accrued dz bit.						#
   10137  1.1     is #									#
   10138  1.1     is #########################################################################
   10139  1.1     is 
   10140  1.1     is 	global		t_dz
   10141  1.1     is t_dz:
   10142  1.1     is 	tst.b		SRC_EX(%a0) 		# no; is src negative?
   10143  1.1     is 	bmi.b		t_dz2			# yes
   10144  1.1     is 
   10145  1.1     is dz_pinf:
   10146  1.1     is 	fmov.s		&0x7f800000,%fp0	# return +INF in fp0
   10147  1.1     is 	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
   10148  1.1     is 	rts
   10149  1.1     is 
   10150  1.1     is 	global		t_dz2
   10151  1.1     is t_dz2:
   10152  1.1     is 	fmov.s		&0xff800000,%fp0	# return -INF in fp0
   10153  1.1     is 	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
   10154  1.1     is 	rts
   10155  1.1     is 
   10156  1.1     is #################################################################
   10157  1.1     is # OPERR exception:						#
   10158  1.1     is #	- set FPSR exception status operr bit, condition code 	#
   10159  1.1     is #	  nan bit; Store default NAN into fp0			#
   10160  1.1     is #################################################################
   10161  1.1     is 	global		t_operr
   10162  1.1     is t_operr:
   10163  1.1     is 	ori.l		&opnan_mask,USER_FPSR(%a6) # set NaN/OPERR/AIOP
   10164  1.1     is 	fmovm.x		qnan(%pc),&0x80		# return default NAN in fp0
   10165  1.1     is 	rts
   10166  1.1     is 
   10167  1.1     is #################################################################
   10168  1.1     is # Extended DENORM:						#
   10169  1.1     is # 	- For all functions that have a denormalized input and	#
   10170  1.1     is #	  that f(x)=x, this is the entry point.			#
   10171  1.1     is #	- we only return the EXOP here if either underflow or	#
   10172  1.1     is #	  inexact is enabled.					#
   10173  1.1     is #################################################################
   10174  1.1     is 
   10175  1.1     is # Entry point for scale w/ extended denorm. The function does
   10176  1.1     is # NOT set INEX2/AUNFL/AINEX.
   10177  1.1     is 	global		t_resdnrm
   10178  1.1     is t_resdnrm:
   10179  1.1     is 	ori.l		&unfl_mask,USER_FPSR(%a6) # set UNFL
   10180  1.1     is 	bra.b		xdnrm_con
   10181  1.1     is 
   10182  1.1     is 	global		t_extdnrm
   10183  1.1     is t_extdnrm:
   10184  1.1     is 	ori.l		&unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
   10185  1.1     is 
   10186  1.1     is xdnrm_con:
   10187  1.1     is 	mov.l		%a0,%a1			# make copy of src ptr
   10188  1.1     is 	mov.l		%d0,%d1			# make copy of rnd prec,mode
   10189  1.1     is 	andi.b		&0xc0,%d1		# extended precision?
   10190  1.1     is 	bne.b		xdnrm_sd		# no
   10191  1.1     is 
   10192  1.1     is # result precision is extended.
   10193  1.1     is 	tst.b		LOCAL_EX(%a0)		# is denorm negative?
   10194  1.1     is 	bpl.b		xdnrm_exit		# no
   10195  1.1     is 
   10196  1.1     is 	bset		&neg_bit,FPSR_CC(%a6)	# yes; set 'N' ccode bit
   10197  1.1     is 	bra.b		xdnrm_exit
   10198  1.1     is 
   10199  1.1     is # result precision is single or double
   10200  1.1     is xdnrm_sd:
   10201  1.1     is 	mov.l		%a1,-(%sp)
   10202  1.1     is 	tst.b		LOCAL_EX(%a0)		# is denorm pos or neg?
   10203  1.1     is 	smi.b		%d1			# set d0 accodingly
   10204  1.1     is 	bsr.l		unf_sub
   10205  1.1     is 	mov.l		(%sp)+,%a1
   10206  1.1     is xdnrm_exit:
   10207  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10208  1.1     is 
   10209  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0
   10210  1.1     is 	andi.b		&0x0a,%d0		# is UNFL or INEX enabled?
   10211  1.1     is 	bne.b		xdnrm_ena		# yes
   10212  1.1     is 	rts
   10213  1.1     is 
   10214  1.1     is ################
   10215  1.1     is # unfl enabled #
   10216  1.1     is ################
   10217  1.1     is # we have a DENORM that needs to be converted into an EXOP.
   10218  1.1     is # so, normalize the mantissa, add 0x6000 to the new exponent,
   10219  1.1     is # and return the result in fp1.
   10220  1.1     is xdnrm_ena:
   10221  1.1     is 	mov.w		LOCAL_EX(%a1),FP_SCR0_EX(%a6)
   10222  1.1     is 	mov.l		LOCAL_HI(%a1),FP_SCR0_HI(%a6)
   10223  1.1     is 	mov.l		LOCAL_LO(%a1),FP_SCR0_LO(%a6)
   10224  1.1     is 
   10225  1.1     is 	lea		FP_SCR0(%a6),%a0
   10226  1.1     is 	bsr.l		norm			# normalize mantissa
   10227  1.1     is 	addi.l		&0x6000,%d0		# add extra bias
   10228  1.1     is 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# keep old sign
   10229  1.1     is 	or.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   10230  1.1     is 
   10231  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   10232  1.1     is 	rts
   10233  1.1     is 
   10234  1.1     is #################################################################
   10235  1.1     is # UNFL exception:						#
   10236  1.1     is # 	- This routine is for cases where even an EXOP isn't	#
   10237  1.1     is #  	  large enough to hold the range of this result.	#
   10238  1.1     is #	  In such a case, the EXOP equals zero.			#
   10239  1.1     is #  	- Return the default result to the proper precision 	#
   10240  1.1     is #	  with the sign of this result being the same as that	#
   10241  1.1     is #	  of the src operand.					#
   10242  1.1     is # 	- t_unfl2() is provided to force the result sign to 	#
   10243  1.1     is #	  positive which is the desired result for fetox().	#
   10244  1.1     is #################################################################
   10245  1.1     is 	global		t_unfl
   10246  1.1     is t_unfl:
   10247  1.1     is 	ori.l		&unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
   10248  1.1     is 
   10249  1.1     is 	tst.b		(%a0)			# is result pos or neg?
   10250  1.1     is 	smi.b		%d1			# set d1 accordingly
   10251  1.1     is 	bsr.l		unf_sub			# calc default unfl result
   10252  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10253  1.1     is 
   10254  1.1     is 	fmov.s		&0x00000000,%fp1	# return EXOP in fp1
   10255  1.1     is 	rts
   10256  1.1     is 
   10257  1.1     is # t_unfl2 ALWAYS tells unf_sub to create a positive result
   10258  1.1     is 	global		t_unfl2
   10259  1.1     is t_unfl2:
   10260  1.1     is 	ori.l		&unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
   10261  1.1     is 
   10262  1.1     is 	sf.b		%d1			# set d0 to represent positive
   10263  1.1     is 	bsr.l		unf_sub			# calc default unfl result
   10264  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10265  1.1     is 
   10266  1.1     is 	fmov.s		&0x0000000,%fp1		# return EXOP in fp1
   10267  1.1     is 	rts
   10268  1.1     is 
   10269  1.1     is #################################################################
   10270  1.1     is # OVFL exception:						#
   10271  1.1     is # 	- This routine is for cases where even an EXOP isn't	#
   10272  1.1     is #  	  large enough to hold the range of this result.	#
   10273  1.1     is # 	- Return the default result to the proper precision 	#
   10274  1.1     is #	  with the sign of this result being the same as that 	#
   10275  1.1     is #	  of the src operand.					#
   10276  1.1     is # 	- t_ovfl2() is provided to force the result sign to 	#
   10277  1.1     is #	  positive which is the desired result for fcosh().	#
   10278  1.1     is # 	- t_ovfl_sc() is provided for scale() which only sets 	#
   10279  1.1     is #	  the inexact bits if the number is inexact for the 	#
   10280  1.1     is #	  precision indicated.					#
   10281  1.1     is #################################################################
   10282  1.1     is 
   10283  1.1     is 	global		t_ovfl_sc
   10284  1.1     is t_ovfl_sc:
   10285  1.1     is 	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
   10286  1.1     is 
   10287  1.1     is 	mov.b		%d0,%d1			# fetch rnd mode/prec
   10288  1.1     is 	andi.b		&0xc0,%d1		# extract rnd prec
   10289  1.1     is 	beq.b		ovfl_work		# prec is extended
   10290  1.1     is 
   10291  1.1     is 	tst.b		LOCAL_HI(%a0)		# is dst a DENORM?
   10292  1.1     is 	bmi.b		ovfl_sc_norm		# no
   10293  1.1     is 
   10294  1.1     is # dst op is a DENORM. we have to normalize the mantissa to see if the
   10295  1.1     is # result would be inexact for the given precision. make a copy of the
   10296  1.1     is # dst so we don't screw up the version passed to us.
   10297  1.1     is 	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
   10298  1.1     is 	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
   10299  1.1     is 	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
   10300  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
   10301  1.1     is 	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
   10302  1.1     is 	bsr.l		norm			# normalize mantissa
   10303  1.1     is 	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
   10304  1.1     is 
   10305  1.1     is ovfl_sc_norm:
   10306  1.1     is 	cmpi.b		%d1,&0x40		# is prec dbl?
   10307  1.1     is 	bne.b		ovfl_sc_dbl		# no; sgl
   10308  1.1     is ovfl_sc_sgl:
   10309  1.1     is 	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
   10310  1.1     is 	bne.b		ovfl_sc_inx		# yes
   10311  1.1     is 	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
   10312  1.1     is 	bne.b		ovfl_sc_inx		# yes
   10313  1.1     is 	bra.b		ovfl_work		# don't set INEX2
   10314  1.1     is ovfl_sc_dbl:
   10315  1.1     is 	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
   10316  1.1     is 	andi.l		&0x7ff,%d1		# dbl mantissa set?
   10317  1.1     is 	beq.b		ovfl_work		# no; don't set INEX2
   10318  1.1     is ovfl_sc_inx:
   10319  1.1     is 	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
   10320  1.1     is 	bra.b		ovfl_work		# continue
   10321  1.1     is 
   10322  1.1     is 	global		t_ovfl
   10323  1.1     is t_ovfl:
   10324  1.1     is 	ori.l		&ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX
   10325  1.1     is 
   10326  1.1     is ovfl_work:
   10327  1.1     is 	tst.b		LOCAL_EX(%a0)		# what is the sign?
   10328  1.1     is 	smi.b		%d1			# set d1 accordingly
   10329  1.1     is 	bsr.l		ovf_res			# calc default ovfl result
   10330  1.1     is 	mov.b		%d0,FPSR_CC(%a6)	# insert new ccodes
   10331  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10332  1.1     is 
   10333  1.1     is 	fmov.s		&0x00000000,%fp1	# return EXOP in fp1
   10334  1.1     is 	rts
   10335  1.1     is 
   10336  1.1     is # t_ovfl2 ALWAYS tells ovf_res to create a positive result
   10337  1.1     is 	global		t_ovfl2
   10338  1.1     is t_ovfl2:
   10339  1.1     is 	ori.l		&ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX
   10340  1.1     is 
   10341  1.1     is 	sf.b		%d1			# clear sign flag for positive
   10342  1.1     is 	bsr.l		ovf_res			# calc default ovfl result
   10343  1.1     is 	mov.b		%d0,FPSR_CC(%a6)	# insert new ccodes
   10344  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10345  1.1     is 
   10346  1.1     is 	fmov.s		&0x00000000,%fp1	# return EXOP in fp1
   10347  1.1     is 	rts
   10348  1.1     is 
   10349  1.1     is #################################################################
   10350  1.1     is # t_catch(): 							#
   10351  1.1     is #	- the last operation of a transcendental emulation	#
   10352  1.1     is # 	  routine may have caused an underflow or overflow. 	#
   10353  1.1     is # 	  we find out if this occurred by doing an fsave and 	#
   10354  1.1     is #	  checking the exception bit. if one did occur, then we	#
   10355  1.1     is #	  jump to fgen_except() which creates the default	#
   10356  1.1     is #	  result and EXOP for us.				#
   10357  1.1     is #################################################################
   10358  1.1     is 	global		t_catch
   10359  1.1     is t_catch:
   10360  1.1     is 
   10361  1.1     is 	fsave		-(%sp)
   10362  1.1     is 	tst.b		0x2(%sp)
   10363  1.1     is 	bmi.b		catch
   10364  1.1     is 	add.l		&0xc,%sp
   10365  1.1     is 
   10366  1.1     is #################################################################
   10367  1.1     is # INEX2 exception:						#
   10368  1.1     is #	- The inex2 and ainex bits are set.			#
   10369  1.1     is #################################################################
   10370  1.1     is 	global		t_inx2
   10371  1.1     is t_inx2:
   10372  1.1     is 	fblt.w		t_minx2
   10373  1.1     is 	fbeq.w		inx2_zero
   10374  1.1     is 
   10375  1.1     is 	global		t_pinx2
   10376  1.1     is t_pinx2:
   10377  1.1     is 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX
   10378  1.1     is 	rts
   10379  1.1     is 
   10380  1.1     is 	global		t_minx2
   10381  1.1     is t_minx2:
   10382  1.1     is 	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6) # set N/INEX2/AINEX
   10383  1.1     is 	rts
   10384  1.1     is 
   10385  1.1     is inx2_zero:
   10386  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)
   10387  1.1     is 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX
   10388  1.1     is 	rts
   10389  1.1     is 
   10390  1.1     is # an underflow or overflow exception occurred.
   10391  1.1     is # we must set INEX/AINEX since the fmul/fdiv/fmov emulation may not!
   10392  1.1     is catch:
   10393  1.1     is 	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6)
   10394  1.1     is catch2:
   10395  1.1     is 	bsr.l		fgen_except
   10396  1.1     is 	add.l		&0xc,%sp
   10397  1.1     is 	rts
   10398  1.1     is 
   10399  1.1     is 	global		t_catch2
   10400  1.1     is t_catch2:
   10401  1.1     is 
   10402  1.1     is 	fsave		-(%sp)
   10403  1.1     is 
   10404  1.1     is 	tst.b		0x2(%sp)
   10405  1.1     is 	bmi.b		catch2
   10406  1.1     is 	add.l		&0xc,%sp
   10407  1.1     is 
   10408  1.1     is 	fmov.l		%fpsr,%d0
   10409  1.1     is 	or.l		%d0,USER_FPSR(%a6)
   10410  1.1     is 
   10411  1.1     is 	rts
   10412  1.1     is 
   10413  1.1     is #########################################################################
   10414  1.1     is 
   10415  1.1     is #########################################################################
   10416  1.1     is # unf_res(): underflow default result calculation for transcendentals	#
   10417  1.1     is #									#
   10418  1.1     is # INPUT:								#
   10419  1.1     is # 	d0   : rnd mode,precision					#
   10420  1.1     is # 	d1.b : sign bit of result ('11111111 = (-) ; '00000000 = (+))	#
   10421  1.1     is # OUTPUT:								#
   10422  1.1     is #	a0   : points to result (in instruction memory)			#
   10423  1.1     is #########################################################################
   10424  1.1     is unf_sub:
   10425  1.1     is 	ori.l		&unfinx_mask,USER_FPSR(%a6)
   10426  1.1     is 
   10427  1.1     is 	andi.w		&0x10,%d1		# keep sign bit in 4th spot
   10428  1.1     is 
   10429  1.1     is 	lsr.b		&0x4,%d0		# shift rnd prec,mode to lo bits
   10430  1.1     is 	andi.b		&0xf,%d0		# strip hi rnd mode bit
   10431  1.1     is 	or.b		%d1,%d0			# concat {sgn,mode,prec}
   10432  1.1     is 
   10433  1.1     is 	mov.l		%d0,%d1			# make a copy
   10434  1.1     is 	lsl.b		&0x1,%d1		# mult index 2 by 2
   10435  1.1     is 
   10436  1.1     is 	mov.b		(tbl_unf_cc.b,%pc,%d0.w*1),FPSR_CC(%a6) # insert ccode bits
   10437  1.1     is 	lea		(tbl_unf_result.b,%pc,%d1.w*8),%a0 # grab result ptr
   10438  1.1     is 	rts
   10439  1.1     is 
   10440  1.1     is tbl_unf_cc:
   10441  1.1     is 	byte		0x4, 0x4, 0x4, 0x0
   10442  1.1     is 	byte		0x4, 0x4, 0x4, 0x0
   10443  1.1     is 	byte		0x4, 0x4, 0x4, 0x0
   10444  1.1     is 	byte		0x0, 0x0, 0x0, 0x0
   10445  1.1     is 	byte		0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
   10446  1.1     is 	byte		0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
   10447  1.1     is 	byte		0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
   10448  1.1     is 
   10449  1.1     is tbl_unf_result:
   10450  1.1     is 	long		0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10451  1.1     is 	long		0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10452  1.1     is 	long		0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10453  1.1     is 	long		0x00000000, 0x00000000, 0x00000001, 0x0 # MIN; ext
   10454  1.1     is 
   10455  1.1     is 	long		0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10456  1.1     is 	long		0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10457  1.1     is 	long		0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10458  1.1     is 	long		0x3f810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl
   10459  1.1     is 
   10460  1.1     is 	long		0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10461  1.1     is 	long		0x3c010000, 0x00000000, 0x00000000, 0x0 # ZER0;dbl
   10462  1.1     is 	long		0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10463  1.1     is 	long		0x3c010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl
   10464  1.1     is 
   10465  1.1     is 	long		0x0,0x0,0x0,0x0
   10466  1.1     is 	long		0x0,0x0,0x0,0x0
   10467  1.1     is 	long		0x0,0x0,0x0,0x0
   10468  1.1     is 	long		0x0,0x0,0x0,0x0
   10469  1.1     is 
   10470  1.1     is 	long		0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10471  1.1     is 	long		0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10472  1.1     is 	long		0x80000000, 0x00000000, 0x00000001, 0x0 # MIN; ext
   10473  1.1     is 	long		0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10474  1.1     is 
   10475  1.1     is 	long		0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10476  1.1     is 	long		0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10477  1.1     is 	long		0xbf810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl
   10478  1.1     is 	long		0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10479  1.1     is 
   10480  1.1     is 	long		0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10481  1.1     is 	long		0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10482  1.1     is 	long		0xbc010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl
   10483  1.1     is 	long		0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10484  1.1     is 
   10485  1.1     is ############################################################
   10486  1.1     is 
   10487  1.1     is #########################################################################
   10488  1.1     is # src_zero(): Return signed zero according to sign of src operand.	#
   10489  1.1     is #########################################################################
   10490  1.1     is 	global		src_zero
   10491  1.1     is src_zero:
   10492  1.1     is 	tst.b		SRC_EX(%a0)		# get sign of src operand
   10493  1.1     is 	bmi.b		ld_mzero		# if neg, load neg zero
   10494  1.1     is 
   10495  1.1     is #
   10496  1.1     is # ld_pzero(): return a positive zero.
   10497  1.1     is #
   10498  1.1     is 	global		ld_pzero
   10499  1.1     is ld_pzero:
   10500  1.1     is 	fmov.s		&0x00000000,%fp0	# load +0
   10501  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   10502  1.1     is 	rts
   10503  1.1     is 
   10504  1.1     is # ld_mzero(): return a negative zero.
   10505  1.1     is 	global		ld_mzero
   10506  1.1     is ld_mzero:
   10507  1.1     is 	fmov.s		&0x80000000,%fp0	# load -0
   10508  1.1     is 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
   10509  1.1     is 	rts
   10510  1.1     is 
   10511  1.1     is #########################################################################
   10512  1.1     is # dst_zero(): Return signed zero according to sign of dst operand.	#
   10513  1.1     is #########################################################################
   10514  1.1     is 	global		dst_zero
   10515  1.1     is dst_zero:
   10516  1.1     is 	tst.b		DST_EX(%a1) 		# get sign of dst operand
   10517  1.1     is 	bmi.b		ld_mzero		# if neg, load neg zero
   10518  1.1     is 	bra.b		ld_pzero		# load positive zero
   10519  1.1     is 
   10520  1.1     is #########################################################################
   10521  1.1     is # src_inf(): Return signed inf according to sign of src operand.	#
   10522  1.1     is #########################################################################
   10523  1.1     is 	global		src_inf
   10524  1.1     is src_inf:
   10525  1.1     is 	tst.b		SRC_EX(%a0) 		# get sign of src operand
   10526  1.1     is 	bmi.b		ld_minf			# if negative branch
   10527  1.1     is 
   10528  1.1     is #
   10529  1.1     is # ld_pinf(): return a positive infinity.
   10530  1.1     is #
   10531  1.1     is 	global		ld_pinf
   10532  1.1     is ld_pinf:
   10533  1.1     is 	fmov.s		&0x7f800000,%fp0	# load +INF
   10534  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
   10535  1.1     is 	rts
   10536  1.1     is 
   10537  1.1     is #
   10538  1.1     is # ld_minf():return a negative infinity.
   10539  1.1     is #
   10540  1.1     is 	global		ld_minf
   10541  1.1     is ld_minf:
   10542  1.1     is 	fmov.s		&0xff800000,%fp0	# load -INF
   10543  1.1     is 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   10544  1.1     is 	rts
   10545  1.1     is 
   10546  1.1     is #########################################################################
   10547  1.1     is # dst_inf(): Return signed inf according to sign of dst operand.	#
   10548  1.1     is #########################################################################
   10549  1.1     is 	global		dst_inf
   10550  1.1     is dst_inf:
   10551  1.1     is 	tst.b		DST_EX(%a1) 		# get sign of dst operand
   10552  1.1     is 	bmi.b		ld_minf			# if negative branch
   10553  1.1     is 	bra.b		ld_pinf
   10554  1.1     is 
   10555  1.1     is 	global		szr_inf
   10556  1.1     is #################################################################
   10557  1.1     is # szr_inf(): Return +ZERO for a negative src operand or		#
   10558  1.1     is #	            +INF for a positive src operand.		#
   10559  1.1     is #	     Routine used for fetox, ftwotox, and ftentox.	#
   10560  1.1     is #################################################################
   10561  1.1     is szr_inf:
   10562  1.1     is 	tst.b		SRC_EX(%a0)		# check sign of source
   10563  1.1     is 	bmi.b		ld_pzero
   10564  1.1     is 	bra.b		ld_pinf
   10565  1.1     is 
   10566  1.1     is #########################################################################
   10567  1.1     is # sopr_inf(): Return +INF for a positive src operand or			#
   10568  1.1     is #	      jump to operand error routine for a negative src operand.	#
   10569  1.1     is #	      Routine used for flogn, flognp1, flog10, and flog2.	#
   10570  1.1     is #########################################################################
   10571  1.1     is 	global		sopr_inf
   10572  1.1     is sopr_inf:
   10573  1.1     is 	tst.b		SRC_EX(%a0)		# check sign of source
   10574  1.1     is 	bmi.w		t_operr
   10575  1.1     is 	bra.b		ld_pinf
   10576  1.1     is 
   10577  1.1     is #################################################################
   10578  1.1     is # setoxm1i(): Return minus one for a negative src operand or	#
   10579  1.1     is #	      positive infinity for a positive src operand.	#
   10580  1.1     is #	      Routine used for fetoxm1.				#
   10581  1.1     is #################################################################
   10582  1.1     is 	global		setoxm1i
   10583  1.1     is setoxm1i:
   10584  1.1     is 	tst.b		SRC_EX(%a0)		# check sign of source
   10585  1.1     is 	bmi.b		ld_mone
   10586  1.1     is 	bra.b		ld_pinf
   10587  1.1     is 
   10588  1.1     is #########################################################################
   10589  1.1     is # src_one(): Return signed one according to sign of src operand.	#
   10590  1.1     is #########################################################################
   10591  1.1     is 	global		src_one
   10592  1.1     is src_one:
   10593  1.1     is 	tst.b		SRC_EX(%a0) 		# check sign of source
   10594  1.1     is 	bmi.b		ld_mone
   10595  1.1     is 
   10596  1.1     is #
   10597  1.1     is # ld_pone(): return positive one.
   10598  1.1     is #
   10599  1.1     is 	global		ld_pone
   10600  1.1     is ld_pone:
   10601  1.1     is 	fmov.s		&0x3f800000,%fp0	# load +1
   10602  1.1     is 	clr.b		FPSR_CC(%a6)
   10603  1.1     is 	rts
   10604  1.1     is 
   10605  1.1     is #
   10606  1.1     is # ld_mone(): return negative one.
   10607  1.1     is #
   10608  1.1     is 	global		ld_mone
   10609  1.1     is ld_mone:
   10610  1.1     is 	fmov.s		&0xbf800000,%fp0	# load -1
   10611  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   10612  1.1     is 	rts
   10613  1.1     is 
   10614  1.1     is ppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
   10615  1.1     is mpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
   10616  1.1     is 
   10617  1.1     is #################################################################
   10618  1.1     is # spi_2(): Return signed PI/2 according to sign of src operand.	#
   10619  1.1     is #################################################################
   10620  1.1     is 	global		spi_2
   10621  1.1     is spi_2:
   10622  1.1     is 	tst.b		SRC_EX(%a0) 		# check sign of source
   10623  1.1     is 	bmi.b		ld_mpi2
   10624  1.1     is 
   10625  1.1     is #
   10626  1.1     is # ld_ppi2(): return positive PI/2.
   10627  1.1     is #
   10628  1.1     is 	global		ld_ppi2
   10629  1.1     is ld_ppi2:
   10630  1.1     is 	fmov.l		%d0,%fpcr
   10631  1.1     is 	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
   10632  1.1     is 	bra.w		t_pinx2			# set INEX2
   10633  1.1     is 
   10634  1.1     is #
   10635  1.1     is # ld_mpi2(): return negative PI/2.
   10636  1.1     is #
   10637  1.1     is 	global		ld_mpi2
   10638  1.1     is ld_mpi2:
   10639  1.1     is 	fmov.l		%d0,%fpcr
   10640  1.1     is 	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
   10641  1.1     is 	bra.w		t_minx2			# set INEX2
   10642  1.1     is 
   10643  1.1     is ####################################################
   10644  1.1     is # The following routines give support for fsincos. #
   10645  1.1     is ####################################################
   10646  1.1     is 
   10647  1.1     is #
   10648  1.1     is # ssincosz(): When the src operand is ZERO, store a one in the
   10649  1.1     is # 	      cosine register and return a ZERO in fp0 w/ the same sign
   10650  1.1     is #	      as the src operand.
   10651  1.1     is #
   10652  1.1     is 	global		ssincosz
   10653  1.1     is ssincosz:
   10654  1.1     is 	fmov.s		&0x3f800000,%fp1
   10655  1.1     is 	tst.b		SRC_EX(%a0)		# test sign
   10656  1.1     is 	bpl.b		sincoszp
   10657  1.1     is 	fmov.s		&0x80000000,%fp0	# return sin result in fp0
   10658  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
   10659  1.1     is 	bra.b		sto_cos			# store cosine result
   10660  1.1     is sincoszp:
   10661  1.1     is 	fmov.s		&0x00000000,%fp0	# return sin result in fp0
   10662  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)
   10663  1.1     is 	bra.b		sto_cos			# store cosine result
   10664  1.1     is 
   10665  1.1     is #
   10666  1.1     is # ssincosi(): When the src operand is INF, store a QNAN in the cosine
   10667  1.1     is #	      register and jump to the operand error routine for negative
   10668  1.1     is #	      src operands.
   10669  1.1     is #
   10670  1.1     is 	global		ssincosi
   10671  1.1     is ssincosi:
   10672  1.1     is 	fmov.x		qnan(%pc),%fp1		# load NAN
   10673  1.1     is 	bsr.l		sto_cos			# store cosine result
   10674  1.1     is 	bra.w		t_operr
   10675  1.1     is 
   10676  1.1     is #
   10677  1.1     is # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
   10678  1.1     is # 		 register and branch to the src QNAN routine.
   10679  1.1     is #
   10680  1.1     is 	global		ssincosqnan
   10681  1.1     is ssincosqnan:
   10682  1.1     is 	fmov.x		LOCAL_EX(%a0),%fp1
   10683  1.1     is 	bsr.l		sto_cos
   10684  1.1     is 	bra.w		src_qnan
   10685  1.1     is 
   10686  1.1     is #
   10687  1.1     is # ssincossnan(): When the src operand is an SNAN, store the SNAN w/ the SNAN bit set
   10688  1.1     is #		 in the cosine register and branch to the src SNAN routine.
   10689  1.1     is #
   10690  1.1     is 	global		ssincossnan
   10691  1.1     is ssincossnan:
   10692  1.1     is 	fmov.x		LOCAL_EX(%a0),%fp1
   10693  1.1     is 	bsr.l		sto_cos
   10694  1.1     is 	bra.w		src_snan
   10695  1.1     is 
   10696  1.1     is ########################################################################
   10697  1.1     is 
   10698  1.1     is #########################################################################
   10699  1.1     is # sto_cos(): store fp1 to the fpreg designated by the CMDREG dst field.	#
   10700  1.1     is #	     fp1 holds the result of the cosine portion of ssincos().	#
   10701  1.1     is #	     the value in fp1 will not take any exceptions when moved.	#
   10702  1.1     is # INPUT:								#
   10703  1.1     is #	fp1 : fp value to store						#
   10704  1.1     is # MODIFIED:								#
   10705  1.1     is #	d0								#
   10706  1.1     is #########################################################################
   10707  1.1     is 	global		sto_cos
   10708  1.1     is sto_cos:
   10709  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d0
   10710  1.1     is 	andi.w		&0x7,%d0
   10711  1.1     is 	mov.w		(tbl_sto_cos.b,%pc,%d0.w*2),%d0
   10712  1.1     is 	jmp		(tbl_sto_cos.b,%pc,%d0.w*1)
   10713  1.1     is 
   10714  1.1     is tbl_sto_cos:
   10715  1.1     is 	short		sto_cos_0 - tbl_sto_cos
   10716  1.1     is 	short		sto_cos_1 - tbl_sto_cos
   10717  1.1     is 	short		sto_cos_2 - tbl_sto_cos
   10718  1.1     is 	short		sto_cos_3 - tbl_sto_cos
   10719  1.1     is 	short		sto_cos_4 - tbl_sto_cos
   10720  1.1     is 	short		sto_cos_5 - tbl_sto_cos
   10721  1.1     is 	short		sto_cos_6 - tbl_sto_cos
   10722  1.1     is 	short		sto_cos_7 - tbl_sto_cos
   10723  1.1     is 
   10724  1.1     is sto_cos_0:
   10725  1.1     is 	fmovm.x		&0x40,EXC_FP0(%a6)
   10726  1.1     is 	rts
   10727  1.1     is sto_cos_1:
   10728  1.1     is 	fmovm.x		&0x40,EXC_FP1(%a6)
   10729  1.1     is 	rts
   10730  1.1     is sto_cos_2:
   10731  1.1     is 	fmov.x 		%fp1,%fp2
   10732  1.1     is 	rts
   10733  1.1     is sto_cos_3:
   10734  1.1     is 	fmov.x		%fp1,%fp3
   10735  1.1     is 	rts
   10736  1.1     is sto_cos_4:
   10737  1.1     is 	fmov.x		%fp1,%fp4
   10738  1.1     is 	rts
   10739  1.1     is sto_cos_5:
   10740  1.1     is 	fmov.x		%fp1,%fp5
   10741  1.1     is 	rts
   10742  1.1     is sto_cos_6:
   10743  1.1     is 	fmov.x		%fp1,%fp6
   10744  1.1     is 	rts
   10745  1.1     is sto_cos_7:
   10746  1.1     is 	fmov.x		%fp1,%fp7
   10747  1.1     is 	rts
   10748  1.1     is 
   10749  1.1     is ##################################################################
   10750  1.1     is 	global		smod_sdnrm
   10751  1.1     is 	global		smod_snorm
   10752  1.1     is smod_sdnrm:
   10753  1.1     is smod_snorm:
   10754  1.1     is 	mov.b		DTAG(%a6),%d1
   10755  1.1     is 	beq.l		smod
   10756  1.1     is 	cmpi.b		%d1,&ZERO
   10757  1.1     is 	beq.w		smod_zro
   10758  1.1     is 	cmpi.b		%d1,&INF
   10759  1.1     is 	beq.l		t_operr
   10760  1.1     is 	cmpi.b		%d1,&DENORM
   10761  1.1     is 	beq.l		smod
   10762  1.1     is 	cmpi.b		%d1,&SNAN
   10763  1.1     is 	beq.l		dst_snan
   10764  1.1     is 	bra.l		dst_qnan
   10765  1.1     is 
   10766  1.1     is 	global		smod_szero
   10767  1.1     is smod_szero:
   10768  1.1     is 	mov.b		DTAG(%a6),%d1
   10769  1.1     is 	beq.l		t_operr
   10770  1.1     is 	cmpi.b		%d1,&ZERO
   10771  1.1     is 	beq.l		t_operr
   10772  1.1     is 	cmpi.b		%d1,&INF
   10773  1.1     is 	beq.l		t_operr
   10774  1.1     is 	cmpi.b		%d1,&DENORM
   10775  1.1     is 	beq.l		t_operr
   10776  1.1     is 	cmpi.b		%d1,&QNAN
   10777  1.1     is 	beq.l		dst_qnan
   10778  1.1     is 	bra.l		dst_snan
   10779  1.1     is 
   10780  1.1     is 	global		smod_sinf
   10781  1.1     is smod_sinf:
   10782  1.1     is 	mov.b		DTAG(%a6),%d1
   10783  1.1     is 	beq.l		smod_fpn
   10784  1.1     is 	cmpi.b		%d1,&ZERO
   10785  1.1     is 	beq.l		smod_zro
   10786  1.1     is 	cmpi.b		%d1,&INF
   10787  1.1     is 	beq.l		t_operr
   10788  1.1     is 	cmpi.b		%d1,&DENORM
   10789  1.1     is 	beq.l		smod_fpn
   10790  1.1     is 	cmpi.b		%d1,&QNAN
   10791  1.1     is 	beq.l		dst_qnan
   10792  1.1     is 	bra.l		dst_snan
   10793  1.1     is 
   10794  1.1     is smod_zro:
   10795  1.1     is srem_zro:
   10796  1.1     is 	mov.b		SRC_EX(%a0),%d1		# get src sign
   10797  1.1     is 	mov.b		DST_EX(%a1),%d0		# get dst sign
   10798  1.1     is 	eor.b		%d0,%d1			# get qbyte sign
   10799  1.1     is 	andi.b		&0x80,%d1
   10800  1.1     is 	mov.b		%d1,FPSR_QBYTE(%a6)
   10801  1.1     is 	tst.b		%d0
   10802  1.1     is 	bpl.w		ld_pzero
   10803  1.1     is 	bra.w		ld_mzero
   10804  1.1     is 
   10805  1.1     is smod_fpn:
   10806  1.1     is srem_fpn:
   10807  1.1     is 	clr.b		FPSR_QBYTE(%a6)
   10808  1.1     is 	mov.l		%d0,-(%sp)
   10809  1.1     is 	mov.b		SRC_EX(%a0),%d1		# get src sign
   10810  1.1     is 	mov.b		DST_EX(%a1),%d0		# get dst sign
   10811  1.1     is 	eor.b		%d0,%d1			# get qbyte sign
   10812  1.1     is 	andi.b		&0x80,%d1
   10813  1.1     is 	mov.b		%d1,FPSR_QBYTE(%a6)
   10814  1.1     is 	cmpi.b		DTAG(%a6),&DENORM
   10815  1.1     is 	bne.b		smod_nrm
   10816  1.1     is 	lea		DST(%a1),%a0
   10817  1.1     is 	mov.l		(%sp)+,%d0
   10818  1.1     is 	bra		t_resdnrm
   10819  1.1     is smod_nrm:
   10820  1.1     is 	fmov.l		(%sp)+,%fpcr
   10821  1.1     is 	fmov.x		DST(%a1),%fp0
   10822  1.1     is 	tst.b		DST_EX(%a1)
   10823  1.1     is 	bmi.b		smod_nrm_neg
   10824  1.1     is 	rts
   10825  1.1     is 
   10826  1.1     is smod_nrm_neg:
   10827  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode
   10828  1.1     is 	rts
   10829  1.1     is 
   10830  1.1     is #########################################################################
   10831  1.1     is 	global		srem_snorm
   10832  1.1     is 	global		srem_sdnrm
   10833  1.1     is srem_sdnrm:
   10834  1.1     is srem_snorm:
   10835  1.1     is 	mov.b		DTAG(%a6),%d1
   10836  1.1     is 	beq.l		srem
   10837  1.1     is 	cmpi.b		%d1,&ZERO
   10838  1.1     is 	beq.w		srem_zro
   10839  1.1     is 	cmpi.b		%d1,&INF
   10840  1.1     is 	beq.l		t_operr
   10841  1.1     is 	cmpi.b		%d1,&DENORM
   10842  1.1     is 	beq.l		srem
   10843  1.1     is 	cmpi.b		%d1,&QNAN
   10844  1.1     is 	beq.l		dst_qnan
   10845  1.1     is 	bra.l		dst_snan
   10846  1.1     is 
   10847  1.1     is 	global		srem_szero
   10848  1.1     is srem_szero:
   10849  1.1     is 	mov.b		DTAG(%a6),%d1
   10850  1.1     is 	beq.l		t_operr
   10851  1.1     is 	cmpi.b		%d1,&ZERO
   10852  1.1     is 	beq.l		t_operr
   10853  1.1     is 	cmpi.b		%d1,&INF
   10854  1.1     is 	beq.l		t_operr
   10855  1.1     is 	cmpi.b		%d1,&DENORM
   10856  1.1     is 	beq.l		t_operr
   10857  1.1     is 	cmpi.b		%d1,&QNAN
   10858  1.1     is 	beq.l		dst_qnan
   10859  1.1     is 	bra.l		dst_snan
   10860  1.1     is 
   10861  1.1     is 	global		srem_sinf
   10862  1.1     is srem_sinf:
   10863  1.1     is 	mov.b		DTAG(%a6),%d1
   10864  1.1     is 	beq.w		srem_fpn
   10865  1.1     is 	cmpi.b		%d1,&ZERO
   10866  1.1     is 	beq.w		srem_zro
   10867  1.1     is 	cmpi.b		%d1,&INF
   10868  1.1     is 	beq.l		t_operr
   10869  1.1     is 	cmpi.b		%d1,&DENORM
   10870  1.1     is 	beq.l		srem_fpn
   10871  1.1     is 	cmpi.b		%d1,&QNAN
   10872  1.1     is 	beq.l		dst_qnan
   10873  1.1     is 	bra.l		dst_snan
   10874  1.1     is 
   10875  1.1     is #########################################################################
   10876  1.1     is 	global		sscale_snorm
   10877  1.1     is 	global		sscale_sdnrm
   10878  1.1     is sscale_snorm:
   10879  1.1     is sscale_sdnrm:
   10880  1.1     is 	mov.b		DTAG(%a6),%d1
   10881  1.1     is 	beq.l		sscale
   10882  1.1     is 	cmpi.b		%d1,&ZERO
   10883  1.1     is 	beq.l		dst_zero
   10884  1.1     is 	cmpi.b		%d1,&INF
   10885  1.1     is 	beq.l		dst_inf
   10886  1.1     is 	cmpi.b		%d1,&DENORM
   10887  1.1     is 	beq.l		sscale
   10888  1.1     is 	cmpi.b		%d1,&QNAN
   10889  1.1     is 	beq.l		dst_qnan
   10890  1.1     is 	bra.l		dst_snan
   10891  1.1     is 
   10892  1.1     is 	global		sscale_szero
   10893  1.1     is sscale_szero:
   10894  1.1     is 	mov.b		DTAG(%a6),%d1
   10895  1.1     is 	beq.l		sscale
   10896  1.1     is 	cmpi.b		%d1,&ZERO
   10897  1.1     is 	beq.l		dst_zero
   10898  1.1     is 	cmpi.b		%d1,&INF
   10899  1.1     is 	beq.l		dst_inf
   10900  1.1     is 	cmpi.b		%d1,&DENORM
   10901  1.1     is 	beq.l		sscale
   10902  1.1     is 	cmpi.b		%d1,&QNAN
   10903  1.1     is 	beq.l		dst_qnan
   10904  1.1     is 	bra.l		dst_snan
   10905  1.1     is 
   10906  1.1     is 	global		sscale_sinf
   10907  1.1     is sscale_sinf:
   10908  1.1     is 	mov.b		DTAG(%a6),%d1
   10909  1.1     is 	beq.l		t_operr
   10910  1.1     is 	cmpi.b		%d1,&QNAN
   10911  1.1     is 	beq.l		dst_qnan
   10912  1.1     is 	cmpi.b		%d1,&SNAN
   10913  1.1     is 	beq.l		dst_snan
   10914  1.1     is 	bra.l		t_operr
   10915  1.1     is 
   10916  1.1     is ########################################################################
   10917  1.1     is 
   10918  1.1     is #
   10919  1.1     is # sop_sqnan(): The src op for frem/fmod/fscale was a QNAN.
   10920  1.1     is #
   10921  1.1     is 	global		sop_sqnan
   10922  1.1     is sop_sqnan:
   10923  1.1     is 	mov.b		DTAG(%a6),%d1
   10924  1.1     is 	cmpi.b		%d1,&QNAN
   10925  1.1     is 	beq.b		dst_qnan
   10926  1.1     is 	cmpi.b		%d1,&SNAN
   10927  1.1     is 	beq.b		dst_snan
   10928  1.1     is 	bra.b		src_qnan
   10929  1.1     is 
   10930  1.1     is #
   10931  1.1     is # sop_ssnan(): The src op for frem/fmod/fscale was an SNAN.
   10932  1.1     is #
   10933  1.1     is 	global		sop_ssnan
   10934  1.1     is sop_ssnan:
   10935  1.1     is 	mov.b		DTAG(%a6),%d1
   10936  1.1     is 	cmpi.b		%d1,&QNAN
   10937  1.1     is 	beq.b		dst_qnan_src_snan
   10938  1.1     is 	cmpi.b		%d1,&SNAN
   10939  1.1     is 	beq.b		dst_snan
   10940  1.1     is 	bra.b		src_snan
   10941  1.1     is 
   10942  1.1     is dst_qnan_src_snan:
   10943  1.1     is 	ori.l		&snaniop_mask,USER_FPSR(%a6) # set NAN/SNAN/AIOP
   10944  1.1     is 	bra.b		dst_qnan
   10945  1.1     is 
   10946  1.1     is #
   10947  1.1     is # dst_qnan(): Return the dst SNAN w/ the SNAN bit set.
   10948  1.1     is #
   10949  1.1     is 	global		dst_snan
   10950  1.1     is dst_snan:
   10951  1.1     is 	fmov.x		DST(%a1),%fp0		# the fmove sets the SNAN bit
   10952  1.1     is 	fmov.l		%fpsr,%d0		# catch resulting status
   10953  1.1     is 	or.l		%d0,USER_FPSR(%a6)	# store status
   10954  1.1     is 	rts
   10955  1.1     is 
   10956  1.1     is #
   10957  1.1     is # dst_qnan(): Return the dst QNAN.
   10958  1.1     is #
   10959  1.1     is 	global		dst_qnan
   10960  1.1     is dst_qnan:
   10961  1.1     is 	fmov.x		DST(%a1),%fp0		# return the non-signalling nan
   10962  1.1     is 	tst.b		DST_EX(%a1)		# set ccodes according to QNAN sign
   10963  1.1     is 	bmi.b		dst_qnan_m
   10964  1.1     is dst_qnan_p:
   10965  1.1     is 	mov.b		&nan_bmask,FPSR_CC(%a6)
   10966  1.1     is 	rts
   10967  1.1     is dst_qnan_m:
   10968  1.1     is 	mov.b		&neg_bmask+nan_bmask,FPSR_CC(%a6)
   10969  1.1     is 	rts
   10970  1.1     is 
   10971  1.1     is #
   10972  1.1     is # src_snan(): Return the src SNAN w/ the SNAN bit set.
   10973  1.1     is #
   10974  1.1     is 	global		src_snan
   10975  1.1     is src_snan:
   10976  1.1     is 	fmov.x		SRC(%a0),%fp0		# the fmove sets the SNAN bit
   10977  1.1     is 	fmov.l		%fpsr,%d0		# catch resulting status
   10978  1.1     is 	or.l		%d0,USER_FPSR(%a6)	# store status
   10979  1.1     is 	rts
   10980  1.1     is 
   10981  1.1     is #
   10982  1.1     is # src_qnan(): Return the src QNAN.
   10983  1.1     is #
   10984  1.1     is 	global		src_qnan
   10985  1.1     is src_qnan:
   10986  1.1     is 	fmov.x		SRC(%a0),%fp0		# return the non-signalling nan
   10987  1.1     is 	tst.b		SRC_EX(%a0)		# set ccodes according to QNAN sign
   10988  1.1     is 	bmi.b		dst_qnan_m
   10989  1.1     is src_qnan_p:
   10990  1.1     is 	mov.b		&nan_bmask,FPSR_CC(%a6)
   10991  1.1     is 	rts
   10992  1.1     is src_qnan_m:
   10993  1.1     is 	mov.b		&neg_bmask+nan_bmask,FPSR_CC(%a6)
   10994  1.1     is 	rts
   10995  1.1     is 
   10996  1.1     is #
   10997  1.1     is # fkern2.s:
   10998  1.1     is #	These entry points are used by the exception handler
   10999  1.1     is # routines where an instruction is selected by an index into
   11000  1.1     is # a large jump table corresponding to a given instruction which
   11001  1.1     is # has been decoded. Flow continues here where we now decode
   11002  1.1     is # further accoding to the source operand type.
   11003  1.1     is #
   11004  1.1     is 
   11005  1.1     is 	global		fsinh
   11006  1.1     is fsinh:
   11007  1.1     is 	mov.b		STAG(%a6),%d1
   11008  1.1     is 	beq.l		ssinh
   11009  1.1     is 	cmpi.b		%d1,&ZERO
   11010  1.1     is 	beq.l		src_zero
   11011  1.1     is 	cmpi.b		%d1,&INF
   11012  1.1     is 	beq.l		src_inf
   11013  1.1     is 	cmpi.b		%d1,&DENORM
   11014  1.1     is 	beq.l		ssinhd
   11015  1.1     is 	cmpi.b		%d1,&QNAN
   11016  1.1     is 	beq.l		src_qnan
   11017  1.1     is 	bra.l		src_snan
   11018  1.1     is 
   11019  1.1     is 	global		flognp1
   11020  1.1     is flognp1:
   11021  1.1     is 	mov.b		STAG(%a6),%d1
   11022  1.1     is 	beq.l		slognp1
   11023  1.1     is 	cmpi.b		%d1,&ZERO
   11024  1.1     is 	beq.l		src_zero
   11025  1.1     is 	cmpi.b		%d1,&INF
   11026  1.1     is 	beq.l		sopr_inf
   11027  1.1     is 	cmpi.b		%d1,&DENORM
   11028  1.1     is 	beq.l		slognp1d
   11029  1.1     is 	cmpi.b		%d1,&QNAN
   11030  1.1     is 	beq.l		src_qnan
   11031  1.1     is 	bra.l		src_snan
   11032  1.1     is 
   11033  1.1     is 	global		fetoxm1
   11034  1.1     is fetoxm1:
   11035  1.1     is 	mov.b		STAG(%a6),%d1
   11036  1.1     is 	beq.l		setoxm1
   11037  1.1     is 	cmpi.b		%d1,&ZERO
   11038  1.1     is 	beq.l		src_zero
   11039  1.1     is 	cmpi.b		%d1,&INF
   11040  1.1     is 	beq.l		setoxm1i
   11041  1.1     is 	cmpi.b		%d1,&DENORM
   11042  1.1     is 	beq.l		setoxm1d
   11043  1.1     is 	cmpi.b		%d1,&QNAN
   11044  1.1     is 	beq.l		src_qnan
   11045  1.1     is 	bra.l		src_snan
   11046  1.1     is 
   11047  1.1     is 	global		ftanh
   11048  1.1     is ftanh:
   11049  1.1     is 	mov.b		STAG(%a6),%d1
   11050  1.1     is 	beq.l		stanh
   11051  1.1     is 	cmpi.b		%d1,&ZERO
   11052  1.1     is 	beq.l		src_zero
   11053  1.1     is 	cmpi.b		%d1,&INF
   11054  1.1     is 	beq.l		src_one
   11055  1.1     is 	cmpi.b		%d1,&DENORM
   11056  1.1     is 	beq.l		stanhd
   11057  1.1     is 	cmpi.b		%d1,&QNAN
   11058  1.1     is 	beq.l		src_qnan
   11059  1.1     is 	bra.l		src_snan
   11060  1.1     is 
   11061  1.1     is 	global		fatan
   11062  1.1     is fatan:
   11063  1.1     is 	mov.b		STAG(%a6),%d1
   11064  1.1     is 	beq.l		satan
   11065  1.1     is 	cmpi.b		%d1,&ZERO
   11066  1.1     is 	beq.l		src_zero
   11067  1.1     is 	cmpi.b		%d1,&INF
   11068  1.1     is 	beq.l		spi_2
   11069  1.1     is 	cmpi.b		%d1,&DENORM
   11070  1.1     is 	beq.l		satand
   11071  1.1     is 	cmpi.b		%d1,&QNAN
   11072  1.1     is 	beq.l		src_qnan
   11073  1.1     is 	bra.l		src_snan
   11074  1.1     is 
   11075  1.1     is 	global		fasin
   11076  1.1     is fasin:
   11077  1.1     is 	mov.b		STAG(%a6),%d1
   11078  1.1     is 	beq.l		sasin
   11079  1.1     is 	cmpi.b		%d1,&ZERO
   11080  1.1     is 	beq.l		src_zero
   11081  1.1     is 	cmpi.b		%d1,&INF
   11082  1.1     is 	beq.l		t_operr
   11083  1.1     is 	cmpi.b		%d1,&DENORM
   11084  1.1     is 	beq.l		sasind
   11085  1.1     is 	cmpi.b		%d1,&QNAN
   11086  1.1     is 	beq.l		src_qnan
   11087  1.1     is 	bra.l		src_snan
   11088  1.1     is 
   11089  1.1     is 	global		fatanh
   11090  1.1     is fatanh:
   11091  1.1     is 	mov.b		STAG(%a6),%d1
   11092  1.1     is 	beq.l		satanh
   11093  1.1     is 	cmpi.b		%d1,&ZERO
   11094  1.1     is 	beq.l		src_zero
   11095  1.1     is 	cmpi.b		%d1,&INF
   11096  1.1     is 	beq.l		t_operr
   11097  1.1     is 	cmpi.b		%d1,&DENORM
   11098  1.1     is 	beq.l		satanhd
   11099  1.1     is 	cmpi.b		%d1,&QNAN
   11100  1.1     is 	beq.l		src_qnan
   11101  1.1     is 	bra.l		src_snan
   11102  1.1     is 
   11103  1.1     is 	global		fsine
   11104  1.1     is fsine:
   11105  1.1     is 	mov.b		STAG(%a6),%d1
   11106  1.1     is 	beq.l		ssin
   11107  1.1     is 	cmpi.b		%d1,&ZERO
   11108  1.1     is 	beq.l		src_zero
   11109  1.1     is 	cmpi.b		%d1,&INF
   11110  1.1     is 	beq.l		t_operr
   11111  1.1     is 	cmpi.b		%d1,&DENORM
   11112  1.1     is 	beq.l		ssind
   11113  1.1     is 	cmpi.b		%d1,&QNAN
   11114  1.1     is 	beq.l		src_qnan
   11115  1.1     is 	bra.l		src_snan
   11116  1.1     is 
   11117  1.1     is 	global		ftan
   11118  1.1     is ftan:
   11119  1.1     is 	mov.b		STAG(%a6),%d1
   11120  1.1     is 	beq.l		stan
   11121  1.1     is 	cmpi.b		%d1,&ZERO
   11122  1.1     is 	beq.l		src_zero
   11123  1.1     is 	cmpi.b		%d1,&INF
   11124  1.1     is 	beq.l		t_operr
   11125  1.1     is 	cmpi.b		%d1,&DENORM
   11126  1.1     is 	beq.l		stand
   11127  1.1     is 	cmpi.b		%d1,&QNAN
   11128  1.1     is 	beq.l		src_qnan
   11129  1.1     is 	bra.l		src_snan
   11130  1.1     is 
   11131  1.1     is 	global		fetox
   11132  1.1     is fetox:
   11133  1.1     is 	mov.b		STAG(%a6),%d1
   11134  1.1     is 	beq.l		setox
   11135  1.1     is 	cmpi.b		%d1,&ZERO
   11136  1.1     is 	beq.l		ld_pone
   11137  1.1     is 	cmpi.b		%d1,&INF
   11138  1.1     is 	beq.l		szr_inf
   11139  1.1     is 	cmpi.b		%d1,&DENORM
   11140  1.1     is 	beq.l		setoxd
   11141  1.1     is 	cmpi.b		%d1,&QNAN
   11142  1.1     is 	beq.l		src_qnan
   11143  1.1     is 	bra.l		src_snan
   11144  1.1     is 
   11145  1.1     is 	global		ftwotox
   11146  1.1     is ftwotox:
   11147  1.1     is 	mov.b		STAG(%a6),%d1
   11148  1.1     is 	beq.l		stwotox
   11149  1.1     is 	cmpi.b		%d1,&ZERO
   11150  1.1     is 	beq.l		ld_pone
   11151  1.1     is 	cmpi.b		%d1,&INF
   11152  1.1     is 	beq.l		szr_inf
   11153  1.1     is 	cmpi.b		%d1,&DENORM
   11154  1.1     is 	beq.l		stwotoxd
   11155  1.1     is 	cmpi.b		%d1,&QNAN
   11156  1.1     is 	beq.l		src_qnan
   11157  1.1     is 	bra.l		src_snan
   11158  1.1     is 
   11159  1.1     is 	global		ftentox
   11160  1.1     is ftentox:
   11161  1.1     is 	mov.b		STAG(%a6),%d1
   11162  1.1     is 	beq.l		stentox
   11163  1.1     is 	cmpi.b		%d1,&ZERO
   11164  1.1     is 	beq.l		ld_pone
   11165  1.1     is 	cmpi.b		%d1,&INF
   11166  1.1     is 	beq.l		szr_inf
   11167  1.1     is 	cmpi.b		%d1,&DENORM
   11168  1.1     is 	beq.l		stentoxd
   11169  1.1     is 	cmpi.b		%d1,&QNAN
   11170  1.1     is 	beq.l		src_qnan
   11171  1.1     is 	bra.l		src_snan
   11172  1.1     is 
   11173  1.1     is 	global		flogn
   11174  1.1     is flogn:
   11175  1.1     is 	mov.b		STAG(%a6),%d1
   11176  1.1     is 	beq.l		slogn
   11177  1.1     is 	cmpi.b		%d1,&ZERO
   11178  1.1     is 	beq.l		t_dz2
   11179  1.1     is 	cmpi.b		%d1,&INF
   11180  1.1     is 	beq.l		sopr_inf
   11181  1.1     is 	cmpi.b		%d1,&DENORM
   11182  1.1     is 	beq.l		slognd
   11183  1.1     is 	cmpi.b		%d1,&QNAN
   11184  1.1     is 	beq.l		src_qnan
   11185  1.1     is 	bra.l		src_snan
   11186  1.1     is 
   11187  1.1     is 	global		flog10
   11188  1.1     is flog10:
   11189  1.1     is 	mov.b		STAG(%a6),%d1
   11190  1.1     is 	beq.l		slog10
   11191  1.1     is 	cmpi.b		%d1,&ZERO
   11192  1.1     is 	beq.l		t_dz2
   11193  1.1     is 	cmpi.b		%d1,&INF
   11194  1.1     is 	beq.l		sopr_inf
   11195  1.1     is 	cmpi.b		%d1,&DENORM
   11196  1.1     is 	beq.l		slog10d
   11197  1.1     is 	cmpi.b		%d1,&QNAN
   11198  1.1     is 	beq.l		src_qnan
   11199  1.1     is 	bra.l		src_snan
   11200  1.1     is 
   11201  1.1     is 	global		flog2
   11202  1.1     is flog2:
   11203  1.1     is 	mov.b		STAG(%a6),%d1
   11204  1.1     is 	beq.l		slog2
   11205  1.1     is 	cmpi.b		%d1,&ZERO
   11206  1.1     is 	beq.l		t_dz2
   11207  1.1     is 	cmpi.b		%d1,&INF
   11208  1.1     is 	beq.l		sopr_inf
   11209  1.1     is 	cmpi.b		%d1,&DENORM
   11210  1.1     is 	beq.l		slog2d
   11211  1.1     is 	cmpi.b		%d1,&QNAN
   11212  1.1     is 	beq.l		src_qnan
   11213  1.1     is 	bra.l		src_snan
   11214  1.1     is 
   11215  1.1     is 	global		fcosh
   11216  1.1     is fcosh:
   11217  1.1     is 	mov.b		STAG(%a6),%d1
   11218  1.1     is 	beq.l		scosh
   11219  1.1     is 	cmpi.b		%d1,&ZERO
   11220  1.1     is 	beq.l		ld_pone
   11221  1.1     is 	cmpi.b		%d1,&INF
   11222  1.1     is 	beq.l		ld_pinf
   11223  1.1     is 	cmpi.b		%d1,&DENORM
   11224  1.1     is 	beq.l		scoshd
   11225  1.1     is 	cmpi.b		%d1,&QNAN
   11226  1.1     is 	beq.l		src_qnan
   11227  1.1     is 	bra.l		src_snan
   11228  1.1     is 
   11229  1.1     is 	global		facos
   11230  1.1     is facos:
   11231  1.1     is 	mov.b		STAG(%a6),%d1
   11232  1.1     is 	beq.l		sacos
   11233  1.1     is 	cmpi.b		%d1,&ZERO
   11234  1.1     is 	beq.l		ld_ppi2
   11235  1.1     is 	cmpi.b		%d1,&INF
   11236  1.1     is 	beq.l		t_operr
   11237  1.1     is 	cmpi.b		%d1,&DENORM
   11238  1.1     is 	beq.l		sacosd
   11239  1.1     is 	cmpi.b		%d1,&QNAN
   11240  1.1     is 	beq.l		src_qnan
   11241  1.1     is 	bra.l		src_snan
   11242  1.1     is 
   11243  1.1     is 	global		fcos
   11244  1.1     is fcos:
   11245  1.1     is 	mov.b		STAG(%a6),%d1
   11246  1.1     is 	beq.l		scos
   11247  1.1     is 	cmpi.b		%d1,&ZERO
   11248  1.1     is 	beq.l		ld_pone
   11249  1.1     is 	cmpi.b		%d1,&INF
   11250  1.1     is 	beq.l		t_operr
   11251  1.1     is 	cmpi.b		%d1,&DENORM
   11252  1.1     is 	beq.l		scosd
   11253  1.1     is 	cmpi.b		%d1,&QNAN
   11254  1.1     is 	beq.l		src_qnan
   11255  1.1     is 	bra.l		src_snan
   11256  1.1     is 
   11257  1.1     is 	global		fgetexp
   11258  1.1     is fgetexp:
   11259  1.1     is 	mov.b		STAG(%a6),%d1
   11260  1.1     is 	beq.l		sgetexp
   11261  1.1     is 	cmpi.b		%d1,&ZERO
   11262  1.1     is 	beq.l		src_zero
   11263  1.1     is 	cmpi.b		%d1,&INF
   11264  1.1     is 	beq.l		t_operr
   11265  1.1     is 	cmpi.b		%d1,&DENORM
   11266  1.1     is 	beq.l		sgetexpd
   11267  1.1     is 	cmpi.b		%d1,&QNAN
   11268  1.1     is 	beq.l		src_qnan
   11269  1.1     is 	bra.l		src_snan
   11270  1.1     is 
   11271  1.1     is 	global		fgetman
   11272  1.1     is fgetman:
   11273  1.1     is 	mov.b		STAG(%a6),%d1
   11274  1.1     is 	beq.l		sgetman
   11275  1.1     is 	cmpi.b		%d1,&ZERO
   11276  1.1     is 	beq.l		src_zero
   11277  1.1     is 	cmpi.b		%d1,&INF
   11278  1.1     is 	beq.l		t_operr
   11279  1.1     is 	cmpi.b		%d1,&DENORM
   11280  1.1     is 	beq.l		sgetmand
   11281  1.1     is 	cmpi.b		%d1,&QNAN
   11282  1.1     is 	beq.l		src_qnan
   11283  1.1     is 	bra.l		src_snan
   11284  1.1     is 
   11285  1.1     is 	global		fsincos
   11286  1.1     is fsincos:
   11287  1.1     is 	mov.b		STAG(%a6),%d1
   11288  1.1     is 	beq.l		ssincos
   11289  1.1     is 	cmpi.b		%d1,&ZERO
   11290  1.1     is 	beq.l		ssincosz
   11291  1.1     is 	cmpi.b		%d1,&INF
   11292  1.1     is 	beq.l		ssincosi
   11293  1.1     is 	cmpi.b		%d1,&DENORM
   11294  1.1     is 	beq.l		ssincosd
   11295  1.1     is 	cmpi.b		%d1,&QNAN
   11296  1.1     is 	beq.l		ssincosqnan
   11297  1.1     is 	bra.l		ssincossnan
   11298  1.1     is 
   11299  1.1     is 	global		fmod
   11300  1.1     is fmod:
   11301  1.1     is 	mov.b		STAG(%a6),%d1
   11302  1.1     is 	beq.l		smod_snorm
   11303  1.1     is 	cmpi.b		%d1,&ZERO
   11304  1.1     is 	beq.l		smod_szero
   11305  1.1     is 	cmpi.b		%d1,&INF
   11306  1.1     is 	beq.l		smod_sinf
   11307  1.1     is 	cmpi.b		%d1,&DENORM
   11308  1.1     is 	beq.l		smod_sdnrm
   11309  1.1     is 	cmpi.b		%d1,&QNAN
   11310  1.1     is 	beq.l		sop_sqnan
   11311  1.1     is 	bra.l		sop_ssnan
   11312  1.1     is 
   11313  1.1     is 	global		frem
   11314  1.1     is frem:
   11315  1.1     is 	mov.b		STAG(%a6),%d1
   11316  1.1     is 	beq.l		srem_snorm
   11317  1.1     is 	cmpi.b		%d1,&ZERO
   11318  1.1     is 	beq.l		srem_szero
   11319  1.1     is 	cmpi.b		%d1,&INF
   11320  1.1     is 	beq.l		srem_sinf
   11321  1.1     is 	cmpi.b		%d1,&DENORM
   11322  1.1     is 	beq.l		srem_sdnrm
   11323  1.1     is 	cmpi.b		%d1,&QNAN
   11324  1.1     is 	beq.l		sop_sqnan
   11325  1.1     is 	bra.l		sop_ssnan
   11326  1.1     is 
   11327  1.1     is 	global		fscale
   11328  1.1     is fscale:
   11329  1.1     is 	mov.b		STAG(%a6),%d1
   11330  1.1     is 	beq.l		sscale_snorm
   11331  1.1     is 	cmpi.b		%d1,&ZERO
   11332  1.1     is 	beq.l		sscale_szero
   11333  1.1     is 	cmpi.b		%d1,&INF
   11334  1.1     is 	beq.l		sscale_sinf
   11335  1.1     is 	cmpi.b		%d1,&DENORM
   11336  1.1     is 	beq.l		sscale_sdnrm
   11337  1.1     is 	cmpi.b		%d1,&QNAN
   11338  1.1     is 	beq.l		sop_sqnan
   11339  1.1     is 	bra.l		sop_ssnan
   11340  1.1     is 
   11341  1.1     is #########################################################################
   11342  1.1     is # XDEF ****************************************************************	#
   11343  1.1     is # 	fgen_except(): catch an exception during transcendental 	#
   11344  1.1     is #		       emulation					#
   11345  1.1     is #									#
   11346  1.1     is # XREF ****************************************************************	#
   11347  1.1     is #	fmul() - emulate a multiply instruction				#
   11348  1.1     is #	fadd() - emulate an add instruction				#
   11349  1.1     is #	fin() - emulate an fmove instruction				#
   11350  1.1     is #									#
   11351  1.1     is # INPUT ***************************************************************	#
   11352  1.1     is #	fp0 = destination operand					#
   11353  1.1     is #	d0  = type of instruction that took exception			#
   11354  1.1     is #	fsave frame = source operand					#
   11355  1.1     is # 									#
   11356  1.1     is # OUTPUT **************************************************************	#
   11357  1.1     is #	fp0 = result							#
   11358  1.1     is #	fp1 = EXOP							#
   11359  1.1     is #									#
   11360  1.1     is # ALGORITHM ***********************************************************	#
   11361  1.1     is # 	An exception occurred on the last instruction of the 		#
   11362  1.1     is # transcendental emulation. hopefully, this won't be happening much 	#
   11363  1.1     is # because it will be VERY slow.						#
   11364  1.1     is # 	The only exceptions capable of passing through here are		#
   11365  1.1     is # Overflow, Underflow, and Unsupported Data Type.			#
   11366  1.1     is #									#
   11367  1.1     is #########################################################################
   11368  1.1     is 
   11369  1.1     is 	global		fgen_except
   11370  1.1     is fgen_except:
   11371  1.1     is 	cmpi.b		0x3(%sp),&0x7		# is exception UNSUPP?
   11372  1.1     is 	beq.b		fge_unsupp		# yes
   11373  1.1     is 
   11374  1.1     is 	mov.b		&NORM,STAG(%a6)
   11375  1.1     is 
   11376  1.1     is fge_cont:
   11377  1.1     is 	mov.b		&NORM,DTAG(%a6)
   11378  1.1     is 
   11379  1.1     is # ok, I have a problem with putting the dst op at FP_DST. the emulation
   11380  1.1     is # routines aren't supposed to alter the operands but we've just squashed
   11381  1.1     is # FP_DST here...
   11382  1.1     is 
   11383  1.1     is # 8/17/93 - this turns out to be more of a "cleanliness" standpoint
   11384  1.1     is # then a potential bug. to begin with, only the dyadic functions
   11385  1.1     is # frem,fmod, and fscale would get the dst trashed here. But, for
   11386  1.1     is # the 060SP, the FP_DST is never used again anyways.
   11387  1.1     is 	fmovm.x		&0x80,FP_DST(%a6)	# dst op is in fp0
   11388  1.1     is 
   11389  1.1     is 	lea		0x4(%sp),%a0		# pass: ptr to src op
   11390  1.1     is 	lea		FP_DST(%a6),%a1		# pass: ptr to dst op
   11391  1.1     is 
   11392  1.1     is 	cmpi.b		%d1,&FMOV_OP
   11393  1.1     is 	beq.b		fge_fin			# it was an "fmov"
   11394  1.1     is 	cmpi.b		%d1,&FADD_OP
   11395  1.1     is 	beq.b		fge_fadd		# it was an "fadd"
   11396  1.1     is fge_fmul:
   11397  1.1     is 	bsr.l		fmul
   11398  1.1     is 	rts
   11399  1.1     is fge_fadd:
   11400  1.1     is 	bsr.l		fadd
   11401  1.1     is 	rts
   11402  1.1     is fge_fin:
   11403  1.1     is 	bsr.l		fin
   11404  1.1     is 	rts
   11405  1.1     is 
   11406  1.1     is fge_unsupp:
   11407  1.1     is 	mov.b		&DENORM,STAG(%a6)
   11408  1.1     is 	bra.b		fge_cont
   11409  1.1     is 
   11410  1.1     is #
   11411  1.1     is # This table holds the offsets of the emulation routines for each individual
   11412  1.1     is # math operation relative to the address of this table. Included are
   11413  1.1     is # routines like fadd/fmul/fabs as well as the transcendentals.
   11414  1.1     is # The location within the table is determined by the extension bits of the
   11415  1.1     is # operation longword.
   11416  1.1     is #
   11417  1.1     is 
   11418  1.1     is 	swbeg		&109
   11419  1.1     is tbl_unsupp:
   11420  1.1     is 	long		fin	 	- tbl_unsupp	# 00: fmove
   11421  1.1     is 	long		fint	 	- tbl_unsupp	# 01: fint
   11422  1.1     is 	long		fsinh	 	- tbl_unsupp	# 02: fsinh
   11423  1.1     is 	long		fintrz	 	- tbl_unsupp	# 03: fintrz
   11424  1.1     is 	long		fsqrt	 	- tbl_unsupp	# 04: fsqrt
   11425  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11426  1.1     is 	long		flognp1		- tbl_unsupp	# 06: flognp1
   11427  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11428  1.1     is 	long		fetoxm1		- tbl_unsupp	# 08: fetoxm1
   11429  1.1     is 	long		ftanh		- tbl_unsupp	# 09: ftanh
   11430  1.1     is 	long		fatan		- tbl_unsupp	# 0a: fatan
   11431  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11432  1.1     is 	long		fasin		- tbl_unsupp	# 0c: fasin
   11433  1.1     is 	long		fatanh		- tbl_unsupp	# 0d: fatanh
   11434  1.1     is 	long		fsine		- tbl_unsupp	# 0e: fsin
   11435  1.1     is 	long		ftan		- tbl_unsupp	# 0f: ftan
   11436  1.1     is 	long		fetox		- tbl_unsupp	# 10: fetox
   11437  1.1     is 	long		ftwotox		- tbl_unsupp	# 11: ftwotox
   11438  1.1     is 	long		ftentox		- tbl_unsupp	# 12: ftentox
   11439  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11440  1.1     is 	long		flogn		- tbl_unsupp	# 14: flogn
   11441  1.1     is 	long		flog10		- tbl_unsupp	# 15: flog10
   11442  1.1     is 	long		flog2		- tbl_unsupp	# 16: flog2
   11443  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11444  1.1     is 	long		fabs		- tbl_unsupp 	# 18: fabs
   11445  1.1     is 	long		fcosh		- tbl_unsupp	# 19: fcosh
   11446  1.1     is 	long		fneg		- tbl_unsupp 	# 1a: fneg
   11447  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11448  1.1     is 	long		facos		- tbl_unsupp	# 1c: facos
   11449  1.1     is 	long		fcos		- tbl_unsupp	# 1d: fcos
   11450  1.1     is 	long		fgetexp		- tbl_unsupp	# 1e: fgetexp
   11451  1.1     is 	long		fgetman		- tbl_unsupp	# 1f: fgetman
   11452  1.1     is 	long		fdiv		- tbl_unsupp 	# 20: fdiv
   11453  1.1     is 	long		fmod		- tbl_unsupp	# 21: fmod
   11454  1.1     is 	long		fadd		- tbl_unsupp 	# 22: fadd
   11455  1.1     is 	long		fmul		- tbl_unsupp 	# 23: fmul
   11456  1.1     is 	long		fsgldiv		- tbl_unsupp 	# 24: fsgldiv
   11457  1.1     is 	long		frem		- tbl_unsupp	# 25: frem
   11458  1.1     is 	long		fscale		- tbl_unsupp	# 26: fscale
   11459  1.1     is 	long		fsglmul		- tbl_unsupp 	# 27: fsglmul
   11460  1.1     is 	long		fsub		- tbl_unsupp 	# 28: fsub
   11461  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11462  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11463  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11464  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11465  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11466  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11467  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11468  1.1     is 	long		fsincos		- tbl_unsupp	# 30: fsincos
   11469  1.1     is 	long		fsincos		- tbl_unsupp	# 31: fsincos
   11470  1.1     is 	long		fsincos		- tbl_unsupp	# 32: fsincos
   11471  1.1     is 	long		fsincos		- tbl_unsupp	# 33: fsincos
   11472  1.1     is 	long		fsincos		- tbl_unsupp	# 34: fsincos
   11473  1.1     is 	long		fsincos		- tbl_unsupp	# 35: fsincos
   11474  1.1     is 	long		fsincos		- tbl_unsupp	# 36: fsincos
   11475  1.1     is 	long		fsincos		- tbl_unsupp	# 37: fsincos
   11476  1.1     is 	long		fcmp		- tbl_unsupp 	# 38: fcmp
   11477  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11478  1.1     is 	long		ftst		- tbl_unsupp 	# 3a: ftst
   11479  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11480  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11481  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11482  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11483  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11484  1.1     is 	long		fsin		- tbl_unsupp 	# 40: fsmove
   11485  1.1     is 	long		fssqrt		- tbl_unsupp 	# 41: fssqrt
   11486  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11487  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11488  1.1     is 	long		fdin		- tbl_unsupp	# 44: fdmove
   11489  1.1     is 	long		fdsqrt		- tbl_unsupp 	# 45: fdsqrt
   11490  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11491  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11492  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11493  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11494  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11495  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11496  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11497  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11498  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11499  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11500  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11501  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11502  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11503  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11504  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11505  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11506  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11507  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11508  1.1     is 	long		fsabs		- tbl_unsupp 	# 58: fsabs
   11509  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11510  1.1     is 	long		fsneg		- tbl_unsupp 	# 5a: fsneg
   11511  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11512  1.1     is 	long		fdabs		- tbl_unsupp	# 5c: fdabs
   11513  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11514  1.1     is 	long		fdneg		- tbl_unsupp 	# 5e: fdneg
   11515  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11516  1.1     is 	long		fsdiv		- tbl_unsupp	# 60: fsdiv
   11517  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11518  1.1     is 	long		fsadd		- tbl_unsupp	# 62: fsadd
   11519  1.1     is 	long		fsmul		- tbl_unsupp	# 63: fsmul
   11520  1.1     is 	long		fddiv		- tbl_unsupp 	# 64: fddiv
   11521  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11522  1.1     is 	long		fdadd		- tbl_unsupp	# 66: fdadd
   11523  1.1     is 	long		fdmul		- tbl_unsupp 	# 67: fdmul
   11524  1.1     is 	long		fssub		- tbl_unsupp	# 68: fssub
   11525  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11526  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11527  1.1     is 	long		tbl_unsupp	- tbl_unsupp
   11528  1.1     is 	long		fdsub		- tbl_unsupp 	# 6c: fdsub
   11529  1.1     is 
   11530  1.1     is #########################################################################
   11531  1.1     is # XDEF ****************************************************************	#
   11532  1.1     is # 	fmul(): emulates the fmul instruction				#
   11533  1.1     is #	fsmul(): emulates the fsmul instruction				#
   11534  1.1     is #	fdmul(): emulates the fdmul instruction				#
   11535  1.1     is #									#
   11536  1.1     is # XREF ****************************************************************	#
   11537  1.1     is #	scale_to_zero_src() - scale src exponent to zero		#
   11538  1.1     is #	scale_to_zero_dst() - scale dst exponent to zero		#
   11539  1.1     is #	unf_res() - return default underflow result			#
   11540  1.1     is #	ovf_res() - return default overflow result			#
   11541  1.1     is # 	res_qnan() - return QNAN result					#
   11542  1.1     is # 	res_snan() - return SNAN result					#
   11543  1.1     is #									#
   11544  1.1     is # INPUT ***************************************************************	#
   11545  1.1     is #	a0 = pointer to extended precision source operand		#
   11546  1.1     is #	a1 = pointer to extended precision destination operand		#
   11547  1.1     is #	d0  rnd prec,mode						#
   11548  1.1     is #									#
   11549  1.1     is # OUTPUT **************************************************************	#
   11550  1.1     is #	fp0 = result							#
   11551  1.1     is #	fp1 = EXOP (if exception occurred)				#
   11552  1.1     is #									#
   11553  1.1     is # ALGORITHM ***********************************************************	#
   11554  1.1     is #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   11555  1.1     is # norms/denorms into ext/sgl/dbl precision.				#
   11556  1.1     is #	For norms/denorms, scale the exponents such that a multiply	#
   11557  1.1     is # instruction won't cause an exception. Use the regular fmul to		#
   11558  1.1     is # compute a result. Check if the regular operands would have taken	#
   11559  1.1     is # an exception. If so, return the default overflow/underflow result	#
   11560  1.1     is # and return the EXOP if exceptions are enabled. Else, scale the 	#
   11561  1.1     is # result operand to the proper exponent.				#
   11562  1.1     is #									#
   11563  1.1     is #########################################################################
   11564  1.1     is 
   11565  1.1     is 	align 		0x10
   11566  1.1     is tbl_fmul_ovfl:
   11567  1.1     is 	long		0x3fff - 0x7ffe		# ext_max
   11568  1.1     is 	long		0x3fff - 0x407e		# sgl_max
   11569  1.1     is 	long		0x3fff - 0x43fe		# dbl_max
   11570  1.1     is tbl_fmul_unfl:
   11571  1.1     is 	long		0x3fff + 0x0001		# ext_unfl
   11572  1.1     is 	long		0x3fff - 0x3f80		# sgl_unfl
   11573  1.1     is 	long		0x3fff - 0x3c00		# dbl_unfl
   11574  1.1     is 
   11575  1.1     is 	global		fsmul
   11576  1.1     is fsmul:
   11577  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   11578  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   11579  1.1     is 	bra.b		fmul
   11580  1.1     is 
   11581  1.1     is 	global		fdmul
   11582  1.1     is fdmul:
   11583  1.1     is 	andi.b		&0x30,%d0
   11584  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   11585  1.1     is 
   11586  1.1     is 	global		fmul
   11587  1.1     is fmul:
   11588  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   11589  1.1     is 
   11590  1.1     is 	clr.w		%d1
   11591  1.1     is 	mov.b		DTAG(%a6),%d1
   11592  1.1     is 	lsl.b		&0x3,%d1
   11593  1.1     is 	or.b		STAG(%a6),%d1		# combine src tags
   11594  1.1     is 	bne.w		fmul_not_norm		# optimize on non-norm input
   11595  1.1     is 
   11596  1.1     is fmul_norm:
   11597  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   11598  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   11599  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   11600  1.1     is 
   11601  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   11602  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   11603  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   11604  1.1     is 
   11605  1.1     is 	bsr.l		scale_to_zero_src	# scale src exponent
   11606  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor 1
   11607  1.1     is 
   11608  1.1     is 	bsr.l		scale_to_zero_dst	# scale dst exponent
   11609  1.1     is 
   11610  1.1     is 	add.l		%d0,(%sp)		# SCALE_FACTOR = scale1 + scale2
   11611  1.1     is 
   11612  1.1     is 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision
   11613  1.1     is 	lsr.b		&0x6,%d1		# shift to lo bits
   11614  1.1     is 	mov.l		(%sp)+,%d0		# load S.F.
   11615  1.1     is 	cmp.l		%d0,(tbl_fmul_ovfl.w,%pc,%d1.w*4) # would result ovfl?
   11616  1.1     is 	beq.w		fmul_may_ovfl		# result may rnd to overflow
   11617  1.1     is 	blt.w		fmul_ovfl		# result will overflow
   11618  1.1     is 
   11619  1.1     is 	cmp.l		%d0,(tbl_fmul_unfl.w,%pc,%d1.w*4) # would result unfl?
   11620  1.1     is 	beq.w		fmul_may_unfl		# result may rnd to no unfl
   11621  1.1     is 	bgt.w		fmul_unfl		# result will underflow
   11622  1.1     is 
   11623  1.1     is #
   11624  1.1     is # NORMAL:
   11625  1.1     is # - the result of the multiply operation will neither overflow nor underflow.
   11626  1.1     is # - do the multiply to the proper precision and rounding mode.
   11627  1.1     is # - scale the result exponent using the scale factor. if both operands were
   11628  1.1     is # normalized then we really don't need to go through this scaling. but for now,
   11629  1.1     is # this will do.
   11630  1.1     is #
   11631  1.1     is fmul_normal:
   11632  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11633  1.1     is 
   11634  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11635  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11636  1.1     is 
   11637  1.1     is 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11638  1.1     is 
   11639  1.1     is 	fmov.l		%fpsr,%d1		# save status
   11640  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11641  1.1     is 
   11642  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11643  1.1     is 
   11644  1.1     is fmul_normal_exit:
   11645  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   11646  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   11647  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   11648  1.1     is 	mov.l		%d1,%d2			# make a copy
   11649  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   11650  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   11651  1.1     is 	sub.l		%d0,%d1			# add scale factor
   11652  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   11653  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   11654  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   11655  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   11656  1.1     is 	rts
   11657  1.1     is 
   11658  1.1     is #
   11659  1.1     is # OVERFLOW:
   11660  1.1     is # - the result of the multiply operation is an overflow.
   11661  1.1     is # - do the multiply to the proper precision and rounding mode in order to
   11662  1.1     is # set the inexact bits.
   11663  1.1     is # - calculate the default result and return it in fp0.
   11664  1.1     is # - if overflow or inexact is enabled, we need a multiply result rounded to
   11665  1.1     is # extended precision. if the original operation was extended, then we have this
   11666  1.1     is # result. if the original operation was single or double, we have to do another
   11667  1.1     is # multiply using extended precision and the correct rounding mode. the result
   11668  1.1     is # of this operation then has its exponent scaled by -0x6000 to create the
   11669  1.1     is # exceptional operand.
   11670  1.1     is #
   11671  1.1     is fmul_ovfl:
   11672  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11673  1.1     is 
   11674  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11675  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11676  1.1     is 
   11677  1.1     is 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11678  1.1     is 
   11679  1.1     is 	fmov.l		%fpsr,%d1		# save status
   11680  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11681  1.1     is 
   11682  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11683  1.1     is 
   11684  1.1     is # save setting this until now because this is where fmul_may_ovfl may jump in
   11685  1.1     is fmul_ovfl_tst:
   11686  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   11687  1.1     is 
   11688  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   11689  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   11690  1.1     is 	bne.b		fmul_ovfl_ena		# yes
   11691  1.1     is 
   11692  1.1     is # calculate the default result
   11693  1.1     is fmul_ovfl_dis:
   11694  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   11695  1.1     is 	sne		%d1			# set sign param accordingly
   11696  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass rnd prec,mode
   11697  1.1     is 	bsr.l		ovf_res			# calculate default result
   11698  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   11699  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   11700  1.1     is 	rts
   11701  1.1     is 
   11702  1.1     is #
   11703  1.1     is # OVFL is enabled; Create EXOP:
   11704  1.1     is # - if precision is extended, then we have the EXOP. simply bias the exponent
   11705  1.1     is # with an extra -0x6000. if the precision is single or double, we need to
   11706  1.1     is # calculate a result rounded to extended precision.
   11707  1.1     is #
   11708  1.1     is fmul_ovfl_ena:
   11709  1.1     is 	mov.l		L_SCR3(%a6),%d1
   11710  1.1     is 	andi.b		&0xc0,%d1		# test the rnd prec
   11711  1.1     is 	bne.b		fmul_ovfl_ena_sd	# it's sgl or dbl
   11712  1.1     is 
   11713  1.1     is fmul_ovfl_ena_cont:
   11714  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   11715  1.1     is 
   11716  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   11717  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   11718  1.1     is 	mov.w		%d1,%d2			# make a copy
   11719  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   11720  1.1     is 	sub.l		%d0,%d1			# add scale factor
   11721  1.1     is 	subi.l		&0x6000,%d1		# subtract bias
   11722  1.1     is 	andi.w		&0x7fff,%d1		# clear sign bit
   11723  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   11724  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   11725  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   11726  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   11727  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   11728  1.1     is 	bra.b		fmul_ovfl_dis
   11729  1.1     is 
   11730  1.1     is fmul_ovfl_ena_sd:
   11731  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11732  1.1     is 
   11733  1.1     is 	mov.l		L_SCR3(%a6),%d1
   11734  1.1     is 	andi.b		&0x30,%d1		# keep rnd mode only
   11735  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   11736  1.1     is 
   11737  1.1     is 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11738  1.1     is 
   11739  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11740  1.1     is 	bra.b		fmul_ovfl_ena_cont
   11741  1.1     is 
   11742  1.1     is #
   11743  1.1     is # may OVERFLOW:
   11744  1.1     is # - the result of the multiply operation MAY overflow.
   11745  1.1     is # - do the multiply to the proper precision and rounding mode in order to
   11746  1.1     is # set the inexact bits.
   11747  1.1     is # - calculate the default result and return it in fp0.
   11748  1.1     is #
   11749  1.1     is fmul_may_ovfl:
   11750  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   11751  1.1     is 
   11752  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11753  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11754  1.1     is 
   11755  1.1     is 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11756  1.1     is 
   11757  1.1     is 	fmov.l		%fpsr,%d1		# save status
   11758  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11759  1.1     is 
   11760  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11761  1.1     is 
   11762  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   11763  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   11764  1.1     is 	fbge.w		fmul_ovfl_tst		# yes; overflow has occurred
   11765  1.1     is 
   11766  1.1     is # no, it didn't overflow; we have correct result
   11767  1.1     is 	bra.w		fmul_normal_exit
   11768  1.1     is 
   11769  1.1     is #
   11770  1.1     is # UNDERFLOW:
   11771  1.1     is # - the result of the multiply operation is an underflow.
   11772  1.1     is # - do the multiply to the proper precision and rounding mode in order to
   11773  1.1     is # set the inexact bits.
   11774  1.1     is # - calculate the default result and return it in fp0.
   11775  1.1     is # - if overflow or inexact is enabled, we need a multiply result rounded to
   11776  1.1     is # extended precision. if the original operation was extended, then we have this
   11777  1.1     is # result. if the original operation was single or double, we have to do another
   11778  1.1     is # multiply using extended precision and the correct rounding mode. the result
   11779  1.1     is # of this operation then has its exponent scaled by -0x6000 to create the
   11780  1.1     is # exceptional operand.
   11781  1.1     is #
   11782  1.1     is fmul_unfl:
   11783  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   11784  1.1     is 
   11785  1.1     is # for fun, let's use only extended precision, round to zero. then, let
   11786  1.1     is # the unf_res() routine figure out all the rest.
   11787  1.1     is # will we get the correct answer.
   11788  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11789  1.1     is 
   11790  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   11791  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11792  1.1     is 
   11793  1.1     is 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11794  1.1     is 
   11795  1.1     is 	fmov.l		%fpsr,%d1		# save status
   11796  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11797  1.1     is 
   11798  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11799  1.1     is 
   11800  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   11801  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   11802  1.1     is 	bne.b		fmul_unfl_ena		# yes
   11803  1.1     is 
   11804  1.1     is fmul_unfl_dis:
   11805  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   11806  1.1     is 
   11807  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   11808  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   11809  1.1     is 	bsr.l		unf_res			# calculate default result
   11810  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# unf_res2 may have set 'Z'
   11811  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   11812  1.1     is 	rts
   11813  1.1     is 
   11814  1.1     is #
   11815  1.1     is # UNFL is enabled.
   11816  1.1     is #
   11817  1.1     is fmul_unfl_ena:
   11818  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   11819  1.1     is 
   11820  1.1     is 	mov.l		L_SCR3(%a6),%d1
   11821  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   11822  1.1     is 	bne.b		fmul_unfl_ena_sd	# no, sgl or dbl
   11823  1.1     is 
   11824  1.1     is # if the rnd mode is anything but RZ, then we have to re-do the above
   11825  1.4    wiz # multiplication because we used RZ for all.
   11826  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11827  1.1     is 
   11828  1.1     is fmul_unfl_ena_cont:
   11829  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11830  1.1     is 
   11831  1.1     is 	fmul.x		FP_SCR0(%a6),%fp1	# execute multiply
   11832  1.1     is 
   11833  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11834  1.1     is 
   11835  1.1     is 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   11836  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   11837  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   11838  1.1     is 	mov.l		%d1,%d2			# make a copy
   11839  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   11840  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   11841  1.1     is 	sub.l		%d0,%d1			# add scale factor
   11842  1.1     is 	addi.l		&0x6000,%d1		# add bias
   11843  1.1     is 	andi.w		&0x7fff,%d1
   11844  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   11845  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   11846  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   11847  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   11848  1.1     is 	bra.w		fmul_unfl_dis
   11849  1.1     is 
   11850  1.1     is fmul_unfl_ena_sd:
   11851  1.1     is 	mov.l		L_SCR3(%a6),%d1
   11852  1.1     is 	andi.b		&0x30,%d1		# use only rnd mode
   11853  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   11854  1.1     is 
   11855  1.1     is 	bra.b		fmul_unfl_ena_cont
   11856  1.1     is 
   11857  1.1     is # MAY UNDERFLOW:
   11858  1.1     is # -use the correct rounding mode and precision. this code favors operations
   11859  1.1     is # that do not underflow.
   11860  1.1     is fmul_may_unfl:
   11861  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11862  1.1     is 
   11863  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11864  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11865  1.1     is 
   11866  1.1     is 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11867  1.1     is 
   11868  1.1     is 	fmov.l		%fpsr,%d1		# save status
   11869  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11870  1.1     is 
   11871  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11872  1.1     is 
   11873  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   11874  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| > 2.b?
   11875  1.1     is 	fbgt.w		fmul_normal_exit	# no; no underflow occurred
   11876  1.1     is 	fblt.w		fmul_unfl		# yes; underflow occurred
   11877  1.1     is 
   11878  1.1     is #
   11879  1.1     is # we still don't know if underflow occurred. result is ~ equal to 2. but,
   11880  1.1     is # we don't know if the result was an underflow that rounded up to a 2 or
   11881  1.1     is # a normalized number that rounded down to a 2. so, redo the entire operation
   11882  1.1     is # using RZ as the rounding mode to see what the pre-rounded result is.
   11883  1.1     is # this case should be relatively rare.
   11884  1.1     is #
   11885  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst operand
   11886  1.1     is 
   11887  1.1     is 	mov.l		L_SCR3(%a6),%d1
   11888  1.1     is 	andi.b		&0xc0,%d1		# keep rnd prec
   11889  1.1     is 	ori.b		&rz_mode*0x10,%d1	# insert RZ
   11890  1.1     is 
   11891  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   11892  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   11893  1.1     is 
   11894  1.1     is 	fmul.x		FP_SCR0(%a6),%fp1	# execute multiply
   11895  1.1     is 
   11896  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   11897  1.1     is 	fabs.x		%fp1			# make absolute value
   11898  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| < 2.b?
   11899  1.1     is 	fbge.w		fmul_normal_exit	# no; no underflow occurred
   11900  1.1     is 	bra.w		fmul_unfl		# yes, underflow occurred
   11901  1.1     is 
   11902  1.1     is ################################################################################
   11903  1.1     is 
   11904  1.1     is #
   11905  1.1     is # Multiply: inputs are not both normalized; what are they?
   11906  1.1     is #
   11907  1.1     is fmul_not_norm:
   11908  1.1     is 	mov.w		(tbl_fmul_op.b,%pc,%d1.w*2),%d1
   11909  1.1     is 	jmp		(tbl_fmul_op.b,%pc,%d1.w)
   11910  1.1     is 
   11911  1.1     is 	swbeg		&48
   11912  1.1     is tbl_fmul_op:
   11913  1.1     is 	short		fmul_norm	- tbl_fmul_op # NORM x NORM
   11914  1.1     is 	short		fmul_zero	- tbl_fmul_op # NORM x ZERO
   11915  1.1     is 	short		fmul_inf_src	- tbl_fmul_op # NORM x INF
   11916  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # NORM x QNAN
   11917  1.1     is 	short		fmul_norm	- tbl_fmul_op # NORM x DENORM
   11918  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # NORM x SNAN
   11919  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11920  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11921  1.1     is 
   11922  1.1     is 	short		fmul_zero	- tbl_fmul_op # ZERO x NORM
   11923  1.1     is 	short		fmul_zero	- tbl_fmul_op # ZERO x ZERO
   11924  1.1     is 	short		fmul_res_operr	- tbl_fmul_op # ZERO x INF
   11925  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # ZERO x QNAN
   11926  1.1     is 	short		fmul_zero	- tbl_fmul_op # ZERO x DENORM
   11927  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # ZERO x SNAN
   11928  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11929  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11930  1.1     is 
   11931  1.1     is 	short		fmul_inf_dst	- tbl_fmul_op # INF x NORM
   11932  1.1     is 	short		fmul_res_operr	- tbl_fmul_op # INF x ZERO
   11933  1.1     is 	short		fmul_inf_dst	- tbl_fmul_op # INF x INF
   11934  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # INF x QNAN
   11935  1.1     is 	short		fmul_inf_dst	- tbl_fmul_op # INF x DENORM
   11936  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # INF x SNAN
   11937  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11938  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11939  1.1     is 
   11940  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x NORM
   11941  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x ZERO
   11942  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x INF
   11943  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x QNAN
   11944  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x DENORM
   11945  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # QNAN x SNAN
   11946  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11947  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11948  1.1     is 
   11949  1.1     is 	short		fmul_norm	- tbl_fmul_op # NORM x NORM
   11950  1.1     is 	short		fmul_zero	- tbl_fmul_op # NORM x ZERO
   11951  1.1     is 	short		fmul_inf_src	- tbl_fmul_op # NORM x INF
   11952  1.1     is 	short		fmul_res_qnan	- tbl_fmul_op # NORM x QNAN
   11953  1.1     is 	short		fmul_norm	- tbl_fmul_op # NORM x DENORM
   11954  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # NORM x SNAN
   11955  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11956  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11957  1.1     is 
   11958  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # SNAN x NORM
   11959  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # SNAN x ZERO
   11960  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # SNAN x INF
   11961  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # SNAN x QNAN
   11962  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # SNAN x DENORM
   11963  1.1     is 	short		fmul_res_snan	- tbl_fmul_op # SNAN x SNAN
   11964  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11965  1.1     is 	short		tbl_fmul_op	- tbl_fmul_op #
   11966  1.1     is 
   11967  1.1     is fmul_res_operr:
   11968  1.1     is 	bra.l		res_operr
   11969  1.1     is fmul_res_snan:
   11970  1.1     is 	bra.l		res_snan
   11971  1.1     is fmul_res_qnan:
   11972  1.1     is 	bra.l		res_qnan
   11973  1.1     is 
   11974  1.1     is #
   11975  1.1     is # Multiply: (Zero x Zero) || (Zero x norm) || (Zero x denorm)
   11976  1.1     is #
   11977  1.1     is 	global		fmul_zero		# global for fsglmul
   11978  1.1     is fmul_zero:
   11979  1.1     is 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   11980  1.1     is 	mov.b		DST_EX(%a1),%d1
   11981  1.1     is 	eor.b		%d0,%d1
   11982  1.1     is 	bpl.b		fmul_zero_p		# result ZERO is pos.
   11983  1.1     is fmul_zero_n:
   11984  1.1     is 	fmov.s		&0x80000000,%fp0	# load -ZERO
   11985  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N
   11986  1.1     is 	rts
   11987  1.1     is fmul_zero_p:
   11988  1.1     is 	fmov.s		&0x00000000,%fp0	# load +ZERO
   11989  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   11990  1.1     is 	rts
   11991  1.1     is 
   11992  1.1     is #
   11993  1.1     is # Multiply: (inf x inf) || (inf x norm) || (inf x denorm)
   11994  1.1     is #
   11995  1.1     is # Note: The j-bit for an infinity is a don't-care. However, to be
   11996  1.1     is # strictly compatible w/ the 68881/882, we make sure to return an
   11997  1.1     is # INF w/ the j-bit set if the input INF j-bit was set. Destination
   11998  1.1     is # INFs take priority.
   11999  1.1     is #
   12000  1.1     is 	global		fmul_inf_dst		# global for fsglmul
   12001  1.1     is fmul_inf_dst:
   12002  1.1     is 	fmovm.x		DST(%a1),&0x80		# return INF result in fp0
   12003  1.1     is 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   12004  1.1     is 	mov.b		DST_EX(%a1),%d1
   12005  1.1     is 	eor.b		%d0,%d1
   12006  1.1     is 	bpl.b		fmul_inf_dst_p		# result INF is pos.
   12007  1.1     is fmul_inf_dst_n:
   12008  1.1     is 	fabs.x		%fp0			# clear result sign
   12009  1.1     is 	fneg.x		%fp0			# set result sign
   12010  1.1     is 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
   12011  1.1     is 	rts
   12012  1.1     is fmul_inf_dst_p:
   12013  1.1     is 	fabs.x		%fp0			# clear result sign
   12014  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
   12015  1.1     is 	rts
   12016  1.1     is 
   12017  1.1     is 	global		fmul_inf_src		# global for fsglmul
   12018  1.1     is fmul_inf_src:
   12019  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return INF result in fp0
   12020  1.1     is 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   12021  1.1     is 	mov.b		DST_EX(%a1),%d1
   12022  1.1     is 	eor.b		%d0,%d1
   12023  1.1     is 	bpl.b		fmul_inf_dst_p		# result INF is pos.
   12024  1.1     is 	bra.b		fmul_inf_dst_n
   12025  1.1     is 
   12026  1.1     is #########################################################################
   12027  1.1     is # XDEF ****************************************************************	#
   12028  1.1     is #	fin(): emulates the fmove instruction				#
   12029  1.1     is #	fsin(): emulates the fsmove instruction				#
   12030  1.1     is #	fdin(): emulates the fdmove instruction				#
   12031  1.1     is #									#
   12032  1.1     is # XREF ****************************************************************	#
   12033  1.1     is #	norm() - normalize mantissa for EXOP on denorm			#
   12034  1.1     is #	scale_to_zero_src() - scale src exponent to zero		#
   12035  1.1     is #	ovf_res() - return default overflow result			#
   12036  1.1     is # 	unf_res() - return default underflow result			#
   12037  1.1     is #	res_qnan_1op() - return QNAN result				#
   12038  1.1     is #	res_snan_1op() - return SNAN result				#
   12039  1.1     is #									#
   12040  1.1     is # INPUT ***************************************************************	#
   12041  1.1     is #	a0 = pointer to extended precision source operand		#
   12042  1.1     is #	d0 = round prec/mode						#
   12043  1.1     is # 									#
   12044  1.1     is # OUTPUT **************************************************************	#
   12045  1.1     is #	fp0 = result							#
   12046  1.1     is #	fp1 = EXOP (if exception occurred)				#
   12047  1.1     is #									#
   12048  1.1     is # ALGORITHM ***********************************************************	#
   12049  1.1     is # 	Handle NANs, infinities, and zeroes as special cases. Divide	#
   12050  1.1     is # norms into extended, single, and double precision.			#
   12051  1.1     is # 	Norms can be emulated w/ a regular fmove instruction. For	#
   12052  1.1     is # sgl/dbl, must scale exponent and perform an "fmove". Check to see	#
   12053  1.1     is # if the result would have overflowed/underflowed. If so, use unf_res()	#
   12054  1.1     is # or ovf_res() to return the default result. Also return EXOP if	#
   12055  1.1     is # exception is enabled. If no exception, return the default result.	#
   12056  1.1     is #	Unnorms don't pass through here.				#
   12057  1.1     is #									#
   12058  1.1     is #########################################################################
   12059  1.1     is 
   12060  1.1     is 	global		fsin
   12061  1.1     is fsin:
   12062  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   12063  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   12064  1.1     is 	bra.b		fin
   12065  1.1     is 
   12066  1.1     is 	global		fdin
   12067  1.1     is fdin:
   12068  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   12069  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
   12070  1.1     is 
   12071  1.1     is 	global		fin
   12072  1.1     is fin:
   12073  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   12074  1.1     is 
   12075  1.1     is 	mov.b		STAG(%a6),%d1		# fetch src optype tag
   12076  1.1     is 	bne.w		fin_not_norm		# optimize on non-norm input
   12077  1.1     is 
   12078  1.1     is #
   12079  1.1     is # FP MOVE IN: NORMs and DENORMs ONLY!
   12080  1.1     is #
   12081  1.1     is fin_norm:
   12082  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   12083  1.1     is 	bne.w		fin_not_ext		# no, so go handle dbl or sgl
   12084  1.1     is 
   12085  1.1     is #
   12086  1.1     is # precision selected is extended. so...we cannot get an underflow
   12087  1.1     is # or overflow because of rounding to the correct precision. so...
   12088  1.1     is # skip the scaling and unscaling...
   12089  1.1     is #
   12090  1.1     is 	tst.b		SRC_EX(%a0)		# is the operand negative?
   12091  1.1     is 	bpl.b		fin_norm_done		# no
   12092  1.1     is 	bset		&neg_bit,FPSR_CC(%a6)	# yes, so set 'N' ccode bit
   12093  1.1     is fin_norm_done:
   12094  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   12095  1.1     is 	rts
   12096  1.1     is 
   12097  1.1     is #
   12098  1.1     is # for an extended precision DENORM, the UNFL exception bit is set
   12099  1.1     is # the accrued bit is NOT set in this instance(no inexactness!)
   12100  1.1     is #
   12101  1.1     is fin_denorm:
   12102  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   12103  1.1     is 	bne.w		fin_not_ext		# no, so go handle dbl or sgl
   12104  1.1     is 
   12105  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12106  1.1     is 	tst.b		SRC_EX(%a0)		# is the operand negative?
   12107  1.1     is 	bpl.b		fin_denorm_done		# no
   12108  1.1     is 	bset		&neg_bit,FPSR_CC(%a6)	# yes, so set 'N' ccode bit
   12109  1.1     is fin_denorm_done:
   12110  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   12111  1.1     is 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
   12112  1.1     is 	bne.b		fin_denorm_unfl_ena	# yes
   12113  1.1     is 	rts
   12114  1.1     is 
   12115  1.1     is #
   12116  1.1     is # the input is an extended DENORM and underflow is enabled in the FPCR.
   12117  1.1     is # normalize the mantissa and add the bias of 0x6000 to the resulting negative
   12118  1.1     is # exponent and insert back into the operand.
   12119  1.1     is #
   12120  1.1     is fin_denorm_unfl_ena:
   12121  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12122  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12123  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12124  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   12125  1.1     is 	bsr.l		norm			# normalize result
   12126  1.1     is 	neg.w		%d0			# new exponent = -(shft val)
   12127  1.1     is 	addi.w		&0x6000,%d0		# add new bias to exponent
   12128  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
   12129  1.1     is 	andi.w		&0x8000,%d1		# keep old sign
   12130  1.1     is 	andi.w		&0x7fff,%d0		# clear sign position
   12131  1.1     is 	or.w		%d1,%d0			# concat new exo,old sign
   12132  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   12133  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12134  1.1     is 	rts
   12135  1.1     is 
   12136  1.1     is #
   12137  1.1     is # operand is to be rounded to single or double precision
   12138  1.1     is #
   12139  1.1     is fin_not_ext:
   12140  1.1     is 	cmpi.b		%d0,&s_mode*0x10 	# separate sgl/dbl prec
   12141  1.1     is 	bne.b		fin_dbl
   12142  1.1     is 
   12143  1.1     is #
   12144  1.1     is # operand is to be rounded to single precision
   12145  1.1     is #
   12146  1.1     is fin_sgl:
   12147  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12148  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12149  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12150  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor
   12151  1.1     is 
   12152  1.1     is 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
   12153  1.1     is 	bge.w		fin_sd_unfl		# yes; go handle underflow
   12154  1.1     is 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
   12155  1.1     is 	beq.w		fin_sd_may_ovfl		# maybe; go check
   12156  1.1     is 	blt.w		fin_sd_ovfl		# yes; go handle overflow
   12157  1.1     is 
   12158  1.1     is #
   12159  1.1     is # operand will NOT overflow or underflow when moved into the fp reg file
   12160  1.1     is #
   12161  1.1     is fin_sd_normal:
   12162  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12163  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12164  1.1     is 
   12165  1.1     is 	fmov.x		FP_SCR0(%a6),%fp0	# perform move
   12166  1.1     is 
   12167  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   12168  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12169  1.1     is 
   12170  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12171  1.1     is 
   12172  1.1     is fin_sd_normal_exit:
   12173  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   12174  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   12175  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   12176  1.1     is 	mov.w		%d1,%d2			# make a copy
   12177  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12178  1.1     is 	sub.l		%d0,%d1			# add scale factor
   12179  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   12180  1.1     is 	or.w		%d1,%d2			# concat old sign,new exponent
   12181  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   12182  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12183  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12184  1.1     is 	rts
   12185  1.1     is 
   12186  1.1     is #
   12187  1.1     is # operand is to be rounded to double precision
   12188  1.1     is #
   12189  1.1     is fin_dbl:
   12190  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12191  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12192  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12193  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor
   12194  1.1     is 
   12195  1.1     is 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
   12196  1.1     is 	bge.w		fin_sd_unfl		# yes; go handle underflow
   12197  1.1     is 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
   12198  1.1     is 	beq.w		fin_sd_may_ovfl		# maybe; go check
   12199  1.1     is 	blt.w		fin_sd_ovfl		# yes; go handle overflow
   12200  1.1     is 	bra.w		fin_sd_normal		# no; ho handle normalized op
   12201  1.1     is 
   12202  1.1     is #
   12203  1.1     is # operand WILL underflow when moved in to the fp register file
   12204  1.1     is #
   12205  1.1     is fin_sd_unfl:
   12206  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12207  1.1     is 
   12208  1.1     is 	tst.b		FP_SCR0_EX(%a6)		# is operand negative?
   12209  1.1     is 	bpl.b		fin_sd_unfl_tst
   12210  1.1     is 	bset		&neg_bit,FPSR_CC(%a6)	# set 'N' ccode bit
   12211  1.1     is 
   12212  1.1     is # if underflow or inexact is enabled, then go calculate the EXOP first.
   12213  1.1     is fin_sd_unfl_tst:
   12214  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   12215  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   12216  1.1     is 	bne.b		fin_sd_unfl_ena		# yes
   12217  1.1     is 
   12218  1.1     is fin_sd_unfl_dis:
   12219  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   12220  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   12221  1.1     is 	bsr.l		unf_res			# calculate default result
   12222  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# unf_res may have set 'Z'
   12223  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   12224  1.1     is 	rts
   12225  1.1     is 
   12226  1.1     is #
   12227  1.1     is # operand will underflow AND underflow or inexact is enabled.
   12228  1.1     is # therefore, we must return the result rounded to extended precision.
   12229  1.1     is #
   12230  1.1     is fin_sd_unfl_ena:
   12231  1.1     is 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   12232  1.1     is 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   12233  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   12234  1.1     is 
   12235  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   12236  1.1     is 	mov.w		%d1,%d2			# make a copy
   12237  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12238  1.1     is 	sub.l		%d0,%d1			# subtract scale factor
   12239  1.1     is 	andi.w		&0x8000,%d2		# extract old sign
   12240  1.1     is 	addi.l		&0x6000,%d1		# add new bias
   12241  1.1     is 	andi.w		&0x7fff,%d1
   12242  1.1     is 	or.w		%d1,%d2			# concat old sign,new exp
   12243  1.1     is 	mov.w		%d2,FP_SCR1_EX(%a6)	# insert new exponent
   12244  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   12245  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12246  1.1     is 	bra.b		fin_sd_unfl_dis
   12247  1.1     is 
   12248  1.1     is #
   12249  1.1     is # operand WILL overflow.
   12250  1.1     is #
   12251  1.1     is fin_sd_ovfl:
   12252  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12253  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12254  1.1     is 
   12255  1.1     is 	fmov.x		FP_SCR0(%a6),%fp0	# perform move
   12256  1.1     is 
   12257  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12258  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   12259  1.1     is 
   12260  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12261  1.1     is 
   12262  1.1     is fin_sd_ovfl_tst:
   12263  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   12264  1.1     is 
   12265  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   12266  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   12267  1.1     is 	bne.b		fin_sd_ovfl_ena		# yes
   12268  1.1     is 
   12269  1.1     is #
   12270  1.1     is # OVFL is not enabled; therefore, we must create the default result by
   12271  1.1     is # calling ovf_res().
   12272  1.1     is #
   12273  1.1     is fin_sd_ovfl_dis:
   12274  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   12275  1.1     is 	sne		%d1			# set sign param accordingly
   12276  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   12277  1.1     is 	bsr.l		ovf_res			# calculate default result
   12278  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   12279  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   12280  1.1     is 	rts
   12281  1.1     is 
   12282  1.1     is #
   12283  1.1     is # OVFL is enabled.
   12284  1.1     is # the INEX2 bit has already been updated by the round to the correct precision.
   12285  1.1     is # now, round to extended(and don't alter the FPSR).
   12286  1.1     is #
   12287  1.1     is fin_sd_ovfl_ena:
   12288  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   12289  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   12290  1.1     is 	mov.l		%d1,%d2			# make a copy
   12291  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12292  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   12293  1.1     is 	sub.l		%d0,%d1			# add scale factor
   12294  1.1     is 	sub.l		&0x6000,%d1		# subtract bias
   12295  1.1     is 	andi.w		&0x7fff,%d1
   12296  1.1     is 	or.w		%d2,%d1
   12297  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   12298  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12299  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12300  1.1     is 	bra.b		fin_sd_ovfl_dis
   12301  1.1     is 
   12302  1.1     is #
   12303  1.1     is # the move in MAY overflow. so...
   12304  1.1     is #
   12305  1.1     is fin_sd_may_ovfl:
   12306  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12307  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12308  1.1     is 
   12309  1.1     is 	fmov.x		FP_SCR0(%a6),%fp0	# perform the move
   12310  1.1     is 
   12311  1.1     is 	fmov.l		%fpsr,%d1		# save status
   12312  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12313  1.1     is 
   12314  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12315  1.1     is 
   12316  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   12317  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   12318  1.1     is 	fbge.w		fin_sd_ovfl_tst		# yes; overflow has occurred
   12319  1.1     is 
   12320  1.1     is # no, it didn't overflow; we have correct result
   12321  1.1     is 	bra.w		fin_sd_normal_exit
   12322  1.1     is 
   12323  1.1     is ##########################################################################
   12324  1.1     is 
   12325  1.1     is #
   12326  1.1     is # operand is not a NORM: check its optype and branch accordingly
   12327  1.1     is #
   12328  1.1     is fin_not_norm:
   12329  1.1     is 	cmpi.b		%d1,&DENORM		# weed out DENORM
   12330  1.1     is 	beq.w		fin_denorm
   12331  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNANs
   12332  1.1     is 	beq.l		res_snan_1op
   12333  1.1     is 	cmpi.b		%d1,&QNAN		# weed out QNANs
   12334  1.1     is 	beq.l		res_qnan_1op
   12335  1.1     is 
   12336  1.1     is #
   12337  1.1     is # do the fmove in; at this point, only possible ops are ZERO and INF.
   12338  1.1     is # use fmov to determine ccodes.
   12339  1.1     is # prec:mode should be zero at this point but it won't affect answer anyways.
   12340  1.1     is #
   12341  1.1     is 	fmov.x		SRC(%a0),%fp0		# do fmove in
   12342  1.1     is 	fmov.l		%fpsr,%d0		# no exceptions possible
   12343  1.1     is 	rol.l		&0x8,%d0		# put ccodes in lo byte
   12344  1.1     is 	mov.b		%d0,FPSR_CC(%a6)	# insert correct ccodes
   12345  1.1     is 	rts
   12346  1.1     is 
   12347  1.1     is #########################################################################
   12348  1.1     is # XDEF ****************************************************************	#
   12349  1.1     is # 	fdiv(): emulates the fdiv instruction				#
   12350  1.1     is #	fsdiv(): emulates the fsdiv instruction				#
   12351  1.1     is #	fddiv(): emulates the fddiv instruction				#
   12352  1.1     is #									#
   12353  1.1     is # XREF ****************************************************************	#
   12354  1.1     is #	scale_to_zero_src() - scale src exponent to zero		#
   12355  1.1     is #	scale_to_zero_dst() - scale dst exponent to zero		#
   12356  1.1     is #	unf_res() - return default underflow result			#
   12357  1.1     is #	ovf_res() - return default overflow result			#
   12358  1.1     is # 	res_qnan() - return QNAN result					#
   12359  1.1     is # 	res_snan() - return SNAN result					#
   12360  1.1     is #									#
   12361  1.1     is # INPUT ***************************************************************	#
   12362  1.1     is #	a0 = pointer to extended precision source operand		#
   12363  1.1     is #	a1 = pointer to extended precision destination operand		#
   12364  1.1     is #	d0  rnd prec,mode						#
   12365  1.1     is #									#
   12366  1.1     is # OUTPUT **************************************************************	#
   12367  1.1     is #	fp0 = result							#
   12368  1.1     is #	fp1 = EXOP (if exception occurred)				#
   12369  1.1     is #									#
   12370  1.1     is # ALGORITHM ***********************************************************	#
   12371  1.1     is #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   12372  1.1     is # norms/denorms into ext/sgl/dbl precision.				#
   12373  1.1     is #	For norms/denorms, scale the exponents such that a divide	#
   12374  1.1     is # instruction won't cause an exception. Use the regular fdiv to		#
   12375  1.1     is # compute a result. Check if the regular operands would have taken	#
   12376  1.1     is # an exception. If so, return the default overflow/underflow result	#
   12377  1.1     is # and return the EXOP if exceptions are enabled. Else, scale the 	#
   12378  1.1     is # result operand to the proper exponent.				#
   12379  1.1     is #									#
   12380  1.1     is #########################################################################
   12381  1.1     is 
   12382  1.1     is 	align		0x10
   12383  1.1     is tbl_fdiv_unfl:
   12384  1.1     is 	long		0x3fff - 0x0000		# ext_unfl
   12385  1.1     is 	long		0x3fff - 0x3f81		# sgl_unfl
   12386  1.1     is 	long		0x3fff - 0x3c01		# dbl_unfl
   12387  1.1     is 
   12388  1.1     is tbl_fdiv_ovfl:
   12389  1.1     is 	long		0x3fff - 0x7ffe		# ext overflow exponent
   12390  1.1     is 	long		0x3fff - 0x407e		# sgl overflow exponent
   12391  1.1     is 	long		0x3fff - 0x43fe		# dbl overflow exponent
   12392  1.1     is 
   12393  1.1     is 	global		fsdiv
   12394  1.1     is fsdiv:
   12395  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   12396  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   12397  1.1     is 	bra.b		fdiv
   12398  1.1     is 
   12399  1.1     is 	global		fddiv
   12400  1.1     is fddiv:
   12401  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   12402  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   12403  1.1     is 
   12404  1.1     is 	global		fdiv
   12405  1.1     is fdiv:
   12406  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   12407  1.1     is 
   12408  1.1     is 	clr.w		%d1
   12409  1.1     is 	mov.b		DTAG(%a6),%d1
   12410  1.1     is 	lsl.b		&0x3,%d1
   12411  1.1     is 	or.b		STAG(%a6),%d1		# combine src tags
   12412  1.1     is 
   12413  1.1     is 	bne.w		fdiv_not_norm		# optimize on non-norm input
   12414  1.1     is 
   12415  1.1     is #
   12416  1.1     is # DIVIDE: NORMs and DENORMs ONLY!
   12417  1.1     is #
   12418  1.1     is fdiv_norm:
   12419  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   12420  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   12421  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   12422  1.1     is 
   12423  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12424  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12425  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12426  1.1     is 
   12427  1.1     is 	bsr.l		scale_to_zero_src	# scale src exponent
   12428  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor 1
   12429  1.1     is 
   12430  1.1     is 	bsr.l		scale_to_zero_dst	# scale dst exponent
   12431  1.1     is 
   12432  1.1     is 	neg.l		(%sp)			# SCALE FACTOR = scale1 - scale2
   12433  1.1     is 	add.l		%d0,(%sp)
   12434  1.1     is 
   12435  1.1     is 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision
   12436  1.1     is 	lsr.b		&0x6,%d1		# shift to lo bits
   12437  1.1     is 	mov.l		(%sp)+,%d0		# load S.F.
   12438  1.1     is 	cmp.l		%d0,(tbl_fdiv_ovfl.b,%pc,%d1.w*4) # will result overflow?
   12439  1.1     is 	ble.w		fdiv_may_ovfl		# result will overflow
   12440  1.1     is 
   12441  1.1     is 	cmp.l		%d0,(tbl_fdiv_unfl.w,%pc,%d1.w*4) # will result underflow?
   12442  1.1     is 	beq.w		fdiv_may_unfl		# maybe
   12443  1.1     is 	bgt.w		fdiv_unfl		# yes; go handle underflow
   12444  1.1     is 
   12445  1.1     is fdiv_normal:
   12446  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12447  1.1     is 
   12448  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# save FPCR
   12449  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12450  1.1     is 
   12451  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp0	# perform divide
   12452  1.1     is 
   12453  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   12454  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12455  1.1     is 
   12456  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12457  1.1     is 
   12458  1.1     is fdiv_normal_exit:
   12459  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store result on stack
   12460  1.1     is 	mov.l		%d2,-(%sp)		# store d2
   12461  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   12462  1.1     is 	mov.l		%d1,%d2			# make a copy
   12463  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12464  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   12465  1.1     is 	sub.l		%d0,%d1			# add scale factor
   12466  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   12467  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   12468  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12469  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12470  1.1     is 	rts
   12471  1.1     is 
   12472  1.1     is tbl_fdiv_ovfl2:
   12473  1.1     is 	long		0x7fff
   12474  1.1     is 	long		0x407f
   12475  1.1     is 	long		0x43ff
   12476  1.1     is 
   12477  1.1     is fdiv_no_ovfl:
   12478  1.1     is 	mov.l		(%sp)+,%d0		# restore scale factor
   12479  1.1     is 	bra.b		fdiv_normal_exit
   12480  1.1     is 
   12481  1.1     is fdiv_may_ovfl:
   12482  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor
   12483  1.1     is 
   12484  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12485  1.1     is 
   12486  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12487  1.1     is 	fmov.l		&0x0,%fpsr		# set FPSR
   12488  1.1     is 
   12489  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12490  1.1     is 
   12491  1.1     is 	fmov.l		%fpsr,%d0
   12492  1.1     is 	fmov.l		&0x0,%fpcr
   12493  1.1     is 
   12494  1.1     is 	or.l		%d0,USER_FPSR(%a6)	# save INEX,N
   12495  1.1     is 
   12496  1.1     is 	fmovm.x		&0x01,-(%sp)		# save result to stack
   12497  1.1     is 	mov.w		(%sp),%d0		# fetch new exponent
   12498  1.1     is 	add.l		&0xc,%sp		# clear result from stack
   12499  1.1     is 	andi.l		&0x7fff,%d0		# strip sign
   12500  1.1     is 	sub.l		(%sp),%d0		# add scale factor
   12501  1.1     is 	cmp.l		%d0,(tbl_fdiv_ovfl2.b,%pc,%d1.w*4)
   12502  1.1     is 	blt.b		fdiv_no_ovfl
   12503  1.1     is 	mov.l		(%sp)+,%d0
   12504  1.1     is 
   12505  1.1     is fdiv_ovfl_tst:
   12506  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   12507  1.1     is 
   12508  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   12509  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   12510  1.1     is 	bne.b		fdiv_ovfl_ena		# yes
   12511  1.1     is 
   12512  1.1     is fdiv_ovfl_dis:
   12513  1.1     is 	btst		&neg_bit,FPSR_CC(%a6) 	# is result negative?
   12514  1.1     is 	sne		%d1			# set sign param accordingly
   12515  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   12516  1.1     is 	bsr.l		ovf_res			# calculate default result
   12517  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF if applicable
   12518  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   12519  1.1     is 	rts
   12520  1.1     is 
   12521  1.1     is fdiv_ovfl_ena:
   12522  1.1     is 	mov.l		L_SCR3(%a6),%d1
   12523  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   12524  1.1     is 	bne.b		fdiv_ovfl_ena_sd	# no, do sgl or dbl
   12525  1.1     is 
   12526  1.1     is fdiv_ovfl_ena_cont:
   12527  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   12528  1.1     is 
   12529  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   12530  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   12531  1.1     is 	mov.w		%d1,%d2			# make a copy
   12532  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12533  1.1     is 	sub.l		%d0,%d1			# add scale factor
   12534  1.1     is 	subi.l		&0x6000,%d1		# subtract bias
   12535  1.1     is 	andi.w		&0x7fff,%d1		# clear sign bit
   12536  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   12537  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   12538  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   12539  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12540  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12541  1.1     is 	bra.b		fdiv_ovfl_dis
   12542  1.1     is 
   12543  1.1     is fdiv_ovfl_ena_sd:
   12544  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   12545  1.1     is 
   12546  1.1     is 	mov.l		L_SCR3(%a6),%d1
   12547  1.1     is 	andi.b		&0x30,%d1		# keep rnd mode
   12548  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   12549  1.1     is 
   12550  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12551  1.1     is 
   12552  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12553  1.1     is 	bra.b		fdiv_ovfl_ena_cont
   12554  1.1     is 
   12555  1.1     is fdiv_unfl:
   12556  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12557  1.1     is 
   12558  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12559  1.1     is 
   12560  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   12561  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12562  1.1     is 
   12563  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12564  1.1     is 
   12565  1.1     is 	fmov.l		%fpsr,%d1		# save status
   12566  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12567  1.1     is 
   12568  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12569  1.1     is 
   12570  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   12571  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   12572  1.1     is 	bne.b		fdiv_unfl_ena		# yes
   12573  1.1     is 
   12574  1.1     is fdiv_unfl_dis:
   12575  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   12576  1.1     is 
   12577  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   12578  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   12579  1.1     is 	bsr.l		unf_res			# calculate default result
   12580  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# 'Z' may have been set
   12581  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   12582  1.1     is 	rts
   12583  1.1     is 
   12584  1.1     is #
   12585  1.1     is # UNFL is enabled.
   12586  1.1     is #
   12587  1.1     is fdiv_unfl_ena:
   12588  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   12589  1.1     is 
   12590  1.1     is 	mov.l		L_SCR3(%a6),%d1
   12591  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   12592  1.1     is 	bne.b		fdiv_unfl_ena_sd	# no, sgl or dbl
   12593  1.1     is 
   12594  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12595  1.1     is 
   12596  1.1     is fdiv_unfl_ena_cont:
   12597  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12598  1.1     is 
   12599  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp1	# execute divide
   12600  1.1     is 
   12601  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12602  1.1     is 
   12603  1.1     is 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   12604  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   12605  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   12606  1.1     is 	mov.l		%d1,%d2			# make a copy
   12607  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12608  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   12609  1.1     is 	sub.l		%d0,%d1			# add scale factoer
   12610  1.1     is 	addi.l		&0x6000,%d1		# add bias
   12611  1.1     is 	andi.w		&0x7fff,%d1
   12612  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   12613  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exp
   12614  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12615  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12616  1.1     is 	bra.w		fdiv_unfl_dis
   12617  1.1     is 
   12618  1.1     is fdiv_unfl_ena_sd:
   12619  1.1     is 	mov.l		L_SCR3(%a6),%d1
   12620  1.1     is 	andi.b		&0x30,%d1		# use only rnd mode
   12621  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   12622  1.1     is 
   12623  1.1     is 	bra.b		fdiv_unfl_ena_cont
   12624  1.1     is 
   12625  1.1     is #
   12626  1.1     is # the divide operation MAY underflow:
   12627  1.1     is #
   12628  1.1     is fdiv_may_unfl:
   12629  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12630  1.1     is 
   12631  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12632  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12633  1.1     is 
   12634  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12635  1.1     is 
   12636  1.1     is 	fmov.l		%fpsr,%d1		# save status
   12637  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12638  1.1     is 
   12639  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12640  1.1     is 
   12641  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   12642  1.1     is 	fcmp.b		%fp1,&0x1		# is |result| > 1.b?
   12643  1.1     is 	fbgt.w		fdiv_normal_exit	# no; no underflow occurred
   12644  1.1     is 	fblt.w		fdiv_unfl		# yes; underflow occurred
   12645  1.1     is 
   12646  1.1     is #
   12647  1.1     is # we still don't know if underflow occurred. result is ~ equal to 1. but,
   12648  1.1     is # we don't know if the result was an underflow that rounded up to a 1
   12649  1.1     is # or a normalized number that rounded down to a 1. so, redo the entire
   12650  1.1     is # operation using RZ as the rounding mode to see what the pre-rounded
   12651  1.1     is # result is. this case should be relatively rare.
   12652  1.1     is #
   12653  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   12654  1.1     is 
   12655  1.1     is 	mov.l		L_SCR3(%a6),%d1
   12656  1.1     is 	andi.b		&0xc0,%d1		# keep rnd prec
   12657  1.1     is 	ori.b		&rz_mode*0x10,%d1	# insert RZ
   12658  1.1     is 
   12659  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   12660  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12661  1.1     is 
   12662  1.1     is 	fdiv.x		FP_SCR0(%a6),%fp1	# execute divide
   12663  1.1     is 
   12664  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12665  1.1     is 	fabs.x		%fp1			# make absolute value
   12666  1.1     is 	fcmp.b		%fp1,&0x1		# is |result| < 1.b?
   12667  1.1     is 	fbge.w		fdiv_normal_exit	# no; no underflow occurred
   12668  1.1     is 	bra.w		fdiv_unfl		# yes; underflow occurred
   12669  1.1     is 
   12670  1.1     is ############################################################################
   12671  1.1     is 
   12672  1.1     is #
   12673  1.1     is # Divide: inputs are not both normalized; what are they?
   12674  1.1     is #
   12675  1.1     is fdiv_not_norm:
   12676  1.1     is 	mov.w		(tbl_fdiv_op.b,%pc,%d1.w*2),%d1
   12677  1.1     is 	jmp		(tbl_fdiv_op.b,%pc,%d1.w*1)
   12678  1.1     is 
   12679  1.1     is 	swbeg		&48
   12680  1.1     is tbl_fdiv_op:
   12681  1.1     is 	short		fdiv_norm	- tbl_fdiv_op # NORM / NORM
   12682  1.1     is 	short		fdiv_inf_load	- tbl_fdiv_op # NORM / ZERO
   12683  1.1     is 	short		fdiv_zero_load	- tbl_fdiv_op # NORM / INF
   12684  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # NORM / QNAN
   12685  1.1     is 	short		fdiv_norm	- tbl_fdiv_op # NORM / DENORM
   12686  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # NORM / SNAN
   12687  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12688  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12689  1.1     is 
   12690  1.1     is 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / NORM
   12691  1.1     is 	short		fdiv_res_operr	- tbl_fdiv_op # ZERO / ZERO
   12692  1.1     is 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / INF
   12693  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # ZERO / QNAN
   12694  1.1     is 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / DENORM
   12695  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # ZERO / SNAN
   12696  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12697  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12698  1.1     is 
   12699  1.1     is 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / NORM
   12700  1.1     is 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / ZERO
   12701  1.1     is 	short		fdiv_res_operr	- tbl_fdiv_op # INF / INF
   12702  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # INF / QNAN
   12703  1.1     is 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / DENORM
   12704  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # INF / SNAN
   12705  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12706  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12707  1.1     is 
   12708  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / NORM
   12709  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / ZERO
   12710  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / INF
   12711  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / QNAN
   12712  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / DENORM
   12713  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # QNAN / SNAN
   12714  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12715  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12716  1.1     is 
   12717  1.1     is 	short		fdiv_norm	- tbl_fdiv_op # DENORM / NORM
   12718  1.1     is 	short		fdiv_inf_load	- tbl_fdiv_op # DENORM / ZERO
   12719  1.1     is 	short		fdiv_zero_load	- tbl_fdiv_op # DENORM / INF
   12720  1.1     is 	short		fdiv_res_qnan	- tbl_fdiv_op # DENORM / QNAN
   12721  1.1     is 	short		fdiv_norm	- tbl_fdiv_op # DENORM / DENORM
   12722  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # DENORM / SNAN
   12723  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12724  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12725  1.1     is 
   12726  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / NORM
   12727  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / ZERO
   12728  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / INF
   12729  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / QNAN
   12730  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / DENORM
   12731  1.1     is 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / SNAN
   12732  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12733  1.1     is 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12734  1.1     is 
   12735  1.1     is fdiv_res_qnan:
   12736  1.1     is 	bra.l		res_qnan
   12737  1.1     is fdiv_res_snan:
   12738  1.1     is 	bra.l		res_snan
   12739  1.1     is fdiv_res_operr:
   12740  1.1     is 	bra.l		res_operr
   12741  1.1     is 
   12742  1.1     is 	global		fdiv_zero_load		# global for fsgldiv
   12743  1.1     is fdiv_zero_load:
   12744  1.1     is 	mov.b		SRC_EX(%a0),%d0		# result sign is exclusive
   12745  1.1     is 	mov.b		DST_EX(%a1),%d1		# or of input signs.
   12746  1.1     is 	eor.b		%d0,%d1
   12747  1.1     is 	bpl.b		fdiv_zero_load_p	# result is positive
   12748  1.1     is 	fmov.s		&0x80000000,%fp0	# load a -ZERO
   12749  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set Z/N
   12750  1.1     is 	rts
   12751  1.1     is fdiv_zero_load_p:
   12752  1.1     is 	fmov.s		&0x00000000,%fp0	# load a +ZERO
   12753  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   12754  1.1     is 	rts
   12755  1.1     is 
   12756  1.1     is #
   12757  1.1     is # The destination was In Range and the source was a ZERO. The result,
   12758  1.1     is # therefore, is an INF w/ the proper sign.
   12759  1.1     is # So, determine the sign and return a new INF (w/ the j-bit cleared).
   12760  1.1     is #
   12761  1.1     is 	global		fdiv_inf_load		# global for fsgldiv
   12762  1.1     is fdiv_inf_load:
   12763  1.1     is 	ori.w		&dz_mask+adz_mask,2+USER_FPSR(%a6) # no; set DZ/ADZ
   12764  1.1     is 	mov.b		SRC_EX(%a0),%d0		# load both signs
   12765  1.1     is 	mov.b		DST_EX(%a1),%d1
   12766  1.1     is 	eor.b		%d0,%d1
   12767  1.1     is 	bpl.b		fdiv_inf_load_p		# result is positive
   12768  1.1     is 	fmov.s		&0xff800000,%fp0	# make result -INF
   12769  1.1     is 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
   12770  1.1     is 	rts
   12771  1.1     is fdiv_inf_load_p:
   12772  1.1     is 	fmov.s		&0x7f800000,%fp0	# make result +INF
   12773  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
   12774  1.1     is 	rts
   12775  1.1     is 
   12776  1.1     is #
   12777  1.1     is # The destination was an INF w/ an In Range or ZERO source, the result is
   12778  1.1     is # an INF w/ the proper sign.
   12779  1.1     is # The 68881/882 returns the destination INF w/ the new sign(if the j-bit of the
   12780  1.1     is # dst INF is set, then then j-bit of the result INF is also set).
   12781  1.1     is #
   12782  1.1     is 	global		fdiv_inf_dst		# global for fsgldiv
   12783  1.1     is fdiv_inf_dst:
   12784  1.1     is 	mov.b		DST_EX(%a1),%d0		# load both signs
   12785  1.1     is 	mov.b		SRC_EX(%a0),%d1
   12786  1.1     is 	eor.b		%d0,%d1
   12787  1.1     is 	bpl.b		fdiv_inf_dst_p		# result is positive
   12788  1.1     is 
   12789  1.1     is 	fmovm.x		DST(%a1),&0x80		# return result in fp0
   12790  1.1     is 	fabs.x		%fp0			# clear sign bit
   12791  1.1     is 	fneg.x		%fp0			# set sign bit
   12792  1.1     is 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/NEG
   12793  1.1     is 	rts
   12794  1.1     is 
   12795  1.1     is fdiv_inf_dst_p:
   12796  1.1     is 	fmovm.x		DST(%a1),&0x80		# return result in fp0
   12797  1.1     is 	fabs.x		%fp0			# return positive INF
   12798  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6) # set INF
   12799  1.1     is 	rts
   12800  1.1     is 
   12801  1.1     is #########################################################################
   12802  1.1     is # XDEF ****************************************************************	#
   12803  1.1     is #	fneg(): emulates the fneg instruction				#
   12804  1.1     is #	fsneg(): emulates the fsneg instruction				#
   12805  1.1     is #	fdneg(): emulates the fdneg instruction				#
   12806  1.1     is #									#
   12807  1.1     is # XREF ****************************************************************	#
   12808  1.1     is # 	norm() - normalize a denorm to provide EXOP			#
   12809  1.1     is #	scale_to_zero_src() - scale sgl/dbl source exponent		#
   12810  1.1     is #	ovf_res() - return default overflow result			#
   12811  1.1     is #	unf_res() - return default underflow result			#
   12812  1.1     is # 	res_qnan_1op() - return QNAN result				#
   12813  1.1     is #	res_snan_1op() - return SNAN result				#
   12814  1.1     is #									#
   12815  1.1     is # INPUT ***************************************************************	#
   12816  1.1     is #	a0 = pointer to extended precision source operand		#
   12817  1.1     is #	d0 = rnd prec,mode						#
   12818  1.1     is #									#
   12819  1.1     is # OUTPUT **************************************************************	#
   12820  1.1     is #	fp0 = result							#
   12821  1.1     is #	fp1 = EXOP (if exception occurred)				#
   12822  1.1     is #									#
   12823  1.1     is # ALGORITHM ***********************************************************	#
   12824  1.1     is #	Handle NANs, zeroes, and infinities as special cases. Separate	#
   12825  1.1     is # norms/denorms into ext/sgl/dbl precisions. Extended precision can be	#
   12826  1.1     is # emulated by simply setting sign bit. Sgl/dbl operands must be scaled	#
   12827  1.1     is # and an actual fneg performed to see if overflow/underflow would have	#
   12828  1.1     is # occurred. If so, return default underflow/overflow result. Else,	#
   12829  1.1     is # scale the result exponent and return result. FPSR gets set based on	#
   12830  1.1     is # the result value.							#
   12831  1.1     is #									#
   12832  1.1     is #########################################################################
   12833  1.1     is 
   12834  1.1     is 	global		fsneg
   12835  1.1     is fsneg:
   12836  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   12837  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   12838  1.1     is 	bra.b		fneg
   12839  1.1     is 
   12840  1.1     is 	global		fdneg
   12841  1.1     is fdneg:
   12842  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   12843  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   12844  1.1     is 
   12845  1.1     is 	global		fneg
   12846  1.1     is fneg:
   12847  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   12848  1.1     is 	mov.b		STAG(%a6),%d1
   12849  1.1     is 	bne.w		fneg_not_norm		# optimize on non-norm input
   12850  1.1     is 
   12851  1.1     is #
   12852  1.1     is # NEGATE SIGN : norms and denorms ONLY!
   12853  1.1     is #
   12854  1.1     is fneg_norm:
   12855  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   12856  1.1     is 	bne.w		fneg_not_ext		# no; go handle sgl or dbl
   12857  1.1     is 
   12858  1.1     is #
   12859  1.1     is # precision selected is extended. so...we can not get an underflow
   12860  1.1     is # or overflow because of rounding to the correct precision. so...
   12861  1.1     is # skip the scaling and unscaling...
   12862  1.1     is #
   12863  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12864  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12865  1.1     is 	mov.w		SRC_EX(%a0),%d0
   12866  1.1     is 	eori.w		&0x8000,%d0		# negate sign
   12867  1.1     is 	bpl.b		fneg_norm_load		# sign is positive
   12868  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   12869  1.1     is fneg_norm_load:
   12870  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)
   12871  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12872  1.1     is 	rts
   12873  1.1     is 
   12874  1.1     is #
   12875  1.1     is # for an extended precision DENORM, the UNFL exception bit is set
   12876  1.1     is # the accrued bit is NOT set in this instance(no inexactness!)
   12877  1.1     is #
   12878  1.1     is fneg_denorm:
   12879  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   12880  1.1     is 	bne.b		fneg_not_ext		# no; go handle sgl or dbl
   12881  1.1     is 
   12882  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12883  1.1     is 
   12884  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12885  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12886  1.1     is 	mov.w		SRC_EX(%a0),%d0
   12887  1.1     is 	eori.w		&0x8000,%d0		# negate sign
   12888  1.1     is 	bpl.b		fneg_denorm_done	# no
   12889  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# yes, set 'N' ccode bit
   12890  1.1     is fneg_denorm_done:
   12891  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)
   12892  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   12893  1.1     is 
   12894  1.1     is 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
   12895  1.1     is 	bne.b		fneg_ext_unfl_ena	# yes
   12896  1.1     is 	rts
   12897  1.1     is 
   12898  1.1     is #
   12899  1.1     is # the input is an extended DENORM and underflow is enabled in the FPCR.
   12900  1.1     is # normalize the mantissa and add the bias of 0x6000 to the resulting negative
   12901  1.1     is # exponent and insert back into the operand.
   12902  1.1     is #
   12903  1.1     is fneg_ext_unfl_ena:
   12904  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   12905  1.1     is 	bsr.l		norm			# normalize result
   12906  1.1     is 	neg.w		%d0			# new exponent = -(shft val)
   12907  1.1     is 	addi.w		&0x6000,%d0		# add new bias to exponent
   12908  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
   12909  1.1     is 	andi.w		&0x8000,%d1	 	# keep old sign
   12910  1.1     is 	andi.w		&0x7fff,%d0		# clear sign position
   12911  1.1     is 	or.w		%d1,%d0			# concat old sign, new exponent
   12912  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   12913  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12914  1.1     is 	rts
   12915  1.1     is 
   12916  1.1     is #
   12917  1.1     is # operand is either single or double
   12918  1.1     is #
   12919  1.1     is fneg_not_ext:
   12920  1.1     is 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
   12921  1.1     is 	bne.b		fneg_dbl
   12922  1.1     is 
   12923  1.1     is #
   12924  1.1     is # operand is to be rounded to single precision
   12925  1.1     is #
   12926  1.1     is fneg_sgl:
   12927  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12928  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12929  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12930  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor
   12931  1.1     is 
   12932  1.1     is 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
   12933  1.1     is 	bge.w		fneg_sd_unfl		# yes; go handle underflow
   12934  1.1     is 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
   12935  1.1     is 	beq.w		fneg_sd_may_ovfl	# maybe; go check
   12936  1.1     is 	blt.w		fneg_sd_ovfl		# yes; go handle overflow
   12937  1.1     is 
   12938  1.1     is #
   12939  1.1     is # operand will NOT overflow or underflow when moved in to the fp reg file
   12940  1.1     is #
   12941  1.1     is fneg_sd_normal:
   12942  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   12943  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12944  1.1     is 
   12945  1.1     is 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
   12946  1.1     is 
   12947  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   12948  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   12949  1.1     is 
   12950  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12951  1.1     is 
   12952  1.1     is fneg_sd_normal_exit:
   12953  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   12954  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   12955  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
   12956  1.1     is 	mov.w		%d1,%d2			# make a copy
   12957  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   12958  1.1     is 	sub.l		%d0,%d1			# add scale factor
   12959  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   12960  1.1     is 	or.w		%d1,%d2			# concat old sign,new exp
   12961  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   12962  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   12963  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12964  1.1     is 	rts
   12965  1.1     is 
   12966  1.1     is #
   12967  1.1     is # operand is to be rounded to double precision
   12968  1.1     is #
   12969  1.1     is fneg_dbl:
   12970  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12971  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12972  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12973  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor
   12974  1.1     is 
   12975  1.1     is 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
   12976  1.1     is 	bge.b		fneg_sd_unfl		# yes; go handle underflow
   12977  1.1     is 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
   12978  1.1     is 	beq.w		fneg_sd_may_ovfl	# maybe; go check
   12979  1.1     is 	blt.w		fneg_sd_ovfl		# yes; go handle overflow
   12980  1.1     is 	bra.w		fneg_sd_normal		# no; ho handle normalized op
   12981  1.1     is 
   12982  1.1     is #
   12983  1.1     is # operand WILL underflow when moved in to the fp register file
   12984  1.1     is #
   12985  1.1     is fneg_sd_unfl:
   12986  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12987  1.1     is 
   12988  1.1     is 	eori.b		&0x80,FP_SCR0_EX(%a6)	# negate sign
   12989  1.1     is 	bpl.b		fneg_sd_unfl_tst
   12990  1.1     is 	bset		&neg_bit,FPSR_CC(%a6)	# set 'N' ccode bit
   12991  1.1     is 
   12992  1.1     is # if underflow or inexact is enabled, go calculate EXOP first.
   12993  1.1     is fneg_sd_unfl_tst:
   12994  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   12995  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   12996  1.1     is 	bne.b		fneg_sd_unfl_ena	# yes
   12997  1.1     is 
   12998  1.1     is fneg_sd_unfl_dis:
   12999  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   13000  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   13001  1.1     is 	bsr.l		unf_res			# calculate default result
   13002  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# unf_res may have set 'Z'
   13003  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   13004  1.1     is 	rts
   13005  1.1     is 
   13006  1.1     is #
   13007  1.1     is # operand will underflow AND underflow is enabled.
   13008  1.1     is # therefore, we must return the result rounded to extended precision.
   13009  1.1     is #
   13010  1.1     is fneg_sd_unfl_ena:
   13011  1.1     is 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   13012  1.1     is 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   13013  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   13014  1.1     is 
   13015  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   13016  1.1     is 	mov.l		%d1,%d2			# make a copy
   13017  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   13018  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   13019  1.1     is 	sub.l		%d0,%d1			# subtract scale factor
   13020  1.1     is 	addi.l		&0x6000,%d1		# add new bias
   13021  1.1     is 	andi.w		&0x7fff,%d1
   13022  1.1     is 	or.w		%d2,%d1			# concat new sign,new exp
   13023  1.1     is 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
   13024  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   13025  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   13026  1.1     is 	bra.b		fneg_sd_unfl_dis
   13027  1.1     is 
   13028  1.1     is #
   13029  1.1     is # operand WILL overflow.
   13030  1.1     is #
   13031  1.1     is fneg_sd_ovfl:
   13032  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13033  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13034  1.1     is 
   13035  1.1     is 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
   13036  1.1     is 
   13037  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   13038  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   13039  1.1     is 
   13040  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13041  1.1     is 
   13042  1.1     is fneg_sd_ovfl_tst:
   13043  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   13044  1.1     is 
   13045  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   13046  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   13047  1.1     is 	bne.b		fneg_sd_ovfl_ena	# yes
   13048  1.1     is 
   13049  1.1     is #
   13050  1.1     is # OVFL is not enabled; therefore, we must create the default result by
   13051  1.1     is # calling ovf_res().
   13052  1.1     is #
   13053  1.1     is fneg_sd_ovfl_dis:
   13054  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   13055  1.1     is 	sne		%d1			# set sign param accordingly
   13056  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   13057  1.1     is 	bsr.l		ovf_res			# calculate default result
   13058  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   13059  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   13060  1.1     is 	rts
   13061  1.1     is 
   13062  1.1     is #
   13063  1.1     is # OVFL is enabled.
   13064  1.1     is # the INEX2 bit has already been updated by the round to the correct precision.
   13065  1.1     is # now, round to extended(and don't alter the FPSR).
   13066  1.1     is #
   13067  1.1     is fneg_sd_ovfl_ena:
   13068  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   13069  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   13070  1.1     is 	mov.l		%d1,%d2			# make a copy
   13071  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   13072  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   13073  1.1     is 	sub.l		%d0,%d1			# add scale factor
   13074  1.1     is 	subi.l		&0x6000,%d1		# subtract bias
   13075  1.1     is 	andi.w		&0x7fff,%d1
   13076  1.1     is 	or.w		%d2,%d1			# concat sign,exp
   13077  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   13078  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   13079  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   13080  1.1     is 	bra.b		fneg_sd_ovfl_dis
   13081  1.1     is 
   13082  1.1     is #
   13083  1.1     is # the move in MAY underflow. so...
   13084  1.1     is #
   13085  1.1     is fneg_sd_may_ovfl:
   13086  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13087  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13088  1.1     is 
   13089  1.1     is 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
   13090  1.1     is 
   13091  1.1     is 	fmov.l		%fpsr,%d1		# save status
   13092  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   13093  1.1     is 
   13094  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13095  1.1     is 
   13096  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   13097  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   13098  1.1     is 	fbge.w		fneg_sd_ovfl_tst	# yes; overflow has occurred
   13099  1.1     is 
   13100  1.1     is # no, it didn't overflow; we have correct result
   13101  1.1     is 	bra.w		fneg_sd_normal_exit
   13102  1.1     is 
   13103  1.1     is ##########################################################################
   13104  1.1     is 
   13105  1.1     is #
   13106  1.1     is # input is not normalized; what is it?
   13107  1.1     is #
   13108  1.1     is fneg_not_norm:
   13109  1.1     is 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13110  1.1     is 	beq.w		fneg_denorm
   13111  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13112  1.1     is 	beq.l		res_snan_1op
   13113  1.1     is 	cmpi.b		%d1,&QNAN		# weed out QNAN
   13114  1.1     is 	beq.l		res_qnan_1op
   13115  1.1     is 
   13116  1.1     is #
   13117  1.1     is # do the fneg; at this point, only possible ops are ZERO and INF.
   13118  1.1     is # use fneg to determine ccodes.
   13119  1.1     is # prec:mode should be zero at this point but it won't affect answer anyways.
   13120  1.1     is #
   13121  1.1     is 	fneg.x		SRC_EX(%a0),%fp0	# do fneg
   13122  1.1     is 	fmov.l		%fpsr,%d0
   13123  1.1     is 	rol.l		&0x8,%d0		# put ccodes in lo byte
   13124  1.1     is 	mov.b		%d0,FPSR_CC(%a6)	# insert correct ccodes
   13125  1.1     is 	rts
   13126  1.1     is 
   13127  1.1     is #########################################################################
   13128  1.1     is # XDEF ****************************************************************	#
   13129  1.1     is # 	ftst(): emulates the ftest instruction				#
   13130  1.1     is #									#
   13131  1.1     is # XREF ****************************************************************	#
   13132  1.1     is # 	res{s,q}nan_1op() - set NAN result for monadic instruction	#
   13133  1.1     is #									#
   13134  1.1     is # INPUT ***************************************************************	#
   13135  1.1     is # 	a0 = pointer to extended precision source operand		#
   13136  1.1     is #									#
   13137  1.1     is # OUTPUT **************************************************************	#
   13138  1.1     is #	none								#
   13139  1.1     is #									#
   13140  1.1     is # ALGORITHM ***********************************************************	#
   13141  1.1     is # 	Check the source operand tag (STAG) and set the FPCR according	#
   13142  1.1     is # to the operand type and sign.						#
   13143  1.1     is #									#
   13144  1.1     is #########################################################################
   13145  1.1     is 
   13146  1.1     is 	global		ftst
   13147  1.1     is ftst:
   13148  1.1     is 	mov.b		STAG(%a6),%d1
   13149  1.1     is 	bne.b		ftst_not_norm		# optimize on non-norm input
   13150  1.1     is 
   13151  1.1     is #
   13152  1.1     is # Norm:
   13153  1.1     is #
   13154  1.1     is ftst_norm:
   13155  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   13156  1.1     is 	bmi.b		ftst_norm_m		# yes
   13157  1.1     is 	rts
   13158  1.1     is ftst_norm_m:
   13159  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   13160  1.1     is 	rts
   13161  1.1     is 
   13162  1.1     is #
   13163  1.1     is # input is not normalized; what is it?
   13164  1.1     is #
   13165  1.1     is ftst_not_norm:
   13166  1.1     is 	cmpi.b		%d1,&ZERO		# weed out ZERO
   13167  1.1     is 	beq.b		ftst_zero
   13168  1.1     is 	cmpi.b		%d1,&INF		# weed out INF
   13169  1.1     is 	beq.b		ftst_inf
   13170  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13171  1.1     is 	beq.l		res_snan_1op
   13172  1.1     is 	cmpi.b		%d1,&QNAN		# weed out QNAN
   13173  1.1     is 	beq.l		res_qnan_1op
   13174  1.1     is 
   13175  1.1     is #
   13176  1.1     is # Denorm:
   13177  1.1     is #
   13178  1.1     is ftst_denorm:
   13179  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   13180  1.1     is 	bmi.b		ftst_denorm_m		# yes
   13181  1.1     is 	rts
   13182  1.1     is ftst_denorm_m:
   13183  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   13184  1.1     is 	rts
   13185  1.1     is 
   13186  1.1     is #
   13187  1.1     is # Infinity:
   13188  1.1     is #
   13189  1.1     is ftst_inf:
   13190  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   13191  1.1     is 	bmi.b		ftst_inf_m		# yes
   13192  1.1     is ftst_inf_p:
   13193  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13194  1.1     is 	rts
   13195  1.1     is ftst_inf_m:
   13196  1.1     is 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'I','N' ccode bits
   13197  1.1     is 	rts
   13198  1.1     is 
   13199  1.1     is #
   13200  1.1     is # Zero:
   13201  1.1     is #
   13202  1.1     is ftst_zero:
   13203  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   13204  1.1     is 	bmi.b		ftst_zero_m		# yes
   13205  1.1     is ftst_zero_p:
   13206  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   13207  1.1     is 	rts
   13208  1.1     is ftst_zero_m:
   13209  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set 'Z','N' ccode bits
   13210  1.1     is 	rts
   13211  1.1     is 
   13212  1.1     is #########################################################################
   13213  1.1     is # XDEF ****************************************************************	#
   13214  1.1     is #	fint(): emulates the fint instruction				#
   13215  1.1     is #									#
   13216  1.1     is # XREF ****************************************************************	#
   13217  1.1     is #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
   13218  1.1     is #									#
   13219  1.1     is # INPUT ***************************************************************	#
   13220  1.1     is #	a0 = pointer to extended precision source operand		#
   13221  1.1     is #	d0 = round precision/mode					#
   13222  1.1     is #									#
   13223  1.1     is # OUTPUT **************************************************************	#
   13224  1.1     is #	fp0 = result							#
   13225  1.1     is #									#
   13226  1.1     is # ALGORITHM ***********************************************************	#
   13227  1.1     is # 	Separate according to operand type. Unnorms don't pass through 	#
   13228  1.1     is # here. For norms, load the rounding mode/prec, execute a "fint", then 	#
   13229  1.1     is # store the resulting FPSR bits.					#
   13230  1.1     is # 	For denorms, force the j-bit to a one and do the same as for	#
   13231  1.1     is # norms. Denorms are so low that the answer will either be a zero or a 	#
   13232  1.1     is # one.									#
   13233  1.1     is # 	For zeroes/infs/NANs, return the same while setting the FPSR	#
   13234  1.1     is # as appropriate.							#
   13235  1.1     is #									#
   13236  1.1     is #########################################################################
   13237  1.1     is 
   13238  1.1     is 	global		fint
   13239  1.1     is fint:
   13240  1.1     is 	mov.b		STAG(%a6),%d1
   13241  1.1     is 	bne.b		fint_not_norm		# optimize on non-norm input
   13242  1.1     is 
   13243  1.1     is #
   13244  1.1     is # Norm:
   13245  1.1     is #
   13246  1.1     is fint_norm:
   13247  1.1     is 	andi.b		&0x30,%d0		# set prec = ext
   13248  1.1     is 
   13249  1.1     is 	fmov.l		%d0,%fpcr		# set FPCR
   13250  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13251  1.1     is 
   13252  1.1     is 	fint.x 		SRC(%a0),%fp0		# execute fint
   13253  1.1     is 
   13254  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   13255  1.1     is 	fmov.l		%fpsr,%d0		# save FPSR
   13256  1.1     is 	or.l		%d0,USER_FPSR(%a6)	# set exception bits
   13257  1.1     is 
   13258  1.1     is 	rts
   13259  1.1     is 
   13260  1.1     is #
   13261  1.1     is # input is not normalized; what is it?
   13262  1.1     is #
   13263  1.1     is fint_not_norm:
   13264  1.1     is 	cmpi.b		%d1,&ZERO		# weed out ZERO
   13265  1.1     is 	beq.b		fint_zero
   13266  1.1     is 	cmpi.b		%d1,&INF		# weed out INF
   13267  1.1     is 	beq.b		fint_inf
   13268  1.1     is 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13269  1.1     is 	beq.b		fint_denorm
   13270  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13271  1.1     is 	beq.l		res_snan_1op
   13272  1.1     is 	bra.l		res_qnan_1op		# weed out QNAN
   13273  1.1     is 
   13274  1.1     is #
   13275  1.1     is # Denorm:
   13276  1.1     is #
   13277  1.1     is # for DENORMs, the result will be either (+/-)ZERO or (+/-)1.
   13278  1.1     is # also, the INEX2 and AINEX exception bits will be set.
   13279  1.1     is # so, we could either set these manually or force the DENORM
   13280  1.1     is # to a very small NORM and ship it to the NORM routine.
   13281  1.1     is # I do the latter.
   13282  1.1     is #
   13283  1.1     is fint_denorm:
   13284  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
   13285  1.1     is 	mov.b		&0x80,FP_SCR0_HI(%a6)	# force DENORM ==> small NORM
   13286  1.1     is 	lea		FP_SCR0(%a6),%a0
   13287  1.1     is 	bra.b		fint_norm
   13288  1.1     is 
   13289  1.1     is #
   13290  1.1     is # Zero:
   13291  1.1     is #
   13292  1.1     is fint_zero:
   13293  1.1     is 	tst.b		SRC_EX(%a0)		# is ZERO negative?
   13294  1.1     is 	bmi.b		fint_zero_m		# yes
   13295  1.1     is fint_zero_p:
   13296  1.1     is 	fmov.s		&0x00000000,%fp0	# return +ZERO in fp0
   13297  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13298  1.1     is 	rts
   13299  1.1     is fint_zero_m:
   13300  1.1     is 	fmov.s		&0x80000000,%fp0	# return -ZERO in fp0
   13301  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
   13302  1.1     is 	rts
   13303  1.1     is 
   13304  1.1     is #
   13305  1.1     is # Infinity:
   13306  1.1     is #
   13307  1.1     is fint_inf:
   13308  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   13309  1.1     is 	tst.b		SRC_EX(%a0)		# is INF negative?
   13310  1.1     is 	bmi.b		fint_inf_m		# yes
   13311  1.1     is fint_inf_p:
   13312  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13313  1.1     is 	rts
   13314  1.1     is fint_inf_m:
   13315  1.1     is 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   13316  1.1     is 	rts
   13317  1.1     is 
   13318  1.1     is #########################################################################
   13319  1.1     is # XDEF ****************************************************************	#
   13320  1.1     is #	fintrz(): emulates the fintrz instruction			#
   13321  1.1     is #									#
   13322  1.1     is # XREF ****************************************************************	#
   13323  1.1     is #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
   13324  1.1     is #									#
   13325  1.1     is # INPUT ***************************************************************	#
   13326  1.1     is #	a0 = pointer to extended precision source operand		#
   13327  1.1     is #	d0 = round precision/mode					#
   13328  1.1     is #									#
   13329  1.1     is # OUTPUT **************************************************************	#
   13330  1.1     is # 	fp0 = result							#
   13331  1.1     is #									#
   13332  1.1     is # ALGORITHM ***********************************************************	#
   13333  1.1     is #	Separate according to operand type. Unnorms don't pass through	#
   13334  1.1     is # here. For norms, load the rounding mode/prec, execute a "fintrz", 	#
   13335  1.1     is # then store the resulting FPSR bits.					#
   13336  1.1     is # 	For denorms, force the j-bit to a one and do the same as for	#
   13337  1.1     is # norms. Denorms are so low that the answer will either be a zero or a	#
   13338  1.1     is # one.									#
   13339  1.1     is # 	For zeroes/infs/NANs, return the same while setting the FPSR	#
   13340  1.1     is # as appropriate.							#
   13341  1.1     is #									#
   13342  1.1     is #########################################################################
   13343  1.1     is 
   13344  1.1     is 	global		fintrz
   13345  1.1     is fintrz:
   13346  1.1     is 	mov.b		STAG(%a6),%d1
   13347  1.1     is 	bne.b		fintrz_not_norm		# optimize on non-norm input
   13348  1.1     is 
   13349  1.1     is #
   13350  1.1     is # Norm:
   13351  1.1     is #
   13352  1.1     is fintrz_norm:
   13353  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13354  1.1     is 
   13355  1.1     is 	fintrz.x	SRC(%a0),%fp0		# execute fintrz
   13356  1.1     is 
   13357  1.1     is 	fmov.l		%fpsr,%d0		# save FPSR
   13358  1.1     is 	or.l		%d0,USER_FPSR(%a6)	# set exception bits
   13359  1.1     is 
   13360  1.1     is 	rts
   13361  1.1     is 
   13362  1.1     is #
   13363  1.1     is # input is not normalized; what is it?
   13364  1.1     is #
   13365  1.1     is fintrz_not_norm:
   13366  1.1     is 	cmpi.b		%d1,&ZERO		# weed out ZERO
   13367  1.1     is 	beq.b		fintrz_zero
   13368  1.1     is 	cmpi.b		%d1,&INF		# weed out INF
   13369  1.1     is 	beq.b		fintrz_inf
   13370  1.1     is 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13371  1.1     is 	beq.b		fintrz_denorm
   13372  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13373  1.1     is 	beq.l		res_snan_1op
   13374  1.1     is 	bra.l		res_qnan_1op		# weed out QNAN
   13375  1.1     is 
   13376  1.1     is #
   13377  1.1     is # Denorm:
   13378  1.1     is #
   13379  1.1     is # for DENORMs, the result will be (+/-)ZERO.
   13380  1.1     is # also, the INEX2 and AINEX exception bits will be set.
   13381  1.1     is # so, we could either set these manually or force the DENORM
   13382  1.1     is # to a very small NORM and ship it to the NORM routine.
   13383  1.1     is # I do the latter.
   13384  1.1     is #
   13385  1.1     is fintrz_denorm:
   13386  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
   13387  1.1     is 	mov.b		&0x80,FP_SCR0_HI(%a6)	# force DENORM ==> small NORM
   13388  1.1     is 	lea		FP_SCR0(%a6),%a0
   13389  1.1     is 	bra.b		fintrz_norm
   13390  1.1     is 
   13391  1.1     is #
   13392  1.1     is # Zero:
   13393  1.1     is #
   13394  1.1     is fintrz_zero:
   13395  1.1     is 	tst.b		SRC_EX(%a0)		# is ZERO negative?
   13396  1.1     is 	bmi.b		fintrz_zero_m		# yes
   13397  1.1     is fintrz_zero_p:
   13398  1.1     is 	fmov.s		&0x00000000,%fp0	# return +ZERO in fp0
   13399  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13400  1.1     is 	rts
   13401  1.1     is fintrz_zero_m:
   13402  1.1     is 	fmov.s		&0x80000000,%fp0	# return -ZERO in fp0
   13403  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
   13404  1.1     is 	rts
   13405  1.1     is 
   13406  1.1     is #
   13407  1.1     is # Infinity:
   13408  1.1     is #
   13409  1.1     is fintrz_inf:
   13410  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   13411  1.1     is 	tst.b		SRC_EX(%a0)		# is INF negative?
   13412  1.1     is 	bmi.b		fintrz_inf_m		# yes
   13413  1.1     is fintrz_inf_p:
   13414  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13415  1.1     is 	rts
   13416  1.1     is fintrz_inf_m:
   13417  1.1     is 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   13418  1.1     is 	rts
   13419  1.1     is 
   13420  1.1     is #########################################################################
   13421  1.1     is # XDEF ****************************************************************	#
   13422  1.1     is #	fabs():  emulates the fabs instruction				#
   13423  1.1     is #	fsabs(): emulates the fsabs instruction				#
   13424  1.1     is #	fdabs(): emulates the fdabs instruction				#
   13425  1.1     is #									#
   13426  1.1     is # XREF **************************************************************** #
   13427  1.1     is #	norm() - normalize denorm mantissa to provide EXOP		#
   13428  1.1     is #	scale_to_zero_src() - make exponent. = 0; get scale factor	#
   13429  1.1     is #	unf_res() - calculate underflow result				#
   13430  1.1     is #	ovf_res() - calculate overflow result				#
   13431  1.1     is #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
   13432  1.1     is #									#
   13433  1.1     is # INPUT *************************************************************** #
   13434  1.1     is #	a0 = pointer to extended precision source operand		#
   13435  1.1     is #	d0 = rnd precision/mode						#
   13436  1.1     is #									#
   13437  1.1     is # OUTPUT ************************************************************** #
   13438  1.1     is #	fp0 = result							#
   13439  1.1     is #	fp1 = EXOP (if exception occurred)				#
   13440  1.1     is #									#
   13441  1.1     is # ALGORITHM ***********************************************************	#
   13442  1.1     is #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   13443  1.1     is # norms into extended, single, and double precision. 			#
   13444  1.1     is # 	Simply clear sign for extended precision norm. Ext prec denorm	#
   13445  1.1     is # gets an EXOP created for it since it's an underflow.			#
   13446  1.1     is #	Double and single precision can overflow and underflow. First,	#
   13447  1.1     is # scale the operand such that the exponent is zero. Perform an "fabs"	#
   13448  1.1     is # using the correct rnd mode/prec. Check to see if the original 	#
   13449  1.1     is # exponent would take an exception. If so, use unf_res() or ovf_res()	#
   13450  1.1     is # to calculate the default result. Also, create the EXOP for the	#
   13451  1.1     is # exceptional case. If no exception should occur, insert the correct 	#
   13452  1.1     is # result exponent and return.						#
   13453  1.1     is # 	Unnorms don't pass through here.				#
   13454  1.1     is #									#
   13455  1.1     is #########################################################################
   13456  1.1     is 
   13457  1.1     is 	global		fsabs
   13458  1.1     is fsabs:
   13459  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   13460  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   13461  1.1     is 	bra.b		fabs
   13462  1.1     is 
   13463  1.1     is 	global		fdabs
   13464  1.1     is fdabs:
   13465  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   13466  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
   13467  1.1     is 
   13468  1.1     is 	global		fabs
   13469  1.1     is fabs:
   13470  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   13471  1.1     is 	mov.b		STAG(%a6),%d1
   13472  1.1     is 	bne.w		fabs_not_norm		# optimize on non-norm input
   13473  1.1     is 
   13474  1.1     is #
   13475  1.1     is # ABSOLUTE VALUE: norms and denorms ONLY!
   13476  1.1     is #
   13477  1.1     is fabs_norm:
   13478  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   13479  1.1     is 	bne.b		fabs_not_ext		# no; go handle sgl or dbl
   13480  1.1     is 
   13481  1.1     is #
   13482  1.1     is # precision selected is extended. so...we can not get an underflow
   13483  1.1     is # or overflow because of rounding to the correct precision. so...
   13484  1.1     is # skip the scaling and unscaling...
   13485  1.1     is #
   13486  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13487  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13488  1.1     is 	mov.w		SRC_EX(%a0),%d1
   13489  1.1     is 	bclr		&15,%d1			# force absolute value
   13490  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert exponent
   13491  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   13492  1.1     is 	rts
   13493  1.1     is 
   13494  1.1     is #
   13495  1.1     is # for an extended precision DENORM, the UNFL exception bit is set
   13496  1.1     is # the accrued bit is NOT set in this instance(no inexactness!)
   13497  1.1     is #
   13498  1.1     is fabs_denorm:
   13499  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   13500  1.1     is 	bne.b		fabs_not_ext		# no
   13501  1.1     is 
   13502  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   13503  1.1     is 
   13504  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13505  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13506  1.1     is 	mov.w		SRC_EX(%a0),%d0
   13507  1.1     is 	bclr		&15,%d0			# clear sign
   13508  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert exponent
   13509  1.1     is 
   13510  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   13511  1.1     is 
   13512  1.1     is 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
   13513  1.1     is 	bne.b		fabs_ext_unfl_ena
   13514  1.1     is 	rts
   13515  1.1     is 
   13516  1.1     is #
   13517  1.1     is # the input is an extended DENORM and underflow is enabled in the FPCR.
   13518  1.1     is # normalize the mantissa and add the bias of 0x6000 to the resulting negative
   13519  1.1     is # exponent and insert back into the operand.
   13520  1.1     is #
   13521  1.1     is fabs_ext_unfl_ena:
   13522  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   13523  1.1     is 	bsr.l		norm			# normalize result
   13524  1.1     is 	neg.w		%d0			# new exponent = -(shft val)
   13525  1.1     is 	addi.w		&0x6000,%d0		# add new bias to exponent
   13526  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
   13527  1.1     is 	andi.w		&0x8000,%d1		# keep old sign
   13528  1.1     is 	andi.w		&0x7fff,%d0		# clear sign position
   13529  1.1     is 	or.w		%d1,%d0			# concat old sign, new exponent
   13530  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   13531  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   13532  1.1     is 	rts
   13533  1.1     is 
   13534  1.1     is #
   13535  1.1     is # operand is either single or double
   13536  1.1     is #
   13537  1.1     is fabs_not_ext:
   13538  1.1     is 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
   13539  1.1     is 	bne.b		fabs_dbl
   13540  1.1     is 
   13541  1.1     is #
   13542  1.1     is # operand is to be rounded to single precision
   13543  1.1     is #
   13544  1.1     is fabs_sgl:
   13545  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13546  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13547  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13548  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor
   13549  1.1     is 
   13550  1.1     is 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
   13551  1.1     is 	bge.w		fabs_sd_unfl		# yes; go handle underflow
   13552  1.1     is 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
   13553  1.1     is 	beq.w		fabs_sd_may_ovfl	# maybe; go check
   13554  1.1     is 	blt.w		fabs_sd_ovfl		# yes; go handle overflow
   13555  1.1     is 
   13556  1.1     is #
   13557  1.1     is # operand will NOT overflow or underflow when moved in to the fp reg file
   13558  1.1     is #
   13559  1.1     is fabs_sd_normal:
   13560  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13561  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13562  1.1     is 
   13563  1.1     is 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
   13564  1.1     is 
   13565  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   13566  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   13567  1.1     is 
   13568  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13569  1.1     is 
   13570  1.1     is fabs_sd_normal_exit:
   13571  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   13572  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   13573  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
   13574  1.1     is 	mov.l		%d1,%d2			# make a copy
   13575  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   13576  1.1     is 	sub.l		%d0,%d1			# add scale factor
   13577  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   13578  1.1     is 	or.w		%d1,%d2			# concat old sign,new exp
   13579  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   13580  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   13581  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   13582  1.1     is 	rts
   13583  1.1     is 
   13584  1.1     is #
   13585  1.1     is # operand is to be rounded to double precision
   13586  1.1     is #
   13587  1.1     is fabs_dbl:
   13588  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13589  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13590  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13591  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor
   13592  1.1     is 
   13593  1.1     is 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
   13594  1.1     is 	bge.b		fabs_sd_unfl		# yes; go handle underflow
   13595  1.1     is 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
   13596  1.1     is 	beq.w		fabs_sd_may_ovfl	# maybe; go check
   13597  1.1     is 	blt.w		fabs_sd_ovfl		# yes; go handle overflow
   13598  1.1     is 	bra.w		fabs_sd_normal		# no; ho handle normalized op
   13599  1.1     is 
   13600  1.1     is #
   13601  1.1     is # operand WILL underflow when moved in to the fp register file
   13602  1.1     is #
   13603  1.1     is fabs_sd_unfl:
   13604  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   13605  1.1     is 
   13606  1.1     is 	bclr		&0x7,FP_SCR0_EX(%a6)	# force absolute value
   13607  1.1     is 
   13608  1.1     is # if underflow or inexact is enabled, go calculate EXOP first.
   13609  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   13610  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   13611  1.1     is 	bne.b		fabs_sd_unfl_ena	# yes
   13612  1.1     is 
   13613  1.1     is fabs_sd_unfl_dis:
   13614  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   13615  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   13616  1.1     is 	bsr.l		unf_res			# calculate default result
   13617  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set possible 'Z' ccode
   13618  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   13619  1.1     is 	rts
   13620  1.1     is 
   13621  1.1     is #
   13622  1.1     is # operand will underflow AND underflow is enabled.
   13623  1.1     is # therefore, we must return the result rounded to extended precision.
   13624  1.1     is #
   13625  1.1     is fabs_sd_unfl_ena:
   13626  1.1     is 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   13627  1.1     is 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   13628  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   13629  1.1     is 
   13630  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   13631  1.1     is 	mov.l		%d1,%d2			# make a copy
   13632  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   13633  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   13634  1.1     is 	sub.l		%d0,%d1			# subtract scale factor
   13635  1.1     is 	addi.l		&0x6000,%d1		# add new bias
   13636  1.1     is 	andi.w		&0x7fff,%d1
   13637  1.1     is 	or.w		%d2,%d1			# concat new sign,new exp
   13638  1.1     is 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
   13639  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   13640  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   13641  1.1     is 	bra.b		fabs_sd_unfl_dis
   13642  1.1     is 
   13643  1.1     is #
   13644  1.1     is # operand WILL overflow.
   13645  1.1     is #
   13646  1.1     is fabs_sd_ovfl:
   13647  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13648  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13649  1.1     is 
   13650  1.1     is 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
   13651  1.1     is 
   13652  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   13653  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   13654  1.1     is 
   13655  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13656  1.1     is 
   13657  1.1     is fabs_sd_ovfl_tst:
   13658  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   13659  1.1     is 
   13660  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   13661  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   13662  1.1     is 	bne.b		fabs_sd_ovfl_ena	# yes
   13663  1.1     is 
   13664  1.1     is #
   13665  1.1     is # OVFL is not enabled; therefore, we must create the default result by
   13666  1.1     is # calling ovf_res().
   13667  1.1     is #
   13668  1.1     is fabs_sd_ovfl_dis:
   13669  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   13670  1.1     is 	sne		%d1			# set sign param accordingly
   13671  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   13672  1.1     is 	bsr.l		ovf_res			# calculate default result
   13673  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   13674  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   13675  1.1     is 	rts
   13676  1.1     is 
   13677  1.1     is #
   13678  1.1     is # OVFL is enabled.
   13679  1.1     is # the INEX2 bit has already been updated by the round to the correct precision.
   13680  1.1     is # now, round to extended(and don't alter the FPSR).
   13681  1.1     is #
   13682  1.1     is fabs_sd_ovfl_ena:
   13683  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   13684  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   13685  1.1     is 	mov.l		%d1,%d2			# make a copy
   13686  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   13687  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   13688  1.1     is 	sub.l		%d0,%d1			# add scale factor
   13689  1.1     is 	subi.l		&0x6000,%d1		# subtract bias
   13690  1.1     is 	andi.w		&0x7fff,%d1
   13691  1.1     is 	or.w		%d2,%d1			# concat sign,exp
   13692  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   13693  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   13694  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   13695  1.1     is 	bra.b		fabs_sd_ovfl_dis
   13696  1.1     is 
   13697  1.1     is #
   13698  1.1     is # the move in MAY underflow. so...
   13699  1.1     is #
   13700  1.1     is fabs_sd_may_ovfl:
   13701  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   13702  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13703  1.1     is 
   13704  1.1     is 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
   13705  1.1     is 
   13706  1.1     is 	fmov.l		%fpsr,%d1		# save status
   13707  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   13708  1.1     is 
   13709  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13710  1.1     is 
   13711  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   13712  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   13713  1.1     is 	fbge.w		fabs_sd_ovfl_tst	# yes; overflow has occurred
   13714  1.1     is 
   13715  1.1     is # no, it didn't overflow; we have correct result
   13716  1.1     is 	bra.w		fabs_sd_normal_exit
   13717  1.1     is 
   13718  1.1     is ##########################################################################
   13719  1.1     is 
   13720  1.1     is #
   13721  1.1     is # input is not normalized; what is it?
   13722  1.1     is #
   13723  1.1     is fabs_not_norm:
   13724  1.1     is 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13725  1.1     is 	beq.w		fabs_denorm
   13726  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13727  1.1     is 	beq.l		res_snan_1op
   13728  1.1     is 	cmpi.b		%d1,&QNAN		# weed out QNAN
   13729  1.1     is 	beq.l		res_qnan_1op
   13730  1.1     is 
   13731  1.1     is 	fabs.x		SRC(%a0),%fp0		# force absolute value
   13732  1.1     is 
   13733  1.1     is 	cmpi.b		%d1,&INF		# weed out INF
   13734  1.1     is 	beq.b		fabs_inf
   13735  1.1     is fabs_zero:
   13736  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13737  1.1     is 	rts
   13738  1.1     is fabs_inf:
   13739  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13740  1.1     is 	rts
   13741  1.1     is 
   13742  1.1     is #########################################################################
   13743  1.1     is # XDEF ****************************************************************	#
   13744  1.1     is # 	fcmp(): fp compare op routine					#
   13745  1.1     is #									#
   13746  1.1     is # XREF ****************************************************************	#
   13747  1.1     is # 	res_qnan() - return QNAN result					#
   13748  1.1     is #	res_snan() - return SNAN result					#
   13749  1.1     is #									#
   13750  1.1     is # INPUT ***************************************************************	#
   13751  1.1     is #	a0 = pointer to extended precision source operand		#
   13752  1.1     is #	a1 = pointer to extended precision destination operand		#
   13753  1.1     is #	d0 = round prec/mode						#
   13754  1.1     is #									#
   13755  1.1     is # OUTPUT ************************************************************** #
   13756  1.1     is #	None								#
   13757  1.1     is #									#
   13758  1.1     is # ALGORITHM ***********************************************************	#
   13759  1.1     is # 	Handle NANs and denorms as special cases. For everything else,	#
   13760  1.1     is # just use the actual fcmp instruction to produce the correct condition	#
   13761  1.1     is # codes.								#
   13762  1.1     is #									#
   13763  1.1     is #########################################################################
   13764  1.1     is 
   13765  1.1     is 	global		fcmp
   13766  1.1     is fcmp:
   13767  1.1     is 	clr.w		%d1
   13768  1.1     is 	mov.b		DTAG(%a6),%d1
   13769  1.1     is 	lsl.b		&0x3,%d1
   13770  1.1     is 	or.b		STAG(%a6),%d1
   13771  1.1     is 	bne.b		fcmp_not_norm		# optimize on non-norm input
   13772  1.1     is 
   13773  1.1     is #
   13774  1.1     is # COMPARE FP OPs : NORMs, ZEROs, INFs, and "corrected" DENORMs
   13775  1.1     is #
   13776  1.1     is fcmp_norm:
   13777  1.1     is 	fmovm.x		DST(%a1),&0x80		# load dst op
   13778  1.1     is 
   13779  1.1     is 	fcmp.x 		%fp0,SRC(%a0)		# do compare
   13780  1.1     is 
   13781  1.1     is 	fmov.l		%fpsr,%d0		# save FPSR
   13782  1.1     is 	rol.l		&0x8,%d0		# extract ccode bits
   13783  1.1     is 	mov.b		%d0,FPSR_CC(%a6)	# set ccode bits(no exc bits are set)
   13784  1.1     is 
   13785  1.1     is 	rts
   13786  1.1     is 
   13787  1.1     is #
   13788  1.1     is # fcmp: inputs are not both normalized; what are they?
   13789  1.1     is #
   13790  1.1     is fcmp_not_norm:
   13791  1.1     is 	mov.w		(tbl_fcmp_op.b,%pc,%d1.w*2),%d1
   13792  1.1     is 	jmp		(tbl_fcmp_op.b,%pc,%d1.w*1)
   13793  1.1     is 
   13794  1.1     is 	swbeg		&48
   13795  1.1     is tbl_fcmp_op:
   13796  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # NORM - NORM
   13797  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # NORM - ZERO
   13798  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # NORM - INF
   13799  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # NORM - QNAN
   13800  1.1     is 	short		fcmp_nrm_dnrm 	- tbl_fcmp_op # NORM - DENORM
   13801  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # NORM - SNAN
   13802  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13803  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13804  1.1     is 
   13805  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # ZERO - NORM
   13806  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # ZERO - ZERO
   13807  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # ZERO - INF
   13808  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # ZERO - QNAN
   13809  1.1     is 	short		fcmp_dnrm_s	- tbl_fcmp_op # ZERO - DENORM
   13810  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # ZERO - SNAN
   13811  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13812  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13813  1.1     is 
   13814  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # INF - NORM
   13815  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # INF - ZERO
   13816  1.1     is 	short		fcmp_norm	- tbl_fcmp_op # INF - INF
   13817  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # INF - QNAN
   13818  1.1     is 	short		fcmp_dnrm_s	- tbl_fcmp_op # INF - DENORM
   13819  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # INF - SNAN
   13820  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13821  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13822  1.1     is 
   13823  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - NORM
   13824  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - ZERO
   13825  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - INF
   13826  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - QNAN
   13827  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - DENORM
   13828  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # QNAN - SNAN
   13829  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13830  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13831  1.1     is 
   13832  1.1     is 	short		fcmp_dnrm_nrm	- tbl_fcmp_op # DENORM - NORM
   13833  1.1     is 	short		fcmp_dnrm_d	- tbl_fcmp_op # DENORM - ZERO
   13834  1.1     is 	short		fcmp_dnrm_d	- tbl_fcmp_op # DENORM - INF
   13835  1.1     is 	short		fcmp_res_qnan	- tbl_fcmp_op # DENORM - QNAN
   13836  1.1     is 	short		fcmp_dnrm_sd	- tbl_fcmp_op # DENORM - DENORM
   13837  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # DENORM - SNAN
   13838  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13839  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13840  1.1     is 
   13841  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - NORM
   13842  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - ZERO
   13843  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - INF
   13844  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - QNAN
   13845  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - DENORM
   13846  1.1     is 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - SNAN
   13847  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13848  1.1     is 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13849  1.1     is 
   13850  1.1     is # unlike all other functions for QNAN and SNAN, fcmp does NOT set the
   13851  1.1     is # 'N' bit for a negative QNAN or SNAN input so we must squelch it here.
   13852  1.1     is fcmp_res_qnan:
   13853  1.1     is 	bsr.l		res_qnan
   13854  1.1     is 	andi.b		&0xf7,FPSR_CC(%a6)
   13855  1.1     is 	rts
   13856  1.1     is fcmp_res_snan:
   13857  1.1     is 	bsr.l		res_snan
   13858  1.1     is 	andi.b		&0xf7,FPSR_CC(%a6)
   13859  1.1     is 	rts
   13860  1.1     is 
   13861  1.1     is #
   13862  1.1     is # DENORMs are a little more difficult.
   13863  1.1     is # If you have a 2 DENORMs, then you can just force the j-bit to a one
   13864  1.1     is # and use the fcmp_norm routine.
   13865  1.1     is # If you have a DENORM and an INF or ZERO, just force the DENORM's j-bit to a one
   13866  1.1     is # and use the fcmp_norm routine.
   13867  1.1     is # If you have a DENORM and a NORM with opposite signs, then use fcmp_norm, also.
   13868  1.1     is # But with a DENORM and a NORM of the same sign, the neg bit is set if the
   13869  1.1     is # (1) signs are (+) and the DENORM is the dst or
   13870  1.1     is # (2) signs are (-) and the DENORM is the src
   13871  1.1     is #
   13872  1.1     is 
   13873  1.1     is fcmp_dnrm_s:
   13874  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13875  1.1     is 	mov.l		SRC_HI(%a0),%d0
   13876  1.1     is 	bset		&31,%d0			# DENORM src; make into small norm
   13877  1.1     is 	mov.l		%d0,FP_SCR0_HI(%a6)
   13878  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13879  1.1     is 	lea		FP_SCR0(%a6),%a0
   13880  1.1     is 	bra.w		fcmp_norm
   13881  1.1     is 
   13882  1.1     is fcmp_dnrm_d:
   13883  1.1     is 	mov.l		DST_EX(%a1),FP_SCR0_EX(%a6)
   13884  1.1     is 	mov.l		DST_HI(%a1),%d0
   13885  1.1     is 	bset		&31,%d0			# DENORM src; make into small norm
   13886  1.1     is 	mov.l		%d0,FP_SCR0_HI(%a6)
   13887  1.1     is 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
   13888  1.1     is 	lea		FP_SCR0(%a6),%a1
   13889  1.1     is 	bra.w		fcmp_norm
   13890  1.1     is 
   13891  1.1     is fcmp_dnrm_sd:
   13892  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   13893  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13894  1.1     is 	mov.l		DST_HI(%a1),%d0
   13895  1.1     is 	bset		&31,%d0			# DENORM dst; make into small norm
   13896  1.1     is 	mov.l		%d0,FP_SCR1_HI(%a6)
   13897  1.1     is 	mov.l		SRC_HI(%a0),%d0
   13898  1.1     is 	bset		&31,%d0			# DENORM dst; make into small norm
   13899  1.1     is 	mov.l		%d0,FP_SCR0_HI(%a6)
   13900  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   13901  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13902  1.1     is 	lea		FP_SCR1(%a6),%a1
   13903  1.1     is 	lea		FP_SCR0(%a6),%a0
   13904  1.1     is 	bra.w		fcmp_norm
   13905  1.1     is 
   13906  1.1     is fcmp_nrm_dnrm:
   13907  1.1     is 	mov.b		SRC_EX(%a0),%d0		# determine if like signs
   13908  1.1     is 	mov.b		DST_EX(%a1),%d1
   13909  1.1     is 	eor.b		%d0,%d1
   13910  1.1     is 	bmi.w		fcmp_dnrm_s
   13911  1.1     is 
   13912  1.1     is # signs are the same, so must determine the answer ourselves.
   13913  1.1     is 	tst.b		%d0			# is src op negative?
   13914  1.1     is 	bmi.b		fcmp_nrm_dnrm_m		# yes
   13915  1.1     is 	rts
   13916  1.1     is fcmp_nrm_dnrm_m:
   13917  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13918  1.1     is 	rts
   13919  1.1     is 
   13920  1.1     is fcmp_dnrm_nrm:
   13921  1.1     is 	mov.b		SRC_EX(%a0),%d0		# determine if like signs
   13922  1.1     is 	mov.b		DST_EX(%a1),%d1
   13923  1.1     is 	eor.b		%d0,%d1
   13924  1.1     is 	bmi.w		fcmp_dnrm_d
   13925  1.1     is 
   13926  1.1     is # signs are the same, so must determine the answer ourselves.
   13927  1.1     is 	tst.b		%d0			# is src op negative?
   13928  1.1     is 	bpl.b		fcmp_dnrm_nrm_m		# no
   13929  1.1     is 	rts
   13930  1.1     is fcmp_dnrm_nrm_m:
   13931  1.1     is 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13932  1.1     is 	rts
   13933  1.1     is 
   13934  1.1     is #########################################################################
   13935  1.1     is # XDEF ****************************************************************	#
   13936  1.1     is # 	fsglmul(): emulates the fsglmul instruction			#
   13937  1.1     is #									#
   13938  1.1     is # XREF ****************************************************************	#
   13939  1.1     is #	scale_to_zero_src() - scale src exponent to zero		#
   13940  1.1     is #	scale_to_zero_dst() - scale dst exponent to zero		#
   13941  1.1     is #	unf_res4() - return default underflow result for sglop		#
   13942  1.1     is #	ovf_res() - return default overflow result			#
   13943  1.1     is # 	res_qnan() - return QNAN result					#
   13944  1.1     is # 	res_snan() - return SNAN result					#
   13945  1.1     is #									#
   13946  1.1     is # INPUT ***************************************************************	#
   13947  1.1     is #	a0 = pointer to extended precision source operand		#
   13948  1.1     is #	a1 = pointer to extended precision destination operand		#
   13949  1.1     is #	d0  rnd prec,mode						#
   13950  1.1     is #									#
   13951  1.1     is # OUTPUT **************************************************************	#
   13952  1.1     is #	fp0 = result							#
   13953  1.1     is #	fp1 = EXOP (if exception occurred)				#
   13954  1.1     is #									#
   13955  1.1     is # ALGORITHM ***********************************************************	#
   13956  1.1     is #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   13957  1.1     is # norms/denorms into ext/sgl/dbl precision.				#
   13958  1.1     is #	For norms/denorms, scale the exponents such that a multiply	#
   13959  1.1     is # instruction won't cause an exception. Use the regular fsglmul to	#
   13960  1.1     is # compute a result. Check if the regular operands would have taken	#
   13961  1.1     is # an exception. If so, return the default overflow/underflow result	#
   13962  1.1     is # and return the EXOP if exceptions are enabled. Else, scale the 	#
   13963  1.1     is # result operand to the proper exponent.				#
   13964  1.1     is #									#
   13965  1.1     is #########################################################################
   13966  1.1     is 
   13967  1.1     is 	global		fsglmul
   13968  1.1     is fsglmul:
   13969  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   13970  1.1     is 
   13971  1.1     is 	clr.w		%d1
   13972  1.1     is 	mov.b		DTAG(%a6),%d1
   13973  1.1     is 	lsl.b		&0x3,%d1
   13974  1.1     is 	or.b		STAG(%a6),%d1
   13975  1.1     is 
   13976  1.1     is 	bne.w		fsglmul_not_norm	# optimize on non-norm input
   13977  1.1     is 
   13978  1.1     is fsglmul_norm:
   13979  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   13980  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   13981  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   13982  1.1     is 
   13983  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13984  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13985  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13986  1.1     is 
   13987  1.1     is 	bsr.l		scale_to_zero_src	# scale exponent
   13988  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor 1
   13989  1.1     is 
   13990  1.1     is 	bsr.l		scale_to_zero_dst	# scale dst exponent
   13991  1.1     is 
   13992  1.1     is 	add.l		(%sp)+,%d0		# SCALE_FACTOR = scale1 + scale2
   13993  1.1     is 
   13994  1.1     is 	cmpi.l		%d0,&0x3fff-0x7ffe 	# would result ovfl?
   13995  1.1     is 	beq.w		fsglmul_may_ovfl	# result may rnd to overflow
   13996  1.1     is 	blt.w		fsglmul_ovfl		# result will overflow
   13997  1.1     is 
   13998  1.1     is 	cmpi.l		%d0,&0x3fff+0x0001 	# would result unfl?
   13999  1.1     is 	beq.w		fsglmul_may_unfl	# result may rnd to no unfl
   14000  1.1     is 	bgt.w		fsglmul_unfl		# result will underflow
   14001  1.1     is 
   14002  1.1     is fsglmul_normal:
   14003  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14004  1.1     is 
   14005  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14006  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14007  1.1     is 
   14008  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14009  1.1     is 
   14010  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14011  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14012  1.1     is 
   14013  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14014  1.1     is 
   14015  1.1     is fsglmul_normal_exit:
   14016  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14017  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14018  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   14019  1.1     is 	mov.l		%d1,%d2			# make a copy
   14020  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14021  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14022  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14023  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   14024  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14025  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14026  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   14027  1.1     is 	rts
   14028  1.1     is 
   14029  1.1     is fsglmul_ovfl:
   14030  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14031  1.1     is 
   14032  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14033  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14034  1.1     is 
   14035  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14036  1.1     is 
   14037  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14038  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14039  1.1     is 
   14040  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14041  1.1     is 
   14042  1.1     is fsglmul_ovfl_tst:
   14043  1.1     is 
   14044  1.1     is # save setting this until now because this is where fsglmul_may_ovfl may jump in
   14045  1.1     is 	or.l		&ovfl_inx_mask, USER_FPSR(%a6) # set ovfl/aovfl/ainex
   14046  1.1     is 
   14047  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   14048  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   14049  1.1     is 	bne.b		fsglmul_ovfl_ena	# yes
   14050  1.1     is 
   14051  1.1     is fsglmul_ovfl_dis:
   14052  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   14053  1.1     is 	sne		%d1			# set sign param accordingly
   14054  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   14055  1.1     is 	andi.b		&0x30,%d0		# force prec = ext
   14056  1.1     is 	bsr.l		ovf_res			# calculate default result
   14057  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   14058  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   14059  1.1     is 	rts
   14060  1.1     is 
   14061  1.1     is fsglmul_ovfl_ena:
   14062  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   14063  1.1     is 
   14064  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14065  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14066  1.1     is 	mov.l		%d1,%d2			# make a copy
   14067  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14068  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14069  1.1     is 	subi.l		&0x6000,%d1		# subtract bias
   14070  1.1     is 	andi.w		&0x7fff,%d1
   14071  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14072  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   14073  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14074  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14075  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14076  1.1     is 	bra.b		fsglmul_ovfl_dis
   14077  1.1     is 
   14078  1.1     is fsglmul_may_ovfl:
   14079  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14080  1.1     is 
   14081  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14082  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14083  1.1     is 
   14084  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14085  1.1     is 
   14086  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14087  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14088  1.1     is 
   14089  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14090  1.1     is 
   14091  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   14092  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   14093  1.1     is 	fbge.w		fsglmul_ovfl_tst	# yes; overflow has occurred
   14094  1.1     is 
   14095  1.1     is # no, it didn't overflow; we have correct result
   14096  1.1     is 	bra.w		fsglmul_normal_exit
   14097  1.1     is 
   14098  1.1     is fsglmul_unfl:
   14099  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   14100  1.1     is 
   14101  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14102  1.1     is 
   14103  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   14104  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14105  1.1     is 
   14106  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14107  1.1     is 
   14108  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14109  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14110  1.1     is 
   14111  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14112  1.1     is 
   14113  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   14114  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   14115  1.1     is 	bne.b		fsglmul_unfl_ena	# yes
   14116  1.1     is 
   14117  1.1     is fsglmul_unfl_dis:
   14118  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14119  1.1     is 
   14120  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   14121  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   14122  1.1     is 	bsr.l		unf_res4		# calculate default result
   14123  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
   14124  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   14125  1.1     is 	rts
   14126  1.1     is 
   14127  1.1     is #
   14128  1.1     is # UNFL is enabled.
   14129  1.1     is #
   14130  1.1     is fsglmul_unfl_ena:
   14131  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   14132  1.1     is 
   14133  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14134  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14135  1.1     is 
   14136  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp1	# execute sgl multiply
   14137  1.1     is 
   14138  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14139  1.1     is 
   14140  1.1     is 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   14141  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14142  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14143  1.1     is 	mov.l		%d1,%d2			# make a copy
   14144  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14145  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14146  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14147  1.1     is 	addi.l		&0x6000,%d1		# add bias
   14148  1.1     is 	andi.w		&0x7fff,%d1
   14149  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   14150  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14151  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14152  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14153  1.1     is 	bra.w		fsglmul_unfl_dis
   14154  1.1     is 
   14155  1.1     is fsglmul_may_unfl:
   14156  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14157  1.1     is 
   14158  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14159  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14160  1.1     is 
   14161  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14162  1.1     is 
   14163  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14164  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14165  1.1     is 
   14166  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14167  1.1     is 
   14168  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   14169  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| > 2.b?
   14170  1.1     is 	fbgt.w		fsglmul_normal_exit	# no; no underflow occurred
   14171  1.1     is 	fblt.w		fsglmul_unfl		# yes; underflow occurred
   14172  1.1     is 
   14173  1.1     is #
   14174  1.1     is # we still don't know if underflow occurred. result is ~ equal to 2. but,
   14175  1.1     is # we don't know if the result was an underflow that rounded up to a 2 or
   14176  1.1     is # a normalized number that rounded down to a 2. so, redo the entire operation
   14177  1.1     is # using RZ as the rounding mode to see what the pre-rounded result is.
   14178  1.1     is # this case should be relatively rare.
   14179  1.1     is #
   14180  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   14181  1.1     is 
   14182  1.1     is 	mov.l		L_SCR3(%a6),%d1
   14183  1.1     is 	andi.b		&0xc0,%d1		# keep rnd prec
   14184  1.1     is 	ori.b		&rz_mode*0x10,%d1	# insert RZ
   14185  1.1     is 
   14186  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   14187  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14188  1.1     is 
   14189  1.1     is 	fsglmul.x	FP_SCR0(%a6),%fp1	# execute sgl multiply
   14190  1.1     is 
   14191  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14192  1.1     is 	fabs.x		%fp1			# make absolute value
   14193  1.1     is 	fcmp.b		%fp1,&0x2		# is |result| < 2.b?
   14194  1.1     is 	fbge.w		fsglmul_normal_exit	# no; no underflow occurred
   14195  1.1     is 	bra.w		fsglmul_unfl		# yes, underflow occurred
   14196  1.1     is 
   14197  1.1     is ##############################################################################
   14198  1.1     is 
   14199  1.1     is #
   14200  1.1     is # Single Precision Multiply: inputs are not both normalized; what are they?
   14201  1.1     is #
   14202  1.1     is fsglmul_not_norm:
   14203  1.1     is 	mov.w		(tbl_fsglmul_op.b,%pc,%d1.w*2),%d1
   14204  1.1     is 	jmp		(tbl_fsglmul_op.b,%pc,%d1.w*1)
   14205  1.1     is 
   14206  1.1     is 	swbeg		&48
   14207  1.1     is tbl_fsglmul_op:
   14208  1.1     is 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x NORM
   14209  1.1     is 	short		fsglmul_zero		- tbl_fsglmul_op # NORM x ZERO
   14210  1.1     is 	short		fsglmul_inf_src		- tbl_fsglmul_op # NORM x INF
   14211  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # NORM x QNAN
   14212  1.1     is 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x DENORM
   14213  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # NORM x SNAN
   14214  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14215  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14216  1.1     is 
   14217  1.1     is 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x NORM
   14218  1.1     is 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x ZERO
   14219  1.1     is 	short		fsglmul_res_operr	- tbl_fsglmul_op # ZERO x INF
   14220  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # ZERO x QNAN
   14221  1.1     is 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x DENORM
   14222  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # ZERO x SNAN
   14223  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14224  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14225  1.1     is 
   14226  1.1     is 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x NORM
   14227  1.1     is 	short		fsglmul_res_operr	- tbl_fsglmul_op # INF x ZERO
   14228  1.1     is 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x INF
   14229  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # INF x QNAN
   14230  1.1     is 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x DENORM
   14231  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # INF x SNAN
   14232  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14233  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14234  1.1     is 
   14235  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x NORM
   14236  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x ZERO
   14237  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x INF
   14238  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x QNAN
   14239  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x DENORM
   14240  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # QNAN x SNAN
   14241  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14242  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14243  1.1     is 
   14244  1.1     is 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x NORM
   14245  1.1     is 	short		fsglmul_zero		- tbl_fsglmul_op # NORM x ZERO
   14246  1.1     is 	short		fsglmul_inf_src		- tbl_fsglmul_op # NORM x INF
   14247  1.1     is 	short		fsglmul_res_qnan	- tbl_fsglmul_op # NORM x QNAN
   14248  1.1     is 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x DENORM
   14249  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # NORM x SNAN
   14250  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14251  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14252  1.1     is 
   14253  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x NORM
   14254  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x ZERO
   14255  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x INF
   14256  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x QNAN
   14257  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x DENORM
   14258  1.1     is 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x SNAN
   14259  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14260  1.1     is 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14261  1.1     is 
   14262  1.1     is fsglmul_res_operr:
   14263  1.1     is 	bra.l		res_operr
   14264  1.1     is fsglmul_res_snan:
   14265  1.1     is 	bra.l		res_snan
   14266  1.1     is fsglmul_res_qnan:
   14267  1.1     is 	bra.l		res_qnan
   14268  1.1     is fsglmul_zero:
   14269  1.1     is 	bra.l		fmul_zero
   14270  1.1     is fsglmul_inf_src:
   14271  1.1     is 	bra.l		fmul_inf_src
   14272  1.1     is fsglmul_inf_dst:
   14273  1.1     is 	bra.l		fmul_inf_dst
   14274  1.1     is 
   14275  1.1     is #########################################################################
   14276  1.1     is # XDEF ****************************************************************	#
   14277  1.1     is # 	fsgldiv(): emulates the fsgldiv instruction			#
   14278  1.1     is #									#
   14279  1.1     is # XREF ****************************************************************	#
   14280  1.1     is #	scale_to_zero_src() - scale src exponent to zero		#
   14281  1.1     is #	scale_to_zero_dst() - scale dst exponent to zero		#
   14282  1.1     is #	unf_res4() - return default underflow result for sglop		#
   14283  1.1     is #	ovf_res() - return default overflow result			#
   14284  1.1     is # 	res_qnan() - return QNAN result					#
   14285  1.1     is # 	res_snan() - return SNAN result					#
   14286  1.1     is #									#
   14287  1.1     is # INPUT ***************************************************************	#
   14288  1.1     is #	a0 = pointer to extended precision source operand		#
   14289  1.1     is #	a1 = pointer to extended precision destination operand		#
   14290  1.1     is #	d0  rnd prec,mode						#
   14291  1.1     is #									#
   14292  1.1     is # OUTPUT **************************************************************	#
   14293  1.1     is #	fp0 = result							#
   14294  1.1     is #	fp1 = EXOP (if exception occurred)				#
   14295  1.1     is #									#
   14296  1.1     is # ALGORITHM ***********************************************************	#
   14297  1.1     is #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   14298  1.1     is # norms/denorms into ext/sgl/dbl precision.				#
   14299  1.1     is #	For norms/denorms, scale the exponents such that a divide	#
   14300  1.1     is # instruction won't cause an exception. Use the regular fsgldiv to	#
   14301  1.1     is # compute a result. Check if the regular operands would have taken	#
   14302  1.1     is # an exception. If so, return the default overflow/underflow result	#
   14303  1.1     is # and return the EXOP if exceptions are enabled. Else, scale the 	#
   14304  1.1     is # result operand to the proper exponent.				#
   14305  1.1     is #									#
   14306  1.1     is #########################################################################
   14307  1.1     is 
   14308  1.1     is 	global		fsgldiv
   14309  1.1     is fsgldiv:
   14310  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   14311  1.1     is 
   14312  1.1     is 	clr.w		%d1
   14313  1.1     is 	mov.b		DTAG(%a6),%d1
   14314  1.1     is 	lsl.b		&0x3,%d1
   14315  1.1     is 	or.b		STAG(%a6),%d1		# combine src tags
   14316  1.1     is 
   14317  1.1     is 	bne.w		fsgldiv_not_norm	# optimize on non-norm input
   14318  1.1     is 
   14319  1.1     is #
   14320  1.1     is # DIVIDE: NORMs and DENORMs ONLY!
   14321  1.1     is #
   14322  1.1     is fsgldiv_norm:
   14323  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   14324  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   14325  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   14326  1.1     is 
   14327  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   14328  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   14329  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   14330  1.1     is 
   14331  1.1     is 	bsr.l		scale_to_zero_src	# calculate scale factor 1
   14332  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor 1
   14333  1.1     is 
   14334  1.1     is 	bsr.l		scale_to_zero_dst	# calculate scale factor 2
   14335  1.1     is 
   14336  1.1     is 	neg.l		(%sp)			# S.F. = scale1 - scale2
   14337  1.1     is 	add.l		%d0,(%sp)
   14338  1.1     is 
   14339  1.1     is 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision,mode
   14340  1.1     is 	lsr.b		&0x6,%d1
   14341  1.1     is 	mov.l		(%sp)+,%d0
   14342  1.1     is 	cmpi.l		%d0,&0x3fff-0x7ffe
   14343  1.1     is 	ble.w		fsgldiv_may_ovfl
   14344  1.1     is 
   14345  1.1     is 	cmpi.l		%d0,&0x3fff-0x0000 	# will result underflow?
   14346  1.1     is 	beq.w		fsgldiv_may_unfl	# maybe
   14347  1.1     is 	bgt.w		fsgldiv_unfl		# yes; go handle underflow
   14348  1.1     is 
   14349  1.1     is fsgldiv_normal:
   14350  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14351  1.1     is 
   14352  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# save FPCR
   14353  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14354  1.1     is 
   14355  1.1     is 	fsgldiv.x	FP_SCR0(%a6),%fp0	# perform sgl divide
   14356  1.1     is 
   14357  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   14358  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14359  1.1     is 
   14360  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14361  1.1     is 
   14362  1.1     is fsgldiv_normal_exit:
   14363  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store result on stack
   14364  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14365  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   14366  1.1     is 	mov.l		%d1,%d2			# make a copy
   14367  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14368  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14369  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14370  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   14371  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14372  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14373  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   14374  1.1     is 	rts
   14375  1.1     is 
   14376  1.1     is fsgldiv_may_ovfl:
   14377  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14378  1.1     is 
   14379  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14380  1.1     is 	fmov.l		&0x0,%fpsr		# set FPSR
   14381  1.1     is 
   14382  1.1     is 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute divide
   14383  1.1     is 
   14384  1.1     is 	fmov.l		%fpsr,%d1
   14385  1.1     is 	fmov.l		&0x0,%fpcr
   14386  1.1     is 
   14387  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX,N
   14388  1.1     is 
   14389  1.1     is 	fmovm.x		&0x01,-(%sp)		# save result to stack
   14390  1.1     is 	mov.w		(%sp),%d1		# fetch new exponent
   14391  1.1     is 	add.l		&0xc,%sp		# clear result
   14392  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14393  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14394  1.1     is 	cmp.l		%d1,&0x7fff		# did divide overflow?
   14395  1.1     is 	blt.b		fsgldiv_normal_exit
   14396  1.1     is 
   14397  1.1     is fsgldiv_ovfl_tst:
   14398  1.1     is 	or.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
   14399  1.1     is 
   14400  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   14401  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   14402  1.1     is 	bne.b		fsgldiv_ovfl_ena	# yes
   14403  1.1     is 
   14404  1.1     is fsgldiv_ovfl_dis:
   14405  1.1     is 	btst		&neg_bit,FPSR_CC(%a6) 	# is result negative
   14406  1.1     is 	sne		%d1			# set sign param accordingly
   14407  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   14408  1.1     is 	andi.b		&0x30,%d0		# kill precision
   14409  1.1     is 	bsr.l		ovf_res			# calculate default result
   14410  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF if applicable
   14411  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   14412  1.1     is 	rts
   14413  1.1     is 
   14414  1.1     is fsgldiv_ovfl_ena:
   14415  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   14416  1.1     is 
   14417  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14418  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14419  1.1     is 	mov.l		%d1,%d2			# make a copy
   14420  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14421  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14422  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14423  1.1     is 	subi.l		&0x6000,%d1		# subtract new bias
   14424  1.1     is 	andi.w		&0x7fff,%d1		# clear ms bit
   14425  1.1     is 	or.w		%d2,%d1			# concat old sign,new exp
   14426  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14427  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14428  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14429  1.1     is 	bra.b		fsgldiv_ovfl_dis
   14430  1.1     is 
   14431  1.1     is fsgldiv_unfl:
   14432  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   14433  1.1     is 
   14434  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14435  1.1     is 
   14436  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   14437  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14438  1.1     is 
   14439  1.1     is 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute sgl divide
   14440  1.1     is 
   14441  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14442  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14443  1.1     is 
   14444  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14445  1.1     is 
   14446  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   14447  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   14448  1.1     is 	bne.b		fsgldiv_unfl_ena	# yes
   14449  1.1     is 
   14450  1.1     is fsgldiv_unfl_dis:
   14451  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14452  1.1     is 
   14453  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   14454  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   14455  1.1     is 	bsr.l		unf_res4		# calculate default result
   14456  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
   14457  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   14458  1.1     is 	rts
   14459  1.1     is 
   14460  1.1     is #
   14461  1.1     is # UNFL is enabled.
   14462  1.1     is #
   14463  1.1     is fsgldiv_unfl_ena:
   14464  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   14465  1.1     is 
   14466  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14467  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14468  1.1     is 
   14469  1.1     is 	fsgldiv.x	FP_SCR0(%a6),%fp1	# execute sgl divide
   14470  1.1     is 
   14471  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14472  1.1     is 
   14473  1.1     is 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   14474  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14475  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14476  1.1     is 	mov.l		%d1,%d2			# make a copy
   14477  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14478  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14479  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14480  1.1     is 	addi.l		&0x6000,%d1		# add bias
   14481  1.1     is 	andi.w		&0x7fff,%d1		# clear top bit
   14482  1.1     is 	or.w		%d2,%d1			# concat old sign, new exp
   14483  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14484  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14485  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14486  1.1     is 	bra.b		fsgldiv_unfl_dis
   14487  1.1     is 
   14488  1.1     is #
   14489  1.1     is # the divide operation MAY underflow:
   14490  1.1     is #
   14491  1.1     is fsgldiv_may_unfl:
   14492  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14493  1.1     is 
   14494  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14495  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14496  1.1     is 
   14497  1.1     is 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute sgl divide
   14498  1.1     is 
   14499  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14500  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14501  1.1     is 
   14502  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14503  1.1     is 
   14504  1.1     is 	fabs.x		%fp0,%fp1		# make a copy of result
   14505  1.1     is 	fcmp.b		%fp1,&0x1		# is |result| > 1.b?
   14506  1.1     is 	fbgt.w		fsgldiv_normal_exit	# no; no underflow occurred
   14507  1.1     is 	fblt.w		fsgldiv_unfl		# yes; underflow occurred
   14508  1.1     is 
   14509  1.1     is #
   14510  1.1     is # we still don't know if underflow occurred. result is ~ equal to 1. but,
   14511  1.1     is # we don't know if the result was an underflow that rounded up to a 1
   14512  1.1     is # or a normalized number that rounded down to a 1. so, redo the entire
   14513  1.1     is # operation using RZ as the rounding mode to see what the pre-rounded
   14514  1.1     is # result is. this case should be relatively rare.
   14515  1.1     is #
   14516  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into %fp1
   14517  1.1     is 
   14518  1.1     is 	clr.l		%d1			# clear scratch register
   14519  1.1     is 	ori.b		&rz_mode*0x10,%d1	# force RZ rnd mode
   14520  1.1     is 
   14521  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   14522  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14523  1.1     is 
   14524  1.1     is 	fsgldiv.x	FP_SCR0(%a6),%fp1	# execute sgl divide
   14525  1.1     is 
   14526  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14527  1.1     is 	fabs.x		%fp1			# make absolute value
   14528  1.1     is 	fcmp.b		%fp1,&0x1		# is |result| < 1.b?
   14529  1.1     is 	fbge.w		fsgldiv_normal_exit	# no; no underflow occurred
   14530  1.1     is 	bra.w		fsgldiv_unfl		# yes; underflow occurred
   14531  1.1     is 
   14532  1.1     is ############################################################################
   14533  1.1     is 
   14534  1.1     is #
   14535  1.1     is # Divide: inputs are not both normalized; what are they?
   14536  1.1     is #
   14537  1.1     is fsgldiv_not_norm:
   14538  1.1     is 	mov.w		(tbl_fsgldiv_op.b,%pc,%d1.w*2),%d1
   14539  1.1     is 	jmp		(tbl_fsgldiv_op.b,%pc,%d1.w*1)
   14540  1.1     is 
   14541  1.1     is 	swbeg		&48
   14542  1.1     is tbl_fsgldiv_op:
   14543  1.1     is 	short		fsgldiv_norm		- tbl_fsgldiv_op # NORM / NORM
   14544  1.1     is 	short		fsgldiv_inf_load	- tbl_fsgldiv_op # NORM / ZERO
   14545  1.1     is 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # NORM / INF
   14546  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # NORM / QNAN
   14547  1.1     is 	short		fsgldiv_norm		- tbl_fsgldiv_op # NORM / DENORM
   14548  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # NORM / SNAN
   14549  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14550  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14551  1.1     is 
   14552  1.1     is 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / NORM
   14553  1.1     is 	short		fsgldiv_res_operr	- tbl_fsgldiv_op # ZERO / ZERO
   14554  1.1     is 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / INF
   14555  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # ZERO / QNAN
   14556  1.1     is 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / DENORM
   14557  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # ZERO / SNAN
   14558  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14559  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14560  1.1     is 
   14561  1.1     is 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / NORM
   14562  1.1     is 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / ZERO
   14563  1.1     is 	short		fsgldiv_res_operr	- tbl_fsgldiv_op # INF / INF
   14564  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # INF / QNAN
   14565  1.1     is 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / DENORM
   14566  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # INF / SNAN
   14567  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14568  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14569  1.1     is 
   14570  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / NORM
   14571  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / ZERO
   14572  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / INF
   14573  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / QNAN
   14574  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / DENORM
   14575  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # QNAN / SNAN
   14576  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14577  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14578  1.1     is 
   14579  1.1     is 	short		fsgldiv_norm		- tbl_fsgldiv_op # DENORM / NORM
   14580  1.1     is 	short		fsgldiv_inf_load	- tbl_fsgldiv_op # DENORM / ZERO
   14581  1.1     is 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # DENORM / INF
   14582  1.1     is 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # DENORM / QNAN
   14583  1.1     is 	short		fsgldiv_norm		- tbl_fsgldiv_op # DENORM / DENORM
   14584  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # DENORM / SNAN
   14585  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14586  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14587  1.1     is 
   14588  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / NORM
   14589  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / ZERO
   14590  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / INF
   14591  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / QNAN
   14592  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / DENORM
   14593  1.1     is 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / SNAN
   14594  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14595  1.1     is 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14596  1.1     is 
   14597  1.1     is fsgldiv_res_qnan:
   14598  1.1     is 	bra.l		res_qnan
   14599  1.1     is fsgldiv_res_snan:
   14600  1.1     is 	bra.l		res_snan
   14601  1.1     is fsgldiv_res_operr:
   14602  1.1     is 	bra.l		res_operr
   14603  1.1     is fsgldiv_inf_load:
   14604  1.1     is 	bra.l		fdiv_inf_load
   14605  1.1     is fsgldiv_zero_load:
   14606  1.1     is 	bra.l		fdiv_zero_load
   14607  1.1     is fsgldiv_inf_dst:
   14608  1.1     is 	bra.l		fdiv_inf_dst
   14609  1.1     is 
   14610  1.1     is #########################################################################
   14611  1.1     is # XDEF ****************************************************************	#
   14612  1.1     is #	fadd(): emulates the fadd instruction				#
   14613  1.1     is #	fsadd(): emulates the fadd instruction				#
   14614  1.1     is #	fdadd(): emulates the fdadd instruction				#
   14615  1.1     is #									#
   14616  1.1     is # XREF ****************************************************************	#
   14617  1.1     is # 	addsub_scaler2() - scale the operands so they won't take exc	#
   14618  1.1     is #	ovf_res() - return default overflow result			#
   14619  1.1     is #	unf_res() - return default underflow result			#
   14620  1.1     is #	res_qnan() - set QNAN result					#
   14621  1.1     is # 	res_snan() - set SNAN result					#
   14622  1.1     is #	res_operr() - set OPERR result					#
   14623  1.1     is #	scale_to_zero_src() - set src operand exponent equal to zero	#
   14624  1.1     is #	scale_to_zero_dst() - set dst operand exponent equal to zero	#
   14625  1.1     is #									#
   14626  1.1     is # INPUT ***************************************************************	#
   14627  1.1     is #	a0 = pointer to extended precision source operand		#
   14628  1.1     is # 	a1 = pointer to extended precision destination operand		#
   14629  1.1     is #									#
   14630  1.1     is # OUTPUT **************************************************************	#
   14631  1.1     is #	fp0 = result							#
   14632  1.1     is #	fp1 = EXOP (if exception occurred)				#
   14633  1.1     is #									#
   14634  1.1     is # ALGORITHM ***********************************************************	#
   14635  1.1     is # 	Handle NANs, infinities, and zeroes as special cases. Divide	#
   14636  1.1     is # norms into extended, single, and double precision.			#
   14637  1.1     is #	Do addition after scaling exponents such that exception won't	#
   14638  1.1     is # occur. Then, check result exponent to see if exception would have	#
   14639  1.1     is # occurred. If so, return default result and maybe EXOP. Else, insert	#
   14640  1.1     is # the correct result exponent and return. Set FPSR bits as appropriate.	#
   14641  1.1     is #									#
   14642  1.1     is #########################################################################
   14643  1.1     is 
   14644  1.1     is 	global		fsadd
   14645  1.1     is fsadd:
   14646  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   14647  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   14648  1.1     is 	bra.b		fadd
   14649  1.1     is 
   14650  1.1     is 	global		fdadd
   14651  1.1     is fdadd:
   14652  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   14653  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   14654  1.1     is 
   14655  1.1     is 	global		fadd
   14656  1.1     is fadd:
   14657  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   14658  1.1     is 
   14659  1.1     is 	clr.w		%d1
   14660  1.1     is 	mov.b		DTAG(%a6),%d1
   14661  1.1     is 	lsl.b		&0x3,%d1
   14662  1.1     is 	or.b		STAG(%a6),%d1		# combine src tags
   14663  1.1     is 
   14664  1.1     is 	bne.w		fadd_not_norm		# optimize on non-norm input
   14665  1.1     is 
   14666  1.1     is #
   14667  1.1     is # ADD: norms and denorms
   14668  1.1     is #
   14669  1.1     is fadd_norm:
   14670  1.1     is 	bsr.l		addsub_scaler2		# scale exponents
   14671  1.1     is 
   14672  1.1     is fadd_zero_entry:
   14673  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14674  1.1     is 
   14675  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14676  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14677  1.1     is 
   14678  1.1     is 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
   14679  1.1     is 
   14680  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14681  1.1     is 	fmov.l		%fpsr,%d1		# fetch INEX2,N,Z
   14682  1.1     is 
   14683  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save exc and ccode bits
   14684  1.1     is 
   14685  1.1     is 	fbeq.w		fadd_zero_exit		# if result is zero, end now
   14686  1.1     is 
   14687  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   14688  1.1     is 
   14689  1.1     is 	fmovm.x		&0x01,-(%sp)		# save result to stack
   14690  1.1     is 
   14691  1.1     is 	mov.w		2+L_SCR3(%a6),%d1
   14692  1.1     is 	lsr.b		&0x6,%d1
   14693  1.1     is 
   14694  1.1     is 	mov.w		(%sp),%d2		# fetch new sign, exp
   14695  1.1     is 	andi.l		&0x7fff,%d2		# strip sign
   14696  1.1     is 	sub.l		%d0,%d2			# add scale factor
   14697  1.1     is 
   14698  1.1     is 	cmp.l		%d2,(tbl_fadd_ovfl.b,%pc,%d1.w*4) # is it an overflow?
   14699  1.1     is 	bge.b		fadd_ovfl		# yes
   14700  1.1     is 
   14701  1.1     is 	cmp.l		%d2,(tbl_fadd_unfl.b,%pc,%d1.w*4) # is it an underflow?
   14702  1.1     is 	blt.w		fadd_unfl		# yes
   14703  1.1     is 	beq.w		fadd_may_unfl		# maybe; go find out
   14704  1.1     is 
   14705  1.1     is fadd_normal:
   14706  1.1     is 	mov.w		(%sp),%d1
   14707  1.1     is 	andi.w		&0x8000,%d1		# keep sign
   14708  1.1     is 	or.w		%d2,%d1			# concat sign,new exp
   14709  1.1     is 	mov.w		%d1,(%sp)		# insert new exponent
   14710  1.1     is 
   14711  1.1     is 	fmovm.x		(%sp)+,&0x80		# return result in fp0
   14712  1.1     is 
   14713  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14714  1.1     is 	rts
   14715  1.1     is 
   14716  1.1     is fadd_zero_exit:
   14717  1.1     is #	fmov.s		&0x00000000,%fp0	# return zero in fp0
   14718  1.1     is 	rts
   14719  1.1     is 
   14720  1.1     is tbl_fadd_ovfl:
   14721  1.1     is 	long		0x7fff			# ext ovfl
   14722  1.1     is 	long		0x407f			# sgl ovfl
   14723  1.1     is 	long		0x43ff			# dbl ovfl
   14724  1.1     is 
   14725  1.1     is tbl_fadd_unfl:
   14726  1.1     is 	long	        0x0000			# ext unfl
   14727  1.1     is 	long		0x3f81			# sgl unfl
   14728  1.1     is 	long		0x3c01			# dbl unfl
   14729  1.1     is 
   14730  1.1     is fadd_ovfl:
   14731  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   14732  1.1     is 
   14733  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   14734  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   14735  1.1     is 	bne.b		fadd_ovfl_ena		# yes
   14736  1.1     is 
   14737  1.1     is 	add.l		&0xc,%sp
   14738  1.1     is fadd_ovfl_dis:
   14739  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   14740  1.1     is 	sne		%d1			# set sign param accordingly
   14741  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   14742  1.1     is 	bsr.l		ovf_res			# calculate default result
   14743  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   14744  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   14745  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14746  1.1     is 	rts
   14747  1.1     is 
   14748  1.1     is fadd_ovfl_ena:
   14749  1.1     is 	mov.b		L_SCR3(%a6),%d1
   14750  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   14751  1.1     is 	bne.b		fadd_ovfl_ena_sd	# no; prec = sgl or dbl
   14752  1.1     is 
   14753  1.1     is fadd_ovfl_ena_cont:
   14754  1.1     is 	mov.w		(%sp),%d1
   14755  1.1     is 	andi.w		&0x8000,%d1		# keep sign
   14756  1.1     is 	subi.l		&0x6000,%d2		# add extra bias
   14757  1.1     is 	andi.w		&0x7fff,%d2
   14758  1.1     is 	or.w		%d2,%d1			# concat sign,new exp
   14759  1.1     is 	mov.w		%d1,(%sp)		# insert new exponent
   14760  1.1     is 
   14761  1.1     is 	fmovm.x		(%sp)+,&0x40		# return EXOP in fp1
   14762  1.1     is 	bra.b		fadd_ovfl_dis
   14763  1.1     is 
   14764  1.1     is fadd_ovfl_ena_sd:
   14765  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14766  1.1     is 
   14767  1.1     is 	mov.l		L_SCR3(%a6),%d1
   14768  1.1     is 	andi.b		&0x30,%d1		# keep rnd mode
   14769  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   14770  1.1     is 
   14771  1.1     is 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
   14772  1.1     is 
   14773  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14774  1.1     is 
   14775  1.1     is 	add.l		&0xc,%sp
   14776  1.1     is 	fmovm.x		&0x01,-(%sp)
   14777  1.1     is 	bra.b		fadd_ovfl_ena_cont
   14778  1.1     is 
   14779  1.1     is fadd_unfl:
   14780  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   14781  1.1     is 
   14782  1.1     is 	add.l		&0xc,%sp
   14783  1.1     is 
   14784  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14785  1.1     is 
   14786  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   14787  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14788  1.1     is 
   14789  1.1     is 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
   14790  1.1     is 
   14791  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14792  1.1     is 	fmov.l		%fpsr,%d1		# save status
   14793  1.1     is 
   14794  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX,N
   14795  1.1     is 
   14796  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   14797  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   14798  1.1     is 	bne.b		fadd_unfl_ena		# yes
   14799  1.1     is 
   14800  1.1     is fadd_unfl_dis:
   14801  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14802  1.1     is 
   14803  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   14804  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   14805  1.1     is 	bsr.l		unf_res			# calculate default result
   14806  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
   14807  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   14808  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   14809  1.1     is 	rts
   14810  1.1     is 
   14811  1.1     is fadd_unfl_ena:
   14812  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   14813  1.1     is 
   14814  1.1     is 	mov.l		L_SCR3(%a6),%d1
   14815  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   14816  1.1     is 	bne.b		fadd_unfl_ena_sd	# no; sgl or dbl
   14817  1.1     is 
   14818  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14819  1.1     is 
   14820  1.1     is fadd_unfl_ena_cont:
   14821  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14822  1.1     is 
   14823  1.1     is 	fadd.x		FP_SCR0(%a6),%fp1	# execute multiply
   14824  1.1     is 
   14825  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14826  1.1     is 
   14827  1.1     is 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   14828  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14829  1.1     is 	mov.l		%d1,%d2			# make a copy
   14830  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   14831  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   14832  1.1     is 	sub.l		%d0,%d1			# add scale factor
   14833  1.1     is 	addi.l		&0x6000,%d1		# add new bias
   14834  1.1     is 	andi.w		&0x7fff,%d1		# clear top bit
   14835  1.1     is 	or.w		%d2,%d1			# concat sign,new exp
   14836  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14837  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14838  1.1     is 	bra.w		fadd_unfl_dis
   14839  1.1     is 
   14840  1.1     is fadd_unfl_ena_sd:
   14841  1.1     is 	mov.l		L_SCR3(%a6),%d1
   14842  1.1     is 	andi.b		&0x30,%d1		# use only rnd mode
   14843  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   14844  1.1     is 
   14845  1.1     is 	bra.b		fadd_unfl_ena_cont
   14846  1.1     is 
   14847  1.1     is #
   14848  1.1     is # result is equal to the smallest normalized number in the selected precision
   14849  1.1     is # if the precision is extended, this result could not have come from an
   14850  1.1     is # underflow that rounded up.
   14851  1.1     is #
   14852  1.1     is fadd_may_unfl:
   14853  1.1     is 	mov.l		L_SCR3(%a6),%d1
   14854  1.1     is 	andi.b		&0xc0,%d1
   14855  1.1     is 	beq.w		fadd_normal		# yes; no underflow occurred
   14856  1.1     is 
   14857  1.1     is 	mov.l		0x4(%sp),%d1		# extract hi(man)
   14858  1.1     is 	cmpi.l		%d1,&0x80000000		# is hi(man) = 0x80000000?
   14859  1.1     is 	bne.w		fadd_normal		# no; no underflow occurred
   14860  1.1     is 
   14861  1.1     is 	tst.l		0x8(%sp)		# is lo(man) = 0x0?
   14862  1.1     is 	bne.w		fadd_normal		# no; no underflow occurred
   14863  1.1     is 
   14864  1.1     is 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
   14865  1.1     is 	beq.w		fadd_normal		# no; no underflow occurred
   14866  1.1     is 
   14867  1.1     is #
   14868  1.1     is # ok, so now the result has a exponent equal to the smallest normalized
   14869  1.1     is # exponent for the selected precision. also, the mantissa is equal to
   14870  1.1     is # 0x8000000000000000 and this mantissa is the result of rounding non-zero
   14871  1.1     is # g,r,s.
   14872  1.1     is # now, we must determine whether the pre-rounded result was an underflow
   14873  1.1     is # rounded "up" or a normalized number rounded "down".
   14874  1.1     is # so, we do this be re-executing the add using RZ as the rounding mode and
   14875  1.1     is # seeing if the new result is smaller or equal to the current result.
   14876  1.1     is #
   14877  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   14878  1.1     is 
   14879  1.1     is 	mov.l		L_SCR3(%a6),%d1
   14880  1.1     is 	andi.b		&0xc0,%d1		# keep rnd prec
   14881  1.1     is 	ori.b		&rz_mode*0x10,%d1	# insert rnd mode
   14882  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   14883  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   14884  1.1     is 
   14885  1.1     is 	fadd.x		FP_SCR0(%a6),%fp1	# execute add
   14886  1.1     is 
   14887  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   14888  1.1     is 
   14889  1.1     is 	fabs.x		%fp0			# compare absolute values
   14890  1.1     is 	fabs.x		%fp1
   14891  1.1     is 	fcmp.x		%fp0,%fp1		# is first result > second?
   14892  1.1     is 
   14893  1.1     is 	fbgt.w		fadd_unfl		# yes; it's an underflow
   14894  1.1     is 	bra.w		fadd_normal		# no; it's not an underflow
   14895  1.1     is 
   14896  1.1     is ##########################################################################
   14897  1.1     is 
   14898  1.1     is #
   14899  1.1     is # Add: inputs are not both normalized; what are they?
   14900  1.1     is #
   14901  1.1     is fadd_not_norm:
   14902  1.1     is 	mov.w		(tbl_fadd_op.b,%pc,%d1.w*2),%d1
   14903  1.1     is 	jmp		(tbl_fadd_op.b,%pc,%d1.w*1)
   14904  1.1     is 
   14905  1.1     is 	swbeg		&48
   14906  1.1     is tbl_fadd_op:
   14907  1.1     is 	short		fadd_norm	- tbl_fadd_op # NORM + NORM
   14908  1.1     is 	short		fadd_zero_src	- tbl_fadd_op # NORM + ZERO
   14909  1.1     is 	short		fadd_inf_src	- tbl_fadd_op # NORM + INF
   14910  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14911  1.1     is 	short		fadd_norm	- tbl_fadd_op # NORM + DENORM
   14912  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14913  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14914  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14915  1.1     is 
   14916  1.1     is 	short		fadd_zero_dst	- tbl_fadd_op # ZERO + NORM
   14917  1.1     is 	short		fadd_zero_2	- tbl_fadd_op # ZERO + ZERO
   14918  1.1     is 	short		fadd_inf_src	- tbl_fadd_op # ZERO + INF
   14919  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14920  1.1     is 	short		fadd_zero_dst	- tbl_fadd_op # ZERO + DENORM
   14921  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14922  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14923  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14924  1.1     is 
   14925  1.1     is 	short		fadd_inf_dst	- tbl_fadd_op # INF + NORM
   14926  1.1     is 	short		fadd_inf_dst	- tbl_fadd_op # INF + ZERO
   14927  1.1     is 	short		fadd_inf_2	- tbl_fadd_op # INF + INF
   14928  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14929  1.1     is 	short		fadd_inf_dst	- tbl_fadd_op # INF + DENORM
   14930  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14931  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14932  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14933  1.1     is 
   14934  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + NORM
   14935  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + ZERO
   14936  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + INF
   14937  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + QNAN
   14938  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + DENORM
   14939  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # QNAN + SNAN
   14940  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14941  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14942  1.1     is 
   14943  1.1     is 	short		fadd_norm	- tbl_fadd_op # DENORM + NORM
   14944  1.1     is 	short		fadd_zero_src	- tbl_fadd_op # DENORM + ZERO
   14945  1.1     is 	short		fadd_inf_src	- tbl_fadd_op # DENORM + INF
   14946  1.1     is 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14947  1.1     is 	short		fadd_norm	- tbl_fadd_op # DENORM + DENORM
   14948  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14949  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14950  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14951  1.1     is 
   14952  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # SNAN + NORM
   14953  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # SNAN + ZERO
   14954  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # SNAN + INF
   14955  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # SNAN + QNAN
   14956  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # SNAN + DENORM
   14957  1.1     is 	short		fadd_res_snan	- tbl_fadd_op # SNAN + SNAN
   14958  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14959  1.1     is 	short		tbl_fadd_op	- tbl_fadd_op #
   14960  1.1     is 
   14961  1.1     is fadd_res_qnan:
   14962  1.1     is 	bra.l		res_qnan
   14963  1.1     is fadd_res_snan:
   14964  1.1     is 	bra.l		res_snan
   14965  1.1     is 
   14966  1.1     is #
   14967  1.1     is # both operands are ZEROes
   14968  1.1     is #
   14969  1.1     is fadd_zero_2:
   14970  1.1     is 	mov.b		SRC_EX(%a0),%d0		# are the signs opposite
   14971  1.1     is 	mov.b		DST_EX(%a1),%d1
   14972  1.1     is 	eor.b		%d0,%d1
   14973  1.1     is 	bmi.w		fadd_zero_2_chk_rm	# weed out (-ZERO)+(+ZERO)
   14974  1.1     is 
   14975  1.1     is # the signs are the same. so determine whether they are positive or negative
   14976  1.1     is # and return the appropriately signed zero.
   14977  1.1     is 	tst.b		%d0			# are ZEROes positive or negative?
   14978  1.1     is 	bmi.b		fadd_zero_rm		# negative
   14979  1.1     is 	fmov.s		&0x00000000,%fp0	# return +ZERO
   14980  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   14981  1.1     is 	rts
   14982  1.1     is 
   14983  1.1     is #
   14984  1.1     is # the ZEROes have opposite signs:
   14985  1.1     is # - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
   14986  1.1     is # - -ZERO is returned in the case of RM.
   14987  1.1     is #
   14988  1.1     is fadd_zero_2_chk_rm:
   14989  1.1     is 	mov.b		3+L_SCR3(%a6),%d1
   14990  1.1     is 	andi.b		&0x30,%d1		# extract rnd mode
   14991  1.1     is 	cmpi.b		%d1,&rm_mode*0x10	# is rnd mode == RM?
   14992  1.1     is 	beq.b		fadd_zero_rm		# yes
   14993  1.1     is 	fmov.s		&0x00000000,%fp0	# return +ZERO
   14994  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   14995  1.1     is 	rts
   14996  1.1     is 
   14997  1.1     is fadd_zero_rm:
   14998  1.1     is 	fmov.s		&0x80000000,%fp0	# return -ZERO
   14999  1.1     is 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set NEG/Z
   15000  1.1     is 	rts
   15001  1.1     is 
   15002  1.1     is #
   15003  1.1     is # one operand is a ZERO and the other is a DENORM or NORM. scale
   15004  1.1     is # the DENORM or NORM and jump to the regular fadd routine.
   15005  1.1     is #
   15006  1.1     is fadd_zero_dst:
   15007  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15008  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15009  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15010  1.1     is 	bsr.l		scale_to_zero_src	# scale the operand
   15011  1.1     is 	clr.w		FP_SCR1_EX(%a6)
   15012  1.1     is 	clr.l		FP_SCR1_HI(%a6)
   15013  1.1     is 	clr.l		FP_SCR1_LO(%a6)
   15014  1.1     is 	bra.w		fadd_zero_entry		# go execute fadd
   15015  1.1     is 
   15016  1.1     is fadd_zero_src:
   15017  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   15018  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   15019  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   15020  1.1     is 	bsr.l		scale_to_zero_dst	# scale the operand
   15021  1.1     is 	clr.w		FP_SCR0_EX(%a6)
   15022  1.1     is 	clr.l		FP_SCR0_HI(%a6)
   15023  1.1     is 	clr.l		FP_SCR0_LO(%a6)
   15024  1.1     is 	bra.w		fadd_zero_entry		# go execute fadd
   15025  1.1     is 
   15026  1.1     is #
   15027  1.1     is # both operands are INFs. an OPERR will result if the INFs have
   15028  1.1     is # different signs. else, an INF of the same sign is returned
   15029  1.1     is #
   15030  1.1     is fadd_inf_2:
   15031  1.1     is 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   15032  1.1     is 	mov.b		DST_EX(%a1),%d1
   15033  1.1     is 	eor.b		%d1,%d0
   15034  1.1     is 	bmi.l		res_operr		# weed out (-INF)+(+INF)
   15035  1.1     is 
   15036  1.1     is # ok, so it's not an OPERR. but, we do have to remember to return the
   15037  1.1     is # src INF since that's where the 881/882 gets the j-bit from...
   15038  1.1     is 
   15039  1.1     is #
   15040  1.1     is # operands are INF and one of {ZERO, INF, DENORM, NORM}
   15041  1.1     is #
   15042  1.1     is fadd_inf_src:
   15043  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return src INF
   15044  1.1     is 	tst.b		SRC_EX(%a0)		# is INF positive?
   15045  1.1     is 	bpl.b		fadd_inf_done		# yes; we're done
   15046  1.1     is 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15047  1.1     is 	rts
   15048  1.1     is 
   15049  1.1     is #
   15050  1.1     is # operands are INF and one of {ZERO, INF, DENORM, NORM}
   15051  1.1     is #
   15052  1.1     is fadd_inf_dst:
   15053  1.1     is 	fmovm.x		DST(%a1),&0x80		# return dst INF
   15054  1.1     is 	tst.b		DST_EX(%a1)		# is INF positive?
   15055  1.1     is 	bpl.b		fadd_inf_done		# yes; we're done
   15056  1.1     is 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15057  1.1     is 	rts
   15058  1.1     is 
   15059  1.1     is fadd_inf_done:
   15060  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6) # set INF
   15061  1.1     is 	rts
   15062  1.1     is 
   15063  1.1     is #########################################################################
   15064  1.1     is # XDEF ****************************************************************	#
   15065  1.1     is #	fsub(): emulates the fsub instruction				#
   15066  1.1     is #	fssub(): emulates the fssub instruction				#
   15067  1.1     is #	fdsub(): emulates the fdsub instruction				#
   15068  1.1     is #									#
   15069  1.1     is # XREF ****************************************************************	#
   15070  1.1     is # 	addsub_scaler2() - scale the operands so they won't take exc	#
   15071  1.1     is #	ovf_res() - return default overflow result			#
   15072  1.1     is #	unf_res() - return default underflow result			#
   15073  1.1     is #	res_qnan() - set QNAN result					#
   15074  1.1     is # 	res_snan() - set SNAN result					#
   15075  1.1     is #	res_operr() - set OPERR result					#
   15076  1.1     is #	scale_to_zero_src() - set src operand exponent equal to zero	#
   15077  1.1     is #	scale_to_zero_dst() - set dst operand exponent equal to zero	#
   15078  1.1     is #									#
   15079  1.1     is # INPUT ***************************************************************	#
   15080  1.1     is #	a0 = pointer to extended precision source operand		#
   15081  1.1     is # 	a1 = pointer to extended precision destination operand		#
   15082  1.1     is #									#
   15083  1.1     is # OUTPUT **************************************************************	#
   15084  1.1     is #	fp0 = result							#
   15085  1.1     is #	fp1 = EXOP (if exception occurred)				#
   15086  1.1     is #									#
   15087  1.1     is # ALGORITHM ***********************************************************	#
   15088  1.1     is # 	Handle NANs, infinities, and zeroes as special cases. Divide	#
   15089  1.1     is # norms into extended, single, and double precision.			#
   15090  1.1     is #	Do subtraction after scaling exponents such that exception won't#
   15091  1.1     is # occur. Then, check result exponent to see if exception would have	#
   15092  1.1     is # occurred. If so, return default result and maybe EXOP. Else, insert	#
   15093  1.1     is # the correct result exponent and return. Set FPSR bits as appropriate.	#
   15094  1.1     is #									#
   15095  1.1     is #########################################################################
   15096  1.1     is 
   15097  1.1     is 	global		fssub
   15098  1.1     is fssub:
   15099  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   15100  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   15101  1.1     is 	bra.b		fsub
   15102  1.1     is 
   15103  1.1     is 	global		fdsub
   15104  1.1     is fdsub:
   15105  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   15106  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   15107  1.1     is 
   15108  1.1     is 	global		fsub
   15109  1.1     is fsub:
   15110  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   15111  1.1     is 
   15112  1.1     is 	clr.w		%d1
   15113  1.1     is 	mov.b		DTAG(%a6),%d1
   15114  1.1     is 	lsl.b		&0x3,%d1
   15115  1.1     is 	or.b		STAG(%a6),%d1		# combine src tags
   15116  1.1     is 
   15117  1.1     is 	bne.w		fsub_not_norm		# optimize on non-norm input
   15118  1.1     is 
   15119  1.1     is #
   15120  1.1     is # SUB: norms and denorms
   15121  1.1     is #
   15122  1.1     is fsub_norm:
   15123  1.1     is 	bsr.l		addsub_scaler2		# scale exponents
   15124  1.1     is 
   15125  1.1     is fsub_zero_entry:
   15126  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   15127  1.1     is 
   15128  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15129  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15130  1.1     is 
   15131  1.1     is 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
   15132  1.1     is 
   15133  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15134  1.1     is 	fmov.l		%fpsr,%d1		# fetch INEX2, N, Z
   15135  1.1     is 
   15136  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save exc and ccode bits
   15137  1.1     is 
   15138  1.1     is 	fbeq.w		fsub_zero_exit		# if result zero, end now
   15139  1.1     is 
   15140  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   15141  1.1     is 
   15142  1.1     is 	fmovm.x		&0x01,-(%sp)		# save result to stack
   15143  1.1     is 
   15144  1.1     is 	mov.w		2+L_SCR3(%a6),%d1
   15145  1.1     is 	lsr.b		&0x6,%d1
   15146  1.1     is 
   15147  1.1     is 	mov.w		(%sp),%d2		# fetch new exponent
   15148  1.1     is 	andi.l		&0x7fff,%d2		# strip sign
   15149  1.1     is 	sub.l		%d0,%d2			# add scale factor
   15150  1.1     is 
   15151  1.1     is 	cmp.l		%d2,(tbl_fsub_ovfl.b,%pc,%d1.w*4) # is it an overflow?
   15152  1.1     is 	bge.b		fsub_ovfl		# yes
   15153  1.1     is 
   15154  1.1     is 	cmp.l		%d2,(tbl_fsub_unfl.b,%pc,%d1.w*4) # is it an underflow?
   15155  1.1     is 	blt.w		fsub_unfl		# yes
   15156  1.1     is 	beq.w		fsub_may_unfl		# maybe; go find out
   15157  1.1     is 
   15158  1.1     is fsub_normal:
   15159  1.1     is 	mov.w		(%sp),%d1
   15160  1.1     is 	andi.w		&0x8000,%d1		# keep sign
   15161  1.1     is 	or.w		%d2,%d1			# insert new exponent
   15162  1.1     is 	mov.w		%d1,(%sp)		# insert new exponent
   15163  1.1     is 
   15164  1.1     is 	fmovm.x		(%sp)+,&0x80		# return result in fp0
   15165  1.1     is 
   15166  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   15167  1.1     is 	rts
   15168  1.1     is 
   15169  1.1     is fsub_zero_exit:
   15170  1.1     is #	fmov.s		&0x00000000,%fp0	# return zero in fp0
   15171  1.1     is 	rts
   15172  1.1     is 
   15173  1.1     is tbl_fsub_ovfl:
   15174  1.1     is 	long		0x7fff			# ext ovfl
   15175  1.1     is 	long		0x407f			# sgl ovfl
   15176  1.1     is 	long		0x43ff			# dbl ovfl
   15177  1.1     is 
   15178  1.1     is tbl_fsub_unfl:
   15179  1.1     is 	long	        0x0000			# ext unfl
   15180  1.1     is 	long		0x3f81			# sgl unfl
   15181  1.1     is 	long		0x3c01			# dbl unfl
   15182  1.1     is 
   15183  1.1     is fsub_ovfl:
   15184  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   15185  1.1     is 
   15186  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   15187  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   15188  1.1     is 	bne.b		fsub_ovfl_ena		# yes
   15189  1.1     is 
   15190  1.1     is 	add.l		&0xc,%sp
   15191  1.1     is fsub_ovfl_dis:
   15192  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   15193  1.1     is 	sne		%d1			# set sign param accordingly
   15194  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   15195  1.1     is 	bsr.l		ovf_res			# calculate default result
   15196  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   15197  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   15198  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   15199  1.1     is 	rts
   15200  1.1     is 
   15201  1.1     is fsub_ovfl_ena:
   15202  1.1     is 	mov.b		L_SCR3(%a6),%d1
   15203  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   15204  1.1     is 	bne.b		fsub_ovfl_ena_sd	# no
   15205  1.1     is 
   15206  1.1     is fsub_ovfl_ena_cont:
   15207  1.1     is 	mov.w		(%sp),%d1		# fetch {sgn,exp}
   15208  1.1     is 	andi.w		&0x8000,%d1		# keep sign
   15209  1.1     is 	subi.l		&0x6000,%d2		# subtract new bias
   15210  1.1     is 	andi.w		&0x7fff,%d2		# clear top bit
   15211  1.1     is 	or.w		%d2,%d1			# concat sign,exp
   15212  1.1     is 	mov.w		%d1,(%sp)		# insert new exponent
   15213  1.1     is 
   15214  1.1     is 	fmovm.x		(%sp)+,&0x40		# return EXOP in fp1
   15215  1.1     is 	bra.b		fsub_ovfl_dis
   15216  1.1     is 
   15217  1.1     is fsub_ovfl_ena_sd:
   15218  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   15219  1.1     is 
   15220  1.1     is 	mov.l		L_SCR3(%a6),%d1
   15221  1.1     is 	andi.b		&0x30,%d1		# clear rnd prec
   15222  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   15223  1.1     is 
   15224  1.1     is 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
   15225  1.1     is 
   15226  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15227  1.1     is 
   15228  1.1     is 	add.l		&0xc,%sp
   15229  1.1     is 	fmovm.x		&0x01,-(%sp)
   15230  1.1     is 	bra.b		fsub_ovfl_ena_cont
   15231  1.1     is 
   15232  1.1     is fsub_unfl:
   15233  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   15234  1.1     is 
   15235  1.1     is 	add.l		&0xc,%sp
   15236  1.1     is 
   15237  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   15238  1.1     is 
   15239  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   15240  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15241  1.1     is 
   15242  1.1     is 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
   15243  1.1     is 
   15244  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15245  1.1     is 	fmov.l		%fpsr,%d1		# save status
   15246  1.1     is 
   15247  1.1     is 	or.l		%d1,USER_FPSR(%a6)
   15248  1.1     is 
   15249  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   15250  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   15251  1.1     is 	bne.b		fsub_unfl_ena		# yes
   15252  1.1     is 
   15253  1.1     is fsub_unfl_dis:
   15254  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   15255  1.1     is 
   15256  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   15257  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   15258  1.1     is 	bsr.l		unf_res			# calculate default result
   15259  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# 'Z' may have been set
   15260  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   15261  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   15262  1.1     is 	rts
   15263  1.1     is 
   15264  1.1     is fsub_unfl_ena:
   15265  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40
   15266  1.1     is 
   15267  1.1     is 	mov.l		L_SCR3(%a6),%d1
   15268  1.1     is 	andi.b		&0xc0,%d1		# is precision extended?
   15269  1.1     is 	bne.b		fsub_unfl_ena_sd	# no
   15270  1.1     is 
   15271  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15272  1.1     is 
   15273  1.1     is fsub_unfl_ena_cont:
   15274  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15275  1.1     is 
   15276  1.1     is 	fsub.x		FP_SCR0(%a6),%fp1	# execute subtract
   15277  1.1     is 
   15278  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15279  1.1     is 
   15280  1.1     is 	fmovm.x		&0x40,FP_SCR0(%a6)	# store result to stack
   15281  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   15282  1.1     is 	mov.l		%d1,%d2			# make a copy
   15283  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   15284  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   15285  1.1     is 	sub.l		%d0,%d1			# add scale factor
   15286  1.1     is 	addi.l		&0x6000,%d1		# subtract new bias
   15287  1.1     is 	andi.w		&0x7fff,%d1		# clear top bit
   15288  1.1     is 	or.w		%d2,%d1			# concat sgn,exp
   15289  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   15290  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   15291  1.1     is 	bra.w		fsub_unfl_dis
   15292  1.1     is 
   15293  1.1     is fsub_unfl_ena_sd:
   15294  1.1     is 	mov.l		L_SCR3(%a6),%d1
   15295  1.1     is 	andi.b		&0x30,%d1		# clear rnd prec
   15296  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   15297  1.1     is 
   15298  1.1     is 	bra.b		fsub_unfl_ena_cont
   15299  1.1     is 
   15300  1.1     is #
   15301  1.1     is # result is equal to the smallest normalized number in the selected precision
   15302  1.1     is # if the precision is extended, this result could not have come from an
   15303  1.1     is # underflow that rounded up.
   15304  1.1     is #
   15305  1.1     is fsub_may_unfl:
   15306  1.1     is 	mov.l		L_SCR3(%a6),%d1
   15307  1.1     is 	andi.b		&0xc0,%d1		# fetch rnd prec
   15308  1.1     is 	beq.w		fsub_normal		# yes; no underflow occurred
   15309  1.1     is 
   15310  1.1     is 	mov.l		0x4(%sp),%d1
   15311  1.1     is 	cmpi.l		%d1,&0x80000000		# is hi(man) = 0x80000000?
   15312  1.1     is 	bne.w		fsub_normal		# no; no underflow occurred
   15313  1.1     is 
   15314  1.1     is 	tst.l		0x8(%sp)		# is lo(man) = 0x0?
   15315  1.1     is 	bne.w		fsub_normal		# no; no underflow occurred
   15316  1.1     is 
   15317  1.1     is 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
   15318  1.1     is 	beq.w		fsub_normal		# no; no underflow occurred
   15319  1.1     is 
   15320  1.1     is #
   15321  1.1     is # ok, so now the result has a exponent equal to the smallest normalized
   15322  1.1     is # exponent for the selected precision. also, the mantissa is equal to
   15323  1.1     is # 0x8000000000000000 and this mantissa is the result of rounding non-zero
   15324  1.1     is # g,r,s.
   15325  1.1     is # now, we must determine whether the pre-rounded result was an underflow
   15326  1.1     is # rounded "up" or a normalized number rounded "down".
   15327  1.1     is # so, we do this be re-executing the add using RZ as the rounding mode and
   15328  1.1     is # seeing if the new result is smaller or equal to the current result.
   15329  1.1     is #
   15330  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   15331  1.1     is 
   15332  1.1     is 	mov.l		L_SCR3(%a6),%d1
   15333  1.1     is 	andi.b		&0xc0,%d1		# keep rnd prec
   15334  1.1     is 	ori.b		&rz_mode*0x10,%d1	# insert rnd mode
   15335  1.1     is 	fmov.l		%d1,%fpcr		# set FPCR
   15336  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15337  1.1     is 
   15338  1.1     is 	fsub.x		FP_SCR0(%a6),%fp1	# execute subtract
   15339  1.1     is 
   15340  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15341  1.1     is 
   15342  1.1     is 	fabs.x		%fp0			# compare absolute values
   15343  1.1     is 	fabs.x		%fp1
   15344  1.1     is 	fcmp.x		%fp0,%fp1		# is first result > second?
   15345  1.1     is 
   15346  1.1     is 	fbgt.w		fsub_unfl		# yes; it's an underflow
   15347  1.1     is 	bra.w		fsub_normal		# no; it's not an underflow
   15348  1.1     is 
   15349  1.1     is ##########################################################################
   15350  1.1     is 
   15351  1.1     is #
   15352  1.1     is # Sub: inputs are not both normalized; what are they?
   15353  1.1     is #
   15354  1.1     is fsub_not_norm:
   15355  1.1     is 	mov.w		(tbl_fsub_op.b,%pc,%d1.w*2),%d1
   15356  1.1     is 	jmp		(tbl_fsub_op.b,%pc,%d1.w*1)
   15357  1.1     is 
   15358  1.1     is 	swbeg		&48
   15359  1.1     is tbl_fsub_op:
   15360  1.1     is 	short		fsub_norm	- tbl_fsub_op # NORM - NORM
   15361  1.1     is 	short		fsub_zero_src	- tbl_fsub_op # NORM - ZERO
   15362  1.1     is 	short		fsub_inf_src	- tbl_fsub_op # NORM - INF
   15363  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15364  1.1     is 	short		fsub_norm	- tbl_fsub_op # NORM - DENORM
   15365  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15366  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15367  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15368  1.1     is 
   15369  1.1     is 	short		fsub_zero_dst	- tbl_fsub_op # ZERO - NORM
   15370  1.1     is 	short		fsub_zero_2	- tbl_fsub_op # ZERO - ZERO
   15371  1.1     is 	short		fsub_inf_src	- tbl_fsub_op # ZERO - INF
   15372  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15373  1.1     is 	short		fsub_zero_dst	- tbl_fsub_op # ZERO - DENORM
   15374  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15375  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15376  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15377  1.1     is 
   15378  1.1     is 	short		fsub_inf_dst	- tbl_fsub_op # INF - NORM
   15379  1.1     is 	short		fsub_inf_dst	- tbl_fsub_op # INF - ZERO
   15380  1.1     is 	short		fsub_inf_2	- tbl_fsub_op # INF - INF
   15381  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15382  1.1     is 	short		fsub_inf_dst	- tbl_fsub_op # INF - DENORM
   15383  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15384  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15385  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15386  1.1     is 
   15387  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - NORM
   15388  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - ZERO
   15389  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - INF
   15390  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - QNAN
   15391  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - DENORM
   15392  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # QNAN - SNAN
   15393  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15394  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15395  1.1     is 
   15396  1.1     is 	short		fsub_norm	- tbl_fsub_op # DENORM - NORM
   15397  1.1     is 	short		fsub_zero_src	- tbl_fsub_op # DENORM - ZERO
   15398  1.1     is 	short		fsub_inf_src	- tbl_fsub_op # DENORM - INF
   15399  1.1     is 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15400  1.1     is 	short		fsub_norm	- tbl_fsub_op # DENORM - DENORM
   15401  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15402  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15403  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15404  1.1     is 
   15405  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # SNAN - NORM
   15406  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # SNAN - ZERO
   15407  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # SNAN - INF
   15408  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # SNAN - QNAN
   15409  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # SNAN - DENORM
   15410  1.1     is 	short		fsub_res_snan	- tbl_fsub_op # SNAN - SNAN
   15411  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15412  1.1     is 	short		tbl_fsub_op	- tbl_fsub_op #
   15413  1.1     is 
   15414  1.1     is fsub_res_qnan:
   15415  1.1     is 	bra.l		res_qnan
   15416  1.1     is fsub_res_snan:
   15417  1.1     is 	bra.l		res_snan
   15418  1.1     is 
   15419  1.1     is #
   15420  1.1     is # both operands are ZEROes
   15421  1.1     is #
   15422  1.1     is fsub_zero_2:
   15423  1.1     is 	mov.b		SRC_EX(%a0),%d0
   15424  1.1     is 	mov.b		DST_EX(%a1),%d1
   15425  1.1     is 	eor.b		%d1,%d0
   15426  1.1     is 	bpl.b		fsub_zero_2_chk_rm
   15427  1.1     is 
   15428  1.1     is # the signs are opposite, so, return a ZERO w/ the sign of the dst ZERO
   15429  1.1     is 	tst.b		%d0			# is dst negative?
   15430  1.1     is 	bmi.b		fsub_zero_2_rm		# yes
   15431  1.1     is 	fmov.s		&0x00000000,%fp0	# no; return +ZERO
   15432  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   15433  1.1     is 	rts
   15434  1.1     is 
   15435  1.1     is #
   15436  1.1     is # the ZEROes have the same signs:
   15437  1.1     is # - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
   15438  1.1     is # - -ZERO is returned in the case of RM.
   15439  1.1     is #
   15440  1.1     is fsub_zero_2_chk_rm:
   15441  1.1     is 	mov.b		3+L_SCR3(%a6),%d1
   15442  1.1     is 	andi.b		&0x30,%d1		# extract rnd mode
   15443  1.1     is 	cmpi.b		%d1,&rm_mode*0x10	# is rnd mode = RM?
   15444  1.1     is 	beq.b		fsub_zero_2_rm		# yes
   15445  1.1     is 	fmov.s		&0x00000000,%fp0	# no; return +ZERO
   15446  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   15447  1.1     is 	rts
   15448  1.1     is 
   15449  1.1     is fsub_zero_2_rm:
   15450  1.1     is 	fmov.s		&0x80000000,%fp0	# return -ZERO
   15451  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set Z/NEG
   15452  1.1     is 	rts
   15453  1.1     is 
   15454  1.1     is #
   15455  1.1     is # one operand is a ZERO and the other is a DENORM or a NORM.
   15456  1.1     is # scale the DENORM or NORM and jump to the regular fsub routine.
   15457  1.1     is #
   15458  1.1     is fsub_zero_dst:
   15459  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15460  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15461  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15462  1.1     is 	bsr.l		scale_to_zero_src	# scale the operand
   15463  1.1     is 	clr.w		FP_SCR1_EX(%a6)
   15464  1.1     is 	clr.l		FP_SCR1_HI(%a6)
   15465  1.1     is 	clr.l		FP_SCR1_LO(%a6)
   15466  1.1     is 	bra.w		fsub_zero_entry		# go execute fsub
   15467  1.1     is 
   15468  1.1     is fsub_zero_src:
   15469  1.1     is 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   15470  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   15471  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   15472  1.1     is 	bsr.l		scale_to_zero_dst	# scale the operand
   15473  1.1     is 	clr.w		FP_SCR0_EX(%a6)
   15474  1.1     is 	clr.l		FP_SCR0_HI(%a6)
   15475  1.1     is 	clr.l		FP_SCR0_LO(%a6)
   15476  1.1     is 	bra.w		fsub_zero_entry		# go execute fsub
   15477  1.1     is 
   15478  1.1     is #
   15479  1.1     is # both operands are INFs. an OPERR will result if the INFs have the
   15480  1.1     is # same signs. else,
   15481  1.1     is #
   15482  1.1     is fsub_inf_2:
   15483  1.1     is 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   15484  1.1     is 	mov.b		DST_EX(%a1),%d1
   15485  1.1     is 	eor.b		%d1,%d0
   15486  1.1     is 	bpl.l		res_operr		# weed out (-INF)+(+INF)
   15487  1.1     is 
   15488  1.1     is # ok, so it's not an OPERR. but we do have to remember to return
   15489  1.1     is # the src INF since that's where the 881/882 gets the j-bit.
   15490  1.1     is 
   15491  1.1     is fsub_inf_src:
   15492  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return src INF
   15493  1.1     is 	fneg.x		%fp0			# invert sign
   15494  1.1     is 	fbge.w		fsub_inf_done		# sign is now positive
   15495  1.1     is 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15496  1.1     is 	rts
   15497  1.1     is 
   15498  1.1     is fsub_inf_dst:
   15499  1.1     is 	fmovm.x		DST(%a1),&0x80		# return dst INF
   15500  1.1     is 	tst.b		DST_EX(%a1)		# is INF negative?
   15501  1.1     is 	bpl.b		fsub_inf_done		# no
   15502  1.1     is 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15503  1.1     is 	rts
   15504  1.1     is 
   15505  1.1     is fsub_inf_done:
   15506  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
   15507  1.1     is 	rts
   15508  1.1     is 
   15509  1.1     is #########################################################################
   15510  1.1     is # XDEF ****************************************************************	#
   15511  1.1     is # 	fsqrt(): emulates the fsqrt instruction				#
   15512  1.1     is #	fssqrt(): emulates the fssqrt instruction			#
   15513  1.1     is #	fdsqrt(): emulates the fdsqrt instruction			#
   15514  1.1     is #									#
   15515  1.1     is # XREF ****************************************************************	#
   15516  1.1     is #	scale_sqrt() - scale the source operand				#
   15517  1.1     is #	unf_res() - return default underflow result			#
   15518  1.1     is #	ovf_res() - return default overflow result			#
   15519  1.1     is # 	res_qnan_1op() - return QNAN result				#
   15520  1.1     is # 	res_snan_1op() - return SNAN result				#
   15521  1.1     is #									#
   15522  1.1     is # INPUT ***************************************************************	#
   15523  1.1     is #	a0 = pointer to extended precision source operand		#
   15524  1.1     is #	d0  rnd prec,mode						#
   15525  1.1     is #									#
   15526  1.1     is # OUTPUT **************************************************************	#
   15527  1.1     is #	fp0 = result							#
   15528  1.1     is #	fp1 = EXOP (if exception occurred)				#
   15529  1.1     is #									#
   15530  1.1     is # ALGORITHM ***********************************************************	#
   15531  1.1     is #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   15532  1.1     is # norms/denorms into ext/sgl/dbl precision.				#
   15533  1.1     is #	For norms/denorms, scale the exponents such that a sqrt		#
   15534  1.1     is # instruction won't cause an exception. Use the regular fsqrt to	#
   15535  1.1     is # compute a result. Check if the regular operands would have taken	#
   15536  1.1     is # an exception. If so, return the default overflow/underflow result	#
   15537  1.1     is # and return the EXOP if exceptions are enabled. Else, scale the 	#
   15538  1.1     is # result operand to the proper exponent.				#
   15539  1.1     is #									#
   15540  1.1     is #########################################################################
   15541  1.1     is 
   15542  1.1     is 	global		fssqrt
   15543  1.1     is fssqrt:
   15544  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   15545  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   15546  1.1     is 	bra.b		fsqrt
   15547  1.1     is 
   15548  1.1     is 	global		fdsqrt
   15549  1.1     is fdsqrt:
   15550  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   15551  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
   15552  1.1     is 
   15553  1.1     is 	global		fsqrt
   15554  1.1     is fsqrt:
   15555  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   15556  1.1     is 	clr.w		%d1
   15557  1.1     is 	mov.b		STAG(%a6),%d1
   15558  1.1     is 	bne.w		fsqrt_not_norm		# optimize on non-norm input
   15559  1.1     is 
   15560  1.1     is #
   15561  1.1     is # SQUARE ROOT: norms and denorms ONLY!
   15562  1.1     is #
   15563  1.1     is fsqrt_norm:
   15564  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   15565  1.1     is 	bmi.l		res_operr		# yes
   15566  1.1     is 
   15567  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   15568  1.1     is 	bne.b		fsqrt_not_ext		# no; go handle sgl or dbl
   15569  1.1     is 
   15570  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15571  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15572  1.1     is 
   15573  1.1     is 	fsqrt.x		(%a0),%fp0		# execute square root
   15574  1.1     is 
   15575  1.1     is 	fmov.l		%fpsr,%d1
   15576  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# set N,INEX
   15577  1.1     is 
   15578  1.1     is 	rts
   15579  1.1     is 
   15580  1.1     is fsqrt_denorm:
   15581  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   15582  1.1     is 	bmi.l		res_operr		# yes
   15583  1.1     is 
   15584  1.1     is 	andi.b		&0xc0,%d0		# is precision extended?
   15585  1.1     is 	bne.b		fsqrt_not_ext		# no; go handle sgl or dbl
   15586  1.1     is 
   15587  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15588  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15589  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15590  1.1     is 
   15591  1.1     is 	bsr.l		scale_sqrt		# calculate scale factor
   15592  1.1     is 
   15593  1.1     is 	bra.w		fsqrt_sd_normal
   15594  1.1     is 
   15595  1.1     is #
   15596  1.1     is # operand is either single or double
   15597  1.1     is #
   15598  1.1     is fsqrt_not_ext:
   15599  1.1     is 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
   15600  1.1     is 	bne.w		fsqrt_dbl
   15601  1.1     is 
   15602  1.1     is #
   15603  1.1     is # operand is to be rounded to single precision
   15604  1.1     is #
   15605  1.1     is fsqrt_sgl:
   15606  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15607  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15608  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15609  1.1     is 
   15610  1.1     is 	bsr.l		scale_sqrt		# calculate scale factor
   15611  1.1     is 
   15612  1.1     is 	cmpi.l		%d0,&0x3fff-0x3f81	# will move in underflow?
   15613  1.1     is 	beq.w		fsqrt_sd_may_unfl
   15614  1.1     is 	bgt.w		fsqrt_sd_unfl		# yes; go handle underflow
   15615  1.1     is 	cmpi.l		%d0,&0x3fff-0x407f	# will move in overflow?
   15616  1.1     is 	beq.w		fsqrt_sd_may_ovfl	# maybe; go check
   15617  1.1     is 	blt.w		fsqrt_sd_ovfl		# yes; go handle overflow
   15618  1.1     is 
   15619  1.1     is #
   15620  1.1     is # operand will NOT overflow or underflow when moved in to the fp reg file
   15621  1.1     is #
   15622  1.1     is fsqrt_sd_normal:
   15623  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15624  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15625  1.1     is 
   15626  1.1     is 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform absolute
   15627  1.1     is 
   15628  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   15629  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15630  1.1     is 
   15631  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15632  1.1     is 
   15633  1.1     is fsqrt_sd_normal_exit:
   15634  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   15635  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   15636  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
   15637  1.1     is 	mov.l		%d1,%d2			# make a copy
   15638  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   15639  1.1     is 	sub.l		%d0,%d1			# add scale factor
   15640  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   15641  1.1     is 	or.w		%d1,%d2			# concat old sign,new exp
   15642  1.1     is 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   15643  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   15644  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   15645  1.1     is 	rts
   15646  1.1     is 
   15647  1.1     is #
   15648  1.1     is # operand is to be rounded to double precision
   15649  1.1     is #
   15650  1.1     is fsqrt_dbl:
   15651  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15652  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15653  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15654  1.1     is 
   15655  1.1     is 	bsr.l		scale_sqrt		# calculate scale factor
   15656  1.1     is 
   15657  1.1     is 	cmpi.l		%d0,&0x3fff-0x3c01	# will move in underflow?
   15658  1.1     is 	beq.w		fsqrt_sd_may_unfl
   15659  1.1     is 	bgt.b		fsqrt_sd_unfl		# yes; go handle underflow
   15660  1.1     is 	cmpi.l		%d0,&0x3fff-0x43ff	# will move in overflow?
   15661  1.1     is 	beq.w		fsqrt_sd_may_ovfl	# maybe; go check
   15662  1.1     is 	blt.w		fsqrt_sd_ovfl		# yes; go handle overflow
   15663  1.1     is 	bra.w		fsqrt_sd_normal		# no; ho handle normalized op
   15664  1.1     is 
   15665  1.1     is # we're on the line here and the distinguising characteristic is whether
   15666  1.1     is # the exponent is 3fff or 3ffe. if it's 3ffe, then it's a safe number
   15667  1.1     is # elsewise fall through to underflow.
   15668  1.1     is fsqrt_sd_may_unfl:
   15669  1.1     is 	btst		&0x0,1+FP_SCR0_EX(%a6)	# is exponent 0x3fff?
   15670  1.1     is 	bne.w		fsqrt_sd_normal		# yes, so no underflow
   15671  1.1     is 
   15672  1.1     is #
   15673  1.1     is # operand WILL underflow when moved in to the fp register file
   15674  1.1     is #
   15675  1.1     is fsqrt_sd_unfl:
   15676  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   15677  1.1     is 
   15678  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   15679  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15680  1.1     is 
   15681  1.1     is 	fsqrt.x 	FP_SCR0(%a6),%fp0	# execute square root
   15682  1.1     is 
   15683  1.1     is 	fmov.l		%fpsr,%d1		# save status
   15684  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15685  1.1     is 
   15686  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15687  1.1     is 
   15688  1.1     is # if underflow or inexact is enabled, go calculate EXOP first.
   15689  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   15690  1.1     is 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   15691  1.1     is 	bne.b		fsqrt_sd_unfl_ena	# yes
   15692  1.1     is 
   15693  1.1     is fsqrt_sd_unfl_dis:
   15694  1.1     is 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   15695  1.1     is 
   15696  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   15697  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   15698  1.1     is 	bsr.l		unf_res			# calculate default result
   15699  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set possible 'Z' ccode
   15700  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   15701  1.1     is 	rts
   15702  1.1     is 
   15703  1.1     is #
   15704  1.1     is # operand will underflow AND underflow is enabled.
   15705  1.1     is # therefore, we must return the result rounded to extended precision.
   15706  1.1     is #
   15707  1.1     is fsqrt_sd_unfl_ena:
   15708  1.1     is 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   15709  1.1     is 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   15710  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   15711  1.1     is 
   15712  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   15713  1.1     is 	mov.l		%d1,%d2			# make a copy
   15714  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   15715  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   15716  1.1     is 	sub.l		%d0,%d1			# subtract scale factor
   15717  1.1     is 	addi.l		&0x6000,%d1		# add new bias
   15718  1.1     is 	andi.w		&0x7fff,%d1
   15719  1.1     is 	or.w		%d2,%d1			# concat new sign,new exp
   15720  1.1     is 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
   15721  1.1     is 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   15722  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   15723  1.1     is 	bra.b		fsqrt_sd_unfl_dis
   15724  1.1     is 
   15725  1.1     is #
   15726  1.1     is # operand WILL overflow.
   15727  1.1     is #
   15728  1.1     is fsqrt_sd_ovfl:
   15729  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15730  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15731  1.1     is 
   15732  1.1     is 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform square root
   15733  1.1     is 
   15734  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15735  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   15736  1.1     is 
   15737  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15738  1.1     is 
   15739  1.1     is fsqrt_sd_ovfl_tst:
   15740  1.1     is 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   15741  1.1     is 
   15742  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   15743  1.1     is 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   15744  1.1     is 	bne.b		fsqrt_sd_ovfl_ena	# yes
   15745  1.1     is 
   15746  1.1     is #
   15747  1.1     is # OVFL is not enabled; therefore, we must create the default result by
   15748  1.1     is # calling ovf_res().
   15749  1.1     is #
   15750  1.1     is fsqrt_sd_ovfl_dis:
   15751  1.1     is 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   15752  1.1     is 	sne		%d1			# set sign param accordingly
   15753  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   15754  1.1     is 	bsr.l		ovf_res			# calculate default result
   15755  1.1     is 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   15756  1.1     is 	fmovm.x		(%a0),&0x80		# return default result in fp0
   15757  1.1     is 	rts
   15758  1.1     is 
   15759  1.1     is #
   15760  1.1     is # OVFL is enabled.
   15761  1.1     is # the INEX2 bit has already been updated by the round to the correct precision.
   15762  1.1     is # now, round to extended(and don't alter the FPSR).
   15763  1.1     is #
   15764  1.1     is fsqrt_sd_ovfl_ena:
   15765  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   15766  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   15767  1.1     is 	mov.l		%d1,%d2			# make a copy
   15768  1.1     is 	andi.l		&0x7fff,%d1		# strip sign
   15769  1.1     is 	andi.w		&0x8000,%d2		# keep old sign
   15770  1.1     is 	sub.l		%d0,%d1			# add scale factor
   15771  1.1     is 	subi.l		&0x6000,%d1		# subtract bias
   15772  1.1     is 	andi.w		&0x7fff,%d1
   15773  1.1     is 	or.w		%d2,%d1			# concat sign,exp
   15774  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   15775  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   15776  1.1     is 	mov.l		(%sp)+,%d2		# restore d2
   15777  1.1     is 	bra.b		fsqrt_sd_ovfl_dis
   15778  1.1     is 
   15779  1.1     is #
   15780  1.1     is # the move in MAY underflow. so...
   15781  1.1     is #
   15782  1.1     is fsqrt_sd_may_ovfl:
   15783  1.1     is 	btst		&0x0,1+FP_SCR0_EX(%a6)	# is exponent 0x3fff?
   15784  1.1     is 	bne.w		fsqrt_sd_ovfl		# yes, so overflow
   15785  1.1     is 
   15786  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   15787  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15788  1.1     is 
   15789  1.1     is 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform absolute
   15790  1.1     is 
   15791  1.1     is 	fmov.l		%fpsr,%d1		# save status
   15792  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   15793  1.1     is 
   15794  1.1     is 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15795  1.1     is 
   15796  1.1     is 	fmov.x		%fp0,%fp1		# make a copy of result
   15797  1.1     is 	fcmp.b		%fp1,&0x1		# is |result| >= 1.b?
   15798  1.1     is 	fbge.w		fsqrt_sd_ovfl_tst	# yes; overflow has occurred
   15799  1.1     is 
   15800  1.1     is # no, it didn't overflow; we have correct result
   15801  1.1     is 	bra.w		fsqrt_sd_normal_exit
   15802  1.1     is 
   15803  1.1     is ##########################################################################
   15804  1.1     is 
   15805  1.1     is #
   15806  1.1     is # input is not normalized; what is it?
   15807  1.1     is #
   15808  1.1     is fsqrt_not_norm:
   15809  1.1     is 	cmpi.b		%d1,&DENORM		# weed out DENORM
   15810  1.1     is 	beq.w		fsqrt_denorm
   15811  1.1     is 	cmpi.b		%d1,&ZERO		# weed out ZERO
   15812  1.1     is 	beq.b		fsqrt_zero
   15813  1.1     is 	cmpi.b		%d1,&INF		# weed out INF
   15814  1.1     is 	beq.b		fsqrt_inf
   15815  1.1     is 	cmpi.b		%d1,&SNAN		# weed out SNAN
   15816  1.1     is 	beq.l		res_snan_1op
   15817  1.1     is 	bra.l		res_qnan_1op
   15818  1.1     is 
   15819  1.1     is #
   15820  1.1     is # 	fsqrt(+0) = +0
   15821  1.1     is # 	fsqrt(-0) = -0
   15822  1.1     is #	fsqrt(+INF) = +INF
   15823  1.1     is # 	fsqrt(-INF) = OPERR
   15824  1.1     is #
   15825  1.1     is fsqrt_zero:
   15826  1.1     is 	tst.b		SRC_EX(%a0)		# is ZERO positive or negative?
   15827  1.1     is 	bmi.b		fsqrt_zero_m		# negative
   15828  1.1     is fsqrt_zero_p:
   15829  1.1     is 	fmov.s		&0x00000000,%fp0	# return +ZERO
   15830  1.1     is 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   15831  1.1     is 	rts
   15832  1.1     is fsqrt_zero_m:
   15833  1.1     is 	fmov.s		&0x80000000,%fp0	# return -ZERO
   15834  1.1     is 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set 'Z','N' ccode bits
   15835  1.1     is 	rts
   15836  1.1     is 
   15837  1.1     is fsqrt_inf:
   15838  1.1     is 	tst.b		SRC_EX(%a0)		# is INF positive or negative?
   15839  1.1     is 	bmi.l		res_operr		# negative
   15840  1.1     is fsqrt_inf_p:
   15841  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return +INF in fp0
   15842  1.1     is 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   15843  1.1     is 	rts
   15844  1.1     is 
   15845  1.1     is ##########################################################################
   15846  1.1     is 
   15847  1.1     is #########################################################################
   15848  1.1     is # XDEF ****************************************************************	#
   15849  1.1     is #	addsub_scaler2(): scale inputs to fadd/fsub such that no	#
   15850  1.1     is #			  OVFL/UNFL exceptions will result		#
   15851  1.1     is #									#
   15852  1.1     is # XREF ****************************************************************	#
   15853  1.1     is #	norm() - normalize mantissa after adjusting exponent		#
   15854  1.1     is #									#
   15855  1.1     is # INPUT ***************************************************************	#
   15856  1.1     is #	FP_SRC(a6) = fp op1(src)					#
   15857  1.1     is #	FP_DST(a6) = fp op2(dst)					#
   15858  1.1     is # 									#
   15859  1.1     is # OUTPUT **************************************************************	#
   15860  1.1     is #	FP_SRC(a6) = fp op1 scaled(src)					#
   15861  1.1     is #	FP_DST(a6) = fp op2 scaled(dst)					#
   15862  1.1     is #	d0         = scale amount					#
   15863  1.1     is #									#
   15864  1.1     is # ALGORITHM ***********************************************************	#
   15865  1.1     is # 	If the DST exponent is > the SRC exponent, set the DST exponent	#
   15866  1.1     is # equal to 0x3fff and scale the SRC exponent by the value that the	#
   15867  1.1     is # DST exponent was scaled by. If the SRC exponent is greater or equal,	#
   15868  1.1     is # do the opposite. Return this scale factor in d0.			#
   15869  1.1     is #	If the two exponents differ by > the number of mantissa bits	#
   15870  1.1     is # plus two, then set the smallest exponent to a very small value as a	#
   15871  1.1     is # quick shortcut.							#
   15872  1.1     is #									#
   15873  1.1     is #########################################################################
   15874  1.1     is 
   15875  1.1     is 	global		addsub_scaler2
   15876  1.1     is addsub_scaler2:
   15877  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15878  1.1     is 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   15879  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15880  1.1     is 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   15881  1.1     is 	mov.w		SRC_EX(%a0),%d0
   15882  1.1     is 	mov.w		DST_EX(%a1),%d1
   15883  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)
   15884  1.1     is 	mov.w		%d1,FP_SCR1_EX(%a6)
   15885  1.1     is 
   15886  1.1     is 	andi.w		&0x7fff,%d0
   15887  1.1     is 	andi.w		&0x7fff,%d1
   15888  1.1     is 	mov.w		%d0,L_SCR1(%a6)		# store src exponent
   15889  1.1     is 	mov.w		%d1,2+L_SCR1(%a6)	# store dst exponent
   15890  1.1     is 
   15891  1.1     is 	cmp.w		%d0, %d1		# is src exp >= dst exp?
   15892  1.1     is 	bge.l		src_exp_ge2
   15893  1.1     is 
   15894  1.1     is # dst exp is >  src exp; scale dst to exp = 0x3fff
   15895  1.1     is dst_exp_gt2:
   15896  1.1     is 	bsr.l		scale_to_zero_dst
   15897  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor
   15898  1.1     is 
   15899  1.1     is 	cmpi.b		STAG(%a6),&DENORM	# is dst denormalized?
   15900  1.1     is 	bne.b		cmpexp12
   15901  1.1     is 
   15902  1.1     is 	lea		FP_SCR0(%a6),%a0
   15903  1.1     is 	bsr.l		norm			# normalize the denorm; result is new exp
   15904  1.1     is 	neg.w		%d0			# new exp = -(shft val)
   15905  1.1     is 	mov.w		%d0,L_SCR1(%a6)		# inset new exp
   15906  1.1     is 
   15907  1.1     is cmpexp12:
   15908  1.1     is 	mov.w		2+L_SCR1(%a6),%d0
   15909  1.1     is 	subi.w		&mantissalen+2,%d0	# subtract mantissalen+2 from larger exp
   15910  1.1     is 
   15911  1.1     is 	cmp.w		%d0,L_SCR1(%a6)		# is difference >= len(mantissa)+2?
   15912  1.1     is 	bge.b		quick_scale12
   15913  1.1     is 
   15914  1.1     is 	mov.w		L_SCR1(%a6),%d0
   15915  1.1     is 	add.w		0x2(%sp),%d0		# scale src exponent by scale factor
   15916  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1
   15917  1.1     is 	and.w		&0x8000,%d1
   15918  1.1     is 	or.w		%d1,%d0			# concat {sgn,new exp}
   15919  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new dst exponent
   15920  1.1     is 
   15921  1.1     is 	mov.l		(%sp)+,%d0		# return SCALE factor
   15922  1.1     is 	rts
   15923  1.1     is 
   15924  1.1     is quick_scale12:
   15925  1.1     is 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# zero src exponent
   15926  1.1     is 	bset		&0x0,1+FP_SCR0_EX(%a6)	# set exp = 1
   15927  1.1     is 
   15928  1.1     is 	mov.l		(%sp)+,%d0		# return SCALE factor
   15929  1.1     is 	rts
   15930  1.1     is 
   15931  1.1     is # src exp is >= dst exp; scale src to exp = 0x3fff
   15932  1.1     is src_exp_ge2:
   15933  1.1     is 	bsr.l		scale_to_zero_src
   15934  1.1     is 	mov.l		%d0,-(%sp)		# save scale factor
   15935  1.1     is 
   15936  1.1     is 	cmpi.b		DTAG(%a6),&DENORM	# is dst denormalized?
   15937  1.1     is 	bne.b		cmpexp22
   15938  1.1     is 	lea		FP_SCR1(%a6),%a0
   15939  1.1     is 	bsr.l		norm			# normalize the denorm; result is new exp
   15940  1.1     is 	neg.w		%d0			# new exp = -(shft val)
   15941  1.1     is 	mov.w		%d0,2+L_SCR1(%a6)	# inset new exp
   15942  1.1     is 
   15943  1.1     is cmpexp22:
   15944  1.1     is 	mov.w		L_SCR1(%a6),%d0
   15945  1.1     is 	subi.w		&mantissalen+2,%d0	# subtract mantissalen+2 from larger exp
   15946  1.1     is 
   15947  1.1     is 	cmp.w		%d0,2+L_SCR1(%a6)	# is difference >= len(mantissa)+2?
   15948  1.1     is 	bge.b		quick_scale22
   15949  1.1     is 
   15950  1.1     is 	mov.w		2+L_SCR1(%a6),%d0
   15951  1.1     is 	add.w		0x2(%sp),%d0		# scale dst exponent by scale factor
   15952  1.1     is 	mov.w		FP_SCR1_EX(%a6),%d1
   15953  1.1     is 	andi.w		&0x8000,%d1
   15954  1.1     is 	or.w		%d1,%d0			# concat {sgn,new exp}
   15955  1.1     is 	mov.w		%d0,FP_SCR1_EX(%a6)	# insert new dst exponent
   15956  1.1     is 
   15957  1.1     is 	mov.l		(%sp)+,%d0		# return SCALE factor
   15958  1.1     is 	rts
   15959  1.1     is 
   15960  1.1     is quick_scale22:
   15961  1.1     is 	andi.w		&0x8000,FP_SCR1_EX(%a6)	# zero dst exponent
   15962  1.1     is 	bset		&0x0,1+FP_SCR1_EX(%a6)	# set exp = 1
   15963  1.1     is 
   15964  1.1     is 	mov.l		(%sp)+,%d0		# return SCALE factor
   15965  1.1     is 	rts
   15966  1.1     is 
   15967  1.1     is ##########################################################################
   15968  1.1     is 
   15969  1.1     is #########################################################################
   15970  1.1     is # XDEF ****************************************************************	#
   15971  1.1     is #	scale_to_zero_src(): scale the exponent of extended precision	#
   15972  1.1     is #			     value at FP_SCR0(a6).			#
   15973  1.1     is #									#
   15974  1.1     is # XREF ****************************************************************	#
   15975  1.1     is #	norm() - normalize the mantissa if the operand was a DENORM	#
   15976  1.1     is #									#
   15977  1.1     is # INPUT ***************************************************************	#
   15978  1.1     is #	FP_SCR0(a6) = extended precision operand to be scaled		#
   15979  1.1     is # 									#
   15980  1.1     is # OUTPUT **************************************************************	#
   15981  1.1     is #	FP_SCR0(a6) = scaled extended precision operand			#
   15982  1.1     is #	d0	    = scale value					#
   15983  1.1     is #									#
   15984  1.1     is # ALGORITHM ***********************************************************	#
   15985  1.1     is # 	Set the exponent of the input operand to 0x3fff. Save the value	#
   15986  1.1     is # of the difference between the original and new exponent. Then, 	#
   15987  1.1     is # normalize the operand if it was a DENORM. Add this normalization	#
   15988  1.1     is # value to the previous value. Return the result.			#
   15989  1.1     is #									#
   15990  1.1     is #########################################################################
   15991  1.1     is 
   15992  1.1     is 	global		scale_to_zero_src
   15993  1.1     is scale_to_zero_src:
   15994  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# extract operand's {sgn,exp}
   15995  1.1     is 	mov.w		%d1,%d0			# make a copy
   15996  1.1     is 
   15997  1.1     is 	andi.l		&0x7fff,%d1		# extract operand's exponent
   15998  1.1     is 
   15999  1.1     is 	andi.w		&0x8000,%d0		# extract operand's sgn
   16000  1.1     is 	or.w		&0x3fff,%d0		# insert new operand's exponent(=0)
   16001  1.1     is 
   16002  1.1     is 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert biased exponent
   16003  1.1     is 
   16004  1.1     is 	cmpi.b		STAG(%a6),&DENORM	# is operand normalized?
   16005  1.1     is 	beq.b		stzs_denorm		# normalize the DENORM
   16006  1.1     is 
   16007  1.1     is stzs_norm:
   16008  1.1     is 	mov.l		&0x3fff,%d0
   16009  1.1     is 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16010  1.1     is 
   16011  1.1     is 	rts
   16012  1.1     is 
   16013  1.1     is stzs_denorm:
   16014  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass ptr to src op
   16015  1.1     is 	bsr.l		norm			# normalize denorm
   16016  1.1     is 	neg.l		%d0			# new exponent = -(shft val)
   16017  1.1     is 	mov.l		%d0,%d1			# prepare for op_norm call
   16018  1.1     is 	bra.b		stzs_norm		# finish scaling
   16019  1.1     is 
   16020  1.1     is ###
   16021  1.1     is 
   16022  1.1     is #########################################################################
   16023  1.1     is # XDEF ****************************************************************	#
   16024  1.1     is #	scale_sqrt(): scale the input operand exponent so a subsequent	#
   16025  1.1     is #		      fsqrt operation won't take an exception.		#
   16026  1.1     is #									#
   16027  1.1     is # XREF ****************************************************************	#
   16028  1.1     is #	norm() - normalize the mantissa if the operand was a DENORM	#
   16029  1.1     is #									#
   16030  1.1     is # INPUT ***************************************************************	#
   16031  1.1     is #	FP_SCR0(a6) = extended precision operand to be scaled		#
   16032  1.1     is # 									#
   16033  1.1     is # OUTPUT **************************************************************	#
   16034  1.1     is #	FP_SCR0(a6) = scaled extended precision operand			#
   16035  1.1     is #	d0	    = scale value					#
   16036  1.1     is #									#
   16037  1.1     is # ALGORITHM ***********************************************************	#
   16038  1.1     is #	If the input operand is a DENORM, normalize it.			#
   16039  1.1     is # 	If the exponent of the input operand is even, set the exponent	#
   16040  1.1     is # to 0x3ffe and return a scale factor of "(exp-0x3ffe)/2". If the 	#
   16041  1.1     is # exponent of the input operand is off, set the exponent to ox3fff and	#
   16042  1.1     is # return a scale factor of "(exp-0x3fff)/2". 				#
   16043  1.1     is #									#
   16044  1.1     is #########################################################################
   16045  1.1     is 
   16046  1.1     is 	global		scale_sqrt
   16047  1.1     is scale_sqrt:
   16048  1.1     is 	cmpi.b		STAG(%a6),&DENORM	# is operand normalized?
   16049  1.1     is 	beq.b		ss_denorm		# normalize the DENORM
   16050  1.1     is 
   16051  1.1     is 	mov.w		FP_SCR0_EX(%a6),%d1	# extract operand's {sgn,exp}
   16052  1.1     is 	andi.l		&0x7fff,%d1		# extract operand's exponent
   16053  1.1     is 
   16054  1.1     is 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# extract operand's sgn
   16055  1.1     is 
   16056  1.1     is 	btst		&0x0,%d1		# is exp even or odd?
   16057  1.1     is 	beq.b		ss_norm_even
   16058  1.1     is 
   16059  1.1     is 	ori.w		&0x3fff,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16060  1.1     is 
   16061  1.1     is 	mov.l		&0x3fff,%d0
   16062  1.1     is 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16063  1.1     is 	asr.l		&0x1,%d0		# divide scale factor by 2
   16064  1.1     is 	rts
   16065  1.1     is 
   16066  1.1     is ss_norm_even:
   16067  1.1     is 	ori.w		&0x3ffe,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16068  1.1     is 
   16069  1.1     is 	mov.l		&0x3ffe,%d0
   16070  1.1     is 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16071  1.1     is 	asr.l		&0x1,%d0		# divide scale factor by 2
   16072  1.1     is 	rts
   16073  1.1     is 
   16074  1.1     is ss_denorm:
   16075  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass ptr to src op
   16076  1.1     is 	bsr.l		norm			# normalize denorm
   16077  1.1     is 
   16078  1.1     is 	btst		&0x0,%d0		# is exp even or odd?
   16079  1.1     is 	beq.b		ss_denorm_even
   16080  1.1     is 
   16081  1.1     is 	ori.w		&0x3fff,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16082  1.1     is 
   16083  1.1     is 	add.l		&0x3fff,%d0
   16084  1.1     is 	asr.l		&0x1,%d0		# divide scale factor by 2
   16085  1.1     is 	rts
   16086  1.1     is 
   16087  1.1     is ss_denorm_even:
   16088  1.1     is 	ori.w		&0x3ffe,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16089  1.1     is 
   16090  1.1     is 	add.l		&0x3ffe,%d0
   16091  1.1     is 	asr.l		&0x1,%d0		# divide scale factor by 2
   16092  1.1     is 	rts
   16093  1.1     is 
   16094  1.1     is ###
   16095  1.1     is 
   16096  1.1     is #########################################################################
   16097  1.1     is # XDEF ****************************************************************	#
   16098  1.1     is #	scale_to_zero_dst(): scale the exponent of extended precision	#
   16099  1.1     is #			     value at FP_SCR1(a6).			#
   16100  1.1     is #									#
   16101  1.1     is # XREF ****************************************************************	#
   16102  1.1     is #	norm() - normalize the mantissa if the operand was a DENORM	#
   16103  1.1     is #									#
   16104  1.1     is # INPUT ***************************************************************	#
   16105  1.1     is #	FP_SCR1(a6) = extended precision operand to be scaled		#
   16106  1.1     is # 									#
   16107  1.1     is # OUTPUT **************************************************************	#
   16108  1.1     is #	FP_SCR1(a6) = scaled extended precision operand			#
   16109  1.1     is #	d0	    = scale value					#
   16110  1.1     is #									#
   16111  1.1     is # ALGORITHM ***********************************************************	#
   16112  1.1     is # 	Set the exponent of the input operand to 0x3fff. Save the value	#
   16113  1.1     is # of the difference between the original and new exponent. Then, 	#
   16114  1.1     is # normalize the operand if it was a DENORM. Add this normalization	#
   16115  1.1     is # value to the previous value. Return the result.			#
   16116  1.1     is #									#
   16117  1.1     is #########################################################################
   16118  1.1     is 
   16119  1.1     is 	global		scale_to_zero_dst
   16120  1.1     is scale_to_zero_dst:
   16121  1.1     is 	mov.w		FP_SCR1_EX(%a6),%d1	# extract operand's {sgn,exp}
   16122  1.1     is 	mov.w		%d1,%d0			# make a copy
   16123  1.1     is 
   16124  1.1     is 	andi.l		&0x7fff,%d1		# extract operand's exponent
   16125  1.1     is 
   16126  1.1     is 	andi.w		&0x8000,%d0		# extract operand's sgn
   16127  1.1     is 	or.w		&0x3fff,%d0		# insert new operand's exponent(=0)
   16128  1.1     is 
   16129  1.1     is 	mov.w		%d0,FP_SCR1_EX(%a6)	# insert biased exponent
   16130  1.1     is 
   16131  1.1     is 	cmpi.b		DTAG(%a6),&DENORM	# is operand normalized?
   16132  1.1     is 	beq.b		stzd_denorm		# normalize the DENORM
   16133  1.1     is 
   16134  1.1     is stzd_norm:
   16135  1.1     is 	mov.l		&0x3fff,%d0
   16136  1.1     is 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16137  1.1     is 	rts
   16138  1.1     is 
   16139  1.1     is stzd_denorm:
   16140  1.1     is 	lea		FP_SCR1(%a6),%a0	# pass ptr to dst op
   16141  1.1     is 	bsr.l		norm			# normalize denorm
   16142  1.1     is 	neg.l		%d0			# new exponent = -(shft val)
   16143  1.1     is 	mov.l		%d0,%d1			# prepare for op_norm call
   16144  1.1     is 	bra.b		stzd_norm		# finish scaling
   16145  1.1     is 
   16146  1.1     is ##########################################################################
   16147  1.1     is 
   16148  1.1     is #########################################################################
   16149  1.1     is # XDEF ****************************************************************	#
   16150  1.1     is #	res_qnan(): return default result w/ QNAN operand for dyadic	#
   16151  1.1     is #	res_snan(): return default result w/ SNAN operand for dyadic	#
   16152  1.1     is #	res_qnan_1op(): return dflt result w/ QNAN operand for monadic	#
   16153  1.1     is #	res_snan_1op(): return dflt result w/ SNAN operand for monadic	#
   16154  1.1     is #									#
   16155  1.1     is # XREF ****************************************************************	#
   16156  1.1     is #	None								#
   16157  1.1     is #									#
   16158  1.1     is # INPUT ***************************************************************	#
   16159  1.1     is #	FP_SRC(a6) = pointer to extended precision src operand		#
   16160  1.1     is #	FP_DST(a6) = pointer to extended precision dst operand		#
   16161  1.1     is # 									#
   16162  1.1     is # OUTPUT **************************************************************	#
   16163  1.1     is #	fp0 = default result						#
   16164  1.1     is #									#
   16165  1.1     is # ALGORITHM ***********************************************************	#
   16166  1.1     is # 	If either operand (but not both operands) of an operation is a	#
   16167  1.1     is # nonsignalling NAN, then that NAN is returned as the result. If both	#
   16168  1.1     is # operands are nonsignalling NANs, then the destination operand 	#
   16169  1.1     is # nonsignalling NAN is returned as the result.				#
   16170  1.1     is # 	If either operand to an operation is a signalling NAN (SNAN),	#
   16171  1.1     is # then, the SNAN bit is set in the FPSR EXC byte. If the SNAN trap	#
   16172  1.1     is # enable bit is set in the FPCR, then the trap is taken and the 	#
   16173  1.1     is # destination is not modified. If the SNAN trap enable bit is not set,	#
   16174  1.1     is # then the SNAN is converted to a nonsignalling NAN (by setting the 	#
   16175  1.1     is # SNAN bit in the operand to one), and the operation continues as 	#
   16176  1.1     is # described in the preceding paragraph, for nonsignalling NANs.		#
   16177  1.1     is #	Make sure the appropriate FPSR bits are set before exiting.	#
   16178  1.1     is #									#
   16179  1.1     is #########################################################################
   16180  1.1     is 
   16181  1.1     is 	global		res_qnan
   16182  1.1     is 	global		res_snan
   16183  1.1     is res_qnan:
   16184  1.1     is res_snan:
   16185  1.1     is 	cmp.b		DTAG(%a6), &SNAN	# is the dst an SNAN?
   16186  1.1     is 	beq.b		dst_snan2
   16187  1.1     is 	cmp.b		DTAG(%a6), &QNAN	# is the dst a  QNAN?
   16188  1.1     is 	beq.b		dst_qnan2
   16189  1.1     is src_nan:
   16190  1.1     is 	cmp.b		STAG(%a6), &QNAN
   16191  1.1     is 	beq.b		src_qnan2
   16192  1.1     is 	global		res_snan_1op
   16193  1.1     is res_snan_1op:
   16194  1.1     is src_snan2:
   16195  1.1     is 	bset		&0x6, FP_SRC_HI(%a6)	# set SNAN bit
   16196  1.1     is 	or.l		&nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
   16197  1.1     is 	lea		FP_SRC(%a6), %a0
   16198  1.1     is 	bra.b		nan_comp
   16199  1.1     is 	global		res_qnan_1op
   16200  1.1     is res_qnan_1op:
   16201  1.1     is src_qnan2:
   16202  1.1     is 	or.l		&nan_mask, USER_FPSR(%a6)
   16203  1.1     is 	lea		FP_SRC(%a6), %a0
   16204  1.1     is 	bra.b		nan_comp
   16205  1.1     is dst_snan2:
   16206  1.1     is 	or.l		&nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
   16207  1.1     is 	bset		&0x6, FP_DST_HI(%a6)	# set SNAN bit
   16208  1.1     is 	lea		FP_DST(%a6), %a0
   16209  1.1     is 	bra.b		nan_comp
   16210  1.1     is dst_qnan2:
   16211  1.1     is 	lea		FP_DST(%a6), %a0
   16212  1.1     is 	cmp.b		STAG(%a6), &SNAN
   16213  1.1     is 	bne		nan_done
   16214  1.1     is 	or.l		&aiop_mask+snan_mask, USER_FPSR(%a6)
   16215  1.1     is nan_done:
   16216  1.1     is 	or.l		&nan_mask, USER_FPSR(%a6)
   16217  1.1     is nan_comp:
   16218  1.1     is 	btst		&0x7, FTEMP_EX(%a0)	# is NAN neg?
   16219  1.1     is 	beq.b		nan_not_neg
   16220  1.1     is 	or.l		&neg_mask, USER_FPSR(%a6)
   16221  1.1     is nan_not_neg:
   16222  1.1     is 	fmovm.x		(%a0), &0x80
   16223  1.1     is 	rts
   16224  1.1     is 
   16225  1.1     is #########################################################################
   16226  1.1     is # XDEF ****************************************************************	#
   16227  1.1     is # 	res_operr(): return default result during operand error		#
   16228  1.1     is #									#
   16229  1.1     is # XREF ****************************************************************	#
   16230  1.1     is #	None								#
   16231  1.1     is #									#
   16232  1.1     is # INPUT ***************************************************************	#
   16233  1.1     is #	None								#
   16234  1.1     is # 									#
   16235  1.1     is # OUTPUT **************************************************************	#
   16236  1.1     is #	fp0 = default operand error result				#
   16237  1.1     is #									#
   16238  1.1     is # ALGORITHM ***********************************************************	#
   16239  1.1     is #	An nonsignalling NAN is returned as the default result when	#
   16240  1.1     is # an operand error occurs for the following cases:			#
   16241  1.1     is #									#
   16242  1.1     is # 	Multiply: (Infinity x Zero)					#
   16243  1.1     is # 	Divide  : (Zero / Zero) || (Infinity / Infinity)		#
   16244  1.1     is #									#
   16245  1.1     is #########################################################################
   16246  1.1     is 
   16247  1.1     is 	global		res_operr
   16248  1.1     is res_operr:
   16249  1.1     is 	or.l		&nan_mask+operr_mask+aiop_mask, USER_FPSR(%a6)
   16250  1.1     is 	fmovm.x		nan_return(%pc), &0x80
   16251  1.1     is 	rts
   16252  1.1     is 
   16253  1.1     is nan_return:
   16254  1.1     is 	long		0x7fff0000, 0xffffffff, 0xffffffff
   16255  1.1     is 
   16256  1.1     is #########################################################################
   16257  1.1     is # fdbcc(): routine to emulate the fdbcc instruction			#
   16258  1.1     is #									#
   16259  1.1     is # XDEF **************************************************************** #
   16260  1.1     is #	_fdbcc()							#
   16261  1.1     is #									#
   16262  1.1     is # XREF **************************************************************** #
   16263  1.1     is #	fetch_dreg() - fetch Dn value					#
   16264  1.1     is #	store_dreg_l() - store updated Dn value				#
   16265  1.1     is #									#
   16266  1.1     is # INPUT ***************************************************************	#
   16267  1.1     is #	d0 = displacement						#
   16268  1.1     is #									#
   16269  1.1     is # OUTPUT ************************************************************** #
   16270  1.1     is #	none								#
   16271  1.1     is #									#
   16272  1.1     is # ALGORITHM ***********************************************************	#
   16273  1.1     is #	This routine checks which conditional predicate is specified by	#
   16274  1.1     is # the stacked fdbcc instruction opcode and then branches to a routine	#
   16275  1.1     is # for that predicate. The corresponding fbcc instruction is then used	#
   16276  1.1     is # to see whether the condition (specified by the stacked FPSR) is true	#
   16277  1.1     is # or false.								#
   16278  1.1     is #	If a BSUN exception should be indicated, the BSUN and ABSUN	#
   16279  1.1     is # bits are set in the stacked FPSR. If the BSUN exception is enabled,	#
   16280  1.1     is # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an 	#
   16281  1.1     is # enabled BSUN should not be flagged and the predicate is true, then	#
   16282  1.1     is # Dn is fetched and decremented by one. If Dn is not equal to -1, add	#
   16283  1.1     is # the displacement value to the stacked PC so that when an "rte" is	#
   16284  1.1     is # finally executed, the branch occurs.					#
   16285  1.1     is #									#
   16286  1.1     is #########################################################################
   16287  1.1     is 	global		_fdbcc
   16288  1.1     is _fdbcc:
   16289  1.1     is 	mov.l		%d0,L_SCR1(%a6)		# save displacement
   16290  1.1     is 
   16291  1.1     is 	mov.w		EXC_CMDREG(%a6),%d0	# fetch predicate
   16292  1.1     is 
   16293  1.1     is 	clr.l		%d1			# clear scratch reg
   16294  1.1     is 	mov.b		FPSR_CC(%a6),%d1	# fetch fp ccodes
   16295  1.1     is 	ror.l		&0x8,%d1		# rotate to top byte
   16296  1.1     is 	fmov.l		%d1,%fpsr		# insert into FPSR
   16297  1.1     is 
   16298  1.1     is 	mov.w		(tbl_fdbcc.b,%pc,%d0.w*2),%d1 # load table
   16299  1.1     is 	jmp		(tbl_fdbcc.b,%pc,%d1.w) # jump to fdbcc routine
   16300  1.1     is 
   16301  1.1     is tbl_fdbcc:
   16302  1.1     is 	short		fdbcc_f		-	tbl_fdbcc	# 00
   16303  1.1     is 	short		fdbcc_eq	-	tbl_fdbcc	# 01
   16304  1.1     is 	short		fdbcc_ogt	-	tbl_fdbcc	# 02
   16305  1.1     is 	short		fdbcc_oge	-	tbl_fdbcc	# 03
   16306  1.1     is 	short		fdbcc_olt	-	tbl_fdbcc	# 04
   16307  1.1     is 	short		fdbcc_ole	-	tbl_fdbcc	# 05
   16308  1.1     is 	short		fdbcc_ogl	-	tbl_fdbcc	# 06
   16309  1.1     is 	short		fdbcc_or	-	tbl_fdbcc	# 07
   16310  1.1     is 	short		fdbcc_un	-	tbl_fdbcc	# 08
   16311  1.1     is 	short		fdbcc_ueq	-	tbl_fdbcc	# 09
   16312  1.1     is 	short		fdbcc_ugt	-	tbl_fdbcc	# 10
   16313  1.1     is 	short		fdbcc_uge	-	tbl_fdbcc	# 11
   16314  1.1     is 	short		fdbcc_ult	-	tbl_fdbcc	# 12
   16315  1.1     is 	short		fdbcc_ule	-	tbl_fdbcc	# 13
   16316  1.1     is 	short		fdbcc_neq	-	tbl_fdbcc	# 14
   16317  1.1     is 	short		fdbcc_t		-	tbl_fdbcc	# 15
   16318  1.1     is 	short		fdbcc_sf	-	tbl_fdbcc	# 16
   16319  1.1     is 	short		fdbcc_seq	-	tbl_fdbcc	# 17
   16320  1.1     is 	short		fdbcc_gt	-	tbl_fdbcc	# 18
   16321  1.1     is 	short		fdbcc_ge	-	tbl_fdbcc	# 19
   16322  1.1     is 	short		fdbcc_lt	-	tbl_fdbcc	# 20
   16323  1.1     is 	short		fdbcc_le	-	tbl_fdbcc	# 21
   16324  1.1     is 	short		fdbcc_gl	-	tbl_fdbcc	# 22
   16325  1.1     is 	short		fdbcc_gle	-	tbl_fdbcc	# 23
   16326  1.1     is 	short		fdbcc_ngle	-	tbl_fdbcc	# 24
   16327  1.1     is 	short		fdbcc_ngl	-	tbl_fdbcc	# 25
   16328  1.1     is 	short		fdbcc_nle	-	tbl_fdbcc	# 26
   16329  1.1     is 	short		fdbcc_nlt	-	tbl_fdbcc	# 27
   16330  1.1     is 	short		fdbcc_nge	-	tbl_fdbcc	# 28
   16331  1.1     is 	short		fdbcc_ngt	-	tbl_fdbcc	# 29
   16332  1.1     is 	short		fdbcc_sneq	-	tbl_fdbcc	# 30
   16333  1.1     is 	short		fdbcc_st	-	tbl_fdbcc	# 31
   16334  1.1     is 
   16335  1.1     is #########################################################################
   16336  1.1     is #									#
   16337  1.1     is # IEEE Nonaware tests							#
   16338  1.1     is #									#
   16339  1.1     is # For the IEEE nonaware tests, only the false branch changes the 	#
   16340  1.1     is # counter. However, the true branch may set bsun so we check to see	#
   16341  1.1     is # if the NAN bit is set, in which case BSUN and AIOP will be set.	#
   16342  1.1     is #									#
   16343  1.1     is # The cases EQ and NE are shared by the Aware and Nonaware groups	#
   16344  1.1     is # and are incapable of setting the BSUN exception bit.			#
   16345  1.1     is #									#
   16346  1.1     is # Typically, only one of the two possible branch directions could	#
   16347  1.1     is # have the NAN bit set.							#
   16348  1.1     is # (This is assuming the mutual exclusiveness of FPSR cc bit groupings	#
   16349  1.1     is #  is preserved.)							#
   16350  1.1     is #									#
   16351  1.1     is #########################################################################
   16352  1.1     is 
   16353  1.1     is #
   16354  1.1     is # equal:
   16355  1.1     is #
   16356  1.1     is #	Z
   16357  1.1     is #
   16358  1.1     is fdbcc_eq:
   16359  1.1     is 	fbeq.w		fdbcc_eq_yes		# equal?
   16360  1.1     is fdbcc_eq_no:
   16361  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16362  1.1     is fdbcc_eq_yes:
   16363  1.1     is 	rts
   16364  1.1     is 
   16365  1.1     is #
   16366  1.1     is # not equal:
   16367  1.1     is #	_
   16368  1.1     is #	Z
   16369  1.1     is #
   16370  1.1     is fdbcc_neq:
   16371  1.1     is 	fbneq.w		fdbcc_neq_yes		# not equal?
   16372  1.1     is fdbcc_neq_no:
   16373  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16374  1.1     is fdbcc_neq_yes:
   16375  1.1     is 	rts
   16376  1.1     is 
   16377  1.1     is #
   16378  1.1     is # greater than:
   16379  1.1     is #	_______
   16380  1.1     is #	NANvZvN
   16381  1.1     is #
   16382  1.1     is fdbcc_gt:
   16383  1.1     is 	fbgt.w		fdbcc_gt_yes		# greater than?
   16384  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16385  1.1     is 	beq.w		fdbcc_false		# no;go handle counter
   16386  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16387  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16388  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16389  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16390  1.1     is fdbcc_gt_yes:
   16391  1.1     is 	rts					# do nothing
   16392  1.1     is 
   16393  1.1     is #
   16394  1.1     is # not greater than:
   16395  1.1     is #
   16396  1.1     is #	NANvZvN
   16397  1.1     is #
   16398  1.1     is fdbcc_ngt:
   16399  1.1     is 	fbngt.w		fdbcc_ngt_yes		# not greater than?
   16400  1.1     is fdbcc_ngt_no:
   16401  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16402  1.1     is fdbcc_ngt_yes:
   16403  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16404  1.1     is 	beq.b		fdbcc_ngt_done		# no;go finish
   16405  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16406  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16407  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16408  1.1     is fdbcc_ngt_done:
   16409  1.1     is 	rts					# no; do nothing
   16410  1.1     is 
   16411  1.1     is #
   16412  1.1     is # greater than or equal:
   16413  1.1     is #	   _____
   16414  1.1     is #	Zv(NANvN)
   16415  1.1     is #
   16416  1.1     is fdbcc_ge:
   16417  1.1     is 	fbge.w		fdbcc_ge_yes		# greater than or equal?
   16418  1.1     is fdbcc_ge_no:
   16419  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16420  1.1     is 	beq.w		fdbcc_false		# no;go handle counter
   16421  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16422  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16423  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16424  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16425  1.1     is fdbcc_ge_yes:
   16426  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16427  1.1     is 	beq.b		fdbcc_ge_yes_done	# no;go do nothing
   16428  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16429  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16430  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16431  1.1     is fdbcc_ge_yes_done:
   16432  1.1     is 	rts					# do nothing
   16433  1.1     is 
   16434  1.1     is #
   16435  1.1     is # not (greater than or equal):
   16436  1.1     is #	       _
   16437  1.1     is #	NANv(N^Z)
   16438  1.1     is #
   16439  1.1     is fdbcc_nge:
   16440  1.1     is 	fbnge.w		fdbcc_nge_yes		# not (greater than or equal)?
   16441  1.1     is fdbcc_nge_no:
   16442  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16443  1.1     is fdbcc_nge_yes:
   16444  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16445  1.1     is 	beq.b		fdbcc_nge_done		# no;go finish
   16446  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16447  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16448  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16449  1.1     is fdbcc_nge_done:
   16450  1.1     is 	rts					# no; do nothing
   16451  1.1     is 
   16452  1.1     is #
   16453  1.1     is # less than:
   16454  1.1     is #	   _____
   16455  1.1     is #	N^(NANvZ)
   16456  1.1     is #
   16457  1.1     is fdbcc_lt:
   16458  1.1     is 	fblt.w		fdbcc_lt_yes		# less than?
   16459  1.1     is fdbcc_lt_no:
   16460  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16461  1.1     is 	beq.w		fdbcc_false		# no; go handle counter
   16462  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16463  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16464  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16465  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16466  1.1     is fdbcc_lt_yes:
   16467  1.1     is 	rts					# do nothing
   16468  1.1     is 
   16469  1.1     is #
   16470  1.1     is # not less than:
   16471  1.1     is #	       _
   16472  1.1     is #	NANv(ZvN)
   16473  1.1     is #
   16474  1.1     is fdbcc_nlt:
   16475  1.1     is 	fbnlt.w		fdbcc_nlt_yes		# not less than?
   16476  1.1     is fdbcc_nlt_no:
   16477  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16478  1.1     is fdbcc_nlt_yes:
   16479  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16480  1.1     is 	beq.b		fdbcc_nlt_done		# no;go finish
   16481  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16482  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16483  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16484  1.1     is fdbcc_nlt_done:
   16485  1.1     is 	rts					# no; do nothing
   16486  1.1     is 
   16487  1.1     is #
   16488  1.1     is # less than or equal:
   16489  1.1     is #	     ___
   16490  1.1     is #	Zv(N^NAN)
   16491  1.1     is #
   16492  1.1     is fdbcc_le:
   16493  1.1     is 	fble.w		fdbcc_le_yes		# less than or equal?
   16494  1.1     is fdbcc_le_no:
   16495  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16496  1.1     is 	beq.w		fdbcc_false		# no; go handle counter
   16497  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16498  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16499  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16500  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16501  1.1     is fdbcc_le_yes:
   16502  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16503  1.1     is 	beq.b		fdbcc_le_yes_done	# no; go do nothing
   16504  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16505  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16506  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16507  1.1     is fdbcc_le_yes_done:
   16508  1.1     is 	rts					# do nothing
   16509  1.1     is 
   16510  1.1     is #
   16511  1.1     is # not (less than or equal):
   16512  1.1     is #	     ___
   16513  1.1     is #	NANv(NvZ)
   16514  1.1     is #
   16515  1.1     is fdbcc_nle:
   16516  1.1     is 	fbnle.w		fdbcc_nle_yes		# not (less than or equal)?
   16517  1.1     is fdbcc_nle_no:
   16518  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16519  1.1     is fdbcc_nle_yes:
   16520  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16521  1.1     is 	beq.w		fdbcc_nle_done		# no; go finish
   16522  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16523  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16524  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16525  1.1     is fdbcc_nle_done:
   16526  1.1     is 	rts					# no; do nothing
   16527  1.1     is 
   16528  1.1     is #
   16529  1.1     is # greater or less than:
   16530  1.1     is #	_____
   16531  1.1     is #	NANvZ
   16532  1.1     is #
   16533  1.1     is fdbcc_gl:
   16534  1.1     is 	fbgl.w		fdbcc_gl_yes		# greater or less than?
   16535  1.1     is fdbcc_gl_no:
   16536  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16537  1.1     is 	beq.w		fdbcc_false		# no; handle counter
   16538  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16539  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16540  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16541  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16542  1.1     is fdbcc_gl_yes:
   16543  1.1     is 	rts					# do nothing
   16544  1.1     is 
   16545  1.1     is #
   16546  1.1     is # not (greater or less than):
   16547  1.1     is #
   16548  1.1     is #	NANvZ
   16549  1.1     is #
   16550  1.1     is fdbcc_ngl:
   16551  1.1     is 	fbngl.w		fdbcc_ngl_yes		# not (greater or less than)?
   16552  1.1     is fdbcc_ngl_no:
   16553  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16554  1.1     is fdbcc_ngl_yes:
   16555  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16556  1.1     is 	beq.b		fdbcc_ngl_done		# no; go finish
   16557  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16558  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16559  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16560  1.1     is fdbcc_ngl_done:
   16561  1.1     is 	rts					# no; do nothing
   16562  1.1     is 
   16563  1.1     is #
   16564  1.1     is # greater, less, or equal:
   16565  1.1     is #	___
   16566  1.1     is #	NAN
   16567  1.1     is #
   16568  1.1     is fdbcc_gle:
   16569  1.1     is 	fbgle.w		fdbcc_gle_yes		# greater, less, or equal?
   16570  1.1     is fdbcc_gle_no:
   16571  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16572  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16573  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16574  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16575  1.1     is fdbcc_gle_yes:
   16576  1.1     is 	rts					# do nothing
   16577  1.1     is 
   16578  1.1     is #
   16579  1.1     is # not (greater, less, or equal):
   16580  1.1     is #
   16581  1.1     is #	NAN
   16582  1.1     is #
   16583  1.1     is fdbcc_ngle:
   16584  1.1     is 	fbngle.w	fdbcc_ngle_yes		# not (greater, less, or equal)?
   16585  1.1     is fdbcc_ngle_no:
   16586  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16587  1.1     is fdbcc_ngle_yes:
   16588  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16589  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16590  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16591  1.1     is 	rts					# no; do nothing
   16592  1.1     is 
   16593  1.1     is #########################################################################
   16594  1.1     is #									#
   16595  1.1     is # Miscellaneous tests							#
   16596  1.1     is #									#
   16597  1.1     is # For the IEEE miscellaneous tests, all but fdbf and fdbt can set bsun. #
   16598  1.1     is #									#
   16599  1.1     is #########################################################################
   16600  1.1     is 
   16601  1.1     is #
   16602  1.1     is # false:
   16603  1.1     is #
   16604  1.1     is #	False
   16605  1.1     is #
   16606  1.1     is fdbcc_f:					# no bsun possible
   16607  1.1     is 	bra.w		fdbcc_false		# go handle counter
   16608  1.1     is 
   16609  1.1     is #
   16610  1.1     is # true:
   16611  1.1     is #
   16612  1.1     is #	True
   16613  1.1     is #
   16614  1.1     is fdbcc_t:					# no bsun possible
   16615  1.1     is 	rts					# do nothing
   16616  1.1     is 
   16617  1.1     is #
   16618  1.1     is # signalling false:
   16619  1.1     is #
   16620  1.1     is #	False
   16621  1.1     is #
   16622  1.1     is fdbcc_sf:
   16623  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16624  1.1     is 	beq.w		fdbcc_false		# no;go handle counter
   16625  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16626  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16627  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16628  1.1     is 	bra.w		fdbcc_false		# go handle counter
   16629  1.1     is 
   16630  1.1     is #
   16631  1.1     is # signalling true:
   16632  1.1     is #
   16633  1.1     is #	True
   16634  1.1     is #
   16635  1.1     is fdbcc_st:
   16636  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16637  1.1     is 	beq.b		fdbcc_st_done		# no;go finish
   16638  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16639  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16640  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16641  1.1     is fdbcc_st_done:
   16642  1.1     is 	rts
   16643  1.1     is 
   16644  1.1     is #
   16645  1.1     is # signalling equal:
   16646  1.1     is #
   16647  1.1     is #	Z
   16648  1.1     is #
   16649  1.1     is fdbcc_seq:
   16650  1.1     is 	fbseq.w		fdbcc_seq_yes		# signalling equal?
   16651  1.1     is fdbcc_seq_no:
   16652  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16653  1.1     is 	beq.w		fdbcc_false		# no;go handle counter
   16654  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16655  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16656  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16657  1.1     is 	bra.w		fdbcc_false		# go handle counter
   16658  1.1     is fdbcc_seq_yes:
   16659  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16660  1.1     is 	beq.b		fdbcc_seq_yes_done	# no;go do nothing
   16661  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16662  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16663  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16664  1.1     is fdbcc_seq_yes_done:
   16665  1.1     is 	rts					# yes; do nothing
   16666  1.1     is 
   16667  1.1     is #
   16668  1.1     is # signalling not equal:
   16669  1.1     is #	_
   16670  1.1     is #	Z
   16671  1.1     is #
   16672  1.1     is fdbcc_sneq:
   16673  1.1     is 	fbsneq.w	fdbcc_sneq_yes		# signalling not equal?
   16674  1.1     is fdbcc_sneq_no:
   16675  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16676  1.1     is 	beq.w		fdbcc_false		# no;go handle counter
   16677  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16678  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16679  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16680  1.1     is 	bra.w		fdbcc_false		# go handle counter
   16681  1.1     is fdbcc_sneq_yes:
   16682  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   16683  1.1     is 	beq.w		fdbcc_sneq_done		# no;go finish
   16684  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16685  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16686  1.1     is 	bne.w		fdbcc_bsun		# yes; we have an exception
   16687  1.1     is fdbcc_sneq_done:
   16688  1.1     is 	rts
   16689  1.1     is 
   16690  1.1     is #########################################################################
   16691  1.1     is #									#
   16692  1.1     is # IEEE Aware tests							#
   16693  1.1     is #									#
   16694  1.1     is # For the IEEE aware tests, action is only taken if the result is false.#
   16695  1.1     is # Therefore, the opposite branch type is used to jump to the decrement	#
   16696  1.1     is # routine. 								#
   16697  1.1     is # The BSUN exception will not be set for any of these tests.		#
   16698  1.1     is #									#
   16699  1.1     is #########################################################################
   16700  1.1     is 
   16701  1.1     is #
   16702  1.1     is # ordered greater than:
   16703  1.1     is #	_______
   16704  1.1     is #	NANvZvN
   16705  1.1     is #
   16706  1.1     is fdbcc_ogt:
   16707  1.1     is 	fbogt.w		fdbcc_ogt_yes		# ordered greater than?
   16708  1.1     is fdbcc_ogt_no:
   16709  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16710  1.1     is fdbcc_ogt_yes:
   16711  1.1     is 	rts					# yes; do nothing
   16712  1.1     is 
   16713  1.1     is #
   16714  1.1     is # unordered or less or equal:
   16715  1.1     is #	_______
   16716  1.1     is #	NANvZvN
   16717  1.1     is #
   16718  1.1     is fdbcc_ule:
   16719  1.1     is 	fbule.w		fdbcc_ule_yes		# unordered or less or equal?
   16720  1.1     is fdbcc_ule_no:
   16721  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16722  1.1     is fdbcc_ule_yes:
   16723  1.1     is 	rts					# yes; do nothing
   16724  1.1     is 
   16725  1.1     is #
   16726  1.1     is # ordered greater than or equal:
   16727  1.1     is #	   _____
   16728  1.1     is #	Zv(NANvN)
   16729  1.1     is #
   16730  1.1     is fdbcc_oge:
   16731  1.1     is 	fboge.w		fdbcc_oge_yes		# ordered greater than or equal?
   16732  1.1     is fdbcc_oge_no:
   16733  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16734  1.1     is fdbcc_oge_yes:
   16735  1.1     is 	rts					# yes; do nothing
   16736  1.1     is 
   16737  1.1     is #
   16738  1.1     is # unordered or less than:
   16739  1.1     is #	       _
   16740  1.1     is #	NANv(N^Z)
   16741  1.1     is #
   16742  1.1     is fdbcc_ult:
   16743  1.1     is 	fbult.w		fdbcc_ult_yes		# unordered or less than?
   16744  1.1     is fdbcc_ult_no:
   16745  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16746  1.1     is fdbcc_ult_yes:
   16747  1.1     is 	rts					# yes; do nothing
   16748  1.1     is 
   16749  1.1     is #
   16750  1.1     is # ordered less than:
   16751  1.1     is #	   _____
   16752  1.1     is #	N^(NANvZ)
   16753  1.1     is #
   16754  1.1     is fdbcc_olt:
   16755  1.1     is 	fbolt.w		fdbcc_olt_yes		# ordered less than?
   16756  1.1     is fdbcc_olt_no:
   16757  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16758  1.1     is fdbcc_olt_yes:
   16759  1.1     is 	rts					# yes; do nothing
   16760  1.1     is 
   16761  1.1     is #
   16762  1.1     is # unordered or greater or equal:
   16763  1.1     is #
   16764  1.1     is #	NANvZvN
   16765  1.1     is #
   16766  1.1     is fdbcc_uge:
   16767  1.1     is 	fbuge.w		fdbcc_uge_yes		# unordered or greater than?
   16768  1.1     is fdbcc_uge_no:
   16769  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16770  1.1     is fdbcc_uge_yes:
   16771  1.1     is 	rts					# yes; do nothing
   16772  1.1     is 
   16773  1.1     is #
   16774  1.1     is # ordered less than or equal:
   16775  1.1     is #	     ___
   16776  1.1     is #	Zv(N^NAN)
   16777  1.1     is #
   16778  1.1     is fdbcc_ole:
   16779  1.1     is 	fbole.w		fdbcc_ole_yes		# ordered greater or less than?
   16780  1.1     is fdbcc_ole_no:
   16781  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16782  1.1     is fdbcc_ole_yes:
   16783  1.1     is 	rts					# yes; do nothing
   16784  1.1     is 
   16785  1.1     is #
   16786  1.1     is # unordered or greater than:
   16787  1.1     is #	     ___
   16788  1.1     is #	NANv(NvZ)
   16789  1.1     is #
   16790  1.1     is fdbcc_ugt:
   16791  1.1     is 	fbugt.w		fdbcc_ugt_yes		# unordered or greater than?
   16792  1.1     is fdbcc_ugt_no:
   16793  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16794  1.1     is fdbcc_ugt_yes:
   16795  1.1     is 	rts					# yes; do nothing
   16796  1.1     is 
   16797  1.1     is #
   16798  1.1     is # ordered greater or less than:
   16799  1.1     is #	_____
   16800  1.1     is #	NANvZ
   16801  1.1     is #
   16802  1.1     is fdbcc_ogl:
   16803  1.1     is 	fbogl.w		fdbcc_ogl_yes		# ordered greater or less than?
   16804  1.1     is fdbcc_ogl_no:
   16805  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16806  1.1     is fdbcc_ogl_yes:
   16807  1.1     is 	rts					# yes; do nothing
   16808  1.1     is 
   16809  1.1     is #
   16810  1.1     is # unordered or equal:
   16811  1.1     is #
   16812  1.1     is #	NANvZ
   16813  1.1     is #
   16814  1.1     is fdbcc_ueq:
   16815  1.1     is 	fbueq.w		fdbcc_ueq_yes		# unordered or equal?
   16816  1.1     is fdbcc_ueq_no:
   16817  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16818  1.1     is fdbcc_ueq_yes:
   16819  1.1     is 	rts					# yes; do nothing
   16820  1.1     is 
   16821  1.1     is #
   16822  1.1     is # ordered:
   16823  1.1     is #	___
   16824  1.1     is #	NAN
   16825  1.1     is #
   16826  1.1     is fdbcc_or:
   16827  1.1     is 	fbor.w		fdbcc_or_yes		# ordered?
   16828  1.1     is fdbcc_or_no:
   16829  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16830  1.1     is fdbcc_or_yes:
   16831  1.1     is 	rts					# yes; do nothing
   16832  1.1     is 
   16833  1.1     is #
   16834  1.1     is # unordered:
   16835  1.1     is #
   16836  1.1     is #	NAN
   16837  1.1     is #
   16838  1.1     is fdbcc_un:
   16839  1.1     is 	fbun.w		fdbcc_un_yes		# unordered?
   16840  1.1     is fdbcc_un_no:
   16841  1.1     is 	bra.w		fdbcc_false		# no; go handle counter
   16842  1.1     is fdbcc_un_yes:
   16843  1.1     is 	rts					# yes; do nothing
   16844  1.1     is 
   16845  1.1     is #######################################################################
   16846  1.1     is 
   16847  1.1     is #
   16848  1.1     is # the bsun exception bit was not set.
   16849  1.1     is #
   16850  1.1     is # (1) subtract 1 from the count register
   16851  1.1     is # (2) if (cr == -1) then
   16852  1.1     is #	pc = pc of next instruction
   16853  1.1     is #     else
   16854  1.1     is #	pc += sign_ext(16-bit displacement)
   16855  1.1     is #
   16856  1.1     is fdbcc_false:
   16857  1.1     is 	mov.b		1+EXC_OPWORD(%a6), %d1	# fetch lo opword
   16858  1.1     is 	andi.w		&0x7, %d1		# extract count register
   16859  1.1     is 
   16860  1.1     is 	bsr.l		fetch_dreg		# fetch count value
   16861  1.1     is # make sure that d0 isn't corrupted between calls...
   16862  1.1     is 
   16863  1.1     is 	subq.w		&0x1, %d0		# Dn - 1 -> Dn
   16864  1.1     is 
   16865  1.1     is 	bsr.l		store_dreg_l		# store new count value
   16866  1.1     is 
   16867  1.1     is 	cmpi.w		%d0, &-0x1		# is (Dn == -1)?
   16868  1.1     is 	bne.b		fdbcc_false_cont	# no;
   16869  1.1     is 	rts
   16870  1.1     is 
   16871  1.1     is fdbcc_false_cont:
   16872  1.1     is 	mov.l		L_SCR1(%a6),%d0		# fetch displacement
   16873  1.1     is 	add.l		USER_FPIAR(%a6),%d0	# add instruction PC
   16874  1.1     is 	addq.l		&0x4,%d0		# add instruction length
   16875  1.1     is 	mov.l		%d0,EXC_PC(%a6)		# set new PC
   16876  1.1     is 	rts
   16877  1.1     is 
   16878  1.1     is # the emulation routine set bsun and BSUN was enabled. have to
   16879  1.1     is # fix stack and jump to the bsun handler.
   16880  1.1     is # let the caller of this routine shift the stack frame up to
   16881  1.1     is # eliminate the effective address field.
   16882  1.1     is fdbcc_bsun:
   16883  1.1     is 	mov.b		&fbsun_flg,SPCOND_FLG(%a6)
   16884  1.1     is 	rts
   16885  1.1     is 
   16886  1.1     is #########################################################################
   16887  1.1     is # ftrapcc(): routine to emulate the ftrapcc instruction			#
   16888  1.1     is #									#
   16889  1.1     is # XDEF ****************************************************************	#
   16890  1.1     is #	_ftrapcc()							#
   16891  1.1     is #									#
   16892  1.1     is # XREF ****************************************************************	#
   16893  1.1     is #	none								#
   16894  1.1     is #									#
   16895  1.1     is # INPUT *************************************************************** #
   16896  1.1     is #	none								#
   16897  1.1     is #									#
   16898  1.1     is # OUTPUT ************************************************************** #
   16899  1.1     is #	none								#
   16900  1.1     is #									#
   16901  1.1     is # ALGORITHM *********************************************************** #
   16902  1.1     is #	This routine checks which conditional predicate is specified by	#
   16903  1.1     is # the stacked ftrapcc instruction opcode and then branches to a routine	#
   16904  1.1     is # for that predicate. The corresponding fbcc instruction is then used	#
   16905  1.1     is # to see whether the condition (specified by the stacked FPSR) is true	#
   16906  1.1     is # or false.								#
   16907  1.1     is #	If a BSUN exception should be indicated, the BSUN and ABSUN	#
   16908  1.1     is # bits are set in the stacked FPSR. If the BSUN exception is enabled,	#
   16909  1.1     is # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an 	#
   16910  1.1     is # enabled BSUN should not be flagged and the predicate is true, then	#
   16911  1.1     is # the ftrapcc_flg is set in the SPCOND_FLG location. These special	#
   16912  1.1     is # flags indicate to the calling routine to emulate the exceptional	#
   16913  1.1     is # condition.								#
   16914  1.1     is #									#
   16915  1.1     is #########################################################################
   16916  1.1     is 
   16917  1.1     is 	global		_ftrapcc
   16918  1.1     is _ftrapcc:
   16919  1.1     is 	mov.w		EXC_CMDREG(%a6),%d0	# fetch predicate
   16920  1.1     is 
   16921  1.1     is 	clr.l		%d1			# clear scratch reg
   16922  1.1     is 	mov.b		FPSR_CC(%a6),%d1	# fetch fp ccodes
   16923  1.1     is 	ror.l		&0x8,%d1		# rotate to top byte
   16924  1.1     is 	fmov.l		%d1,%fpsr		# insert into FPSR
   16925  1.1     is 
   16926  1.1     is 	mov.w		(tbl_ftrapcc.b,%pc,%d0.w*2), %d1 # load table
   16927  1.1     is 	jmp		(tbl_ftrapcc.b,%pc,%d1.w) # jump to ftrapcc routine
   16928  1.1     is 
   16929  1.1     is tbl_ftrapcc:
   16930  1.1     is 	short		ftrapcc_f	-	tbl_ftrapcc	# 00
   16931  1.1     is 	short		ftrapcc_eq	-	tbl_ftrapcc	# 01
   16932  1.1     is 	short		ftrapcc_ogt	-	tbl_ftrapcc	# 02
   16933  1.1     is 	short		ftrapcc_oge	-	tbl_ftrapcc	# 03
   16934  1.1     is 	short		ftrapcc_olt	-	tbl_ftrapcc	# 04
   16935  1.1     is 	short		ftrapcc_ole	-	tbl_ftrapcc	# 05
   16936  1.1     is 	short		ftrapcc_ogl	-	tbl_ftrapcc	# 06
   16937  1.1     is 	short		ftrapcc_or	-	tbl_ftrapcc	# 07
   16938  1.1     is 	short		ftrapcc_un	-	tbl_ftrapcc	# 08
   16939  1.1     is 	short		ftrapcc_ueq	-	tbl_ftrapcc	# 09
   16940  1.1     is 	short		ftrapcc_ugt	-	tbl_ftrapcc	# 10
   16941  1.1     is 	short		ftrapcc_uge	-	tbl_ftrapcc	# 11
   16942  1.1     is 	short		ftrapcc_ult	-	tbl_ftrapcc	# 12
   16943  1.1     is 	short		ftrapcc_ule	-	tbl_ftrapcc	# 13
   16944  1.1     is 	short		ftrapcc_neq	-	tbl_ftrapcc	# 14
   16945  1.1     is 	short		ftrapcc_t	-	tbl_ftrapcc	# 15
   16946  1.1     is 	short		ftrapcc_sf	-	tbl_ftrapcc	# 16
   16947  1.1     is 	short		ftrapcc_seq	-	tbl_ftrapcc	# 17
   16948  1.1     is 	short		ftrapcc_gt	-	tbl_ftrapcc	# 18
   16949  1.1     is 	short		ftrapcc_ge	-	tbl_ftrapcc	# 19
   16950  1.1     is 	short		ftrapcc_lt	-	tbl_ftrapcc	# 20
   16951  1.1     is 	short		ftrapcc_le	-	tbl_ftrapcc	# 21
   16952  1.1     is 	short		ftrapcc_gl	-	tbl_ftrapcc	# 22
   16953  1.1     is 	short		ftrapcc_gle	-	tbl_ftrapcc	# 23
   16954  1.1     is 	short		ftrapcc_ngle	-	tbl_ftrapcc	# 24
   16955  1.1     is 	short		ftrapcc_ngl	-	tbl_ftrapcc	# 25
   16956  1.1     is 	short		ftrapcc_nle	-	tbl_ftrapcc	# 26
   16957  1.1     is 	short		ftrapcc_nlt	-	tbl_ftrapcc	# 27
   16958  1.1     is 	short		ftrapcc_nge	-	tbl_ftrapcc	# 28
   16959  1.1     is 	short		ftrapcc_ngt	-	tbl_ftrapcc	# 29
   16960  1.1     is 	short		ftrapcc_sneq	-	tbl_ftrapcc	# 30
   16961  1.1     is 	short		ftrapcc_st	-	tbl_ftrapcc	# 31
   16962  1.1     is 
   16963  1.1     is #########################################################################
   16964  1.1     is #									#
   16965  1.1     is # IEEE Nonaware tests							#
   16966  1.1     is #									#
   16967  1.1     is # For the IEEE nonaware tests, we set the result based on the		#
   16968  1.1     is # floating point condition codes. In addition, we check to see		#
   16969  1.1     is # if the NAN bit is set, in which case BSUN and AIOP will be set.	#
   16970  1.1     is #									#
   16971  1.1     is # The cases EQ and NE are shared by the Aware and Nonaware groups	#
   16972  1.1     is # and are incapable of setting the BSUN exception bit.			#
   16973  1.1     is #									#
   16974  1.1     is # Typically, only one of the two possible branch directions could	#
   16975  1.1     is # have the NAN bit set.							#
   16976  1.1     is #									#
   16977  1.1     is #########################################################################
   16978  1.1     is 
   16979  1.1     is #
   16980  1.1     is # equal:
   16981  1.1     is #
   16982  1.1     is #	Z
   16983  1.1     is #
   16984  1.1     is ftrapcc_eq:
   16985  1.1     is 	fbeq.w		ftrapcc_trap		# equal?
   16986  1.1     is ftrapcc_eq_no:
   16987  1.1     is 	rts					# do nothing
   16988  1.1     is 
   16989  1.1     is #
   16990  1.1     is # not equal:
   16991  1.1     is #	_
   16992  1.1     is #	Z
   16993  1.1     is #
   16994  1.1     is ftrapcc_neq:
   16995  1.1     is 	fbneq.w		ftrapcc_trap		# not equal?
   16996  1.1     is ftrapcc_neq_no:
   16997  1.1     is 	rts					# do nothing
   16998  1.1     is 
   16999  1.1     is #
   17000  1.1     is # greater than:
   17001  1.1     is #	_______
   17002  1.1     is #	NANvZvN
   17003  1.1     is #
   17004  1.1     is ftrapcc_gt:
   17005  1.1     is 	fbgt.w		ftrapcc_trap		# greater than?
   17006  1.1     is ftrapcc_gt_no:
   17007  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17008  1.1     is 	beq.b		ftrapcc_gt_done		# no
   17009  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17010  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17011  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17012  1.1     is ftrapcc_gt_done:
   17013  1.1     is 	rts					# no; do nothing
   17014  1.1     is 
   17015  1.1     is #
   17016  1.1     is # not greater than:
   17017  1.1     is #
   17018  1.1     is #	NANvZvN
   17019  1.1     is #
   17020  1.1     is ftrapcc_ngt:
   17021  1.1     is 	fbngt.w		ftrapcc_ngt_yes		# not greater than?
   17022  1.1     is ftrapcc_ngt_no:
   17023  1.1     is 	rts					# do nothing
   17024  1.1     is ftrapcc_ngt_yes:
   17025  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17026  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17027  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17028  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17029  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17030  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17031  1.1     is 
   17032  1.1     is #
   17033  1.1     is # greater than or equal:
   17034  1.1     is #	   _____
   17035  1.1     is #	Zv(NANvN)
   17036  1.1     is #
   17037  1.1     is ftrapcc_ge:
   17038  1.1     is 	fbge.w		ftrapcc_ge_yes		# greater than or equal?
   17039  1.1     is ftrapcc_ge_no:
   17040  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17041  1.1     is 	beq.b		ftrapcc_ge_done		# no; go finish
   17042  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17043  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17044  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17045  1.1     is ftrapcc_ge_done:
   17046  1.1     is 	rts					# no; do nothing
   17047  1.1     is ftrapcc_ge_yes:
   17048  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17049  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17050  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17051  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17052  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17053  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17054  1.1     is 
   17055  1.1     is #
   17056  1.1     is # not (greater than or equal):
   17057  1.1     is #	       _
   17058  1.1     is #	NANv(N^Z)
   17059  1.1     is #
   17060  1.1     is ftrapcc_nge:
   17061  1.1     is 	fbnge.w		ftrapcc_nge_yes		# not (greater than or equal)?
   17062  1.1     is ftrapcc_nge_no:
   17063  1.1     is 	rts					# do nothing
   17064  1.1     is ftrapcc_nge_yes:
   17065  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17066  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17067  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17068  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17069  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17070  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17071  1.1     is 
   17072  1.1     is #
   17073  1.1     is # less than:
   17074  1.1     is #	   _____
   17075  1.1     is #	N^(NANvZ)
   17076  1.1     is #
   17077  1.1     is ftrapcc_lt:
   17078  1.1     is 	fblt.w		ftrapcc_trap		# less than?
   17079  1.1     is ftrapcc_lt_no:
   17080  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17081  1.1     is 	beq.b		ftrapcc_lt_done		# no; go finish
   17082  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17083  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17084  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17085  1.1     is ftrapcc_lt_done:
   17086  1.1     is 	rts					# no; do nothing
   17087  1.1     is 
   17088  1.1     is #
   17089  1.1     is # not less than:
   17090  1.1     is #	       _
   17091  1.1     is #	NANv(ZvN)
   17092  1.1     is #
   17093  1.1     is ftrapcc_nlt:
   17094  1.1     is 	fbnlt.w		ftrapcc_nlt_yes		# not less than?
   17095  1.1     is ftrapcc_nlt_no:
   17096  1.1     is 	rts					# do nothing
   17097  1.1     is ftrapcc_nlt_yes:
   17098  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17099  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17100  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17101  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17102  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17103  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17104  1.1     is 
   17105  1.1     is #
   17106  1.1     is # less than or equal:
   17107  1.1     is #	     ___
   17108  1.1     is #	Zv(N^NAN)
   17109  1.1     is #
   17110  1.1     is ftrapcc_le:
   17111  1.1     is 	fble.w		ftrapcc_le_yes		# less than or equal?
   17112  1.1     is ftrapcc_le_no:
   17113  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17114  1.1     is 	beq.b		ftrapcc_le_done		# no; go finish
   17115  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17116  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17117  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17118  1.1     is ftrapcc_le_done:
   17119  1.1     is 	rts					# no; do nothing
   17120  1.1     is ftrapcc_le_yes:
   17121  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17122  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17123  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17124  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17125  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17126  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17127  1.1     is 
   17128  1.1     is #
   17129  1.1     is # not (less than or equal):
   17130  1.1     is #	     ___
   17131  1.1     is #	NANv(NvZ)
   17132  1.1     is #
   17133  1.1     is ftrapcc_nle:
   17134  1.1     is 	fbnle.w		ftrapcc_nle_yes		# not (less than or equal)?
   17135  1.1     is ftrapcc_nle_no:
   17136  1.1     is 	rts					# do nothing
   17137  1.1     is ftrapcc_nle_yes:
   17138  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17139  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17140  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17141  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17142  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17143  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17144  1.1     is 
   17145  1.1     is #
   17146  1.1     is # greater or less than:
   17147  1.1     is #	_____
   17148  1.1     is #	NANvZ
   17149  1.1     is #
   17150  1.1     is ftrapcc_gl:
   17151  1.1     is 	fbgl.w		ftrapcc_trap		# greater or less than?
   17152  1.1     is ftrapcc_gl_no:
   17153  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17154  1.1     is 	beq.b		ftrapcc_gl_done		# no; go finish
   17155  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17156  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17157  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17158  1.1     is ftrapcc_gl_done:
   17159  1.1     is 	rts					# no; do nothing
   17160  1.1     is 
   17161  1.1     is #
   17162  1.1     is # not (greater or less than):
   17163  1.1     is #
   17164  1.1     is #	NANvZ
   17165  1.1     is #
   17166  1.1     is ftrapcc_ngl:
   17167  1.1     is 	fbngl.w		ftrapcc_ngl_yes		# not (greater or less than)?
   17168  1.1     is ftrapcc_ngl_no:
   17169  1.1     is 	rts					# do nothing
   17170  1.1     is ftrapcc_ngl_yes:
   17171  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17172  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17173  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17174  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17175  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17176  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17177  1.1     is 
   17178  1.1     is #
   17179  1.1     is # greater, less, or equal:
   17180  1.1     is #	___
   17181  1.1     is #	NAN
   17182  1.1     is #
   17183  1.1     is ftrapcc_gle:
   17184  1.1     is 	fbgle.w		ftrapcc_trap		# greater, less, or equal?
   17185  1.1     is ftrapcc_gle_no:
   17186  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17187  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17188  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17189  1.1     is 	rts					# no; do nothing
   17190  1.1     is 
   17191  1.1     is #
   17192  1.1     is # not (greater, less, or equal):
   17193  1.1     is #
   17194  1.1     is #	NAN
   17195  1.1     is #
   17196  1.1     is ftrapcc_ngle:
   17197  1.1     is 	fbngle.w	ftrapcc_ngle_yes	# not (greater, less, or equal)?
   17198  1.1     is ftrapcc_ngle_no:
   17199  1.1     is 	rts					# do nothing
   17200  1.1     is ftrapcc_ngle_yes:
   17201  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17202  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17203  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17204  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17205  1.1     is 
   17206  1.1     is #########################################################################
   17207  1.1     is #									#
   17208  1.1     is # Miscellaneous tests							#
   17209  1.1     is #									#
   17210  1.1     is # For the IEEE aware tests, we only have to set the result based on the	#
   17211  1.1     is # floating point condition codes. The BSUN exception will not be	#
   17212  1.1     is # set for any of these tests.						#
   17213  1.1     is #									#
   17214  1.1     is #########################################################################
   17215  1.1     is 
   17216  1.1     is #
   17217  1.1     is # false:
   17218  1.1     is #
   17219  1.1     is #	False
   17220  1.1     is #
   17221  1.1     is ftrapcc_f:
   17222  1.1     is 	rts					# do nothing
   17223  1.1     is 
   17224  1.1     is #
   17225  1.1     is # true:
   17226  1.1     is #
   17227  1.1     is #	True
   17228  1.1     is #
   17229  1.1     is ftrapcc_t:
   17230  1.1     is 	bra.w		ftrapcc_trap		# go take trap
   17231  1.1     is 
   17232  1.1     is #
   17233  1.1     is # signalling false:
   17234  1.1     is #
   17235  1.1     is #	False
   17236  1.1     is #
   17237  1.1     is ftrapcc_sf:
   17238  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17239  1.1     is 	beq.b		ftrapcc_sf_done		# no; go finish
   17240  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17241  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17242  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17243  1.1     is ftrapcc_sf_done:
   17244  1.1     is 	rts					# no; do nothing
   17245  1.1     is 
   17246  1.1     is #
   17247  1.1     is # signalling true:
   17248  1.1     is #
   17249  1.1     is #	True
   17250  1.1     is #
   17251  1.1     is ftrapcc_st:
   17252  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17253  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17254  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17255  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17256  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17257  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17258  1.1     is 
   17259  1.1     is #
   17260  1.1     is # signalling equal:
   17261  1.1     is #
   17262  1.1     is #	Z
   17263  1.1     is #
   17264  1.1     is ftrapcc_seq:
   17265  1.1     is 	fbseq.w		ftrapcc_seq_yes		# signalling equal?
   17266  1.1     is ftrapcc_seq_no:
   17267  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17268  1.1     is 	beq.w		ftrapcc_seq_done	# no; go finish
   17269  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17270  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17271  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17272  1.1     is ftrapcc_seq_done:
   17273  1.1     is 	rts					# no; do nothing
   17274  1.1     is ftrapcc_seq_yes:
   17275  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17276  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17277  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17278  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17279  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17280  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17281  1.1     is 
   17282  1.1     is #
   17283  1.1     is # signalling not equal:
   17284  1.1     is #	_
   17285  1.1     is #	Z
   17286  1.1     is #
   17287  1.1     is ftrapcc_sneq:
   17288  1.1     is 	fbsneq.w	ftrapcc_sneq_yes	# signalling equal?
   17289  1.1     is ftrapcc_sneq_no:
   17290  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17291  1.1     is 	beq.w		ftrapcc_sneq_no_done	# no; go finish
   17292  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17293  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17294  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17295  1.1     is ftrapcc_sneq_no_done:
   17296  1.1     is 	rts					# do nothing
   17297  1.1     is ftrapcc_sneq_yes:
   17298  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17299  1.1     is 	beq.w		ftrapcc_trap		# no; go take trap
   17300  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17301  1.1     is 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17302  1.1     is 	bne.w		ftrapcc_bsun		# yes
   17303  1.1     is 	bra.w		ftrapcc_trap		# no; go take trap
   17304  1.1     is 
   17305  1.1     is #########################################################################
   17306  1.1     is #									#
   17307  1.1     is # IEEE Aware tests							#
   17308  1.1     is #									#
   17309  1.1     is # For the IEEE aware tests, we only have to set the result based on the	#
   17310  1.1     is # floating point condition codes. The BSUN exception will not be	#
   17311  1.1     is # set for any of these tests.						#
   17312  1.1     is #									#
   17313  1.1     is #########################################################################
   17314  1.1     is 
   17315  1.1     is #
   17316  1.1     is # ordered greater than:
   17317  1.1     is #	_______
   17318  1.1     is #	NANvZvN
   17319  1.1     is #
   17320  1.1     is ftrapcc_ogt:
   17321  1.1     is 	fbogt.w		ftrapcc_trap		# ordered greater than?
   17322  1.1     is ftrapcc_ogt_no:
   17323  1.1     is 	rts					# do nothing
   17324  1.1     is 
   17325  1.1     is #
   17326  1.1     is # unordered or less or equal:
   17327  1.1     is #	_______
   17328  1.1     is #	NANvZvN
   17329  1.1     is #
   17330  1.1     is ftrapcc_ule:
   17331  1.1     is 	fbule.w		ftrapcc_trap		# unordered or less or equal?
   17332  1.1     is ftrapcc_ule_no:
   17333  1.1     is 	rts					# do nothing
   17334  1.1     is 
   17335  1.1     is #
   17336  1.1     is # ordered greater than or equal:
   17337  1.1     is #	   _____
   17338  1.1     is #	Zv(NANvN)
   17339  1.1     is #
   17340  1.1     is ftrapcc_oge:
   17341  1.1     is 	fboge.w		ftrapcc_trap		# ordered greater than or equal?
   17342  1.1     is ftrapcc_oge_no:
   17343  1.1     is 	rts					# do nothing
   17344  1.1     is 
   17345  1.1     is #
   17346  1.1     is # unordered or less than:
   17347  1.1     is #	       _
   17348  1.1     is #	NANv(N^Z)
   17349  1.1     is #
   17350  1.1     is ftrapcc_ult:
   17351  1.1     is 	fbult.w		ftrapcc_trap		# unordered or less than?
   17352  1.1     is ftrapcc_ult_no:
   17353  1.1     is 	rts					# do nothing
   17354  1.1     is 
   17355  1.1     is #
   17356  1.1     is # ordered less than:
   17357  1.1     is #	   _____
   17358  1.1     is #	N^(NANvZ)
   17359  1.1     is #
   17360  1.1     is ftrapcc_olt:
   17361  1.1     is 	fbolt.w		ftrapcc_trap		# ordered less than?
   17362  1.1     is ftrapcc_olt_no:
   17363  1.1     is 	rts					# do nothing
   17364  1.1     is 
   17365  1.1     is #
   17366  1.1     is # unordered or greater or equal:
   17367  1.1     is #
   17368  1.1     is #	NANvZvN
   17369  1.1     is #
   17370  1.1     is ftrapcc_uge:
   17371  1.1     is 	fbuge.w		ftrapcc_trap		# unordered or greater than?
   17372  1.1     is ftrapcc_uge_no:
   17373  1.1     is 	rts					# do nothing
   17374  1.1     is 
   17375  1.1     is #
   17376  1.1     is # ordered less than or equal:
   17377  1.1     is #	     ___
   17378  1.1     is #	Zv(N^NAN)
   17379  1.1     is #
   17380  1.1     is ftrapcc_ole:
   17381  1.1     is 	fbole.w		ftrapcc_trap		# ordered greater or less than?
   17382  1.1     is ftrapcc_ole_no:
   17383  1.1     is 	rts					# do nothing
   17384  1.1     is 
   17385  1.1     is #
   17386  1.1     is # unordered or greater than:
   17387  1.1     is #	     ___
   17388  1.1     is #	NANv(NvZ)
   17389  1.1     is #
   17390  1.1     is ftrapcc_ugt:
   17391  1.1     is 	fbugt.w		ftrapcc_trap		# unordered or greater than?
   17392  1.1     is ftrapcc_ugt_no:
   17393  1.1     is 	rts					# do nothing
   17394  1.1     is 
   17395  1.1     is #
   17396  1.1     is # ordered greater or less than:
   17397  1.1     is #	_____
   17398  1.1     is #	NANvZ
   17399  1.1     is #
   17400  1.1     is ftrapcc_ogl:
   17401  1.1     is 	fbogl.w		ftrapcc_trap		# ordered greater or less than?
   17402  1.1     is ftrapcc_ogl_no:
   17403  1.1     is 	rts					# do nothing
   17404  1.1     is 
   17405  1.1     is #
   17406  1.1     is # unordered or equal:
   17407  1.1     is #
   17408  1.1     is #	NANvZ
   17409  1.1     is #
   17410  1.1     is ftrapcc_ueq:
   17411  1.1     is 	fbueq.w		ftrapcc_trap		# unordered or equal?
   17412  1.1     is ftrapcc_ueq_no:
   17413  1.1     is 	rts					# do nothing
   17414  1.1     is 
   17415  1.1     is #
   17416  1.1     is # ordered:
   17417  1.1     is #	___
   17418  1.1     is #	NAN
   17419  1.1     is #
   17420  1.1     is ftrapcc_or:
   17421  1.1     is 	fbor.w		ftrapcc_trap		# ordered?
   17422  1.1     is ftrapcc_or_no:
   17423  1.1     is 	rts					# do nothing
   17424  1.1     is 
   17425  1.1     is #
   17426  1.1     is # unordered:
   17427  1.1     is #
   17428  1.1     is #	NAN
   17429  1.1     is #
   17430  1.1     is ftrapcc_un:
   17431  1.1     is 	fbun.w		ftrapcc_trap		# unordered?
   17432  1.1     is ftrapcc_un_no:
   17433  1.1     is 	rts					# do nothing
   17434  1.1     is 
   17435  1.1     is #######################################################################
   17436  1.1     is 
   17437  1.1     is # the bsun exception bit was not set.
   17438  1.1     is # we will need to jump to the ftrapcc vector. the stack frame
   17439  1.1     is # is the same size as that of the fp unimp instruction. the
   17440  1.1     is # only difference is that the <ea> field should hold the PC
   17441  1.1     is # of the ftrapcc instruction and the vector offset field
   17442  1.1     is # should denote the ftrapcc trap.
   17443  1.1     is ftrapcc_trap:
   17444  1.1     is 	mov.b		&ftrapcc_flg,SPCOND_FLG(%a6)
   17445  1.1     is 	rts
   17446  1.1     is 
   17447  1.1     is # the emulation routine set bsun and BSUN was enabled. have to
   17448  1.1     is # fix stack and jump to the bsun handler.
   17449  1.1     is # let the caller of this routine shift the stack frame up to
   17450  1.1     is # eliminate the effective address field.
   17451  1.1     is ftrapcc_bsun:
   17452  1.1     is 	mov.b		&fbsun_flg,SPCOND_FLG(%a6)
   17453  1.1     is 	rts
   17454  1.1     is 
   17455  1.1     is #########################################################################
   17456  1.1     is # fscc(): routine to emulate the fscc instruction			#
   17457  1.1     is #									#
   17458  1.1     is # XDEF **************************************************************** #
   17459  1.1     is #	_fscc()								#
   17460  1.1     is #									#
   17461  1.1     is # XREF **************************************************************** #
   17462  1.1     is #	store_dreg_b() - store result to data register file		#
   17463  1.1     is #	dec_areg() - decrement an areg for -(an) mode			#
   17464  1.1     is #	inc_areg() - increment an areg for (an)+ mode			#
   17465  1.1     is #	_dmem_write_byte() - store result to memory			#
   17466  1.1     is #									#
   17467  1.1     is # INPUT ***************************************************************	#
   17468  1.1     is #	none								#
   17469  1.1     is #									#
   17470  1.1     is # OUTPUT ************************************************************** #
   17471  1.1     is #	none								#
   17472  1.1     is #									#
   17473  1.1     is # ALGORITHM ***********************************************************	#
   17474  1.1     is #	This routine checks which conditional predicate is specified by	#
   17475  1.1     is # the stacked fscc instruction opcode and then branches to a routine	#
   17476  1.1     is # for that predicate. The corresponding fbcc instruction is then used	#
   17477  1.1     is # to see whether the condition (specified by the stacked FPSR) is true	#
   17478  1.1     is # or false.								#
   17479  1.1     is #	If a BSUN exception should be indicated, the BSUN and ABSUN	#
   17480  1.1     is # bits are set in the stacked FPSR. If the BSUN exception is enabled,	#
   17481  1.1     is # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an 	#
   17482  1.1     is # enabled BSUN should not be flagged and the predicate is true, then	#
   17483  1.1     is # the result is stored to the data register file or memory		#
   17484  1.1     is #									#
   17485  1.1     is #########################################################################
   17486  1.1     is 
   17487  1.1     is 	global		_fscc
   17488  1.1     is _fscc:
   17489  1.1     is 	mov.w		EXC_CMDREG(%a6),%d0	# fetch predicate
   17490  1.1     is 
   17491  1.1     is 	clr.l		%d1			# clear scratch reg
   17492  1.1     is 	mov.b		FPSR_CC(%a6),%d1	# fetch fp ccodes
   17493  1.1     is 	ror.l		&0x8,%d1		# rotate to top byte
   17494  1.1     is 	fmov.l		%d1,%fpsr		# insert into FPSR
   17495  1.1     is 
   17496  1.1     is 	mov.w		(tbl_fscc.b,%pc,%d0.w*2),%d1 # load table
   17497  1.1     is 	jmp		(tbl_fscc.b,%pc,%d1.w) 	# jump to fscc routine
   17498  1.1     is 
   17499  1.1     is tbl_fscc:
   17500  1.1     is 	short		fscc_f		-	tbl_fscc	# 00
   17501  1.1     is 	short		fscc_eq		-	tbl_fscc	# 01
   17502  1.1     is 	short		fscc_ogt	-	tbl_fscc	# 02
   17503  1.1     is 	short		fscc_oge	-	tbl_fscc	# 03
   17504  1.1     is 	short		fscc_olt	-	tbl_fscc	# 04
   17505  1.1     is 	short		fscc_ole	-	tbl_fscc	# 05
   17506  1.1     is 	short		fscc_ogl	-	tbl_fscc	# 06
   17507  1.1     is 	short		fscc_or		-	tbl_fscc	# 07
   17508  1.1     is 	short		fscc_un		-	tbl_fscc	# 08
   17509  1.1     is 	short		fscc_ueq	-	tbl_fscc	# 09
   17510  1.1     is 	short		fscc_ugt	-	tbl_fscc	# 10
   17511  1.1     is 	short		fscc_uge	-	tbl_fscc	# 11
   17512  1.1     is 	short		fscc_ult	-	tbl_fscc	# 12
   17513  1.1     is 	short		fscc_ule	-	tbl_fscc	# 13
   17514  1.1     is 	short		fscc_neq	-	tbl_fscc	# 14
   17515  1.1     is 	short		fscc_t		-	tbl_fscc	# 15
   17516  1.1     is 	short		fscc_sf		-	tbl_fscc	# 16
   17517  1.1     is 	short		fscc_seq	-	tbl_fscc	# 17
   17518  1.1     is 	short		fscc_gt		-	tbl_fscc	# 18
   17519  1.1     is 	short		fscc_ge		-	tbl_fscc	# 19
   17520  1.1     is 	short		fscc_lt		-	tbl_fscc	# 20
   17521  1.1     is 	short		fscc_le		-	tbl_fscc	# 21
   17522  1.1     is 	short		fscc_gl		-	tbl_fscc	# 22
   17523  1.1     is 	short		fscc_gle	-	tbl_fscc	# 23
   17524  1.1     is 	short		fscc_ngle	-	tbl_fscc	# 24
   17525  1.1     is 	short		fscc_ngl	-	tbl_fscc	# 25
   17526  1.1     is 	short		fscc_nle	-	tbl_fscc	# 26
   17527  1.1     is 	short		fscc_nlt	-	tbl_fscc	# 27
   17528  1.1     is 	short		fscc_nge	-	tbl_fscc	# 28
   17529  1.1     is 	short		fscc_ngt	-	tbl_fscc	# 29
   17530  1.1     is 	short		fscc_sneq	-	tbl_fscc	# 30
   17531  1.1     is 	short		fscc_st		-	tbl_fscc	# 31
   17532  1.1     is 
   17533  1.1     is #########################################################################
   17534  1.1     is #									#
   17535  1.1     is # IEEE Nonaware tests							#
   17536  1.1     is #									#
   17537  1.1     is # For the IEEE nonaware tests, we set the result based on the		#
   17538  1.1     is # floating point condition codes. In addition, we check to see		#
   17539  1.1     is # if the NAN bit is set, in which case BSUN and AIOP will be set.	#
   17540  1.1     is #									#
   17541  1.1     is # The cases EQ and NE are shared by the Aware and Nonaware groups	#
   17542  1.1     is # and are incapable of setting the BSUN exception bit.			#
   17543  1.1     is #									#
   17544  1.1     is # Typically, only one of the two possible branch directions could	#
   17545  1.1     is # have the NAN bit set.							#
   17546  1.1     is #									#
   17547  1.1     is #########################################################################
   17548  1.1     is 
   17549  1.1     is #
   17550  1.1     is # equal:
   17551  1.1     is #
   17552  1.1     is #	Z
   17553  1.1     is #
   17554  1.1     is fscc_eq:
   17555  1.1     is 	fbeq.w		fscc_eq_yes		# equal?
   17556  1.1     is fscc_eq_no:
   17557  1.1     is 	clr.b		%d0			# set false
   17558  1.1     is 	bra.w		fscc_done		# go finish
   17559  1.1     is fscc_eq_yes:
   17560  1.1     is 	st		%d0			# set true
   17561  1.1     is 	bra.w		fscc_done		# go finish
   17562  1.1     is 
   17563  1.1     is #
   17564  1.1     is # not equal:
   17565  1.1     is #	_
   17566  1.1     is #	Z
   17567  1.1     is #
   17568  1.1     is fscc_neq:
   17569  1.1     is 	fbneq.w		fscc_neq_yes		# not equal?
   17570  1.1     is fscc_neq_no:
   17571  1.1     is 	clr.b		%d0			# set false
   17572  1.1     is 	bra.w		fscc_done		# go finish
   17573  1.1     is fscc_neq_yes:
   17574  1.1     is 	st		%d0			# set true
   17575  1.1     is 	bra.w		fscc_done		# go finish
   17576  1.1     is 
   17577  1.1     is #
   17578  1.1     is # greater than:
   17579  1.1     is #	_______
   17580  1.1     is #	NANvZvN
   17581  1.1     is #
   17582  1.1     is fscc_gt:
   17583  1.1     is 	fbgt.w		fscc_gt_yes		# greater than?
   17584  1.1     is fscc_gt_no:
   17585  1.1     is 	clr.b		%d0			# set false
   17586  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17587  1.1     is 	beq.w		fscc_done		# no;go finish
   17588  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17589  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17590  1.1     is fscc_gt_yes:
   17591  1.1     is 	st		%d0			# set true
   17592  1.1     is 	bra.w		fscc_done		# go finish
   17593  1.1     is 
   17594  1.1     is #
   17595  1.1     is # not greater than:
   17596  1.1     is #
   17597  1.1     is #	NANvZvN
   17598  1.1     is #
   17599  1.1     is fscc_ngt:
   17600  1.1     is 	fbngt.w		fscc_ngt_yes		# not greater than?
   17601  1.1     is fscc_ngt_no:
   17602  1.1     is 	clr.b		%d0			# set false
   17603  1.1     is 	bra.w		fscc_done		# go finish
   17604  1.1     is fscc_ngt_yes:
   17605  1.1     is 	st		%d0			# set true
   17606  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17607  1.1     is 	beq.w		fscc_done		# no;go finish
   17608  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17609  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17610  1.1     is 
   17611  1.1     is #
   17612  1.1     is # greater than or equal:
   17613  1.1     is #	   _____
   17614  1.1     is #	Zv(NANvN)
   17615  1.1     is #
   17616  1.1     is fscc_ge:
   17617  1.1     is 	fbge.w		fscc_ge_yes		# greater than or equal?
   17618  1.1     is fscc_ge_no:
   17619  1.1     is 	clr.b		%d0			# set false
   17620  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17621  1.1     is 	beq.w		fscc_done		# no;go finish
   17622  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17623  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17624  1.1     is fscc_ge_yes:
   17625  1.1     is 	st		%d0			# set true
   17626  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17627  1.1     is 	beq.w		fscc_done		# no;go finish
   17628  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17629  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17630  1.1     is 
   17631  1.1     is #
   17632  1.1     is # not (greater than or equal):
   17633  1.1     is #	       _
   17634  1.1     is #	NANv(N^Z)
   17635  1.1     is #
   17636  1.1     is fscc_nge:
   17637  1.1     is 	fbnge.w		fscc_nge_yes		# not (greater than or equal)?
   17638  1.1     is fscc_nge_no:
   17639  1.1     is 	clr.b		%d0			# set false
   17640  1.1     is 	bra.w		fscc_done		# go finish
   17641  1.1     is fscc_nge_yes:
   17642  1.1     is 	st		%d0			# set true
   17643  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17644  1.1     is 	beq.w		fscc_done		# no;go finish
   17645  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17646  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17647  1.1     is 
   17648  1.1     is #
   17649  1.1     is # less than:
   17650  1.1     is #	   _____
   17651  1.1     is #	N^(NANvZ)
   17652  1.1     is #
   17653  1.1     is fscc_lt:
   17654  1.1     is 	fblt.w		fscc_lt_yes		# less than?
   17655  1.1     is fscc_lt_no:
   17656  1.1     is 	clr.b		%d0			# set false
   17657  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17658  1.1     is 	beq.w		fscc_done		# no;go finish
   17659  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17660  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17661  1.1     is fscc_lt_yes:
   17662  1.1     is 	st		%d0			# set true
   17663  1.1     is 	bra.w		fscc_done		# go finish
   17664  1.1     is 
   17665  1.1     is #
   17666  1.1     is # not less than:
   17667  1.1     is #	       _
   17668  1.1     is #	NANv(ZvN)
   17669  1.1     is #
   17670  1.1     is fscc_nlt:
   17671  1.1     is 	fbnlt.w		fscc_nlt_yes		# not less than?
   17672  1.1     is fscc_nlt_no:
   17673  1.1     is 	clr.b		%d0			# set false
   17674  1.1     is 	bra.w		fscc_done		# go finish
   17675  1.1     is fscc_nlt_yes:
   17676  1.1     is 	st		%d0			# set true
   17677  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17678  1.1     is 	beq.w		fscc_done		# no;go finish
   17679  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17680  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17681  1.1     is 
   17682  1.1     is #
   17683  1.1     is # less than or equal:
   17684  1.1     is #	     ___
   17685  1.1     is #	Zv(N^NAN)
   17686  1.1     is #
   17687  1.1     is fscc_le:
   17688  1.1     is 	fble.w		fscc_le_yes		# less than or equal?
   17689  1.1     is fscc_le_no:
   17690  1.1     is 	clr.b		%d0			# set false
   17691  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17692  1.1     is 	beq.w		fscc_done		# no;go finish
   17693  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17694  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17695  1.1     is fscc_le_yes:
   17696  1.1     is 	st		%d0			# set true
   17697  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17698  1.1     is 	beq.w		fscc_done		# no;go finish
   17699  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17700  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17701  1.1     is 
   17702  1.1     is #
   17703  1.1     is # not (less than or equal):
   17704  1.1     is #	     ___
   17705  1.1     is #	NANv(NvZ)
   17706  1.1     is #
   17707  1.1     is fscc_nle:
   17708  1.1     is 	fbnle.w		fscc_nle_yes		# not (less than or equal)?
   17709  1.1     is fscc_nle_no:
   17710  1.1     is 	clr.b		%d0			# set false
   17711  1.1     is 	bra.w		fscc_done		# go finish
   17712  1.1     is fscc_nle_yes:
   17713  1.1     is 	st		%d0			# set true
   17714  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17715  1.1     is 	beq.w		fscc_done		# no;go finish
   17716  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17717  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17718  1.1     is 
   17719  1.1     is #
   17720  1.1     is # greater or less than:
   17721  1.1     is #	_____
   17722  1.1     is #	NANvZ
   17723  1.1     is #
   17724  1.1     is fscc_gl:
   17725  1.1     is 	fbgl.w		fscc_gl_yes		# greater or less than?
   17726  1.1     is fscc_gl_no:
   17727  1.1     is 	clr.b		%d0			# set false
   17728  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17729  1.1     is 	beq.w		fscc_done		# no;go finish
   17730  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17731  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17732  1.1     is fscc_gl_yes:
   17733  1.1     is 	st		%d0			# set true
   17734  1.1     is 	bra.w		fscc_done		# go finish
   17735  1.1     is 
   17736  1.1     is #
   17737  1.1     is # not (greater or less than):
   17738  1.1     is #
   17739  1.1     is #	NANvZ
   17740  1.1     is #
   17741  1.1     is fscc_ngl:
   17742  1.1     is 	fbngl.w		fscc_ngl_yes		# not (greater or less than)?
   17743  1.1     is fscc_ngl_no:
   17744  1.1     is 	clr.b		%d0			# set false
   17745  1.1     is 	bra.w		fscc_done		# go finish
   17746  1.1     is fscc_ngl_yes:
   17747  1.1     is 	st		%d0			# set true
   17748  1.1     is 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17749  1.1     is 	beq.w		fscc_done		# no;go finish
   17750  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17751  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17752  1.1     is 
   17753  1.1     is #
   17754  1.1     is # greater, less, or equal:
   17755  1.1     is #	___
   17756  1.1     is #	NAN
   17757  1.1     is #
   17758  1.1     is fscc_gle:
   17759  1.1     is 	fbgle.w		fscc_gle_yes		# greater, less, or equal?
   17760  1.1     is fscc_gle_no:
   17761  1.1     is 	clr.b		%d0			# set false
   17762  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17763  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17764  1.1     is fscc_gle_yes:
   17765  1.1     is 	st		%d0			# set true
   17766  1.1     is 	bra.w		fscc_done		# go finish
   17767  1.1     is 
   17768  1.1     is #
   17769  1.1     is # not (greater, less, or equal):
   17770  1.1     is #
   17771  1.1     is #	NAN
   17772  1.1     is #
   17773  1.1     is fscc_ngle:
   17774  1.1     is 	fbngle.w		fscc_ngle_yes	# not (greater, less, or equal)?
   17775  1.1     is fscc_ngle_no:
   17776  1.1     is 	clr.b		%d0			# set false
   17777  1.1     is 	bra.w		fscc_done		# go finish
   17778  1.1     is fscc_ngle_yes:
   17779  1.1     is 	st		%d0			# set true
   17780  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17781  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17782  1.1     is 
   17783  1.1     is #########################################################################
   17784  1.1     is #									#
   17785  1.1     is # Miscellaneous tests							#
   17786  1.1     is #									#
   17787  1.1     is # For the IEEE aware tests, we only have to set the result based on the	#
   17788  1.1     is # floating point condition codes. The BSUN exception will not be	#
   17789  1.1     is # set for any of these tests.						#
   17790  1.1     is #									#
   17791  1.1     is #########################################################################
   17792  1.1     is 
   17793  1.1     is #
   17794  1.1     is # false:
   17795  1.1     is #
   17796  1.1     is #	False
   17797  1.1     is #
   17798  1.1     is fscc_f:
   17799  1.1     is 	clr.b		%d0			# set false
   17800  1.1     is 	bra.w		fscc_done		# go finish
   17801  1.1     is 
   17802  1.1     is #
   17803  1.1     is # true:
   17804  1.1     is #
   17805  1.1     is #	True
   17806  1.1     is #
   17807  1.1     is fscc_t:
   17808  1.1     is 	st		%d0			# set true
   17809  1.1     is 	bra.w		fscc_done		# go finish
   17810  1.1     is 
   17811  1.1     is #
   17812  1.1     is # signalling false:
   17813  1.1     is #
   17814  1.1     is #	False
   17815  1.1     is #
   17816  1.1     is fscc_sf:
   17817  1.1     is 	clr.b		%d0			# set false
   17818  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17819  1.1     is 	beq.w		fscc_done		# no;go finish
   17820  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17821  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17822  1.1     is 
   17823  1.1     is #
   17824  1.1     is # signalling true:
   17825  1.1     is #
   17826  1.1     is #	True
   17827  1.1     is #
   17828  1.1     is fscc_st:
   17829  1.1     is 	st		%d0			# set false
   17830  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17831  1.1     is 	beq.w		fscc_done		# no;go finish
   17832  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17833  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17834  1.1     is 
   17835  1.1     is #
   17836  1.1     is # signalling equal:
   17837  1.1     is #
   17838  1.1     is #	Z
   17839  1.1     is #
   17840  1.1     is fscc_seq:
   17841  1.1     is 	fbseq.w		fscc_seq_yes		# signalling equal?
   17842  1.1     is fscc_seq_no:
   17843  1.1     is 	clr.b		%d0			# set false
   17844  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17845  1.1     is 	beq.w		fscc_done		# no;go finish
   17846  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17847  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17848  1.1     is fscc_seq_yes:
   17849  1.1     is 	st		%d0			# set true
   17850  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17851  1.1     is 	beq.w		fscc_done		# no;go finish
   17852  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17853  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17854  1.1     is 
   17855  1.1     is #
   17856  1.1     is # signalling not equal:
   17857  1.1     is #	_
   17858  1.1     is #	Z
   17859  1.1     is #
   17860  1.1     is fscc_sneq:
   17861  1.1     is 	fbsneq.w	fscc_sneq_yes		# signalling equal?
   17862  1.1     is fscc_sneq_no:
   17863  1.1     is 	clr.b		%d0			# set false
   17864  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17865  1.1     is 	beq.w		fscc_done		# no;go finish
   17866  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17867  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17868  1.1     is fscc_sneq_yes:
   17869  1.1     is 	st		%d0			# set true
   17870  1.1     is 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17871  1.1     is 	beq.w		fscc_done		# no;go finish
   17872  1.1     is 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17873  1.1     is 	bra.w		fscc_chk_bsun		# go finish
   17874  1.1     is 
   17875  1.1     is #########################################################################
   17876  1.1     is #									#
   17877  1.1     is # IEEE Aware tests							#
   17878  1.1     is #									#
   17879  1.1     is # For the IEEE aware tests, we only have to set the result based on the	#
   17880  1.1     is # floating point condition codes. The BSUN exception will not be	#
   17881  1.1     is # set for any of these tests.						#
   17882  1.1     is #									#
   17883  1.1     is #########################################################################
   17884  1.1     is 
   17885  1.1     is #
   17886  1.1     is # ordered greater than:
   17887  1.1     is #	_______
   17888  1.1     is #	NANvZvN
   17889  1.1     is #
   17890  1.1     is fscc_ogt:
   17891  1.1     is 	fbogt.w		fscc_ogt_yes		# ordered greater than?
   17892  1.1     is fscc_ogt_no:
   17893  1.1     is 	clr.b		%d0			# set false
   17894  1.1     is 	bra.w		fscc_done		# go finish
   17895  1.1     is fscc_ogt_yes:
   17896  1.1     is 	st		%d0			# set true
   17897  1.1     is 	bra.w		fscc_done		# go finish
   17898  1.1     is 
   17899  1.1     is #
   17900  1.1     is # unordered or less or equal:
   17901  1.1     is #	_______
   17902  1.1     is #	NANvZvN
   17903  1.1     is #
   17904  1.1     is fscc_ule:
   17905  1.1     is 	fbule.w		fscc_ule_yes		# unordered or less or equal?
   17906  1.1     is fscc_ule_no:
   17907  1.1     is 	clr.b		%d0			# set false
   17908  1.1     is 	bra.w		fscc_done		# go finish
   17909  1.1     is fscc_ule_yes:
   17910  1.1     is 	st		%d0			# set true
   17911  1.1     is 	bra.w		fscc_done		# go finish
   17912  1.1     is 
   17913  1.1     is #
   17914  1.1     is # ordered greater than or equal:
   17915  1.1     is #	   _____
   17916  1.1     is #	Zv(NANvN)
   17917  1.1     is #
   17918  1.1     is fscc_oge:
   17919  1.1     is 	fboge.w		fscc_oge_yes		# ordered greater than or equal?
   17920  1.1     is fscc_oge_no:
   17921  1.1     is 	clr.b		%d0			# set false
   17922  1.1     is 	bra.w		fscc_done		# go finish
   17923  1.1     is fscc_oge_yes:
   17924  1.1     is 	st		%d0			# set true
   17925  1.1     is 	bra.w		fscc_done		# go finish
   17926  1.1     is 
   17927  1.1     is #
   17928  1.1     is # unordered or less than:
   17929  1.1     is #	       _
   17930  1.1     is #	NANv(N^Z)
   17931  1.1     is #
   17932  1.1     is fscc_ult:
   17933  1.1     is 	fbult.w		fscc_ult_yes		# unordered or less than?
   17934  1.1     is fscc_ult_no:
   17935  1.1     is 	clr.b		%d0			# set false
   17936  1.1     is 	bra.w		fscc_done		# go finish
   17937  1.1     is fscc_ult_yes:
   17938  1.1     is 	st		%d0			# set true
   17939  1.1     is 	bra.w		fscc_done		# go finish
   17940  1.1     is 
   17941  1.1     is #
   17942  1.1     is # ordered less than:
   17943  1.1     is #	   _____
   17944  1.1     is #	N^(NANvZ)
   17945  1.1     is #
   17946  1.1     is fscc_olt:
   17947  1.1     is 	fbolt.w		fscc_olt_yes		# ordered less than?
   17948  1.1     is fscc_olt_no:
   17949  1.1     is 	clr.b		%d0			# set false
   17950  1.1     is 	bra.w		fscc_done		# go finish
   17951  1.1     is fscc_olt_yes:
   17952  1.1     is 	st		%d0			# set true
   17953  1.1     is 	bra.w		fscc_done		# go finish
   17954  1.1     is 
   17955  1.1     is #
   17956  1.1     is # unordered or greater or equal:
   17957  1.1     is #
   17958  1.1     is #	NANvZvN
   17959  1.1     is #
   17960  1.1     is fscc_uge:
   17961  1.1     is 	fbuge.w		fscc_uge_yes		# unordered or greater than?
   17962  1.1     is fscc_uge_no:
   17963  1.1     is 	clr.b		%d0			# set false
   17964  1.1     is 	bra.w		fscc_done		# go finish
   17965  1.1     is fscc_uge_yes:
   17966  1.1     is 	st		%d0			# set true
   17967  1.1     is 	bra.w		fscc_done		# go finish
   17968  1.1     is 
   17969  1.1     is #
   17970  1.1     is # ordered less than or equal:
   17971  1.1     is #	     ___
   17972  1.1     is #	Zv(N^NAN)
   17973  1.1     is #
   17974  1.1     is fscc_ole:
   17975  1.1     is 	fbole.w		fscc_ole_yes		# ordered greater or less than?
   17976  1.1     is fscc_ole_no:
   17977  1.1     is 	clr.b		%d0			# set false
   17978  1.1     is 	bra.w		fscc_done		# go finish
   17979  1.1     is fscc_ole_yes:
   17980  1.1     is 	st		%d0			# set true
   17981  1.1     is 	bra.w		fscc_done		# go finish
   17982  1.1     is 
   17983  1.1     is #
   17984  1.1     is # unordered or greater than:
   17985  1.1     is #	     ___
   17986  1.1     is #	NANv(NvZ)
   17987  1.1     is #
   17988  1.1     is fscc_ugt:
   17989  1.1     is 	fbugt.w		fscc_ugt_yes		# unordered or greater than?
   17990  1.1     is fscc_ugt_no:
   17991  1.1     is 	clr.b		%d0			# set false
   17992  1.1     is 	bra.w		fscc_done		# go finish
   17993  1.1     is fscc_ugt_yes:
   17994  1.1     is 	st		%d0			# set true
   17995  1.1     is 	bra.w		fscc_done		# go finish
   17996  1.1     is 
   17997  1.1     is #
   17998  1.1     is # ordered greater or less than:
   17999  1.1     is #	_____
   18000  1.1     is #	NANvZ
   18001  1.1     is #
   18002  1.1     is fscc_ogl:
   18003  1.1     is 	fbogl.w		fscc_ogl_yes		# ordered greater or less than?
   18004  1.1     is fscc_ogl_no:
   18005  1.1     is 	clr.b		%d0			# set false
   18006  1.1     is 	bra.w		fscc_done		# go finish
   18007  1.1     is fscc_ogl_yes:
   18008  1.1     is 	st		%d0			# set true
   18009  1.1     is 	bra.w		fscc_done		# go finish
   18010  1.1     is 
   18011  1.1     is #
   18012  1.1     is # unordered or equal:
   18013  1.1     is #
   18014  1.1     is #	NANvZ
   18015  1.1     is #
   18016  1.1     is fscc_ueq:
   18017  1.1     is 	fbueq.w		fscc_ueq_yes		# unordered or equal?
   18018  1.1     is fscc_ueq_no:
   18019  1.1     is 	clr.b		%d0			# set false
   18020  1.1     is 	bra.w		fscc_done		# go finish
   18021  1.1     is fscc_ueq_yes:
   18022  1.1     is 	st		%d0			# set true
   18023  1.1     is 	bra.w		fscc_done		# go finish
   18024  1.1     is 
   18025  1.1     is #
   18026  1.1     is # ordered:
   18027  1.1     is #	___
   18028  1.1     is #	NAN
   18029  1.1     is #
   18030  1.1     is fscc_or:
   18031  1.1     is 	fbor.w		fscc_or_yes		# ordered?
   18032  1.1     is fscc_or_no:
   18033  1.1     is 	clr.b		%d0			# set false
   18034  1.1     is 	bra.w		fscc_done		# go finish
   18035  1.1     is fscc_or_yes:
   18036  1.1     is 	st		%d0			# set true
   18037  1.1     is 	bra.w		fscc_done		# go finish
   18038  1.1     is 
   18039  1.1     is #
   18040  1.1     is # unordered:
   18041  1.1     is #
   18042  1.1     is #	NAN
   18043  1.1     is #
   18044  1.1     is fscc_un:
   18045  1.1     is 	fbun.w		fscc_un_yes		# unordered?
   18046  1.1     is fscc_un_no:
   18047  1.1     is 	clr.b		%d0			# set false
   18048  1.1     is 	bra.w		fscc_done		# go finish
   18049  1.1     is fscc_un_yes:
   18050  1.1     is 	st		%d0			# set true
   18051  1.1     is 	bra.w		fscc_done		# go finish
   18052  1.1     is 
   18053  1.1     is #######################################################################
   18054  1.1     is 
   18055  1.1     is #
   18056  1.1     is # the bsun exception bit was set. now, check to see is BSUN
   18057  1.1     is # is enabled. if so, don't store result and correct stack frame
   18058  1.1     is # for a bsun exception.
   18059  1.1     is #
   18060  1.1     is fscc_chk_bsun:
   18061  1.1     is 	btst		&bsun_bit,FPCR_ENABLE(%a6) # was BSUN set?
   18062  1.1     is 	bne.w		fscc_bsun
   18063  1.1     is 
   18064  1.1     is #
   18065  1.1     is # the bsun exception bit was not set.
   18066  1.1     is # the result has been selected.
   18067  1.1     is # now, check to see if the result is to be stored in the data register
   18068  1.1     is # file or in memory.
   18069  1.1     is #
   18070  1.1     is fscc_done:
   18071  1.1     is 	mov.l		%d0,%a0			# save result for a moment
   18072  1.1     is 
   18073  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# fetch lo opword
   18074  1.1     is 	mov.l		%d1,%d0			# make a copy
   18075  1.1     is 	andi.b		&0x38,%d1		# extract src mode
   18076  1.1     is 
   18077  1.1     is 	bne.b		fscc_mem_op		# it's a memory operation
   18078  1.1     is 
   18079  1.1     is 	mov.l		%d0,%d1
   18080  1.1     is 	andi.w		&0x7,%d1		# pass index in d1
   18081  1.1     is 	mov.l		%a0,%d0			# pass result in d0
   18082  1.1     is 	bsr.l		store_dreg_b		# save result in regfile
   18083  1.1     is 	rts
   18084  1.1     is 
   18085  1.1     is #
   18086  1.1     is # the stacked <ea> is correct with the exception of:
   18087  1.1     is # 	-> Dn : <ea> is garbage
   18088  1.1     is #
   18089  1.1     is # if the addressing mode is post-increment or pre-decrement,
   18090  1.1     is # then the address registers have not been updated.
   18091  1.1     is #
   18092  1.1     is fscc_mem_op:
   18093  1.1     is 	cmpi.b		%d1,&0x18		# is <ea> (An)+ ?
   18094  1.1     is 	beq.b		fscc_mem_inc		# yes
   18095  1.1     is 	cmpi.b		%d1,&0x20		# is <ea> -(An) ?
   18096  1.1     is 	beq.b		fscc_mem_dec		# yes
   18097  1.1     is 
   18098  1.1     is 	mov.l		%a0,%d0			# pass result in d0
   18099  1.1     is 	mov.l		EXC_EA(%a6),%a0		# fetch <ea>
   18100  1.1     is 	bsr.l		_dmem_write_byte	# write result byte
   18101  1.1     is 
   18102  1.1     is 	tst.l		%d1			# did dstore fail?
   18103  1.1     is 	bne.w		fscc_err		# yes
   18104  1.1     is 
   18105  1.1     is 	rts
   18106  1.1     is 
   18107  1.1     is # addresing mode is post-increment. write the result byte. if the write
   18108  1.1     is # fails then don't update the address register. if write passes then
   18109  1.1     is # call inc_areg() to update the address register.
   18110  1.1     is fscc_mem_inc:
   18111  1.1     is 	mov.l		%a0,%d0			# pass result in d0
   18112  1.1     is 	mov.l		EXC_EA(%a6),%a0		# fetch <ea>
   18113  1.1     is 	bsr.l		_dmem_write_byte	# write result byte
   18114  1.1     is 
   18115  1.1     is 	tst.l		%d1			# did dstore fail?
   18116  1.1     is 	bne.w		fscc_err		# yes
   18117  1.1     is 
   18118  1.1     is 	mov.b		0x1+EXC_OPWORD(%a6),%d1	# fetch opword
   18119  1.1     is 	andi.w		&0x7,%d1		# pass index in d1
   18120  1.1     is 	movq.l		&0x1,%d0		# pass amt to inc by
   18121  1.1     is 	bsr.l		inc_areg		# increment address register
   18122  1.1     is 
   18123  1.1     is 	rts
   18124  1.1     is 
   18125  1.1     is # addressing mode is pre-decrement. write the result byte. if the write
   18126  1.1     is # fails then don't update the address register. if the write passes then
   18127  1.1     is # call dec_areg() to update the address register.
   18128  1.1     is fscc_mem_dec:
   18129  1.1     is 	mov.l		%a0,%d0			# pass result in d0
   18130  1.1     is 	mov.l		EXC_EA(%a6),%a0		# fetch <ea>
   18131  1.1     is 	bsr.l		_dmem_write_byte	# write result byte
   18132  1.1     is 
   18133  1.1     is 	tst.l		%d1			# did dstore fail?
   18134  1.1     is 	bne.w		fscc_err		# yes
   18135  1.1     is 
   18136  1.1     is 	mov.b		0x1+EXC_OPWORD(%a6),%d1	# fetch opword
   18137  1.1     is 	andi.w		&0x7,%d1		# pass index in d1
   18138  1.1     is 	movq.l		&0x1,%d0		# pass amt to dec by
   18139  1.1     is 	bsr.l		dec_areg		# decrement address register
   18140  1.1     is 
   18141  1.1     is 	rts
   18142  1.1     is 
   18143  1.1     is # the emulation routine set bsun and BSUN was enabled. have to
   18144  1.1     is # fix stack and jump to the bsun handler.
   18145  1.1     is # let the caller of this routine shift the stack frame up to
   18146  1.1     is # eliminate the effective address field.
   18147  1.1     is fscc_bsun:
   18148  1.1     is 	mov.b		&fbsun_flg,SPCOND_FLG(%a6)
   18149  1.1     is 	rts
   18150  1.1     is 
   18151  1.1     is # the byte write to memory has failed. pass the failing effective address
   18152  1.1     is # and a FSLW to funimp_dacc().
   18153  1.1     is fscc_err:
   18154  1.1     is 	mov.w		&0x00a1,EXC_VOFF(%a6)
   18155  1.1     is 	bra.l		facc_finish
   18156  1.1     is 
   18157  1.1     is #########################################################################
   18158  1.1     is # XDEF ****************************************************************	#
   18159  1.1     is #	fmovm_dynamic(): emulate "fmovm" dynamic instruction		#
   18160  1.1     is #									#
   18161  1.1     is # XREF ****************************************************************	#
   18162  1.1     is #	fetch_dreg() - fetch data register				#
   18163  1.1     is #	{i,d,}mem_read() - fetch data from memory			#
   18164  1.1     is #	_mem_write() - write data to memory				#
   18165  1.1     is #	iea_iacc() - instruction memory access error occurred		#
   18166  1.1     is #	iea_dacc() - data memory access error occurred			#
   18167  1.1     is #	restore() - restore An index regs if access error occurred	#
   18168  1.1     is #									#
   18169  1.1     is # INPUT ***************************************************************	#
   18170  1.1     is #	None								#
   18171  1.1     is # 									#
   18172  1.1     is # OUTPUT **************************************************************	#
   18173  1.1     is #	If instr is "fmovm Dn,-(A7)" from supervisor mode,		#
   18174  1.1     is #		d0 = size of dump					#
   18175  1.1     is #		d1 = Dn							#
   18176  1.1     is #	Else if instruction access error,				#
   18177  1.1     is #		d0 = FSLW						#
   18178  1.1     is #	Else if data access error,					#
   18179  1.1     is #		d0 = FSLW						#
   18180  1.1     is #		a0 = address of fault					#
   18181  1.1     is #	Else								#
   18182  1.1     is #		none.							#
   18183  1.1     is #									#
   18184  1.1     is # ALGORITHM ***********************************************************	#
   18185  1.1     is #	The effective address must be calculated since this is entered	#
   18186  1.1     is # from an "Unimplemented Effective Address" exception handler. So, we	#
   18187  1.1     is # have our own fcalc_ea() routine here. If an access error is flagged	#
   18188  1.1     is # by a _{i,d,}mem_read() call, we must exit through the special		#
   18189  1.1     is # handler.								#
   18190  1.1     is #	The data register is determined and its value loaded to get the	#
   18191  1.1     is # string of FP registers affected. This value is used as an index into	#
   18192  1.1     is # a lookup table such that we can determine the number of bytes		#
   18193  1.1     is # involved. 								#
   18194  1.1     is #	If the instruction is "fmovm.x <ea>,Dn", a _mem_read() is used	#
   18195  1.1     is # to read in all FP values. Again, _mem_read() may fail and require a	#
   18196  1.1     is # special exit. 							#
   18197  1.1     is #	If the instruction is "fmovm.x DN,<ea>", a _mem_write() is used	#
   18198  1.1     is # to write all FP values. _mem_write() may also fail.			#
   18199  1.1     is # 	If the instruction is "fmovm.x DN,-(a7)" from supervisor mode,	#
   18200  1.1     is # then we return the size of the dump and the string to the caller	#
   18201  1.1     is # so that the move can occur outside of this routine. This special	#
   18202  1.1     is # case is required so that moves to the system stack are handled	#
   18203  1.1     is # correctly.								#
   18204  1.1     is #									#
   18205  1.1     is # DYNAMIC:								#
   18206  1.1     is # 	fmovm.x	dn, <ea>						#
   18207  1.1     is # 	fmovm.x	<ea>, dn						#
   18208  1.1     is #									#
   18209  1.1     is #	      <WORD 1>		      <WORD2>				#
   18210  1.1     is #	1111 0010 00 |<ea>|	11@& 1000 0$$$ 0000			#
   18211  1.1     is #					  				#
   18212  1.1     is #	& = (0): predecrement addressing mode				#
   18213  1.1     is #	    (1): postincrement or control addressing mode		#
   18214  1.1     is #	@ = (0): move listed regs from memory to the FPU		#
   18215  1.1     is #	    (1): move listed regs from the FPU to memory		#
   18216  1.1     is #	$$$    : index of data register holding reg select mask		#
   18217  1.1     is #									#
   18218  1.1     is # NOTES:								#
   18219  1.1     is #	If the data register holds a zero, then the			#
   18220  1.1     is #	instruction is a nop.						#
   18221  1.1     is #									#
   18222  1.1     is #########################################################################
   18223  1.1     is 
   18224  1.1     is 	global		fmovm_dynamic
   18225  1.1     is fmovm_dynamic:
   18226  1.1     is 
   18227  1.1     is # extract the data register in which the bit string resides...
   18228  1.1     is 	mov.b		1+EXC_EXTWORD(%a6),%d1	# fetch extword
   18229  1.1     is 	andi.w		&0x70,%d1		# extract reg bits
   18230  1.1     is 	lsr.b		&0x4,%d1		# shift into lo bits
   18231  1.1     is 
   18232  1.1     is # fetch the bit string into d0...
   18233  1.1     is 	bsr.l		fetch_dreg		# fetch reg string
   18234  1.1     is 
   18235  1.1     is 	andi.l		&0x000000ff,%d0		# keep only lo byte
   18236  1.1     is 
   18237  1.1     is 	mov.l		%d0,-(%sp)		# save strg
   18238  1.1     is 	mov.b		(tbl_fmovm_size.w,%pc,%d0),%d0
   18239  1.1     is 	mov.l		%d0,-(%sp)		# save size
   18240  1.1     is 	bsr.l		fmovm_calc_ea		# calculate <ea>
   18241  1.1     is 	mov.l		(%sp)+,%d0		# restore size
   18242  1.1     is 	mov.l		(%sp)+,%d1		# restore strg
   18243  1.1     is 
   18244  1.1     is # if the bit string is a zero, then the operation is a no-op
   18245  1.1     is # but, make sure that we've calculated ea and advanced the opword pointer
   18246  1.1     is 	beq.w		fmovm_data_done
   18247  1.1     is 
   18248  1.1     is # separate move ins from move outs...
   18249  1.1     is 	btst		&0x5,EXC_EXTWORD(%a6)	# is it a move in or out?
   18250  1.1     is 	beq.w		fmovm_data_in		# it's a move out
   18251  1.1     is 
   18252  1.1     is #############
   18253  1.1     is # MOVE OUT: #
   18254  1.1     is #############
   18255  1.1     is fmovm_data_out:
   18256  1.1     is 	btst		&0x4,EXC_EXTWORD(%a6)	# control or predecrement?
   18257  1.1     is 	bne.w		fmovm_out_ctrl		# control
   18258  1.1     is 
   18259  1.1     is ############################
   18260  1.1     is fmovm_out_predec:
   18261  1.1     is # for predecrement mode, the bit string is the opposite of both control
   18262  1.1     is # operations and postincrement mode. (bit7 = FP7 ... bit0 = FP0)
   18263  1.1     is # here, we convert it to be just like the others...
   18264  1.1     is 	mov.b		(tbl_fmovm_convert.w,%pc,%d1.w*1),%d1
   18265  1.1     is 
   18266  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode?
   18267  1.1     is 	beq.b		fmovm_out_ctrl		# user
   18268  1.1     is 
   18269  1.1     is fmovm_out_predec_s:
   18270  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
   18271  1.1     is 	bne.b		fmovm_out_ctrl
   18272  1.1     is 
   18273  1.1     is # the operation was unfortunately an: fmovm.x dn,-(sp)
   18274  1.1     is # called from supervisor mode.
   18275  1.1     is # we're also passing "size" and "strg" back to the calling routine
   18276  1.1     is 	rts
   18277  1.1     is 
   18278  1.1     is ############################
   18279  1.1     is fmovm_out_ctrl:
   18280  1.1     is 	mov.l		%a0,%a1			# move <ea> to a1
   18281  1.1     is 
   18282  1.1     is 	sub.l		%d0,%sp			# subtract size of dump
   18283  1.1     is 	lea		(%sp),%a0
   18284  1.1     is 
   18285  1.1     is 	tst.b		%d1			# should FP0 be moved?
   18286  1.1     is 	bpl.b		fmovm_out_ctrl_fp1	# no
   18287  1.1     is 
   18288  1.1     is 	mov.l		0x0+EXC_FP0(%a6),(%a0)+	# yes
   18289  1.1     is 	mov.l		0x4+EXC_FP0(%a6),(%a0)+
   18290  1.1     is 	mov.l		0x8+EXC_FP0(%a6),(%a0)+
   18291  1.1     is 
   18292  1.1     is fmovm_out_ctrl_fp1:
   18293  1.1     is 	lsl.b		&0x1,%d1		# should FP1 be moved?
   18294  1.1     is 	bpl.b		fmovm_out_ctrl_fp2	# no
   18295  1.1     is 
   18296  1.1     is 	mov.l		0x0+EXC_FP1(%a6),(%a0)+	# yes
   18297  1.1     is 	mov.l		0x4+EXC_FP1(%a6),(%a0)+
   18298  1.1     is 	mov.l		0x8+EXC_FP1(%a6),(%a0)+
   18299  1.1     is 
   18300  1.1     is fmovm_out_ctrl_fp2:
   18301  1.1     is 	lsl.b		&0x1,%d1		# should FP2 be moved?
   18302  1.1     is 	bpl.b		fmovm_out_ctrl_fp3	# no
   18303  1.1     is 
   18304  1.1     is 	fmovm.x		&0x20,(%a0)		# yes
   18305  1.1     is 	add.l		&0xc,%a0
   18306  1.1     is 
   18307  1.1     is fmovm_out_ctrl_fp3:
   18308  1.1     is 	lsl.b		&0x1,%d1		# should FP3 be moved?
   18309  1.1     is 	bpl.b		fmovm_out_ctrl_fp4	# no
   18310  1.1     is 
   18311  1.1     is 	fmovm.x		&0x10,(%a0)		# yes
   18312  1.1     is 	add.l		&0xc,%a0
   18313  1.1     is 
   18314  1.1     is fmovm_out_ctrl_fp4:
   18315  1.1     is 	lsl.b		&0x1,%d1		# should FP4 be moved?
   18316  1.1     is 	bpl.b		fmovm_out_ctrl_fp5	# no
   18317  1.1     is 
   18318  1.1     is 	fmovm.x		&0x08,(%a0)		# yes
   18319  1.1     is 	add.l		&0xc,%a0
   18320  1.1     is 
   18321  1.1     is fmovm_out_ctrl_fp5:
   18322  1.1     is 	lsl.b		&0x1,%d1		# should FP5 be moved?
   18323  1.1     is 	bpl.b		fmovm_out_ctrl_fp6	# no
   18324  1.1     is 
   18325  1.1     is 	fmovm.x		&0x04,(%a0)		# yes
   18326  1.1     is 	add.l		&0xc,%a0
   18327  1.1     is 
   18328  1.1     is fmovm_out_ctrl_fp6:
   18329  1.1     is 	lsl.b		&0x1,%d1		# should FP6 be moved?
   18330  1.1     is 	bpl.b		fmovm_out_ctrl_fp7	# no
   18331  1.1     is 
   18332  1.1     is 	fmovm.x		&0x02,(%a0)		# yes
   18333  1.1     is 	add.l		&0xc,%a0
   18334  1.1     is 
   18335  1.1     is fmovm_out_ctrl_fp7:
   18336  1.1     is 	lsl.b		&0x1,%d1		# should FP7 be moved?
   18337  1.1     is 	bpl.b		fmovm_out_ctrl_done	# no
   18338  1.1     is 
   18339  1.1     is 	fmovm.x		&0x01,(%a0)		# yes
   18340  1.1     is 	add.l		&0xc,%a0
   18341  1.1     is 
   18342  1.1     is fmovm_out_ctrl_done:
   18343  1.1     is 	mov.l		%a1,L_SCR1(%a6)
   18344  1.1     is 
   18345  1.1     is 	lea		(%sp),%a0		# pass: supervisor src
   18346  1.1     is 	mov.l		%d0,-(%sp)		# save size
   18347  1.1     is 	bsr.l		_dmem_write		# copy data to user mem
   18348  1.1     is 
   18349  1.1     is 	mov.l		(%sp)+,%d0
   18350  1.1     is 	add.l		%d0,%sp			# clear fpreg data from stack
   18351  1.1     is 
   18352  1.1     is 	tst.l		%d1			# did dstore err?
   18353  1.1     is 	bne.w		fmovm_out_err		# yes
   18354  1.1     is 
   18355  1.1     is 	rts
   18356  1.1     is 
   18357  1.1     is ############
   18358  1.1     is # MOVE IN: #
   18359  1.1     is ############
   18360  1.1     is fmovm_data_in:
   18361  1.1     is 	mov.l		%a0,L_SCR1(%a6)
   18362  1.1     is 
   18363  1.1     is 	sub.l		%d0,%sp			# make room for fpregs
   18364  1.1     is 	lea		(%sp),%a1
   18365  1.1     is 
   18366  1.1     is 	mov.l		%d1,-(%sp)		# save bit string for later
   18367  1.1     is 	mov.l		%d0,-(%sp)		# save # of bytes
   18368  1.1     is 
   18369  1.1     is 	bsr.l		_dmem_read		# copy data from user mem
   18370  1.1     is 
   18371  1.1     is 	mov.l		(%sp)+,%d0		# retrieve # of bytes
   18372  1.1     is 
   18373  1.1     is 	tst.l		%d1			# did dfetch fail?
   18374  1.1     is 	bne.w		fmovm_in_err		# yes
   18375  1.1     is 
   18376  1.1     is 	mov.l		(%sp)+,%d1		# load bit string
   18377  1.1     is 
   18378  1.1     is 	lea		(%sp),%a0		# addr of stack
   18379  1.1     is 
   18380  1.1     is 	tst.b		%d1			# should FP0 be moved?
   18381  1.1     is 	bpl.b		fmovm_data_in_fp1	# no
   18382  1.1     is 
   18383  1.1     is 	mov.l		(%a0)+,0x0+EXC_FP0(%a6)	# yes
   18384  1.1     is 	mov.l		(%a0)+,0x4+EXC_FP0(%a6)
   18385  1.1     is 	mov.l		(%a0)+,0x8+EXC_FP0(%a6)
   18386  1.1     is 
   18387  1.1     is fmovm_data_in_fp1:
   18388  1.1     is 	lsl.b		&0x1,%d1		# should FP1 be moved?
   18389  1.1     is 	bpl.b		fmovm_data_in_fp2	# no
   18390  1.1     is 
   18391  1.1     is 	mov.l		(%a0)+,0x0+EXC_FP1(%a6)	# yes
   18392  1.1     is 	mov.l		(%a0)+,0x4+EXC_FP1(%a6)
   18393  1.1     is 	mov.l		(%a0)+,0x8+EXC_FP1(%a6)
   18394  1.1     is 
   18395  1.1     is fmovm_data_in_fp2:
   18396  1.1     is 	lsl.b		&0x1,%d1		# should FP2 be moved?
   18397  1.1     is 	bpl.b		fmovm_data_in_fp3	# no
   18398  1.1     is 
   18399  1.1     is 	fmovm.x		(%a0)+,&0x20		# yes
   18400  1.1     is 
   18401  1.1     is fmovm_data_in_fp3:
   18402  1.1     is 	lsl.b		&0x1,%d1		# should FP3 be moved?
   18403  1.1     is 	bpl.b		fmovm_data_in_fp4	# no
   18404  1.1     is 
   18405  1.1     is 	fmovm.x		(%a0)+,&0x10		# yes
   18406  1.1     is 
   18407  1.1     is fmovm_data_in_fp4:
   18408  1.1     is 	lsl.b		&0x1,%d1		# should FP4 be moved?
   18409  1.1     is 	bpl.b		fmovm_data_in_fp5	# no
   18410  1.1     is 
   18411  1.1     is 	fmovm.x		(%a0)+,&0x08		# yes
   18412  1.1     is 
   18413  1.1     is fmovm_data_in_fp5:
   18414  1.1     is 	lsl.b		&0x1,%d1		# should FP5 be moved?
   18415  1.1     is 	bpl.b		fmovm_data_in_fp6	# no
   18416  1.1     is 
   18417  1.1     is 	fmovm.x		(%a0)+,&0x04		# yes
   18418  1.1     is 
   18419  1.1     is fmovm_data_in_fp6:
   18420  1.1     is 	lsl.b		&0x1,%d1		# should FP6 be moved?
   18421  1.1     is 	bpl.b		fmovm_data_in_fp7	# no
   18422  1.1     is 
   18423  1.1     is 	fmovm.x		(%a0)+,&0x02		# yes
   18424  1.1     is 
   18425  1.1     is fmovm_data_in_fp7:
   18426  1.1     is 	lsl.b		&0x1,%d1		# should FP7 be moved?
   18427  1.1     is 	bpl.b		fmovm_data_in_done	# no
   18428  1.1     is 
   18429  1.1     is 	fmovm.x		(%a0)+,&0x01		# yes
   18430  1.1     is 
   18431  1.1     is fmovm_data_in_done:
   18432  1.1     is 	add.l		%d0,%sp			# remove fpregs from stack
   18433  1.1     is 	rts
   18434  1.1     is 
   18435  1.1     is #####################################
   18436  1.1     is 
   18437  1.1     is fmovm_data_done:
   18438  1.1     is 	rts
   18439  1.1     is 
   18440  1.1     is ##############################################################################
   18441  1.1     is 
   18442  1.1     is #
   18443  1.1     is # table indexed by the operation's bit string that gives the number
   18444  1.1     is # of bytes that will be moved.
   18445  1.1     is #
   18446  1.1     is # number of bytes = (# of 1's in bit string) * 12(bytes/fpreg)
   18447  1.1     is #
   18448  1.1     is tbl_fmovm_size:
   18449  1.1     is 	byte	0x00,0x0c,0x0c,0x18,0x0c,0x18,0x18,0x24
   18450  1.1     is 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18451  1.1     is 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18452  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18453  1.1     is 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18454  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18455  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18456  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18457  1.1     is 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18458  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18459  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18460  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18461  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18462  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18463  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18464  1.1     is 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18465  1.1     is 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18466  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18467  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18468  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18469  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18470  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18471  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18472  1.1     is 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18473  1.1     is 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18474  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18475  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18476  1.1     is 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18477  1.1     is 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18478  1.1     is 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18479  1.1     is 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18480  1.1     is 	byte	0x3c,0x48,0x48,0x54,0x48,0x54,0x54,0x60
   18481  1.1     is 
   18482  1.1     is #
   18483  1.1     is # table to convert a pre-decrement bit string into a post-increment
   18484  1.1     is # or control bit string.
   18485  1.1     is # ex: 	0x00	==>	0x00
   18486  1.1     is #	0x01	==>	0x80
   18487  1.1     is #	0x02	==>	0x40
   18488  1.1     is #		.
   18489  1.1     is #		.
   18490  1.1     is #	0xfd	==>	0xbf
   18491  1.1     is #	0xfe	==>	0x7f
   18492  1.1     is #	0xff	==>	0xff
   18493  1.1     is #
   18494  1.1     is tbl_fmovm_convert:
   18495  1.1     is 	byte	0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0
   18496  1.1     is 	byte	0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0
   18497  1.1     is 	byte	0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8
   18498  1.1     is 	byte	0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8
   18499  1.1     is 	byte	0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4
   18500  1.1     is 	byte	0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4
   18501  1.1     is 	byte	0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec
   18502  1.1     is 	byte	0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc
   18503  1.1     is 	byte	0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2
   18504  1.1     is 	byte	0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2
   18505  1.1     is 	byte	0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea
   18506  1.1     is 	byte	0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa
   18507  1.1     is 	byte	0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6
   18508  1.1     is 	byte	0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6
   18509  1.1     is 	byte	0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee
   18510  1.1     is 	byte	0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe
   18511  1.1     is 	byte	0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1
   18512  1.1     is 	byte	0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1
   18513  1.1     is 	byte	0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9
   18514  1.1     is 	byte	0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9
   18515  1.1     is 	byte	0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5
   18516  1.1     is 	byte	0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5
   18517  1.1     is 	byte	0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed
   18518  1.1     is 	byte	0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd
   18519  1.1     is 	byte	0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3
   18520  1.1     is 	byte	0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3
   18521  1.1     is 	byte	0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb
   18522  1.1     is 	byte	0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb
   18523  1.1     is 	byte	0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7
   18524  1.1     is 	byte	0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7
   18525  1.1     is 	byte	0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef
   18526  1.1     is 	byte	0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
   18527  1.1     is 
   18528  1.1     is 	global		fmovm_calc_ea
   18529  1.1     is ###############################################
   18530  1.1     is # _fmovm_calc_ea: calculate effective address #
   18531  1.1     is ###############################################
   18532  1.1     is fmovm_calc_ea:
   18533  1.1     is 	mov.l		%d0,%a0			# move # bytes to a0
   18534  1.1     is 
   18535  1.1     is # currently, MODE and REG are taken from the EXC_OPWORD. this could be
   18536  1.1     is # easily changed if they were inputs passed in registers.
   18537  1.1     is 	mov.w		EXC_OPWORD(%a6),%d0	# fetch opcode word
   18538  1.1     is 	mov.w		%d0,%d1			# make a copy
   18539  1.1     is 
   18540  1.1     is 	andi.w		&0x3f,%d0		# extract mode field
   18541  1.1     is 	andi.l		&0x7,%d1		# extract reg  field
   18542  1.1     is 
   18543  1.1     is # jump to the corresponding function for each {MODE,REG} pair.
   18544  1.1     is 	mov.w		(tbl_fea_mode.b,%pc,%d0.w*2),%d0 # fetch jmp distance
   18545  1.1     is 	jmp		(tbl_fea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode
   18546  1.1     is 
   18547  1.1     is 	swbeg		&64
   18548  1.1     is tbl_fea_mode:
   18549  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18550  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18551  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18552  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18553  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18554  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18555  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18556  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18557  1.1     is 
   18558  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18559  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18560  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18561  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18562  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18563  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18564  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18565  1.1     is 	short		tbl_fea_mode	-	tbl_fea_mode
   18566  1.1     is 
   18567  1.1     is 	short		faddr_ind_a0	- 	tbl_fea_mode
   18568  1.1     is 	short		faddr_ind_a1	- 	tbl_fea_mode
   18569  1.1     is 	short		faddr_ind_a2	- 	tbl_fea_mode
   18570  1.1     is 	short		faddr_ind_a3 	- 	tbl_fea_mode
   18571  1.1     is 	short		faddr_ind_a4 	- 	tbl_fea_mode
   18572  1.1     is 	short		faddr_ind_a5 	- 	tbl_fea_mode
   18573  1.1     is 	short		faddr_ind_a6 	- 	tbl_fea_mode
   18574  1.1     is 	short		faddr_ind_a7 	- 	tbl_fea_mode
   18575  1.1     is 
   18576  1.1     is 	short		faddr_ind_p_a0	- 	tbl_fea_mode
   18577  1.1     is 	short		faddr_ind_p_a1 	- 	tbl_fea_mode
   18578  1.1     is 	short		faddr_ind_p_a2 	- 	tbl_fea_mode
   18579  1.1     is 	short		faddr_ind_p_a3 	- 	tbl_fea_mode
   18580  1.1     is 	short		faddr_ind_p_a4 	- 	tbl_fea_mode
   18581  1.1     is 	short		faddr_ind_p_a5 	- 	tbl_fea_mode
   18582  1.1     is 	short		faddr_ind_p_a6 	- 	tbl_fea_mode
   18583  1.1     is 	short		faddr_ind_p_a7 	- 	tbl_fea_mode
   18584  1.1     is 
   18585  1.1     is 	short		faddr_ind_m_a0 	- 	tbl_fea_mode
   18586  1.1     is 	short		faddr_ind_m_a1 	- 	tbl_fea_mode
   18587  1.1     is 	short		faddr_ind_m_a2 	- 	tbl_fea_mode
   18588  1.1     is 	short		faddr_ind_m_a3 	- 	tbl_fea_mode
   18589  1.1     is 	short		faddr_ind_m_a4 	- 	tbl_fea_mode
   18590  1.1     is 	short		faddr_ind_m_a5 	- 	tbl_fea_mode
   18591  1.1     is 	short		faddr_ind_m_a6 	- 	tbl_fea_mode
   18592  1.1     is 	short		faddr_ind_m_a7 	- 	tbl_fea_mode
   18593  1.1     is 
   18594  1.1     is 	short		faddr_ind_disp_a0	- 	tbl_fea_mode
   18595  1.1     is 	short		faddr_ind_disp_a1 	- 	tbl_fea_mode
   18596  1.1     is 	short		faddr_ind_disp_a2 	- 	tbl_fea_mode
   18597  1.1     is 	short		faddr_ind_disp_a3 	- 	tbl_fea_mode
   18598  1.1     is 	short		faddr_ind_disp_a4 	- 	tbl_fea_mode
   18599  1.1     is 	short		faddr_ind_disp_a5 	- 	tbl_fea_mode
   18600  1.1     is 	short		faddr_ind_disp_a6 	- 	tbl_fea_mode
   18601  1.1     is 	short		faddr_ind_disp_a7	-	tbl_fea_mode
   18602  1.1     is 
   18603  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18604  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18605  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18606  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18607  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18608  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18609  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18610  1.1     is 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18611  1.1     is 
   18612  1.1     is 	short		fabs_short	- 	tbl_fea_mode
   18613  1.1     is 	short		fabs_long	- 	tbl_fea_mode
   18614  1.1     is 	short		fpc_ind		- 	tbl_fea_mode
   18615  1.1     is 	short		fpc_ind_ext	- 	tbl_fea_mode
   18616  1.1     is 	short		tbl_fea_mode	- 	tbl_fea_mode
   18617  1.1     is 	short		tbl_fea_mode	- 	tbl_fea_mode
   18618  1.1     is 	short		tbl_fea_mode	- 	tbl_fea_mode
   18619  1.1     is 	short		tbl_fea_mode	- 	tbl_fea_mode
   18620  1.1     is 
   18621  1.1     is ###################################
   18622  1.1     is # Address register indirect: (An) #
   18623  1.1     is ###################################
   18624  1.1     is faddr_ind_a0:
   18625  1.1     is 	mov.l		EXC_DREGS+0x8(%a6),%a0	# Get current a0
   18626  1.1     is 	rts
   18627  1.1     is 
   18628  1.1     is faddr_ind_a1:
   18629  1.1     is 	mov.l		EXC_DREGS+0xc(%a6),%a0	# Get current a1
   18630  1.1     is 	rts
   18631  1.1     is 
   18632  1.1     is faddr_ind_a2:
   18633  1.1     is 	mov.l		%a2,%a0			# Get current a2
   18634  1.1     is 	rts
   18635  1.1     is 
   18636  1.1     is faddr_ind_a3:
   18637  1.1     is 	mov.l		%a3,%a0			# Get current a3
   18638  1.1     is 	rts
   18639  1.1     is 
   18640  1.1     is faddr_ind_a4:
   18641  1.1     is 	mov.l		%a4,%a0			# Get current a4
   18642  1.1     is 	rts
   18643  1.1     is 
   18644  1.1     is faddr_ind_a5:
   18645  1.1     is 	mov.l		%a5,%a0			# Get current a5
   18646  1.1     is 	rts
   18647  1.1     is 
   18648  1.1     is faddr_ind_a6:
   18649  1.1     is 	mov.l		(%a6),%a0		# Get current a6
   18650  1.1     is 	rts
   18651  1.1     is 
   18652  1.1     is faddr_ind_a7:
   18653  1.1     is 	mov.l		EXC_A7(%a6),%a0		# Get current a7
   18654  1.1     is 	rts
   18655  1.1     is 
   18656  1.1     is #####################################################
   18657  1.1     is # Address register indirect w/ postincrement: (An)+ #
   18658  1.1     is #####################################################
   18659  1.1     is faddr_ind_p_a0:
   18660  1.1     is 	mov.l		EXC_DREGS+0x8(%a6),%d0	# Get current a0
   18661  1.1     is 	mov.l		%d0,%d1
   18662  1.1     is 	add.l		%a0,%d1			# Increment
   18663  1.1     is 	mov.l		%d1,EXC_DREGS+0x8(%a6)	# Save incr value
   18664  1.1     is 	mov.l		%d0,%a0
   18665  1.1     is 	rts
   18666  1.1     is 
   18667  1.1     is faddr_ind_p_a1:
   18668  1.1     is 	mov.l		EXC_DREGS+0xc(%a6),%d0	# Get current a1
   18669  1.1     is 	mov.l		%d0,%d1
   18670  1.1     is 	add.l		%a0,%d1			# Increment
   18671  1.1     is 	mov.l		%d1,EXC_DREGS+0xc(%a6)	# Save incr value
   18672  1.1     is 	mov.l		%d0,%a0
   18673  1.1     is 	rts
   18674  1.1     is 
   18675  1.1     is faddr_ind_p_a2:
   18676  1.1     is 	mov.l		%a2,%d0			# Get current a2
   18677  1.1     is 	mov.l		%d0,%d1
   18678  1.1     is 	add.l		%a0,%d1			# Increment
   18679  1.1     is 	mov.l		%d1,%a2			# Save incr value
   18680  1.1     is 	mov.l		%d0,%a0
   18681  1.1     is 	rts
   18682  1.1     is 
   18683  1.1     is faddr_ind_p_a3:
   18684  1.1     is 	mov.l		%a3,%d0			# Get current a3
   18685  1.1     is 	mov.l		%d0,%d1
   18686  1.1     is 	add.l		%a0,%d1			# Increment
   18687  1.1     is 	mov.l		%d1,%a3			# Save incr value
   18688  1.1     is 	mov.l		%d0,%a0
   18689  1.1     is 	rts
   18690  1.1     is 
   18691  1.1     is faddr_ind_p_a4:
   18692  1.1     is 	mov.l		%a4,%d0			# Get current a4
   18693  1.1     is 	mov.l		%d0,%d1
   18694  1.1     is 	add.l		%a0,%d1			# Increment
   18695  1.1     is 	mov.l		%d1,%a4			# Save incr value
   18696  1.1     is 	mov.l		%d0,%a0
   18697  1.1     is 	rts
   18698  1.1     is 
   18699  1.1     is faddr_ind_p_a5:
   18700  1.1     is 	mov.l		%a5,%d0			# Get current a5
   18701  1.1     is 	mov.l		%d0,%d1
   18702  1.1     is 	add.l		%a0,%d1			# Increment
   18703  1.1     is 	mov.l		%d1,%a5			# Save incr value
   18704  1.1     is 	mov.l		%d0,%a0
   18705  1.1     is 	rts
   18706  1.1     is 
   18707  1.1     is faddr_ind_p_a6:
   18708  1.1     is 	mov.l		(%a6),%d0		# Get current a6
   18709  1.1     is 	mov.l		%d0,%d1
   18710  1.1     is 	add.l		%a0,%d1			# Increment
   18711  1.1     is 	mov.l		%d1,(%a6)		# Save incr value
   18712  1.1     is 	mov.l		%d0,%a0
   18713  1.1     is 	rts
   18714  1.1     is 
   18715  1.1     is faddr_ind_p_a7:
   18716  1.1     is 	mov.b		&mia7_flg,SPCOND_FLG(%a6) # set "special case" flag
   18717  1.1     is 
   18718  1.1     is 	mov.l		EXC_A7(%a6),%d0		# Get current a7
   18719  1.1     is 	mov.l		%d0,%d1
   18720  1.1     is 	add.l		%a0,%d1			# Increment
   18721  1.1     is 	mov.l		%d1,EXC_A7(%a6)		# Save incr value
   18722  1.1     is 	mov.l		%d0,%a0
   18723  1.1     is 	rts
   18724  1.1     is 
   18725  1.1     is ####################################################
   18726  1.1     is # Address register indirect w/ predecrement: -(An) #
   18727  1.1     is ####################################################
   18728  1.1     is faddr_ind_m_a0:
   18729  1.1     is 	mov.l		EXC_DREGS+0x8(%a6),%d0	# Get current a0
   18730  1.1     is 	sub.l		%a0,%d0			# Decrement
   18731  1.1     is 	mov.l		%d0,EXC_DREGS+0x8(%a6)	# Save decr value
   18732  1.1     is 	mov.l		%d0,%a0
   18733  1.1     is 	rts
   18734  1.1     is 
   18735  1.1     is faddr_ind_m_a1:
   18736  1.1     is 	mov.l		EXC_DREGS+0xc(%a6),%d0	# Get current a1
   18737  1.1     is 	sub.l		%a0,%d0			# Decrement
   18738  1.1     is 	mov.l		%d0,EXC_DREGS+0xc(%a6)	# Save decr value
   18739  1.1     is 	mov.l		%d0,%a0
   18740  1.1     is 	rts
   18741  1.1     is 
   18742  1.1     is faddr_ind_m_a2:
   18743  1.1     is 	mov.l		%a2,%d0			# Get current a2
   18744  1.1     is 	sub.l		%a0,%d0			# Decrement
   18745  1.1     is 	mov.l		%d0,%a2			# Save decr value
   18746  1.1     is 	mov.l		%d0,%a0
   18747  1.1     is 	rts
   18748  1.1     is 
   18749  1.1     is faddr_ind_m_a3:
   18750  1.1     is 	mov.l		%a3,%d0			# Get current a3
   18751  1.1     is 	sub.l		%a0,%d0			# Decrement
   18752  1.1     is 	mov.l		%d0,%a3			# Save decr value
   18753  1.1     is 	mov.l		%d0,%a0
   18754  1.1     is 	rts
   18755  1.1     is 
   18756  1.1     is faddr_ind_m_a4:
   18757  1.1     is 	mov.l		%a4,%d0			# Get current a4
   18758  1.1     is 	sub.l		%a0,%d0			# Decrement
   18759  1.1     is 	mov.l		%d0,%a4			# Save decr value
   18760  1.1     is 	mov.l		%d0,%a0
   18761  1.1     is 	rts
   18762  1.1     is 
   18763  1.1     is faddr_ind_m_a5:
   18764  1.1     is 	mov.l		%a5,%d0			# Get current a5
   18765  1.1     is 	sub.l		%a0,%d0			# Decrement
   18766  1.1     is 	mov.l		%d0,%a5			# Save decr value
   18767  1.1     is 	mov.l		%d0,%a0
   18768  1.1     is 	rts
   18769  1.1     is 
   18770  1.1     is faddr_ind_m_a6:
   18771  1.1     is 	mov.l		(%a6),%d0		# Get current a6
   18772  1.1     is 	sub.l		%a0,%d0			# Decrement
   18773  1.1     is 	mov.l		%d0,(%a6)		# Save decr value
   18774  1.1     is 	mov.l		%d0,%a0
   18775  1.1     is 	rts
   18776  1.1     is 
   18777  1.1     is faddr_ind_m_a7:
   18778  1.1     is 	mov.b		&mda7_flg,SPCOND_FLG(%a6) # set "special case" flag
   18779  1.1     is 
   18780  1.1     is 	mov.l		EXC_A7(%a6),%d0		# Get current a7
   18781  1.1     is 	sub.l		%a0,%d0			# Decrement
   18782  1.1     is 	mov.l		%d0,EXC_A7(%a6)		# Save decr value
   18783  1.1     is 	mov.l		%d0,%a0
   18784  1.1     is 	rts
   18785  1.1     is 
   18786  1.1     is ########################################################
   18787  1.1     is # Address register indirect w/ displacement: (d16, An) #
   18788  1.1     is ########################################################
   18789  1.1     is faddr_ind_disp_a0:
   18790  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18791  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18792  1.1     is 	bsr.l		_imem_read_word
   18793  1.1     is 
   18794  1.1     is 	tst.l		%d1			# did ifetch fail?
   18795  1.1     is 	bne.l		iea_iacc		# yes
   18796  1.1     is 
   18797  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18798  1.1     is 
   18799  1.1     is 	add.l		EXC_DREGS+0x8(%a6),%a0	# a0 + d16
   18800  1.1     is 	rts
   18801  1.1     is 
   18802  1.1     is faddr_ind_disp_a1:
   18803  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18804  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18805  1.1     is 	bsr.l		_imem_read_word
   18806  1.1     is 
   18807  1.1     is 	tst.l		%d1			# did ifetch fail?
   18808  1.1     is 	bne.l		iea_iacc		# yes
   18809  1.1     is 
   18810  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18811  1.1     is 
   18812  1.1     is 	add.l		EXC_DREGS+0xc(%a6),%a0	# a1 + d16
   18813  1.1     is 	rts
   18814  1.1     is 
   18815  1.1     is faddr_ind_disp_a2:
   18816  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18817  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18818  1.1     is 	bsr.l		_imem_read_word
   18819  1.1     is 
   18820  1.1     is 	tst.l		%d1			# did ifetch fail?
   18821  1.1     is 	bne.l		iea_iacc		# yes
   18822  1.1     is 
   18823  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18824  1.1     is 
   18825  1.1     is 	add.l		%a2,%a0			# a2 + d16
   18826  1.1     is 	rts
   18827  1.1     is 
   18828  1.1     is faddr_ind_disp_a3:
   18829  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18830  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18831  1.1     is 	bsr.l		_imem_read_word
   18832  1.1     is 
   18833  1.1     is 	tst.l		%d1			# did ifetch fail?
   18834  1.1     is 	bne.l		iea_iacc		# yes
   18835  1.1     is 
   18836  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18837  1.1     is 
   18838  1.1     is 	add.l		%a3,%a0			# a3 + d16
   18839  1.1     is 	rts
   18840  1.1     is 
   18841  1.1     is faddr_ind_disp_a4:
   18842  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18843  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18844  1.1     is 	bsr.l		_imem_read_word
   18845  1.1     is 
   18846  1.1     is 	tst.l		%d1			# did ifetch fail?
   18847  1.1     is 	bne.l		iea_iacc		# yes
   18848  1.1     is 
   18849  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18850  1.1     is 
   18851  1.1     is 	add.l		%a4,%a0			# a4 + d16
   18852  1.1     is 	rts
   18853  1.1     is 
   18854  1.1     is faddr_ind_disp_a5:
   18855  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18856  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18857  1.1     is 	bsr.l		_imem_read_word
   18858  1.1     is 
   18859  1.1     is 	tst.l		%d1			# did ifetch fail?
   18860  1.1     is 	bne.l		iea_iacc		# yes
   18861  1.1     is 
   18862  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18863  1.1     is 
   18864  1.1     is 	add.l		%a5,%a0			# a5 + d16
   18865  1.1     is 	rts
   18866  1.1     is 
   18867  1.1     is faddr_ind_disp_a6:
   18868  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18869  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18870  1.1     is 	bsr.l		_imem_read_word
   18871  1.1     is 
   18872  1.1     is 	tst.l		%d1			# did ifetch fail?
   18873  1.1     is 	bne.l		iea_iacc		# yes
   18874  1.1     is 
   18875  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18876  1.1     is 
   18877  1.1     is 	add.l		(%a6),%a0		# a6 + d16
   18878  1.1     is 	rts
   18879  1.1     is 
   18880  1.1     is faddr_ind_disp_a7:
   18881  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18882  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18883  1.1     is 	bsr.l		_imem_read_word
   18884  1.1     is 
   18885  1.1     is 	tst.l		%d1			# did ifetch fail?
   18886  1.1     is 	bne.l		iea_iacc		# yes
   18887  1.1     is 
   18888  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18889  1.1     is 
   18890  1.1     is 	add.l		EXC_A7(%a6),%a0		# a7 + d16
   18891  1.1     is 	rts
   18892  1.1     is 
   18893  1.1     is ########################################################################
   18894  1.1     is # Address register indirect w/ index(8-bit displacement): (d8, An, Xn) #
   18895  1.1     is #    "       "         "    w/   "  (base displacement): (bd, An, Xn)  #
   18896  1.1     is # Memory indirect postindexed: ([bd, An], Xn, od)		       #
   18897  1.1     is # Memory indirect preindexed: ([bd, An, Xn], od)		       #
   18898  1.1     is ########################################################################
   18899  1.1     is faddr_ind_ext:
   18900  1.1     is 	addq.l		&0x8,%d1
   18901  1.1     is 	bsr.l		fetch_dreg		# fetch base areg
   18902  1.1     is 	mov.l		%d0,-(%sp)
   18903  1.1     is 
   18904  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18905  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18906  1.1     is 	bsr.l		_imem_read_word		# fetch extword in d0
   18907  1.1     is 
   18908  1.1     is 	tst.l		%d1			# did ifetch fail?
   18909  1.1     is 	bne.l		iea_iacc		# yes
   18910  1.1     is 
   18911  1.1     is 	mov.l		(%sp)+,%a0
   18912  1.1     is 
   18913  1.1     is 	btst		&0x8,%d0
   18914  1.1     is 	bne.w		fcalc_mem_ind
   18915  1.1     is 
   18916  1.1     is 	mov.l		%d0,L_SCR1(%a6)		# hold opword
   18917  1.1     is 
   18918  1.1     is 	mov.l		%d0,%d1
   18919  1.1     is 	rol.w		&0x4,%d1
   18920  1.1     is 	andi.w		&0xf,%d1		# extract index regno
   18921  1.1     is 
   18922  1.1     is # count on fetch_dreg() not to alter a0...
   18923  1.1     is 	bsr.l		fetch_dreg		# fetch index
   18924  1.1     is 
   18925  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   18926  1.1     is 	mov.l		L_SCR1(%a6),%d2		# fetch opword
   18927  1.1     is 
   18928  1.1     is 	btst		&0xb,%d2		# is it word or long?
   18929  1.1     is 	bne.b		faii8_long
   18930  1.1     is 	ext.l		%d0			# sign extend word index
   18931  1.1     is faii8_long:
   18932  1.1     is 	mov.l		%d2,%d1
   18933  1.1     is 	rol.w		&0x7,%d1
   18934  1.1     is 	andi.l		&0x3,%d1		# extract scale value
   18935  1.1     is 
   18936  1.1     is 	lsl.l		%d1,%d0			# shift index by scale
   18937  1.1     is 
   18938  1.1     is 	extb.l		%d2			# sign extend displacement
   18939  1.1     is 	add.l		%d2,%d0			# index + disp
   18940  1.1     is 	add.l		%d0,%a0			# An + (index + disp)
   18941  1.1     is 
   18942  1.1     is 	mov.l		(%sp)+,%d2		# restore old d2
   18943  1.1     is 	rts
   18944  1.1     is 
   18945  1.1     is ###########################
   18946  1.1     is # Absolute short: (XXX).W #
   18947  1.1     is ###########################
   18948  1.1     is fabs_short:
   18949  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18950  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18951  1.1     is 	bsr.l		_imem_read_word		# fetch short address
   18952  1.1     is 
   18953  1.1     is 	tst.l		%d1			# did ifetch fail?
   18954  1.1     is 	bne.l		iea_iacc		# yes
   18955  1.1     is 
   18956  1.1     is 	mov.w		%d0,%a0			# return <ea> in a0
   18957  1.1     is 	rts
   18958  1.1     is 
   18959  1.1     is ##########################
   18960  1.1     is # Absolute long: (XXX).L #
   18961  1.1     is ##########################
   18962  1.1     is fabs_long:
   18963  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18964  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18965  1.1     is 	bsr.l		_imem_read_long		# fetch long address
   18966  1.1     is 
   18967  1.1     is 	tst.l		%d1			# did ifetch fail?
   18968  1.1     is 	bne.l		iea_iacc		# yes
   18969  1.1     is 
   18970  1.1     is 	mov.l		%d0,%a0			# return <ea> in a0
   18971  1.1     is 	rts
   18972  1.1     is 
   18973  1.1     is #######################################################
   18974  1.1     is # Program counter indirect w/ displacement: (d16, PC) #
   18975  1.1     is #######################################################
   18976  1.1     is fpc_ind:
   18977  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18978  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18979  1.1     is 	bsr.l		_imem_read_word		# fetch word displacement
   18980  1.1     is 
   18981  1.1     is 	tst.l		%d1			# did ifetch fail?
   18982  1.1     is 	bne.l		iea_iacc		# yes
   18983  1.1     is 
   18984  1.1     is 	mov.w		%d0,%a0			# sign extend displacement
   18985  1.1     is 
   18986  1.1     is 	add.l		EXC_EXTWPTR(%a6),%a0	# pc + d16
   18987  1.1     is 
   18988  1.1     is # _imem_read_word() increased the extwptr by 2. need to adjust here.
   18989  1.1     is 	subq.l		&0x2,%a0		# adjust <ea>
   18990  1.1     is 	rts
   18991  1.1     is 
   18992  1.1     is ##########################################################
   18993  1.1     is # PC indirect w/ index(8-bit displacement): (d8, PC, An) #
   18994  1.1     is # "     "     w/   "  (base displacement): (bd, PC, An)  #
   18995  1.1     is # PC memory indirect postindexed: ([bd, PC], Xn, od)     #
   18996  1.1     is # PC memory indirect preindexed: ([bd, PC, Xn], od)      #
   18997  1.1     is ##########################################################
   18998  1.1     is fpc_ind_ext:
   18999  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19000  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19001  1.1     is 	bsr.l		_imem_read_word		# fetch ext word
   19002  1.1     is 
   19003  1.1     is 	tst.l		%d1			# did ifetch fail?
   19004  1.1     is 	bne.l		iea_iacc		# yes
   19005  1.1     is 
   19006  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# put base in a0
   19007  1.1     is 	subq.l		&0x2,%a0		# adjust base
   19008  1.1     is 
   19009  1.1     is 	btst		&0x8,%d0		# is disp only 8 bits?
   19010  1.1     is 	bne.w		fcalc_mem_ind		# calc memory indirect
   19011  1.1     is 
   19012  1.1     is 	mov.l		%d0,L_SCR1(%a6)		# store opword
   19013  1.1     is 
   19014  1.1     is 	mov.l		%d0,%d1			# make extword copy
   19015  1.1     is 	rol.w		&0x4,%d1		# rotate reg num into place
   19016  1.1     is 	andi.w		&0xf,%d1		# extract register number
   19017  1.1     is 
   19018  1.1     is # count on fetch_dreg() not to alter a0...
   19019  1.1     is 	bsr.l		fetch_dreg		# fetch index
   19020  1.1     is 
   19021  1.1     is 	mov.l		%d2,-(%sp)		# save d2
   19022  1.1     is 	mov.l		L_SCR1(%a6),%d2		# fetch opword
   19023  1.1     is 
   19024  1.1     is 	btst		&0xb,%d2		# is index word or long?
   19025  1.1     is 	bne.b		fpii8_long		# long
   19026  1.1     is 	ext.l		%d0			# sign extend word index
   19027  1.1     is fpii8_long:
   19028  1.1     is 	mov.l		%d2,%d1
   19029  1.1     is 	rol.w		&0x7,%d1		# rotate scale value into place
   19030  1.1     is 	andi.l		&0x3,%d1		# extract scale value
   19031  1.1     is 
   19032  1.1     is 	lsl.l		%d1,%d0			# shift index by scale
   19033  1.1     is 
   19034  1.1     is 	extb.l		%d2			# sign extend displacement
   19035  1.1     is 	add.l		%d2,%d0			# disp + index
   19036  1.1     is 	add.l		%d0,%a0			# An + (index + disp)
   19037  1.1     is 
   19038  1.1     is 	mov.l		(%sp)+,%d2		# restore temp register
   19039  1.1     is 	rts
   19040  1.1     is 
   19041  1.1     is # d2 = index
   19042  1.1     is # d3 = base
   19043  1.1     is # d4 = od
   19044  1.1     is # d5 = extword
   19045  1.1     is fcalc_mem_ind:
   19046  1.1     is 	btst		&0x6,%d0		# is the index suppressed?
   19047  1.1     is 	beq.b		fcalc_index
   19048  1.1     is 
   19049  1.1     is 	movm.l		&0x3c00,-(%sp)		# save d2-d5
   19050  1.1     is 
   19051  1.1     is 	mov.l		%d0,%d5			# put extword in d5
   19052  1.1     is 	mov.l		%a0,%d3			# put base in d3
   19053  1.1     is 
   19054  1.1     is 	clr.l		%d2			# yes, so index = 0
   19055  1.1     is 	bra.b		fbase_supp_ck
   19056  1.1     is 
   19057  1.1     is # index:
   19058  1.1     is fcalc_index:
   19059  1.1     is 	mov.l		%d0,L_SCR1(%a6)		# save d0 (opword)
   19060  1.1     is 	bfextu		%d0{&16:&4},%d1		# fetch dreg index
   19061  1.1     is 	bsr.l		fetch_dreg
   19062  1.1     is 
   19063  1.1     is 	movm.l		&0x3c00,-(%sp)		# save d2-d5
   19064  1.1     is 	mov.l		%d0,%d2			# put index in d2
   19065  1.1     is 	mov.l		L_SCR1(%a6),%d5
   19066  1.1     is 	mov.l		%a0,%d3
   19067  1.1     is 
   19068  1.1     is 	btst		&0xb,%d5		# is index word or long?
   19069  1.1     is 	bne.b		fno_ext
   19070  1.1     is 	ext.l		%d2
   19071  1.1     is 
   19072  1.1     is fno_ext:
   19073  1.1     is 	bfextu		%d5{&21:&2},%d0
   19074  1.1     is 	lsl.l		%d0,%d2
   19075  1.1     is 
   19076  1.1     is # base address (passed as parameter in d3):
   19077  1.1     is # we clear the value here if it should actually be suppressed.
   19078  1.1     is fbase_supp_ck:
   19079  1.1     is 	btst		&0x7,%d5		# is the bd suppressed?
   19080  1.1     is 	beq.b		fno_base_sup
   19081  1.1     is 	clr.l		%d3
   19082  1.1     is 
   19083  1.1     is # base displacement:
   19084  1.1     is fno_base_sup:
   19085  1.1     is 	bfextu		%d5{&26:&2},%d0		# get bd size
   19086  1.1     is #	beq.l		fmovm_error		# if (size == 0) it's reserved
   19087  1.1     is 
   19088  1.1     is 	cmpi.b	 	%d0,&0x2
   19089  1.1     is 	blt.b		fno_bd
   19090  1.1     is 	beq.b		fget_word_bd
   19091  1.1     is 
   19092  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19093  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19094  1.1     is 	bsr.l		_imem_read_long
   19095  1.1     is 
   19096  1.1     is 	tst.l		%d1			# did ifetch fail?
   19097  1.1     is 	bne.l		fcea_iacc		# yes
   19098  1.1     is 
   19099  1.1     is 	bra.b		fchk_ind
   19100  1.1     is 
   19101  1.1     is fget_word_bd:
   19102  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19103  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19104  1.1     is 	bsr.l		_imem_read_word
   19105  1.1     is 
   19106  1.1     is 	tst.l		%d1			# did ifetch fail?
   19107  1.1     is 	bne.l		fcea_iacc		# yes
   19108  1.1     is 
   19109  1.1     is 	ext.l		%d0			# sign extend bd
   19110  1.1     is 
   19111  1.1     is fchk_ind:
   19112  1.1     is 	add.l		%d0,%d3			# base += bd
   19113  1.1     is 
   19114  1.1     is # outer displacement:
   19115  1.1     is fno_bd:
   19116  1.1     is 	bfextu		%d5{&30:&2},%d0		# is od suppressed?
   19117  1.1     is 	beq.w		faii_bd
   19118  1.1     is 
   19119  1.1     is 	cmpi.b	 	%d0,&0x2
   19120  1.1     is 	blt.b		fnull_od
   19121  1.1     is 	beq.b		fword_od
   19122  1.1     is 
   19123  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19124  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19125  1.1     is 	bsr.l		_imem_read_long
   19126  1.1     is 
   19127  1.1     is 	tst.l		%d1			# did ifetch fail?
   19128  1.1     is 	bne.l		fcea_iacc		# yes
   19129  1.1     is 
   19130  1.1     is 	bra.b 		fadd_them
   19131  1.1     is 
   19132  1.1     is fword_od:
   19133  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19134  1.1     is 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19135  1.1     is 	bsr.l		_imem_read_word
   19136  1.1     is 
   19137  1.1     is 	tst.l		%d1			# did ifetch fail?
   19138  1.1     is 	bne.l		fcea_iacc		# yes
   19139  1.1     is 
   19140  1.1     is 	ext.l		%d0			# sign extend od
   19141  1.1     is 	bra.b		fadd_them
   19142  1.1     is 
   19143  1.1     is fnull_od:
   19144  1.1     is 	clr.l		%d0
   19145  1.1     is 
   19146  1.1     is fadd_them:
   19147  1.1     is 	mov.l		%d0,%d4
   19148  1.1     is 
   19149  1.1     is 	btst		&0x2,%d5		# pre or post indexing?
   19150  1.1     is 	beq.b		fpre_indexed
   19151  1.1     is 
   19152  1.1     is 	mov.l		%d3,%a0
   19153  1.1     is 	bsr.l		_dmem_read_long
   19154  1.1     is 
   19155  1.1     is 	tst.l		%d1			# did dfetch fail?
   19156  1.1     is 	bne.w		fcea_err		# yes
   19157  1.1     is 
   19158  1.1     is 	add.l		%d2,%d0			# <ea> += index
   19159  1.1     is 	add.l		%d4,%d0			# <ea> += od
   19160  1.1     is 	bra.b		fdone_ea
   19161  1.1     is 
   19162  1.1     is fpre_indexed:
   19163  1.1     is 	add.l		%d2,%d3			# preindexing
   19164  1.1     is 	mov.l		%d3,%a0
   19165  1.1     is 	bsr.l		_dmem_read_long
   19166  1.1     is 
   19167  1.1     is 	tst.l		%d1			# did dfetch fail?
   19168  1.1     is 	bne.w		fcea_err		# yes
   19169  1.1     is 
   19170  1.1     is 	add.l		%d4,%d0			# ea += od
   19171  1.1     is 	bra.b		fdone_ea
   19172  1.1     is 
   19173  1.1     is faii_bd:
   19174  1.1     is 	add.l		%d2,%d3			# ea = (base + bd) + index
   19175  1.1     is 	mov.l		%d3,%d0
   19176  1.1     is fdone_ea:
   19177  1.1     is 	mov.l		%d0,%a0
   19178  1.1     is 
   19179  1.1     is 	movm.l		(%sp)+,&0x003c		# restore d2-d5
   19180  1.1     is 	rts
   19181  1.1     is 
   19182  1.1     is #########################################################
   19183  1.1     is fcea_err:
   19184  1.1     is 	mov.l		%d3,%a0
   19185  1.1     is 
   19186  1.1     is 	movm.l		(%sp)+,&0x003c		# restore d2-d5
   19187  1.1     is 	mov.w		&0x0101,%d0
   19188  1.1     is 	bra.l		iea_dacc
   19189  1.1     is 
   19190  1.1     is fcea_iacc:
   19191  1.1     is 	movm.l		(%sp)+,&0x003c		# restore d2-d5
   19192  1.1     is 	bra.l		iea_iacc
   19193  1.1     is 
   19194  1.1     is fmovm_out_err:
   19195  1.1     is 	bsr.l		restore
   19196  1.1     is 	mov.w		&0x00e1,%d0
   19197  1.1     is 	bra.b		fmovm_err
   19198  1.1     is 
   19199  1.1     is fmovm_in_err:
   19200  1.1     is 	bsr.l		restore
   19201  1.1     is 	mov.w		&0x0161,%d0
   19202  1.1     is 
   19203  1.1     is fmovm_err:
   19204  1.1     is 	mov.l		L_SCR1(%a6),%a0
   19205  1.1     is 	bra.l		iea_dacc
   19206  1.1     is 
   19207  1.1     is #########################################################################
   19208  1.1     is # XDEF ****************************************************************	#
   19209  1.1     is # 	fmovm_ctrl(): emulate fmovm.l of control registers instr	#
   19210  1.1     is #									#
   19211  1.1     is # XREF ****************************************************************	#
   19212  1.1     is #	_imem_read_long() - read longword from memory			#
   19213  1.1     is #	iea_iacc() - _imem_read_long() failed; error recovery		#
   19214  1.1     is #									#
   19215  1.1     is # INPUT ***************************************************************	#
   19216  1.1     is #	None								#
   19217  1.1     is # 									#
   19218  1.1     is # OUTPUT **************************************************************	#
   19219  1.1     is #	If _imem_read_long() doesn't fail:				#
   19220  1.1     is #		USER_FPCR(a6)  = new FPCR value				#
   19221  1.1     is #		USER_FPSR(a6)  = new FPSR value				#
   19222  1.1     is #		USER_FPIAR(a6) = new FPIAR value			#
   19223  1.1     is #									#
   19224  1.1     is # ALGORITHM ***********************************************************	#
   19225  1.1     is # 	Decode the instruction type by looking at the extension word 	#
   19226  1.1     is # in order to see how many control registers to fetch from memory.	#
   19227  1.1     is # Fetch them using _imem_read_long(). If this fetch fails, exit through	#
   19228  1.1     is # the special access error exit handler iea_iacc().			#
   19229  1.1     is #									#
   19230  1.1     is # Instruction word decoding:						#
   19231  1.1     is #									#
   19232  1.1     is # 	fmovem.l #<data>, {FPIAR&|FPCR&|FPSR}				#
   19233  1.1     is #									#
   19234  1.1     is #		WORD1			WORD2				#
   19235  1.1     is #	1111 0010 00 111100	100$ $$00 0000 0000			#
   19236  1.1     is #									#
   19237  1.1     is #	$$$ (100): FPCR							#
   19238  1.1     is #	    (010): FPSR							#
   19239  1.1     is #	    (001): FPIAR						#
   19240  1.1     is #	    (000): FPIAR						#
   19241  1.1     is #									#
   19242  1.1     is #########################################################################
   19243  1.1     is 
   19244  1.1     is 	global		fmovm_ctrl
   19245  1.1     is fmovm_ctrl:
   19246  1.1     is 	mov.b		EXC_EXTWORD(%a6),%d0	# fetch reg select bits
   19247  1.1     is 	cmpi.b		%d0,&0x9c		# fpcr & fpsr & fpiar ?
   19248  1.1     is 	beq.w		fctrl_in_7		# yes
   19249  1.1     is 	cmpi.b		%d0,&0x98		# fpcr & fpsr ?
   19250  1.1     is 	beq.w		fctrl_in_6		# yes
   19251  1.1     is 	cmpi.b		%d0,&0x94		# fpcr & fpiar ?
   19252  1.1     is 	beq.b		fctrl_in_5		# yes
   19253  1.1     is 
   19254  1.1     is # fmovem.l #<data>, fpsr/fpiar
   19255  1.1     is fctrl_in_3:
   19256  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19257  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19258  1.1     is 	bsr.l		_imem_read_long		# fetch FPSR from mem
   19259  1.1     is 
   19260  1.1     is 	tst.l		%d1			# did ifetch fail?
   19261  1.1     is 	bne.l		iea_iacc		# yes
   19262  1.1     is 
   19263  1.1     is 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to stack
   19264  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19265  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19266  1.1     is 	bsr.l		_imem_read_long		# fetch FPIAR from mem
   19267  1.1     is 
   19268  1.1     is 	tst.l		%d1			# did ifetch fail?
   19269  1.1     is 	bne.l		iea_iacc		# yes
   19270  1.1     is 
   19271  1.1     is 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to stack
   19272  1.1     is 	rts
   19273  1.1     is 
   19274  1.1     is # fmovem.l #<data>, fpcr/fpiar
   19275  1.1     is fctrl_in_5:
   19276  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19277  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19278  1.1     is 	bsr.l		_imem_read_long		# fetch FPCR from mem
   19279  1.1     is 
   19280  1.1     is 	tst.l		%d1			# did ifetch fail?
   19281  1.1     is 	bne.l		iea_iacc		# yes
   19282  1.1     is 
   19283  1.1     is 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to stack
   19284  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19285  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19286  1.1     is 	bsr.l		_imem_read_long		# fetch FPIAR from mem
   19287  1.1     is 
   19288  1.1     is 	tst.l		%d1			# did ifetch fail?
   19289  1.1     is 	bne.l		iea_iacc		# yes
   19290  1.1     is 
   19291  1.1     is 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to stack
   19292  1.1     is 	rts
   19293  1.1     is 
   19294  1.1     is # fmovem.l #<data>, fpcr/fpsr
   19295  1.1     is fctrl_in_6:
   19296  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19297  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19298  1.1     is 	bsr.l		_imem_read_long		# fetch FPCR from mem
   19299  1.1     is 
   19300  1.1     is 	tst.l		%d1			# did ifetch fail?
   19301  1.1     is 	bne.l		iea_iacc		# yes
   19302  1.1     is 
   19303  1.1     is 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to mem
   19304  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19305  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19306  1.1     is 	bsr.l		_imem_read_long		# fetch FPSR from mem
   19307  1.1     is 
   19308  1.1     is 	tst.l		%d1			# did ifetch fail?
   19309  1.1     is 	bne.l		iea_iacc		# yes
   19310  1.1     is 
   19311  1.1     is 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to mem
   19312  1.1     is 	rts
   19313  1.1     is 
   19314  1.1     is # fmovem.l #<data>, fpcr/fpsr/fpiar
   19315  1.1     is fctrl_in_7:
   19316  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19317  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19318  1.1     is 	bsr.l		_imem_read_long		# fetch FPCR from mem
   19319  1.1     is 
   19320  1.1     is 	tst.l		%d1			# did ifetch fail?
   19321  1.1     is 	bne.l		iea_iacc		# yes
   19322  1.1     is 
   19323  1.1     is 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to mem
   19324  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19325  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19326  1.1     is 	bsr.l		_imem_read_long		# fetch FPSR from mem
   19327  1.1     is 
   19328  1.1     is 	tst.l		%d1			# did ifetch fail?
   19329  1.1     is 	bne.l		iea_iacc		# yes
   19330  1.1     is 
   19331  1.1     is 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to mem
   19332  1.1     is 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19333  1.1     is 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19334  1.1     is 	bsr.l		_imem_read_long		# fetch FPIAR from mem
   19335  1.1     is 
   19336  1.1     is 	tst.l		%d1			# did ifetch fail?
   19337  1.1     is 	bne.l		iea_iacc		# yes
   19338  1.1     is 
   19339  1.1     is 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to mem
   19340  1.1     is 	rts
   19341  1.1     is 
   19342  1.1     is #########################################################################
   19343  1.1     is # XDEF ****************************************************************	#
   19344  1.1     is #	_dcalc_ea(): calc correct <ea> from <ea> stacked on exception	#
   19345  1.1     is #									#
   19346  1.1     is # XREF ****************************************************************	#
   19347  1.1     is #	inc_areg() - increment an address register			#
   19348  1.1     is #	dec_areg() - decrement an address register			#
   19349  1.1     is #									#
   19350  1.1     is # INPUT ***************************************************************	#
   19351  1.1     is #	d0 = number of bytes to adjust <ea> by				#
   19352  1.1     is # 									#
   19353  1.1     is # OUTPUT **************************************************************	#
   19354  1.1     is #	None								#
   19355  1.1     is #									#
   19356  1.1     is # ALGORITHM ***********************************************************	#
   19357  1.1     is # "Dummy" CALCulate Effective Address:					#
   19358  1.1     is # 	The stacked <ea> for FP unimplemented instructions and opclass	#
   19359  1.1     is #	two packed instructions is correct with the exception of...	#
   19360  1.1     is #									#
   19361  1.1     is #	1) -(An)   : The register is not updated regardless of size.	#
   19362  1.1     is #		     Also, for extended precision and packed, the 	#
   19363  1.1     is #		     stacked <ea> value is 8 bytes too big		#
   19364  1.1     is #	2) (An)+   : The register is not updated.			#
   19365  1.1     is #	3) #<data> : The upper longword of the immediate operand is 	#
   19366  1.1     is #		     stacked b,w,l and s sizes are completely stacked. 	#
   19367  1.1     is #		     d,x, and p are not.				#
   19368  1.1     is #									#
   19369  1.1     is #########################################################################
   19370  1.1     is 
   19371  1.1     is 	global		_dcalc_ea
   19372  1.1     is _dcalc_ea:
   19373  1.1     is 	mov.l		%d0, %a0		# move # bytes to %a0
   19374  1.1     is 
   19375  1.1     is 	mov.b		1+EXC_OPWORD(%a6), %d0	# fetch opcode word
   19376  1.1     is 	mov.l		%d0, %d1		# make a copy
   19377  1.1     is 
   19378  1.1     is 	andi.w		&0x38, %d0		# extract mode field
   19379  1.1     is 	andi.l		&0x7, %d1		# extract reg  field
   19380  1.1     is 
   19381  1.1     is 	cmpi.b		%d0,&0x18		# is mode (An)+ ?
   19382  1.1     is 	beq.b		dcea_pi			# yes
   19383  1.1     is 
   19384  1.1     is 	cmpi.b		%d0,&0x20		# is mode -(An) ?
   19385  1.1     is 	beq.b		dcea_pd			# yes
   19386  1.1     is 
   19387  1.1     is 	or.w		%d1,%d0			# concat mode,reg
   19388  1.1     is 	cmpi.b		%d0,&0x3c		# is mode #<data>?
   19389  1.1     is 
   19390  1.1     is 	beq.b		dcea_imm		# yes
   19391  1.1     is 
   19392  1.1     is 	mov.l		EXC_EA(%a6),%a0		# return <ea>
   19393  1.1     is 	rts
   19394  1.1     is 
   19395  1.1     is # need to set immediate data flag here since we'll need to do
   19396  1.1     is # an imem_read to fetch this later.
   19397  1.1     is dcea_imm:
   19398  1.1     is 	mov.b		&immed_flg,SPCOND_FLG(%a6)
   19399  1.1     is 	lea		([USER_FPIAR,%a6],0x4),%a0 # no; return <ea>
   19400  1.1     is 	rts
   19401  1.1     is 
   19402  1.1     is # here, the <ea> is stacked correctly. however, we must update the
   19403  1.1     is # address register...
   19404  1.1     is dcea_pi:
   19405  1.1     is 	mov.l		%a0,%d0			# pass amt to inc by
   19406  1.1     is 	bsr.l		inc_areg		# inc addr register
   19407  1.1     is 
   19408  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   19409  1.1     is 	rts
   19410  1.1     is 
   19411  1.1     is # the <ea> is stacked correctly for all but extended and packed which
   19412  1.1     is # the <ea>s are 8 bytes too large.
   19413  1.1     is # it would make no sense to have a pre-decrement to a7 in supervisor
   19414  1.1     is # mode so we don't even worry about this tricky case here : )
   19415  1.1     is dcea_pd:
   19416  1.1     is 	mov.l		%a0,%d0			# pass amt to dec by
   19417  1.1     is 	bsr.l		dec_areg		# dec addr register
   19418  1.1     is 
   19419  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   19420  1.1     is 
   19421  1.1     is 	cmpi.b		%d0,&0xc		# is opsize ext or packed?
   19422  1.1     is 	beq.b		dcea_pd2		# yes
   19423  1.1     is 	rts
   19424  1.1     is dcea_pd2:
   19425  1.1     is 	sub.l		&0x8,%a0		# correct <ea>
   19426  1.1     is 	mov.l		%a0,EXC_EA(%a6)		# put correct <ea> on stack
   19427  1.1     is 	rts
   19428  1.1     is 
   19429  1.1     is #########################################################################
   19430  1.1     is # XDEF ****************************************************************	#
   19431  1.1     is # 	_calc_ea_fout(): calculate correct stacked <ea> for extended	#
   19432  1.1     is #			 and packed data opclass 3 operations.		#
   19433  1.1     is #									#
   19434  1.1     is # XREF ****************************************************************	#
   19435  1.1     is #	None								#
   19436  1.1     is #									#
   19437  1.1     is # INPUT ***************************************************************	#
   19438  1.1     is #	None								#
   19439  1.1     is # 									#
   19440  1.1     is # OUTPUT **************************************************************	#
   19441  1.1     is #	a0 = return correct effective address				#
   19442  1.1     is #									#
   19443  1.1     is # ALGORITHM ***********************************************************	#
   19444  1.1     is #	For opclass 3 extended and packed data operations, the <ea>	#
   19445  1.1     is # stacked for the exception is incorrect for -(an) and (an)+ addressing	#
   19446  1.1     is # modes. Also, while we're at it, the index register itself must get 	#
   19447  1.1     is # updated.								#
   19448  1.1     is # 	So, for -(an), we must subtract 8 off of the stacked <ea> value	#
   19449  1.1     is # and return that value as the correct <ea> and store that value in An.	#
   19450  1.1     is # For (an)+, the stacked <ea> is correct but we must adjust An by +12.	#
   19451  1.1     is #									#
   19452  1.1     is #########################################################################
   19453  1.1     is 
   19454  1.1     is # This calc_ea is currently used to retrieve the correct <ea>
   19455  1.1     is # for fmove outs of type extended and packed.
   19456  1.1     is 	global		_calc_ea_fout
   19457  1.1     is _calc_ea_fout:
   19458  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d0	# fetch opcode word
   19459  1.1     is 	mov.l		%d0,%d1			# make a copy
   19460  1.1     is 
   19461  1.1     is 	andi.w		&0x38,%d0		# extract mode field
   19462  1.1     is 	andi.l		&0x7,%d1		# extract reg  field
   19463  1.1     is 
   19464  1.1     is 	cmpi.b		%d0,&0x18		# is mode (An)+ ?
   19465  1.1     is 	beq.b		ceaf_pi			# yes
   19466  1.1     is 
   19467  1.1     is 	cmpi.b		%d0,&0x20		# is mode -(An) ?
   19468  1.1     is 	beq.w		ceaf_pd			# yes
   19469  1.1     is 
   19470  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   19471  1.1     is 	rts
   19472  1.1     is 
   19473  1.1     is # (An)+ : extended and packed fmove out
   19474  1.1     is #	: stacked <ea> is correct
   19475  1.1     is #	: "An" not updated
   19476  1.1     is ceaf_pi:
   19477  1.1     is 	mov.w		(tbl_ceaf_pi.b,%pc,%d1.w*2),%d1
   19478  1.1     is 	mov.l		EXC_EA(%a6),%a0
   19479  1.1     is 	jmp		(tbl_ceaf_pi.b,%pc,%d1.w*1)
   19480  1.1     is 
   19481  1.1     is 	swbeg		&0x8
   19482  1.1     is tbl_ceaf_pi:
   19483  1.1     is 	short		ceaf_pi0 - tbl_ceaf_pi
   19484  1.1     is 	short		ceaf_pi1 - tbl_ceaf_pi
   19485  1.1     is 	short		ceaf_pi2 - tbl_ceaf_pi
   19486  1.1     is 	short		ceaf_pi3 - tbl_ceaf_pi
   19487  1.1     is 	short		ceaf_pi4 - tbl_ceaf_pi
   19488  1.1     is 	short		ceaf_pi5 - tbl_ceaf_pi
   19489  1.1     is 	short		ceaf_pi6 - tbl_ceaf_pi
   19490  1.1     is 	short		ceaf_pi7 - tbl_ceaf_pi
   19491  1.1     is 
   19492  1.1     is ceaf_pi0:
   19493  1.1     is 	addi.l		&0xc,EXC_DREGS+0x8(%a6)
   19494  1.1     is 	rts
   19495  1.1     is ceaf_pi1:
   19496  1.1     is 	addi.l		&0xc,EXC_DREGS+0xc(%a6)
   19497  1.1     is 	rts
   19498  1.1     is ceaf_pi2:
   19499  1.1     is 	add.l		&0xc,%a2
   19500  1.1     is 	rts
   19501  1.1     is ceaf_pi3:
   19502  1.1     is 	add.l		&0xc,%a3
   19503  1.1     is 	rts
   19504  1.1     is ceaf_pi4:
   19505  1.1     is 	add.l		&0xc,%a4
   19506  1.1     is 	rts
   19507  1.1     is ceaf_pi5:
   19508  1.1     is 	add.l		&0xc,%a5
   19509  1.1     is 	rts
   19510  1.1     is ceaf_pi6:
   19511  1.1     is 	addi.l		&0xc,EXC_A6(%a6)
   19512  1.1     is 	rts
   19513  1.1     is ceaf_pi7:
   19514  1.1     is 	mov.b		&mia7_flg,SPCOND_FLG(%a6)
   19515  1.1     is 	addi.l		&0xc,EXC_A7(%a6)
   19516  1.1     is 	rts
   19517  1.1     is 
   19518  1.1     is # -(An) : extended and packed fmove out
   19519  1.1     is #	: stacked <ea> = actual <ea> + 8
   19520  1.1     is #	: "An" not updated
   19521  1.1     is ceaf_pd:
   19522  1.1     is 	mov.w		(tbl_ceaf_pd.b,%pc,%d1.w*2),%d1
   19523  1.1     is 	mov.l		EXC_EA(%a6),%a0
   19524  1.1     is 	sub.l		&0x8,%a0
   19525  1.1     is 	sub.l		&0x8,EXC_EA(%a6)
   19526  1.1     is 	jmp		(tbl_ceaf_pd.b,%pc,%d1.w*1)
   19527  1.1     is 
   19528  1.1     is 	swbeg		&0x8
   19529  1.1     is tbl_ceaf_pd:
   19530  1.1     is 	short		ceaf_pd0 - tbl_ceaf_pd
   19531  1.1     is 	short		ceaf_pd1 - tbl_ceaf_pd
   19532  1.1     is 	short		ceaf_pd2 - tbl_ceaf_pd
   19533  1.1     is 	short		ceaf_pd3 - tbl_ceaf_pd
   19534  1.1     is 	short		ceaf_pd4 - tbl_ceaf_pd
   19535  1.1     is 	short		ceaf_pd5 - tbl_ceaf_pd
   19536  1.1     is 	short		ceaf_pd6 - tbl_ceaf_pd
   19537  1.1     is 	short		ceaf_pd7 - tbl_ceaf_pd
   19538  1.1     is 
   19539  1.1     is ceaf_pd0:
   19540  1.1     is 	mov.l		%a0,EXC_DREGS+0x8(%a6)
   19541  1.1     is 	rts
   19542  1.1     is ceaf_pd1:
   19543  1.1     is 	mov.l		%a0,EXC_DREGS+0xc(%a6)
   19544  1.1     is 	rts
   19545  1.1     is ceaf_pd2:
   19546  1.1     is 	mov.l		%a0,%a2
   19547  1.1     is 	rts
   19548  1.1     is ceaf_pd3:
   19549  1.1     is 	mov.l		%a0,%a3
   19550  1.1     is 	rts
   19551  1.1     is ceaf_pd4:
   19552  1.1     is 	mov.l		%a0,%a4
   19553  1.1     is 	rts
   19554  1.1     is ceaf_pd5:
   19555  1.1     is 	mov.l		%a0,%a5
   19556  1.1     is 	rts
   19557  1.1     is ceaf_pd6:
   19558  1.1     is 	mov.l		%a0,EXC_A6(%a6)
   19559  1.1     is 	rts
   19560  1.1     is ceaf_pd7:
   19561  1.1     is 	mov.l		%a0,EXC_A7(%a6)
   19562  1.1     is 	mov.b		&mda7_flg,SPCOND_FLG(%a6)
   19563  1.1     is 	rts
   19564  1.1     is 
   19565  1.1     is #########################################################################
   19566  1.1     is # XDEF ****************************************************************	#
   19567  1.1     is #	_load_fop(): load operand for unimplemented FP exception	#
   19568  1.1     is #									#
   19569  1.1     is # XREF ****************************************************************	#
   19570  1.1     is #	set_tag_x() - determine ext prec optype tag			#
   19571  1.1     is #	set_tag_s() - determine sgl prec optype tag			#
   19572  1.1     is #	set_tag_d() - determine dbl prec optype tag			#
   19573  1.1     is #	unnorm_fix() - convert normalized number to denorm or zero	#
   19574  1.1     is #	norm() - normalize a denormalized number			#
   19575  1.1     is #	get_packed() - fetch a packed operand from memory		#
   19576  1.1     is #	_dcalc_ea() - calculate <ea>, fixing An in process		#
   19577  1.1     is #									#
   19578  1.1     is #	_imem_read_{word,long}() - read from instruction memory		#
   19579  1.1     is #	_dmem_read() - read from data memory				#
   19580  1.1     is #	_dmem_read_{byte,word,long}() - read from data memory		#
   19581  1.1     is #									#
   19582  1.1     is #	facc_in_{b,w,l,d,x}() - mem read failed; special exit point	#
   19583  1.1     is #									#
   19584  1.1     is # INPUT ***************************************************************	#
   19585  1.1     is #	None								#
   19586  1.1     is # 									#
   19587  1.1     is # OUTPUT **************************************************************	#
   19588  1.1     is #	If memory access doesn't fail:					#
   19589  1.1     is #		FP_SRC(a6) = source operand in extended precision	#
   19590  1.1     is # 		FP_DST(a6) = destination operand in extended precision	#
   19591  1.1     is #									#
   19592  1.1     is # ALGORITHM ***********************************************************	#
   19593  1.1     is # 	This is called from the Unimplemented FP exception handler in	#
   19594  1.1     is # order to load the source and maybe destination operand into		#
   19595  1.1     is # FP_SRC(a6) and FP_DST(a6). If the instruction was opclass zero, load	#
   19596  1.1     is # the source and destination from the FP register file. Set the optype	#
   19597  1.1     is # tags for both if dyadic, one for monadic. If a number is an UNNORM,	#
   19598  1.1     is # convert it to a DENORM or a ZERO.					#
   19599  1.1     is # 	If the instruction is opclass two (memory->reg), then fetch	#
   19600  1.1     is # the destination from the register file and the source operand from 	#
   19601  1.1     is # memory. Tag and fix both as above w/ opclass zero instructions.	#
   19602  1.1     is # 	If the source operand is byte,word,long, or single, it may be	#
   19603  1.1     is # in the data register file. If it's actually out in memory, use one of	#
   19604  1.1     is # the mem_read() routines to fetch it. If the mem_read() access returns	#
   19605  1.1     is # a failing value, exit through the special facc_in() routine which	#
   19606  1.1     is # will create an acess error exception frame from the current exception #
   19607  1.1     is # frame.								#
   19608  1.1     is # 	Immediate data and regular data accesses are separated because 	#
   19609  1.1     is # if an immediate data access fails, the resulting fault status		#
   19610  1.1     is # longword stacked for the access error exception must have the 	#
   19611  1.1     is # instruction bit set.							#
   19612  1.1     is #									#
   19613  1.1     is #########################################################################
   19614  1.1     is 
   19615  1.1     is 	global		_load_fop
   19616  1.1     is _load_fop:
   19617  1.1     is 
   19618  1.1     is #  15     13 12 10  9 7  6       0
   19619  1.1     is # /        \ /   \ /  \ /         \
   19620  1.1     is # ---------------------------------
   19621  1.1     is # | opclass | RX  | RY | EXTENSION |  (2nd word of general FP instruction)
   19622  1.1     is # ---------------------------------
   19623  1.1     is #
   19624  1.1     is 
   19625  1.1     is #	bfextu		EXC_CMDREG(%a6){&0:&3}, %d0 # extract opclass
   19626  1.1     is #	cmpi.b		%d0, &0x2		# which class is it? ('000,'010,'011)
   19627  1.1     is #	beq.w		op010			# handle <ea> -> fpn
   19628  1.1     is #	bgt.w		op011			# handle fpn -> <ea>
   19629  1.1     is 
   19630  1.1     is # we're not using op011 for now...
   19631  1.1     is 	btst		&0x6,EXC_CMDREG(%a6)
   19632  1.1     is 	bne.b		op010
   19633  1.1     is 
   19634  1.1     is ############################
   19635  1.1     is # OPCLASS '000: reg -> reg #
   19636  1.1     is ############################
   19637  1.1     is op000:
   19638  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension word lo
   19639  1.1     is 	btst		&0x5,%d0		# testing extension bits
   19640  1.1     is 	beq.b		op000_src		# (bit 5 == 0) => monadic
   19641  1.1     is 	btst		&0x4,%d0		# (bit 5 == 1)
   19642  1.1     is 	beq.b		op000_dst		# (bit 4 == 0) => dyadic
   19643  1.1     is 	and.w		&0x007f,%d0		# extract extension bits {6:0}
   19644  1.1     is 	cmpi.w		%d0,&0x0038		# is it an fcmp (dyadic) ?
   19645  1.1     is 	bne.b		op000_src		# it's an fcmp
   19646  1.1     is 
   19647  1.1     is op000_dst:
   19648  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field
   19649  1.1     is 	bsr.l		load_fpn2		# fetch dst fpreg into FP_DST
   19650  1.1     is 
   19651  1.1     is 	bsr.l		set_tag_x		# get dst optype tag
   19652  1.1     is 
   19653  1.1     is 	cmpi.b		%d0, &UNNORM		# is dst fpreg an UNNORM?
   19654  1.1     is 	beq.b		op000_dst_unnorm	# yes
   19655  1.1     is op000_dst_cont:
   19656  1.1     is 	mov.b 		%d0, DTAG(%a6)		# store the dst optype tag
   19657  1.1     is 
   19658  1.1     is op000_src:
   19659  1.1     is 	bfextu		EXC_CMDREG(%a6){&3:&3}, %d0 # extract src field
   19660  1.1     is 	bsr.l		load_fpn1		# fetch src fpreg into FP_SRC
   19661  1.1     is 
   19662  1.1     is 	bsr.l		set_tag_x		# get src optype tag
   19663  1.1     is 
   19664  1.1     is 	cmpi.b		%d0, &UNNORM		# is src fpreg an UNNORM?
   19665  1.1     is 	beq.b		op000_src_unnorm	# yes
   19666  1.1     is op000_src_cont:
   19667  1.1     is 	mov.b		%d0, STAG(%a6)		# store the src optype tag
   19668  1.1     is 	rts
   19669  1.1     is 
   19670  1.1     is op000_dst_unnorm:
   19671  1.1     is 	bsr.l		unnorm_fix		# fix the dst UNNORM
   19672  1.1     is 	bra.b		op000_dst_cont
   19673  1.1     is op000_src_unnorm:
   19674  1.1     is 	bsr.l		unnorm_fix		# fix the src UNNORM
   19675  1.1     is 	bra.b		op000_src_cont
   19676  1.1     is 
   19677  1.1     is #############################
   19678  1.1     is # OPCLASS '010: <ea> -> reg #
   19679  1.1     is #############################
   19680  1.1     is op010:
   19681  1.1     is 	mov.w		EXC_CMDREG(%a6),%d0	# fetch extension word
   19682  1.1     is 	btst		&0x5,%d0		# testing extension bits
   19683  1.1     is 	beq.b		op010_src		# (bit 5 == 0) => monadic
   19684  1.1     is 	btst		&0x4,%d0		# (bit 5 == 1)
   19685  1.1     is 	beq.b		op010_dst		# (bit 4 == 0) => dyadic
   19686  1.1     is 	and.w		&0x007f,%d0		# extract extension bits {6:0}
   19687  1.1     is 	cmpi.w		%d0,&0x0038		# is it an fcmp (dyadic) ?
   19688  1.1     is 	bne.b		op010_src		# it's an fcmp
   19689  1.1     is 
   19690  1.1     is op010_dst:
   19691  1.1     is 	bfextu		EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field
   19692  1.1     is 	bsr.l		load_fpn2		# fetch dst fpreg ptr
   19693  1.1     is 
   19694  1.1     is 	bsr.l		set_tag_x		# get dst type tag
   19695  1.1     is 
   19696  1.1     is 	cmpi.b		%d0, &UNNORM		# is dst fpreg an UNNORM?
   19697  1.1     is 	beq.b		op010_dst_unnorm	# yes
   19698  1.1     is op010_dst_cont:
   19699  1.1     is 	mov.b		%d0, DTAG(%a6)		# store the dst optype tag
   19700  1.1     is 
   19701  1.1     is op010_src:
   19702  1.1     is 	bfextu		EXC_CMDREG(%a6){&3:&3}, %d0 # extract src type field
   19703  1.1     is 
   19704  1.1     is 	bfextu		EXC_OPWORD(%a6){&10:&3}, %d1 # extract <ea> mode field
   19705  1.1     is 	bne.w		fetch_from_mem		# src op is in memory
   19706  1.1     is 
   19707  1.1     is op010_dreg:
   19708  1.1     is 	clr.b		STAG(%a6)		# either NORM or ZERO
   19709  1.1     is 	bfextu		EXC_OPWORD(%a6){&13:&3}, %d1 # extract src reg field
   19710  1.1     is 
   19711  1.1     is 	mov.w		(tbl_op010_dreg.b,%pc,%d0.w*2), %d0 # jmp based on optype
   19712  1.1     is 	jmp		(tbl_op010_dreg.b,%pc,%d0.w*1) # fetch src from dreg
   19713  1.1     is 
   19714  1.1     is op010_dst_unnorm:
   19715  1.1     is 	bsr.l		unnorm_fix		# fix the dst UNNORM
   19716  1.1     is 	bra.b		op010_dst_cont
   19717  1.1     is 
   19718  1.1     is 	swbeg		&0x8
   19719  1.1     is tbl_op010_dreg:
   19720  1.1     is 	short		opd_long	- tbl_op010_dreg
   19721  1.1     is 	short		opd_sgl 	- tbl_op010_dreg
   19722  1.1     is 	short		tbl_op010_dreg	- tbl_op010_dreg
   19723  1.1     is 	short		tbl_op010_dreg	- tbl_op010_dreg
   19724  1.1     is 	short		opd_word	- tbl_op010_dreg
   19725  1.1     is 	short		tbl_op010_dreg	- tbl_op010_dreg
   19726  1.1     is 	short		opd_byte	- tbl_op010_dreg
   19727  1.1     is 	short		tbl_op010_dreg	- tbl_op010_dreg
   19728  1.1     is 
   19729  1.1     is #
   19730  1.1     is # LONG: can be either NORM or ZERO...
   19731  1.1     is #
   19732  1.1     is opd_long:
   19733  1.1     is 	bsr.l		fetch_dreg		# fetch long in d0
   19734  1.1     is 	fmov.l		%d0, %fp0 		# load a long
   19735  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19736  1.1     is 	fbeq.w		opd_long_zero		# long is a ZERO
   19737  1.1     is 	rts
   19738  1.1     is opd_long_zero:
   19739  1.1     is 	mov.b		&ZERO, STAG(%a6)	# set ZERO optype flag
   19740  1.1     is 	rts
   19741  1.1     is 
   19742  1.1     is #
   19743  1.1     is # WORD: can be either NORM or ZERO...
   19744  1.1     is #
   19745  1.1     is opd_word:
   19746  1.1     is 	bsr.l		fetch_dreg		# fetch word in d0
   19747  1.1     is 	fmov.w		%d0, %fp0 		# load a word
   19748  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19749  1.1     is 	fbeq.w		opd_word_zero		# WORD is a ZERO
   19750  1.1     is 	rts
   19751  1.1     is opd_word_zero:
   19752  1.1     is 	mov.b		&ZERO, STAG(%a6)	# set ZERO optype flag
   19753  1.1     is 	rts
   19754  1.1     is 
   19755  1.1     is #
   19756  1.1     is # BYTE: can be either NORM or ZERO...
   19757  1.1     is #
   19758  1.1     is opd_byte:
   19759  1.1     is 	bsr.l		fetch_dreg		# fetch word in d0
   19760  1.1     is 	fmov.b		%d0, %fp0 		# load a byte
   19761  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19762  1.1     is 	fbeq.w		opd_byte_zero		# byte is a ZERO
   19763  1.1     is 	rts
   19764  1.1     is opd_byte_zero:
   19765  1.1     is 	mov.b		&ZERO, STAG(%a6)	# set ZERO optype flag
   19766  1.1     is 	rts
   19767  1.1     is 
   19768  1.1     is #
   19769  1.1     is # SGL: can be either NORM, DENORM, ZERO, INF, QNAN or SNAN but not UNNORM
   19770  1.1     is #
   19771  1.1     is # separate SNANs and DENORMs so they can be loaded w/ special care.
   19772  1.1     is # all others can simply be moved "in" using fmove.
   19773  1.1     is #
   19774  1.1     is opd_sgl:
   19775  1.1     is 	bsr.l		fetch_dreg		# fetch sgl in d0
   19776  1.1     is 	mov.l		%d0,L_SCR1(%a6)
   19777  1.1     is 
   19778  1.1     is 	lea		L_SCR1(%a6), %a0 	# pass: ptr to the sgl
   19779  1.1     is 	bsr.l		set_tag_s		# determine sgl type
   19780  1.1     is 	mov.b		%d0, STAG(%a6)		# save the src tag
   19781  1.1     is 
   19782  1.1     is 	cmpi.b		%d0, &SNAN		# is it an SNAN?
   19783  1.1     is 	beq.w		get_sgl_snan		# yes
   19784  1.1     is 
   19785  1.1     is 	cmpi.b		%d0, &DENORM		# is it a DENORM?
   19786  1.1     is 	beq.w		get_sgl_denorm		# yes
   19787  1.1     is 
   19788  1.1     is 	fmov.s		(%a0), %fp0		# no, so can load it regular
   19789  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19790  1.1     is 	rts
   19791  1.1     is 
   19792  1.1     is ##############################################################################
   19793  1.1     is 
   19794  1.1     is #########################################################################
   19795  1.1     is # fetch_from_mem():							#
   19796  1.1     is # - src is out in memory. must:						#
   19797  1.1     is #	(1) calc ea - must read AFTER you know the src type since	#
   19798  1.1     is #		      if the ea is -() or ()+, need to know # of bytes.	#
   19799  1.1     is #	(2) read it in from either user or supervisor space		#
   19800  1.1     is #	(3) if (b || w || l) then simply read in			#
   19801  1.1     is #	    if (s || d || x) then check for SNAN,UNNORM,DENORM		#
   19802  1.1     is #	    if (packed) then punt for now				#
   19803  1.1     is # INPUT:								#
   19804  1.1     is #	%d0 : src type field						#
   19805  1.1     is #########################################################################
   19806  1.1     is fetch_from_mem:
   19807  1.1     is 	clr.b		STAG(%a6)		# either NORM or ZERO
   19808  1.1     is 
   19809  1.1     is 	mov.w		(tbl_fp_type.b,%pc,%d0.w*2), %d0 # index by src type field
   19810  1.1     is 	jmp		(tbl_fp_type.b,%pc,%d0.w*1)
   19811  1.1     is 
   19812  1.1     is 	swbeg		&0x8
   19813  1.1     is tbl_fp_type:
   19814  1.1     is 	short		load_long	- tbl_fp_type
   19815  1.1     is 	short		load_sgl	- tbl_fp_type
   19816  1.1     is 	short		load_ext	- tbl_fp_type
   19817  1.1     is 	short		load_packed	- tbl_fp_type
   19818  1.1     is 	short		load_word	- tbl_fp_type
   19819  1.1     is 	short		load_dbl	- tbl_fp_type
   19820  1.1     is 	short		load_byte	- tbl_fp_type
   19821  1.1     is 	short		tbl_fp_type	- tbl_fp_type
   19822  1.1     is 
   19823  1.1     is #########################################
   19824  1.1     is # load a LONG into %fp0:		#
   19825  1.1     is # 	-number can't fault		#
   19826  1.1     is #	(1) calc ea			#
   19827  1.1     is #	(2) read 4 bytes into L_SCR1	#
   19828  1.1     is #	(3) fmov.l into %fp0		#
   19829  1.1     is #########################################
   19830  1.1     is load_long:
   19831  1.1     is 	movq.l		&0x4, %d0		# pass: 4 (bytes)
   19832  1.1     is 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19833  1.1     is 
   19834  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19835  1.1     is 	beq.b		load_long_immed
   19836  1.1     is 
   19837  1.1     is 	bsr.l		_dmem_read_long		# fetch src operand from memory
   19838  1.1     is 
   19839  1.1     is 	tst.l		%d1			# did dfetch fail?
   19840  1.1     is 	bne.l		facc_in_l		# yes
   19841  1.1     is 
   19842  1.1     is load_long_cont:
   19843  1.1     is 	fmov.l		%d0, %fp0		# read into %fp0;convert to xprec
   19844  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19845  1.1     is 
   19846  1.1     is 	fbeq.w		load_long_zero		# src op is a ZERO
   19847  1.1     is 	rts
   19848  1.1     is load_long_zero:
   19849  1.1     is 	mov.b		&ZERO, STAG(%a6)	# set optype tag to ZERO
   19850  1.1     is 	rts
   19851  1.1     is 
   19852  1.1     is load_long_immed:
   19853  1.1     is 	bsr.l		_imem_read_long		# fetch src operand immed data
   19854  1.1     is 
   19855  1.1     is 	tst.l		%d1			# did ifetch fail?
   19856  1.1     is 	bne.l		funimp_iacc		# yes
   19857  1.1     is 	bra.b		load_long_cont
   19858  1.1     is 
   19859  1.1     is #########################################
   19860  1.1     is # load a WORD into %fp0:		#
   19861  1.1     is # 	-number can't fault		#
   19862  1.1     is #	(1) calc ea			#
   19863  1.1     is #	(2) read 2 bytes into L_SCR1	#
   19864  1.1     is #	(3) fmov.w into %fp0		#
   19865  1.1     is #########################################
   19866  1.1     is load_word:
   19867  1.1     is 	movq.l		&0x2, %d0		# pass: 2 (bytes)
   19868  1.1     is 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19869  1.1     is 
   19870  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19871  1.1     is 	beq.b		load_word_immed
   19872  1.1     is 
   19873  1.1     is 	bsr.l		_dmem_read_word		# fetch src operand from memory
   19874  1.1     is 
   19875  1.1     is 	tst.l		%d1			# did dfetch fail?
   19876  1.1     is 	bne.l		facc_in_w		# yes
   19877  1.1     is 
   19878  1.1     is load_word_cont:
   19879  1.1     is 	fmov.w		%d0, %fp0		# read into %fp0;convert to xprec
   19880  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19881  1.1     is 
   19882  1.1     is 	fbeq.w		load_word_zero		# src op is a ZERO
   19883  1.1     is 	rts
   19884  1.1     is load_word_zero:
   19885  1.1     is 	mov.b		&ZERO, STAG(%a6)	# set optype tag to ZERO
   19886  1.1     is 	rts
   19887  1.1     is 
   19888  1.1     is load_word_immed:
   19889  1.1     is 	bsr.l		_imem_read_word		# fetch src operand immed data
   19890  1.1     is 
   19891  1.1     is 	tst.l		%d1			# did ifetch fail?
   19892  1.1     is 	bne.l		funimp_iacc		# yes
   19893  1.1     is 	bra.b		load_word_cont
   19894  1.1     is 
   19895  1.1     is #########################################
   19896  1.1     is # load a BYTE into %fp0:		#
   19897  1.1     is # 	-number can't fault		#
   19898  1.1     is #	(1) calc ea			#
   19899  1.1     is #	(2) read 1 byte into L_SCR1	#
   19900  1.1     is #	(3) fmov.b into %fp0		#
   19901  1.1     is #########################################
   19902  1.1     is load_byte:
   19903  1.1     is 	movq.l		&0x1, %d0		# pass: 1 (byte)
   19904  1.1     is 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19905  1.1     is 
   19906  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19907  1.1     is 	beq.b		load_byte_immed
   19908  1.1     is 
   19909  1.1     is 	bsr.l		_dmem_read_byte		# fetch src operand from memory
   19910  1.1     is 
   19911  1.1     is 	tst.l		%d1			# did dfetch fail?
   19912  1.1     is 	bne.l		facc_in_b		# yes
   19913  1.1     is 
   19914  1.1     is load_byte_cont:
   19915  1.1     is 	fmov.b		%d0, %fp0		# read into %fp0;convert to xprec
   19916  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19917  1.1     is 
   19918  1.1     is 	fbeq.w		load_byte_zero		# src op is a ZERO
   19919  1.1     is 	rts
   19920  1.1     is load_byte_zero:
   19921  1.1     is 	mov.b		&ZERO, STAG(%a6)	# set optype tag to ZERO
   19922  1.1     is 	rts
   19923  1.1     is 
   19924  1.1     is load_byte_immed:
   19925  1.1     is 	bsr.l		_imem_read_word		# fetch src operand immed data
   19926  1.1     is 
   19927  1.1     is 	tst.l		%d1			# did ifetch fail?
   19928  1.1     is 	bne.l		funimp_iacc		# yes
   19929  1.1     is 	bra.b		load_byte_cont
   19930  1.1     is 
   19931  1.1     is #########################################
   19932  1.1     is # load a SGL into %fp0:			#
   19933  1.1     is # 	-number can't fault		#
   19934  1.1     is #	(1) calc ea			#
   19935  1.1     is #	(2) read 4 bytes into L_SCR1	#
   19936  1.1     is #	(3) fmov.s into %fp0		#
   19937  1.1     is #########################################
   19938  1.1     is load_sgl:
   19939  1.1     is 	movq.l		&0x4, %d0		# pass: 4 (bytes)
   19940  1.1     is 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19941  1.1     is 
   19942  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19943  1.1     is 	beq.b		load_sgl_immed
   19944  1.1     is 
   19945  1.1     is 	bsr.l		_dmem_read_long		# fetch src operand from memory
   19946  1.1     is 	mov.l		%d0, L_SCR1(%a6)	# store src op on stack
   19947  1.1     is 
   19948  1.1     is 	tst.l		%d1			# did dfetch fail?
   19949  1.1     is 	bne.l		facc_in_l		# yes
   19950  1.1     is 
   19951  1.1     is load_sgl_cont:
   19952  1.1     is 	lea		L_SCR1(%a6), %a0	# pass: ptr to sgl src op
   19953  1.1     is 	bsr.l		set_tag_s		# determine src type tag
   19954  1.1     is 	mov.b		%d0, STAG(%a6)		# save src optype tag on stack
   19955  1.1     is 
   19956  1.1     is 	cmpi.b		%d0, &DENORM		# is it a sgl DENORM?
   19957  1.1     is 	beq.w		get_sgl_denorm		# yes
   19958  1.1     is 
   19959  1.1     is 	cmpi.b		%d0, &SNAN		# is it a sgl SNAN?
   19960  1.1     is 	beq.w		get_sgl_snan		# yes
   19961  1.1     is 
   19962  1.1     is 	fmov.s		L_SCR1(%a6), %fp0	# read into %fp0;convert to xprec
   19963  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19964  1.1     is 	rts
   19965  1.1     is 
   19966  1.1     is load_sgl_immed:
   19967  1.1     is 	bsr.l		_imem_read_long		# fetch src operand immed data
   19968  1.1     is 
   19969  1.1     is 	tst.l		%d1			# did ifetch fail?
   19970  1.1     is 	bne.l		funimp_iacc		# yes
   19971  1.1     is 	bra.b		load_sgl_cont
   19972  1.1     is 
   19973  1.1     is # must convert sgl denorm format to an Xprec denorm fmt suitable for
   19974  1.1     is # normalization...
   19975  1.1     is # %a0 : points to sgl denorm
   19976  1.1     is get_sgl_denorm:
   19977  1.1     is 	clr.w		FP_SRC_EX(%a6)
   19978  1.1     is 	bfextu		(%a0){&9:&23}, %d0	# fetch sgl hi(_mantissa)
   19979  1.1     is 	lsl.l		&0x8, %d0
   19980  1.1     is 	mov.l		%d0, FP_SRC_HI(%a6)	# set ext hi(_mantissa)
   19981  1.1     is 	clr.l		FP_SRC_LO(%a6)		# set ext lo(_mantissa)
   19982  1.1     is 
   19983  1.1     is 	clr.w		FP_SRC_EX(%a6)
   19984  1.1     is 	btst		&0x7, (%a0)		# is sgn bit set?
   19985  1.1     is 	beq.b		sgl_dnrm_norm
   19986  1.1     is 	bset		&0x7, FP_SRC_EX(%a6)	# set sgn of xprec value
   19987  1.1     is 
   19988  1.1     is sgl_dnrm_norm:
   19989  1.1     is 	lea		FP_SRC(%a6), %a0
   19990  1.1     is 	bsr.l		norm			# normalize number
   19991  1.1     is 	mov.w		&0x3f81, %d1		# xprec exp = 0x3f81
   19992  1.1     is 	sub.w		%d0, %d1		# exp = 0x3f81 - shft amt.
   19993  1.1     is 	or.w		%d1, FP_SRC_EX(%a6)	# {sgn,exp}
   19994  1.1     is 
   19995  1.1     is 	mov.b		&NORM, STAG(%a6)	# fix src type tag
   19996  1.1     is 	rts
   19997  1.1     is 
   19998  1.1     is # convert sgl to ext SNAN
   19999  1.1     is # %a0 : points to sgl SNAN
   20000  1.1     is get_sgl_snan:
   20001  1.1     is 	mov.w		&0x7fff, FP_SRC_EX(%a6) # set exp of SNAN
   20002  1.1     is 	bfextu		(%a0){&9:&23}, %d0
   20003  1.1     is 	lsl.l		&0x8, %d0		# extract and insert hi(man)
   20004  1.1     is 	mov.l		%d0, FP_SRC_HI(%a6)
   20005  1.1     is 	clr.l		FP_SRC_LO(%a6)
   20006  1.1     is 
   20007  1.1     is 	btst		&0x7, (%a0)		# see if sign of SNAN is set
   20008  1.1     is 	beq.b		no_sgl_snan_sgn
   20009  1.1     is 	bset		&0x7, FP_SRC_EX(%a6)
   20010  1.1     is no_sgl_snan_sgn:
   20011  1.1     is 	rts
   20012  1.1     is 
   20013  1.1     is #########################################
   20014  1.1     is # load a DBL into %fp0:			#
   20015  1.1     is # 	-number can't fault		#
   20016  1.1     is #	(1) calc ea			#
   20017  1.1     is #	(2) read 8 bytes into L_SCR(1,2)#
   20018  1.1     is #	(3) fmov.d into %fp0		#
   20019  1.1     is #########################################
   20020  1.1     is load_dbl:
   20021  1.1     is 	movq.l		&0x8, %d0		# pass: 8 (bytes)
   20022  1.1     is 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   20023  1.1     is 
   20024  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   20025  1.1     is 	beq.b		load_dbl_immed
   20026  1.1     is 
   20027  1.1     is 	lea		L_SCR1(%a6), %a1	# pass: ptr to input dbl tmp space
   20028  1.1     is 	movq.l		&0x8, %d0		# pass: # bytes to read
   20029  1.1     is 	bsr.l		_dmem_read		# fetch src operand from memory
   20030  1.1     is 
   20031  1.1     is 	tst.l		%d1			# did dfetch fail?
   20032  1.1     is 	bne.l		facc_in_d		# yes
   20033  1.1     is 
   20034  1.1     is load_dbl_cont:
   20035  1.1     is 	lea		L_SCR1(%a6), %a0	# pass: ptr to input dbl
   20036  1.1     is 	bsr.l		set_tag_d		# determine src type tag
   20037  1.1     is 	mov.b		%d0, STAG(%a6)		# set src optype tag
   20038  1.1     is 
   20039  1.1     is 	cmpi.b		%d0, &DENORM		# is it a dbl DENORM?
   20040  1.1     is 	beq.w		get_dbl_denorm		# yes
   20041  1.1     is 
   20042  1.1     is 	cmpi.b		%d0, &SNAN		# is it a dbl SNAN?
   20043  1.1     is 	beq.w		get_dbl_snan		# yes
   20044  1.1     is 
   20045  1.1     is 	fmov.d		L_SCR1(%a6), %fp0	# read into %fp0;convert to xprec
   20046  1.1     is 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   20047  1.1     is 	rts
   20048  1.1     is 
   20049  1.1     is load_dbl_immed:
   20050  1.1     is 	lea		L_SCR1(%a6), %a1	# pass: ptr to input dbl tmp space
   20051  1.1     is 	movq.l		&0x8, %d0		# pass: # bytes to read
   20052  1.1     is 	bsr.l		_imem_read		# fetch src operand from memory
   20053  1.1     is 
   20054  1.1     is 	tst.l		%d1			# did ifetch fail?
   20055  1.1     is 	bne.l		funimp_iacc		# yes
   20056  1.1     is 	bra.b		load_dbl_cont
   20057  1.1     is 
   20058  1.1     is # must convert dbl denorm format to an Xprec denorm fmt suitable for
   20059  1.1     is # normalization...
   20060  1.1     is # %a0 : loc. of dbl denorm
   20061  1.1     is get_dbl_denorm:
   20062  1.1     is 	clr.w		FP_SRC_EX(%a6)
   20063  1.1     is 	bfextu		(%a0){&12:&31}, %d0	# fetch hi(_mantissa)
   20064  1.1     is 	mov.l		%d0, FP_SRC_HI(%a6)
   20065  1.1     is 	bfextu		4(%a0){&11:&21}, %d0	# fetch lo(_mantissa)
   20066  1.1     is 	mov.l		&0xb, %d1
   20067  1.1     is 	lsl.l		%d1, %d0
   20068  1.1     is 	mov.l		%d0, FP_SRC_LO(%a6)
   20069  1.1     is 
   20070  1.1     is 	btst		&0x7, (%a0)		# is sgn bit set?
   20071  1.1     is 	beq.b		dbl_dnrm_norm
   20072  1.1     is 	bset		&0x7, FP_SRC_EX(%a6)	# set sgn of xprec value
   20073  1.1     is 
   20074  1.1     is dbl_dnrm_norm:
   20075  1.1     is 	lea		FP_SRC(%a6), %a0
   20076  1.1     is 	bsr.l		norm			# normalize number
   20077  1.1     is 	mov.w		&0x3c01, %d1		# xprec exp = 0x3c01
   20078  1.1     is 	sub.w		%d0, %d1		# exp = 0x3c01 - shft amt.
   20079  1.1     is 	or.w		%d1, FP_SRC_EX(%a6)	# {sgn,exp}
   20080  1.1     is 
   20081  1.1     is 	mov.b		&NORM, STAG(%a6)	# fix src type tag
   20082  1.1     is 	rts
   20083  1.1     is 
   20084  1.1     is # convert dbl to ext SNAN
   20085  1.1     is # %a0 : points to dbl SNAN
   20086  1.1     is get_dbl_snan:
   20087  1.1     is 	mov.w		&0x7fff, FP_SRC_EX(%a6) # set exp of SNAN
   20088  1.1     is 
   20089  1.1     is 	bfextu		(%a0){&12:&31}, %d0	# fetch hi(_mantissa)
   20090  1.1     is 	mov.l		%d0, FP_SRC_HI(%a6)
   20091  1.1     is 	bfextu		4(%a0){&11:&21}, %d0	# fetch lo(_mantissa)
   20092  1.1     is 	mov.l		&0xb, %d1
   20093  1.1     is 	lsl.l		%d1, %d0
   20094  1.1     is 	mov.l		%d0, FP_SRC_LO(%a6)
   20095  1.1     is 
   20096  1.1     is 	btst		&0x7, (%a0)		# see if sign of SNAN is set
   20097  1.1     is 	beq.b		no_dbl_snan_sgn
   20098  1.1     is 	bset		&0x7, FP_SRC_EX(%a6)
   20099  1.1     is no_dbl_snan_sgn:
   20100  1.1     is 	rts
   20101  1.1     is 
   20102  1.1     is #################################################
   20103  1.1     is # load a Xprec into %fp0:			#
   20104  1.1     is # 	-number can't fault			#
   20105  1.1     is #	(1) calc ea				#
   20106  1.1     is #	(2) read 12 bytes into L_SCR(1,2)	#
   20107  1.1     is #	(3) fmov.x into %fp0			#
   20108  1.1     is #################################################
   20109  1.1     is load_ext:
   20110  1.1     is 	mov.l		&0xc, %d0		# pass: 12 (bytes)
   20111  1.1     is 	bsr.l		_dcalc_ea		# calc <ea>
   20112  1.1     is 
   20113  1.1     is 	lea		FP_SRC(%a6), %a1	# pass: ptr to input ext tmp space
   20114  1.1     is 	mov.l		&0xc, %d0		# pass: # of bytes to read
   20115  1.1     is 	bsr.l		_dmem_read		# fetch src operand from memory
   20116  1.1     is 
   20117  1.1     is 	tst.l		%d1			# did dfetch fail?
   20118  1.1     is 	bne.l		facc_in_x		# yes
   20119  1.1     is 
   20120  1.1     is 	lea		FP_SRC(%a6), %a0	# pass: ptr to src op
   20121  1.1     is 	bsr.l		set_tag_x		# determine src type tag
   20122  1.1     is 
   20123  1.1     is 	cmpi.b		%d0, &UNNORM		# is the src op an UNNORM?
   20124  1.1     is 	beq.b		load_ext_unnorm		# yes
   20125  1.1     is 
   20126  1.1     is 	mov.b		%d0, STAG(%a6)		# store the src optype tag
   20127  1.1     is 	rts
   20128  1.1     is 
   20129  1.1     is load_ext_unnorm:
   20130  1.1     is 	bsr.l		unnorm_fix		# fix the src UNNORM
   20131  1.1     is 	mov.b		%d0, STAG(%a6)		# store the src optype tag
   20132  1.1     is 	rts
   20133  1.1     is 
   20134  1.1     is #################################################
   20135  1.1     is # load a packed into %fp0:			#
   20136  1.1     is # 	-number can't fault			#
   20137  1.1     is #	(1) calc ea				#
   20138  1.1     is #	(2) read 12 bytes into L_SCR(1,2,3)	#
   20139  1.1     is #	(3) fmov.x into %fp0			#
   20140  1.1     is #################################################
   20141  1.1     is load_packed:
   20142  1.1     is 	bsr.l		get_packed
   20143  1.1     is 
   20144  1.1     is 	lea		FP_SRC(%a6),%a0		# pass ptr to src op
   20145  1.1     is 	bsr.l		set_tag_x		# determine src type tag
   20146  1.1     is 	cmpi.b		%d0,&UNNORM		# is the src op an UNNORM ZERO?
   20147  1.1     is 	beq.b		load_packed_unnorm	# yes
   20148  1.1     is 
   20149  1.1     is 	mov.b		%d0,STAG(%a6)		# store the src optype tag
   20150  1.1     is 	rts
   20151  1.1     is 
   20152  1.1     is load_packed_unnorm:
   20153  1.1     is 	bsr.l		unnorm_fix		# fix the UNNORM ZERO
   20154  1.1     is 	mov.b		%d0,STAG(%a6)		# store the src optype tag
   20155  1.1     is 	rts
   20156  1.1     is 
   20157  1.1     is #########################################################################
   20158  1.1     is # XDEF ****************************************************************	#
   20159  1.1     is # 	fout(): move from fp register to memory or data register	#
   20160  1.1     is #									#
   20161  1.1     is # XREF ****************************************************************	#
   20162  1.1     is #	_round() - needed to create EXOP for sgl/dbl precision		#
   20163  1.1     is #	norm() - needed to create EXOP for extended precision		#
   20164  1.1     is #	ovf_res() - create default overflow result for sgl/dbl precision#
   20165  1.1     is #	unf_res() - create default underflow result for sgl/dbl prec.	#
   20166  1.1     is #	dst_dbl() - create rounded dbl precision result.		#
   20167  1.1     is #	dst_sgl() - create rounded sgl precision result.		#
   20168  1.1     is #	fetch_dreg() - fetch dynamic k-factor reg for packed.		#
   20169  1.1     is #	bindec() - convert FP binary number to packed number.		#
   20170  1.1     is #	_mem_write() - write data to memory.				#
   20171  1.1     is #	_mem_write2() - write data to memory unless supv mode -(a7) exc.#
   20172  1.1     is #	_dmem_write_{byte,word,long}() - write data to memory.		#
   20173  1.1     is #	store_dreg_{b,w,l}() - store data to data register file.	#
   20174  1.1     is #	facc_out_{b,w,l,d,x}() - data access error occurred.		#
   20175  1.1     is #									#
   20176  1.1     is # INPUT ***************************************************************	#
   20177  1.1     is #	a0 = pointer to extended precision source operand		#
   20178  1.1     is #	d0 = round prec,mode						#
   20179  1.1     is # 									#
   20180  1.1     is # OUTPUT **************************************************************	#
   20181  1.1     is #	fp0 : intermediate underflow or overflow result if		#
   20182  1.1     is #	      OVFL/UNFL occurred for a sgl or dbl operand		#
   20183  1.1     is #									#
   20184  1.1     is # ALGORITHM ***********************************************************	#
   20185  1.1     is #	This routine is accessed by many handlers that need to do an	#
   20186  1.1     is # opclass three move of an operand out to memory.			#
   20187  1.1     is #	Decode an fmove out (opclass 3) instruction to determine if	#
   20188  1.1     is # it's b,w,l,s,d,x, or p in size. b,w,l can be stored to either a data	#
   20189  1.1     is # register or memory. The algorithm uses a standard "fmove" to create	#
   20190  1.1     is # the rounded result. Also, since exceptions are disabled, this also	#
   20191  1.1     is # create the correct OPERR default result if appropriate.		#
   20192  1.1     is #	For sgl or dbl precision, overflow or underflow can occur. If	#
   20193  1.1     is # either occurs and is enabled, the EXOP.				#
   20194  1.1     is #	For extended precision, the stacked <ea> must be fixed along	#
   20195  1.1     is # w/ the address index register as appropriate w/ _calc_ea_fout(). If	#
   20196  1.1     is # the source is a denorm and if underflow is enabled, an EXOP must be	#
   20197  1.1     is # created.								#
   20198  1.1     is # 	For packed, the k-factor must be fetched from the instruction	#
   20199  1.1     is # word or a data register. The <ea> must be fixed as w/ extended 	#
   20200  1.1     is # precision. Then, bindec() is called to create the appropriate 	#
   20201  1.1     is # packed result.							#
   20202  1.1     is #	If at any time an access error is flagged by one of the move-	#
   20203  1.1     is # to-memory routines, then a special exit must be made so that the	#
   20204  1.1     is # access error can be handled properly.					#
   20205  1.1     is #									#
   20206  1.1     is #########################################################################
   20207  1.1     is 
   20208  1.1     is 	global		fout
   20209  1.1     is fout:
   20210  1.1     is 	bfextu		EXC_CMDREG(%a6){&3:&3},%d1 # extract dst fmt
   20211  1.1     is 	mov.w		(tbl_fout.b,%pc,%d1.w*2),%a1 # use as index
   20212  1.1     is 	jmp		(tbl_fout.b,%pc,%a1)	# jump to routine
   20213  1.1     is 
   20214  1.1     is 	swbeg		&0x8
   20215  1.1     is tbl_fout:
   20216  1.1     is 	short		fout_long	-	tbl_fout
   20217  1.1     is 	short		fout_sgl	-	tbl_fout
   20218  1.1     is 	short		fout_ext	-	tbl_fout
   20219  1.1     is 	short		fout_pack	-	tbl_fout
   20220  1.1     is 	short		fout_word	-	tbl_fout
   20221  1.1     is 	short		fout_dbl	-	tbl_fout
   20222  1.1     is 	short		fout_byte	-	tbl_fout
   20223  1.1     is 	short		fout_pack	-	tbl_fout
   20224  1.1     is 
   20225  1.1     is #################################################################
   20226  1.1     is # fmove.b out ###################################################
   20227  1.1     is #################################################################
   20228  1.1     is 
   20229  1.1     is # Only "Unimplemented Data Type" exceptions enter here. The operand
   20230  1.1     is # is either a DENORM or a NORM.
   20231  1.1     is fout_byte:
   20232  1.1     is 	tst.b		STAG(%a6)		# is operand normalized?
   20233  1.1     is 	bne.b		fout_byte_denorm	# no
   20234  1.1     is 
   20235  1.1     is 	fmovm.x		SRC(%a0),&0x80		# load value
   20236  1.1     is 
   20237  1.1     is fout_byte_norm:
   20238  1.1     is 	fmov.l		%d0,%fpcr		# insert rnd prec,mode
   20239  1.1     is 
   20240  1.1     is 	fmov.b		%fp0,%d0		# exec move out w/ correct rnd mode
   20241  1.1     is 
   20242  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20243  1.1     is 	fmov.l		%fpsr,%d1		# fetch FPSR
   20244  1.1     is 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
   20245  1.1     is 
   20246  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20247  1.1     is 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20248  1.1     is 	beq.b		fout_byte_dn		# must save to integer regfile
   20249  1.1     is 
   20250  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20251  1.1     is 	bsr.l		_dmem_write_byte	# write byte
   20252  1.1     is 
   20253  1.1     is 	tst.l		%d1			# did dstore fail?
   20254  1.1     is 	bne.l		facc_out_b		# yes
   20255  1.1     is 
   20256  1.1     is 	rts
   20257  1.1     is 
   20258  1.1     is fout_byte_dn:
   20259  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20260  1.1     is 	andi.w		&0x7,%d1
   20261  1.1     is 	bsr.l		store_dreg_b
   20262  1.1     is 	rts
   20263  1.1     is 
   20264  1.1     is fout_byte_denorm:
   20265  1.1     is 	mov.l		SRC_EX(%a0),%d1
   20266  1.1     is 	andi.l		&0x80000000,%d1		# keep DENORM sign
   20267  1.1     is 	ori.l		&0x00800000,%d1		# make smallest sgl
   20268  1.1     is 	fmov.s		%d1,%fp0
   20269  1.1     is 	bra.b		fout_byte_norm
   20270  1.1     is 
   20271  1.1     is #################################################################
   20272  1.1     is # fmove.w out ###################################################
   20273  1.1     is #################################################################
   20274  1.1     is 
   20275  1.1     is # Only "Unimplemented Data Type" exceptions enter here. The operand
   20276  1.1     is # is either a DENORM or a NORM.
   20277  1.1     is fout_word:
   20278  1.1     is 	tst.b		STAG(%a6)		# is operand normalized?
   20279  1.1     is 	bne.b		fout_word_denorm	# no
   20280  1.1     is 
   20281  1.1     is 	fmovm.x		SRC(%a0),&0x80		# load value
   20282  1.1     is 
   20283  1.1     is fout_word_norm:
   20284  1.1     is 	fmov.l		%d0,%fpcr		# insert rnd prec:mode
   20285  1.1     is 
   20286  1.1     is 	fmov.w		%fp0,%d0		# exec move out w/ correct rnd mode
   20287  1.1     is 
   20288  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20289  1.1     is 	fmov.l		%fpsr,%d1		# fetch FPSR
   20290  1.1     is 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
   20291  1.1     is 
   20292  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20293  1.1     is 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20294  1.1     is 	beq.b		fout_word_dn		# must save to integer regfile
   20295  1.1     is 
   20296  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20297  1.1     is 	bsr.l		_dmem_write_word	# write word
   20298  1.1     is 
   20299  1.1     is 	tst.l		%d1			# did dstore fail?
   20300  1.1     is 	bne.l		facc_out_w		# yes
   20301  1.1     is 
   20302  1.1     is 	rts
   20303  1.1     is 
   20304  1.1     is fout_word_dn:
   20305  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20306  1.1     is 	andi.w		&0x7,%d1
   20307  1.1     is 	bsr.l		store_dreg_w
   20308  1.1     is 	rts
   20309  1.1     is 
   20310  1.1     is fout_word_denorm:
   20311  1.1     is 	mov.l		SRC_EX(%a0),%d1
   20312  1.1     is 	andi.l		&0x80000000,%d1		# keep DENORM sign
   20313  1.1     is 	ori.l		&0x00800000,%d1		# make smallest sgl
   20314  1.1     is 	fmov.s		%d1,%fp0
   20315  1.1     is 	bra.b		fout_word_norm
   20316  1.1     is 
   20317  1.1     is #################################################################
   20318  1.1     is # fmove.l out ###################################################
   20319  1.1     is #################################################################
   20320  1.1     is 
   20321  1.1     is # Only "Unimplemented Data Type" exceptions enter here. The operand
   20322  1.1     is # is either a DENORM or a NORM.
   20323  1.1     is fout_long:
   20324  1.1     is 	tst.b		STAG(%a6)		# is operand normalized?
   20325  1.1     is 	bne.b		fout_long_denorm	# no
   20326  1.1     is 
   20327  1.1     is 	fmovm.x		SRC(%a0),&0x80		# load value
   20328  1.1     is 
   20329  1.1     is fout_long_norm:
   20330  1.1     is 	fmov.l		%d0,%fpcr		# insert rnd prec:mode
   20331  1.1     is 
   20332  1.1     is 	fmov.l		%fp0,%d0		# exec move out w/ correct rnd mode
   20333  1.1     is 
   20334  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20335  1.1     is 	fmov.l		%fpsr,%d1		# fetch FPSR
   20336  1.1     is 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
   20337  1.1     is 
   20338  1.1     is fout_long_write:
   20339  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20340  1.1     is 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20341  1.1     is 	beq.b		fout_long_dn		# must save to integer regfile
   20342  1.1     is 
   20343  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20344  1.1     is 	bsr.l		_dmem_write_long	# write long
   20345  1.1     is 
   20346  1.1     is 	tst.l		%d1			# did dstore fail?
   20347  1.1     is 	bne.l		facc_out_l		# yes
   20348  1.1     is 
   20349  1.1     is 	rts
   20350  1.1     is 
   20351  1.1     is fout_long_dn:
   20352  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20353  1.1     is 	andi.w		&0x7,%d1
   20354  1.1     is 	bsr.l		store_dreg_l
   20355  1.1     is 	rts
   20356  1.1     is 
   20357  1.1     is fout_long_denorm:
   20358  1.1     is 	mov.l		SRC_EX(%a0),%d1
   20359  1.1     is 	andi.l		&0x80000000,%d1		# keep DENORM sign
   20360  1.1     is 	ori.l		&0x00800000,%d1		# make smallest sgl
   20361  1.1     is 	fmov.s		%d1,%fp0
   20362  1.1     is 	bra.b		fout_long_norm
   20363  1.1     is 
   20364  1.1     is #################################################################
   20365  1.1     is # fmove.x out ###################################################
   20366  1.1     is #################################################################
   20367  1.1     is 
   20368  1.1     is # Only "Unimplemented Data Type" exceptions enter here. The operand
   20369  1.1     is # is either a DENORM or a NORM.
   20370  1.1     is # The DENORM causes an Underflow exception.
   20371  1.1     is fout_ext:
   20372  1.1     is 
   20373  1.1     is # we copy the extended precision result to FP_SCR0 so that the reserved
   20374  1.1     is # 16-bit field gets zeroed. we do this since we promise not to disturb
   20375  1.1     is # what's at SRC(a0).
   20376  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20377  1.1     is 	clr.w		2+FP_SCR0_EX(%a6)	# clear reserved field
   20378  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20379  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20380  1.1     is 
   20381  1.1     is 	fmovm.x		SRC(%a0),&0x80		# return result
   20382  1.1     is 
   20383  1.1     is 	bsr.l		_calc_ea_fout		# fix stacked <ea>
   20384  1.1     is 
   20385  1.1     is 	mov.l		%a0,%a1			# pass: dst addr
   20386  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: src addr
   20387  1.1     is 	mov.l		&0xc,%d0		# pass: opsize is 12 bytes
   20388  1.1     is 
   20389  1.1     is # we must not yet write the extended precision data to the stack
   20390  1.1     is # in the pre-decrement case from supervisor mode or else we'll corrupt
   20391  1.1     is # the stack frame. so, leave it in FP_SRC for now and deal with it later...
   20392  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   20393  1.1     is 	beq.b		fout_ext_a7
   20394  1.1     is 
   20395  1.1     is 	bsr.l		_dmem_write		# write ext prec number to memory
   20396  1.1     is 
   20397  1.1     is 	tst.l		%d1			# did dstore fail?
   20398  1.1     is 	bne.w		fout_ext_err		# yes
   20399  1.1     is 
   20400  1.1     is 	tst.b		STAG(%a6)		# is operand normalized?
   20401  1.1     is 	bne.b		fout_ext_denorm		# no
   20402  1.1     is 	rts
   20403  1.1     is 
   20404  1.1     is # the number is a DENORM. must set the underflow exception bit
   20405  1.1     is fout_ext_denorm:
   20406  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set underflow exc bit
   20407  1.1     is 
   20408  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d0
   20409  1.1     is 	andi.b		&0x0a,%d0		# is UNFL or INEX enabled?
   20410  1.1     is 	bne.b		fout_ext_exc		# yes
   20411  1.1     is 	rts
   20412  1.1     is 
   20413  1.1     is # we don't want to do the write if the exception occurred in supervisor mode
   20414  1.1     is # so _mem_write2() handles this for us.
   20415  1.1     is fout_ext_a7:
   20416  1.1     is 	bsr.l		_mem_write2		# write ext prec number to memory
   20417  1.1     is 
   20418  1.1     is 	tst.l		%d1			# did dstore fail?
   20419  1.1     is 	bne.w		fout_ext_err		# yes
   20420  1.1     is 
   20421  1.1     is 	tst.b		STAG(%a6)		# is operand normalized?
   20422  1.1     is 	bne.b		fout_ext_denorm		# no
   20423  1.1     is 	rts
   20424  1.1     is 
   20425  1.1     is fout_ext_exc:
   20426  1.1     is 	lea		FP_SCR0(%a6),%a0
   20427  1.1     is 	bsr.l		norm			# normalize the mantissa
   20428  1.1     is 	neg.w		%d0			# new exp = -(shft amt)
   20429  1.1     is 	andi.w		&0x7fff,%d0
   20430  1.1     is 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# keep only old sign
   20431  1.1     is 	or.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   20432  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   20433  1.1     is 	rts
   20434  1.1     is 
   20435  1.1     is fout_ext_err:
   20436  1.1     is 	mov.l		EXC_A6(%a6),(%a6)	# fix stacked a6
   20437  1.1     is 	bra.l		facc_out_x
   20438  1.1     is 
   20439  1.1     is #########################################################################
   20440  1.1     is # fmove.s out ###########################################################
   20441  1.1     is #########################################################################
   20442  1.1     is fout_sgl:
   20443  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   20444  1.1     is 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   20445  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# save rnd prec,mode on stack
   20446  1.1     is 
   20447  1.1     is #
   20448  1.1     is # operand is a normalized number. first, we check to see if the move out
   20449  1.1     is # would cause either an underflow or overflow. these cases are handled
   20450  1.1     is # separately. otherwise, set the FPCR to the proper rounding mode and
   20451  1.1     is # execute the move.
   20452  1.1     is #
   20453  1.1     is 	mov.w		SRC_EX(%a0),%d0		# extract exponent
   20454  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   20455  1.1     is 
   20456  1.1     is 	cmpi.w		%d0,&SGL_HI		# will operand overflow?
   20457  1.1     is 	bgt.w		fout_sgl_ovfl		# yes; go handle OVFL
   20458  1.1     is 	beq.w		fout_sgl_may_ovfl	# maybe; go handle possible OVFL
   20459  1.1     is 	cmpi.w		%d0,&SGL_LO		# will operand underflow?
   20460  1.1     is 	blt.w		fout_sgl_unfl		# yes; go handle underflow
   20461  1.1     is 
   20462  1.1     is #
   20463  1.1     is # NORMs(in range) can be stored out by a simple "fmov.s"
   20464  1.1     is # Unnormalized inputs can come through this point.
   20465  1.1     is #
   20466  1.1     is fout_sgl_exg:
   20467  1.1     is 	fmovm.x		SRC(%a0),&0x80		# fetch fop from stack
   20468  1.1     is 
   20469  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20470  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   20471  1.1     is 
   20472  1.1     is 	fmov.s		%fp0,%d0		# store does convert and round
   20473  1.1     is 
   20474  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20475  1.1     is 	fmov.l		%fpsr,%d1		# save FPSR
   20476  1.1     is 
   20477  1.1     is 	or.w		%d1,2+USER_FPSR(%a6) 	# set possible inex2/ainex
   20478  1.1     is 
   20479  1.1     is fout_sgl_exg_write:
   20480  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20481  1.1     is 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20482  1.1     is 	beq.b		fout_sgl_exg_write_dn	# must save to integer regfile
   20483  1.1     is 
   20484  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20485  1.1     is 	bsr.l		_dmem_write_long	# write long
   20486  1.1     is 
   20487  1.1     is 	tst.l		%d1			# did dstore fail?
   20488  1.1     is 	bne.l		facc_out_l		# yes
   20489  1.1     is 
   20490  1.1     is 	rts
   20491  1.1     is 
   20492  1.1     is fout_sgl_exg_write_dn:
   20493  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20494  1.1     is 	andi.w		&0x7,%d1
   20495  1.1     is 	bsr.l		store_dreg_l
   20496  1.1     is 	rts
   20497  1.1     is 
   20498  1.1     is #
   20499  1.1     is # here, we know that the operand would UNFL if moved out to single prec,
   20500  1.1     is # so, denorm and round and then use generic store single routine to
   20501  1.1     is # write the value to memory.
   20502  1.1     is #
   20503  1.1     is fout_sgl_unfl:
   20504  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
   20505  1.1     is 
   20506  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20507  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20508  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20509  1.1     is 	mov.l		%a0,-(%sp)
   20510  1.1     is 
   20511  1.1     is 	clr.l		%d0			# pass: S.F. = 0
   20512  1.1     is 
   20513  1.1     is 	cmpi.b		STAG(%a6),&DENORM	# fetch src optype tag
   20514  1.1     is 	bne.b		fout_sgl_unfl_cont	# let DENORMs fall through
   20515  1.1     is 
   20516  1.1     is 	lea		FP_SCR0(%a6),%a0
   20517  1.1     is 	bsr.l		norm			# normalize the DENORM
   20518  1.1     is 
   20519  1.1     is fout_sgl_unfl_cont:
   20520  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   20521  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   20522  1.1     is 	bsr.l		unf_res			# calc default underflow result
   20523  1.1     is 
   20524  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to fop
   20525  1.1     is 	bsr.l		dst_sgl			# convert to single prec
   20526  1.1     is 
   20527  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20528  1.1     is 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20529  1.1     is 	beq.b		fout_sgl_unfl_dn	# must save to integer regfile
   20530  1.1     is 
   20531  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20532  1.1     is 	bsr.l		_dmem_write_long	# write long
   20533  1.1     is 
   20534  1.1     is 	tst.l		%d1			# did dstore fail?
   20535  1.1     is 	bne.l		facc_out_l		# yes
   20536  1.1     is 
   20537  1.1     is 	bra.b		fout_sgl_unfl_chkexc
   20538  1.1     is 
   20539  1.1     is fout_sgl_unfl_dn:
   20540  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20541  1.1     is 	andi.w		&0x7,%d1
   20542  1.1     is 	bsr.l		store_dreg_l
   20543  1.1     is 
   20544  1.1     is fout_sgl_unfl_chkexc:
   20545  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   20546  1.1     is 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20547  1.1     is 	bne.w		fout_sd_exc_unfl	# yes
   20548  1.1     is 	addq.l		&0x4,%sp
   20549  1.1     is 	rts
   20550  1.1     is 
   20551  1.1     is #
   20552  1.1     is # it's definitely an overflow so call ovf_res to get the correct answer
   20553  1.1     is #
   20554  1.1     is fout_sgl_ovfl:
   20555  1.1     is 	tst.b		3+SRC_HI(%a0)		# is result inexact?
   20556  1.1     is 	bne.b		fout_sgl_ovfl_inex2
   20557  1.1     is 	tst.l		SRC_LO(%a0)		# is result inexact?
   20558  1.1     is 	bne.b		fout_sgl_ovfl_inex2
   20559  1.1     is 	ori.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
   20560  1.1     is 	bra.b		fout_sgl_ovfl_cont
   20561  1.1     is fout_sgl_ovfl_inex2:
   20562  1.1     is 	ori.w		&ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
   20563  1.1     is 
   20564  1.1     is fout_sgl_ovfl_cont:
   20565  1.1     is 	mov.l		%a0,-(%sp)
   20566  1.1     is 
   20567  1.1     is # call ovf_res() w/ sgl prec and the correct rnd mode to create the default
   20568  1.1     is # overflow result. DON'T save the returned ccodes from ovf_res() since
   20569  1.1     is # fmove out doesn't alter them.
   20570  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   20571  1.1     is 	smi		%d1			# set if so
   20572  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass: sgl prec,rnd mode
   20573  1.1     is 	bsr.l		ovf_res			# calc OVFL result
   20574  1.1     is 	fmovm.x		(%a0),&0x80		# load default overflow result
   20575  1.1     is 	fmov.s		%fp0,%d0		# store to single
   20576  1.1     is 
   20577  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20578  1.1     is 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20579  1.1     is 	beq.b		fout_sgl_ovfl_dn	# must save to integer regfile
   20580  1.1     is 
   20581  1.1     is 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20582  1.1     is 	bsr.l		_dmem_write_long	# write long
   20583  1.1     is 
   20584  1.1     is 	tst.l		%d1			# did dstore fail?
   20585  1.1     is 	bne.l		facc_out_l		# yes
   20586  1.1     is 
   20587  1.1     is 	bra.b		fout_sgl_ovfl_chkexc
   20588  1.1     is 
   20589  1.1     is fout_sgl_ovfl_dn:
   20590  1.1     is 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20591  1.1     is 	andi.w		&0x7,%d1
   20592  1.1     is 	bsr.l		store_dreg_l
   20593  1.1     is 
   20594  1.1     is fout_sgl_ovfl_chkexc:
   20595  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   20596  1.1     is 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20597  1.1     is 	bne.w		fout_sd_exc_ovfl	# yes
   20598  1.1     is 	addq.l		&0x4,%sp
   20599  1.1     is 	rts
   20600  1.1     is 
   20601  1.1     is #
   20602  1.1     is # move out MAY overflow:
   20603  1.1     is # (1) force the exp to 0x3fff
   20604  1.1     is # (2) do a move w/ appropriate rnd mode
   20605  1.1     is # (3) if exp still equals zero, then insert original exponent
   20606  1.1     is #	for the correct result.
   20607  1.1     is #     if exp now equals one, then it overflowed so call ovf_res.
   20608  1.1     is #
   20609  1.1     is fout_sgl_may_ovfl:
   20610  1.1     is 	mov.w		SRC_EX(%a0),%d1		# fetch current sign
   20611  1.1     is 	andi.w		&0x8000,%d1		# keep it,clear exp
   20612  1.1     is 	ori.w		&0x3fff,%d1		# insert exp = 0
   20613  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert scaled exp
   20614  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
   20615  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
   20616  1.1     is 
   20617  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20618  1.1     is 
   20619  1.1     is 	fmov.x		FP_SCR0(%a6),%fp0	# force fop to be rounded
   20620  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20621  1.1     is 
   20622  1.1     is 	fabs.x		%fp0			# need absolute value
   20623  1.1     is 	fcmp.b		%fp0,&0x2		# did exponent increase?
   20624  1.1     is 	fblt.w		fout_sgl_exg		# no; go finish NORM
   20625  1.1     is 	bra.w		fout_sgl_ovfl		# yes; go handle overflow
   20626  1.1     is 
   20627  1.1     is ################
   20628  1.1     is 
   20629  1.1     is fout_sd_exc_unfl:
   20630  1.1     is 	mov.l		(%sp)+,%a0
   20631  1.1     is 
   20632  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20633  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20634  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20635  1.1     is 
   20636  1.1     is 	cmpi.b		STAG(%a6),&DENORM	# was src a DENORM?
   20637  1.1     is 	bne.b		fout_sd_exc_cont	# no
   20638  1.1     is 
   20639  1.1     is 	lea		FP_SCR0(%a6),%a0
   20640  1.1     is 	bsr.l		norm
   20641  1.1     is 	neg.l		%d0
   20642  1.1     is 	andi.w		&0x7fff,%d0
   20643  1.1     is 	bfins		%d0,FP_SCR0_EX(%a6){&1:&15}
   20644  1.1     is 	bra.b		fout_sd_exc_cont
   20645  1.1     is 
   20646  1.1     is fout_sd_exc:
   20647  1.1     is fout_sd_exc_ovfl:
   20648  1.1     is 	mov.l		(%sp)+,%a0		# restore a0
   20649  1.1     is 
   20650  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20651  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20652  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20653  1.1     is 
   20654  1.1     is fout_sd_exc_cont:
   20655  1.1     is 	bclr		&0x7,FP_SCR0_EX(%a6)	# clear sign bit
   20656  1.1     is 	sne.b		2+FP_SCR0_EX(%a6)	# set internal sign bit
   20657  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to DENORM
   20658  1.1     is 
   20659  1.1     is 	mov.b		3+L_SCR3(%a6),%d1
   20660  1.1     is 	lsr.b		&0x4,%d1
   20661  1.1     is 	andi.w		&0x0c,%d1
   20662  1.1     is 	swap		%d1
   20663  1.1     is 	mov.b		3+L_SCR3(%a6),%d1
   20664  1.1     is 	lsr.b		&0x4,%d1
   20665  1.1     is 	andi.w		&0x03,%d1
   20666  1.1     is 	clr.l		%d0			# pass: zero g,r,s
   20667  1.1     is 	bsr.l		_round			# round the DENORM
   20668  1.1     is 
   20669  1.1     is 	tst.b		2+FP_SCR0_EX(%a6)	# is EXOP negative?
   20670  1.1     is 	beq.b		fout_sd_exc_done	# no
   20671  1.1     is 	bset		&0x7,FP_SCR0_EX(%a6)	# yes
   20672  1.1     is 
   20673  1.1     is fout_sd_exc_done:
   20674  1.1     is 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   20675  1.1     is 	rts
   20676  1.1     is 
   20677  1.1     is #################################################################
   20678  1.1     is # fmove.d out ###################################################
   20679  1.1     is #################################################################
   20680  1.1     is fout_dbl:
   20681  1.1     is 	andi.b		&0x30,%d0		# clear rnd prec
   20682  1.1     is 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   20683  1.1     is 	mov.l		%d0,L_SCR3(%a6)		# save rnd prec,mode on stack
   20684  1.1     is 
   20685  1.1     is #
   20686  1.1     is # operand is a normalized number. first, we check to see if the move out
   20687  1.1     is # would cause either an underflow or overflow. these cases are handled
   20688  1.1     is # separately. otherwise, set the FPCR to the proper rounding mode and
   20689  1.1     is # execute the move.
   20690  1.1     is #
   20691  1.1     is 	mov.w		SRC_EX(%a0),%d0		# extract exponent
   20692  1.1     is 	andi.w		&0x7fff,%d0		# strip sign
   20693  1.1     is 
   20694  1.1     is 	cmpi.w		%d0,&DBL_HI		# will operand overflow?
   20695  1.1     is 	bgt.w		fout_dbl_ovfl		# yes; go handle OVFL
   20696  1.1     is 	beq.w		fout_dbl_may_ovfl	# maybe; go handle possible OVFL
   20697  1.1     is 	cmpi.w		%d0,&DBL_LO		# will operand underflow?
   20698  1.1     is 	blt.w		fout_dbl_unfl		# yes; go handle underflow
   20699  1.1     is 
   20700  1.1     is #
   20701  1.1     is # NORMs(in range) can be stored out by a simple "fmov.d"
   20702  1.1     is # Unnormalized inputs can come through this point.
   20703  1.1     is #
   20704  1.1     is fout_dbl_exg:
   20705  1.1     is 	fmovm.x		SRC(%a0),&0x80		# fetch fop from stack
   20706  1.1     is 
   20707  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20708  1.1     is 	fmov.l		&0x0,%fpsr		# clear FPSR
   20709  1.1     is 
   20710  1.1     is 	fmov.d		%fp0,L_SCR1(%a6)	# store does convert and round
   20711  1.1     is 
   20712  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20713  1.1     is 	fmov.l		%fpsr,%d0		# save FPSR
   20714  1.1     is 
   20715  1.1     is 	or.w		%d0,2+USER_FPSR(%a6) 	# set possible inex2/ainex
   20716  1.1     is 
   20717  1.1     is 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   20718  1.1     is 	lea		L_SCR1(%a6),%a0		# pass: src addr
   20719  1.1     is 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
   20720  1.1     is 	bsr.l		_dmem_write		# store dbl fop to memory
   20721  1.1     is 
   20722  1.1     is 	tst.l		%d1			# did dstore fail?
   20723  1.1     is 	bne.l		facc_out_d		# yes
   20724  1.1     is 
   20725  1.1     is 	rts					# no; so we're finished
   20726  1.1     is 
   20727  1.1     is #
   20728  1.1     is # here, we know that the operand would UNFL if moved out to double prec,
   20729  1.1     is # so, denorm and round and then use generic store double routine to
   20730  1.1     is # write the value to memory.
   20731  1.1     is #
   20732  1.1     is fout_dbl_unfl:
   20733  1.1     is 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
   20734  1.1     is 
   20735  1.1     is 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20736  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20737  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20738  1.1     is 	mov.l		%a0,-(%sp)
   20739  1.1     is 
   20740  1.1     is 	clr.l		%d0			# pass: S.F. = 0
   20741  1.1     is 
   20742  1.1     is 	cmpi.b		STAG(%a6),&DENORM	# fetch src optype tag
   20743  1.1     is 	bne.b		fout_dbl_unfl_cont	# let DENORMs fall through
   20744  1.1     is 
   20745  1.1     is 	lea		FP_SCR0(%a6),%a0
   20746  1.1     is 	bsr.l		norm			# normalize the DENORM
   20747  1.1     is 
   20748  1.1     is fout_dbl_unfl_cont:
   20749  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   20750  1.1     is 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   20751  1.1     is 	bsr.l		unf_res			# calc default underflow result
   20752  1.1     is 
   20753  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: ptr to fop
   20754  1.1     is 	bsr.l		dst_dbl			# convert to single prec
   20755  1.1     is 	mov.l		%d0,L_SCR1(%a6)
   20756  1.1     is 	mov.l		%d1,L_SCR2(%a6)
   20757  1.1     is 
   20758  1.1     is 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   20759  1.1     is 	lea		L_SCR1(%a6),%a0		# pass: src addr
   20760  1.1     is 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
   20761  1.1     is 	bsr.l		_dmem_write		# store dbl fop to memory
   20762  1.1     is 
   20763  1.1     is 	tst.l		%d1			# did dstore fail?
   20764  1.1     is 	bne.l		facc_out_d		# yes
   20765  1.1     is 
   20766  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   20767  1.1     is 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20768  1.1     is 	bne.w		fout_sd_exc_unfl	# yes
   20769  1.1     is 	addq.l		&0x4,%sp
   20770  1.1     is 	rts
   20771  1.1     is 
   20772  1.1     is #
   20773  1.1     is # it's definitely an overflow so call ovf_res to get the correct answer
   20774  1.1     is #
   20775  1.1     is fout_dbl_ovfl:
   20776  1.1     is 	mov.w		2+SRC_LO(%a0),%d0
   20777  1.1     is 	andi.w		&0x7ff,%d0
   20778  1.1     is 	bne.b		fout_dbl_ovfl_inex2
   20779  1.1     is 
   20780  1.1     is 	ori.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
   20781  1.1     is 	bra.b		fout_dbl_ovfl_cont
   20782  1.1     is fout_dbl_ovfl_inex2:
   20783  1.1     is 	ori.w		&ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
   20784  1.1     is 
   20785  1.1     is fout_dbl_ovfl_cont:
   20786  1.1     is 	mov.l		%a0,-(%sp)
   20787  1.1     is 
   20788  1.1     is # call ovf_res() w/ dbl prec and the correct rnd mode to create the default
   20789  1.1     is # overflow result. DON'T save the returned ccodes from ovf_res() since
   20790  1.1     is # fmove out doesn't alter them.
   20791  1.1     is 	tst.b		SRC_EX(%a0)		# is operand negative?
   20792  1.1     is 	smi		%d1			# set if so
   20793  1.1     is 	mov.l		L_SCR3(%a6),%d0		# pass: dbl prec,rnd mode
   20794  1.1     is 	bsr.l		ovf_res			# calc OVFL result
   20795  1.1     is 	fmovm.x		(%a0),&0x80		# load default overflow result
   20796  1.1     is 	fmov.d		%fp0,L_SCR1(%a6)	# store to double
   20797  1.1     is 
   20798  1.1     is 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   20799  1.1     is 	lea		L_SCR1(%a6),%a0		# pass: src addr
   20800  1.1     is 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
   20801  1.1     is 	bsr.l		_dmem_write		# store dbl fop to memory
   20802  1.1     is 
   20803  1.1     is 	tst.l		%d1			# did dstore fail?
   20804  1.1     is 	bne.l		facc_out_d		# yes
   20805  1.1     is 
   20806  1.1     is 	mov.b		FPCR_ENABLE(%a6),%d1
   20807  1.1     is 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20808  1.1     is 	bne.w		fout_sd_exc_ovfl	# yes
   20809  1.1     is 	addq.l		&0x4,%sp
   20810  1.1     is 	rts
   20811  1.1     is 
   20812  1.1     is #
   20813  1.1     is # move out MAY overflow:
   20814  1.1     is # (1) force the exp to 0x3fff
   20815  1.1     is # (2) do a move w/ appropriate rnd mode
   20816  1.1     is # (3) if exp still equals zero, then insert original exponent
   20817  1.1     is #	for the correct result.
   20818  1.1     is #     if exp now equals one, then it overflowed so call ovf_res.
   20819  1.1     is #
   20820  1.1     is fout_dbl_may_ovfl:
   20821  1.1     is 	mov.w		SRC_EX(%a0),%d1		# fetch current sign
   20822  1.1     is 	andi.w		&0x8000,%d1		# keep it,clear exp
   20823  1.1     is 	ori.w		&0x3fff,%d1		# insert exp = 0
   20824  1.1     is 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert scaled exp
   20825  1.1     is 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
   20826  1.1     is 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
   20827  1.1     is 
   20828  1.1     is 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20829  1.1     is 
   20830  1.1     is 	fmov.x		FP_SCR0(%a6),%fp0	# force fop to be rounded
   20831  1.1     is 	fmov.l		&0x0,%fpcr		# clear FPCR
   20832  1.1     is 
   20833  1.1     is 	fabs.x		%fp0			# need absolute value
   20834  1.1     is 	fcmp.b		%fp0,&0x2		# did exponent increase?
   20835  1.1     is 	fblt.w		fout_dbl_exg		# no; go finish NORM
   20836  1.1     is 	bra.w		fout_dbl_ovfl		# yes; go handle overflow
   20837  1.1     is 
   20838  1.1     is #########################################################################
   20839  1.1     is # XDEF ****************************************************************	#
   20840  1.1     is # 	dst_dbl(): create double precision value from extended prec.	#
   20841  1.1     is #									#
   20842  1.1     is # XREF ****************************************************************	#
   20843  1.1     is #	None								#
   20844  1.1     is #									#
   20845  1.1     is # INPUT ***************************************************************	#
   20846  1.1     is #	a0 = pointer to source operand in extended precision		#
   20847  1.1     is # 									#
   20848  1.1     is # OUTPUT **************************************************************	#
   20849  1.1     is #	d0 = hi(double precision result)				#
   20850  1.1     is #	d1 = lo(double precision result)				#
   20851  1.1     is #									#
   20852  1.1     is # ALGORITHM ***********************************************************	#
   20853  1.1     is #									#
   20854  1.1     is #  Changes extended precision to double precision.			#
   20855  1.1     is #  Note: no attempt is made to round the extended value to double.	#
   20856  1.1     is #	dbl_sign = ext_sign						#
   20857  1.1     is #	dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)		#
   20858  1.1     is #	get rid of ext integer bit					#
   20859  1.1     is #	dbl_mant = ext_mant{62:12}					#
   20860  1.1     is #									#
   20861  1.1     is #	    	---------------   ---------------    ---------------	#
   20862  1.1     is #  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |	#
   20863  1.1     is #	    	---------------   ---------------    ---------------	#
   20864  1.1     is #	   	 95	    64    63 62	      32      31     11	  0	#
   20865  1.1     is #				     |			     |		#
   20866  1.1     is #				     |			     |		#
   20867  1.1     is #				     |			     |		#
   20868  1.1     is #		 	             v   		     v		#
   20869  1.1     is #	    		      ---------------   ---------------		#
   20870  1.1     is #  double   ->  	      |s|exp| mant  |   |  mant       |		#
   20871  1.1     is #	    		      ---------------   ---------------		#
   20872  1.1     is #	   	 	      63     51   32   31	       0	#
   20873  1.1     is #									#
   20874  1.1     is #########################################################################
   20875  1.1     is 
   20876  1.1     is dst_dbl:
   20877  1.1     is 	clr.l		%d0			# clear d0
   20878  1.1     is 	mov.w		FTEMP_EX(%a0),%d0	# get exponent
   20879  1.1     is 	subi.w		&EXT_BIAS,%d0		# subtract extended precision bias
   20880  1.1     is 	addi.w		&DBL_BIAS,%d0		# add double precision bias
   20881  1.1     is 	tst.b		FTEMP_HI(%a0)		# is number a denorm?
   20882  1.1     is 	bmi.b		dst_get_dupper		# no
   20883  1.1     is 	subq.w		&0x1,%d0		# yes; denorm bias = DBL_BIAS - 1
   20884  1.1     is dst_get_dupper:
   20885  1.1     is 	swap		%d0			# d0 now in upper word
   20886  1.1     is 	lsl.l		&0x4,%d0		# d0 in proper place for dbl prec exp
   20887  1.1     is 	tst.b		FTEMP_EX(%a0)		# test sign
   20888  1.1     is 	bpl.b		dst_get_dman		# if postive, go process mantissa
   20889  1.1     is 	bset		&0x1f,%d0		# if negative, set sign
   20890  1.1     is dst_get_dman:
   20891  1.1     is 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
   20892  1.1     is 	bfextu		%d1{&1:&20},%d1		# get upper 20 bits of ms
   20893  1.1     is 	or.l		%d1,%d0			# put these bits in ms word of double
   20894  1.1     is 	mov.l		%d0,L_SCR1(%a6)		# put the new exp back on the stack
   20895  1.1     is 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
   20896  1.1     is 	mov.l		&21,%d0			# load shift count
   20897  1.1     is 	lsl.l		%d0,%d1			# put lower 11 bits in upper bits
   20898  1.1     is 	mov.l		%d1,L_SCR2(%a6)		# build lower lword in memory
   20899  1.1     is 	mov.l		FTEMP_LO(%a0),%d1	# get ls mantissa
   20900  1.1     is 	bfextu		%d1{&0:&21},%d0		# get ls 21 bits of double
   20901  1.1     is 	mov.l		L_SCR2(%a6),%d1
   20902  1.1     is 	or.l		%d0,%d1			# put them in double result
   20903  1.1     is 	mov.l		L_SCR1(%a6),%d0
   20904  1.1     is 	rts
   20905  1.1     is 
   20906  1.1     is #########################################################################
   20907  1.1     is # XDEF ****************************************************************	#
   20908  1.1     is # 	dst_sgl(): create single precision value from extended prec	#
   20909  1.1     is #									#
   20910  1.1     is # XREF ****************************************************************	#
   20911  1.1     is #									#
   20912  1.1     is # INPUT ***************************************************************	#
   20913  1.1     is #	a0 = pointer to source operand in extended precision		#
   20914  1.1     is # 									#
   20915  1.1     is # OUTPUT **************************************************************	#
   20916  1.1     is #	d0 = single precision result					#
   20917  1.1     is #									#
   20918  1.1     is # ALGORITHM ***********************************************************	#
   20919  1.1     is #									#
   20920  1.1     is # Changes extended precision to single precision.			#
   20921  1.1     is #	sgl_sign = ext_sign						#
   20922  1.1     is #	sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)		#
   20923  1.1     is #	get rid of ext integer bit					#
   20924  1.1     is #	sgl_mant = ext_mant{62:12}					#
   20925  1.1     is #									#
   20926  1.1     is #	    	---------------   ---------------    ---------------	#
   20927  1.1     is #  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |	#
   20928  1.1     is #	    	---------------   ---------------    ---------------	#
   20929  1.1     is #	   	 95	    64    63 62	   40 32      31     12	  0	#
   20930  1.1     is #				     |	   |				#
   20931  1.1     is #				     |	   |				#
   20932  1.1     is #				     |	   |				#
   20933  1.1     is #		 	             v     v				#
   20934  1.1     is #	    		      ---------------				#
   20935  1.1     is #  single   ->  	      |s|exp| mant  |				#
   20936  1.1     is #	    		      ---------------				#
   20937  1.1     is #	   	 	      31     22     0				#
   20938  1.1     is #									#
   20939  1.1     is #########################################################################
   20940  1.1     is 
   20941  1.1     is dst_sgl:
   20942  1.1     is 	clr.l		%d0
   20943  1.1     is 	mov.w		FTEMP_EX(%a0),%d0	# get exponent
   20944  1.1     is 	subi.w		&EXT_BIAS,%d0		# subtract extended precision bias
   20945  1.1     is 	addi.w		&SGL_BIAS,%d0		# add single precision bias
   20946  1.1     is 	tst.b		FTEMP_HI(%a0)		# is number a denorm?
   20947  1.1     is 	bmi.b		dst_get_supper		# no
   20948  1.1     is 	subq.w		&0x1,%d0		# yes; denorm bias = SGL_BIAS - 1
   20949  1.1     is dst_get_supper:
   20950  1.1     is 	swap		%d0			# put exp in upper word of d0
   20951  1.1     is 	lsl.l		&0x7,%d0		# shift it into single exp bits
   20952  1.1     is 	tst.b		FTEMP_EX(%a0)		# test sign
   20953  1.1     is 	bpl.b		dst_get_sman		# if positive, continue
   20954  1.1     is 	bset		&0x1f,%d0		# if negative, put in sign first
   20955  1.1     is dst_get_sman:
   20956  1.1     is 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
   20957  1.1     is 	andi.l		&0x7fffff00,%d1		# get upper 23 bits of ms
   20958  1.1     is 	lsr.l		&0x8,%d1		# and put them flush right
   20959  1.1     is 	or.l		%d1,%d0			# put these bits in ms word of single
   20960  1.1     is 	rts
   20961  1.1     is 
   20962  1.1     is ##############################################################################
   20963  1.1     is fout_pack:
   20964  1.1     is 	bsr.l		_calc_ea_fout		# fetch the <ea>
   20965  1.1     is 	mov.l		%a0,-(%sp)
   20966  1.1     is 
   20967  1.1     is 	mov.b		STAG(%a6),%d0		# fetch input type
   20968  1.1     is 	bne.w		fout_pack_not_norm	# input is not NORM
   20969  1.1     is 
   20970  1.1     is fout_pack_norm:
   20971  1.1     is 	btst		&0x4,EXC_CMDREG(%a6)	# static or dynamic?
   20972  1.1     is 	beq.b		fout_pack_s		# static
   20973  1.1     is 
   20974  1.1     is fout_pack_d:
   20975  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d1	# fetch dynamic reg
   20976  1.1     is 	lsr.b		&0x4,%d1
   20977  1.1     is 	andi.w		&0x7,%d1
   20978  1.1     is 
   20979  1.1     is 	bsr.l		fetch_dreg		# fetch Dn w/ k-factor
   20980  1.1     is 
   20981  1.1     is 	bra.b		fout_pack_type
   20982  1.1     is fout_pack_s:
   20983  1.1     is 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch static field
   20984  1.1     is 
   20985  1.1     is fout_pack_type:
   20986  1.1     is 	bfexts		%d0{&25:&7},%d0		# extract k-factor
   20987  1.1     is 	mov.l	%d0,-(%sp)
   20988  1.1     is 
   20989  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to input
   20990  1.1     is 
   20991  1.1     is # bindec is currently scrambling FP_SRC for denorm inputs.
   20992  1.1     is # we'll have to change this, but for now, tough luck!!!
   20993  1.1     is 	bsr.l		bindec			# convert xprec to packed
   20994  1.1     is 
   20995  1.1     is #	andi.l		&0xcfff000f,FP_SCR0(%a6) # clear unused fields
   20996  1.1     is 	andi.l		&0xcffff00f,FP_SCR0(%a6) # clear unused fields
   20997  1.1     is 
   20998  1.1     is 	mov.l	(%sp)+,%d0
   20999  1.1     is 
   21000  1.1     is 	tst.b		3+FP_SCR0_EX(%a6)
   21001  1.1     is 	bne.b		fout_pack_set
   21002  1.1     is 	tst.l		FP_SCR0_HI(%a6)
   21003  1.1     is 	bne.b		fout_pack_set
   21004  1.1     is 	tst.l		FP_SCR0_LO(%a6)
   21005  1.1     is 	bne.b		fout_pack_set
   21006  1.1     is 
   21007  1.1     is # add the extra condition that only if the k-factor was zero, too, should
   21008  1.1     is # we zero the exponent
   21009  1.1     is 	tst.l		%d0
   21010  1.1     is 	bne.b		fout_pack_set
   21011  1.1     is # "mantissa" is all zero which means that the answer is zero. but, the '040
   21012  1.1     is # algorithm allows the exponent to be non-zero. the 881/2 do not. therefore,
   21013  1.1     is # if the mantissa is zero, I will zero the exponent, too.
   21014  1.1     is # the question now is whether the exponents sign bit is allowed to be non-zero
   21015  1.1     is # for a zero, also...
   21016  1.1     is 	andi.w		&0xf000,FP_SCR0(%a6)
   21017  1.1     is 
   21018  1.1     is fout_pack_set:
   21019  1.1     is 
   21020  1.1     is 	lea		FP_SCR0(%a6),%a0	# pass: src addr
   21021  1.1     is 
   21022  1.1     is fout_pack_write:
   21023  1.1     is 	mov.l		(%sp)+,%a1		# pass: dst addr
   21024  1.1     is 	mov.l		&0xc,%d0		# pass: opsize is 12 bytes
   21025  1.1     is 
   21026  1.1     is 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   21027  1.1     is 	beq.b		fout_pack_a7
   21028  1.1     is 
   21029  1.1     is 	bsr.l		_dmem_write		# write ext prec number to memory
   21030  1.1     is 
   21031  1.1     is 	tst.l		%d1			# did dstore fail?
   21032  1.1     is 	bne.w		fout_ext_err		# yes
   21033  1.1     is 
   21034  1.1     is 	rts
   21035  1.1     is 
   21036  1.1     is # we don't want to do the write if the exception occurred in supervisor mode
   21037  1.1     is # so _mem_write2() handles this for us.
   21038  1.1     is fout_pack_a7:
   21039  1.1     is 	bsr.l		_mem_write2		# write ext prec number to memory
   21040  1.1     is 
   21041  1.1     is 	tst.l		%d1			# did dstore fail?
   21042  1.1     is 	bne.w		fout_ext_err		# yes
   21043  1.1     is 
   21044  1.1     is 	rts
   21045  1.1     is 
   21046  1.1     is fout_pack_not_norm:
   21047  1.1     is 	cmpi.b		%d0,&DENORM		# is it a DENORM?
   21048  1.1     is 	beq.w		fout_pack_norm		# yes
   21049  1.1     is 	lea		FP_SRC(%a6),%a0
   21050  1.1     is 	clr.w		2+FP_SRC_EX(%a6)
   21051  1.1     is 	cmpi.b		%d0,&SNAN		# is it an SNAN?
   21052  1.1     is 	beq.b		fout_pack_snan		# yes
   21053  1.1     is 	bra.b		fout_pack_write		# no
   21054  1.1     is 
   21055  1.1     is fout_pack_snan:
   21056  1.1     is 	ori.w		&snaniop2_mask,FPSR_EXCEPT(%a6) # set SNAN/AIOP
   21057  1.1     is 	bset		&0x6,FP_SRC_HI(%a6)	# set snan bit
   21058  1.1     is 	bra.b		fout_pack_write
   21059  1.1     is 
   21060  1.1     is #########################################################################
   21061  1.1     is # XDEF ****************************************************************	#
   21062  1.1     is #	fetch_dreg(): fetch register according to index in d1		#
   21063  1.1     is #									#
   21064  1.1     is # XREF ****************************************************************	#
   21065  1.1     is #	None								#
   21066  1.1     is #									#
   21067  1.1     is # INPUT ***************************************************************	#
   21068  1.1     is #	d1 = index of register to fetch from				#
   21069  1.1     is # 									#
   21070  1.1     is # OUTPUT **************************************************************	#
   21071  1.1     is #	d0 = value of register fetched					#
   21072  1.1     is #									#
   21073  1.1     is # ALGORITHM ***********************************************************	#
   21074  1.1     is #	According to the index value in d1 which can range from zero 	#
   21075  1.1     is # to fifteen, load the corresponding register file value (where 	#
   21076  1.1     is # address register indexes start at 8). D0/D1/A0/A1/A6/A7 are on the	#
   21077  1.1     is # stack. The rest should still be in their original places.		#
   21078  1.1     is #									#
   21079  1.1     is #########################################################################
   21080  1.1     is 
   21081  1.1     is # this routine leaves d1 intact for subsequent store_dreg calls.
   21082  1.1     is 	global		fetch_dreg
   21083  1.1     is fetch_dreg:
   21084  1.1     is 	mov.w		(tbl_fdreg.b,%pc,%d1.w*2),%d0
   21085  1.1     is 	jmp		(tbl_fdreg.b,%pc,%d0.w*1)
   21086  1.1     is 
   21087  1.1     is tbl_fdreg:
   21088  1.1     is 	short		fdreg0 - tbl_fdreg
   21089  1.1     is 	short		fdreg1 - tbl_fdreg
   21090  1.1     is 	short		fdreg2 - tbl_fdreg
   21091  1.1     is 	short		fdreg3 - tbl_fdreg
   21092  1.1     is 	short		fdreg4 - tbl_fdreg
   21093  1.1     is 	short		fdreg5 - tbl_fdreg
   21094  1.1     is 	short		fdreg6 - tbl_fdreg
   21095  1.1     is 	short		fdreg7 - tbl_fdreg
   21096  1.1     is 	short		fdreg8 - tbl_fdreg
   21097  1.1     is 	short		fdreg9 - tbl_fdreg
   21098  1.1     is 	short		fdrega - tbl_fdreg
   21099  1.1     is 	short		fdregb - tbl_fdreg
   21100  1.1     is 	short		fdregc - tbl_fdreg
   21101  1.1     is 	short		fdregd - tbl_fdreg
   21102  1.1     is 	short		fdrege - tbl_fdreg
   21103  1.1     is 	short		fdregf - tbl_fdreg
   21104  1.1     is 
   21105  1.1     is fdreg0:
   21106  1.1     is 	mov.l		EXC_DREGS+0x0(%a6),%d0
   21107  1.1     is 	rts
   21108  1.1     is fdreg1:
   21109  1.1     is 	mov.l		EXC_DREGS+0x4(%a6),%d0
   21110  1.1     is 	rts
   21111  1.1     is fdreg2:
   21112  1.1     is 	mov.l		%d2,%d0
   21113  1.1     is 	rts
   21114  1.1     is fdreg3:
   21115  1.1     is 	mov.l		%d3,%d0
   21116  1.1     is 	rts
   21117  1.1     is fdreg4:
   21118  1.1     is 	mov.l		%d4,%d0
   21119  1.1     is 	rts
   21120  1.1     is fdreg5:
   21121  1.1     is 	mov.l		%d5,%d0
   21122  1.1     is 	rts
   21123  1.1     is fdreg6:
   21124  1.1     is 	mov.l		%d6,%d0
   21125  1.1     is 	rts
   21126  1.1     is fdreg7:
   21127  1.1     is 	mov.l		%d7,%d0
   21128  1.1     is 	rts
   21129  1.1     is fdreg8:
   21130  1.1     is 	mov.l		EXC_DREGS+0x8(%a6),%d0
   21131  1.1     is 	rts
   21132  1.1     is fdreg9:
   21133  1.1     is 	mov.l		EXC_DREGS+0xc(%a6),%d0
   21134  1.1     is 	rts
   21135  1.1     is fdrega:
   21136  1.1     is 	mov.l		%a2,%d0
   21137  1.1     is 	rts
   21138  1.1     is fdregb:
   21139  1.1     is 	mov.l		%a3,%d0
   21140  1.1     is 	rts
   21141  1.1     is fdregc:
   21142  1.1     is 	mov.l		%a4,%d0
   21143  1.1     is 	rts
   21144  1.1     is fdregd:
   21145  1.1     is 	mov.l		%a5,%d0
   21146  1.1     is 	rts
   21147  1.1     is fdrege:
   21148  1.1     is 	mov.l		(%a6),%d0
   21149  1.1     is 	rts
   21150  1.1     is fdregf:
   21151  1.1     is 	mov.l		EXC_A7(%a6),%d0
   21152  1.1     is 	rts
   21153  1.1     is 
   21154  1.1     is #########################################################################
   21155  1.1     is # XDEF ****************************************************************	#
   21156  1.1     is #	store_dreg_l(): store longword to data register specified by d1	#
   21157  1.1     is #									#
   21158  1.1     is # XREF ****************************************************************	#
   21159  1.1     is #	None								#
   21160  1.1     is #									#
   21161  1.1     is # INPUT ***************************************************************	#
   21162  1.1     is #	d0 = longowrd value to store					#
   21163  1.1     is #	d1 = index of register to fetch from				#
   21164  1.1     is # 									#
   21165  1.1     is # OUTPUT **************************************************************	#
   21166  1.1     is #	(data register is updated)					#
   21167  1.1     is #									#
   21168  1.1     is # ALGORITHM ***********************************************************	#
   21169  1.1     is #	According to the index value in d1, store the longword value	#
   21170  1.1     is # in d0 to the corresponding data register. D0/D1 are on the stack	#
   21171  1.1     is # while the rest are in their initial places.				#
   21172  1.1     is #									#
   21173  1.1     is #########################################################################
   21174  1.1     is 
   21175  1.1     is 	global		store_dreg_l
   21176  1.1     is store_dreg_l:
   21177  1.1     is 	mov.w		(tbl_sdregl.b,%pc,%d1.w*2),%d1
   21178  1.1     is 	jmp		(tbl_sdregl.b,%pc,%d1.w*1)
   21179  1.1     is 
   21180  1.1     is tbl_sdregl:
   21181  1.1     is 	short		sdregl0 - tbl_sdregl
   21182  1.1     is 	short		sdregl1 - tbl_sdregl
   21183  1.1     is 	short		sdregl2 - tbl_sdregl
   21184  1.1     is 	short		sdregl3 - tbl_sdregl
   21185  1.1     is 	short		sdregl4 - tbl_sdregl
   21186  1.1     is 	short		sdregl5 - tbl_sdregl
   21187  1.1     is 	short		sdregl6 - tbl_sdregl
   21188  1.1     is 	short		sdregl7 - tbl_sdregl
   21189  1.1     is 
   21190  1.1     is sdregl0:
   21191  1.1     is 	mov.l		%d0,EXC_DREGS+0x0(%a6)
   21192  1.1     is 	rts
   21193  1.1     is sdregl1:
   21194  1.1     is 	mov.l		%d0,EXC_DREGS+0x4(%a6)
   21195  1.1     is 	rts
   21196  1.1     is sdregl2:
   21197  1.1     is 	mov.l		%d0,%d2
   21198  1.1     is 	rts
   21199  1.1     is sdregl3:
   21200  1.1     is 	mov.l		%d0,%d3
   21201  1.1     is 	rts
   21202  1.1     is sdregl4:
   21203  1.1     is 	mov.l		%d0,%d4
   21204  1.1     is 	rts
   21205  1.1     is sdregl5:
   21206  1.1     is 	mov.l		%d0,%d5
   21207  1.1     is 	rts
   21208  1.1     is sdregl6:
   21209  1.1     is 	mov.l		%d0,%d6
   21210  1.1     is 	rts
   21211  1.1     is sdregl7:
   21212  1.1     is 	mov.l		%d0,%d7
   21213  1.1     is 	rts
   21214  1.1     is 
   21215  1.1     is #########################################################################
   21216  1.1     is # XDEF ****************************************************************	#
   21217  1.1     is #	store_dreg_w(): store word to data register specified by d1	#
   21218  1.1     is #									#
   21219  1.1     is # XREF ****************************************************************	#
   21220  1.1     is #	None								#
   21221  1.1     is #									#
   21222  1.1     is # INPUT ***************************************************************	#
   21223  1.1     is #	d0 = word value to store					#
   21224  1.1     is #	d1 = index of register to fetch from				#
   21225  1.1     is # 									#
   21226  1.1     is # OUTPUT **************************************************************	#
   21227  1.1     is #	(data register is updated)					#
   21228  1.1     is #									#
   21229  1.1     is # ALGORITHM ***********************************************************	#
   21230  1.1     is #	According to the index value in d1, store the word value	#
   21231  1.1     is # in d0 to the corresponding data register. D0/D1 are on the stack	#
   21232  1.1     is # while the rest are in their initial places.				#
   21233  1.1     is #									#
   21234  1.1     is #########################################################################
   21235  1.1     is 
   21236  1.1     is 	global		store_dreg_w
   21237  1.1     is store_dreg_w:
   21238  1.1     is 	mov.w		(tbl_sdregw.b,%pc,%d1.w*2),%d1
   21239  1.1     is 	jmp		(tbl_sdregw.b,%pc,%d1.w*1)
   21240  1.1     is 
   21241  1.1     is tbl_sdregw:
   21242  1.1     is 	short		sdregw0 - tbl_sdregw
   21243  1.1     is 	short		sdregw1 - tbl_sdregw
   21244  1.1     is 	short		sdregw2 - tbl_sdregw
   21245  1.1     is 	short		sdregw3 - tbl_sdregw
   21246  1.1     is 	short		sdregw4 - tbl_sdregw
   21247  1.1     is 	short		sdregw5 - tbl_sdregw
   21248  1.1     is 	short		sdregw6 - tbl_sdregw
   21249  1.1     is 	short		sdregw7 - tbl_sdregw
   21250  1.1     is 
   21251  1.1     is sdregw0:
   21252  1.1     is 	mov.w		%d0,2+EXC_DREGS+0x0(%a6)
   21253  1.1     is 	rts
   21254  1.1     is sdregw1:
   21255  1.1     is 	mov.w		%d0,2+EXC_DREGS+0x4(%a6)
   21256  1.1     is 	rts
   21257  1.1     is sdregw2:
   21258  1.1     is 	mov.w		%d0,%d2
   21259  1.1     is 	rts
   21260  1.1     is sdregw3:
   21261  1.1     is 	mov.w		%d0,%d3
   21262  1.1     is 	rts
   21263  1.1     is sdregw4:
   21264  1.1     is 	mov.w		%d0,%d4
   21265  1.1     is 	rts
   21266  1.1     is sdregw5:
   21267  1.1     is 	mov.w		%d0,%d5
   21268  1.1     is 	rts
   21269  1.1     is sdregw6:
   21270  1.1     is 	mov.w		%d0,%d6
   21271  1.1     is 	rts
   21272  1.1     is sdregw7:
   21273  1.1     is 	mov.w		%d0,%d7
   21274  1.1     is 	rts
   21275  1.1     is 
   21276  1.1     is #########################################################################
   21277  1.1     is # XDEF ****************************************************************	#
   21278  1.1     is #	store_dreg_b(): store byte to data register specified by d1	#
   21279  1.1     is #									#
   21280  1.1     is # XREF ****************************************************************	#
   21281  1.1     is #	None								#
   21282  1.1     is #									#
   21283  1.1     is # INPUT ***************************************************************	#
   21284  1.1     is #	d0 = byte value to store					#
   21285  1.1     is #	d1 = index of register to fetch from				#
   21286  1.1     is # 									#
   21287  1.1     is # OUTPUT **************************************************************	#
   21288  1.1     is #	(data register is updated)					#
   21289  1.1     is #									#
   21290  1.1     is # ALGORITHM ***********************************************************	#
   21291  1.1     is #	According to the index value in d1, store the byte value	#
   21292  1.1     is # in d0 to the corresponding data register. D0/D1 are on the stack	#
   21293  1.1     is # while the rest are in their initial places.				#
   21294  1.1     is #									#
   21295  1.1     is #########################################################################
   21296  1.1     is 
   21297  1.1     is 	global		store_dreg_b
   21298  1.1     is store_dreg_b:
   21299  1.1     is 	mov.w		(tbl_sdregb.b,%pc,%d1.w*2),%d1
   21300  1.1     is 	jmp		(tbl_sdregb.b,%pc,%d1.w*1)
   21301  1.1     is 
   21302  1.1     is tbl_sdregb:
   21303  1.1     is 	short		sdregb0 - tbl_sdregb
   21304  1.1     is 	short		sdregb1 - tbl_sdregb
   21305  1.1     is 	short		sdregb2 - tbl_sdregb
   21306  1.1     is 	short		sdregb3 - tbl_sdregb
   21307  1.1     is 	short		sdregb4 - tbl_sdregb
   21308  1.1     is 	short		sdregb5 - tbl_sdregb
   21309  1.1     is 	short		sdregb6 - tbl_sdregb
   21310  1.1     is 	short		sdregb7 - tbl_sdregb
   21311  1.1     is 
   21312  1.1     is sdregb0:
   21313  1.1     is 	mov.b		%d0,3+EXC_DREGS+0x0(%a6)
   21314  1.1     is 	rts
   21315  1.1     is sdregb1:
   21316  1.1     is 	mov.b		%d0,3+EXC_DREGS+0x4(%a6)
   21317  1.1     is 	rts
   21318  1.1     is sdregb2:
   21319  1.1     is 	mov.b		%d0,%d2
   21320  1.1     is 	rts
   21321  1.1     is sdregb3:
   21322  1.1     is 	mov.b		%d0,%d3
   21323  1.1     is 	rts
   21324  1.1     is sdregb4:
   21325  1.1     is 	mov.b		%d0,%d4
   21326  1.1     is 	rts
   21327  1.1     is sdregb5:
   21328  1.1     is 	mov.b		%d0,%d5
   21329  1.1     is 	rts
   21330  1.1     is sdregb6:
   21331  1.1     is 	mov.b		%d0,%d6
   21332  1.1     is 	rts
   21333  1.1     is sdregb7:
   21334  1.1     is 	mov.b		%d0,%d7
   21335  1.1     is 	rts
   21336  1.1     is 
   21337  1.1     is #########################################################################
   21338  1.1     is # XDEF ****************************************************************	#
   21339  1.1     is #	inc_areg(): increment an address register by the value in d0	#
   21340  1.1     is #									#
   21341  1.1     is # XREF ****************************************************************	#
   21342  1.1     is #	None								#
   21343  1.1     is #									#
   21344  1.1     is # INPUT ***************************************************************	#
   21345  1.1     is #	d0 = amount to increment by					#
   21346  1.1     is #	d1 = index of address register to increment			#
   21347  1.1     is # 									#
   21348  1.1     is # OUTPUT **************************************************************	#
   21349  1.1     is #	(address register is updated)					#
   21350  1.1     is #									#
   21351  1.1     is # ALGORITHM ***********************************************************	#
   21352  1.1     is # 	Typically used for an instruction w/ a post-increment <ea>, 	#
   21353  1.1     is # this routine adds the increment value in d0 to the address register	#
   21354  1.1     is # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside	#
   21355  1.1     is # in their original places.						#
   21356  1.1     is # 	For a7, if the increment amount is one, then we have to 	#
   21357  1.1     is # increment by two. For any a7 update, set the mia7_flag so that if	#
   21358  1.1     is # an access error exception occurs later in emulation, this address	#
   21359  1.1     is # register update can be undone.					#
   21360  1.1     is #									#
   21361  1.1     is #########################################################################
   21362  1.1     is 
   21363  1.1     is 	global		inc_areg
   21364  1.1     is inc_areg:
   21365  1.1     is 	mov.w		(tbl_iareg.b,%pc,%d1.w*2),%d1
   21366  1.1     is 	jmp		(tbl_iareg.b,%pc,%d1.w*1)
   21367  1.1     is 
   21368  1.1     is tbl_iareg:
   21369  1.1     is 	short		iareg0 - tbl_iareg
   21370  1.1     is 	short		iareg1 - tbl_iareg
   21371  1.1     is 	short		iareg2 - tbl_iareg
   21372  1.1     is 	short		iareg3 - tbl_iareg
   21373  1.1     is 	short		iareg4 - tbl_iareg
   21374  1.1     is 	short		iareg5 - tbl_iareg
   21375  1.1     is 	short		iareg6 - tbl_iareg
   21376  1.1     is 	short		iareg7 - tbl_iareg
   21377  1.1     is 
   21378  1.1     is iareg0:	add.l		%d0,EXC_DREGS+0x8(%a6)
   21379  1.1     is 	rts
   21380  1.1     is iareg1:	add.l		%d0,EXC_DREGS+0xc(%a6)
   21381  1.1     is 	rts
   21382  1.1     is iareg2:	add.l		%d0,%a2
   21383  1.1     is 	rts
   21384  1.1     is iareg3:	add.l		%d0,%a3
   21385  1.1     is 	rts
   21386  1.1     is iareg4:	add.l		%d0,%a4
   21387  1.1     is 	rts
   21388  1.1     is iareg5:	add.l		%d0,%a5
   21389  1.1     is 	rts
   21390  1.1     is iareg6:	add.l		%d0,(%a6)
   21391  1.1     is 	rts
   21392  1.1     is iareg7:	mov.b		&mia7_flg,SPCOND_FLG(%a6)
   21393  1.1     is 	cmpi.b		%d0,&0x1
   21394  1.1     is 	beq.b		iareg7b
   21395  1.1     is 	add.l		%d0,EXC_A7(%a6)
   21396  1.1     is 	rts
   21397  1.1     is iareg7b:
   21398  1.1     is 	addq.l		&0x2,EXC_A7(%a6)
   21399  1.1     is 	rts
   21400  1.1     is 
   21401  1.1     is #########################################################################
   21402  1.1     is # XDEF ****************************************************************	#
   21403  1.1     is #	dec_areg(): decrement an address register by the value in d0	#
   21404  1.1     is #									#
   21405  1.1     is # XREF ****************************************************************	#
   21406  1.1     is #	None								#
   21407  1.1     is #									#
   21408  1.1     is # INPUT ***************************************************************	#
   21409  1.1     is #	d0 = amount to decrement by					#
   21410  1.1     is #	d1 = index of address register to decrement			#
   21411  1.1     is # 									#
   21412  1.1     is # OUTPUT **************************************************************	#
   21413  1.1     is #	(address register is updated)					#
   21414  1.1     is #									#
   21415  1.1     is # ALGORITHM ***********************************************************	#
   21416  1.1     is # 	Typically used for an instruction w/ a pre-decrement <ea>, 	#
   21417  1.1     is # this routine adds the decrement value in d0 to the address register	#
   21418  1.1     is # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside	#
   21419  1.1     is # in their original places.						#
   21420  1.1     is # 	For a7, if the decrement amount is one, then we have to 	#
   21421  1.1     is # decrement by two. For any a7 update, set the mda7_flag so that if	#
   21422  1.1     is # an access error exception occurs later in emulation, this address	#
   21423  1.1     is # register update can be undone.					#
   21424  1.1     is #									#
   21425  1.1     is #########################################################################
   21426  1.1     is 
   21427  1.1     is 	global		dec_areg
   21428  1.1     is dec_areg:
   21429  1.1     is 	mov.w		(tbl_dareg.b,%pc,%d1.w*2),%d1
   21430  1.1     is 	jmp		(tbl_dareg.b,%pc,%d1.w*1)
   21431  1.1     is 
   21432  1.1     is tbl_dareg:
   21433  1.1     is 	short		dareg0 - tbl_dareg
   21434  1.1     is 	short		dareg1 - tbl_dareg
   21435  1.1     is 	short		dareg2 - tbl_dareg
   21436  1.1     is 	short		dareg3 - tbl_dareg
   21437  1.1     is 	short		dareg4 - tbl_dareg
   21438  1.1     is 	short		dareg5 - tbl_dareg
   21439  1.1     is 	short		dareg6 - tbl_dareg
   21440  1.1     is 	short		dareg7 - tbl_dareg
   21441  1.1     is 
   21442  1.1     is dareg0:	sub.l		%d0,EXC_DREGS+0x8(%a6)
   21443  1.1     is 	rts
   21444  1.1     is dareg1:	sub.l		%d0,EXC_DREGS+0xc(%a6)
   21445  1.1     is 	rts
   21446  1.1     is dareg2:	sub.l		%d0,%a2
   21447  1.1     is 	rts
   21448  1.1     is dareg3:	sub.l		%d0,%a3
   21449  1.1     is 	rts
   21450  1.1     is dareg4:	sub.l		%d0,%a4
   21451  1.1     is 	rts
   21452  1.1     is dareg5:	sub.l		%d0,%a5
   21453  1.1     is 	rts
   21454  1.1     is dareg6:	sub.l		%d0,(%a6)
   21455  1.1     is 	rts
   21456  1.1     is dareg7:	mov.b		&mda7_flg,SPCOND_FLG(%a6)
   21457  1.1     is 	cmpi.b		%d0,&0x1
   21458  1.1     is 	beq.b		dareg7b
   21459  1.1     is 	sub.l		%d0,EXC_A7(%a6)
   21460  1.1     is 	rts
   21461  1.1     is dareg7b:
   21462  1.1     is 	subq.l		&0x2,EXC_A7(%a6)
   21463  1.1     is 	rts
   21464  1.1     is 
   21465  1.1     is ##############################################################################
   21466  1.1     is 
   21467  1.1     is #########################################################################
   21468  1.1     is # XDEF ****************************************************************	#
   21469  1.1     is #	load_fpn1(): load FP register value into FP_SRC(a6).		#
   21470  1.1     is #									#
   21471  1.1     is # XREF ****************************************************************	#
   21472  1.1     is #	None								#
   21473  1.1     is #									#
   21474  1.1     is # INPUT ***************************************************************	#
   21475  1.1     is #	d0 = index of FP register to load				#
   21476  1.1     is # 									#
   21477  1.1     is # OUTPUT **************************************************************	#
   21478  1.1     is #	FP_SRC(a6) = value loaded from FP register file			#
   21479  1.1     is #									#
   21480  1.1     is # ALGORITHM ***********************************************************	#
   21481  1.1     is #	Using the index in d0, load FP_SRC(a6) with a number from the 	#
   21482  1.1     is # FP register file.							#
   21483  1.1     is #									#
   21484  1.1     is #########################################################################
   21485  1.1     is 
   21486  1.1     is 	global 		load_fpn1
   21487  1.1     is load_fpn1:
   21488  1.1     is 	mov.w		(tbl_load_fpn1.b,%pc,%d0.w*2), %d0
   21489  1.1     is 	jmp		(tbl_load_fpn1.b,%pc,%d0.w*1)
   21490  1.1     is 
   21491  1.1     is tbl_load_fpn1:
   21492  1.1     is 	short		load_fpn1_0 - tbl_load_fpn1
   21493  1.1     is 	short		load_fpn1_1 - tbl_load_fpn1
   21494  1.1     is 	short		load_fpn1_2 - tbl_load_fpn1
   21495  1.1     is 	short		load_fpn1_3 - tbl_load_fpn1
   21496  1.1     is 	short		load_fpn1_4 - tbl_load_fpn1
   21497  1.1     is 	short		load_fpn1_5 - tbl_load_fpn1
   21498  1.1     is 	short		load_fpn1_6 - tbl_load_fpn1
   21499  1.1     is 	short		load_fpn1_7 - tbl_load_fpn1
   21500  1.1     is 
   21501  1.1     is load_fpn1_0:
   21502  1.1     is 	mov.l		0+EXC_FP0(%a6), 0+FP_SRC(%a6)
   21503  1.1     is 	mov.l		4+EXC_FP0(%a6), 4+FP_SRC(%a6)
   21504  1.1     is 	mov.l		8+EXC_FP0(%a6), 8+FP_SRC(%a6)
   21505  1.1     is 	lea		FP_SRC(%a6), %a0
   21506  1.1     is 	rts
   21507  1.1     is load_fpn1_1:
   21508  1.1     is 	mov.l		0+EXC_FP1(%a6), 0+FP_SRC(%a6)
   21509  1.1     is 	mov.l		4+EXC_FP1(%a6), 4+FP_SRC(%a6)
   21510  1.1     is 	mov.l		8+EXC_FP1(%a6), 8+FP_SRC(%a6)
   21511  1.1     is 	lea		FP_SRC(%a6), %a0
   21512  1.1     is 	rts
   21513  1.1     is load_fpn1_2:
   21514  1.1     is 	fmovm.x		&0x20, FP_SRC(%a6)
   21515  1.1     is 	lea		FP_SRC(%a6), %a0
   21516  1.1     is 	rts
   21517  1.1     is load_fpn1_3:
   21518  1.1     is 	fmovm.x		&0x10, FP_SRC(%a6)
   21519  1.1     is 	lea		FP_SRC(%a6), %a0
   21520  1.1     is 	rts
   21521  1.1     is load_fpn1_4:
   21522  1.1     is 	fmovm.x		&0x08, FP_SRC(%a6)
   21523  1.1     is 	lea		FP_SRC(%a6), %a0
   21524  1.1     is 	rts
   21525  1.1     is load_fpn1_5:
   21526  1.1     is 	fmovm.x		&0x04, FP_SRC(%a6)
   21527  1.1     is 	lea		FP_SRC(%a6), %a0
   21528  1.1     is 	rts
   21529  1.1     is load_fpn1_6:
   21530  1.1     is 	fmovm.x		&0x02, FP_SRC(%a6)
   21531  1.1     is 	lea		FP_SRC(%a6), %a0
   21532  1.1     is 	rts
   21533  1.1     is load_fpn1_7:
   21534  1.1     is 	fmovm.x		&0x01, FP_SRC(%a6)
   21535  1.1     is 	lea		FP_SRC(%a6), %a0
   21536  1.1     is 	rts
   21537  1.1     is 
   21538  1.1     is #############################################################################
   21539  1.1     is 
   21540  1.1     is #########################################################################
   21541  1.1     is # XDEF ****************************************************************	#
   21542  1.1     is #	load_fpn2(): load FP register value into FP_DST(a6).		#
   21543  1.1     is #									#
   21544  1.1     is # XREF ****************************************************************	#
   21545  1.1     is #	None								#
   21546  1.1     is #									#
   21547  1.1     is # INPUT ***************************************************************	#
   21548  1.1     is #	d0 = index of FP register to load				#
   21549  1.1     is # 									#
   21550  1.1     is # OUTPUT **************************************************************	#
   21551  1.1     is #	FP_DST(a6) = value loaded from FP register file			#
   21552  1.1     is #									#
   21553  1.1     is # ALGORITHM ***********************************************************	#
   21554  1.1     is #	Using the index in d0, load FP_DST(a6) with a number from the 	#
   21555  1.1     is # FP register file.							#
   21556  1.1     is #									#
   21557  1.1     is #########################################################################
   21558  1.1     is 
   21559  1.1     is 	global		load_fpn2
   21560  1.1     is load_fpn2:
   21561  1.1     is 	mov.w		(tbl_load_fpn2.b,%pc,%d0.w*2), %d0
   21562  1.1     is 	jmp		(tbl_load_fpn2.b,%pc,%d0.w*1)
   21563  1.1     is 
   21564  1.1     is tbl_load_fpn2:
   21565  1.1     is 	short		load_fpn2_0 - tbl_load_fpn2
   21566  1.1     is 	short		load_fpn2_1 - tbl_load_fpn2
   21567  1.1     is 	short		load_fpn2_2 - tbl_load_fpn2
   21568  1.1     is 	short		load_fpn2_3 - tbl_load_fpn2
   21569  1.1     is 	short		load_fpn2_4 - tbl_load_fpn2
   21570  1.1     is 	short		load_fpn2_5 - tbl_load_fpn2
   21571  1.1     is 	short		load_fpn2_6 - tbl_load_fpn2
   21572  1.1     is 	short		load_fpn2_7 - tbl_load_fpn2
   21573  1.1     is 
   21574  1.1     is load_fpn2_0:
   21575  1.1     is 	mov.l		0+EXC_FP0(%a6), 0+FP_DST(%a6)
   21576  1.1     is 	mov.l		4+EXC_FP0(%a6), 4+FP_DST(%a6)
   21577  1.1     is 	mov.l		8+EXC_FP0(%a6), 8+FP_DST(%a6)
   21578  1.1     is 	lea		FP_DST(%a6), %a0
   21579  1.1     is 	rts
   21580  1.1     is load_fpn2_1:
   21581  1.1     is 	mov.l		0+EXC_FP1(%a6), 0+FP_DST(%a6)
   21582  1.1     is 	mov.l		4+EXC_FP1(%a6), 4+FP_DST(%a6)
   21583  1.1     is 	mov.l		8+EXC_FP1(%a6), 8+FP_DST(%a6)
   21584  1.1     is 	lea		FP_DST(%a6), %a0
   21585  1.1     is 	rts
   21586  1.1     is load_fpn2_2:
   21587  1.1     is 	fmovm.x		&0x20, FP_DST(%a6)
   21588  1.1     is 	lea		FP_DST(%a6), %a0
   21589  1.1     is 	rts
   21590  1.1     is load_fpn2_3:
   21591  1.1     is 	fmovm.x		&0x10, FP_DST(%a6)
   21592  1.1     is 	lea		FP_DST(%a6), %a0
   21593  1.1     is 	rts
   21594  1.1     is load_fpn2_4:
   21595  1.1     is 	fmovm.x		&0x08, FP_DST(%a6)
   21596  1.1     is 	lea		FP_DST(%a6), %a0
   21597  1.1     is 	rts
   21598  1.1     is load_fpn2_5:
   21599  1.1     is 	fmovm.x		&0x04, FP_DST(%a6)
   21600  1.1     is 	lea		FP_DST(%a6), %a0
   21601  1.1     is 	rts
   21602  1.1     is load_fpn2_6:
   21603  1.1     is 	fmovm.x		&0x02, FP_DST(%a6)
   21604  1.1     is 	lea		FP_DST(%a6), %a0
   21605  1.1     is 	rts
   21606  1.1     is load_fpn2_7:
   21607  1.1     is 	fmovm.x		&0x01, FP_DST(%a6)
   21608  1.1     is 	lea		FP_DST(%a6), %a0
   21609  1.1     is 	rts
   21610  1.1     is 
   21611  1.1     is #############################################################################
   21612  1.1     is 
   21613  1.1     is #########################################################################
   21614  1.1     is # XDEF ****************************************************************	#
   21615  1.1     is # 	store_fpreg(): store an fp value to the fpreg designated d0.	#
   21616  1.1     is #									#
   21617  1.1     is # XREF ****************************************************************	#
   21618  1.1     is #	None								#
   21619  1.1     is #									#
   21620  1.1     is # INPUT ***************************************************************	#
   21621  1.1     is #	fp0 = extended precision value to store				#
   21622  1.1     is #	d0  = index of floating-point register				#
   21623  1.1     is # 									#
   21624  1.1     is # OUTPUT **************************************************************	#
   21625  1.1     is #	None								#
   21626  1.1     is #									#
   21627  1.1     is # ALGORITHM ***********************************************************	#
   21628  1.1     is #	Store the value in fp0 to the FP register designated by the	#
   21629  1.1     is # value in d0. The FP number can be DENORM or SNAN so we have to be	#
   21630  1.1     is # careful that we don't take an exception here.				#
   21631  1.1     is #									#
   21632  1.1     is #########################################################################
   21633  1.1     is 
   21634  1.1     is 	global		store_fpreg
   21635  1.1     is store_fpreg:
   21636  1.1     is 	mov.w		(tbl_store_fpreg.b,%pc,%d0.w*2), %d0
   21637  1.1     is 	jmp		(tbl_store_fpreg.b,%pc,%d0.w*1)
   21638  1.1     is 
   21639  1.1     is tbl_store_fpreg:
   21640  1.1     is 	short		store_fpreg_0 - tbl_store_fpreg
   21641  1.1     is 	short		store_fpreg_1 - tbl_store_fpreg
   21642  1.1     is 	short		store_fpreg_2 - tbl_store_fpreg
   21643  1.1     is 	short		store_fpreg_3 - tbl_store_fpreg
   21644  1.1     is 	short		store_fpreg_4 - tbl_store_fpreg
   21645  1.1     is 	short		store_fpreg_5 - tbl_store_fpreg
   21646  1.1     is 	short		store_fpreg_6 - tbl_store_fpreg
   21647  1.1     is 	short		store_fpreg_7 - tbl_store_fpreg
   21648  1.1     is 
   21649  1.1     is store_fpreg_0:
   21650  1.1     is 	fmovm.x		&0x80, EXC_FP0(%a6)
   21651  1.1     is 	rts
   21652  1.1     is store_fpreg_1:
   21653  1.1     is 	fmovm.x		&0x80, EXC_FP1(%a6)
   21654  1.1     is 	rts
   21655  1.1     is store_fpreg_2:
   21656  1.1     is 	fmovm.x 	&0x01, -(%sp)
   21657  1.1     is 	fmovm.x		(%sp)+, &0x20
   21658  1.1     is 	rts
   21659  1.1     is store_fpreg_3:
   21660  1.1     is 	fmovm.x 	&0x01, -(%sp)
   21661  1.1     is 	fmovm.x		(%sp)+, &0x10
   21662  1.1     is 	rts
   21663  1.1     is store_fpreg_4:
   21664  1.1     is 	fmovm.x 	&0x01, -(%sp)
   21665  1.1     is 	fmovm.x		(%sp)+, &0x08
   21666  1.1     is 	rts
   21667  1.1     is store_fpreg_5:
   21668  1.1     is 	fmovm.x 	&0x01, -(%sp)
   21669  1.1     is 	fmovm.x		(%sp)+, &0x04
   21670  1.1     is 	rts
   21671  1.1     is store_fpreg_6:
   21672  1.1     is 	fmovm.x 	&0x01, -(%sp)
   21673  1.1     is 	fmovm.x		(%sp)+, &0x02
   21674  1.1     is 	rts
   21675  1.1     is store_fpreg_7:
   21676  1.1     is 	fmovm.x 	&0x01, -(%sp)
   21677  1.1     is 	fmovm.x		(%sp)+, &0x01
   21678  1.1     is 	rts
   21679  1.1     is 
   21680  1.1     is #########################################################################
   21681  1.1     is # XDEF ****************************************************************	#
   21682  1.1     is # 	_denorm(): denormalize an intermediate result			#
   21683  1.1     is #									#
   21684  1.1     is # XREF ****************************************************************	#
   21685  1.1     is #	None								#
   21686  1.1     is #									#
   21687  1.1     is # INPUT *************************************************************** #
   21688  1.1     is #	a0 = points to the operand to be denormalized			#
   21689  1.1     is #		(in the internal extended format)			#
   21690  1.1     is #		 							#
   21691  1.1     is #	d0 = rounding precision						#
   21692  1.1     is #									#
   21693  1.1     is # OUTPUT **************************************************************	#
   21694  1.1     is #	a0 = pointer to the denormalized result				#
   21695  1.1     is #		(in the internal extended format)			#
   21696  1.1     is #									#
   21697  1.1     is #	d0 = guard,round,sticky						#
   21698  1.1     is #									#
   21699  1.1     is # ALGORITHM ***********************************************************	#
   21700  1.1     is # 	According to the exponent underflow threshold for the given	#
   21701  1.1     is # precision, shift the mantissa bits to the right in order raise the	#
   21702  1.1     is # exponent of the operand to the threshold value. While shifting the 	#
   21703  1.1     is # mantissa bits right, maintain the value of the guard, round, and 	#
   21704  1.1     is # sticky bits.								#
   21705  1.1     is # other notes:								#
   21706  1.1     is #	(1) _denorm() is called by the underflow routines		#
   21707  1.1     is #	(2) _denorm() does NOT affect the status register		#
   21708  1.1     is #									#
   21709  1.1     is #########################################################################
   21710  1.1     is 
   21711  1.1     is #
   21712  1.1     is # table of exponent threshold values for each precision
   21713  1.1     is #
   21714  1.1     is tbl_thresh:
   21715  1.1     is 	short		0x0
   21716  1.1     is 	short		sgl_thresh
   21717  1.1     is 	short		dbl_thresh
   21718  1.1     is 
   21719  1.1     is 	global		_denorm
   21720  1.1     is _denorm:
   21721  1.1     is #
   21722  1.1     is # Load the exponent threshold for the precision selected and check
   21723  1.1     is # to see if (threshold - exponent) is > 65 in which case we can
   21724  1.1     is # simply calculate the sticky bit and zero the mantissa. otherwise
   21725  1.1     is # we have to call the denormalization routine.
   21726  1.1     is #
   21727  1.1     is 	lsr.b		&0x2, %d0		# shift prec to lo bits
   21728  1.1     is 	mov.w		(tbl_thresh.b,%pc,%d0.w*2), %d1 # load prec threshold
   21729  1.1     is 	mov.w		%d1, %d0		# copy d1 into d0
   21730  1.1     is 	sub.w		FTEMP_EX(%a0), %d0	# diff = threshold - exp
   21731  1.1     is 	cmpi.w		%d0, &66		# is diff > 65? (mant + g,r bits)
   21732  1.1     is 	bpl.b		denorm_set_stky		# yes; just calc sticky
   21733  1.1     is 
   21734  1.1     is 	clr.l		%d0			# clear g,r,s
   21735  1.1     is 	btst		&inex2_bit, FPSR_EXCEPT(%a6) # yes; was INEX2 set?
   21736  1.1     is 	beq.b		denorm_call		# no; don't change anything
   21737  1.1     is 	bset		&29, %d0		# yes; set sticky bit
   21738  1.1     is 
   21739  1.1     is denorm_call:
   21740  1.1     is 	bsr.l		dnrm_lp			# denormalize the number
   21741  1.1     is 	rts
   21742  1.1     is 
   21743  1.1     is #
   21744  1.1     is # all bit would have been shifted off during the denorm so simply
   21745  1.1     is # calculate if the sticky should be set and clear the entire mantissa.
   21746  1.1     is #
   21747  1.1     is denorm_set_stky:
   21748  1.1     is 	mov.l		&0x20000000, %d0	# set sticky bit in return value
   21749  1.1     is 	mov.w		%d1, FTEMP_EX(%a0)	# load exp with threshold
   21750  1.1     is 	clr.l		FTEMP_HI(%a0)		# set d1 = 0 (ms mantissa)
   21751  1.1     is 	clr.l		FTEMP_LO(%a0)		# set d2 = 0 (ms mantissa)
   21752  1.1     is 	rts
   21753  1.1     is 
   21754  1.1     is #									#
   21755  1.1     is # dnrm_lp(): normalize exponent/mantissa to specified threshhold	#
   21756  1.1     is #									#
   21757  1.1     is # INPUT:								#
   21758  1.1     is #	%a0	   : points to the operand to be denormalized		#
   21759  1.1     is #	%d0{31:29} : initial guard,round,sticky				#
   21760  1.1     is #	%d1{15:0}  : denormalization threshold				#
   21761  1.1     is # OUTPUT:								#
   21762  1.1     is #	%a0	   : points to the denormalized operand		 	#
   21763  1.1     is #	%d0{31:29} : final guard,round,sticky				#
   21764  1.1     is #									#
   21765  1.1     is 
   21766  1.1     is # *** Local Equates *** #
   21767  1.1     is set	GRS,		L_SCR2			# g,r,s temp storage
   21768  1.1     is set	FTEMP_LO2,	L_SCR1			# FTEMP_LO copy
   21769  1.1     is 
   21770  1.1     is 	global		dnrm_lp
   21771  1.1     is dnrm_lp:
   21772  1.1     is 
   21773  1.1     is #
   21774  1.1     is # make a copy of FTEMP_LO and place the g,r,s bits directly after it
   21775  1.1     is # in memory so as to make the bitfield extraction for denormalization easier.
   21776  1.1     is #
   21777  1.1     is 	mov.l		FTEMP_LO(%a0), FTEMP_LO2(%a6) # make FTEMP_LO copy
   21778  1.1     is 	mov.l		%d0, GRS(%a6)		# place g,r,s after it
   21779  1.1     is 
   21780  1.1     is #
   21781  1.1     is # check to see how much less than the underflow threshold the operand
   21782  1.1     is # exponent is.
   21783  1.1     is #
   21784  1.1     is 	mov.l		%d1, %d0		# copy the denorm threshold
   21785  1.1     is 	sub.w		FTEMP_EX(%a0), %d1	# d1 = threshold - uns exponent
   21786  1.1     is 	ble.b		dnrm_no_lp		# d1 <= 0
   21787  1.1     is 	cmpi.w		%d1, &0x20		# is ( 0 <= d1 < 32) ?
   21788  1.1     is 	blt.b		case_1			# yes
   21789  1.1     is 	cmpi.w		%d1, &0x40		# is (32 <= d1 < 64) ?
   21790  1.1     is 	blt.b		case_2			# yes
   21791  1.1     is 	bra.w		case_3			# (d1 >= 64)
   21792  1.1     is 
   21793  1.1     is #
   21794  1.1     is # No normalization necessary
   21795  1.1     is #
   21796  1.1     is dnrm_no_lp:
   21797  1.1     is 	mov.l		GRS(%a6), %d0 		# restore original g,r,s
   21798  1.1     is 	rts
   21799  1.1     is 
   21800  1.1     is #
   21801  1.1     is # case (0<d1<32)
   21802  1.1     is #
   21803  1.1     is # %d0 = denorm threshold
   21804  1.1     is # %d1 = "n" = amt to shift
   21805  1.1     is #
   21806  1.1     is #	---------------------------------------------------------
   21807  1.1     is #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21808  1.1     is #	---------------------------------------------------------
   21809  1.1     is #	<-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
   21810  1.1     is #	\	   \		      \			 \
   21811  1.1     is #	 \	    \		       \		  \
   21812  1.1     is #	  \	     \			\		   \
   21813  1.1     is #	   \	      \			 \		    \
   21814  1.1     is #	    \	       \		  \		     \
   21815  1.1     is #	     \		\		   \		      \
   21816  1.1     is #	      \		 \		    \		       \
   21817  1.1     is #	       \	  \		     \			\
   21818  1.1     is #	<-(n)-><-(32 - n)-><------(32)-------><------(32)------->
   21819  1.1     is #	---------------------------------------------------------
   21820  1.1     is #	|0.....0| NEW_HI  |  NEW_FTEMP_LO     |grs		|
   21821  1.1     is #	---------------------------------------------------------
   21822  1.1     is #
   21823  1.1     is case_1:
   21824  1.1     is 	mov.l		%d2, -(%sp)		# create temp storage
   21825  1.1     is 
   21826  1.1     is 	mov.w		%d0, FTEMP_EX(%a0)	# exponent = denorm threshold
   21827  1.1     is 	mov.l		&32, %d0
   21828  1.1     is 	sub.w		%d1, %d0		# %d0 = 32 - %d1
   21829  1.1     is 
   21830  1.1     is 	cmpi.w		%d1, &29		# is shft amt >= 29
   21831  1.1     is 	blt.b		case1_extract		# no; no fix needed
   21832  1.1     is 	mov.b		GRS(%a6), %d2
   21833  1.1     is 	or.b		%d2, 3+FTEMP_LO2(%a6)
   21834  1.1     is 
   21835  1.1     is case1_extract:
   21836  1.1     is 	bfextu		FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_HI
   21837  1.1     is 	bfextu		FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new FTEMP_LO
   21838  1.1     is 	bfextu		FTEMP_LO2(%a6){%d0:&32}, %d0 # %d0 = new G,R,S
   21839  1.1     is 
   21840  1.1     is 	mov.l		%d2, FTEMP_HI(%a0)	# store new FTEMP_HI
   21841  1.1     is 	mov.l		%d1, FTEMP_LO(%a0)	# store new FTEMP_LO
   21842  1.1     is 
   21843  1.1     is 	bftst		%d0{&2:&30}		# were bits shifted off?
   21844  1.1     is 	beq.b		case1_sticky_clear	# no; go finish
   21845  1.1     is 	bset		&rnd_stky_bit, %d0	# yes; set sticky bit
   21846  1.1     is 
   21847  1.1     is case1_sticky_clear:
   21848  1.1     is 	and.l		&0xe0000000, %d0	# clear all but G,R,S
   21849  1.1     is 	mov.l		(%sp)+, %d2		# restore temp register
   21850  1.1     is 	rts
   21851  1.1     is 
   21852  1.1     is #
   21853  1.1     is # case (32<=d1<64)
   21854  1.1     is #
   21855  1.1     is # %d0 = denorm threshold
   21856  1.1     is # %d1 = "n" = amt to shift
   21857  1.1     is #
   21858  1.1     is #	---------------------------------------------------------
   21859  1.1     is #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21860  1.1     is #	---------------------------------------------------------
   21861  1.1     is #	<-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
   21862  1.1     is #	\	   \		      \
   21863  1.1     is #	 \	    \		       \
   21864  1.1     is #	  \	     \			-------------------
   21865  1.1     is #	   \	      --------------------		   \
   21866  1.1     is #	    -------------------	  	  \		    \
   21867  1.1     is #	     		       \	   \		     \
   21868  1.1     is #	      		 	\     	    \		      \
   21869  1.1     is #	       		  	 \	     \		       \
   21870  1.1     is #	<-------(32)------><-(n)-><-(32 - n)-><------(32)------->
   21871  1.1     is #	---------------------------------------------------------
   21872  1.1     is #	|0...............0|0....0| NEW_LO     |grs		|
   21873  1.1     is #	---------------------------------------------------------
   21874  1.1     is #
   21875  1.1     is case_2:
   21876  1.1     is 	mov.l		%d2, -(%sp)		# create temp storage
   21877  1.1     is 
   21878  1.1     is 	mov.w		%d0, FTEMP_EX(%a0)	# exponent = denorm threshold
   21879  1.1     is 	subi.w		&0x20, %d1		# %d1 now between 0 and 32
   21880  1.1     is 	mov.l		&0x20, %d0
   21881  1.1     is 	sub.w		%d1, %d0		# %d0 = 32 - %d1
   21882  1.1     is 
   21883  1.1     is # subtle step here; or in the g,r,s at the bottom of FTEMP_LO to minimize
   21884  1.1     is # the number of bits to check for the sticky detect.
   21885  1.1     is # it only plays a role in shift amounts of 61-63.
   21886  1.1     is 	mov.b		GRS(%a6), %d2
   21887  1.1     is 	or.b		%d2, 3+FTEMP_LO2(%a6)
   21888  1.1     is 
   21889  1.1     is 	bfextu		FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_LO
   21890  1.1     is 	bfextu		FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new G,R,S
   21891  1.1     is 
   21892  1.1     is 	bftst		%d1{&2:&30}		# were any bits shifted off?
   21893  1.1     is 	bne.b		case2_set_sticky	# yes; set sticky bit
   21894  1.1     is 	bftst		FTEMP_LO2(%a6){%d0:&31}	# were any bits shifted off?
   21895  1.1     is 	bne.b		case2_set_sticky	# yes; set sticky bit
   21896  1.1     is 
   21897  1.1     is 	mov.l		%d1, %d0		# move new G,R,S to %d0
   21898  1.1     is 	bra.b		case2_end
   21899  1.1     is 
   21900  1.1     is case2_set_sticky:
   21901  1.1     is 	mov.l		%d1, %d0		# move new G,R,S to %d0
   21902  1.1     is 	bset		&rnd_stky_bit, %d0	# set sticky bit
   21903  1.1     is 
   21904  1.1     is case2_end:
   21905  1.1     is 	clr.l		FTEMP_HI(%a0)		# store FTEMP_HI = 0
   21906  1.1     is 	mov.l		%d2, FTEMP_LO(%a0)	# store FTEMP_LO
   21907  1.1     is 	and.l		&0xe0000000, %d0	# clear all but G,R,S
   21908  1.1     is 
   21909  1.1     is 	mov.l		(%sp)+,%d2		# restore temp register
   21910  1.1     is 	rts
   21911  1.1     is 
   21912  1.1     is #
   21913  1.1     is # case (d1>=64)
   21914  1.1     is #
   21915  1.1     is # %d0 = denorm threshold
   21916  1.1     is # %d1 = amt to shift
   21917  1.1     is #
   21918  1.1     is case_3:
   21919  1.1     is 	mov.w		%d0, FTEMP_EX(%a0)	# insert denorm threshold
   21920  1.1     is 
   21921  1.1     is 	cmpi.w		%d1, &65		# is shift amt > 65?
   21922  1.1     is 	blt.b		case3_64		# no; it's == 64
   21923  1.1     is 	beq.b		case3_65		# no; it's == 65
   21924  1.1     is 
   21925  1.1     is #
   21926  1.1     is # case (d1>65)
   21927  1.1     is #
   21928  1.1     is # Shift value is > 65 and out of range. All bits are shifted off.
   21929  1.1     is # Return a zero mantissa with the sticky bit set
   21930  1.1     is #
   21931  1.1     is 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
   21932  1.1     is 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
   21933  1.1     is 	mov.l		&0x20000000, %d0	# set sticky bit
   21934  1.1     is 	rts
   21935  1.1     is 
   21936  1.1     is #
   21937  1.1     is # case (d1 == 64)
   21938  1.1     is #
   21939  1.1     is #	---------------------------------------------------------
   21940  1.1     is #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21941  1.1     is #	---------------------------------------------------------
   21942  1.1     is #	<-------(32)------>
   21943  1.1     is #	\	   	   \
   21944  1.1     is #	 \	    	    \
   21945  1.1     is #	  \	     	     \
   21946  1.1     is #	   \	      	      ------------------------------
   21947  1.1     is #	    -------------------------------		    \
   21948  1.1     is #	     		       		   \		     \
   21949  1.1     is #	      		 	     	    \		      \
   21950  1.1     is #	       		  	 	     \		       \
   21951  1.1     is #					      <-------(32)------>
   21952  1.1     is #	---------------------------------------------------------
   21953  1.1     is #	|0...............0|0................0|grs		|
   21954  1.1     is #	---------------------------------------------------------
   21955  1.1     is #
   21956  1.1     is case3_64:
   21957  1.1     is 	mov.l		FTEMP_HI(%a0), %d0	# fetch hi(mantissa)
   21958  1.1     is 	mov.l		%d0, %d1		# make a copy
   21959  1.1     is 	and.l		&0xc0000000, %d0	# extract G,R
   21960  1.1     is 	and.l		&0x3fffffff, %d1	# extract other bits
   21961  1.1     is 
   21962  1.1     is 	bra.b		case3_complete
   21963  1.1     is 
   21964  1.1     is #
   21965  1.1     is # case (d1 == 65)
   21966  1.1     is #
   21967  1.1     is #	---------------------------------------------------------
   21968  1.1     is #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21969  1.1     is #	---------------------------------------------------------
   21970  1.1     is #	<-------(32)------>
   21971  1.1     is #	\	   	   \
   21972  1.1     is #	 \	    	    \
   21973  1.1     is #	  \	     	     \
   21974  1.1     is #	   \	      	      ------------------------------
   21975  1.1     is #	    --------------------------------		    \
   21976  1.1     is #	     		       		    \		     \
   21977  1.1     is #	      		 	     	     \		      \
   21978  1.1     is #	       		  	 	      \		       \
   21979  1.1     is #					       <-------(31)----->
   21980  1.1     is #	---------------------------------------------------------
   21981  1.1     is #	|0...............0|0................0|0rs		|
   21982  1.1     is #	---------------------------------------------------------
   21983  1.1     is #
   21984  1.1     is case3_65:
   21985  1.1     is 	mov.l		FTEMP_HI(%a0), %d0	# fetch hi(mantissa)
   21986  1.1     is 	and.l		&0x80000000, %d0	# extract R bit
   21987  1.1     is 	lsr.l		&0x1, %d0		# shift high bit into R bit
   21988  1.1     is 	and.l		&0x7fffffff, %d1	# extract other bits
   21989  1.1     is 
   21990  1.1     is case3_complete:
   21991  1.1     is # last operation done was an "and" of the bits shifted off so the condition
   21992  1.1     is # codes are already set so branch accordingly.
   21993  1.1     is 	bne.b		case3_set_sticky	# yes; go set new sticky
   21994  1.1     is 	tst.l		FTEMP_LO(%a0)		# were any bits shifted off?
   21995  1.1     is 	bne.b		case3_set_sticky	# yes; go set new sticky
   21996  1.1     is 	tst.b		GRS(%a6)		# were any bits shifted off?
   21997  1.1     is 	bne.b		case3_set_sticky	# yes; go set new sticky
   21998  1.1     is 
   21999  1.1     is #
   22000  1.1     is # no bits were shifted off so don't set the sticky bit.
   22001  1.1     is # the guard and
   22002  1.1     is # the entire mantissa is zero.
   22003  1.1     is #
   22004  1.1     is 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
   22005  1.1     is 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
   22006  1.1     is 	rts
   22007  1.1     is 
   22008  1.1     is #
   22009  1.1     is # some bits were shifted off so set the sticky bit.
   22010  1.1     is # the entire mantissa is zero.
   22011  1.1     is #
   22012  1.1     is case3_set_sticky:
   22013  1.1     is 	bset		&rnd_stky_bit,%d0	# set new sticky bit
   22014  1.1     is 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
   22015  1.1     is 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
   22016  1.1     is 	rts
   22017  1.1     is 
   22018  1.1     is #########################################################################
   22019  1.1     is # XDEF ****************************************************************	#
   22020  1.1     is #	_round(): round result according to precision/mode		#
   22021  1.1     is #									#
   22022  1.1     is # XREF ****************************************************************	#
   22023  1.1     is #	None								#
   22024  1.1     is #									#
   22025  1.1     is # INPUT ***************************************************************	#
   22026  1.1     is #	a0	  = ptr to input operand in internal extended format 	#
   22027  1.1     is #	d1(hi)    = contains rounding precision:			#
   22028  1.1     is #			ext = $0000xxxx					#
   22029  1.1     is #			sgl = $0004xxxx					#
   22030  1.1     is #			dbl = $0008xxxx					#
   22031  1.1     is #	d1(lo)	  = contains rounding mode:				#
   22032  1.1     is #			RN  = $xxxx0000					#
   22033  1.1     is #			RZ  = $xxxx0001					#
   22034  1.1     is #			RM  = $xxxx0002					#
   22035  1.1     is #			RP  = $xxxx0003					#
   22036  1.1     is #	d0{31:29} = contains the g,r,s bits (extended)			#
   22037  1.1     is #									#
   22038  1.1     is # OUTPUT **************************************************************	#
   22039  1.1     is #	a0 = pointer to rounded result					#
   22040  1.1     is #									#
   22041  1.1     is # ALGORITHM ***********************************************************	#
   22042  1.1     is #	On return the value pointed to by a0 is correctly rounded,	#
   22043  1.1     is #	a0 is preserved and the g-r-s bits in d0 are cleared.		#
   22044  1.1     is #	The result is not typed - the tag field is invalid.  The	#
   22045  1.1     is #	result is still in the internal extended format.		#
   22046  1.1     is #									#
   22047  1.1     is #	The INEX bit of USER_FPSR will be set if the rounded result was	#
   22048  1.1     is #	inexact (i.e. if any of the g-r-s bits were set).		#
   22049  1.1     is #									#
   22050  1.1     is #########################################################################
   22051  1.1     is 
   22052  1.1     is 	global		_round
   22053  1.1     is _round:
   22054  1.1     is #
   22055  1.1     is # ext_grs() looks at the rounding precision and sets the appropriate
   22056  1.1     is # G,R,S bits.
   22057  1.1     is # If (G,R,S == 0) then result is exact and round is done, else set
   22058  1.1     is # the inex flag in status reg and continue.
   22059  1.1     is #
   22060  1.1     is 	bsr.l		ext_grs			# extract G,R,S
   22061  1.1     is 
   22062  1.1     is 	tst.l		%d0			# are G,R,S zero?
   22063  1.1     is 	beq.w		truncate		# yes; round is complete
   22064  1.1     is 
   22065  1.1     is 	or.w		&inx2a_mask, 2+USER_FPSR(%a6) # set inex2/ainex
   22066  1.1     is 
   22067  1.1     is #
   22068  1.1     is # Use rounding mode as an index into a jump table for these modes.
   22069  1.1     is # All of the following assumes grs != 0.
   22070  1.1     is #
   22071  1.1     is 	mov.w		(tbl_mode.b,%pc,%d1.w*2), %a1 # load jump offset
   22072  1.1     is 	jmp		(tbl_mode.b,%pc,%a1)	# jmp to rnd mode handler
   22073  1.1     is 
   22074  1.1     is tbl_mode:
   22075  1.1     is 	short		rnd_near - tbl_mode
   22076  1.1     is 	short		truncate - tbl_mode	# RZ always truncates
   22077  1.1     is 	short		rnd_mnus - tbl_mode
   22078  1.1     is 	short		rnd_plus - tbl_mode
   22079  1.1     is 
   22080  1.1     is #################################################################
   22081  1.1     is #	ROUND PLUS INFINITY					#
   22082  1.1     is #								#
   22083  1.1     is #	If sign of fp number = 0 (positive), then add 1 to l.	#
   22084  1.1     is #################################################################
   22085  1.1     is rnd_plus:
   22086  1.1     is 	tst.b		FTEMP_SGN(%a0)		# check for sign
   22087  1.1     is 	bmi.w		truncate		# if positive then truncate
   22088  1.1     is 
   22089  1.1     is 	mov.l		&0xffffffff, %d0	# force g,r,s to be all f's
   22090  1.1     is 	swap		%d1			# set up d1 for round prec.
   22091  1.1     is 
   22092  1.1     is 	cmpi.b		%d1, &s_mode		# is prec = sgl?
   22093  1.1     is 	beq.w		add_sgl			# yes
   22094  1.1     is 	bgt.w		add_dbl			# no; it's dbl
   22095  1.1     is 	bra.w		add_ext			# no; it's ext
   22096  1.1     is 
   22097  1.1     is #################################################################
   22098  1.1     is #	ROUND MINUS INFINITY					#
   22099  1.1     is #								#
   22100  1.1     is #	If sign of fp number = 1 (negative), then add 1 to l.	#
   22101  1.1     is #################################################################
   22102  1.1     is rnd_mnus:
   22103  1.1     is 	tst.b		FTEMP_SGN(%a0)		# check for sign
   22104  1.1     is 	bpl.w		truncate		# if negative then truncate
   22105  1.1     is 
   22106  1.1     is 	mov.l		&0xffffffff, %d0	# force g,r,s to be all f's
   22107  1.1     is 	swap		%d1			# set up d1 for round prec.
   22108  1.1     is 
   22109  1.1     is 	cmpi.b		%d1, &s_mode		# is prec = sgl?
   22110  1.1     is 	beq.w		add_sgl			# yes
   22111  1.1     is 	bgt.w		add_dbl			# no; it's dbl
   22112  1.1     is 	bra.w		add_ext			# no; it's ext
   22113  1.1     is 
   22114  1.1     is #################################################################
   22115  1.1     is #	ROUND NEAREST						#
   22116  1.1     is #								#
   22117  1.1     is #	If (g=1), then add 1 to l and if (r=s=0), then clear l	#
   22118  1.1     is #	Note that this will round to even in case of a tie.	#
   22119  1.1     is #################################################################
   22120  1.1     is rnd_near:
   22121  1.1     is 	asl.l		&0x1, %d0		# shift g-bit to c-bit
   22122  1.1     is 	bcc.w		truncate		# if (g=1) then
   22123  1.1     is 
   22124  1.1     is 	swap		%d1			# set up d1 for round prec.
   22125  1.1     is 
   22126  1.1     is 	cmpi.b		%d1, &s_mode		# is prec = sgl?
   22127  1.1     is 	beq.w		add_sgl			# yes
   22128  1.1     is 	bgt.w		add_dbl			# no; it's dbl
   22129  1.1     is 	bra.w		add_ext			# no; it's ext
   22130  1.1     is 
   22131  1.1     is # *** LOCAL EQUATES ***
   22132  1.1     is set	ad_1_sgl,	0x00000100	# constant to add 1 to l-bit in sgl prec
   22133  1.1     is set	ad_1_dbl,	0x00000800	# constant to add 1 to l-bit in dbl prec
   22134  1.1     is 
   22135  1.1     is #########################
   22136  1.1     is #	ADD SINGLE	#
   22137  1.1     is #########################
   22138  1.1     is add_sgl:
   22139  1.1     is 	add.l		&ad_1_sgl, FTEMP_HI(%a0)
   22140  1.1     is 	bcc.b		scc_clr			# no mantissa overflow
   22141  1.1     is 	roxr.w		FTEMP_HI(%a0)		# shift v-bit back in
   22142  1.1     is 	roxr.w		FTEMP_HI+2(%a0)		# shift v-bit back in
   22143  1.1     is 	add.w		&0x1, FTEMP_EX(%a0)	# and incr exponent
   22144  1.1     is scc_clr:
   22145  1.1     is 	tst.l		%d0			# test for rs = 0
   22146  1.1     is 	bne.b		sgl_done
   22147  1.1     is 	and.w		&0xfe00, FTEMP_HI+2(%a0) # clear the l-bit
   22148  1.1     is sgl_done:
   22149  1.1     is 	and.l		&0xffffff00, FTEMP_HI(%a0) # truncate bits beyond sgl limit
   22150  1.1     is 	clr.l		FTEMP_LO(%a0)		# clear d2
   22151  1.1     is 	rts
   22152  1.1     is 
   22153  1.1     is #########################
   22154  1.1     is #	ADD EXTENDED	#
   22155  1.1     is #########################
   22156  1.1     is add_ext:
   22157  1.1     is 	addq.l		&1,FTEMP_LO(%a0)	# add 1 to l-bit
   22158  1.1     is 	bcc.b		xcc_clr			# test for carry out
   22159  1.1     is 	addq.l		&1,FTEMP_HI(%a0)	# propogate carry
   22160  1.1     is 	bcc.b		xcc_clr
   22161  1.1     is 	roxr.w		FTEMP_HI(%a0)		# mant is 0 so restore v-bit
   22162  1.1     is 	roxr.w		FTEMP_HI+2(%a0)		# mant is 0 so restore v-bit
   22163  1.1     is 	roxr.w		FTEMP_LO(%a0)
   22164  1.1     is 	roxr.w		FTEMP_LO+2(%a0)
   22165  1.1     is 	add.w		&0x1,FTEMP_EX(%a0)	# and inc exp
   22166  1.1     is xcc_clr:
   22167  1.1     is 	tst.l		%d0			# test rs = 0
   22168  1.1     is 	bne.b		add_ext_done
   22169  1.1     is 	and.b		&0xfe,FTEMP_LO+3(%a0)	# clear the l bit
   22170  1.1     is add_ext_done:
   22171  1.1     is 	rts
   22172  1.1     is 
   22173  1.1     is #########################
   22174  1.1     is #	ADD DOUBLE	#
   22175  1.1     is #########################
   22176  1.1     is add_dbl:
   22177  1.1     is 	add.l		&ad_1_dbl, FTEMP_LO(%a0) # add 1 to lsb
   22178  1.1     is 	bcc.b		dcc_clr			# no carry
   22179  1.1     is 	addq.l		&0x1, FTEMP_HI(%a0)	# propogate carry
   22180  1.1     is 	bcc.b		dcc_clr			# no carry
   22181  1.1     is 
   22182  1.1     is 	roxr.w		FTEMP_HI(%a0)		# mant is 0 so restore v-bit
   22183  1.1     is 	roxr.w		FTEMP_HI+2(%a0)		# mant is 0 so restore v-bit
   22184  1.1     is 	roxr.w		FTEMP_LO(%a0)
   22185  1.1     is 	roxr.w		FTEMP_LO+2(%a0)
   22186  1.1     is 	addq.w		&0x1, FTEMP_EX(%a0)	# incr exponent
   22187  1.1     is dcc_clr:
   22188  1.1     is 	tst.l		%d0			# test for rs = 0
   22189  1.1     is 	bne.b		dbl_done
   22190  1.1     is 	and.w		&0xf000, FTEMP_LO+2(%a0) # clear the l-bit
   22191  1.1     is 
   22192  1.1     is dbl_done:
   22193  1.1     is 	and.l		&0xfffff800,FTEMP_LO(%a0) # truncate bits beyond dbl limit
   22194  1.1     is 	rts
   22195  1.1     is 
   22196  1.1     is ###########################
   22197  1.1     is # Truncate all other bits #
   22198  1.1     is ###########################
   22199  1.1     is truncate:
   22200  1.1     is 	swap		%d1			# select rnd prec
   22201  1.1     is 
   22202  1.1     is 	cmpi.b		%d1, &s_mode		# is prec sgl?
   22203  1.1     is 	beq.w		sgl_done		# yes
   22204  1.1     is 	bgt.b		dbl_done		# no; it's dbl
   22205  1.1     is 	rts					# no; it's ext
   22206  1.1     is 
   22207  1.1     is 
   22208  1.1     is #
   22209  1.1     is # ext_grs(): extract guard, round and sticky bits according to
   22210  1.1     is #	     rounding precision.
   22211  1.1     is #
   22212  1.1     is # INPUT
   22213  1.1     is #	d0	   = extended precision g,r,s (in d0{31:29})
   22214  1.1     is #	d1 	   = {PREC,ROUND}
   22215  1.1     is # OUTPUT
   22216  1.1     is #	d0{31:29}  = guard, round, sticky
   22217  1.1     is #
   22218  1.1     is # The ext_grs extract the guard/round/sticky bits according to the
   22219  1.1     is # selected rounding precision. It is called by the round subroutine
   22220  1.1     is # only.  All registers except d0 are kept intact. d0 becomes an
   22221  1.1     is # updated guard,round,sticky in d0{31:29}
   22222  1.1     is #
   22223  1.1     is # Notes: the ext_grs uses the round PREC, and therefore has to swap d1
   22224  1.1     is #	 prior to usage, and needs to restore d1 to original. this
   22225  1.1     is #	 routine is tightly tied to the round routine and not meant to
   22226  1.1     is #	 uphold standard subroutine calling practices.
   22227  1.1     is #
   22228  1.1     is 
   22229  1.1     is ext_grs:
   22230  1.1     is 	swap		%d1			# have d1.w point to round precision
   22231  1.1     is 	tst.b		%d1			# is rnd prec = extended?
   22232  1.1     is 	bne.b		ext_grs_not_ext		# no; go handle sgl or dbl
   22233  1.1     is 
   22234  1.1     is #
   22235  1.1     is # %d0 actually already hold g,r,s since _round() had it before calling
   22236  1.1     is # this function. so, as long as we don't disturb it, we are "returning" it.
   22237  1.1     is #
   22238  1.1     is ext_grs_ext:
   22239  1.1     is 	swap		%d1			# yes; return to correct positions
   22240  1.1     is 	rts
   22241  1.1     is 
   22242  1.1     is ext_grs_not_ext:
   22243  1.1     is 	movm.l		&0x3000, -(%sp)		# make some temp registers {d2/d3}
   22244  1.1     is 
   22245  1.1     is 	cmpi.b		%d1, &s_mode		# is rnd prec = sgl?
   22246  1.1     is 	bne.b		ext_grs_dbl		# no; go handle dbl
   22247  1.1     is 
   22248  1.1     is #
   22249  1.1     is # sgl:
   22250  1.1     is #	96		64	  40	32		0
   22251  1.1     is #	-----------------------------------------------------
   22252  1.1     is #	| EXP	|XXXXXXX|	  |xx	|		|grs|
   22253  1.1     is #	-----------------------------------------------------
   22254  1.1     is #			<--(24)--->nn\			   /
   22255  1.1     is #				   ee ---------------------
   22256  1.1     is #				   ww		|
   22257  1.1     is #						v
   22258  1.1     is #				   gr	   new sticky
   22259  1.1     is #
   22260  1.1     is ext_grs_sgl:
   22261  1.1     is 	bfextu		FTEMP_HI(%a0){&24:&2}, %d3 # sgl prec. g-r are 2 bits right
   22262  1.1     is 	mov.l		&30, %d2		# of the sgl prec. limits
   22263  1.1     is 	lsl.l		%d2, %d3		# shift g-r bits to MSB of d3
   22264  1.1     is 	mov.l		FTEMP_HI(%a0), %d2	# get word 2 for s-bit test
   22265  1.1     is 	and.l		&0x0000003f, %d2	# s bit is the or of all other
   22266  1.1     is 	bne.b		ext_grs_st_stky		# bits to the right of g-r
   22267  1.1     is 	tst.l		FTEMP_LO(%a0)		# test lower mantissa
   22268  1.1     is 	bne.b		ext_grs_st_stky		# if any are set, set sticky
   22269  1.1     is 	tst.l		%d0			# test original g,r,s
   22270  1.1     is 	bne.b		ext_grs_st_stky		# if any are set, set sticky
   22271  1.1     is 	bra.b		ext_grs_end_sd		# if words 3 and 4 are clr, exit
   22272  1.1     is 
   22273  1.1     is #
   22274  1.1     is # dbl:
   22275  1.1     is #	96		64	  	32	 11	0
   22276  1.1     is #	-----------------------------------------------------
   22277  1.1     is #	| EXP	|XXXXXXX|	  	|	 |xx	|grs|
   22278  1.1     is #	-----------------------------------------------------
   22279  1.1     is #						  nn\	    /
   22280  1.1     is #						  ee -------
   22281  1.1     is #						  ww	|
   22282  1.1     is #							v
   22283  1.1     is #						  gr	new sticky
   22284  1.1     is #
   22285  1.1     is ext_grs_dbl:
   22286  1.1     is 	bfextu		FTEMP_LO(%a0){&21:&2}, %d3 # dbl-prec. g-r are 2 bits right
   22287  1.1     is 	mov.l		&30, %d2		# of the dbl prec. limits
   22288  1.1     is 	lsl.l		%d2, %d3		# shift g-r bits to the MSB of d3
   22289  1.1     is 	mov.l		FTEMP_LO(%a0), %d2	# get lower mantissa  for s-bit test
   22290  1.1     is 	and.l		&0x000001ff, %d2	# s bit is the or-ing of all
   22291  1.1     is 	bne.b		ext_grs_st_stky		# other bits to the right of g-r
   22292  1.1     is 	tst.l		%d0			# test word original g,r,s
   22293  1.1     is 	bne.b		ext_grs_st_stky		# if any are set, set sticky
   22294  1.1     is 	bra.b		ext_grs_end_sd		# if clear, exit
   22295  1.1     is 
   22296  1.1     is ext_grs_st_stky:
   22297  1.1     is 	bset		&rnd_stky_bit, %d3	# set sticky bit
   22298  1.1     is ext_grs_end_sd:
   22299  1.1     is 	mov.l		%d3, %d0		# return grs to d0
   22300  1.1     is 
   22301  1.1     is 	movm.l		(%sp)+, &0xc		# restore scratch registers {d2/d3}
   22302  1.1     is 
   22303  1.1     is 	swap		%d1			# restore d1 to original
   22304  1.1     is 	rts
   22305  1.1     is 
   22306  1.1     is #########################################################################
   22307  1.1     is # norm(): normalize the mantissa of an extended precision input. the	#
   22308  1.1     is #	  input operand should not be normalized already.		#
   22309  1.1     is #									#
   22310  1.1     is # XDEF ****************************************************************	#
   22311  1.1     is #	norm()								#
   22312  1.1     is #									#
   22313  1.1     is # XREF **************************************************************** #
   22314  1.1     is #	none								#
   22315  1.1     is #									#
   22316  1.1     is # INPUT *************************************************************** #
   22317  1.1     is #	a0 = pointer fp extended precision operand to normalize		#
   22318  1.1     is #									#
   22319  1.1     is # OUTPUT ************************************************************** #
   22320  1.1     is # 	d0 = number of bit positions the mantissa was shifted		#
   22321  1.1     is #	a0 = the input operand's mantissa is normalized; the exponent	#
   22322  1.1     is #	     is unchanged.						#
   22323  1.1     is #									#
   22324  1.1     is #########################################################################
   22325  1.1     is 	global		norm
   22326  1.1     is norm:
   22327  1.1     is 	mov.l		%d2, -(%sp)		# create some temp regs
   22328  1.1     is 	mov.l		%d3, -(%sp)
   22329  1.1     is 
   22330  1.1     is 	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
   22331  1.1     is 	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
   22332  1.1     is 
   22333  1.1     is 	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
   22334  1.1     is 	beq.b		norm_lo			# hi(man) is all zeroes!
   22335  1.1     is 
   22336  1.1     is norm_hi:
   22337  1.1     is 	lsl.l		%d2, %d0		# left shift hi(man)
   22338  1.1     is 	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
   22339  1.1     is 
   22340  1.1     is 	or.l		%d3, %d0		# create hi(man)
   22341  1.1     is 	lsl.l		%d2, %d1		# create lo(man)
   22342  1.1     is 
   22343  1.1     is 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
   22344  1.1     is 	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
   22345  1.1     is 
   22346  1.1     is 	mov.l		%d2, %d0		# return shift amount
   22347  1.1     is 
   22348  1.1     is 	mov.l		(%sp)+, %d3		# restore temp regs
   22349  1.1     is 	mov.l		(%sp)+, %d2
   22350  1.1     is 
   22351  1.1     is 	rts
   22352  1.1     is 
   22353  1.1     is norm_lo:
   22354  1.1     is 	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
   22355  1.1     is 	lsl.l		%d2, %d1		# shift lo(man)
   22356  1.1     is 	add.l		&32, %d2		# add 32 to shft amount
   22357  1.1     is 
   22358  1.1     is 	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
   22359  1.1     is 	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
   22360  1.1     is 
   22361  1.1     is 	mov.l		%d2, %d0		# return shift amount
   22362  1.1     is 
   22363  1.1     is 	mov.l		(%sp)+, %d3		# restore temp regs
   22364  1.1     is 	mov.l		(%sp)+, %d2
   22365  1.1     is 
   22366  1.1     is 	rts
   22367  1.1     is 
   22368  1.1     is #########################################################################
   22369  1.1     is # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
   22370  1.1     is #		- returns corresponding optype tag			#
   22371  1.1     is #									#
   22372  1.1     is # XDEF ****************************************************************	#
   22373  1.1     is #	unnorm_fix()							#
   22374  1.1     is #									#
   22375  1.1     is # XREF **************************************************************** #
   22376  1.1     is #	norm() - normalize the mantissa					#
   22377  1.1     is #									#
   22378  1.1     is # INPUT *************************************************************** #
   22379  1.1     is #	a0 = pointer to unnormalized extended precision number		#
   22380  1.1     is #									#
   22381  1.1     is # OUTPUT ************************************************************** #
   22382  1.1     is #	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
   22383  1.1     is #	a0 = input operand has been converted to a norm, denorm, or	#
   22384  1.1     is #	     zero; both the exponent and mantissa are changed.		#
   22385  1.1     is #									#
   22386  1.1     is #########################################################################
   22387  1.1     is 
   22388  1.1     is 	global		unnorm_fix
   22389  1.1     is unnorm_fix:
   22390  1.1     is 	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
   22391  1.1     is 	bne.b		unnorm_shift		# hi(man) is not all zeroes
   22392  1.1     is 
   22393  1.1     is #
   22394  1.1     is # hi(man) is all zeroes so see if any bits in lo(man) are set
   22395  1.1     is #
   22396  1.1     is unnorm_chk_lo:
   22397  1.1     is 	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
   22398  1.1     is 	beq.w		unnorm_zero		# yes
   22399  1.1     is 
   22400  1.1     is 	add.w		&32, %d0		# no; fix shift distance
   22401  1.1     is 
   22402  1.1     is #
   22403  1.1     is # d0 = # shifts needed for complete normalization
   22404  1.1     is #
   22405  1.1     is unnorm_shift:
   22406  1.1     is 	clr.l		%d1			# clear top word
   22407  1.1     is 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
   22408  1.1     is 	and.w		&0x7fff, %d1		# strip off sgn
   22409  1.1     is 
   22410  1.1     is 	cmp.w		%d0, %d1		# will denorm push exp < 0?
   22411  1.1     is 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
   22412  1.1     is 
   22413  1.1     is #
   22414  1.1     is # exponent would not go < 0. therefore, number stays normalized
   22415  1.1     is #
   22416  1.1     is 	sub.w		%d0, %d1		# shift exponent value
   22417  1.1     is 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
   22418  1.1     is 	and.w		&0x8000, %d0		# save old sign
   22419  1.1     is 	or.w		%d0, %d1		# {sgn,new exp}
   22420  1.1     is 	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
   22421  1.1     is 
   22422  1.1     is 	bsr.l		norm			# normalize UNNORM
   22423  1.1     is 
   22424  1.1     is 	mov.b		&NORM, %d0		# return new optype tag
   22425  1.1     is 	rts
   22426  1.1     is 
   22427  1.1     is #
   22428  1.1     is # exponent would go < 0, so only denormalize until exp = 0
   22429  1.1     is #
   22430  1.1     is unnorm_nrm_zero:
   22431  1.1     is 	cmp.b		%d1, &32		# is exp <= 32?
   22432  1.1     is 	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
   22433  1.1     is 
   22434  1.1     is 	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
   22435  1.1     is 	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
   22436  1.1     is 
   22437  1.1     is 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
   22438  1.1     is 	lsl.l		%d1, %d0		# extract new lo(man)
   22439  1.1     is 	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
   22440  1.1     is 
   22441  1.1     is 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
   22442  1.1     is 
   22443  1.1     is 	mov.b		&DENORM, %d0		# return new optype tag
   22444  1.1     is 	rts
   22445  1.1     is 
   22446  1.1     is #
   22447  1.1     is # only mantissa bits set are in lo(man)
   22448  1.1     is #
   22449  1.1     is unnorm_nrm_zero_lrg:
   22450  1.1     is 	sub.w		&32, %d1		# adjust shft amt by 32
   22451  1.1     is 
   22452  1.1     is 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
   22453  1.1     is 	lsl.l		%d1, %d0		# left shift lo(man)
   22454  1.1     is 
   22455  1.1     is 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
   22456  1.1     is 	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
   22457  1.1     is 
   22458  1.1     is 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
   22459  1.1     is 
   22460  1.1     is 	mov.b		&DENORM, %d0		# return new optype tag
   22461  1.1     is 	rts
   22462  1.1     is 
   22463  1.1     is #
   22464  1.1     is # whole mantissa is zero so this UNNORM is actually a zero
   22465  1.1     is #
   22466  1.1     is unnorm_zero:
   22467  1.1     is 	and.w		&0x8000, FTEMP_EX(%a0) 	# force exponent to zero
   22468  1.1     is 
   22469  1.1     is 	mov.b		&ZERO, %d0		# fix optype tag
   22470  1.1     is 	rts
   22471  1.1     is 
   22472  1.1     is #########################################################################
   22473  1.1     is # XDEF ****************************************************************	#
   22474  1.1     is # 	set_tag_x(): return the optype of the input ext fp number	#
   22475  1.1     is #									#
   22476  1.1     is # XREF ****************************************************************	#
   22477  1.1     is #	None								#
   22478  1.1     is #									#
   22479  1.1     is # INPUT ***************************************************************	#
   22480  1.1     is #	a0 = pointer to extended precision operand			#
   22481  1.1     is # 									#
   22482  1.1     is # OUTPUT **************************************************************	#
   22483  1.1     is #	d0 = value of type tag						#
   22484  1.1     is # 		one of: NORM, INF, QNAN, SNAN, DENORM, UNNORM, ZERO	#
   22485  1.1     is #									#
   22486  1.1     is # ALGORITHM ***********************************************************	#
   22487  1.1     is #	Simply test the exponent, j-bit, and mantissa values to 	#
   22488  1.1     is # determine the type of operand.					#
   22489  1.1     is #	If it's an unnormalized zero, alter the operand and force it	#
   22490  1.1     is # to be a normal zero.							#
   22491  1.1     is #									#
   22492  1.1     is #########################################################################
   22493  1.1     is 
   22494  1.1     is 	global		set_tag_x
   22495  1.1     is set_tag_x:
   22496  1.1     is 	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
   22497  1.1     is 	andi.w		&0x7fff, %d0		# strip off sign
   22498  1.1     is 	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
   22499  1.1     is 	beq.b		inf_or_nan_x
   22500  1.1     is not_inf_or_nan_x:
   22501  1.1     is 	btst		&0x7,FTEMP_HI(%a0)
   22502  1.1     is 	beq.b		not_norm_x
   22503  1.1     is is_norm_x:
   22504  1.1     is 	mov.b		&NORM, %d0
   22505  1.1     is 	rts
   22506  1.1     is not_norm_x:
   22507  1.1     is 	tst.w		%d0			# is exponent = 0?
   22508  1.1     is 	bne.b		is_unnorm_x
   22509  1.1     is not_unnorm_x:
   22510  1.1     is 	tst.l		FTEMP_HI(%a0)
   22511  1.1     is 	bne.b		is_denorm_x
   22512  1.1     is 	tst.l		FTEMP_LO(%a0)
   22513  1.1     is 	bne.b		is_denorm_x
   22514  1.1     is is_zero_x:
   22515  1.1     is 	mov.b		&ZERO, %d0
   22516  1.1     is 	rts
   22517  1.1     is is_denorm_x:
   22518  1.1     is 	mov.b		&DENORM, %d0
   22519  1.1     is 	rts
   22520  1.1     is # must distinguish now "Unnormalized zeroes" which we
   22521  1.1     is # must convert to zero.
   22522  1.1     is is_unnorm_x:
   22523  1.1     is 	tst.l		FTEMP_HI(%a0)
   22524  1.1     is 	bne.b		is_unnorm_reg_x
   22525  1.1     is 	tst.l		FTEMP_LO(%a0)
   22526  1.1     is 	bne.b		is_unnorm_reg_x
   22527  1.1     is # it's an "unnormalized zero". let's convert it to an actual zero...
   22528  1.1     is 	andi.w		&0x8000,FTEMP_EX(%a0)	# clear exponent
   22529  1.1     is 	mov.b		&ZERO, %d0
   22530  1.1     is 	rts
   22531  1.1     is is_unnorm_reg_x:
   22532  1.1     is 	mov.b		&UNNORM, %d0
   22533  1.1     is 	rts
   22534  1.1     is inf_or_nan_x:
   22535  1.1     is 	tst.l		FTEMP_LO(%a0)
   22536  1.1     is 	bne.b		is_nan_x
   22537  1.1     is 	mov.l		FTEMP_HI(%a0), %d0
   22538  1.1     is 	and.l		&0x7fffffff, %d0	# msb is a don't care!
   22539  1.1     is 	bne.b		is_nan_x
   22540  1.1     is is_inf_x:
   22541  1.1     is 	mov.b		&INF, %d0
   22542  1.1     is 	rts
   22543  1.1     is is_nan_x:
   22544  1.1     is 	btst		&0x6, FTEMP_HI(%a0)
   22545  1.1     is 	beq.b		is_snan_x
   22546  1.1     is 	mov.b		&QNAN, %d0
   22547  1.1     is 	rts
   22548  1.1     is is_snan_x:
   22549  1.1     is 	mov.b		&SNAN, %d0
   22550  1.1     is 	rts
   22551  1.1     is 
   22552  1.1     is #########################################################################
   22553  1.1     is # XDEF ****************************************************************	#
   22554  1.1     is # 	set_tag_d(): return the optype of the input dbl fp number	#
   22555  1.1     is #									#
   22556  1.1     is # XREF ****************************************************************	#
   22557  1.1     is #	None								#
   22558  1.1     is #									#
   22559  1.1     is # INPUT ***************************************************************	#
   22560  1.1     is #	a0 = points to double precision operand				#
   22561  1.1     is # 									#
   22562  1.1     is # OUTPUT **************************************************************	#
   22563  1.1     is #	d0 = value of type tag						#
   22564  1.1     is # 		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
   22565  1.1     is #									#
   22566  1.1     is # ALGORITHM ***********************************************************	#
   22567  1.1     is #	Simply test the exponent, j-bit, and mantissa values to 	#
   22568  1.1     is # determine the type of operand.					#
   22569  1.1     is #									#
   22570  1.1     is #########################################################################
   22571  1.1     is 
   22572  1.1     is 	global		set_tag_d
   22573  1.1     is set_tag_d:
   22574  1.1     is 	mov.l		FTEMP(%a0), %d0
   22575  1.1     is 	mov.l		%d0, %d1
   22576  1.1     is 
   22577  1.1     is 	andi.l		&0x7ff00000, %d0
   22578  1.1     is 	beq.b		zero_or_denorm_d
   22579  1.1     is 
   22580  1.1     is 	cmpi.l		%d0, &0x7ff00000
   22581  1.1     is 	beq.b		inf_or_nan_d
   22582  1.1     is 
   22583  1.1     is is_norm_d:
   22584  1.1     is 	mov.b		&NORM, %d0
   22585  1.1     is 	rts
   22586  1.1     is zero_or_denorm_d:
   22587  1.1     is 	and.l		&0x000fffff, %d1
   22588  1.1     is 	bne		is_denorm_d
   22589  1.1     is 	tst.l		4+FTEMP(%a0)
   22590  1.1     is 	bne		is_denorm_d
   22591  1.1     is is_zero_d:
   22592  1.1     is 	mov.b		&ZERO, %d0
   22593  1.1     is 	rts
   22594  1.1     is is_denorm_d:
   22595  1.1     is 	mov.b		&DENORM, %d0
   22596  1.1     is 	rts
   22597  1.1     is inf_or_nan_d:
   22598  1.1     is 	and.l		&0x000fffff, %d1
   22599  1.1     is 	bne		is_nan_d
   22600  1.1     is 	tst.l		4+FTEMP(%a0)
   22601  1.1     is 	bne		is_nan_d
   22602  1.1     is is_inf_d:
   22603  1.1     is 	mov.b		&INF, %d0
   22604  1.1     is 	rts
   22605  1.1     is is_nan_d:
   22606  1.1     is 	btst		&19, %d1
   22607  1.1     is 	bne		is_qnan_d
   22608  1.1     is is_snan_d:
   22609  1.1     is 	mov.b		&SNAN, %d0
   22610  1.1     is 	rts
   22611  1.1     is is_qnan_d:
   22612  1.1     is 	mov.b		&QNAN, %d0
   22613  1.1     is 	rts
   22614  1.1     is 
   22615  1.1     is #########################################################################
   22616  1.1     is # XDEF ****************************************************************	#
   22617  1.1     is # 	set_tag_s(): return the optype of the input sgl fp number	#
   22618  1.1     is #									#
   22619  1.1     is # XREF ****************************************************************	#
   22620  1.1     is #	None								#
   22621  1.1     is #									#
   22622  1.1     is # INPUT ***************************************************************	#
   22623  1.1     is #	a0 = pointer to single precision operand			#
   22624  1.1     is # 									#
   22625  1.1     is # OUTPUT **************************************************************	#
   22626  1.1     is #	d0 = value of type tag						#
   22627  1.1     is # 		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
   22628  1.1     is #									#
   22629  1.1     is # ALGORITHM ***********************************************************	#
   22630  1.1     is #	Simply test the exponent, j-bit, and mantissa values to 	#
   22631  1.1     is # determine the type of operand.					#
   22632  1.1     is #									#
   22633  1.1     is #########################################################################
   22634  1.1     is 
   22635  1.1     is 	global		set_tag_s
   22636  1.1     is set_tag_s:
   22637  1.1     is 	mov.l		FTEMP(%a0), %d0
   22638  1.1     is 	mov.l		%d0, %d1
   22639  1.1     is 
   22640  1.1     is 	andi.l		&0x7f800000, %d0
   22641  1.1     is 	beq.b		zero_or_denorm_s
   22642  1.1     is 
   22643  1.1     is 	cmpi.l		%d0, &0x7f800000
   22644  1.1     is 	beq.b		inf_or_nan_s
   22645  1.1     is 
   22646  1.1     is is_norm_s:
   22647  1.1     is 	mov.b		&NORM, %d0
   22648  1.1     is 	rts
   22649  1.1     is zero_or_denorm_s:
   22650  1.1     is 	and.l		&0x007fffff, %d1
   22651  1.1     is 	bne		is_denorm_s
   22652  1.1     is is_zero_s:
   22653  1.1     is 	mov.b		&ZERO, %d0
   22654  1.1     is 	rts
   22655  1.1     is is_denorm_s:
   22656  1.1     is 	mov.b		&DENORM, %d0
   22657  1.1     is 	rts
   22658  1.1     is inf_or_nan_s:
   22659  1.1     is 	and.l		&0x007fffff, %d1
   22660  1.1     is 	bne		is_nan_s
   22661  1.1     is is_inf_s:
   22662  1.1     is 	mov.b		&INF, %d0
   22663  1.1     is 	rts
   22664  1.1     is is_nan_s:
   22665  1.1     is 	btst		&22, %d1
   22666  1.1     is 	bne		is_qnan_s
   22667  1.1     is is_snan_s:
   22668  1.1     is 	mov.b		&SNAN, %d0
   22669  1.1     is 	rts
   22670  1.1     is is_qnan_s:
   22671  1.1     is 	mov.b		&QNAN, %d0
   22672  1.1     is 	rts
   22673  1.1     is 
   22674  1.1     is #########################################################################
   22675  1.1     is # XDEF ****************************************************************	#
   22676  1.1     is # 	unf_res(): routine to produce default underflow result of a 	#
   22677  1.1     is #	 	   scaled extended precision number; this is used by 	#
   22678  1.1     is #		   fadd/fdiv/fmul/etc. emulation routines.		#
   22679  1.1     is # 	unf_res4(): same as above but for fsglmul/fsgldiv which use	#
   22680  1.1     is #		    single round prec and extended prec mode.		#
   22681  1.1     is #									#
   22682  1.1     is # XREF ****************************************************************	#
   22683  1.1     is #	_denorm() - denormalize according to scale factor		#
   22684  1.1     is # 	_round() - round denormalized number according to rnd prec	#
   22685  1.1     is #									#
   22686  1.1     is # INPUT ***************************************************************	#
   22687  1.1     is #	a0 = pointer to extended precison operand			#
   22688  1.1     is #	d0 = scale factor						#
   22689  1.1     is #	d1 = rounding precision/mode					#
   22690  1.1     is #									#
   22691  1.1     is # OUTPUT **************************************************************	#
   22692  1.1     is #	a0 = pointer to default underflow result in extended precision	#
   22693  1.1     is #	d0.b = result FPSR_cc which caller may or may not want to save	#
   22694  1.1     is #									#
   22695  1.1     is # ALGORITHM ***********************************************************	#
   22696  1.1     is # 	Convert the input operand to "internal format" which means the	#
   22697  1.1     is # exponent is extended to 16 bits and the sign is stored in the unused	#
   22698  1.1     is # portion of the extended precison operand. Denormalize the number	#
   22699  1.1     is # according to the scale factor passed in d0. Then, round the 		#
   22700  1.1     is # denormalized result.							#
   22701  1.1     is # 	Set the FPSR_exc bits as appropriate but return the cc bits in	#
   22702  1.1     is # d0 in case the caller doesn't want to save them (as is the case for	#
   22703  1.1     is # fmove out).								#
   22704  1.1     is # 	unf_res4() for fsglmul/fsgldiv forces the denorm to extended	#
   22705  1.1     is # precision and the rounding mode to single.				#
   22706  1.1     is #									#
   22707  1.1     is #########################################################################
   22708  1.1     is 	global		unf_res
   22709  1.1     is unf_res:
   22710  1.1     is 	mov.l		%d1, -(%sp)		# save rnd prec,mode on stack
   22711  1.1     is 
   22712  1.1     is 	btst		&0x7, FTEMP_EX(%a0)	# make "internal" format
   22713  1.1     is 	sne		FTEMP_SGN(%a0)
   22714  1.1     is 
   22715  1.1     is 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
   22716  1.1     is 	and.w		&0x7fff, %d1
   22717  1.1     is 	sub.w		%d0, %d1
   22718  1.1     is 	mov.w		%d1, FTEMP_EX(%a0)	# insert 16 bit exponent
   22719  1.1     is 
   22720  1.1     is 	mov.l		%a0, -(%sp)		# save operand ptr during calls
   22721  1.1     is 
   22722  1.1     is 	mov.l		0x4(%sp),%d0		# pass rnd prec.
   22723  1.1     is 	andi.w		&0x00c0,%d0
   22724  1.1     is 	lsr.w		&0x4,%d0
   22725  1.1     is 	bsr.l		_denorm			# denorm result
   22726  1.1     is 
   22727  1.1     is 	mov.l		(%sp),%a0
   22728  1.1     is 	mov.w		0x6(%sp),%d1		# load prec:mode into %d1
   22729  1.1     is 	andi.w		&0xc0,%d1		# extract rnd prec
   22730  1.1     is 	lsr.w		&0x4,%d1
   22731  1.1     is 	swap		%d1
   22732  1.1     is 	mov.w		0x6(%sp),%d1
   22733  1.1     is 	andi.w		&0x30,%d1
   22734  1.1     is 	lsr.w		&0x4,%d1
   22735  1.1     is 	bsr.l		_round			# round the denorm
   22736  1.1     is 
   22737  1.1     is 	mov.l		(%sp)+, %a0
   22738  1.1     is 
   22739  1.1     is # result is now rounded properly. convert back to normal format
   22740  1.1     is 	bclr		&0x7, FTEMP_EX(%a0)	# clear sgn first; may have residue
   22741  1.1     is 	tst.b		FTEMP_SGN(%a0)		# is "internal result" sign set?
   22742  1.1     is 	beq.b		unf_res_chkifzero	# no; result is positive
   22743  1.1     is 	bset		&0x7, FTEMP_EX(%a0)	# set result sgn
   22744  1.1     is 	clr.b		FTEMP_SGN(%a0)		# clear temp sign
   22745  1.1     is 
   22746  1.1     is # the number may have become zero after rounding. set ccodes accordingly.
   22747  1.1     is unf_res_chkifzero:
   22748  1.1     is 	clr.l		%d0
   22749  1.1     is 	tst.l		FTEMP_HI(%a0)		# is value now a zero?
   22750  1.1     is 	bne.b		unf_res_cont		# no
   22751  1.1     is 	tst.l		FTEMP_LO(%a0)
   22752  1.1     is 	bne.b		unf_res_cont		# no
   22753  1.1     is #	bset		&z_bit, FPSR_CC(%a6)	# yes; set zero ccode bit
   22754  1.1     is 	bset		&z_bit, %d0		# yes; set zero ccode bit
   22755  1.1     is 
   22756  1.1     is unf_res_cont:
   22757  1.1     is 
   22758  1.1     is #
   22759  1.1     is # can inex1 also be set along with unfl and inex2???
   22760  1.1     is #
   22761  1.1     is # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
   22762  1.1     is #
   22763  1.1     is 	btst		&inex2_bit, FPSR_EXCEPT(%a6) # is INEX2 set?
   22764  1.1     is 	beq.b		unf_res_end		# no
   22765  1.1     is 	bset		&aunfl_bit, FPSR_AEXCEPT(%a6) # yes; set aunfl
   22766  1.1     is 
   22767  1.1     is unf_res_end:
   22768  1.1     is 	add.l		&0x4, %sp		# clear stack
   22769  1.1     is 	rts
   22770  1.1     is 
   22771  1.1     is # unf_res() for fsglmul() and fsgldiv().
   22772  1.1     is 	global		unf_res4
   22773  1.1     is unf_res4:
   22774  1.1     is 	mov.l		%d1,-(%sp)		# save rnd prec,mode on stack
   22775  1.1     is 
   22776  1.1     is 	btst		&0x7,FTEMP_EX(%a0)	# make "internal" format
   22777  1.1     is 	sne		FTEMP_SGN(%a0)
   22778  1.1     is 
   22779  1.1     is 	mov.w		FTEMP_EX(%a0),%d1	# extract exponent
   22780  1.1     is 	and.w		&0x7fff,%d1
   22781  1.1     is 	sub.w		%d0,%d1
   22782  1.1     is 	mov.w		%d1,FTEMP_EX(%a0)	# insert 16 bit exponent
   22783  1.1     is 
   22784  1.1     is 	mov.l		%a0,-(%sp)		# save operand ptr during calls
   22785  1.1     is 
   22786  1.1     is 	clr.l		%d0			# force rnd prec = ext
   22787  1.1     is 	bsr.l		_denorm			# denorm result
   22788  1.1     is 
   22789  1.1     is 	mov.l		(%sp),%a0
   22790  1.1     is 	mov.w		&s_mode,%d1		# force rnd prec = sgl
   22791  1.1     is 	swap		%d1
   22792  1.1     is 	mov.w		0x6(%sp),%d1		# load rnd mode
   22793  1.1     is 	andi.w		&0x30,%d1		# extract rnd prec
   22794  1.1     is 	lsr.w		&0x4,%d1
   22795  1.1     is 	bsr.l		_round			# round the denorm
   22796  1.1     is 
   22797  1.1     is 	mov.l		(%sp)+,%a0
   22798  1.1     is 
   22799  1.1     is # result is now rounded properly. convert back to normal format
   22800  1.1     is 	bclr		&0x7,FTEMP_EX(%a0)	# clear sgn first; may have residue
   22801  1.1     is 	tst.b		FTEMP_SGN(%a0)		# is "internal result" sign set?
   22802  1.1     is 	beq.b		unf_res4_chkifzero	# no; result is positive
   22803  1.1     is 	bset		&0x7,FTEMP_EX(%a0)	# set result sgn
   22804  1.1     is 	clr.b		FTEMP_SGN(%a0)		# clear temp sign
   22805  1.1     is 
   22806  1.1     is # the number may have become zero after rounding. set ccodes accordingly.
   22807  1.1     is unf_res4_chkifzero:
   22808  1.1     is 	clr.l		%d0
   22809  1.1     is 	tst.l		FTEMP_HI(%a0)		# is value now a zero?
   22810  1.1     is 	bne.b		unf_res4_cont		# no
   22811  1.1     is 	tst.l		FTEMP_LO(%a0)
   22812  1.1     is 	bne.b		unf_res4_cont		# no
   22813  1.1     is #	bset		&z_bit,FPSR_CC(%a6)	# yes; set zero ccode bit
   22814  1.1     is 	bset		&z_bit,%d0		# yes; set zero ccode bit
   22815  1.1     is 
   22816  1.1     is unf_res4_cont:
   22817  1.1     is 
   22818  1.1     is #
   22819  1.1     is # can inex1 also be set along with unfl and inex2???
   22820  1.1     is #
   22821  1.1     is # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
   22822  1.1     is #
   22823  1.1     is 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
   22824  1.1     is 	beq.b		unf_res4_end		# no
   22825  1.1     is 	bset		&aunfl_bit,FPSR_AEXCEPT(%a6) # yes; set aunfl
   22826  1.1     is 
   22827  1.1     is unf_res4_end:
   22828  1.1     is 	add.l		&0x4,%sp		# clear stack
   22829  1.1     is 	rts
   22830  1.1     is 
   22831  1.1     is #########################################################################
   22832  1.1     is # XDEF ****************************************************************	#
   22833  1.1     is #	ovf_res(): routine to produce the default overflow result of	#
   22834  1.1     is #		   an overflowing number.				#
   22835  1.1     is #	ovf_res2(): same as above but the rnd mode/prec are passed	#
   22836  1.1     is #		    differently.					#
   22837  1.1     is #									#
   22838  1.1     is # XREF ****************************************************************	#
   22839  1.1     is #	none								#
   22840  1.1     is #									#
   22841  1.1     is # INPUT ***************************************************************	#
   22842  1.1     is #	d1.b 	= '-1' => (-); '0' => (+)				#
   22843  1.1     is #   ovf_res():								#
   22844  1.1     is #	d0 	= rnd mode/prec						#
   22845  1.1     is #   ovf_res2():								#
   22846  1.1     is #	hi(d0) 	= rnd prec						#
   22847  1.1     is #	lo(d0)	= rnd mode						#
   22848  1.1     is #									#
   22849  1.1     is # OUTPUT **************************************************************	#
   22850  1.1     is #	a0   	= points to extended precision result			#
   22851  1.1     is #	d0.b 	= condition code bits					#
   22852  1.1     is #									#
   22853  1.1     is # ALGORITHM ***********************************************************	#
   22854  1.1     is #	The default overflow result can be determined by the sign of	#
   22855  1.1     is # the result and the rounding mode/prec in effect. These bits are	#
   22856  1.1     is # concatenated together to create an index into the default result 	#
   22857  1.1     is # table. A pointer to the correct result is returned in a0. The		#
   22858  1.1     is # resulting condition codes are returned in d0 in case the caller 	#
   22859  1.1     is # doesn't want FPSR_cc altered (as is the case for fmove out).		#
   22860  1.1     is #									#
   22861  1.1     is #########################################################################
   22862  1.1     is 
   22863  1.1     is 	global		ovf_res
   22864  1.1     is ovf_res:
   22865  1.1     is 	andi.w		&0x10,%d1		# keep result sign
   22866  1.1     is 	lsr.b		&0x4,%d0		# shift prec/mode
   22867  1.1     is 	or.b		%d0,%d1			# concat the two
   22868  1.1     is 	mov.w		%d1,%d0			# make a copy
   22869  1.1     is 	lsl.b		&0x1,%d1		# multiply d1 by 2
   22870  1.1     is 	bra.b		ovf_res_load
   22871  1.1     is 
   22872  1.1     is 	global		ovf_res2
   22873  1.1     is ovf_res2:
   22874  1.1     is 	and.w		&0x10, %d1		# keep result sign
   22875  1.1     is 	or.b		%d0, %d1		# insert rnd mode
   22876  1.1     is 	swap		%d0
   22877  1.1     is 	or.b		%d0, %d1		# insert rnd prec
   22878  1.1     is 	mov.w		%d1, %d0		# make a copy
   22879  1.1     is 	lsl.b		&0x1, %d1		# shift left by 1
   22880  1.1     is 
   22881  1.1     is #
   22882  1.1     is # use the rounding mode, precision, and result sign as in index into the
   22883  1.1     is # two tables below to fetch the default result and the result ccodes.
   22884  1.1     is #
   22885  1.1     is ovf_res_load:
   22886  1.1     is 	mov.b		(tbl_ovfl_cc.b,%pc,%d0.w*1), %d0 # fetch result ccodes
   22887  1.1     is 	lea		(tbl_ovfl_result.b,%pc,%d1.w*8), %a0 # return result ptr
   22888  1.1     is 
   22889  1.1     is 	rts
   22890  1.1     is 
   22891  1.1     is tbl_ovfl_cc:
   22892  1.1     is 	byte		0x2, 0x0, 0x0, 0x2
   22893  1.1     is 	byte		0x2, 0x0, 0x0, 0x2
   22894  1.1     is 	byte		0x2, 0x0, 0x0, 0x2
   22895  1.1     is 	byte		0x0, 0x0, 0x0, 0x0
   22896  1.1     is 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
   22897  1.1     is 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
   22898  1.1     is 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
   22899  1.1     is 
   22900  1.1     is tbl_ovfl_result:
   22901  1.1     is 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
   22902  1.1     is 	long		0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RZ
   22903  1.1     is 	long		0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RM
   22904  1.1     is 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
   22905  1.1     is 
   22906  1.1     is 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
   22907  1.1     is 	long		0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RZ
   22908  1.1     is 	long		0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RM
   22909  1.1     is 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
   22910  1.1     is 
   22911  1.1     is 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
   22912  1.1     is 	long		0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RZ
   22913  1.1     is 	long		0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RM
   22914  1.1     is 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
   22915  1.1     is 
   22916  1.1     is 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22917  1.1     is 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22918  1.1     is 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22919  1.1     is 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22920  1.1     is 
   22921  1.1     is 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
   22922  1.1     is 	long		0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RZ
   22923  1.1     is 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
   22924  1.1     is 	long		0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RP
   22925  1.1     is 
   22926  1.1     is 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
   22927  1.1     is 	long		0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RZ
   22928  1.1     is 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
   22929  1.1     is 	long		0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RP
   22930  1.1     is 
   22931  1.1     is 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
   22932  1.1     is 	long		0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RZ
   22933  1.1     is 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
   22934  1.1     is 	long		0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RP
   22935  1.1     is 
   22936  1.1     is #########################################################################
   22937  1.1     is # XDEF ****************************************************************	#
   22938  1.1     is #	get_packed(): fetch a packed operand from memory and then	#
   22939  1.1     is #		      convert it to a floating-point binary number.	#
   22940  1.1     is #									#
   22941  1.1     is # XREF ****************************************************************	#
   22942  1.1     is #	_dcalc_ea() - calculate the correct <ea>			#
   22943  1.1     is #	_mem_read() - fetch the packed operand from memory		#
   22944  1.1     is #	facc_in_x() - the fetch failed so jump to special exit code	#
   22945  1.1     is #	decbin()    - convert packed to binary extended precision	#
   22946  1.1     is #									#
   22947  1.1     is # INPUT ***************************************************************	#
   22948  1.1     is #	None								#
   22949  1.1     is # 									#
   22950  1.1     is # OUTPUT **************************************************************	#
   22951  1.1     is #	If no failure on _mem_read():					#
   22952  1.1     is # 	FP_SRC(a6) = packed operand now as a binary FP number		#
   22953  1.1     is #									#
   22954  1.1     is # ALGORITHM ***********************************************************	#
   22955  1.1     is #	Get the correct <ea> whihc is the value on the exception stack 	#
   22956  1.1     is # frame w/ maybe a correction factor if the <ea> is -(an) or (an)+.	#
   22957  1.1     is # Then, fetch the operand from memory. If the fetch fails, exit		#
   22958  1.1     is # through facc_in_x().							#
   22959  1.1     is #	If the packed operand is a ZERO,NAN, or INF, convert it to	#
   22960  1.1     is # its binary representation here. Else, call decbin() which will 	#
   22961  1.1     is # convert the packed value to an extended precision binary value.	#
   22962  1.1     is #									#
   22963  1.1     is #########################################################################
   22964  1.1     is 
   22965  1.1     is # the stacked <ea> for packed is correct except for -(An).
   22966  1.1     is # the base reg must be updated for both -(An) and (An)+.
   22967  1.1     is 	global		get_packed
   22968  1.1     is get_packed:
   22969  1.1     is 	mov.l		&0xc,%d0		# packed is 12 bytes
   22970  1.1     is 	bsr.l		_dcalc_ea		# fetch <ea>; correct An
   22971  1.1     is 
   22972  1.1     is 	lea		FP_SRC(%a6),%a1		# pass: ptr to super dst
   22973  1.1     is 	mov.l		&0xc,%d0		# pass: 12 bytes
   22974  1.1     is 	bsr.l		_dmem_read		# read packed operand
   22975  1.1     is 
   22976  1.1     is 	tst.l		%d1			# did dfetch fail?
   22977  1.1     is 	bne.l		facc_in_x		# yes
   22978  1.1     is 
   22979  1.1     is # The packed operand is an INF or a NAN if the exponent field is all ones.
   22980  1.1     is 	bfextu		FP_SRC(%a6){&1:&15},%d0	# get exp
   22981  1.1     is 	cmpi.w		%d0,&0x7fff		# INF or NAN?
   22982  1.1     is 	bne.b		gp_try_zero		# no
   22983  1.1     is 	rts					# operand is an INF or NAN
   22984  1.1     is 
   22985  1.1     is # The packed operand is a zero if the mantissa is all zero, else it's
   22986  1.1     is # a normal packed op.
   22987  1.1     is gp_try_zero:
   22988  1.1     is 	mov.b		3+FP_SRC(%a6),%d0	# get byte 4
   22989  1.1     is 	andi.b		&0x0f,%d0		# clear all but last nybble
   22990  1.1     is 	bne.b		gp_not_spec		# not a zero
   22991  1.1     is 	tst.l		FP_SRC_HI(%a6)		# is lw 2 zero?
   22992  1.1     is 	bne.b		gp_not_spec		# not a zero
   22993  1.1     is 	tst.l		FP_SRC_LO(%a6)		# is lw 3 zero?
   22994  1.1     is 	bne.b		gp_not_spec		# not a zero
   22995  1.1     is 	rts					# operand is a ZERO
   22996  1.1     is gp_not_spec:
   22997  1.1     is 	lea		FP_SRC(%a6),%a0		# pass: ptr to packed op
   22998  1.1     is 	bsr.l		decbin			# convert to extended
   22999  1.1     is 	fmovm.x		&0x80,FP_SRC(%a6)	# make this the srcop
   23000  1.1     is 	rts
   23001  1.1     is 
   23002  1.1     is #########################################################################
   23003  1.1     is # decbin(): Converts normalized packed bcd value pointed to by register	#
   23004  1.1     is #	    a0 to extended-precision value in fp0.			#
   23005  1.1     is #									#
   23006  1.1     is # INPUT ***************************************************************	#
   23007  1.1     is #	a0 = pointer to normalized packed bcd value			#
   23008  1.1     is #									#
   23009  1.1     is # OUTPUT **************************************************************	#
   23010  1.1     is #	fp0 = exact fp representation of the packed bcd value.		#
   23011  1.1     is #									#
   23012  1.1     is # ALGORITHM ***********************************************************	#
   23013  1.1     is #	Expected is a normal bcd (i.e. non-exceptional; all inf, zero,	#
   23014  1.1     is #	and NaN operands are dispatched without entering this routine)	#
   23015  1.1     is #	value in 68881/882 format at location (a0).			#
   23016  1.1     is #									#
   23017  1.1     is #	A1. Convert the bcd exponent to binary by successive adds and 	#
   23018  1.1     is #	muls. Set the sign according to SE. Subtract 16 to compensate	#
   23019  1.1     is #	for the mantissa which is to be interpreted as 17 integer	#
   23020  1.1     is #	digits, rather than 1 integer and 16 fraction digits.		#
   23021  1.1     is #	Note: this operation can never overflow.			#
   23022  1.1     is #									#
   23023  1.1     is #	A2. Convert the bcd mantissa to binary by successive		#
   23024  1.1     is #	adds and muls in FP0. Set the sign according to SM.		#
   23025  1.1     is #	The mantissa digits will be converted with the decimal point	#
   23026  1.1     is #	assumed following the least-significant digit.			#
   23027  1.1     is #	Note: this operation can never overflow.			#
   23028  1.1     is #									#
   23029  1.1     is #	A3. Count the number of leading/trailing zeros in the		#
   23030  1.1     is #	bcd string.  If SE is positive, count the leading zeros;	#
   23031  1.1     is #	if negative, count the trailing zeros.  Set the adjusted	#
   23032  1.1     is #	exponent equal to the exponent from A1 and the zero count	#
   23033  1.1     is #	added if SM = 1 and subtracted if SM = 0.  Scale the		#
   23034  1.1     is #	mantissa the equivalent of forcing in the bcd value:		#
   23035  1.1     is #									#
   23036  1.1     is #	SM = 0	a non-zero digit in the integer position		#
   23037  1.1     is #	SM = 1	a non-zero digit in Mant0, lsd of the fraction		#
   23038  1.1     is #									#
   23039  1.1     is #	this will insure that any value, regardless of its		#
   23040  1.1     is #	representation (ex. 0.1E2, 1E1, 10E0, 100E-1), is converted	#
   23041  1.1     is #	consistently.							#
   23042  1.1     is #									#
   23043  1.1     is #	A4. Calculate the factor 10^exp in FP1 using a table of		#
   23044  1.1     is #	10^(2^n) values.  To reduce the error in forming factors	#
   23045  1.1     is #	greater than 10^27, a directed rounding scheme is used with	#
   23046  1.1     is #	tables rounded to RN, RM, and RP, according to the table	#
   23047  1.1     is #	in the comments of the pwrten section.				#
   23048  1.1     is #									#
   23049  1.1     is #	A5. Form the final binary number by scaling the mantissa by	#
   23050  1.1     is #	the exponent factor.  This is done by multiplying the		#
   23051  1.1     is #	mantissa in FP0 by the factor in FP1 if the adjusted		#
   23052  1.1     is #	exponent sign is positive, and dividing FP0 by FP1 if		#
   23053  1.1     is #	it is negative.							#
   23054  1.1     is #									#
   23055  1.1     is #	Clean up and return. Check if the final mul or div was inexact.	#
   23056  1.1     is #	If so, set INEX1 in USER_FPSR.					#
   23057  1.1     is #									#
   23058  1.1     is #########################################################################
   23059  1.1     is 
   23060  1.1     is #
   23061  1.1     is #	PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded
   23062  1.1     is #	to nearest, minus, and plus, respectively.  The tables include
   23063  1.1     is #	10**{1,2,4,8,16,32,64,128,256,512,1024,2048,4096}.  No rounding
   23064  1.1     is #	is required until the power is greater than 27, however, all
   23065  1.1     is #	tables include the first 5 for ease of indexing.
   23066  1.1     is #
   23067  1.1     is RTABLE:
   23068  1.1     is 	byte		0,0,0,0
   23069  1.1     is 	byte		2,3,2,3
   23070  1.1     is 	byte		2,3,3,2
   23071  1.1     is 	byte		3,2,2,3
   23072  1.1     is 
   23073  1.1     is 	set		FNIBS,7
   23074  1.1     is 	set		FSTRT,0
   23075  1.1     is 
   23076  1.1     is 	set		ESTRT,4
   23077  1.1     is 	set		EDIGITS,2
   23078  1.1     is 
   23079  1.1     is 	global		decbin
   23080  1.1     is decbin:
   23081  1.1     is 	mov.l		0x0(%a0),FP_SCR0_EX(%a6) # make a copy of input
   23082  1.1     is 	mov.l		0x4(%a0),FP_SCR0_HI(%a6) # so we don't alter it
   23083  1.1     is 	mov.l		0x8(%a0),FP_SCR0_LO(%a6)
   23084  1.1     is 
   23085  1.1     is 	lea		FP_SCR0(%a6),%a0
   23086  1.1     is 
   23087  1.1     is 	movm.l		&0x3c00,-(%sp)		# save d2-d5
   23088  1.1     is 	fmovm.x		&0x1,-(%sp)		# save fp1
   23089  1.1     is #
   23090  1.1     is # Calculate exponent:
   23091  1.1     is #  1. Copy bcd value in memory for use as a working copy.
   23092  1.1     is #  2. Calculate absolute value of exponent in d1 by mul and add.
   23093  1.1     is #  3. Correct for exponent sign.
   23094  1.1     is #  4. Subtract 16 to compensate for interpreting the mant as all integer digits.
   23095  1.1     is #     (i.e., all digits assumed left of the decimal point.)
   23096  1.1     is #
   23097  1.1     is # Register usage:
   23098  1.1     is #
   23099  1.1     is #  calc_e:
   23100  1.1     is #	(*)  d0: temp digit storage
   23101  1.1     is #	(*)  d1: accumulator for binary exponent
   23102  1.1     is #	(*)  d2: digit count
   23103  1.1     is #	(*)  d3: offset pointer
   23104  1.1     is #	( )  d4: first word of bcd
   23105  1.1     is #	( )  a0: pointer to working bcd value
   23106  1.1     is #	( )  a6: pointer to original bcd value
   23107  1.1     is #	(*)  FP_SCR1: working copy of original bcd value
   23108  1.1     is #	(*)  L_SCR1: copy of original exponent word
   23109  1.1     is #
   23110  1.1     is calc_e:
   23111  1.1     is 	mov.l		&EDIGITS,%d2		# # of nibbles (digits) in fraction part
   23112  1.1     is 	mov.l		&ESTRT,%d3		# counter to pick up digits
   23113  1.1     is 	mov.l		(%a0),%d4		# get first word of bcd
   23114  1.1     is 	clr.l		%d1			# zero d1 for accumulator
   23115  1.1     is e_gd:
   23116  1.1     is 	mulu.l		&0xa,%d1		# mul partial product by one digit place
   23117  1.1     is 	bfextu		%d4{%d3:&4},%d0		# get the digit and zero extend into d0
   23118  1.1     is 	add.l		%d0,%d1			# d1 = d1 + d0
   23119  1.1     is 	addq.b		&4,%d3			# advance d3 to the next digit
   23120  1.1     is 	dbf.w		%d2,e_gd		# if we have used all 3 digits, exit loop
   23121  1.1     is 	btst		&30,%d4			# get SE
   23122  1.1     is 	beq.b		e_pos			# don't negate if pos
   23123  1.1     is 	neg.l		%d1			# negate before subtracting
   23124  1.1     is e_pos:
   23125  1.1     is 	sub.l		&16,%d1			# sub to compensate for shift of mant
   23126  1.1     is 	bge.b		e_save			# if still pos, do not neg
   23127  1.1     is 	neg.l		%d1			# now negative, make pos and set SE
   23128  1.1     is 	or.l		&0x40000000,%d4		# set SE in d4,
   23129  1.1     is 	or.l		&0x40000000,(%a0)	# and in working bcd
   23130  1.1     is e_save:
   23131  1.1     is 	mov.l		%d1,-(%sp)		# save exp on stack
   23132  1.1     is #
   23133  1.1     is #
   23134  1.1     is # Calculate mantissa:
   23135  1.1     is #  1. Calculate absolute value of mantissa in fp0 by mul and add.
   23136  1.1     is #  2. Correct for mantissa sign.
   23137  1.1     is #     (i.e., all digits assumed left of the decimal point.)
   23138  1.1     is #
   23139  1.1     is # Register usage:
   23140  1.1     is #
   23141  1.1     is #  calc_m:
   23142  1.1     is #	(*)  d0: temp digit storage
   23143  1.1     is #	(*)  d1: lword counter
   23144  1.1     is #	(*)  d2: digit count
   23145  1.1     is #	(*)  d3: offset pointer
   23146  1.1     is #	( )  d4: words 2 and 3 of bcd
   23147  1.1     is #	( )  a0: pointer to working bcd value
   23148  1.1     is #	( )  a6: pointer to original bcd value
   23149  1.1     is #	(*) fp0: mantissa accumulator
   23150  1.1     is #	( )  FP_SCR1: working copy of original bcd value
   23151  1.1     is #	( )  L_SCR1: copy of original exponent word
   23152  1.1     is #
   23153  1.1     is calc_m:
   23154  1.1     is 	mov.l		&1,%d1			# word counter, init to 1
   23155  1.1     is 	fmov.s		&0x00000000,%fp0	# accumulator
   23156  1.1     is #
   23157  1.1     is #
   23158  1.1     is #  Since the packed number has a long word between the first & second parts,
   23159  1.1     is #  get the integer digit then skip down & get the rest of the
   23160  1.1     is #  mantissa.  We will unroll the loop once.
   23161  1.1     is #
   23162  1.1     is 	bfextu		(%a0){&28:&4},%d0	# integer part is ls digit in long word
   23163  1.1     is 	fadd.b		%d0,%fp0		# add digit to sum in fp0
   23164  1.1     is #
   23165  1.1     is #
   23166  1.1     is #  Get the rest of the mantissa.
   23167  1.1     is #
   23168  1.1     is loadlw:
   23169  1.1     is 	mov.l		(%a0,%d1.L*4),%d4	# load mantissa lonqword into d4
   23170  1.1     is 	mov.l		&FSTRT,%d3		# counter to pick up digits
   23171  1.1     is 	mov.l		&FNIBS,%d2		# reset number of digits per a0 ptr
   23172  1.1     is md2b:
   23173  1.1     is 	fmul.s		&0x41200000,%fp0	# fp0 = fp0 * 10
   23174  1.1     is 	bfextu		%d4{%d3:&4},%d0		# get the digit and zero extend
   23175  1.1     is 	fadd.b		%d0,%fp0		# fp0 = fp0 + digit
   23176  1.1     is #
   23177  1.1     is #
   23178  1.1     is #  If all the digits (8) in that long word have been converted (d2=0),
   23179  1.1     is #  then inc d1 (=2) to point to the next long word and reset d3 to 0
   23180  1.1     is #  to initialize the digit offset, and set d2 to 7 for the digit count;
   23181  1.1     is #  else continue with this long word.
   23182  1.1     is #
   23183  1.1     is 	addq.b		&4,%d3			# advance d3 to the next digit
   23184  1.1     is 	dbf.w		%d2,md2b		# check for last digit in this lw
   23185  1.1     is nextlw:
   23186  1.1     is 	addq.l		&1,%d1			# inc lw pointer in mantissa
   23187  1.1     is 	cmp.l		%d1,&2			# test for last lw
   23188  1.1     is 	ble.b		loadlw			# if not, get last one
   23189  1.1     is #
   23190  1.1     is #  Check the sign of the mant and make the value in fp0 the same sign.
   23191  1.1     is #
   23192  1.1     is m_sign:
   23193  1.1     is 	btst		&31,(%a0)		# test sign of the mantissa
   23194  1.1     is 	beq.b		ap_st_z			# if clear, go to append/strip zeros
   23195  1.1     is 	fneg.x		%fp0			# if set, negate fp0
   23196  1.1     is #
   23197  1.1     is # Append/strip zeros:
   23198  1.1     is #
   23199  1.1     is #  For adjusted exponents which have an absolute value greater than 27*,
   23200  1.1     is #  this routine calculates the amount needed to normalize the mantissa
   23201  1.1     is #  for the adjusted exponent.  That number is subtracted from the exp
   23202  1.1     is #  if the exp was positive, and added if it was negative.  The purpose
   23203  1.1     is #  of this is to reduce the value of the exponent and the possibility
   23204  1.1     is #  of error in calculation of pwrten.
   23205  1.1     is #
   23206  1.1     is #  1. Branch on the sign of the adjusted exponent.
   23207  1.1     is #  2p.(positive exp)
   23208  1.1     is #   2. Check M16 and the digits in lwords 2 and 3 in decending order.
   23209  1.1     is #   3. Add one for each zero encountered until a non-zero digit.
   23210  1.1     is #   4. Subtract the count from the exp.
   23211  1.1     is #   5. Check if the exp has crossed zero in #3 above; make the exp abs
   23212  1.1     is #	   and set SE.
   23213  1.1     is #	6. Multiply the mantissa by 10**count.
   23214  1.1     is #  2n.(negative exp)
   23215  1.1     is #   2. Check the digits in lwords 3 and 2 in decending order.
   23216  1.1     is #   3. Add one for each zero encountered until a non-zero digit.
   23217  1.1     is #   4. Add the count to the exp.
   23218  1.1     is #   5. Check if the exp has crossed zero in #3 above; clear SE.
   23219  1.1     is #   6. Divide the mantissa by 10**count.
   23220  1.1     is #
   23221  1.1     is #  *Why 27?  If the adjusted exponent is within -28 < expA < 28, than
   23222  1.1     is #   any adjustment due to append/strip zeros will drive the resultane
   23223  1.1     is #   exponent towards zero.  Since all pwrten constants with a power
   23224  1.1     is #   of 27 or less are exact, there is no need to use this routine to
   23225  1.1     is #   attempt to lessen the resultant exponent.
   23226  1.1     is #
   23227  1.1     is # Register usage:
   23228  1.1     is #
   23229  1.1     is #  ap_st_z:
   23230  1.1     is #	(*)  d0: temp digit storage
   23231  1.1     is #	(*)  d1: zero count
   23232  1.1     is #	(*)  d2: digit count
   23233  1.1     is #	(*)  d3: offset pointer
   23234  1.1     is #	( )  d4: first word of bcd
   23235  1.1     is #	(*)  d5: lword counter
   23236  1.1     is #	( )  a0: pointer to working bcd value
   23237  1.1     is #	( )  FP_SCR1: working copy of original bcd value
   23238  1.1     is #	( )  L_SCR1: copy of original exponent word
   23239  1.1     is #
   23240  1.1     is #
   23241  1.1     is # First check the absolute value of the exponent to see if this
   23242  1.1     is # routine is necessary.  If so, then check the sign of the exponent
   23243  1.1     is # and do append (+) or strip (-) zeros accordingly.
   23244  1.1     is # This section handles a positive adjusted exponent.
   23245  1.1     is #
   23246  1.1     is ap_st_z:
   23247  1.1     is 	mov.l		(%sp),%d1		# load expA for range test
   23248  1.1     is 	cmp.l		%d1,&27			# test is with 27
   23249  1.1     is 	ble.w		pwrten			# if abs(expA) <28, skip ap/st zeros
   23250  1.1     is 	btst		&30,(%a0)		# check sign of exp
   23251  1.1     is 	bne.b		ap_st_n			# if neg, go to neg side
   23252  1.1     is 	clr.l		%d1			# zero count reg
   23253  1.1     is 	mov.l		(%a0),%d4		# load lword 1 to d4
   23254  1.1     is 	bfextu		%d4{&28:&4},%d0		# get M16 in d0
   23255  1.1     is 	bne.b		ap_p_fx			# if M16 is non-zero, go fix exp
   23256  1.1     is 	addq.l		&1,%d1			# inc zero count
   23257  1.1     is 	mov.l		&1,%d5			# init lword counter
   23258  1.1     is 	mov.l		(%a0,%d5.L*4),%d4	# get lword 2 to d4
   23259  1.1     is 	bne.b		ap_p_cl			# if lw 2 is zero, skip it
   23260  1.1     is 	addq.l		&8,%d1			# and inc count by 8
   23261  1.1     is 	addq.l		&1,%d5			# inc lword counter
   23262  1.1     is 	mov.l		(%a0,%d5.L*4),%d4	# get lword 3 to d4
   23263  1.1     is ap_p_cl:
   23264  1.1     is 	clr.l		%d3			# init offset reg
   23265  1.1     is 	mov.l		&7,%d2			# init digit counter
   23266  1.1     is ap_p_gd:
   23267  1.1     is 	bfextu		%d4{%d3:&4},%d0		# get digit
   23268  1.1     is 	bne.b		ap_p_fx			# if non-zero, go to fix exp
   23269  1.1     is 	addq.l		&4,%d3			# point to next digit
   23270  1.1     is 	addq.l		&1,%d1			# inc digit counter
   23271  1.1     is 	dbf.w		%d2,ap_p_gd		# get next digit
   23272  1.1     is ap_p_fx:
   23273  1.1     is 	mov.l		%d1,%d0			# copy counter to d2
   23274  1.1     is 	mov.l		(%sp),%d1		# get adjusted exp from memory
   23275  1.1     is 	sub.l		%d0,%d1			# subtract count from exp
   23276  1.1     is 	bge.b		ap_p_fm			# if still pos, go to pwrten
   23277  1.1     is 	neg.l		%d1			# now its neg; get abs
   23278  1.1     is 	mov.l		(%a0),%d4		# load lword 1 to d4
   23279  1.1     is 	or.l		&0x40000000,%d4		# and set SE in d4
   23280  1.1     is 	or.l		&0x40000000,(%a0)	# and in memory
   23281  1.1     is #
   23282  1.1     is # Calculate the mantissa multiplier to compensate for the striping of
   23283  1.1     is # zeros from the mantissa.
   23284  1.1     is #
   23285  1.1     is ap_p_fm:
   23286  1.1     is 	lea.l		PTENRN(%pc),%a1		# get address of power-of-ten table
   23287  1.1     is 	clr.l		%d3			# init table index
   23288  1.1     is 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
   23289  1.1     is 	mov.l		&3,%d2			# init d2 to count bits in counter
   23290  1.1     is ap_p_el:
   23291  1.1     is 	asr.l		&1,%d0			# shift lsb into carry
   23292  1.1     is 	bcc.b		ap_p_en			# if 1, mul fp1 by pwrten factor
   23293  1.1     is 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
   23294  1.1     is ap_p_en:
   23295  1.1     is 	add.l		&12,%d3			# inc d3 to next rtable entry
   23296  1.1     is 	tst.l		%d0			# check if d0 is zero
   23297  1.1     is 	bne.b		ap_p_el			# if not, get next bit
   23298  1.1     is 	fmul.x		%fp1,%fp0		# mul mantissa by 10**(no_bits_shifted)
   23299  1.1     is 	bra.b		pwrten			# go calc pwrten
   23300  1.1     is #
   23301  1.1     is # This section handles a negative adjusted exponent.
   23302  1.1     is #
   23303  1.1     is ap_st_n:
   23304  1.1     is 	clr.l		%d1			# clr counter
   23305  1.1     is 	mov.l		&2,%d5			# set up d5 to point to lword 3
   23306  1.1     is 	mov.l		(%a0,%d5.L*4),%d4	# get lword 3
   23307  1.1     is 	bne.b		ap_n_cl			# if not zero, check digits
   23308  1.1     is 	sub.l		&1,%d5			# dec d5 to point to lword 2
   23309  1.1     is 	addq.l		&8,%d1			# inc counter by 8
   23310  1.1     is 	mov.l		(%a0,%d5.L*4),%d4	# get lword 2
   23311  1.1     is ap_n_cl:
   23312  1.1     is 	mov.l		&28,%d3			# point to last digit
   23313  1.1     is 	mov.l		&7,%d2			# init digit counter
   23314  1.1     is ap_n_gd:
   23315  1.1     is 	bfextu		%d4{%d3:&4},%d0		# get digit
   23316  1.1     is 	bne.b		ap_n_fx			# if non-zero, go to exp fix
   23317  1.1     is 	subq.l		&4,%d3			# point to previous digit
   23318  1.1     is 	addq.l		&1,%d1			# inc digit counter
   23319  1.1     is 	dbf.w		%d2,ap_n_gd		# get next digit
   23320  1.1     is ap_n_fx:
   23321  1.1     is 	mov.l		%d1,%d0			# copy counter to d0
   23322  1.1     is 	mov.l		(%sp),%d1		# get adjusted exp from memory
   23323  1.1     is 	sub.l		%d0,%d1			# subtract count from exp
   23324  1.1     is 	bgt.b		ap_n_fm			# if still pos, go fix mantissa
   23325  1.1     is 	neg.l		%d1			# take abs of exp and clr SE
   23326  1.1     is 	mov.l		(%a0),%d4		# load lword 1 to d4
   23327  1.1     is 	and.l		&0xbfffffff,%d4		# and clr SE in d4
   23328  1.1     is 	and.l		&0xbfffffff,(%a0)	# and in memory
   23329  1.1     is #
   23330  1.1     is # Calculate the mantissa multiplier to compensate for the appending of
   23331  1.1     is # zeros to the mantissa.
   23332  1.1     is #
   23333  1.1     is ap_n_fm:
   23334  1.1     is 	lea.l		PTENRN(%pc),%a1		# get address of power-of-ten table
   23335  1.1     is 	clr.l		%d3			# init table index
   23336  1.1     is 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
   23337  1.1     is 	mov.l		&3,%d2			# init d2 to count bits in counter
   23338  1.1     is ap_n_el:
   23339  1.1     is 	asr.l		&1,%d0			# shift lsb into carry
   23340  1.1     is 	bcc.b		ap_n_en			# if 1, mul fp1 by pwrten factor
   23341  1.1     is 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
   23342  1.1     is ap_n_en:
   23343  1.1     is 	add.l		&12,%d3			# inc d3 to next rtable entry
   23344  1.1     is 	tst.l		%d0			# check if d0 is zero
   23345  1.1     is 	bne.b		ap_n_el			# if not, get next bit
   23346  1.1     is 	fdiv.x		%fp1,%fp0		# div mantissa by 10**(no_bits_shifted)
   23347  1.1     is #
   23348  1.1     is #
   23349  1.1     is # Calculate power-of-ten factor from adjusted and shifted exponent.
   23350  1.1     is #
   23351  1.1     is # Register usage:
   23352  1.1     is #
   23353  1.1     is #  pwrten:
   23354  1.1     is #	(*)  d0: temp
   23355  1.1     is #	( )  d1: exponent
   23356  1.1     is #	(*)  d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp
   23357  1.1     is #	(*)  d3: FPCR work copy
   23358  1.1     is #	( )  d4: first word of bcd
   23359  1.1     is #	(*)  a1: RTABLE pointer
   23360  1.1     is #  calc_p:
   23361  1.1     is #	(*)  d0: temp
   23362  1.1     is #	( )  d1: exponent
   23363  1.1     is #	(*)  d3: PWRTxx table index
   23364  1.1     is #	( )  a0: pointer to working copy of bcd
   23365  1.1     is #	(*)  a1: PWRTxx pointer
   23366  1.1     is #	(*) fp1: power-of-ten accumulator
   23367  1.1     is #
   23368  1.1     is # Pwrten calculates the exponent factor in the selected rounding mode
   23369  1.1     is # according to the following table:
   23370  1.1     is #
   23371  1.1     is #	Sign of Mant  Sign of Exp  Rounding Mode  PWRTEN Rounding Mode
   23372  1.1     is #
   23373  1.1     is #	ANY	  ANY	RN	RN
   23374  1.1     is #
   23375  1.1     is #	 +	   +	RP	RP
   23376  1.1     is #	 -	   +	RP	RM
   23377  1.1     is #	 +	   -	RP	RM
   23378  1.1     is #	 -	   -	RP	RP
   23379  1.1     is #
   23380  1.1     is #	 +	   +	RM	RM
   23381  1.1     is #	 -	   +	RM	RP
   23382  1.1     is #	 +	   -	RM	RP
   23383  1.1     is #	 -	   -	RM	RM
   23384  1.1     is #
   23385  1.1     is #	 +	   +	RZ	RM
   23386  1.1     is #	 -	   +	RZ	RM
   23387  1.1     is #	 +	   -	RZ	RP
   23388  1.1     is #	 -	   -	RZ	RP
   23389  1.1     is #
   23390  1.1     is #
   23391  1.1     is pwrten:
   23392  1.1     is 	mov.l		USER_FPCR(%a6),%d3	# get user's FPCR
   23393  1.1     is 	bfextu		%d3{&26:&2},%d2		# isolate rounding mode bits
   23394  1.1     is 	mov.l		(%a0),%d4		# reload 1st bcd word to d4
   23395  1.1     is 	asl.l		&2,%d2			# format d2 to be
   23396  1.1     is 	bfextu		%d4{&0:&2},%d0		# {FPCR[6],FPCR[5],SM,SE}
   23397  1.1     is 	add.l		%d0,%d2			# in d2 as index into RTABLE
   23398  1.1     is 	lea.l		RTABLE(%pc),%a1		# load rtable base
   23399  1.1     is 	mov.b		(%a1,%d2),%d0		# load new rounding bits from table
   23400  1.1     is 	clr.l		%d3			# clear d3 to force no exc and extended
   23401  1.1     is 	bfins		%d0,%d3{&26:&2}		# stuff new rounding bits in FPCR
   23402  1.1     is 	fmov.l		%d3,%fpcr		# write new FPCR
   23403  1.1     is 	asr.l		&1,%d0			# write correct PTENxx table
   23404  1.1     is 	bcc.b		not_rp			# to a1
   23405  1.1     is 	lea.l		PTENRP(%pc),%a1		# it is RP
   23406  1.1     is 	bra.b		calc_p			# go to init section
   23407  1.1     is not_rp:
   23408  1.1     is 	asr.l		&1,%d0			# keep checking
   23409  1.1     is 	bcc.b		not_rm
   23410  1.1     is 	lea.l		PTENRM(%pc),%a1		# it is RM
   23411  1.1     is 	bra.b		calc_p			# go to init section
   23412  1.1     is not_rm:
   23413  1.1     is 	lea.l		PTENRN(%pc),%a1		# it is RN
   23414  1.1     is calc_p:
   23415  1.1     is 	mov.l		%d1,%d0			# copy exp to d0;use d0
   23416  1.1     is 	bpl.b		no_neg			# if exp is negative,
   23417  1.1     is 	neg.l		%d0			# invert it
   23418  1.1     is 	or.l		&0x40000000,(%a0)	# and set SE bit
   23419  1.1     is no_neg:
   23420  1.1     is 	clr.l		%d3			# table index
   23421  1.1     is 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
   23422  1.1     is e_loop:
   23423  1.1     is 	asr.l		&1,%d0			# shift next bit into carry
   23424  1.1     is 	bcc.b		e_next			# if zero, skip the mul
   23425  1.1     is 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
   23426  1.1     is e_next:
   23427  1.1     is 	add.l		&12,%d3			# inc d3 to next rtable entry
   23428  1.1     is 	tst.l		%d0			# check if d0 is zero
   23429  1.1     is 	bne.b		e_loop			# not zero, continue shifting
   23430  1.1     is #
   23431  1.1     is #
   23432  1.1     is #  Check the sign of the adjusted exp and make the value in fp0 the
   23433  1.1     is #  same sign. If the exp was pos then multiply fp1*fp0;
   23434  1.1     is #  else divide fp0/fp1.
   23435  1.1     is #
   23436  1.1     is # Register Usage:
   23437  1.1     is #  norm:
   23438  1.1     is #	( )  a0: pointer to working bcd value
   23439  1.1     is #	(*) fp0: mantissa accumulator
   23440  1.1     is #	( ) fp1: scaling factor - 10**(abs(exp))
   23441  1.1     is #
   23442  1.1     is pnorm:
   23443  1.1     is 	btst		&30,(%a0)		# test the sign of the exponent
   23444  1.1     is 	beq.b		mul			# if clear, go to multiply
   23445  1.1     is div:
   23446  1.1     is 	fdiv.x		%fp1,%fp0		# exp is negative, so divide mant by exp
   23447  1.1     is 	bra.b		end_dec
   23448  1.1     is mul:
   23449  1.1     is 	fmul.x		%fp1,%fp0		# exp is positive, so multiply by exp
   23450  1.1     is #
   23451  1.1     is #
   23452  1.1     is # Clean up and return with result in fp0.
   23453  1.1     is #
   23454  1.1     is # If the final mul/div in decbin incurred an inex exception,
   23455  1.1     is # it will be inex2, but will be reported as inex1 by get_op.
   23456  1.1     is #
   23457  1.1     is end_dec:
   23458  1.1     is 	fmov.l		%fpsr,%d0		# get status register
   23459  1.1     is 	bclr		&inex2_bit+8,%d0	# test for inex2 and clear it
   23460  1.1     is 	beq.b		no_exc			# skip this if no exc
   23461  1.1     is 	ori.w		&inx1a_mask,2+USER_FPSR(%a6) # set INEX1/AINEX
   23462  1.1     is no_exc:
   23463  1.1     is 	add.l		&0x4,%sp		# clear 1 lw param
   23464  1.1     is 	fmovm.x		(%sp)+,&0x40		# restore fp1
   23465  1.1     is 	movm.l		(%sp)+,&0x3c		# restore d2-d5
   23466  1.1     is 	fmov.l		&0x0,%fpcr
   23467  1.1     is 	fmov.l		&0x0,%fpsr
   23468  1.1     is 	rts
   23469  1.1     is 
   23470  1.1     is #########################################################################
   23471  1.1     is # bindec(): Converts an input in extended precision format to bcd format#
   23472  1.1     is #									#
   23473  1.1     is # INPUT ***************************************************************	#
   23474  1.1     is #	a0 = pointer to the input extended precision value in memory.	#
   23475  1.1     is #	     the input may be either normalized, unnormalized, or 	#
   23476  1.1     is #	     denormalized.						#
   23477  1.1     is #	d0 = contains the k-factor sign-extended to 32-bits. 		#
   23478  1.1     is #									#
   23479  1.1     is # OUTPUT **************************************************************	#
   23480  1.1     is #	FP_SCR0(a6) = bcd format result on the stack.			#
   23481  1.1     is #									#
   23482  1.1     is # ALGORITHM ***********************************************************	#
   23483  1.1     is #									#
   23484  1.1     is #	A1.	Set RM and size ext;  Set SIGMA = sign of input.  	#
   23485  1.1     is #		The k-factor is saved for use in d7. Clear the		#
   23486  1.1     is #		BINDEC_FLG for separating normalized/denormalized	#
   23487  1.1     is #		input.  If input is unnormalized or denormalized,	#
   23488  1.1     is #		normalize it.						#
   23489  1.1     is #									#
   23490  1.1     is #	A2.	Set X = abs(input).					#
   23491  1.1     is #									#
   23492  1.1     is #	A3.	Compute ILOG.						#
   23493  1.1     is #		ILOG is the log base 10 of the input value.  It is	#
   23494  1.1     is #		approximated by adding e + 0.f when the original 	#
   23495  1.1     is #		value is viewed as 2^^e * 1.f in extended precision.  	#
   23496  1.1     is #		This value is stored in d6.				#
   23497  1.1     is #									#
   23498  1.1     is #	A4.	Clr INEX bit.						#
   23499  1.1     is #		The operation in A3 above may have set INEX2.  		#
   23500  1.1     is #									#
   23501  1.1     is #	A5.	Set ICTR = 0;						#
   23502  1.1     is #		ICTR is a flag used in A13.  It must be set before the 	#
   23503  1.1     is #		loop entry A6.						#
   23504  1.1     is #									#
   23505  1.1     is #	A6.	Calculate LEN.						#
   23506  1.1     is #		LEN is the number of digits to be displayed.  The	#
   23507  1.1     is #		k-factor can dictate either the total number of digits,	#
   23508  1.1     is #		if it is a positive number, or the number of digits	#
   23509  1.1     is #		after the decimal point which are to be included as	#
   23510  1.1     is #		significant.  See the 68882 manual for examples.	#
   23511  1.1     is #		If LEN is computed to be greater than 17, set OPERR in	#
   23512  1.1     is #		USER_FPSR.  LEN is stored in d4.			#
   23513  1.1     is #									#
   23514  1.1     is #	A7.	Calculate SCALE.					#
   23515  1.1     is #		SCALE is equal to 10^ISCALE, where ISCALE is the number	#
   23516  1.1     is #		of decimal places needed to insure LEN integer digits	#
   23517  1.1     is #		in the output before conversion to bcd. LAMBDA is the	#
   23518  1.1     is #		sign of ISCALE, used in A9. Fp1 contains		#
   23519  1.1     is #		10^^(abs(ISCALE)) using a rounding mode which is a	#
   23520  1.1     is #		function of the original rounding mode and the signs	#
   23521  1.1     is #		of ISCALE and X.  A table is given in the code.		#
   23522  1.1     is #									#
   23523  1.1     is #	A8.	Clr INEX; Force RZ.					#
   23524  1.1     is #		The operation in A3 above may have set INEX2.  		#
   23525  1.1     is #		RZ mode is forced for the scaling operation to insure	#
   23526  1.1     is #		only one rounding error.  The grs bits are collected in #
   23527  1.1     is #		the INEX flag for use in A10.				#
   23528  1.1     is #									#
   23529  1.1     is #	A9.	Scale X -> Y.						#
   23530  1.1     is #		The mantissa is scaled to the desired number of		#
   23531  1.1     is #		significant digits.  The excess digits are collected	#
   23532  1.1     is #		in INEX2.						#
   23533  1.1     is #									#
   23534  1.1     is #	A10.	Or in INEX.						#
   23535  1.2    wiz #		If INEX is set, round error occurred.  This is		#
   23536  1.1     is #		compensated for by 'or-ing' in the INEX2 flag to	#
   23537  1.1     is #		the lsb of Y.						#
   23538  1.1     is #									#
   23539  1.1     is #	A11.	Restore original FPCR; set size ext.			#
   23540  1.1     is #		Perform FINT operation in the user's rounding mode.	#
   23541  1.1     is #		Keep the size to extended.				#
   23542  1.1     is #									#
   23543  1.1     is #	A12.	Calculate YINT = FINT(Y) according to user's rounding	#
   23544  1.1     is #		mode.  The FPSP routine sintd0 is used.  The output	#
   23545  1.1     is #		is in fp0.						#
   23546  1.1     is #									#
   23547  1.1     is #	A13.	Check for LEN digits.					#
   23548  1.1     is #		If the int operation results in more than LEN digits,	#
   23549  1.1     is #		or less than LEN -1 digits, adjust ILOG and repeat from	#
   23550  1.1     is #		A6.  This test occurs only on the first pass.  If the	#
   23551  1.1     is #		result is exactly 10^LEN, decrement ILOG and divide	#
   23552  1.1     is #		the mantissa by 10.					#
   23553  1.1     is #									#
   23554  1.1     is #	A14.	Convert the mantissa to bcd.				#
   23555  1.1     is #		The binstr routine is used to convert the LEN digit 	#
   23556  1.1     is #		mantissa to bcd in memory.  The input to binstr is	#
   23557  1.1     is #		to be a fraction; i.e. (mantissa)/10^LEN and adjusted	#
   23558  1.1     is #		such that the decimal point is to the left of bit 63.	#
   23559  1.1     is #		The bcd digits are stored in the correct position in 	#
   23560  1.1     is #		the final string area in memory.			#
   23561  1.1     is #									#
   23562  1.1     is #	A15.	Convert the exponent to bcd.				#
   23563  1.1     is #		As in A14 above, the exp is converted to bcd and the	#
   23564  1.1     is #		digits are stored in the final string.			#
   23565  1.1     is #		Test the length of the final exponent string.  If the	#
   23566  1.1     is #		length is 4, set operr.					#
   23567  1.1     is #									#
   23568  1.1     is #	A16.	Write sign bits to final string.			#
   23569  1.1     is #									#
   23570  1.1     is #########################################################################
   23571  1.1     is 
   23572  1.1     is set	BINDEC_FLG,	EXC_TEMP	# DENORM flag
   23573  1.1     is 
   23574  1.1     is # Constants in extended precision
   23575  1.1     is PLOG2:
   23576  1.1     is 	long		0x3FFD0000,0x9A209A84,0xFBCFF798,0x00000000
   23577  1.1     is PLOG2UP1:
   23578  1.1     is 	long		0x3FFD0000,0x9A209A84,0xFBCFF799,0x00000000
   23579  1.1     is 
   23580  1.1     is # Constants in single precision
   23581  1.1     is FONE:
   23582  1.1     is 	long		0x3F800000,0x00000000,0x00000000,0x00000000
   23583  1.1     is FTWO:
   23584  1.1     is 	long		0x40000000,0x00000000,0x00000000,0x00000000
   23585  1.1     is FTEN:
   23586  1.1     is 	long		0x41200000,0x00000000,0x00000000,0x00000000
   23587  1.1     is F4933:
   23588  1.1     is 	long		0x459A2800,0x00000000,0x00000000,0x00000000
   23589  1.1     is 
   23590  1.1     is RBDTBL:
   23591  1.1     is 	byte		0,0,0,0
   23592  1.1     is 	byte		3,3,2,2
   23593  1.1     is 	byte		3,2,2,3
   23594  1.1     is 	byte		2,3,3,2
   23595  1.1     is 
   23596  1.1     is #	Implementation Notes:
   23597  1.1     is #
   23598  1.1     is #	The registers are used as follows:
   23599  1.1     is #
   23600  1.1     is #		d0: scratch; LEN input to binstr
   23601  1.1     is #		d1: scratch
   23602  1.1     is #		d2: upper 32-bits of mantissa for binstr
   23603  1.1     is #		d3: scratch;lower 32-bits of mantissa for binstr
   23604  1.1     is #		d4: LEN
   23605  1.1     is #      		d5: LAMBDA/ICTR
   23606  1.1     is #		d6: ILOG
   23607  1.1     is #		d7: k-factor
   23608  1.1     is #		a0: ptr for original operand/final result
   23609  1.1     is #		a1: scratch pointer
   23610  1.1     is #		a2: pointer to FP_X; abs(original value) in ext
   23611  1.1     is #		fp0: scratch
   23612  1.1     is #		fp1: scratch
   23613  1.1     is #		fp2: scratch
   23614  1.1     is #		F_SCR1:
   23615  1.1     is #		F_SCR2:
   23616  1.1     is #		L_SCR1:
   23617  1.1     is #		L_SCR2:
   23618  1.1     is 
   23619  1.1     is 	global		bindec
   23620  1.1     is bindec:
   23621  1.1     is 	movm.l		&0x3f20,-(%sp)	#  {%d2-%d7/%a2}
   23622  1.1     is 	fmovm.x		&0x7,-(%sp)	#  {%fp0-%fp2}
   23623  1.1     is 
   23624  1.1     is # A1. Set RM and size ext. Set SIGMA = sign input;
   23625  1.1     is #     The k-factor is saved for use in d7.  Clear BINDEC_FLG for
   23626  1.1     is #     separating  normalized/denormalized input.  If the input
   23627  1.1     is #     is a denormalized number, set the BINDEC_FLG memory word
   23628  1.1     is #     to signal denorm.  If the input is unnormalized, normalize
   23629  1.1     is #     the input and test for denormalized result.
   23630  1.1     is #
   23631  1.1     is 	fmov.l		&rm_mode*0x10,%fpcr	# set RM and ext
   23632  1.1     is 	mov.l		(%a0),L_SCR2(%a6)	# save exponent for sign check
   23633  1.1     is 	mov.l		%d0,%d7		# move k-factor to d7
   23634  1.1     is 
   23635  1.1     is 	clr.b		BINDEC_FLG(%a6)	# clr norm/denorm flag
   23636  1.1     is 	cmpi.b		STAG(%a6),&DENORM # is input a DENORM?
   23637  1.1     is 	bne.w		A2_str		# no; input is a NORM
   23638  1.1     is 
   23639  1.1     is #
   23640  1.1     is # Normalize the denorm
   23641  1.1     is #
   23642  1.1     is un_de_norm:
   23643  1.1     is 	mov.w		(%a0),%d0
   23644  1.1     is 	and.w		&0x7fff,%d0	# strip sign of normalized exp
   23645  1.1     is 	mov.l		4(%a0),%d1
   23646  1.1     is 	mov.l		8(%a0),%d2
   23647  1.1     is norm_loop:
   23648  1.1     is 	sub.w		&1,%d0
   23649  1.1     is 	lsl.l		&1,%d2
   23650  1.1     is 	roxl.l		&1,%d1
   23651  1.1     is 	tst.l		%d1
   23652  1.1     is 	bge.b		norm_loop
   23653  1.1     is #
   23654  1.1     is # Test if the normalized input is denormalized
   23655  1.1     is #
   23656  1.1     is 	tst.w		%d0
   23657  1.1     is 	bgt.b		pos_exp		# if greater than zero, it is a norm
   23658  1.1     is 	st		BINDEC_FLG(%a6)	# set flag for denorm
   23659  1.1     is pos_exp:
   23660  1.1     is 	and.w		&0x7fff,%d0	# strip sign of normalized exp
   23661  1.1     is 	mov.w		%d0,(%a0)
   23662  1.1     is 	mov.l		%d1,4(%a0)
   23663  1.1     is 	mov.l		%d2,8(%a0)
   23664  1.1     is 
   23665  1.1     is # A2. Set X = abs(input).
   23666  1.1     is #
   23667  1.1     is A2_str:
   23668  1.1     is 	mov.l		(%a0),FP_SCR1(%a6)	# move input to work space
   23669  1.1     is 	mov.l		4(%a0),FP_SCR1+4(%a6)	# move input to work space
   23670  1.1     is 	mov.l		8(%a0),FP_SCR1+8(%a6)	# move input to work space
   23671  1.1     is 	and.l		&0x7fffffff,FP_SCR1(%a6)	# create abs(X)
   23672  1.1     is 
   23673  1.1     is # A3. Compute ILOG.
   23674  1.1     is #     ILOG is the log base 10 of the input value.  It is approx-
   23675  1.1     is #     imated by adding e + 0.f when the original value is viewed
   23676  1.1     is #     as 2^^e * 1.f in extended precision.  This value is stored
   23677  1.1     is #     in d6.
   23678  1.1     is #
   23679  1.1     is # Register usage:
   23680  1.1     is #	Input/Output
   23681  1.1     is #	d0: k-factor/exponent
   23682  1.1     is #	d2: x/x
   23683  1.1     is #	d3: x/x
   23684  1.1     is #	d4: x/x
   23685  1.1     is #	d5: x/x
   23686  1.1     is #	d6: x/ILOG
   23687  1.1     is #	d7: k-factor/Unchanged
   23688  1.1     is #	a0: ptr for original operand/final result
   23689  1.1     is #	a1: x/x
   23690  1.1     is #	a2: x/x
   23691  1.1     is #	fp0: x/float(ILOG)
   23692  1.1     is #	fp1: x/x
   23693  1.1     is #	fp2: x/x
   23694  1.1     is #	F_SCR1:x/x
   23695  1.1     is #	F_SCR2:Abs(X)/Abs(X) with $3fff exponent
   23696  1.1     is #	L_SCR1:x/x
   23697  1.1     is #	L_SCR2:first word of X packed/Unchanged
   23698  1.1     is 
   23699  1.1     is 	tst.b		BINDEC_FLG(%a6)	# check for denorm
   23700  1.1     is 	beq.b		A3_cont		# if clr, continue with norm
   23701  1.1     is 	mov.l		&-4933,%d6	# force ILOG = -4933
   23702  1.1     is 	bra.b		A4_str
   23703  1.1     is A3_cont:
   23704  1.1     is 	mov.w		FP_SCR1(%a6),%d0	# move exp to d0
   23705  1.1     is 	mov.w		&0x3fff,FP_SCR1(%a6)	# replace exponent with 0x3fff
   23706  1.1     is 	fmov.x		FP_SCR1(%a6),%fp0	# now fp0 has 1.f
   23707  1.1     is 	sub.w		&0x3fff,%d0	# strip off bias
   23708  1.1     is 	fadd.w		%d0,%fp0	# add in exp
   23709  1.1     is 	fsub.s		FONE(%pc),%fp0	# subtract off 1.0
   23710  1.1     is 	fbge.w		pos_res		# if pos, branch
   23711  1.1     is 	fmul.x		PLOG2UP1(%pc),%fp0	# if neg, mul by LOG2UP1
   23712  1.1     is 	fmov.l		%fp0,%d6	# put ILOG in d6 as a lword
   23713  1.1     is 	bra.b		A4_str		# go move out ILOG
   23714  1.1     is pos_res:
   23715  1.1     is 	fmul.x		PLOG2(%pc),%fp0	# if pos, mul by LOG2
   23716  1.1     is 	fmov.l		%fp0,%d6	# put ILOG in d6 as a lword
   23717  1.1     is 
   23718  1.1     is 
   23719  1.1     is # A4. Clr INEX bit.
   23720  1.1     is #     The operation in A3 above may have set INEX2.
   23721  1.1     is 
   23722  1.1     is A4_str:
   23723  1.1     is 	fmov.l		&0,%fpsr	# zero all of fpsr - nothing needed
   23724  1.1     is 
   23725  1.1     is 
   23726  1.1     is # A5. Set ICTR = 0;
   23727  1.1     is #     ICTR is a flag used in A13.  It must be set before the
   23728  1.1     is #     loop entry A6. The lower word of d5 is used for ICTR.
   23729  1.1     is 
   23730  1.1     is 	clr.w		%d5		# clear ICTR
   23731  1.1     is 
   23732  1.1     is # A6. Calculate LEN.
   23733  1.1     is #     LEN is the number of digits to be displayed.  The k-factor
   23734  1.1     is #     can dictate either the total number of digits, if it is
   23735  1.1     is #     a positive number, or the number of digits after the
   23736  1.1     is #     original decimal point which are to be included as
   23737  1.1     is #     significant.  See the 68882 manual for examples.
   23738  1.1     is #     If LEN is computed to be greater than 17, set OPERR in
   23739  1.1     is #     USER_FPSR.  LEN is stored in d4.
   23740  1.1     is #
   23741  1.1     is # Register usage:
   23742  1.1     is #	Input/Output
   23743  1.1     is #	d0: exponent/Unchanged
   23744  1.1     is #	d2: x/x/scratch
   23745  1.1     is #	d3: x/x
   23746  1.1     is #	d4: exc picture/LEN
   23747  1.1     is #	d5: ICTR/Unchanged
   23748  1.1     is #	d6: ILOG/Unchanged
   23749  1.1     is #	d7: k-factor/Unchanged
   23750  1.1     is #	a0: ptr for original operand/final result
   23751  1.1     is #	a1: x/x
   23752  1.1     is #	a2: x/x
   23753  1.1     is #	fp0: float(ILOG)/Unchanged
   23754  1.1     is #	fp1: x/x
   23755  1.1     is #	fp2: x/x
   23756  1.1     is #	F_SCR1:x/x
   23757  1.1     is #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
   23758  1.1     is #	L_SCR1:x/x
   23759  1.1     is #	L_SCR2:first word of X packed/Unchanged
   23760  1.1     is 
   23761  1.1     is A6_str:
   23762  1.1     is 	tst.l		%d7		# branch on sign of k
   23763  1.1     is 	ble.b		k_neg		# if k <= 0, LEN = ILOG + 1 - k
   23764  1.1     is 	mov.l		%d7,%d4		# if k > 0, LEN = k
   23765  1.1     is 	bra.b		len_ck		# skip to LEN check
   23766  1.1     is k_neg:
   23767  1.1     is 	mov.l		%d6,%d4		# first load ILOG to d4
   23768  1.1     is 	sub.l		%d7,%d4		# subtract off k
   23769  1.1     is 	addq.l		&1,%d4		# add in the 1
   23770  1.1     is len_ck:
   23771  1.1     is 	tst.l		%d4		# LEN check: branch on sign of LEN
   23772  1.1     is 	ble.b		LEN_ng		# if neg, set LEN = 1
   23773  1.1     is 	cmp.l		%d4,&17		# test if LEN > 17
   23774  1.1     is 	ble.b		A7_str		# if not, forget it
   23775  1.1     is 	mov.l		&17,%d4		# set max LEN = 17
   23776  1.1     is 	tst.l		%d7		# if negative, never set OPERR
   23777  1.1     is 	ble.b		A7_str		# if positive, continue
   23778  1.1     is 	or.l		&opaop_mask,USER_FPSR(%a6)	# set OPERR & AIOP in USER_FPSR
   23779  1.1     is 	bra.b		A7_str		# finished here
   23780  1.1     is LEN_ng:
   23781  1.1     is 	mov.l		&1,%d4		# min LEN is 1
   23782  1.1     is 
   23783  1.1     is 
   23784  1.1     is # A7. Calculate SCALE.
   23785  1.1     is #     SCALE is equal to 10^ISCALE, where ISCALE is the number
   23786  1.1     is #     of decimal places needed to insure LEN integer digits
   23787  1.1     is #     in the output before conversion to bcd. LAMBDA is the sign
   23788  1.1     is #     of ISCALE, used in A9.  Fp1 contains 10^^(abs(ISCALE)) using
   23789  1.1     is #     the rounding mode as given in the following table (see
   23790  1.1     is #     Coonen, p. 7.23 as ref.; however, the SCALE variable is
   23791  1.1     is #     of opposite sign in bindec.sa from Coonen).
   23792  1.1     is #
   23793  1.1     is #	Initial					USE
   23794  1.1     is #	FPCR[6:5]	LAMBDA	SIGN(X)		FPCR[6:5]
   23795  1.1     is #	----------------------------------------------
   23796  1.1     is #	 RN	00	   0	   0		00/0	RN
   23797  1.1     is #	 RN	00	   0	   1		00/0	RN
   23798  1.1     is #	 RN	00	   1	   0		00/0	RN
   23799  1.1     is #	 RN	00	   1	   1		00/0	RN
   23800  1.1     is #	 RZ	01	   0	   0		11/3	RP
   23801  1.1     is #	 RZ	01	   0	   1		11/3	RP
   23802  1.1     is #	 RZ	01	   1	   0		10/2	RM
   23803  1.1     is #	 RZ	01	   1	   1		10/2	RM
   23804  1.1     is #	 RM	10	   0	   0		11/3	RP
   23805  1.1     is #	 RM	10	   0	   1		10/2	RM
   23806  1.1     is #	 RM	10	   1	   0		10/2	RM
   23807  1.1     is #	 RM	10	   1	   1		11/3	RP
   23808  1.1     is #	 RP	11	   0	   0		10/2	RM
   23809  1.1     is #	 RP	11	   0	   1		11/3	RP
   23810  1.1     is #	 RP	11	   1	   0		11/3	RP
   23811  1.1     is #	 RP	11	   1	   1		10/2	RM
   23812  1.1     is #
   23813  1.1     is # Register usage:
   23814  1.1     is #	Input/Output
   23815  1.1     is #	d0: exponent/scratch - final is 0
   23816  1.1     is #	d2: x/0 or 24 for A9
   23817  1.1     is #	d3: x/scratch - offset ptr into PTENRM array
   23818  1.1     is #	d4: LEN/Unchanged
   23819  1.1     is #	d5: 0/ICTR:LAMBDA
   23820  1.1     is #	d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k))
   23821  1.1     is #	d7: k-factor/Unchanged
   23822  1.1     is #	a0: ptr for original operand/final result
   23823  1.1     is #	a1: x/ptr to PTENRM array
   23824  1.1     is #	a2: x/x
   23825  1.1     is #	fp0: float(ILOG)/Unchanged
   23826  1.1     is #	fp1: x/10^ISCALE
   23827  1.1     is #	fp2: x/x
   23828  1.1     is #	F_SCR1:x/x
   23829  1.1     is #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
   23830  1.1     is #	L_SCR1:x/x
   23831  1.1     is #	L_SCR2:first word of X packed/Unchanged
   23832  1.1     is 
   23833  1.1     is A7_str:
   23834  1.1     is 	tst.l		%d7		# test sign of k
   23835  1.1     is 	bgt.b		k_pos		# if pos and > 0, skip this
   23836  1.1     is 	cmp.l		%d7,%d6		# test k - ILOG
   23837  1.1     is 	blt.b		k_pos		# if ILOG >= k, skip this
   23838  1.1     is 	mov.l		%d7,%d6		# if ((k<0) & (ILOG < k)) ILOG = k
   23839  1.1     is k_pos:
   23840  1.1     is 	mov.l		%d6,%d0		# calc ILOG + 1 - LEN in d0
   23841  1.1     is 	addq.l		&1,%d0		# add the 1
   23842  1.1     is 	sub.l		%d4,%d0		# sub off LEN
   23843  1.1     is 	swap		%d5		# use upper word of d5 for LAMBDA
   23844  1.1     is 	clr.w		%d5		# set it zero initially
   23845  1.1     is 	clr.w		%d2		# set up d2 for very small case
   23846  1.1     is 	tst.l		%d0		# test sign of ISCALE
   23847  1.1     is 	bge.b		iscale		# if pos, skip next inst
   23848  1.1     is 	addq.w		&1,%d5		# if neg, set LAMBDA true
   23849  1.1     is 	cmp.l		%d0,&0xffffecd4	# test iscale <= -4908
   23850  1.1     is 	bgt.b		no_inf		# if false, skip rest
   23851  1.1     is 	add.l		&24,%d0		# add in 24 to iscale
   23852  1.1     is 	mov.l		&24,%d2		# put 24 in d2 for A9
   23853  1.1     is no_inf:
   23854  1.1     is 	neg.l		%d0		# and take abs of ISCALE
   23855  1.1     is iscale:
   23856  1.1     is 	fmov.s		FONE(%pc),%fp1	# init fp1 to 1
   23857  1.1     is 	bfextu		USER_FPCR(%a6){&26:&2},%d1	# get initial rmode bits
   23858  1.1     is 	lsl.w		&1,%d1		# put them in bits 2:1
   23859  1.1     is 	add.w		%d5,%d1		# add in LAMBDA
   23860  1.1     is 	lsl.w		&1,%d1		# put them in bits 3:1
   23861  1.1     is 	tst.l		L_SCR2(%a6)	# test sign of original x
   23862  1.1     is 	bge.b		x_pos		# if pos, don't set bit 0
   23863  1.1     is 	addq.l		&1,%d1		# if neg, set bit 0
   23864  1.1     is x_pos:
   23865  1.1     is 	lea.l		RBDTBL(%pc),%a2	# load rbdtbl base
   23866  1.1     is 	mov.b		(%a2,%d1),%d3	# load d3 with new rmode
   23867  1.1     is 	lsl.l		&4,%d3		# put bits in proper position
   23868  1.1     is 	fmov.l		%d3,%fpcr	# load bits into fpu
   23869  1.1     is 	lsr.l		&4,%d3		# put bits in proper position
   23870  1.1     is 	tst.b		%d3		# decode new rmode for pten table
   23871  1.1     is 	bne.b		not_rn		# if zero, it is RN
   23872  1.1     is 	lea.l		PTENRN(%pc),%a1	# load a1 with RN table base
   23873  1.1     is 	bra.b		rmode		# exit decode
   23874  1.1     is not_rn:
   23875  1.1     is 	lsr.b		&1,%d3		# get lsb in carry
   23876  1.1     is 	bcc.b		not_rp2		# if carry clear, it is RM
   23877  1.1     is 	lea.l		PTENRP(%pc),%a1	# load a1 with RP table base
   23878  1.1     is 	bra.b		rmode		# exit decode
   23879  1.1     is not_rp2:
   23880  1.1     is 	lea.l		PTENRM(%pc),%a1	# load a1 with RM table base
   23881  1.1     is rmode:
   23882  1.1     is 	clr.l		%d3		# clr table index
   23883  1.1     is e_loop2:
   23884  1.1     is 	lsr.l		&1,%d0		# shift next bit into carry
   23885  1.1     is 	bcc.b		e_next2		# if zero, skip the mul
   23886  1.1     is 	fmul.x		(%a1,%d3),%fp1	# mul by 10**(d3_bit_no)
   23887  1.1     is e_next2:
   23888  1.1     is 	add.l		&12,%d3		# inc d3 to next pwrten table entry
   23889  1.1     is 	tst.l		%d0		# test if ISCALE is zero
   23890  1.1     is 	bne.b		e_loop2		# if not, loop
   23891  1.1     is 
   23892  1.1     is # A8. Clr INEX; Force RZ.
   23893  1.1     is #     The operation in A3 above may have set INEX2.
   23894  1.1     is #     RZ mode is forced for the scaling operation to insure
   23895  1.1     is #     only one rounding error.  The grs bits are collected in
   23896  1.1     is #     the INEX flag for use in A10.
   23897  1.1     is #
   23898  1.1     is # Register usage:
   23899  1.1     is #	Input/Output
   23900  1.1     is 
   23901  1.1     is 	fmov.l		&0,%fpsr	# clr INEX
   23902  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# set RZ rounding mode
   23903  1.1     is 
   23904  1.1     is # A9. Scale X -> Y.
   23905  1.1     is #     The mantissa is scaled to the desired number of significant
   23906  1.1     is #     digits.  The excess digits are collected in INEX2. If mul,
   23907  1.1     is #     Check d2 for excess 10 exponential value.  If not zero,
   23908  1.1     is #     the iscale value would have caused the pwrten calculation
   23909  1.1     is #     to overflow.  Only a negative iscale can cause this, so
   23910  1.1     is #     multiply by 10^(d2), which is now only allowed to be 24,
   23911  1.1     is #     with a multiply by 10^8 and 10^16, which is exact since
   23912  1.1     is #     10^24 is exact.  If the input was denormalized, we must
   23913  1.1     is #     create a busy stack frame with the mul command and the
   23914  1.1     is #     two operands, and allow the fpu to complete the multiply.
   23915  1.1     is #
   23916  1.1     is # Register usage:
   23917  1.1     is #	Input/Output
   23918  1.1     is #	d0: FPCR with RZ mode/Unchanged
   23919  1.1     is #	d2: 0 or 24/unchanged
   23920  1.1     is #	d3: x/x
   23921  1.1     is #	d4: LEN/Unchanged
   23922  1.1     is #	d5: ICTR:LAMBDA
   23923  1.1     is #	d6: ILOG/Unchanged
   23924  1.1     is #	d7: k-factor/Unchanged
   23925  1.1     is #	a0: ptr for original operand/final result
   23926  1.1     is #	a1: ptr to PTENRM array/Unchanged
   23927  1.1     is #	a2: x/x
   23928  1.1     is #	fp0: float(ILOG)/X adjusted for SCALE (Y)
   23929  1.1     is #	fp1: 10^ISCALE/Unchanged
   23930  1.1     is #	fp2: x/x
   23931  1.1     is #	F_SCR1:x/x
   23932  1.1     is #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
   23933  1.1     is #	L_SCR1:x/x
   23934  1.1     is #	L_SCR2:first word of X packed/Unchanged
   23935  1.1     is 
   23936  1.1     is A9_str:
   23937  1.1     is 	fmov.x		(%a0),%fp0	# load X from memory
   23938  1.1     is 	fabs.x		%fp0		# use abs(X)
   23939  1.1     is 	tst.w		%d5		# LAMBDA is in lower word of d5
   23940  1.1     is 	bne.b		sc_mul		# if neg (LAMBDA = 1), scale by mul
   23941  1.1     is 	fdiv.x		%fp1,%fp0	# calculate X / SCALE -> Y to fp0
   23942  1.1     is 	bra.w		A10_st		# branch to A10
   23943  1.1     is 
   23944  1.1     is sc_mul:
   23945  1.1     is 	tst.b		BINDEC_FLG(%a6)	# check for denorm
   23946  1.1     is 	beq.w		A9_norm		# if norm, continue with mul
   23947  1.1     is 
   23948  1.1     is # for DENORM, we must calculate:
   23949  1.1     is #	fp0 = input_op * 10^ISCALE * 10^24
   23950  1.1     is # since the input operand is a DENORM, we can't multiply it directly.
   23951  1.1     is # so, we do the multiplication of the exponents and mantissas separately.
   23952  1.1     is # in this way, we avoid underflow on intermediate stages of the
   23953  1.1     is # multiplication and guarantee a result without exception.
   23954  1.1     is 	fmovm.x		&0x2,-(%sp)	# save 10^ISCALE to stack
   23955  1.1     is 
   23956  1.1     is 	mov.w		(%sp),%d3	# grab exponent
   23957  1.1     is 	andi.w		&0x7fff,%d3	# clear sign
   23958  1.1     is 	ori.w		&0x8000,(%a0)	# make DENORM exp negative
   23959  1.1     is 	add.w		(%a0),%d3	# add DENORM exp to 10^ISCALE exp
   23960  1.1     is 	subi.w		&0x3fff,%d3	# subtract BIAS
   23961  1.1     is 	add.w		36(%a1),%d3
   23962  1.1     is 	subi.w		&0x3fff,%d3	# subtract BIAS
   23963  1.1     is 	add.w		48(%a1),%d3
   23964  1.1     is 	subi.w		&0x3fff,%d3	# subtract BIAS
   23965  1.1     is 
   23966  1.1     is 	bmi.w		sc_mul_err	# is result is DENORM, punt!!!
   23967  1.1     is 
   23968  1.1     is 	andi.w		&0x8000,(%sp)	# keep sign
   23969  1.1     is 	or.w		%d3,(%sp)	# insert new exponent
   23970  1.1     is 	andi.w		&0x7fff,(%a0)	# clear sign bit on DENORM again
   23971  1.1     is 	mov.l		0x8(%a0),-(%sp) # put input op mantissa on stk
   23972  1.1     is 	mov.l		0x4(%a0),-(%sp)
   23973  1.1     is 	mov.l		&0x3fff0000,-(%sp) # force exp to zero
   23974  1.1     is 	fmovm.x		(%sp)+,&0x80	# load normalized DENORM into fp0
   23975  1.1     is 	fmul.x		(%sp)+,%fp0
   23976  1.1     is 
   23977  1.1     is #	fmul.x	36(%a1),%fp0	# multiply fp0 by 10^8
   23978  1.1     is #	fmul.x	48(%a1),%fp0	# multiply fp0 by 10^16
   23979  1.1     is 	mov.l		36+8(%a1),-(%sp) # get 10^8 mantissa
   23980  1.1     is 	mov.l		36+4(%a1),-(%sp)
   23981  1.1     is 	mov.l		&0x3fff0000,-(%sp) # force exp to zero
   23982  1.1     is 	mov.l		48+8(%a1),-(%sp) # get 10^16 mantissa
   23983  1.1     is 	mov.l		48+4(%a1),-(%sp)
   23984  1.1     is 	mov.l		&0x3fff0000,-(%sp)# force exp to zero
   23985  1.1     is 	fmul.x		(%sp)+,%fp0	# multiply fp0 by 10^8
   23986  1.1     is 	fmul.x		(%sp)+,%fp0	# multiply fp0 by 10^16
   23987  1.1     is 	bra.b		A10_st
   23988  1.1     is 
   23989  1.1     is sc_mul_err:
   23990  1.1     is 	bra.b		sc_mul_err
   23991  1.1     is 
   23992  1.1     is A9_norm:
   23993  1.1     is 	tst.w		%d2		# test for small exp case
   23994  1.1     is 	beq.b		A9_con		# if zero, continue as normal
   23995  1.1     is 	fmul.x		36(%a1),%fp0	# multiply fp0 by 10^8
   23996  1.1     is 	fmul.x		48(%a1),%fp0	# multiply fp0 by 10^16
   23997  1.1     is A9_con:
   23998  1.1     is 	fmul.x		%fp1,%fp0	# calculate X * SCALE -> Y to fp0
   23999  1.1     is 
   24000  1.1     is # A10. Or in INEX.
   24001  1.2    wiz #      If INEX is set, round error occurred.  This is compensated
   24002  1.1     is #      for by 'or-ing' in the INEX2 flag to the lsb of Y.
   24003  1.1     is #
   24004  1.1     is # Register usage:
   24005  1.1     is #	Input/Output
   24006  1.1     is #	d0: FPCR with RZ mode/FPSR with INEX2 isolated
   24007  1.1     is #	d2: x/x
   24008  1.1     is #	d3: x/x
   24009  1.1     is #	d4: LEN/Unchanged
   24010  1.1     is #	d5: ICTR:LAMBDA
   24011  1.1     is #	d6: ILOG/Unchanged
   24012  1.1     is #	d7: k-factor/Unchanged
   24013  1.1     is #	a0: ptr for original operand/final result
   24014  1.1     is #	a1: ptr to PTENxx array/Unchanged
   24015  1.1     is #	a2: x/ptr to FP_SCR1(a6)
   24016  1.1     is #	fp0: Y/Y with lsb adjusted
   24017  1.1     is #	fp1: 10^ISCALE/Unchanged
   24018  1.1     is #	fp2: x/x
   24019  1.1     is 
   24020  1.1     is A10_st:
   24021  1.1     is 	fmov.l		%fpsr,%d0	# get FPSR
   24022  1.1     is 	fmov.x		%fp0,FP_SCR1(%a6)	# move Y to memory
   24023  1.1     is 	lea.l		FP_SCR1(%a6),%a2	# load a2 with ptr to FP_SCR1
   24024  1.1     is 	btst		&9,%d0		# check if INEX2 set
   24025  1.1     is 	beq.b		A11_st		# if clear, skip rest
   24026  1.1     is 	or.l		&1,8(%a2)	# or in 1 to lsb of mantissa
   24027  1.1     is 	fmov.x		FP_SCR1(%a6),%fp0	# write adjusted Y back to fpu
   24028  1.1     is 
   24029  1.1     is 
   24030  1.1     is # A11. Restore original FPCR; set size ext.
   24031  1.1     is #      Perform FINT operation in the user's rounding mode.  Keep
   24032  1.1     is #      the size to extended.  The sintdo entry point in the sint
   24033  1.1     is #      routine expects the FPCR value to be in USER_FPCR for
   24034  1.1     is #      mode and precision.  The original FPCR is saved in L_SCR1.
   24035  1.1     is 
   24036  1.1     is A11_st:
   24037  1.1     is 	mov.l		USER_FPCR(%a6),L_SCR1(%a6)	# save it for later
   24038  1.1     is 	and.l		&0x00000030,USER_FPCR(%a6)	# set size to ext,
   24039  1.1     is #					;block exceptions
   24040  1.1     is 
   24041  1.1     is 
   24042  1.1     is # A12. Calculate YINT = FINT(Y) according to user's rounding mode.
   24043  1.1     is #      The FPSP routine sintd0 is used.  The output is in fp0.
   24044  1.1     is #
   24045  1.1     is # Register usage:
   24046  1.1     is #	Input/Output
   24047  1.1     is #	d0: FPSR with AINEX cleared/FPCR with size set to ext
   24048  1.1     is #	d2: x/x/scratch
   24049  1.1     is #	d3: x/x
   24050  1.1     is #	d4: LEN/Unchanged
   24051  1.1     is #	d5: ICTR:LAMBDA/Unchanged
   24052  1.1     is #	d6: ILOG/Unchanged
   24053  1.1     is #	d7: k-factor/Unchanged
   24054  1.1     is #	a0: ptr for original operand/src ptr for sintdo
   24055  1.1     is #	a1: ptr to PTENxx array/Unchanged
   24056  1.1     is #	a2: ptr to FP_SCR1(a6)/Unchanged
   24057  1.1     is #	a6: temp pointer to FP_SCR1(a6) - orig value saved and restored
   24058  1.1     is #	fp0: Y/YINT
   24059  1.1     is #	fp1: 10^ISCALE/Unchanged
   24060  1.1     is #	fp2: x/x
   24061  1.1     is #	F_SCR1:x/x
   24062  1.1     is #	F_SCR2:Y adjusted for inex/Y with original exponent
   24063  1.1     is #	L_SCR1:x/original USER_FPCR
   24064  1.1     is #	L_SCR2:first word of X packed/Unchanged
   24065  1.1     is 
   24066  1.1     is A12_st:
   24067  1.1     is 	movm.l	&0xc0c0,-(%sp)	# save regs used by sintd0	 {%d0-%d1/%a0-%a1}
   24068  1.1     is 	mov.l	L_SCR1(%a6),-(%sp)
   24069  1.1     is 	mov.l	L_SCR2(%a6),-(%sp)
   24070  1.1     is 
   24071  1.1     is 	lea.l		FP_SCR1(%a6),%a0	# a0 is ptr to FP_SCR1(a6)
   24072  1.1     is 	fmov.x		%fp0,(%a0)	# move Y to memory at FP_SCR1(a6)
   24073  1.1     is 	tst.l		L_SCR2(%a6)	# test sign of original operand
   24074  1.1     is 	bge.b		do_fint12		# if pos, use Y
   24075  1.1     is 	or.l		&0x80000000,(%a0)	# if neg, use -Y
   24076  1.1     is do_fint12:
   24077  1.1     is 	mov.l	USER_FPSR(%a6),-(%sp)
   24078  1.1     is #	bsr	sintdo		# sint routine returns int in fp0
   24079  1.1     is 
   24080  1.1     is 	fmov.l	USER_FPCR(%a6),%fpcr
   24081  1.1     is 	fmov.l	&0x0,%fpsr			# clear the AEXC bits!!!
   24082  1.1     is ##	mov.l		USER_FPCR(%a6),%d0	# ext prec/keep rnd mode
   24083  1.1     is ##	andi.l		&0x00000030,%d0
   24084  1.1     is ##	fmov.l		%d0,%fpcr
   24085  1.1     is 	fint.x		FP_SCR1(%a6),%fp0	# do fint()
   24086  1.1     is 	fmov.l	%fpsr,%d0
   24087  1.1     is 	or.w	%d0,FPSR_EXCEPT(%a6)
   24088  1.1     is ##	fmov.l		&0x0,%fpcr
   24089  1.1     is ##	fmov.l		%fpsr,%d0		# don't keep ccodes
   24090  1.1     is ##	or.w		%d0,FPSR_EXCEPT(%a6)
   24091  1.1     is 
   24092  1.1     is 	mov.b	(%sp),USER_FPSR(%a6)
   24093  1.1     is 	add.l	&4,%sp
   24094  1.1     is 
   24095  1.1     is 	mov.l	(%sp)+,L_SCR2(%a6)
   24096  1.1     is 	mov.l	(%sp)+,L_SCR1(%a6)
   24097  1.1     is 	movm.l	(%sp)+,&0x303	# restore regs used by sint	 {%d0-%d1/%a0-%a1}
   24098  1.1     is 
   24099  1.1     is 	mov.l	L_SCR2(%a6),FP_SCR1(%a6)	# restore original exponent
   24100  1.1     is 	mov.l	L_SCR1(%a6),USER_FPCR(%a6)	# restore user's FPCR
   24101  1.1     is 
   24102  1.1     is # A13. Check for LEN digits.
   24103  1.1     is #      If the int operation results in more than LEN digits,
   24104  1.1     is #      or less than LEN -1 digits, adjust ILOG and repeat from
   24105  1.1     is #      A6.  This test occurs only on the first pass.  If the
   24106  1.1     is #      result is exactly 10^LEN, decrement ILOG and divide
   24107  1.1     is #      the mantissa by 10.  The calculation of 10^LEN cannot
   24108  1.1     is #      be inexact, since all powers of ten upto 10^27 are exact
   24109  1.1     is #      in extended precision, so the use of a previous power-of-ten
   24110  1.1     is #      table will introduce no error.
   24111  1.1     is #
   24112  1.1     is #
   24113  1.1     is # Register usage:
   24114  1.1     is #	Input/Output
   24115  1.1     is #	d0: FPCR with size set to ext/scratch final = 0
   24116  1.1     is #	d2: x/x
   24117  1.1     is #	d3: x/scratch final = x
   24118  1.1     is #	d4: LEN/LEN adjusted
   24119  1.1     is #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24120  1.1     is #	d6: ILOG/ILOG adjusted
   24121  1.1     is #	d7: k-factor/Unchanged
   24122  1.1     is #	a0: pointer into memory for packed bcd string formation
   24123  1.1     is #	a1: ptr to PTENxx array/Unchanged
   24124  1.1     is #	a2: ptr to FP_SCR1(a6)/Unchanged
   24125  1.1     is #	fp0: int portion of Y/abs(YINT) adjusted
   24126  1.1     is #	fp1: 10^ISCALE/Unchanged
   24127  1.1     is #	fp2: x/10^LEN
   24128  1.1     is #	F_SCR1:x/x
   24129  1.1     is #	F_SCR2:Y with original exponent/Unchanged
   24130  1.1     is #	L_SCR1:original USER_FPCR/Unchanged
   24131  1.1     is #	L_SCR2:first word of X packed/Unchanged
   24132  1.1     is 
   24133  1.1     is A13_st:
   24134  1.1     is 	swap		%d5		# put ICTR in lower word of d5
   24135  1.1     is 	tst.w		%d5		# check if ICTR = 0
   24136  1.1     is 	bne		not_zr		# if non-zero, go to second test
   24137  1.1     is #
   24138  1.1     is # Compute 10^(LEN-1)
   24139  1.1     is #
   24140  1.1     is 	fmov.s		FONE(%pc),%fp2	# init fp2 to 1.0
   24141  1.1     is 	mov.l		%d4,%d0		# put LEN in d0
   24142  1.1     is 	subq.l		&1,%d0		# d0 = LEN -1
   24143  1.1     is 	clr.l		%d3		# clr table index
   24144  1.1     is l_loop:
   24145  1.1     is 	lsr.l		&1,%d0		# shift next bit into carry
   24146  1.1     is 	bcc.b		l_next		# if zero, skip the mul
   24147  1.1     is 	fmul.x		(%a1,%d3),%fp2	# mul by 10**(d3_bit_no)
   24148  1.1     is l_next:
   24149  1.1     is 	add.l		&12,%d3		# inc d3 to next pwrten table entry
   24150  1.1     is 	tst.l		%d0		# test if LEN is zero
   24151  1.1     is 	bne.b		l_loop		# if not, loop
   24152  1.1     is #
   24153  1.1     is # 10^LEN-1 is computed for this test and A14.  If the input was
   24154  1.1     is # denormalized, check only the case in which YINT > 10^LEN.
   24155  1.1     is #
   24156  1.1     is 	tst.b		BINDEC_FLG(%a6)	# check if input was norm
   24157  1.1     is 	beq.b		A13_con		# if norm, continue with checking
   24158  1.1     is 	fabs.x		%fp0		# take abs of YINT
   24159  1.1     is 	bra		test_2
   24160  1.1     is #
   24161  1.1     is # Compare abs(YINT) to 10^(LEN-1) and 10^LEN
   24162  1.1     is #
   24163  1.1     is A13_con:
   24164  1.1     is 	fabs.x		%fp0		# take abs of YINT
   24165  1.1     is 	fcmp.x		%fp0,%fp2	# compare abs(YINT) with 10^(LEN-1)
   24166  1.1     is 	fbge.w		test_2		# if greater, do next test
   24167  1.1     is 	subq.l		&1,%d6		# subtract 1 from ILOG
   24168  1.1     is 	mov.w		&1,%d5		# set ICTR
   24169  1.1     is 	fmov.l		&rm_mode*0x10,%fpcr	# set rmode to RM
   24170  1.1     is 	fmul.s		FTEN(%pc),%fp2	# compute 10^LEN
   24171  1.1     is 	bra.w		A6_str		# return to A6 and recompute YINT
   24172  1.1     is test_2:
   24173  1.1     is 	fmul.s		FTEN(%pc),%fp2	# compute 10^LEN
   24174  1.1     is 	fcmp.x		%fp0,%fp2	# compare abs(YINT) with 10^LEN
   24175  1.1     is 	fblt.w		A14_st		# if less, all is ok, go to A14
   24176  1.1     is 	fbgt.w		fix_ex		# if greater, fix and redo
   24177  1.1     is 	fdiv.s		FTEN(%pc),%fp0	# if equal, divide by 10
   24178  1.1     is 	addq.l		&1,%d6		# and inc ILOG
   24179  1.1     is 	bra.b		A14_st		# and continue elsewhere
   24180  1.1     is fix_ex:
   24181  1.1     is 	addq.l		&1,%d6		# increment ILOG by 1
   24182  1.1     is 	mov.w		&1,%d5		# set ICTR
   24183  1.1     is 	fmov.l		&rm_mode*0x10,%fpcr	# set rmode to RM
   24184  1.1     is 	bra.w		A6_str		# return to A6 and recompute YINT
   24185  1.1     is #
   24186  1.1     is # Since ICTR <> 0, we have already been through one adjustment,
   24187  1.1     is # and shouldn't have another; this is to check if abs(YINT) = 10^LEN
   24188  1.1     is # 10^LEN is again computed using whatever table is in a1 since the
   24189  1.1     is # value calculated cannot be inexact.
   24190  1.1     is #
   24191  1.1     is not_zr:
   24192  1.1     is 	fmov.s		FONE(%pc),%fp2	# init fp2 to 1.0
   24193  1.1     is 	mov.l		%d4,%d0		# put LEN in d0
   24194  1.1     is 	clr.l		%d3		# clr table index
   24195  1.1     is z_loop:
   24196  1.1     is 	lsr.l		&1,%d0		# shift next bit into carry
   24197  1.1     is 	bcc.b		z_next		# if zero, skip the mul
   24198  1.1     is 	fmul.x		(%a1,%d3),%fp2	# mul by 10**(d3_bit_no)
   24199  1.1     is z_next:
   24200  1.1     is 	add.l		&12,%d3		# inc d3 to next pwrten table entry
   24201  1.1     is 	tst.l		%d0		# test if LEN is zero
   24202  1.1     is 	bne.b		z_loop		# if not, loop
   24203  1.1     is 	fabs.x		%fp0		# get abs(YINT)
   24204  1.1     is 	fcmp.x		%fp0,%fp2	# check if abs(YINT) = 10^LEN
   24205  1.1     is 	fbneq.w		A14_st		# if not, skip this
   24206  1.1     is 	fdiv.s		FTEN(%pc),%fp0	# divide abs(YINT) by 10
   24207  1.1     is 	addq.l		&1,%d6		# and inc ILOG by 1
   24208  1.1     is 	addq.l		&1,%d4		# and inc LEN
   24209  1.1     is 	fmul.s		FTEN(%pc),%fp2	# if LEN++, the get 10^^LEN
   24210  1.1     is 
   24211  1.1     is # A14. Convert the mantissa to bcd.
   24212  1.1     is #      The binstr routine is used to convert the LEN digit
   24213  1.1     is #      mantissa to bcd in memory.  The input to binstr is
   24214  1.1     is #      to be a fraction; i.e. (mantissa)/10^LEN and adjusted
   24215  1.1     is #      such that the decimal point is to the left of bit 63.
   24216  1.1     is #      The bcd digits are stored in the correct position in
   24217  1.1     is #      the final string area in memory.
   24218  1.1     is #
   24219  1.1     is #
   24220  1.1     is # Register usage:
   24221  1.1     is #	Input/Output
   24222  1.1     is #	d0: x/LEN call to binstr - final is 0
   24223  1.1     is #	d1: x/0
   24224  1.1     is #	d2: x/ms 32-bits of mant of abs(YINT)
   24225  1.1     is #	d3: x/ls 32-bits of mant of abs(YINT)
   24226  1.1     is #	d4: LEN/Unchanged
   24227  1.1     is #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24228  1.1     is #	d6: ILOG
   24229  1.1     is #	d7: k-factor/Unchanged
   24230  1.1     is #	a0: pointer into memory for packed bcd string formation
   24231  1.1     is #	    /ptr to first mantissa byte in result string
   24232  1.1     is #	a1: ptr to PTENxx array/Unchanged
   24233  1.1     is #	a2: ptr to FP_SCR1(a6)/Unchanged
   24234  1.1     is #	fp0: int portion of Y/abs(YINT) adjusted
   24235  1.1     is #	fp1: 10^ISCALE/Unchanged
   24236  1.1     is #	fp2: 10^LEN/Unchanged
   24237  1.1     is #	F_SCR1:x/Work area for final result
   24238  1.1     is #	F_SCR2:Y with original exponent/Unchanged
   24239  1.1     is #	L_SCR1:original USER_FPCR/Unchanged
   24240  1.1     is #	L_SCR2:first word of X packed/Unchanged
   24241  1.1     is 
   24242  1.1     is A14_st:
   24243  1.1     is 	fmov.l		&rz_mode*0x10,%fpcr	# force rz for conversion
   24244  1.1     is 	fdiv.x		%fp2,%fp0	# divide abs(YINT) by 10^LEN
   24245  1.1     is 	lea.l		FP_SCR0(%a6),%a0
   24246  1.1     is 	fmov.x		%fp0,(%a0)	# move abs(YINT)/10^LEN to memory
   24247  1.1     is 	mov.l		4(%a0),%d2	# move 2nd word of FP_RES to d2
   24248  1.1     is 	mov.l		8(%a0),%d3	# move 3rd word of FP_RES to d3
   24249  1.1     is 	clr.l		4(%a0)		# zero word 2 of FP_RES
   24250  1.1     is 	clr.l		8(%a0)		# zero word 3 of FP_RES
   24251  1.1     is 	mov.l		(%a0),%d0	# move exponent to d0
   24252  1.1     is 	swap		%d0		# put exponent in lower word
   24253  1.1     is 	beq.b		no_sft		# if zero, don't shift
   24254  1.1     is 	sub.l		&0x3ffd,%d0	# sub bias less 2 to make fract
   24255  1.1     is 	tst.l		%d0		# check if > 1
   24256  1.1     is 	bgt.b		no_sft		# if so, don't shift
   24257  1.1     is 	neg.l		%d0		# make exp positive
   24258  1.1     is m_loop:
   24259  1.1     is 	lsr.l		&1,%d2		# shift d2:d3 right, add 0s
   24260  1.1     is 	roxr.l		&1,%d3		# the number of places
   24261  1.1     is 	dbf.w		%d0,m_loop	# given in d0
   24262  1.1     is no_sft:
   24263  1.1     is 	tst.l		%d2		# check for mantissa of zero
   24264  1.1     is 	bne.b		no_zr		# if not, go on
   24265  1.1     is 	tst.l		%d3		# continue zero check
   24266  1.1     is 	beq.b		zer_m		# if zero, go directly to binstr
   24267  1.1     is no_zr:
   24268  1.1     is 	clr.l		%d1		# put zero in d1 for addx
   24269  1.1     is 	add.l		&0x00000080,%d3	# inc at bit 7
   24270  1.1     is 	addx.l		%d1,%d2		# continue inc
   24271  1.1     is 	and.l		&0xffffff80,%d3	# strip off lsb not used by 882
   24272  1.1     is zer_m:
   24273  1.1     is 	mov.l		%d4,%d0		# put LEN in d0 for binstr call
   24274  1.1     is 	addq.l		&3,%a0		# a0 points to M16 byte in result
   24275  1.1     is 	bsr		binstr		# call binstr to convert mant
   24276  1.1     is 
   24277  1.1     is 
   24278  1.1     is # A15. Convert the exponent to bcd.
   24279  1.1     is #      As in A14 above, the exp is converted to bcd and the
   24280  1.1     is #      digits are stored in the final string.
   24281  1.1     is #
   24282  1.1     is #      Digits are stored in L_SCR1(a6) on return from BINDEC as:
   24283  1.1     is #
   24284  1.1     is #  	 32               16 15                0
   24285  1.1     is #	-----------------------------------------
   24286  1.1     is #  	|  0 | e3 | e2 | e1 | e4 |  X |  X |  X |
   24287  1.1     is #	-----------------------------------------
   24288  1.1     is #
   24289  1.1     is # And are moved into their proper places in FP_SCR0.  If digit e4
   24290  1.1     is # is non-zero, OPERR is signaled.  In all cases, all 4 digits are
   24291  1.1     is # written as specified in the 881/882 manual for packed decimal.
   24292  1.1     is #
   24293  1.1     is # Register usage:
   24294  1.1     is #	Input/Output
   24295  1.1     is #	d0: x/LEN call to binstr - final is 0
   24296  1.1     is #	d1: x/scratch (0);shift count for final exponent packing
   24297  1.1     is #	d2: x/ms 32-bits of exp fraction/scratch
   24298  1.1     is #	d3: x/ls 32-bits of exp fraction
   24299  1.1     is #	d4: LEN/Unchanged
   24300  1.1     is #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24301  1.1     is #	d6: ILOG
   24302  1.1     is #	d7: k-factor/Unchanged
   24303  1.1     is #	a0: ptr to result string/ptr to L_SCR1(a6)
   24304  1.1     is #	a1: ptr to PTENxx array/Unchanged
   24305  1.1     is #	a2: ptr to FP_SCR1(a6)/Unchanged
   24306  1.1     is #	fp0: abs(YINT) adjusted/float(ILOG)
   24307  1.1     is #	fp1: 10^ISCALE/Unchanged
   24308  1.1     is #	fp2: 10^LEN/Unchanged
   24309  1.1     is #	F_SCR1:Work area for final result/BCD result
   24310  1.1     is #	F_SCR2:Y with original exponent/ILOG/10^4
   24311  1.1     is #	L_SCR1:original USER_FPCR/Exponent digits on return from binstr
   24312  1.1     is #	L_SCR2:first word of X packed/Unchanged
   24313  1.1     is 
   24314  1.1     is A15_st:
   24315  1.1     is 	tst.b		BINDEC_FLG(%a6)	# check for denorm
   24316  1.1     is 	beq.b		not_denorm
   24317  1.1     is 	ftest.x		%fp0		# test for zero
   24318  1.1     is 	fbeq.w		den_zero	# if zero, use k-factor or 4933
   24319  1.1     is 	fmov.l		%d6,%fp0	# float ILOG
   24320  1.1     is 	fabs.x		%fp0		# get abs of ILOG
   24321  1.1     is 	bra.b		convrt
   24322  1.1     is den_zero:
   24323  1.1     is 	tst.l		%d7		# check sign of the k-factor
   24324  1.1     is 	blt.b		use_ilog	# if negative, use ILOG
   24325  1.1     is 	fmov.s		F4933(%pc),%fp0	# force exponent to 4933
   24326  1.1     is 	bra.b		convrt		# do it
   24327  1.1     is use_ilog:
   24328  1.1     is 	fmov.l		%d6,%fp0	# float ILOG
   24329  1.1     is 	fabs.x		%fp0		# get abs of ILOG
   24330  1.1     is 	bra.b		convrt
   24331  1.1     is not_denorm:
   24332  1.1     is 	ftest.x		%fp0		# test for zero
   24333  1.1     is 	fbneq.w		not_zero	# if zero, force exponent
   24334  1.1     is 	fmov.s		FONE(%pc),%fp0	# force exponent to 1
   24335  1.1     is 	bra.b		convrt		# do it
   24336  1.1     is not_zero:
   24337  1.1     is 	fmov.l		%d6,%fp0	# float ILOG
   24338  1.1     is 	fabs.x		%fp0		# get abs of ILOG
   24339  1.1     is convrt:
   24340  1.1     is 	fdiv.x		24(%a1),%fp0	# compute ILOG/10^4
   24341  1.1     is 	fmov.x		%fp0,FP_SCR1(%a6)	# store fp0 in memory
   24342  1.1     is 	mov.l		4(%a2),%d2	# move word 2 to d2
   24343  1.1     is 	mov.l		8(%a2),%d3	# move word 3 to d3
   24344  1.1     is 	mov.w		(%a2),%d0	# move exp to d0
   24345  1.1     is 	beq.b		x_loop_fin	# if zero, skip the shift
   24346  1.1     is 	sub.w		&0x3ffd,%d0	# subtract off bias
   24347  1.1     is 	neg.w		%d0		# make exp positive
   24348  1.1     is x_loop:
   24349  1.1     is 	lsr.l		&1,%d2		# shift d2:d3 right
   24350  1.1     is 	roxr.l		&1,%d3		# the number of places
   24351  1.1     is 	dbf.w		%d0,x_loop	# given in d0
   24352  1.1     is x_loop_fin:
   24353  1.1     is 	clr.l		%d1		# put zero in d1 for addx
   24354  1.1     is 	add.l		&0x00000080,%d3	# inc at bit 6
   24355  1.1     is 	addx.l		%d1,%d2		# continue inc
   24356  1.1     is 	and.l		&0xffffff80,%d3	# strip off lsb not used by 882
   24357  1.1     is 	mov.l		&4,%d0		# put 4 in d0 for binstr call
   24358  1.1     is 	lea.l		L_SCR1(%a6),%a0	# a0 is ptr to L_SCR1 for exp digits
   24359  1.1     is 	bsr		binstr		# call binstr to convert exp
   24360  1.1     is 	mov.l		L_SCR1(%a6),%d0	# load L_SCR1 lword to d0
   24361  1.1     is 	mov.l		&12,%d1		# use d1 for shift count
   24362  1.1     is 	lsr.l		%d1,%d0		# shift d0 right by 12
   24363  1.1     is 	bfins		%d0,FP_SCR0(%a6){&4:&12}	# put e3:e2:e1 in FP_SCR0
   24364  1.1     is 	lsr.l		%d1,%d0		# shift d0 right by 12
   24365  1.1     is 	bfins		%d0,FP_SCR0(%a6){&16:&4}	# put e4 in FP_SCR0
   24366  1.1     is 	tst.b		%d0		# check if e4 is zero
   24367  1.1     is 	beq.b		A16_st		# if zero, skip rest
   24368  1.1     is 	or.l		&opaop_mask,USER_FPSR(%a6)	# set OPERR & AIOP in USER_FPSR
   24369  1.1     is 
   24370  1.1     is 
   24371  1.1     is # A16. Write sign bits to final string.
   24372  1.1     is #	   Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).
   24373  1.1     is #
   24374  1.1     is # Register usage:
   24375  1.1     is #	Input/Output
   24376  1.1     is #	d0: x/scratch - final is x
   24377  1.1     is #	d2: x/x
   24378  1.1     is #	d3: x/x
   24379  1.1     is #	d4: LEN/Unchanged
   24380  1.1     is #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24381  1.1     is #	d6: ILOG/ILOG adjusted
   24382  1.1     is #	d7: k-factor/Unchanged
   24383  1.1     is #	a0: ptr to L_SCR1(a6)/Unchanged
   24384  1.1     is #	a1: ptr to PTENxx array/Unchanged
   24385  1.1     is #	a2: ptr to FP_SCR1(a6)/Unchanged
   24386  1.1     is #	fp0: float(ILOG)/Unchanged
   24387  1.1     is #	fp1: 10^ISCALE/Unchanged
   24388  1.1     is #	fp2: 10^LEN/Unchanged
   24389  1.1     is #	F_SCR1:BCD result with correct signs
   24390  1.1     is #	F_SCR2:ILOG/10^4
   24391  1.1     is #	L_SCR1:Exponent digits on return from binstr
   24392  1.1     is #	L_SCR2:first word of X packed/Unchanged
   24393  1.1     is 
   24394  1.1     is A16_st:
   24395  1.1     is 	clr.l		%d0		# clr d0 for collection of signs
   24396  1.1     is 	and.b		&0x0f,FP_SCR0(%a6)	# clear first nibble of FP_SCR0
   24397  1.1     is 	tst.l		L_SCR2(%a6)	# check sign of original mantissa
   24398  1.1     is 	bge.b		mant_p		# if pos, don't set SM
   24399  1.1     is 	mov.l		&2,%d0		# move 2 in to d0 for SM
   24400  1.1     is mant_p:
   24401  1.1     is 	tst.l		%d6		# check sign of ILOG
   24402  1.1     is 	bge.b		wr_sgn		# if pos, don't set SE
   24403  1.1     is 	addq.l		&1,%d0		# set bit 0 in d0 for SE
   24404  1.1     is wr_sgn:
   24405  1.1     is 	bfins		%d0,FP_SCR0(%a6){&0:&2}	# insert SM and SE into FP_SCR0
   24406  1.1     is 
   24407  1.1     is # Clean up and restore all registers used.
   24408  1.1     is 
   24409  1.1     is 	fmov.l		&0,%fpsr	# clear possible inex2/ainex bits
   24410  1.1     is 	fmovm.x		(%sp)+,&0xe0	#  {%fp0-%fp2}
   24411  1.1     is 	movm.l		(%sp)+,&0x4fc	#  {%d2-%d7/%a2}
   24412  1.1     is 	rts
   24413  1.1     is 
   24414  1.1     is 	global		PTENRN
   24415  1.1     is PTENRN:
   24416  1.1     is 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   24417  1.1     is 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   24418  1.1     is 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   24419  1.1     is 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   24420  1.1     is 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   24421  1.1     is 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   24422  1.1     is 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   24423  1.1     is 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   24424  1.1     is 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   24425  1.1     is 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   24426  1.1     is 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   24427  1.1     is 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   24428  1.1     is 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   24429  1.1     is 
   24430  1.1     is 	global		PTENRP
   24431  1.1     is PTENRP:
   24432  1.1     is 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   24433  1.1     is 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   24434  1.1     is 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   24435  1.1     is 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   24436  1.1     is 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   24437  1.1     is 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   24438  1.1     is 	long		0x40D30000,0xC2781F49,0xFFCFA6D6	# 10 ^ 64
   24439  1.1     is 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   24440  1.1     is 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   24441  1.1     is 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   24442  1.1     is 	long		0x4D480000,0xC9767586,0x81750C18	# 10 ^ 1024
   24443  1.1     is 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   24444  1.1     is 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   24445  1.1     is 
   24446  1.1     is 	global		PTENRM
   24447  1.1     is PTENRM:
   24448  1.1     is 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   24449  1.1     is 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   24450  1.1     is 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   24451  1.1     is 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   24452  1.1     is 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   24453  1.1     is 	long		0x40690000,0x9DC5ADA8,0x2B70B59D	# 10 ^ 32
   24454  1.1     is 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   24455  1.1     is 	long		0x41A80000,0x93BA47C9,0x80E98CDF	# 10 ^ 128
   24456  1.1     is 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8D	# 10 ^ 256
   24457  1.1     is 	long		0x46A30000,0xE319A0AE,0xA60E91C6	# 10 ^ 512
   24458  1.1     is 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   24459  1.1     is 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE4	# 10 ^ 2048
   24460  1.1     is 	long		0x75250000,0xC4605202,0x8A20979A	# 10 ^ 4096
   24461  1.1     is 
   24462  1.1     is #########################################################################
   24463  1.1     is # binstr(): Converts a 64-bit binary integer to bcd.			#
   24464  1.1     is #									#
   24465  1.1     is # INPUT *************************************************************** #
   24466  1.1     is #	d2:d3 = 64-bit binary integer					#
   24467  1.1     is #	d0    = desired length (LEN)					#
   24468  1.1     is #	a0    = pointer to start in memory for bcd characters		#
   24469  1.1     is #          	(This pointer must point to byte 4 of the first		#
   24470  1.1     is #          	 lword of the packed decimal memory string.)		#
   24471  1.1     is #									#
   24472  1.1     is # OUTPUT ************************************************************** #
   24473  1.1     is #	a0 = pointer to LEN bcd digits representing the 64-bit integer.	#
   24474  1.1     is #									#
   24475  1.1     is # ALGORITHM ***********************************************************	#
   24476  1.1     is #	The 64-bit binary is assumed to have a decimal point before	#
   24477  1.1     is #	bit 63.  The fraction is multiplied by 10 using a mul by 2	#
   24478  1.1     is #	shift and a mul by 8 shift.  The bits shifted out of the	#
   24479  1.1     is #	msb form a decimal digit.  This process is iterated until	#
   24480  1.1     is #	LEN digits are formed.						#
   24481  1.1     is #									#
   24482  1.1     is # A1. Init d7 to 1.  D7 is the byte digit counter, and if 1, the	#
   24483  1.1     is #     digit formed will be assumed the least significant.  This is	#
   24484  1.1     is #     to force the first byte formed to have a 0 in the upper 4 bits.	#
   24485  1.1     is #									#
   24486  1.1     is # A2. Beginning of the loop:						#
   24487  1.1     is #     Copy the fraction in d2:d3 to d4:d5.				#
   24488  1.1     is #									#
   24489  1.1     is # A3. Multiply the fraction in d2:d3 by 8 using bit-field		#
   24490  1.1     is #     extracts and shifts.  The three msbs from d2 will go into d1.	#
   24491  1.1     is #									#
   24492  1.1     is # A4. Multiply the fraction in d4:d5 by 2 using shifts.  The msb	#
   24493  1.1     is #     will be collected by the carry.					#
   24494  1.1     is #									#
   24495  1.1     is # A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5	#
   24496  1.1     is #     into d2:d3.  D1 will contain the bcd digit formed.		#
   24497  1.1     is #									#
   24498  1.1     is # A6. Test d7.  If zero, the digit formed is the ms digit.  If non-	#
   24499  1.1     is #     zero, it is the ls digit.  Put the digit in its place in the	#
   24500  1.1     is #     upper word of d0.  If it is the ls digit, write the word		#
   24501  1.1     is #     from d0 to memory.						#
   24502  1.1     is #									#
   24503  1.1     is # A7. Decrement d6 (LEN counter) and repeat the loop until zero.	#
   24504  1.1     is #									#
   24505  1.1     is #########################################################################
   24506  1.1     is 
   24507  1.1     is #	Implementation Notes:
   24508  1.1     is #
   24509  1.1     is #	The registers are used as follows:
   24510  1.1     is #
   24511  1.1     is #		d0: LEN counter
   24512  1.1     is #		d1: temp used to form the digit
   24513  1.1     is #		d2: upper 32-bits of fraction for mul by 8
   24514  1.1     is #		d3: lower 32-bits of fraction for mul by 8
   24515  1.1     is #		d4: upper 32-bits of fraction for mul by 2
   24516  1.1     is #		d5: lower 32-bits of fraction for mul by 2
   24517  1.1     is #		d6: temp for bit-field extracts
   24518  1.1     is #		d7: byte digit formation word;digit count {0,1}
   24519  1.1     is #		a0: pointer into memory for packed bcd string formation
   24520  1.1     is #
   24521  1.1     is 
   24522  1.1     is 	global		binstr
   24523  1.1     is binstr:
   24524  1.1     is 	movm.l		&0xff00,-(%sp)	#  {%d0-%d7}
   24525  1.1     is 
   24526  1.1     is #
   24527  1.1     is # A1: Init d7
   24528  1.1     is #
   24529  1.1     is 	mov.l		&1,%d7		# init d7 for second digit
   24530  1.1     is 	subq.l		&1,%d0		# for dbf d0 would have LEN+1 passes
   24531  1.1     is #
   24532  1.1     is # A2. Copy d2:d3 to d4:d5.  Start loop.
   24533  1.1     is #
   24534  1.1     is loop:
   24535  1.1     is 	mov.l		%d2,%d4		# copy the fraction before muls
   24536  1.1     is 	mov.l		%d3,%d5		# to d4:d5
   24537  1.1     is #
   24538  1.1     is # A3. Multiply d2:d3 by 8; extract msbs into d1.
   24539  1.1     is #
   24540  1.1     is 	bfextu		%d2{&0:&3},%d1	# copy 3 msbs of d2 into d1
   24541  1.1     is 	asl.l		&3,%d2		# shift d2 left by 3 places
   24542  1.1     is 	bfextu		%d3{&0:&3},%d6	# copy 3 msbs of d3 into d6
   24543  1.1     is 	asl.l		&3,%d3		# shift d3 left by 3 places
   24544  1.1     is 	or.l		%d6,%d2		# or in msbs from d3 into d2
   24545  1.1     is #
   24546  1.1     is # A4. Multiply d4:d5 by 2; add carry out to d1.
   24547  1.1     is #
   24548  1.1     is 	asl.l		&1,%d5		# mul d5 by 2
   24549  1.1     is 	roxl.l		&1,%d4		# mul d4 by 2
   24550  1.1     is 	swap		%d6		# put 0 in d6 lower word
   24551  1.1     is 	addx.w		%d6,%d1		# add in extend from mul by 2
   24552  1.1     is #
   24553  1.1     is # A5. Add mul by 8 to mul by 2.  D1 contains the digit formed.
   24554  1.1     is #
   24555  1.1     is 	add.l		%d5,%d3		# add lower 32 bits
   24556  1.1     is 	nop				# ERRATA FIX #13 (Rev. 1.2 6/6/90)
   24557  1.1     is 	addx.l		%d4,%d2		# add with extend upper 32 bits
   24558  1.1     is 	nop				# ERRATA FIX #13 (Rev. 1.2 6/6/90)
   24559  1.1     is 	addx.w		%d6,%d1		# add in extend from add to d1
   24560  1.1     is 	swap		%d6		# with d6 = 0; put 0 in upper word
   24561  1.1     is #
   24562  1.1     is # A6. Test d7 and branch.
   24563  1.1     is #
   24564  1.1     is 	tst.w		%d7		# if zero, store digit & to loop
   24565  1.1     is 	beq.b		first_d		# if non-zero, form byte & write
   24566  1.1     is sec_d:
   24567  1.1     is 	swap		%d7		# bring first digit to word d7b
   24568  1.1     is 	asl.w		&4,%d7		# first digit in upper 4 bits d7b
   24569  1.1     is 	add.w		%d1,%d7		# add in ls digit to d7b
   24570  1.1     is 	mov.b		%d7,(%a0)+	# store d7b byte in memory
   24571  1.1     is 	swap		%d7		# put LEN counter in word d7a
   24572  1.1     is 	clr.w		%d7		# set d7a to signal no digits done
   24573  1.1     is 	dbf.w		%d0,loop	# do loop some more!
   24574  1.1     is 	bra.b		end_bstr	# finished, so exit
   24575  1.1     is first_d:
   24576  1.1     is 	swap		%d7		# put digit word in d7b
   24577  1.1     is 	mov.w		%d1,%d7		# put new digit in d7b
   24578  1.1     is 	swap		%d7		# put LEN counter in word d7a
   24579  1.1     is 	addq.w		&1,%d7		# set d7a to signal first digit done
   24580  1.1     is 	dbf.w		%d0,loop	# do loop some more!
   24581  1.1     is 	swap		%d7		# put last digit in string
   24582  1.1     is 	lsl.w		&4,%d7		# move it to upper 4 bits
   24583  1.1     is 	mov.b		%d7,(%a0)+	# store it in memory string
   24584  1.1     is #
   24585  1.1     is # Clean up and return with result in fp0.
   24586  1.1     is #
   24587  1.1     is end_bstr:
   24588  1.1     is 	movm.l		(%sp)+,&0xff	#  {%d0-%d7}
   24589  1.1     is 	rts
   24590  1.1     is 
   24591  1.1     is #########################################################################
   24592  1.1     is # XDEF ****************************************************************	#
   24593  1.1     is #	facc_in_b(): dmem_read_byte failed				#
   24594  1.1     is #	facc_in_w(): dmem_read_word failed				#
   24595  1.1     is #	facc_in_l(): dmem_read_long failed				#
   24596  1.1     is #	facc_in_d(): dmem_read of dbl prec failed			#
   24597  1.1     is #	facc_in_x(): dmem_read of ext prec failed			#
   24598  1.1     is #									#
   24599  1.1     is #	facc_out_b(): dmem_write_byte failed				#
   24600  1.1     is #	facc_out_w(): dmem_write_word failed				#
   24601  1.1     is #	facc_out_l(): dmem_write_long failed				#
   24602  1.1     is #	facc_out_d(): dmem_write of dbl prec failed			#
   24603  1.1     is #	facc_out_x(): dmem_write of ext prec failed			#
   24604  1.1     is #									#
   24605  1.1     is # XREF ****************************************************************	#
   24606  1.1     is #	_real_access() - exit through access error handler		#
   24607  1.1     is #									#
   24608  1.1     is # INPUT ***************************************************************	#
   24609  1.1     is #	None								#
   24610  1.1     is # 									#
   24611  1.1     is # OUTPUT **************************************************************	#
   24612  1.1     is #	None								#
   24613  1.1     is #									#
   24614  1.1     is # ALGORITHM ***********************************************************	#
   24615  1.1     is # 	Flow jumps here when an FP data fetch call gets an error 	#
   24616  1.1     is # result. This means the operating system wants an access error frame	#
   24617  1.1     is # made out of the current exception stack frame. 			#
   24618  1.1     is #	So, we first call restore() which makes sure that any updated	#
   24619  1.1     is # -(an)+ register gets returned to its pre-exception value and then	#
   24620  1.1     is # we change the stack to an acess error stack frame.			#
   24621  1.1     is #									#
   24622  1.1     is #########################################################################
   24623  1.1     is 
   24624  1.1     is facc_in_b:
   24625  1.1     is 	movq.l		&0x1,%d0			# one byte
   24626  1.1     is 	bsr.w		restore				# fix An
   24627  1.1     is 
   24628  1.1     is 	mov.w		&0x0121,EXC_VOFF(%a6)		# set FSLW
   24629  1.1     is 	bra.w		facc_finish
   24630  1.1     is 
   24631  1.1     is facc_in_w:
   24632  1.1     is 	movq.l		&0x2,%d0			# two bytes
   24633  1.1     is 	bsr.w		restore				# fix An
   24634  1.1     is 
   24635  1.1     is 	mov.w		&0x0141,EXC_VOFF(%a6)		# set FSLW
   24636  1.1     is 	bra.b		facc_finish
   24637  1.1     is 
   24638  1.1     is facc_in_l:
   24639  1.1     is 	movq.l		&0x4,%d0			# four bytes
   24640  1.1     is 	bsr.w		restore				# fix An
   24641  1.1     is 
   24642  1.1     is 	mov.w		&0x0101,EXC_VOFF(%a6)		# set FSLW
   24643  1.1     is 	bra.b		facc_finish
   24644  1.1     is 
   24645  1.1     is facc_in_d:
   24646  1.1     is 	movq.l		&0x8,%d0			# eight bytes
   24647  1.1     is 	bsr.w		restore				# fix An
   24648  1.1     is 
   24649  1.1     is 	mov.w		&0x0161,EXC_VOFF(%a6)		# set FSLW
   24650  1.1     is 	bra.b		facc_finish
   24651  1.1     is 
   24652  1.1     is facc_in_x:
   24653  1.1     is 	movq.l		&0xc,%d0			# twelve bytes
   24654  1.1     is 	bsr.w		restore				# fix An
   24655  1.1     is 
   24656  1.1     is 	mov.w		&0x0161,EXC_VOFF(%a6)		# set FSLW
   24657  1.1     is 	bra.b		facc_finish
   24658  1.1     is 
   24659  1.1     is ################################################################
   24660  1.1     is 
   24661  1.1     is facc_out_b:
   24662  1.1     is 	movq.l		&0x1,%d0			# one byte
   24663  1.1     is 	bsr.w		restore				# restore An
   24664  1.1     is 
   24665  1.1     is 	mov.w		&0x00a1,EXC_VOFF(%a6)		# set FSLW
   24666  1.1     is 	bra.b		facc_finish
   24667  1.1     is 
   24668  1.1     is facc_out_w:
   24669  1.1     is 	movq.l		&0x2,%d0			# two bytes
   24670  1.1     is 	bsr.w		restore				# restore An
   24671  1.1     is 
   24672  1.1     is 	mov.w		&0x00c1,EXC_VOFF(%a6)		# set FSLW
   24673  1.1     is 	bra.b		facc_finish
   24674  1.1     is 
   24675  1.1     is facc_out_l:
   24676  1.1     is 	movq.l		&0x4,%d0			# four bytes
   24677  1.1     is 	bsr.w		restore				# restore An
   24678  1.1     is 
   24679  1.1     is 	mov.w		&0x0081,EXC_VOFF(%a6)		# set FSLW
   24680  1.1     is 	bra.b		facc_finish
   24681  1.1     is 
   24682  1.1     is facc_out_d:
   24683  1.1     is 	movq.l		&0x8,%d0			# eight bytes
   24684  1.1     is 	bsr.w		restore				# restore An
   24685  1.1     is 
   24686  1.1     is 	mov.w		&0x00e1,EXC_VOFF(%a6)		# set FSLW
   24687  1.1     is 	bra.b		facc_finish
   24688  1.1     is 
   24689  1.1     is facc_out_x:
   24690  1.1     is 	mov.l		&0xc,%d0			# twelve bytes
   24691  1.1     is 	bsr.w		restore				# restore An
   24692  1.1     is 
   24693  1.1     is 	mov.w		&0x00e1,EXC_VOFF(%a6)		# set FSLW
   24694  1.1     is 
   24695  1.1     is # here's where we actually create the access error frame from the
   24696  1.1     is # current exception stack frame.
   24697  1.1     is facc_finish:
   24698  1.1     is 	mov.l		USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
   24699  1.1     is 
   24700  1.1     is 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   24701  1.1     is 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   24702  1.1     is 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   24703  1.1     is 
   24704  1.1     is 	unlk		%a6
   24705  1.1     is 
   24706  1.1     is 	mov.l		(%sp),-(%sp)		# store SR, hi(PC)
   24707  1.1     is 	mov.l		0x8(%sp),0x4(%sp)	# store lo(PC)
   24708  1.1     is 	mov.l		0xc(%sp),0x8(%sp)	# store EA
   24709  1.1     is 	mov.l		&0x00000001,0xc(%sp)	# store FSLW
   24710  1.1     is 	mov.w		0x6(%sp),0xc(%sp)	# fix FSLW (size)
   24711  1.1     is 	mov.w		&0x4008,0x6(%sp)	# store voff
   24712  1.1     is 
   24713  1.1     is 	btst		&0x5,(%sp)		# supervisor or user mode?
   24714  1.1     is 	beq.b		facc_out2		# user
   24715  1.1     is 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
   24716  1.1     is 
   24717  1.1     is facc_out2:
   24718  1.1     is 	bra.l		_real_access
   24719  1.1     is 
   24720  1.1     is ##################################################################
   24721  1.1     is 
   24722  1.1     is # if the effective addressing mode was predecrement or postincrement,
   24723  1.1     is # the emulation has already changed its value to the correct post-
   24724  1.1     is # instruction value. but since we're exiting to the access error
   24725  1.1     is # handler, then AN must be returned to its pre-instruction value.
   24726  1.1     is # we do that here.
   24727  1.1     is restore:
   24728  1.1     is 	mov.b		EXC_OPWORD+0x1(%a6),%d1
   24729  1.1     is 	andi.b		&0x38,%d1		# extract opmode
   24730  1.1     is 	cmpi.b		%d1,&0x18		# postinc?
   24731  1.1     is 	beq.w		rest_inc
   24732  1.1     is 	cmpi.b		%d1,&0x20		# predec?
   24733  1.1     is 	beq.w		rest_dec
   24734  1.1     is 	rts
   24735  1.1     is 
   24736  1.1     is rest_inc:
   24737  1.1     is 	mov.b		EXC_OPWORD+0x1(%a6),%d1
   24738  1.1     is 	andi.w		&0x0007,%d1		# fetch An
   24739  1.1     is 
   24740  1.1     is 	mov.w		(tbl_rest_inc.b,%pc,%d1.w*2),%d1
   24741  1.1     is 	jmp		(tbl_rest_inc.b,%pc,%d1.w*1)
   24742  1.1     is 
   24743  1.1     is tbl_rest_inc:
   24744  1.1     is 	short		ri_a0 - tbl_rest_inc
   24745  1.1     is 	short		ri_a1 - tbl_rest_inc
   24746  1.1     is 	short		ri_a2 - tbl_rest_inc
   24747  1.1     is 	short		ri_a3 - tbl_rest_inc
   24748  1.1     is 	short		ri_a4 - tbl_rest_inc
   24749  1.1     is 	short		ri_a5 - tbl_rest_inc
   24750  1.1     is 	short		ri_a6 - tbl_rest_inc
   24751  1.1     is 	short		ri_a7 - tbl_rest_inc
   24752  1.1     is 
   24753  1.1     is ri_a0:
   24754  1.1     is 	sub.l		%d0,EXC_DREGS+0x8(%a6)	# fix stacked a0
   24755  1.1     is 	rts
   24756  1.1     is ri_a1:
   24757  1.1     is 	sub.l		%d0,EXC_DREGS+0xc(%a6)	# fix stacked a1
   24758  1.1     is 	rts
   24759  1.1     is ri_a2:
   24760  1.1     is 	sub.l		%d0,%a2			# fix a2
   24761  1.1     is 	rts
   24762  1.1     is ri_a3:
   24763  1.1     is 	sub.l		%d0,%a3			# fix a3
   24764  1.1     is 	rts
   24765  1.1     is ri_a4:
   24766  1.1     is 	sub.l		%d0,%a4			# fix a4
   24767  1.1     is 	rts
   24768  1.1     is ri_a5:
   24769  1.1     is 	sub.l		%d0,%a5			# fix a5
   24770  1.1     is 	rts
   24771  1.1     is ri_a6:
   24772  1.1     is 	sub.l		%d0,(%a6)		# fix stacked a6
   24773  1.1     is 	rts
   24774  1.1     is # if it's a fmove out instruction, we don't have to fix a7
   24775  1.1     is # because we hadn't changed it yet. if it's an opclass two
   24776  1.1     is # instruction (data moved in) and the exception was in supervisor
   24777  1.1     is # mode, then also also wasn't updated. if it was user mode, then
   24778  1.1     is # restore the correct a7 which is in the USP currently.
   24779  1.1     is ri_a7:
   24780  1.1     is 	cmpi.b		EXC_VOFF(%a6),&0x30	# move in or out?
   24781  1.1     is 	bne.b		ri_a7_done		# out
   24782  1.1     is 
   24783  1.1     is 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   24784  1.1     is 	bne.b		ri_a7_done		# supervisor
   24785  1.1     is 	movc		%usp,%a0		# restore USP
   24786  1.1     is 	sub.l		%d0,%a0
   24787  1.1     is 	movc		%a0,%usp
   24788  1.1     is ri_a7_done:
   24789  1.1     is 	rts
   24790  1.1     is 
   24791  1.1     is # need to invert adjustment value if the <ea> was predec
   24792  1.1     is rest_dec:
   24793  1.1     is 	neg.l		%d0
   24794  1.1     is 	bra.b		rest_inc
   24795